diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-02-18 17:20:21 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-03-14 19:43:17 -0400 |
commit | 9659cc0678b954f187290c6e8b247a673c5d37e1 (patch) | |
tree | b9b391d2397b0583757dd1529a85d714dbb81697 /Documentation/power/devices.txt | |
parent | cf4fb80ca3d591cae366ae8364e3c3f7a68bd249 (diff) |
PM: Make system-wide PM and runtime PM treat subsystems consistently
The code handling system-wide power transitions (eg. suspend-to-RAM)
can in theory execute callbacks provided by the device's bus type,
device type and class in each phase of the power transition. In
turn, the runtime PM core code only calls one of those callbacks at
a time, preferring bus type callbacks to device type or class
callbacks and device type callbacks to class callbacks.
It seems reasonable to make them both behave in the same way in that
respect. Moreover, even though a device may belong to two subsystems
(eg. bus type and device class) simultaneously, in practice power
management callbacks for system-wide power transitions are always
provided by only one of them (ie. if the bus type callbacks are
defined, the device class ones are not and vice versa). Thus it is
possible to modify the code handling system-wide power transitions
so that it follows the core runtime PM code (ie. treats the
subsystem callbacks as mutually exclusive).
On the other hand, the core runtime PM code will choose to execute,
for example, a runtime suspend callback provided by the device type
even if the bus type's struct dev_pm_ops object exists, but the
runtime_suspend pointer in it happens to be NULL. This is confusing,
because it may lead to the execution of callbacks from different
subsystems during different operations (eg. the bus type suspend
callback may be executed during runtime suspend of the device, while
the device type callback will be executed during system suspend).
Make all of the power management code treat subsystem callbacks in
a consistent way, such that:
(1) If the device's type is defined (eg. dev->type is not NULL)
and its pm pointer is not NULL, the callbacks from dev->type->pm
will be used.
(2) If dev->type is NULL or dev->type->pm is NULL, but the device's
class is defined (eg. dev->class is not NULL) and its pm pointer
is not NULL, the callbacks from dev->class->pm will be used.
(3) If dev->type is NULL or dev->type->pm is NULL and dev->class is
NULL or dev->class->pm is NULL, the callbacks from dev->bus->pm
will be used provided that both dev->bus and dev->bus->pm are
not NULL.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Kevin Hilman <khilman@ti.com>
Reasoning-sounds-sane-to: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'Documentation/power/devices.txt')
-rw-r--r-- | Documentation/power/devices.txt | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index df1a5cb10c42..f023ba6bba62 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt | |||
@@ -249,23 +249,18 @@ various phases always run after tasks have been frozen and before they are | |||
249 | unfrozen. Furthermore, the *_noirq phases run at a time when IRQ handlers have | 249 | unfrozen. Furthermore, the *_noirq phases run at a time when IRQ handlers have |
250 | been disabled (except for those marked with the IRQ_WAKEUP flag). | 250 | been disabled (except for those marked with the IRQ_WAKEUP flag). |
251 | 251 | ||
252 | Most phases use bus, type, and class callbacks (that is, methods defined in | 252 | All phases use bus, type, or class callbacks (that is, methods defined in |
253 | dev->bus->pm, dev->type->pm, and dev->class->pm). The prepare and complete | 253 | dev->bus->pm, dev->type->pm, or dev->class->pm). These callbacks are mutually |
254 | phases are exceptions; they use only bus callbacks. When multiple callbacks | 254 | exclusive, so if the device type provides a struct dev_pm_ops object pointed to |
255 | are used in a phase, they are invoked in the order: <class, type, bus> during | 255 | by its pm field (i.e. both dev->type and dev->type->pm are defined), the |
256 | power-down transitions and in the opposite order during power-up transitions. | 256 | callbacks included in that object (i.e. dev->type->pm) will be used. Otherwise, |
257 | For example, during the suspend phase the PM core invokes | 257 | if the class provides a struct dev_pm_ops object pointed to by its pm field |
258 | 258 | (i.e. both dev->class and dev->class->pm are defined), the PM core will use the | |
259 | dev->class->pm.suspend(dev); | 259 | callbacks from that object (i.e. dev->class->pm). Finally, if the pm fields of |
260 | dev->type->pm.suspend(dev); | 260 | both the device type and class objects are NULL (or those objects do not exist), |
261 | dev->bus->pm.suspend(dev); | 261 | the callbacks provided by the bus (that is, the callbacks from dev->bus->pm) |
262 | 262 | will be used (this allows device types to override callbacks provided by bus | |
263 | before moving on to the next device, whereas during the resume phase the core | 263 | types or classes if necessary). |
264 | invokes | ||
265 | |||
266 | dev->bus->pm.resume(dev); | ||
267 | dev->type->pm.resume(dev); | ||
268 | dev->class->pm.resume(dev); | ||
269 | 264 | ||
270 | These callbacks may in turn invoke device- or driver-specific methods stored in | 265 | These callbacks may in turn invoke device- or driver-specific methods stored in |
271 | dev->driver->pm, but they don't have to. | 266 | dev->driver->pm, but they don't have to. |