aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kexec.c
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 /kernel/kexec.c
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 'kernel/kexec.c')
-rw-r--r--kernel/kexec.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 7b0886786701..a6a675cb9818 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1546,13 +1546,13 @@ int kernel_kexec(void)
1546 if (error) 1546 if (error)
1547 goto Resume_console; 1547 goto Resume_console;
1548 /* At this point, dpm_suspend_start() has been called, 1548 /* At this point, dpm_suspend_start() has been called,
1549 * but *not* dpm_suspend_noirq(). We *must* call 1549 * but *not* dpm_suspend_end(). We *must* call
1550 * dpm_suspend_noirq() now. Otherwise, drivers for 1550 * dpm_suspend_end() now. Otherwise, drivers for
1551 * some devices (e.g. interrupt controllers) become 1551 * some devices (e.g. interrupt controllers) become
1552 * desynchronized with the actual state of the 1552 * desynchronized with the actual state of the
1553 * hardware at resume time, and evil weirdness ensues. 1553 * hardware at resume time, and evil weirdness ensues.
1554 */ 1554 */
1555 error = dpm_suspend_noirq(PMSG_FREEZE); 1555 error = dpm_suspend_end(PMSG_FREEZE);
1556 if (error) 1556 if (error)
1557 goto Resume_devices; 1557 goto Resume_devices;
1558 error = disable_nonboot_cpus(); 1558 error = disable_nonboot_cpus();
@@ -1579,7 +1579,7 @@ int kernel_kexec(void)
1579 local_irq_enable(); 1579 local_irq_enable();
1580 Enable_cpus: 1580 Enable_cpus:
1581 enable_nonboot_cpus(); 1581 enable_nonboot_cpus();
1582 dpm_resume_noirq(PMSG_RESTORE); 1582 dpm_resume_start(PMSG_RESTORE);
1583 Resume_devices: 1583 Resume_devices:
1584 dpm_resume_end(PMSG_RESTORE); 1584 dpm_resume_end(PMSG_RESTORE);
1585 Resume_console: 1585 Resume_console: