dect
/
linux-2.6
Archived
13
0
Fork 0

Merge branch 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

* 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  PM: Update comments describing device power management callbacks
  PM / Sleep: Update documentation related to system wakeup
  PM / Runtime: Make documentation follow the new behavior of irq_safe
  PM / Sleep: Correct inaccurate information in devices.txt
  PM / Domains: Document how PM domains are used by the PM core
  PM / Hibernate: Do not leak memory in error/test code paths
This commit is contained in:
Linus Torvalds 2011-11-29 14:43:22 -08:00
commit 8cd7920370
4 changed files with 227 additions and 149 deletions

View File

@ -123,9 +123,10 @@ please refer directly to the source code for more information about it.
Subsystem-Level Methods Subsystem-Level Methods
----------------------- -----------------------
The core methods to suspend and resume devices reside in struct dev_pm_ops The core methods to suspend and resume devices reside in struct dev_pm_ops
pointed to by the pm member of struct bus_type, struct device_type and pointed to by the ops member of struct dev_pm_domain, or by the pm member of
struct class. They are mostly of interest to the people writing infrastructure struct bus_type, struct device_type and struct class. They are mostly of
for buses, like PCI or USB, or device type and device class drivers. interest to the people writing infrastructure for platforms and buses, like PCI
or USB, or device type and device class drivers.
Bus drivers implement these methods as appropriate for the hardware and the Bus drivers implement these methods as appropriate for the hardware and the
drivers using it; PCI works differently from USB, and so on. Not many people drivers using it; PCI works differently from USB, and so on. Not many people
@ -139,41 +140,57 @@ sequencing in the driver model tree.
/sys/devices/.../power/wakeup files /sys/devices/.../power/wakeup files
----------------------------------- -----------------------------------
All devices in the driver model have two flags to control handling of wakeup All device objects in the driver model contain fields that control the handling
events (hardware signals that can force the device and/or system out of a low of system wakeup events (hardware signals that can force the system out of a
power state). These flags are initialized by bus or device driver code using sleep state). These fields are initialized by bus or device driver code using
device_set_wakeup_capable() and device_set_wakeup_enable(), defined in device_set_wakeup_capable() and device_set_wakeup_enable(), defined in
include/linux/pm_wakeup.h. include/linux/pm_wakeup.h.
The "can_wakeup" flag just records whether the device (and its driver) can The "power.can_wakeup" flag just records whether the device (and its driver) can
physically support wakeup events. The device_set_wakeup_capable() routine physically support wakeup events. The device_set_wakeup_capable() routine
affects this flag. The "should_wakeup" flag controls whether the device should affects this flag. The "power.wakeup" field is a pointer to an object of type
try to use its wakeup mechanism. device_set_wakeup_enable() affects this flag; struct wakeup_source used for controlling whether or not the device should use
for the most part drivers should not change its value. The initial value of its system wakeup mechanism and for notifying the PM core of system wakeup
should_wakeup is supposed to be false for the majority of devices; the major events signaled by the device. This object is only present for wakeup-capable
exceptions are power buttons, keyboards, and Ethernet adapters whose WoL devices (i.e. devices whose "can_wakeup" flags are set) and is created (or
(wake-on-LAN) feature has been set up with ethtool. It should also default removed) by device_set_wakeup_capable().
to true for devices that don't generate wakeup requests on their own but merely
forward wakeup requests from one bus to another (like PCI bridges).
Whether or not a device is capable of issuing wakeup events is a hardware Whether or not a device is capable of issuing wakeup events is a hardware
matter, and the kernel is responsible for keeping track of it. By contrast, matter, and the kernel is responsible for keeping track of it. By contrast,
whether or not a wakeup-capable device should issue wakeup events is a policy whether or not a wakeup-capable device should issue wakeup events is a policy
decision, and it is managed by user space through a sysfs attribute: the decision, and it is managed by user space through a sysfs attribute: the
power/wakeup file. User space can write the strings "enabled" or "disabled" to "power/wakeup" file. User space can write the strings "enabled" or "disabled"
set or clear the "should_wakeup" flag, respectively. This file is only present to it to indicate whether or not, respectively, the device is supposed to signal
for wakeup-capable devices (i.e. devices whose "can_wakeup" flags are set) system wakeup. This file is only present if the "power.wakeup" object exists
and is created (or removed) by device_set_wakeup_capable(). Reads from the for the given device and is created (or removed) along with that object, by
file will return the corresponding string. device_set_wakeup_capable(). Reads from the file will return the corresponding
string.
The device_may_wakeup() routine returns true only if both flags are set. The "power/wakeup" file is supposed to contain the "disabled" string initially
for the majority of devices; the major exceptions are power buttons, keyboards,
and Ethernet adapters whose WoL (wake-on-LAN) feature has been set up with
ethtool. It should also default to "enabled" for devices that don't generate
wakeup requests on their own but merely forward wakeup requests from one bus to
another (like PCI Express ports).
The device_may_wakeup() routine returns true only if the "power.wakeup" object
exists and the corresponding "power/wakeup" file contains the string "enabled".
This information is used by subsystems, like the PCI bus type code, to see This information is used by subsystems, like the PCI bus type code, to see
whether or not to enable the devices' wakeup mechanisms. If device wakeup whether or not to enable the devices' wakeup mechanisms. If device wakeup
mechanisms are enabled or disabled directly by drivers, they also should use mechanisms are enabled or disabled directly by drivers, they also should use
device_may_wakeup() to decide what to do during a system sleep transition. device_may_wakeup() to decide what to do during a system sleep transition.
However for runtime power management, wakeup events should be enabled whenever Device drivers, however, are not supposed to call device_set_wakeup_enable()
the device and driver both support them, regardless of the should_wakeup flag. directly in any case.
It ought to be noted that system wakeup is conceptually different from "remote
wakeup" used by runtime power management, although it may be supported by the
same physical mechanism. Remote wakeup is a feature allowing devices in
low-power states to trigger specific interrupts to signal conditions in which
they should be put into the full-power state. Those interrupts may or may not
be used to signal system wakeup events, depending on the hardware design. On
some systems it is impossible to trigger them from system sleep states. In any
case, remote wakeup should always be enabled for runtime power management for
all devices and drivers that support it.
/sys/devices/.../power/control files /sys/devices/.../power/control files
------------------------------------ ------------------------------------
@ -249,20 +266,31 @@ for every device before the next phase begins. Not all busses or classes
support all these callbacks and not all drivers use all the callbacks. The support all these callbacks and not all drivers use all the callbacks. The
various phases always run after tasks have been frozen and before they are various phases always run after tasks have been frozen and before they are
unfrozen. Furthermore, the *_noirq phases run at a time when IRQ handlers have unfrozen. Furthermore, the *_noirq phases run at a time when IRQ handlers have
been disabled (except for those marked with the IRQ_WAKEUP flag). been disabled (except for those marked with the IRQF_NO_SUSPEND flag).
All phases use bus, type, or class callbacks (that is, methods defined in All phases use PM domain, bus, type, or class callbacks (that is, methods
dev->bus->pm, dev->type->pm, or dev->class->pm). These callbacks are mutually defined in dev->pm_domain->ops, dev->bus->pm, dev->type->pm, or dev->class->pm).
exclusive, so if the device type provides a struct dev_pm_ops object pointed to These callbacks are regarded by the PM core as mutually exclusive. Moreover,
by its pm field (i.e. both dev->type and dev->type->pm are defined), the PM domain callbacks always take precedence over bus, type and class callbacks,
callbacks included in that object (i.e. dev->type->pm) will be used. Otherwise, while type callbacks take precedence over bus and class callbacks, and class
if the class provides a struct dev_pm_ops object pointed to by its pm field callbacks take precedence over bus callbacks. To be precise, the following
(i.e. both dev->class and dev->class->pm are defined), the PM core will use the rules are used to determine which callback to execute in the given phase:
callbacks from that object (i.e. dev->class->pm). Finally, if the pm fields of
both the device type and class objects are NULL (or those objects do not exist), 1. If dev->pm_domain is present, the PM core will attempt to execute the
the callbacks provided by the bus (that is, the callbacks from dev->bus->pm) callback included in dev->pm_domain->ops. If that callback is not
will be used (this allows device types to override callbacks provided by bus present, no action will be carried out for the given device.
types or classes if necessary).
2. Otherwise, if both dev->type and dev->type->pm are present, the callback
included in dev->type->pm will be executed.
3. Otherwise, if both dev->class and dev->class->pm are present, the
callback included in dev->class->pm will be executed.
4. Otherwise, if both dev->bus and dev->bus->pm are present, the callback
included in dev->bus->pm will be executed.
This allows PM domains and device types to override callbacks provided by bus
types or device classes if necessary.
These callbacks may in turn invoke device- or driver-specific methods stored in These callbacks may in turn invoke device- or driver-specific methods stored in
dev->driver->pm, but they don't have to. dev->driver->pm, but they don't have to.
@ -283,9 +311,8 @@ When the system goes into the standby or memory sleep state, the phases are:
After the prepare callback method returns, no new children may be After the prepare callback method returns, no new children may be
registered below the device. The method may also prepare the device or registered below the device. The method may also prepare the device or
driver in some way for the upcoming system power transition (for driver in some way for the upcoming system power transition, but it
example, by allocating additional memory required for this purpose), but should not put the device into a low-power state.
it should not put the device into a low-power state.
2. The suspend methods should quiesce the device to stop it from performing 2. The suspend methods should quiesce the device to stop it from performing
I/O. They also may save the device registers and put it into the I/O. They also may save the device registers and put it into the

View File

@ -44,25 +44,33 @@ struct dev_pm_ops {
}; };
The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks
are executed by the PM core for either the power domain, or the device type are executed by the PM core for the device's subsystem that may be either of
(if the device power domain's struct dev_pm_ops does not exist), or the class the following:
(if the device power domain's and type's struct dev_pm_ops object does not
exist), or the bus type (if the device power domain's, type's and class' 1. PM domain of the device, if the device's PM domain object, dev->pm_domain,
struct dev_pm_ops objects do not exist) of the given device, so the priority is present.
order of callbacks from high to low is that power domain callbacks, device
type callbacks, class callbacks and bus type callbacks, and the high priority 2. Device type of the device, if both dev->type and dev->type->pm are present.
one will take precedence over low priority one. The bus type, device type and
class callbacks are referred to as subsystem-level callbacks in what follows, 3. Device class of the device, if both dev->class and dev->class->pm are
and generally speaking, the power domain callbacks are used for representing present.
power domains within a SoC.
4. Bus type of the device, if both dev->bus and dev->bus->pm are present.
The PM core always checks which callback to use in the order given above, so the
priority order of callbacks from high to low is: PM domain, device type, class
and bus type. Moreover, the high-priority one will always take precedence over
a low-priority one. The PM domain, bus type, device type and class callbacks
are referred to as subsystem-level callbacks in what follows.
By default, the callbacks are always invoked in process context with interrupts By default, the callbacks are always invoked in process context with interrupts
enabled. However, subsystems can use the pm_runtime_irq_safe() helper function enabled. However, subsystems can use the pm_runtime_irq_safe() helper function
to tell the PM core that a device's ->runtime_suspend() and ->runtime_resume() to tell the PM core that their ->runtime_suspend(), ->runtime_resume() and
callbacks should be invoked in atomic context with interrupts disabled. ->runtime_idle() callbacks may be invoked in atomic context with interrupts
This implies that these callback routines must not block or sleep, but it also disabled for a given device. This implies that the callback routines in
means that the synchronous helper functions listed at the end of Section 4 can question must not block or sleep, but it also means that the synchronous helper
be used within an interrupt handler or in an atomic context. functions listed at the end of Section 4 may be used for that device within an
interrupt handler or generally in an atomic context.
The subsystem-level suspend callback is _entirely_ _responsible_ for handling The subsystem-level suspend callback is _entirely_ _responsible_ for handling
the suspend of the device as appropriate, which may, but need not include the suspend of the device as appropriate, which may, but need not include

View File

@ -54,118 +54,145 @@ typedef struct pm_message {
/** /**
* struct dev_pm_ops - device PM callbacks * struct dev_pm_ops - device PM callbacks
* *
* Several driver power state transitions are externally visible, affecting * Several device power state transitions are externally visible, affecting
* the state of pending I/O queues and (for drivers that touch hardware) * the state of pending I/O queues and (for drivers that touch hardware)
* interrupts, wakeups, DMA, and other hardware state. There may also be * interrupts, wakeups, DMA, and other hardware state. There may also be
* internal transitions to various low power modes, which are transparent * internal transitions to various low-power modes which are transparent
* to the rest of the driver stack (such as a driver that's ON gating off * to the rest of the driver stack (such as a driver that's ON gating off
* clocks which are not in active use). * clocks which are not in active use).
* *
* The externally visible transitions are handled with the help of the following * The externally visible transitions are handled with the help of callbacks
* callbacks included in this structure: * included in this structure in such a way that two levels of callbacks are
* involved. First, the PM core executes callbacks provided by PM domains,
* device types, classes and bus types. They are the subsystem-level callbacks
* supposed to execute callbacks provided by device drivers, although they may
* choose not to do that. If the driver callbacks are executed, they have to
* collaborate with the subsystem-level callbacks to achieve the goals
* appropriate for the given system transition, given transition phase and the
* subsystem the device belongs to.
* *
* @prepare: Prepare the device for the upcoming transition, but do NOT change * @prepare: The principal role of this callback is to prevent new children of
* its hardware state. Prevent new children of the device from being * the device from being registered after it has returned (the driver's
* registered after @prepare() returns (the driver's subsystem and * subsystem and generally the rest of the kernel is supposed to prevent
* generally the rest of the kernel is supposed to prevent new calls to the * new calls to the probe method from being made too once @prepare() has
* probe method from being made too once @prepare() has succeeded). If * succeeded). If @prepare() detects a situation it cannot handle (e.g.
* @prepare() detects a situation it cannot handle (e.g. registration of a * registration of a child already in progress), it may return -EAGAIN, so
* child already in progress), it may return -EAGAIN, so that the PM core * that the PM core can execute it once again (e.g. after a new child has
* can execute it once again (e.g. after the new child has been registered) * been registered) to recover from the race condition.
* to recover from the race condition. This method is executed for all * This method is executed for all kinds of suspend transitions and is
* kinds of suspend transitions and is followed by one of the suspend * followed by one of the suspend callbacks: @suspend(), @freeze(), or
* callbacks: @suspend(), @freeze(), or @poweroff(). * @poweroff(). The PM core executes subsystem-level @prepare() for all
* The PM core executes @prepare() for all devices before starting to * devices before starting to invoke suspend callbacks for any of them, so
* execute suspend callbacks for any of them, so drivers may assume all of * generally devices may be assumed to be functional or to respond to
* the other devices to be present and functional while @prepare() is being * runtime resume requests while @prepare() is being executed. However,
* executed. In particular, it is safe to make GFP_KERNEL memory * device drivers may NOT assume anything about the availability of user
* allocations from within @prepare(). However, drivers may NOT assume * space at that time and it is NOT valid to request firmware from within
* anything about the availability of the user space at that time and it * @prepare() (it's too late to do that). It also is NOT valid to allocate
* is not correct to request firmware from within @prepare() (it's too * substantial amounts of memory from @prepare() in the GFP_KERNEL mode.
* late to do that). [To work around this limitation, drivers may * [To work around these limitations, drivers may register suspend and
* register suspend and hibernation notifiers that are executed before the * hibernation notifiers to be executed before the freezing of tasks.]
* freezing of tasks.]
* *
* @complete: Undo the changes made by @prepare(). This method is executed for * @complete: Undo the changes made by @prepare(). This method is executed for
* all kinds of resume transitions, following one of the resume callbacks: * all kinds of resume transitions, following one of the resume callbacks:
* @resume(), @thaw(), @restore(). Also called if the state transition * @resume(), @thaw(), @restore(). Also called if the state transition
* fails before the driver's suspend callback (@suspend(), @freeze(), * fails before the driver's suspend callback: @suspend(), @freeze() or
* @poweroff()) can be executed (e.g. if the suspend callback fails for one * @poweroff(), can be executed (e.g. if the suspend callback fails for one
* of the other devices that the PM core has unsuccessfully attempted to * of the other devices that the PM core has unsuccessfully attempted to
* suspend earlier). * suspend earlier).
* The PM core executes @complete() after it has executed the appropriate * The PM core executes subsystem-level @complete() after it has executed
* resume callback for all devices. * the appropriate resume callbacks for all devices.
* *
* @suspend: Executed before putting the system into a sleep state in which the * @suspend: Executed before putting the system into a sleep state in which the
* contents of main memory are preserved. Quiesce the device, put it into * contents of main memory are preserved. The exact action to perform
* a low power state appropriate for the upcoming system state (such as * depends on the device's subsystem (PM domain, device type, class or bus
* PCI_D3hot), and enable wakeup events as appropriate. * type), but generally the device must be quiescent after subsystem-level
* @suspend() has returned, so that it doesn't do any I/O or DMA.
* Subsystem-level @suspend() is executed for all devices after invoking
* subsystem-level @prepare() for all of them.
* *
* @resume: Executed after waking the system up from a sleep state in which the * @resume: Executed after waking the system up from a sleep state in which the
* contents of main memory were preserved. Put the device into the * contents of main memory were preserved. The exact action to perform
* appropriate state, according to the information saved in memory by the * depends on the device's subsystem, but generally the driver is expected
* preceding @suspend(). The driver starts working again, responding to * to start working again, responding to hardware events and software
* hardware events and software requests. The hardware may have gone * requests (the device itself may be left in a low-power state, waiting
* through a power-off reset, or it may have maintained state from the * for a runtime resume to occur). The state of the device at the time its
* previous suspend() which the driver may rely on while resuming. On most * driver's @resume() callback is run depends on the platform and subsystem
* platforms, there are no restrictions on availability of resources like * the device belongs to. On most platforms, there are no restrictions on
* clocks during @resume(). * availability of resources like clocks during @resume().
* Subsystem-level @resume() is executed for all devices after invoking
* subsystem-level @resume_noirq() for all of them.
* *
* @freeze: Hibernation-specific, executed before creating a hibernation image. * @freeze: Hibernation-specific, executed before creating a hibernation image.
* Quiesce operations so that a consistent image can be created, but do NOT * Analogous to @suspend(), but it should not enable the device to signal
* otherwise put the device into a low power device state and do NOT emit * wakeup events or change its power state. The majority of subsystems
* system wakeup events. Save in main memory the device settings to be * (with the notable exception of the PCI bus type) expect the driver-level
* used by @restore() during the subsequent resume from hibernation or by * @freeze() to save the device settings in memory to be used by @restore()
* the subsequent @thaw(), if the creation of the image or the restoration * during the subsequent resume from hibernation.
* of main memory contents from it fails. * Subsystem-level @freeze() is executed for all devices after invoking
* subsystem-level @prepare() for all of them.
* *
* @thaw: Hibernation-specific, executed after creating a hibernation image OR * @thaw: Hibernation-specific, executed after creating a hibernation image OR
* if the creation of the image fails. Also executed after a failing * if the creation of an image has failed. Also executed after a failing
* attempt to restore the contents of main memory from such an image. * attempt to restore the contents of main memory from such an image.
* Undo the changes made by the preceding @freeze(), so the device can be * Undo the changes made by the preceding @freeze(), so the device can be
* operated in the same way as immediately before the call to @freeze(). * operated in the same way as immediately before the call to @freeze().
* Subsystem-level @thaw() is executed for all devices after invoking
* subsystem-level @thaw_noirq() for all of them. It also may be executed
* directly after @freeze() in case of a transition error.
* *
* @poweroff: Hibernation-specific, executed after saving a hibernation image. * @poweroff: Hibernation-specific, executed after saving a hibernation image.
* Quiesce the device, put it into a low power state appropriate for the * Analogous to @suspend(), but it need not save the device's settings in
* upcoming system state (such as PCI_D3hot), and enable wakeup events as * memory.
* appropriate. * Subsystem-level @poweroff() is executed for all devices after invoking
* subsystem-level @prepare() for all of them.
* *
* @restore: Hibernation-specific, executed after restoring the contents of main * @restore: Hibernation-specific, executed after restoring the contents of main
* memory from a hibernation image. Driver starts working again, * memory from a hibernation image, analogous to @resume().
* responding to hardware events and software requests. Drivers may NOT
* make ANY assumptions about the hardware state right prior to @restore().
* On most platforms, there are no restrictions on availability of
* resources like clocks during @restore().
* *
* @suspend_noirq: Complete the operations of ->suspend() by carrying out any * @suspend_noirq: Complete the actions started by @suspend(). Carry out any
* actions required for suspending the device that need interrupts to be * additional operations required for suspending the device that might be
* disabled * racing with its driver's interrupt handler, which is guaranteed not to
* run while @suspend_noirq() is being executed.
* It generally is expected that the device will be in a low-power state
* (appropriate for the target system sleep state) after subsystem-level
* @suspend_noirq() has returned successfully. If the device can generate
* system wakeup signals and is enabled to wake up the system, it should be
* configured to do so at that time. However, depending on the platform
* and device's subsystem, @suspend() may be allowed to put the device into
* the low-power state and configure it to generate wakeup signals, in
* which case it generally is not necessary to define @suspend_noirq().
* *
* @resume_noirq: Prepare for the execution of ->resume() by carrying out any * @resume_noirq: Prepare for the execution of @resume() by carrying out any
* actions required for resuming the device that need interrupts to be * operations required for resuming the device that might be racing with
* disabled * its driver's interrupt handler, which is guaranteed not to run while
* @resume_noirq() is being executed.
* *
* @freeze_noirq: Complete the operations of ->freeze() by carrying out any * @freeze_noirq: Complete the actions started by @freeze(). Carry out any
* actions required for freezing the device that need interrupts to be * additional operations required for freezing the device that might be
* disabled * racing with its driver's interrupt handler, which is guaranteed not to
* run while @freeze_noirq() is being executed.
* The power state of the device should not be changed by either @freeze()
* or @freeze_noirq() and it should not be configured to signal system
* wakeup by any of these callbacks.
* *
* @thaw_noirq: Prepare for the execution of ->thaw() by carrying out any * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any
* actions required for thawing the device that need interrupts to be * operations required for thawing the device that might be racing with its
* disabled * driver's interrupt handler, which is guaranteed not to run while
* @thaw_noirq() is being executed.
* *
* @poweroff_noirq: Complete the operations of ->poweroff() by carrying out any * @poweroff_noirq: Complete the actions started by @poweroff(). Analogous to
* actions required for handling the device that need interrupts to be * @suspend_noirq(), but it need not save the device's settings in memory.
* disabled
* *
* @restore_noirq: Prepare for the execution of ->restore() by carrying out any * @restore_noirq: Prepare for the execution of @restore() by carrying out any
* actions required for restoring the operations of the device that need * operations required for thawing the device that might be racing with its
* interrupts to be disabled * driver's interrupt handler, which is guaranteed not to run while
* @restore_noirq() is being executed. Analogous to @resume_noirq().
* *
* All of the above callbacks, except for @complete(), return error codes. * All of the above callbacks, except for @complete(), return error codes.
* However, the error codes returned by the resume operations, @resume(), * However, the error codes returned by the resume operations, @resume(),
* @thaw(), @restore(), @resume_noirq(), @thaw_noirq(), and @restore_noirq() do * @thaw(), @restore(), @resume_noirq(), @thaw_noirq(), and @restore_noirq(), do
* not cause the PM core to abort the resume transition during which they are * not cause the PM core to abort the resume transition during which they are
* returned. The error codes returned in that cases are only printed by the PM * returned. The error codes returned in those cases are only printed by the PM
* core to the system logs for debugging purposes. Still, it is recommended * core to the system logs for debugging purposes. Still, it is recommended
* that drivers only return error codes from their resume methods in case of an * that drivers only return error codes from their resume methods in case of an
* unrecoverable failure (i.e. when the device being handled refuses to resume * unrecoverable failure (i.e. when the device being handled refuses to resume
@ -174,31 +201,43 @@ typedef struct pm_message {
* their children. * their children.
* *
* It is allowed to unregister devices while the above callbacks are being * It is allowed to unregister devices while the above callbacks are being
* executed. However, it is not allowed to unregister a device from within any * executed. However, a callback routine must NOT try to unregister the device
* of its own callbacks. * it was called for, although it may unregister children of that device (for
* example, if it detects that a child was unplugged while the system was
* asleep).
* *
* There also are the following callbacks related to run-time power management * Refer to Documentation/power/devices.txt for more information about the role
* of devices: * of the above callbacks in the system suspend process.
*
* There also are callbacks related to runtime power management of devices.
* Again, these callbacks are executed by the PM core only for subsystems
* (PM domains, device types, classes and bus types) and the subsystem-level
* callbacks are supposed to invoke the driver callbacks. Moreover, the exact
* actions to be performed by a device driver's callbacks generally depend on
* the platform and subsystem the device belongs to.
* *
* @runtime_suspend: Prepare the device for a condition in which it won't be * @runtime_suspend: Prepare the device for a condition in which it won't be
* able to communicate with the CPU(s) and RAM due to power management. * able to communicate with the CPU(s) and RAM due to power management.
* This need not mean that the device should be put into a low power state. * This need not mean that the device should be put into a low-power state.
* For example, if the device is behind a link which is about to be turned * For example, if the device is behind a link which is about to be turned
* off, the device may remain at full power. If the device does go to low * off, the device may remain at full power. If the device does go to low
* power and is capable of generating run-time wake-up events, remote * power and is capable of generating runtime wakeup events, remote wakeup
* wake-up (i.e., a hardware mechanism allowing the device to request a * (i.e., a hardware mechanism allowing the device to request a change of
* change of its power state via a wake-up event, such as PCI PME) should * its power state via an interrupt) should be enabled for it.
* be enabled for it.
* *
* @runtime_resume: Put the device into the fully active state in response to a * @runtime_resume: Put the device into the fully active state in response to a
* wake-up event generated by hardware or at the request of software. If * wakeup event generated by hardware or at the request of software. If
* necessary, put the device into the full power state and restore its * necessary, put the device into the full-power state and restore its
* registers, so that it is fully operational. * registers, so that it is fully operational.
* *
* @runtime_idle: Device appears to be inactive and it might be put into a low * @runtime_idle: Device appears to be inactive and it might be put into a
* power state if all of the necessary conditions are satisfied. Check * low-power state if all of the necessary conditions are satisfied. Check
* these conditions and handle the device as appropriate, possibly queueing * these conditions and handle the device as appropriate, possibly queueing
* a suspend request for it. The return value is ignored by the PM core. * a suspend request for it. The return value is ignored by the PM core.
*
* Refer to Documentation/power/runtime_pm.txt for more information about the
* role of the above callbacks in device runtime power management.
*
*/ */
struct dev_pm_ops { struct dev_pm_ops {

View File

@ -347,7 +347,7 @@ int hibernation_snapshot(int platform_mode)
error = freeze_kernel_threads(); error = freeze_kernel_threads();
if (error) if (error)
goto Close; goto Cleanup;
if (hibernation_test(TEST_FREEZER) || if (hibernation_test(TEST_FREEZER) ||
hibernation_testmode(HIBERNATION_TESTPROC)) { hibernation_testmode(HIBERNATION_TESTPROC)) {
@ -357,12 +357,14 @@ int hibernation_snapshot(int platform_mode)
* successful freezer test. * successful freezer test.
*/ */
freezer_test_done = true; freezer_test_done = true;
goto Close; goto Cleanup;
} }
error = dpm_prepare(PMSG_FREEZE); error = dpm_prepare(PMSG_FREEZE);
if (error) if (error) {
goto Complete_devices; dpm_complete(msg);
goto Cleanup;
}
suspend_console(); suspend_console();
pm_restrict_gfp_mask(); pm_restrict_gfp_mask();
@ -391,8 +393,6 @@ int hibernation_snapshot(int platform_mode)
pm_restore_gfp_mask(); pm_restore_gfp_mask();
resume_console(); resume_console();
Complete_devices:
dpm_complete(msg); dpm_complete(msg);
Close: Close:
@ -402,6 +402,10 @@ int hibernation_snapshot(int platform_mode)
Recover_platform: Recover_platform:
platform_recover(platform_mode); platform_recover(platform_mode);
goto Resume_devices; goto Resume_devices;
Cleanup:
swsusp_free();
goto Close;
} }
/** /**