Commit 770824bd authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Linus Torvalds

PM: Split up sysdev_[suspend|resume] from device_power_[down|up]

Move the sysdev_suspend/resume from the callee to the callers, with
no real change in semantics, so that we can rework the disabling of
interrupts during suspend/hibernation.

This is based on an earlier patch from Linus.
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 936577c6
...@@ -1192,6 +1192,7 @@ static int suspend(int vetoable) ...@@ -1192,6 +1192,7 @@ static int suspend(int vetoable)
device_suspend(PMSG_SUSPEND); device_suspend(PMSG_SUSPEND);
local_irq_disable(); local_irq_disable();
device_power_down(PMSG_SUSPEND); device_power_down(PMSG_SUSPEND);
sysdev_suspend(PMSG_SUSPEND);
local_irq_enable(); local_irq_enable();
...@@ -1208,6 +1209,7 @@ static int suspend(int vetoable) ...@@ -1208,6 +1209,7 @@ static int suspend(int vetoable)
if (err != APM_SUCCESS) if (err != APM_SUCCESS)
apm_error("suspend", err); apm_error("suspend", err);
err = (err == APM_SUCCESS) ? 0 : -EIO; err = (err == APM_SUCCESS) ? 0 : -EIO;
sysdev_resume();
device_power_up(PMSG_RESUME); device_power_up(PMSG_RESUME);
local_irq_enable(); local_irq_enable();
device_resume(PMSG_RESUME); device_resume(PMSG_RESUME);
...@@ -1228,6 +1230,7 @@ static void standby(void) ...@@ -1228,6 +1230,7 @@ static void standby(void)
local_irq_disable(); local_irq_disable();
device_power_down(PMSG_SUSPEND); device_power_down(PMSG_SUSPEND);
sysdev_suspend(PMSG_SUSPEND);
local_irq_enable(); local_irq_enable();
err = set_system_power_state(APM_STATE_STANDBY); err = set_system_power_state(APM_STATE_STANDBY);
...@@ -1235,6 +1238,7 @@ static void standby(void) ...@@ -1235,6 +1238,7 @@ static void standby(void)
apm_error("standby", err); apm_error("standby", err);
local_irq_disable(); local_irq_disable();
sysdev_resume();
device_power_up(PMSG_RESUME); device_power_up(PMSG_RESUME);
local_irq_enable(); local_irq_enable();
} }
......
...@@ -88,8 +88,6 @@ extern void driver_detach(struct device_driver *drv); ...@@ -88,8 +88,6 @@ extern void driver_detach(struct device_driver *drv);
extern int driver_probe_device(struct device_driver *drv, struct device *dev); extern int driver_probe_device(struct device_driver *drv, struct device *dev);
extern void sysdev_shutdown(void); extern void sysdev_shutdown(void);
extern int sysdev_suspend(pm_message_t state);
extern int sysdev_resume(void);
extern char *make_class_name(const char *name, struct kobject *kobj); extern char *make_class_name(const char *name, struct kobject *kobj);
......
...@@ -333,7 +333,6 @@ static void dpm_power_up(pm_message_t state) ...@@ -333,7 +333,6 @@ static void dpm_power_up(pm_message_t state)
*/ */
void device_power_up(pm_message_t state) void device_power_up(pm_message_t state)
{ {
sysdev_resume();
dpm_power_up(state); dpm_power_up(state);
} }
EXPORT_SYMBOL_GPL(device_power_up); EXPORT_SYMBOL_GPL(device_power_up);
...@@ -577,8 +576,6 @@ int device_power_down(pm_message_t state) ...@@ -577,8 +576,6 @@ int device_power_down(pm_message_t state)
} }
dev->power.status = DPM_OFF_IRQ; dev->power.status = DPM_OFF_IRQ;
} }
if (!error)
error = sysdev_suspend(state);
if (error) if (error)
dpm_power_up(resume_event(state)); dpm_power_up(resume_event(state));
return error; return error;
......
...@@ -45,6 +45,13 @@ static int xen_suspend(void *data) ...@@ -45,6 +45,13 @@ static int xen_suspend(void *data)
err); err);
return err; return err;
} }
err = sysdev_suspend(PMSG_SUSPEND);
if (err) {
printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
err);
device_power_up(PMSG_RESUME);
return err;
}
xen_mm_pin_all(); xen_mm_pin_all();
gnttab_suspend(); gnttab_suspend();
...@@ -61,6 +68,7 @@ static int xen_suspend(void *data) ...@@ -61,6 +68,7 @@ static int xen_suspend(void *data)
gnttab_resume(); gnttab_resume();
xen_mm_unpin_all(); xen_mm_unpin_all();
sysdev_resume();
device_power_up(PMSG_RESUME); device_power_up(PMSG_RESUME);
if (!*cancelled) { if (!*cancelled) {
......
...@@ -381,10 +381,12 @@ struct dev_pm_info { ...@@ -381,10 +381,12 @@ struct dev_pm_info {
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
extern void device_pm_lock(void); extern void device_pm_lock(void);
extern int sysdev_resume(void);
extern void device_power_up(pm_message_t state); extern void device_power_up(pm_message_t state);
extern void device_resume(pm_message_t state); extern void device_resume(pm_message_t state);
extern void device_pm_unlock(void); extern void device_pm_unlock(void);
extern int sysdev_suspend(pm_message_t state);
extern int device_power_down(pm_message_t state); extern int device_power_down(pm_message_t state);
extern int device_suspend(pm_message_t state); extern int device_suspend(pm_message_t state);
extern int device_prepare_suspend(pm_message_t state); extern int device_prepare_suspend(pm_message_t state);
......
...@@ -1465,6 +1465,11 @@ int kernel_kexec(void) ...@@ -1465,6 +1465,11 @@ int kernel_kexec(void)
error = device_power_down(PMSG_FREEZE); error = device_power_down(PMSG_FREEZE);
if (error) if (error)
goto Enable_irqs; goto Enable_irqs;
/* Suspend system devices */
error = sysdev_suspend(PMSG_FREEZE);
if (error)
goto Power_up_devices;
} else } else
#endif #endif
{ {
...@@ -1477,6 +1482,8 @@ int kernel_kexec(void) ...@@ -1477,6 +1482,8 @@ int kernel_kexec(void)
#ifdef CONFIG_KEXEC_JUMP #ifdef CONFIG_KEXEC_JUMP
if (kexec_image->preserve_context) { if (kexec_image->preserve_context) {
sysdev_resume();
Power_up_devices:
device_power_up(PMSG_RESTORE); device_power_up(PMSG_RESTORE);
Enable_irqs: Enable_irqs:
local_irq_enable(); local_irq_enable();
......
...@@ -227,6 +227,12 @@ static int create_image(int platform_mode) ...@@ -227,6 +227,12 @@ static int create_image(int platform_mode)
"aborting hibernation\n"); "aborting hibernation\n");
goto Enable_irqs; goto Enable_irqs;
} }
sysdev_suspend(PMSG_FREEZE);
if (error) {
printk(KERN_ERR "PM: Some devices failed to power down, "
"aborting hibernation\n");
goto Power_up_devices;
}
if (hibernation_test(TEST_CORE)) if (hibernation_test(TEST_CORE))
goto Power_up; goto Power_up;
...@@ -242,9 +248,11 @@ static int create_image(int platform_mode) ...@@ -242,9 +248,11 @@ static int create_image(int platform_mode)
if (!in_suspend) if (!in_suspend)
platform_leave(platform_mode); platform_leave(platform_mode);
Power_up: Power_up:
sysdev_resume();
/* NOTE: device_power_up() is just a resume() for devices /* NOTE: device_power_up() is just a resume() for devices
* that suspended with irqs off ... no overall powerup. * that suspended with irqs off ... no overall powerup.
*/ */
Power_up_devices:
device_power_up(in_suspend ? device_power_up(in_suspend ?
(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
Enable_irqs: Enable_irqs:
...@@ -335,6 +343,7 @@ static int resume_target_kernel(void) ...@@ -335,6 +343,7 @@ static int resume_target_kernel(void)
"aborting resume\n"); "aborting resume\n");
goto Enable_irqs; goto Enable_irqs;
} }
sysdev_suspend(PMSG_QUIESCE);
/* We'll ignore saved state, but this gets preempt count (etc) right */ /* We'll ignore saved state, but this gets preempt count (etc) right */
save_processor_state(); save_processor_state();
error = restore_highmem(); error = restore_highmem();
...@@ -357,6 +366,7 @@ static int resume_target_kernel(void) ...@@ -357,6 +366,7 @@ static int resume_target_kernel(void)
swsusp_free(); swsusp_free();
restore_processor_state(); restore_processor_state();
touch_softlockup_watchdog(); touch_softlockup_watchdog();
sysdev_resume();
device_power_up(PMSG_RECOVER); device_power_up(PMSG_RECOVER);
Enable_irqs: Enable_irqs:
local_irq_enable(); local_irq_enable();
...@@ -440,6 +450,7 @@ int hibernation_platform_enter(void) ...@@ -440,6 +450,7 @@ int hibernation_platform_enter(void)
local_irq_disable(); local_irq_disable();
error = device_power_down(PMSG_HIBERNATE); error = device_power_down(PMSG_HIBERNATE);
if (!error) { if (!error) {
sysdev_suspend(PMSG_HIBERNATE);
hibernation_ops->enter(); hibernation_ops->enter();
/* We should never get here */ /* We should never get here */
while (1); while (1);
......
...@@ -298,8 +298,12 @@ static int suspend_enter(suspend_state_t state) ...@@ -298,8 +298,12 @@ static int suspend_enter(suspend_state_t state)
goto Done; goto Done;
} }
if (!suspend_test(TEST_CORE)) error = sysdev_suspend(PMSG_SUSPEND);
error = suspend_ops->enter(state); if (!error) {
if (!suspend_test(TEST_CORE))
error = suspend_ops->enter(state);
sysdev_resume();
}
device_power_up(PMSG_RESUME); device_power_up(PMSG_RESUME);
Done: Done:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment