aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kexec.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-03-16 17:34:06 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2009-03-30 15:46:54 -0400
commit2ed8d2b3a81bdbb0418301628ccdb008ac9f40b7 (patch)
tree54ab0cd7aa7db73151533b463bd490b62a29c462 /kernel/kexec.c
parent0a0c5168df270a50e3518e4f12bddb31f8f5f38f (diff)
PM: Rework handling of interrupts during suspend-resume
Use the functions introduced in by the previous patch, suspend_device_irqs(), resume_device_irqs() and check_wakeup_irqs(), to rework the handling of interrupts during suspend (hibernation) and resume. Namely, interrupts will only be disabled on the CPU right before suspending sysdevs, while device drivers will be prevented from receiving interrupts, with the help of the new helper function, before their "late" suspend callbacks run (and analogously during resume). In addition, since the device interrups are now disabled before the CPU has turned all interrupts off and the CPU will ACK the interrupts setting the IRQ_PENDING bit for them, check in sysdev_suspend() if any wake-up interrupts are pending and abort suspend if that's the case. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Ingo Molnar <mingo@elte.hu>
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 c7fd6692939d..dade9af6bf21 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1454,7 +1454,6 @@ int kernel_kexec(void)
1454 if (error) 1454 if (error)
1455 goto Resume_devices; 1455 goto Resume_devices;
1456 device_pm_lock(); 1456 device_pm_lock();
1457 local_irq_disable();
1458 /* At this point, device_suspend() has been called, 1457 /* At this point, device_suspend() has been called,
1459 * but *not* device_power_down(). We *must* 1458 * but *not* device_power_down(). We *must*
1460 * device_power_down() now. Otherwise, drivers for 1459 * device_power_down() now. Otherwise, drivers for
@@ -1464,8 +1463,9 @@ int kernel_kexec(void)
1464 */ 1463 */
1465 error = device_power_down(PMSG_FREEZE); 1464 error = device_power_down(PMSG_FREEZE);
1466 if (error) 1465 if (error)
1467 goto Enable_irqs; 1466 goto Unlock_pm;
1468 1467
1468 local_irq_disable();
1469 /* Suspend system devices */ 1469 /* Suspend system devices */
1470 error = sysdev_suspend(PMSG_FREEZE); 1470 error = sysdev_suspend(PMSG_FREEZE);
1471 if (error) 1471 if (error)
@@ -1484,9 +1484,9 @@ int kernel_kexec(void)
1484 if (kexec_image->preserve_context) { 1484 if (kexec_image->preserve_context) {
1485 sysdev_resume(); 1485 sysdev_resume();
1486 Power_up_devices: 1486 Power_up_devices:
1487 device_power_up(PMSG_RESTORE);
1488 Enable_irqs:
1489 local_irq_enable(); 1487 local_irq_enable();
1488 device_power_up(PMSG_RESTORE);
1489 Unlock_pm:
1490 device_pm_unlock(); 1490 device_pm_unlock();
1491 enable_nonboot_cpus(); 1491 enable_nonboot_cpus();
1492 Resume_devices: 1492 Resume_devices: