|
@@ -214,7 +214,7 @@ static int create_image(int platform_mode)
|
|
|
return error;
|
|
|
|
|
|
device_pm_lock();
|
|
|
- local_irq_disable();
|
|
|
+
|
|
|
/* At this point, device_suspend() has been called, but *not*
|
|
|
* device_power_down(). We *must* call device_power_down() now.
|
|
|
* Otherwise, drivers for some devices (e.g. interrupt controllers)
|
|
@@ -225,8 +225,11 @@ static int create_image(int platform_mode)
|
|
|
if (error) {
|
|
|
printk(KERN_ERR "PM: Some devices failed to power down, "
|
|
|
"aborting hibernation\n");
|
|
|
- goto Enable_irqs;
|
|
|
+ goto Unlock;
|
|
|
}
|
|
|
+
|
|
|
+ local_irq_disable();
|
|
|
+
|
|
|
sysdev_suspend(PMSG_FREEZE);
|
|
|
if (error) {
|
|
|
printk(KERN_ERR "PM: Some devices failed to power down, "
|
|
@@ -252,12 +255,16 @@ static int create_image(int platform_mode)
|
|
|
/* NOTE: device_power_up() is just a resume() for devices
|
|
|
* that suspended with irqs off ... no overall powerup.
|
|
|
*/
|
|
|
+
|
|
|
Power_up_devices:
|
|
|
+ local_irq_enable();
|
|
|
+
|
|
|
device_power_up(in_suspend ?
|
|
|
(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
|
|
|
- Enable_irqs:
|
|
|
- local_irq_enable();
|
|
|
+
|
|
|
+ Unlock:
|
|
|
device_pm_unlock();
|
|
|
+
|
|
|
return error;
|
|
|
}
|
|
|
|
|
@@ -336,13 +343,16 @@ static int resume_target_kernel(void)
|
|
|
int error;
|
|
|
|
|
|
device_pm_lock();
|
|
|
- local_irq_disable();
|
|
|
+
|
|
|
error = device_power_down(PMSG_QUIESCE);
|
|
|
if (error) {
|
|
|
printk(KERN_ERR "PM: Some devices failed to power down, "
|
|
|
"aborting resume\n");
|
|
|
- goto Enable_irqs;
|
|
|
+ goto Unlock;
|
|
|
}
|
|
|
+
|
|
|
+ local_irq_disable();
|
|
|
+
|
|
|
sysdev_suspend(PMSG_QUIESCE);
|
|
|
/* We'll ignore saved state, but this gets preempt count (etc) right */
|
|
|
save_processor_state();
|
|
@@ -366,11 +376,16 @@ static int resume_target_kernel(void)
|
|
|
swsusp_free();
|
|
|
restore_processor_state();
|
|
|
touch_softlockup_watchdog();
|
|
|
+
|
|
|
sysdev_resume();
|
|
|
- device_power_up(PMSG_RECOVER);
|
|
|
- Enable_irqs:
|
|
|
+
|
|
|
local_irq_enable();
|
|
|
+
|
|
|
+ device_power_up(PMSG_RECOVER);
|
|
|
+
|
|
|
+ Unlock:
|
|
|
device_pm_unlock();
|
|
|
+
|
|
|
return error;
|
|
|
}
|
|
|
|
|
@@ -447,15 +462,16 @@ int hibernation_platform_enter(void)
|
|
|
goto Finish;
|
|
|
|
|
|
device_pm_lock();
|
|
|
- local_irq_disable();
|
|
|
+
|
|
|
error = device_power_down(PMSG_HIBERNATE);
|
|
|
if (!error) {
|
|
|
+ local_irq_disable();
|
|
|
sysdev_suspend(PMSG_HIBERNATE);
|
|
|
hibernation_ops->enter();
|
|
|
/* We should never get here */
|
|
|
while (1);
|
|
|
}
|
|
|
- local_irq_enable();
|
|
|
+
|
|
|
device_pm_unlock();
|
|
|
|
|
|
/*
|
|
@@ -464,12 +480,15 @@ int hibernation_platform_enter(void)
|
|
|
*/
|
|
|
Finish:
|
|
|
hibernation_ops->finish();
|
|
|
+
|
|
|
Resume_devices:
|
|
|
entering_platform_hibernation = false;
|
|
|
device_resume(PMSG_RESTORE);
|
|
|
resume_console();
|
|
|
+
|
|
|
Close:
|
|
|
hibernation_ops->end();
|
|
|
+
|
|
|
return error;
|
|
|
}
|
|
|
|