aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/pm.h
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-01-29 14:38:29 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2012-01-29 14:38:29 -0500
commitcf579dfb82550e34de7ccf3ef090d8b834ccd3a9 (patch)
tree764ed72670c18c86d3eb9650025c56d661a31315 /include/linux/pm.h
parent181e9bdef37bfcaa41f3ab6c948a2a0d60a268b5 (diff)
PM / Sleep: Introduce "late suspend" and "early resume" of devices
The current device suspend/resume phases during system-wide power transitions appear to be insufficient for some platforms that want to use the same callback routines for saving device states and related operations during runtime suspend/resume as well as during system suspend/resume. In principle, they could point their .suspend_noirq() and .resume_noirq() to the same callback routines as their .runtime_suspend() and .runtime_resume(), respectively, but at least some of them require device interrupts to be enabled while the code in those routines is running. It also makes sense to have device suspend-resume callbacks that will be executed with runtime PM disabled and with device interrupts enabled in case someone needs to run some special code in that context during system-wide power transitions. Apart from this, .suspend_noirq() and .resume_noirq() were introduced as a workaround for drivers using shared interrupts and failing to prevent their interrupt handlers from accessing suspended hardware. It appears to be better not to use them for other porposes, or we may have to deal with some serious confusion (which seems to be happening already). For the above reasons, introduce new device suspend/resume phases, "late suspend" and "early resume" (and analogously for hibernation) whose callback will be executed with runtime PM disabled and with device interrupts enabled and whose callback pointers generally may point to runtime suspend/resume routines. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Reviewed-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'include/linux/pm.h')
-rw-r--r--include/linux/pm.h43
1 files changed, 35 insertions, 8 deletions
diff --git a/include/linux/pm.h b/include/linux/pm.h
index e4982ac3fbbc..c68e1f22ac95 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -110,6 +110,10 @@ typedef struct pm_message {
110 * Subsystem-level @suspend() is executed for all devices after invoking 110 * Subsystem-level @suspend() is executed for all devices after invoking
111 * subsystem-level @prepare() for all of them. 111 * subsystem-level @prepare() for all of them.
112 * 112 *
113 * @suspend_late: Continue operations started by @suspend(). For a number of
114 * devices @suspend_late() may point to the same callback routine as the
115 * runtime suspend callback.
116 *
113 * @resume: Executed after waking the system up from a sleep state in which the 117 * @resume: Executed after waking the system up from a sleep state in which the
114 * contents of main memory were preserved. The exact action to perform 118 * contents of main memory were preserved. The exact action to perform
115 * depends on the device's subsystem, but generally the driver is expected 119 * depends on the device's subsystem, but generally the driver is expected
@@ -122,6 +126,10 @@ typedef struct pm_message {
122 * Subsystem-level @resume() is executed for all devices after invoking 126 * Subsystem-level @resume() is executed for all devices after invoking
123 * subsystem-level @resume_noirq() for all of them. 127 * subsystem-level @resume_noirq() for all of them.
124 * 128 *
129 * @resume_early: Prepare to execute @resume(). For a number of devices
130 * @resume_early() may point to the same callback routine as the runtime
131 * resume callback.
132 *
125 * @freeze: Hibernation-specific, executed before creating a hibernation image. 133 * @freeze: Hibernation-specific, executed before creating a hibernation image.
126 * Analogous to @suspend(), but it should not enable the device to signal 134 * Analogous to @suspend(), but it should not enable the device to signal
127 * wakeup events or change its power state. The majority of subsystems 135 * wakeup events or change its power state. The majority of subsystems
@@ -131,6 +139,10 @@ typedef struct pm_message {
131 * Subsystem-level @freeze() is executed for all devices after invoking 139 * Subsystem-level @freeze() is executed for all devices after invoking
132 * subsystem-level @prepare() for all of them. 140 * subsystem-level @prepare() for all of them.
133 * 141 *
142 * @freeze_late: Continue operations started by @freeze(). Analogous to
143 * @suspend_late(), but it should not enable the device to signal wakeup
144 * events or change its power state.
145 *
134 * @thaw: Hibernation-specific, executed after creating a hibernation image OR 146 * @thaw: Hibernation-specific, executed after creating a hibernation image OR
135 * if the creation of an image has failed. Also executed after a failing 147 * if the creation of an image has failed. Also executed after a failing
136 * attempt to restore the contents of main memory from such an image. 148 * attempt to restore the contents of main memory from such an image.
@@ -140,15 +152,23 @@ typedef struct pm_message {
140 * subsystem-level @thaw_noirq() for all of them. It also may be executed 152 * subsystem-level @thaw_noirq() for all of them. It also may be executed
141 * directly after @freeze() in case of a transition error. 153 * directly after @freeze() in case of a transition error.
142 * 154 *
155 * @thaw_early: Prepare to execute @thaw(). Undo the changes made by the
156 * preceding @freeze_late().
157 *
143 * @poweroff: Hibernation-specific, executed after saving a hibernation image. 158 * @poweroff: Hibernation-specific, executed after saving a hibernation image.
144 * Analogous to @suspend(), but it need not save the device's settings in 159 * Analogous to @suspend(), but it need not save the device's settings in
145 * memory. 160 * memory.
146 * Subsystem-level @poweroff() is executed for all devices after invoking 161 * Subsystem-level @poweroff() is executed for all devices after invoking
147 * subsystem-level @prepare() for all of them. 162 * subsystem-level @prepare() for all of them.
148 * 163 *
164 * @poweroff_late: Continue operations started by @poweroff(). Analogous to
165 * @suspend_late(), but it need not save the device's settings in memory.
166 *
149 * @restore: Hibernation-specific, executed after restoring the contents of main 167 * @restore: Hibernation-specific, executed after restoring the contents of main
150 * memory from a hibernation image, analogous to @resume(). 168 * memory from a hibernation image, analogous to @resume().
151 * 169 *
170 * @restore_early: Prepare to execute @restore(), analogous to @resume_early().
171 *
152 * @suspend_noirq: Complete the actions started by @suspend(). Carry out any 172 * @suspend_noirq: Complete the actions started by @suspend(). Carry out any
153 * additional operations required for suspending the device that might be 173 * additional operations required for suspending the device that might be
154 * racing with its driver's interrupt handler, which is guaranteed not to 174 * racing with its driver's interrupt handler, which is guaranteed not to
@@ -158,9 +178,10 @@ typedef struct pm_message {
158 * @suspend_noirq() has returned successfully. If the device can generate 178 * @suspend_noirq() has returned successfully. If the device can generate
159 * system wakeup signals and is enabled to wake up the system, it should be 179 * system wakeup signals and is enabled to wake up the system, it should be
160 * configured to do so at that time. However, depending on the platform 180 * configured to do so at that time. However, depending on the platform
161 * and device's subsystem, @suspend() may be allowed to put the device into 181 * and device's subsystem, @suspend() or @suspend_late() may be allowed to
162 * the low-power state and configure it to generate wakeup signals, in 182 * put the device into the low-power state and configure it to generate
163 * which case it generally is not necessary to define @suspend_noirq(). 183 * wakeup signals, in which case it generally is not necessary to define
184 * @suspend_noirq().
164 * 185 *
165 * @resume_noirq: Prepare for the execution of @resume() by carrying out any 186 * @resume_noirq: Prepare for the execution of @resume() by carrying out any
166 * operations required for resuming the device that might be racing with 187 * operations required for resuming the device that might be racing with
@@ -171,9 +192,9 @@ typedef struct pm_message {
171 * additional operations required for freezing the device that might be 192 * additional operations required for freezing the device that might be
172 * racing with its driver's interrupt handler, which is guaranteed not to 193 * racing with its driver's interrupt handler, which is guaranteed not to
173 * run while @freeze_noirq() is being executed. 194 * run while @freeze_noirq() is being executed.
174 * The power state of the device should not be changed by either @freeze() 195 * The power state of the device should not be changed by either @freeze(),
175 * or @freeze_noirq() and it should not be configured to signal system 196 * or @freeze_late(), or @freeze_noirq() and it should not be configured to
176 * wakeup by any of these callbacks. 197 * signal system wakeup by any of these callbacks.
177 * 198 *
178 * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any 199 * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any
179 * operations required for thawing the device that might be racing with its 200 * operations required for thawing the device that might be racing with its
@@ -249,6 +270,12 @@ struct dev_pm_ops {
249 int (*thaw)(struct device *dev); 270 int (*thaw)(struct device *dev);
250 int (*poweroff)(struct device *dev); 271 int (*poweroff)(struct device *dev);
251 int (*restore)(struct device *dev); 272 int (*restore)(struct device *dev);
273 int (*suspend_late)(struct device *dev);
274 int (*resume_early)(struct device *dev);
275 int (*freeze_late)(struct device *dev);
276 int (*thaw_early)(struct device *dev);
277 int (*poweroff_late)(struct device *dev);
278 int (*restore_early)(struct device *dev);
252 int (*suspend_noirq)(struct device *dev); 279 int (*suspend_noirq)(struct device *dev);
253 int (*resume_noirq)(struct device *dev); 280 int (*resume_noirq)(struct device *dev);
254 int (*freeze_noirq)(struct device *dev); 281 int (*freeze_noirq)(struct device *dev);
@@ -584,13 +611,13 @@ struct dev_pm_domain {
584 611
585#ifdef CONFIG_PM_SLEEP 612#ifdef CONFIG_PM_SLEEP
586extern void device_pm_lock(void); 613extern void device_pm_lock(void);
587extern void dpm_resume_noirq(pm_message_t state); 614extern void dpm_resume_start(pm_message_t state);
588extern void dpm_resume_end(pm_message_t state); 615extern void dpm_resume_end(pm_message_t state);
589extern void dpm_resume(pm_message_t state); 616extern void dpm_resume(pm_message_t state);
590extern void dpm_complete(pm_message_t state); 617extern void dpm_complete(pm_message_t state);
591 618
592extern void device_pm_unlock(void); 619extern void device_pm_unlock(void);
593extern int dpm_suspend_noirq(pm_message_t state); 620extern int dpm_suspend_end(pm_message_t state);
594extern int dpm_suspend_start(pm_message_t state); 621extern int dpm_suspend_start(pm_message_t state);
595extern int dpm_suspend(pm_message_t state); 622extern int dpm_suspend(pm_message_t state);
596extern int dpm_prepare(pm_message_t state); 623extern int dpm_prepare(pm_message_t state);