]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
PM: Document rules on using pm_runtime_resume() in system suspend callbacks
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 20 Sep 2017 00:26:00 +0000 (02:26 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 23 Sep 2017 13:00:57 +0000 (15:00 +0200)
It quite often is necessary to resume devices from runtime suspend
during system suspend for various reasons (for example, if their
wakeup settings need to be changed), but that requires middle-layer
or subsystem code to follow additional rules which currently are not
clearly documented.

Namely, if a driver calls pm_runtime_resume() for the device from
its ->suspend (or equivalent) system sleep callback, that may not
work if the middle layer above it has updated the state of the
device from its ->prepare or ->suspend callbacks already in an
incompatible way.  For this reason, all middle layers must follow
the rule that, until the ->suspend callback provided by the device's
driver is invoked, the only way in which the device's state can be
updated is by calling pm_runtime_resume() for it, if necessary.
Fortunately enough, all middle layers in the code base today follow
this rule, but it is not explicitly stated anywhere, so do that.

Note that calling pm_runtime_resume() from the ->suspend callback
of a driver will cause the ->runtime_resume callback provided by the
middle layer to be invoked, but the rule above guarantees that this
callback will nest properly with the middle layer's ->suspend
callback and it will play well with the ->prepare one invoked before.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Documentation/driver-api/pm/devices.rst

index bedd32388dac51d8a603dd1389c3b4de24807d7a..a8b07ec732bd376abf3adc291cae67cc88a69a59 100644 (file)
@@ -328,7 +328,10 @@ the phases are: ``prepare``, ``suspend``, ``suspend_late``, ``suspend_noirq``.
        After the ``->prepare`` callback method returns, no new children may be
        registered below the device.  The method may also prepare the device or
        driver in some way for the upcoming system power transition, but it
-       should not put the device into a low-power state.
+       should not put the device into a low-power state.  Moreover, if the
+       device supports runtime power management, the ``->prepare`` callback
+       method must not update its state in case it is necessary to resume it
+       from runtime suspend later on.
 
        For devices supporting runtime power management, the return value of the
        prepare callback can be used to indicate to the PM core that it may
@@ -356,6 +359,16 @@ the phases are: ``prepare``, ``suspend``, ``suspend_late``, ``suspend_noirq``.
        the appropriate low-power state, depending on the bus type the device is
        on, and they may enable wakeup events.
 
+       However, for devices supporting runtime power management, the
+       ``->suspend`` methods provided by subsystems (bus types and PM domains
+       in particular) must follow an additional rule regarding what can be done
+       to the devices before their drivers' ``->suspend`` methods are called.
+       Namely, they can only resume the devices from runtime suspend by
+       calling :c:func:`pm_runtime_resume` for them, if that is necessary, and
+       they must not update the state of the devices in any other way at that
+       time (in case the drivers need to resume the devices from runtime
+       suspend in their ``->suspend`` methods).
+
     3. For a number of devices it is convenient to split suspend into the
        "quiesce device" and "save device state" phases, in which cases
        ``suspend_late`` is meant to do the latter.  It is always executed after
@@ -729,6 +742,16 @@ state temporarily, for example so that its system wakeup capability can be
 disabled.  This all depends on the hardware and the design of the subsystem and
 device driver in question.
 
+If it is necessary to resume a device from runtime suspend during a system-wide
+transition into a sleep state, that can be done by calling
+:c:func:`pm_runtime_resume` for it from the ``->suspend`` callback (or its
+couterpart for transitions related to hibernation) of either the device's driver
+or a subsystem responsible for it (for example, a bus type or a PM domain).
+That is guaranteed to work by the requirement that subsystems must not change
+the state of devices (possibly except for resuming them from runtime suspend)
+from their ``->prepare`` and ``->suspend`` callbacks (or equivalent) *before*
+invoking device drivers' ``->suspend`` callbacks (or equivalent).
+
 During system-wide resume from a sleep state it's easiest to put devices into
 the full-power state, as explained in :file:`Documentation/power/runtime_pm.txt`.
 Refer to that document for more information regarding this particular issue as