Skip to content

Commit 0eab11c

Browse files
committed
PM / core: Add SMART_SUSPEND driver flag
Define and document a SMART_SUSPEND flag to instruct bus types and PM domains that the system suspend callbacks provided by the driver can cope with runtime-suspended devices, so from the driver's perspective it should be safe to leave devices in runtime suspend during system suspend. Setting that flag may also cause middle-layer code (bus types, PM domains etc.) to skip invocations of the ->suspend_late and ->suspend_noirq callbacks provided by the driver if the device is in runtime suspend at the beginning of the "late" phase of the system-wide suspend transition, in which case the driver's system-wide resume callbacks may be invoked back-to-back with its ->runtime_suspend callback, so the driver has to be able to cope with that too. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent c2eac4d commit 0eab11c

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

Documentation/driver-api/pm/devices.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,26 @@ the state of devices (possibly except for resuming them from runtime suspend)
766766
from their ``->prepare`` and ``->suspend`` callbacks (or equivalent) *before*
767767
invoking device drivers' ``->suspend`` callbacks (or equivalent).
768768

769+
Some bus types and PM domains have a policy to resume all devices from runtime
770+
suspend upfront in their ``->suspend`` callbacks, but that may not be really
771+
necessary if the driver of the device can cope with runtime-suspended devices.
772+
The driver can indicate that by setting ``DPM_FLAG_SMART_SUSPEND`` in
773+
:c:member:`power.driver_flags` at the probe time, by passing it to the
774+
:c:func:`dev_pm_set_driver_flags` helper. That also may cause middle-layer code
775+
(bus types, PM domains etc.) to skip the ``->suspend_late`` and
776+
``->suspend_noirq`` callbacks provided by the driver if the device remains in
777+
runtime suspend at the beginning of the ``suspend_late`` phase of system-wide
778+
suspend (or in the ``poweroff_late`` phase of hibernation), when runtime PM
779+
has been disabled for it, under the assumption that its state should not change
780+
after that point until the system-wide transition is over. If that happens, the
781+
driver's system-wide resume callbacks, if present, may still be invoked during
782+
the subsequent system-wide resume transition and the device's runtime power
783+
management status may be set to "active" before enabling runtime PM for it,
784+
so the driver must be prepared to cope with the invocation of its system-wide
785+
resume callbacks back-to-back with its ``->runtime_suspend`` one (without the
786+
intervening ``->runtime_resume`` and so on) and the final state of the device
787+
must reflect the "active" status for runtime PM in that case.
788+
769789
During system-wide resume from a sleep state it's easiest to put devices into
770790
the full-power state, as explained in :file:`Documentation/power/runtime_pm.txt`.
771791
Refer to that document for more information regarding this particular issue as

drivers/base/power/main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,9 @@ static int device_prepare(struct device *dev, pm_message_t state)
16521652
if (dev->power.syscore)
16531653
return 0;
16541654

1655+
WARN_ON(dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) &&
1656+
!pm_runtime_enabled(dev));
1657+
16551658
/*
16561659
* If a device's parent goes into runtime suspend at the wrong time,
16571660
* it won't be possible to resume the device. To prevent this we

include/linux/pm.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,16 +558,24 @@ struct pm_subsys_data {
558558
*
559559
* NEVER_SKIP: Do not skip system suspend/resume callbacks for the device.
560560
* SMART_PREPARE: Check the return value of the driver's ->prepare callback.
561+
* SMART_SUSPEND: No need to resume the device from runtime suspend.
561562
*
562563
* Setting SMART_PREPARE instructs bus types and PM domains which may want
563564
* system suspend/resume callbacks to be skipped for the device to return 0 from
564565
* their ->prepare callbacks if the driver's ->prepare callback returns 0 (in
565566
* other words, the system suspend/resume callbacks can only be skipped for the
566567
* device if its driver doesn't object against that). This flag has no effect
567568
* if NEVER_SKIP is set.
569+
*
570+
* Setting SMART_SUSPEND instructs bus types and PM domains which may want to
571+
* runtime resume the device upfront during system suspend that doing so is not
572+
* necessary from the driver's perspective. It also may cause them to skip
573+
* invocations of the ->suspend_late and ->suspend_noirq callbacks provided by
574+
* the driver if they decide to leave the device in runtime suspend.
568575
*/
569576
#define DPM_FLAG_NEVER_SKIP BIT(0)
570577
#define DPM_FLAG_SMART_PREPARE BIT(1)
578+
#define DPM_FLAG_SMART_SUSPEND BIT(2)
571579

572580
struct dev_pm_info {
573581
pm_message_t power_state;

0 commit comments

Comments
 (0)