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: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
936577c61d
commit
770824bdc4
|
@ -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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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);
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
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 {
|
||||||
|
|
||||||
#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)
|
||||||
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)
|
||||||
|
|
||||||
#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)
|
||||||
"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)
|
||||||
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)
|
||||||
"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)
|
||||||
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)
|
||||||
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)
|
||||||
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:
|
||||||
|
|
Loading…
Reference in New Issue