Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6: PM: Add empty suspend/resume device irq functions PM/Hibernate: Move NVS routines into a seperate file (v2). PM/Hibernate: Rename disk.c to hibernate.c PM: Separate suspend to RAM functionality from core Driver Core: Rework platform suspend/resume, print warning PM: Remove device_type suspend()/resume() PM/Hibernate: Move memory shrinking to snapshot.c (rev. 2) PM/Suspend: Do not shrink memory before suspend PM: Remove bus_type suspend_late()/resume_early() V2 PM core: rename suspend and resume functions PM: Rename device_power_down/up() PM: Remove unused asm/suspend.h x86: unify power/cpu_(32|64).c x86: unify power/cpu_(32|64) copyright notes x86: unify power/cpu_(32|64) regarding restoring processor state x86: unify power/cpu_(32|64) regarding saving processor state x86: unify power/cpu_(32|64) global variables x86: unify power/cpu_(32|64) headers PM: Warn if interrupts are enabled during suspend-resume of sysdevs PM/ACPI/x86: Fix sparse warning in arch/x86/kernel/acpi/sleep.c
This commit is contained in:
+12
-24
@@ -469,22 +469,6 @@ static void platform_drv_shutdown(struct device *_dev)
|
||||
drv->shutdown(dev);
|
||||
}
|
||||
|
||||
static int platform_drv_suspend(struct device *_dev, pm_message_t state)
|
||||
{
|
||||
struct platform_driver *drv = to_platform_driver(_dev->driver);
|
||||
struct platform_device *dev = to_platform_device(_dev);
|
||||
|
||||
return drv->suspend(dev, state);
|
||||
}
|
||||
|
||||
static int platform_drv_resume(struct device *_dev)
|
||||
{
|
||||
struct platform_driver *drv = to_platform_driver(_dev->driver);
|
||||
struct platform_device *dev = to_platform_device(_dev);
|
||||
|
||||
return drv->resume(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* platform_driver_register
|
||||
* @drv: platform driver structure
|
||||
@@ -498,10 +482,10 @@ int platform_driver_register(struct platform_driver *drv)
|
||||
drv->driver.remove = platform_drv_remove;
|
||||
if (drv->shutdown)
|
||||
drv->driver.shutdown = platform_drv_shutdown;
|
||||
if (drv->suspend)
|
||||
drv->driver.suspend = platform_drv_suspend;
|
||||
if (drv->resume)
|
||||
drv->driver.resume = platform_drv_resume;
|
||||
if (drv->suspend || drv->resume)
|
||||
pr_warning("Platform driver '%s' needs updating - please use "
|
||||
"dev_pm_ops\n", drv->driver.name);
|
||||
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_driver_register);
|
||||
@@ -633,10 +617,12 @@ static int platform_match(struct device *dev, struct device_driver *drv)
|
||||
|
||||
static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
|
||||
{
|
||||
struct platform_driver *pdrv = to_platform_driver(dev->driver);
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
int ret = 0;
|
||||
|
||||
if (dev->driver && dev->driver->suspend)
|
||||
ret = dev->driver->suspend(dev, mesg);
|
||||
if (dev->driver && pdrv->suspend)
|
||||
ret = pdrv->suspend(pdev, mesg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -667,10 +653,12 @@ static int platform_legacy_resume_early(struct device *dev)
|
||||
|
||||
static int platform_legacy_resume(struct device *dev)
|
||||
{
|
||||
struct platform_driver *pdrv = to_platform_driver(dev->driver);
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
int ret = 0;
|
||||
|
||||
if (dev->driver && dev->driver->resume)
|
||||
ret = dev->driver->resume(dev);
|
||||
if (dev->driver && pdrv->resume)
|
||||
ret = pdrv->resume(pdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
+34
-60
@@ -315,13 +315,13 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info,
|
||||
/*------------------------- Resume routines -------------------------*/
|
||||
|
||||
/**
|
||||
* resume_device_noirq - Power on one device (early resume).
|
||||
* device_resume_noirq - Power on one device (early resume).
|
||||
* @dev: Device.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*
|
||||
* Must be called with interrupts disabled.
|
||||
*/
|
||||
static int resume_device_noirq(struct device *dev, pm_message_t state)
|
||||
static int device_resume_noirq(struct device *dev, pm_message_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
@@ -334,9 +334,6 @@ static int resume_device_noirq(struct device *dev, pm_message_t state)
|
||||
if (dev->bus->pm) {
|
||||
pm_dev_dbg(dev, state, "EARLY ");
|
||||
error = pm_noirq_op(dev, dev->bus->pm, state);
|
||||
} else if (dev->bus->resume_early) {
|
||||
pm_dev_dbg(dev, state, "legacy EARLY ");
|
||||
error = dev->bus->resume_early(dev);
|
||||
}
|
||||
End:
|
||||
TRACE_RESUME(error);
|
||||
@@ -344,16 +341,16 @@ static int resume_device_noirq(struct device *dev, pm_message_t state)
|
||||
}
|
||||
|
||||
/**
|
||||
* dpm_power_up - Power on all regular (non-sysdev) devices.
|
||||
* dpm_resume_noirq - Power on all regular (non-sysdev) devices.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*
|
||||
* Execute the appropriate "noirq resume" callback for all devices marked
|
||||
* as DPM_OFF_IRQ.
|
||||
* Call the "noirq" resume handlers for all devices marked as
|
||||
* DPM_OFF_IRQ and enable device drivers to receive interrupts.
|
||||
*
|
||||
* Must be called under dpm_list_mtx. Device drivers should not receive
|
||||
* interrupts while it's being executed.
|
||||
*/
|
||||
static void dpm_power_up(pm_message_t state)
|
||||
void dpm_resume_noirq(pm_message_t state)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
@@ -363,33 +360,21 @@ static void dpm_power_up(pm_message_t state)
|
||||
int error;
|
||||
|
||||
dev->power.status = DPM_OFF;
|
||||
error = resume_device_noirq(dev, state);
|
||||
error = device_resume_noirq(dev, state);
|
||||
if (error)
|
||||
pm_dev_err(dev, state, " early", error);
|
||||
}
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
}
|
||||
|
||||
/**
|
||||
* device_power_up - Turn on all devices that need special attention.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*
|
||||
* Call the "early" resume handlers and enable device drivers to receive
|
||||
* interrupts.
|
||||
*/
|
||||
void device_power_up(pm_message_t state)
|
||||
{
|
||||
dpm_power_up(state);
|
||||
resume_device_irqs();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_power_up);
|
||||
EXPORT_SYMBOL_GPL(dpm_resume_noirq);
|
||||
|
||||
/**
|
||||
* resume_device - Restore state for one device.
|
||||
* device_resume - Restore state for one device.
|
||||
* @dev: Device.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*/
|
||||
static int resume_device(struct device *dev, pm_message_t state)
|
||||
static int device_resume(struct device *dev, pm_message_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
@@ -414,9 +399,6 @@ static int resume_device(struct device *dev, pm_message_t state)
|
||||
if (dev->type->pm) {
|
||||
pm_dev_dbg(dev, state, "type ");
|
||||
error = pm_op(dev, dev->type->pm, state);
|
||||
} else if (dev->type->resume) {
|
||||
pm_dev_dbg(dev, state, "legacy type ");
|
||||
error = dev->type->resume(dev);
|
||||
}
|
||||
if (error)
|
||||
goto End;
|
||||
@@ -462,7 +444,7 @@ static void dpm_resume(pm_message_t state)
|
||||
dev->power.status = DPM_RESUMING;
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
|
||||
error = resume_device(dev, state);
|
||||
error = device_resume(dev, state);
|
||||
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
if (error)
|
||||
@@ -480,11 +462,11 @@ static void dpm_resume(pm_message_t state)
|
||||
}
|
||||
|
||||
/**
|
||||
* complete_device - Complete a PM transition for given device
|
||||
* device_complete - Complete a PM transition for given device
|
||||
* @dev: Device.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*/
|
||||
static void complete_device(struct device *dev, pm_message_t state)
|
||||
static void device_complete(struct device *dev, pm_message_t state)
|
||||
{
|
||||
down(&dev->sem);
|
||||
|
||||
@@ -527,7 +509,7 @@ static void dpm_complete(pm_message_t state)
|
||||
dev->power.status = DPM_ON;
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
|
||||
complete_device(dev, state);
|
||||
device_complete(dev, state);
|
||||
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
}
|
||||
@@ -540,19 +522,19 @@ static void dpm_complete(pm_message_t state)
|
||||
}
|
||||
|
||||
/**
|
||||
* device_resume - Restore state of each device in system.
|
||||
* dpm_resume_end - Restore state of each device in system.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*
|
||||
* Resume all the devices, unlock them all, and allow new
|
||||
* devices to be registered once again.
|
||||
*/
|
||||
void device_resume(pm_message_t state)
|
||||
void dpm_resume_end(pm_message_t state)
|
||||
{
|
||||
might_sleep();
|
||||
dpm_resume(state);
|
||||
dpm_complete(state);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_resume);
|
||||
EXPORT_SYMBOL_GPL(dpm_resume_end);
|
||||
|
||||
|
||||
/*------------------------- Suspend routines -------------------------*/
|
||||
@@ -577,13 +559,13 @@ static pm_message_t resume_event(pm_message_t sleep_state)
|
||||
}
|
||||
|
||||
/**
|
||||
* suspend_device_noirq - Shut down one device (late suspend).
|
||||
* device_suspend_noirq - Shut down one device (late suspend).
|
||||
* @dev: Device.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*
|
||||
* This is called with interrupts off and only a single CPU running.
|
||||
*/
|
||||
static int suspend_device_noirq(struct device *dev, pm_message_t state)
|
||||
static int device_suspend_noirq(struct device *dev, pm_message_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
@@ -593,24 +575,20 @@ static int suspend_device_noirq(struct device *dev, pm_message_t state)
|
||||
if (dev->bus->pm) {
|
||||
pm_dev_dbg(dev, state, "LATE ");
|
||||
error = pm_noirq_op(dev, dev->bus->pm, state);
|
||||
} else if (dev->bus->suspend_late) {
|
||||
pm_dev_dbg(dev, state, "legacy LATE ");
|
||||
error = dev->bus->suspend_late(dev, state);
|
||||
suspend_report_result(dev->bus->suspend_late, error);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* device_power_down - Shut down special devices.
|
||||
* dpm_suspend_noirq - Power down all regular (non-sysdev) devices.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*
|
||||
* Prevent device drivers from receiving interrupts and call the "late"
|
||||
* Prevent device drivers from receiving interrupts and call the "noirq"
|
||||
* suspend handlers.
|
||||
*
|
||||
* Must be called under dpm_list_mtx.
|
||||
*/
|
||||
int device_power_down(pm_message_t state)
|
||||
int dpm_suspend_noirq(pm_message_t state)
|
||||
{
|
||||
struct device *dev;
|
||||
int error = 0;
|
||||
@@ -618,7 +596,7 @@ int device_power_down(pm_message_t state)
|
||||
suspend_device_irqs();
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
|
||||
error = suspend_device_noirq(dev, state);
|
||||
error = device_suspend_noirq(dev, state);
|
||||
if (error) {
|
||||
pm_dev_err(dev, state, " late", error);
|
||||
break;
|
||||
@@ -627,17 +605,17 @@ int device_power_down(pm_message_t state)
|
||||
}
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
if (error)
|
||||
device_power_up(resume_event(state));
|
||||
dpm_resume_noirq(resume_event(state));
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_power_down);
|
||||
EXPORT_SYMBOL_GPL(dpm_suspend_noirq);
|
||||
|
||||
/**
|
||||
* suspend_device - Save state of one device.
|
||||
* device_suspend - Save state of one device.
|
||||
* @dev: Device.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*/
|
||||
static int suspend_device(struct device *dev, pm_message_t state)
|
||||
static int device_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
@@ -660,10 +638,6 @@ static int suspend_device(struct device *dev, pm_message_t state)
|
||||
if (dev->type->pm) {
|
||||
pm_dev_dbg(dev, state, "type ");
|
||||
error = pm_op(dev, dev->type->pm, state);
|
||||
} else if (dev->type->suspend) {
|
||||
pm_dev_dbg(dev, state, "legacy type ");
|
||||
error = dev->type->suspend(dev, state);
|
||||
suspend_report_result(dev->type->suspend, error);
|
||||
}
|
||||
if (error)
|
||||
goto End;
|
||||
@@ -704,7 +678,7 @@ static int dpm_suspend(pm_message_t state)
|
||||
get_device(dev);
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
|
||||
error = suspend_device(dev, state);
|
||||
error = device_suspend(dev, state);
|
||||
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
if (error) {
|
||||
@@ -723,11 +697,11 @@ static int dpm_suspend(pm_message_t state)
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare_device - Execute the ->prepare() callback(s) for given device.
|
||||
* device_prepare - Execute the ->prepare() callback(s) for given device.
|
||||
* @dev: Device.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*/
|
||||
static int prepare_device(struct device *dev, pm_message_t state)
|
||||
static int device_prepare(struct device *dev, pm_message_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
@@ -781,7 +755,7 @@ static int dpm_prepare(pm_message_t state)
|
||||
dev->power.status = DPM_PREPARING;
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
|
||||
error = prepare_device(dev, state);
|
||||
error = device_prepare(dev, state);
|
||||
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
if (error) {
|
||||
@@ -807,12 +781,12 @@ static int dpm_prepare(pm_message_t state)
|
||||
}
|
||||
|
||||
/**
|
||||
* device_suspend - Save state and stop all devices in system.
|
||||
* dpm_suspend_start - Save state and stop all devices in system.
|
||||
* @state: PM transition of the system being carried out.
|
||||
*
|
||||
* Prepare and suspend all devices.
|
||||
*/
|
||||
int device_suspend(pm_message_t state)
|
||||
int dpm_suspend_start(pm_message_t state)
|
||||
{
|
||||
int error;
|
||||
|
||||
@@ -822,7 +796,7 @@ int device_suspend(pm_message_t state)
|
||||
error = dpm_suspend(state);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_suspend);
|
||||
EXPORT_SYMBOL_GPL(dpm_suspend_start);
|
||||
|
||||
void __suspend_report_result(const char *function, void *fn, int ret)
|
||||
{
|
||||
|
||||
@@ -343,11 +343,15 @@ static void __sysdev_resume(struct sys_device *dev)
|
||||
/* First, call the class-specific one */
|
||||
if (cls->resume)
|
||||
cls->resume(dev);
|
||||
WARN_ONCE(!irqs_disabled(),
|
||||
"Interrupts enabled after %pF\n", cls->resume);
|
||||
|
||||
/* Call auxillary drivers next. */
|
||||
list_for_each_entry(drv, &cls->drivers, entry) {
|
||||
if (drv->resume)
|
||||
drv->resume(dev);
|
||||
WARN_ONCE(!irqs_disabled(),
|
||||
"Interrupts enabled after %pF\n", drv->resume);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,6 +381,9 @@ int sysdev_suspend(pm_message_t state)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
WARN_ONCE(!irqs_disabled(),
|
||||
"Interrupts enabled while suspending system devices\n");
|
||||
|
||||
pr_debug("Suspending System Devices\n");
|
||||
|
||||
list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
|
||||
@@ -393,6 +400,9 @@ int sysdev_suspend(pm_message_t state)
|
||||
if (ret)
|
||||
goto aux_driver;
|
||||
}
|
||||
WARN_ONCE(!irqs_disabled(),
|
||||
"Interrupts enabled after %pF\n",
|
||||
drv->suspend);
|
||||
}
|
||||
|
||||
/* Now call the generic one */
|
||||
@@ -400,6 +410,9 @@ int sysdev_suspend(pm_message_t state)
|
||||
ret = cls->suspend(sysdev, state);
|
||||
if (ret)
|
||||
goto cls_driver;
|
||||
WARN_ONCE(!irqs_disabled(),
|
||||
"Interrupts enabled after %pF\n",
|
||||
cls->suspend);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,6 +465,9 @@ int sysdev_resume(void)
|
||||
{
|
||||
struct sysdev_class *cls;
|
||||
|
||||
WARN_ONCE(!irqs_disabled(),
|
||||
"Interrupts enabled while resuming system devices\n");
|
||||
|
||||
pr_debug("Resuming System Devices\n");
|
||||
|
||||
list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
|
||||
|
||||
@@ -43,7 +43,7 @@ static int xen_suspend(void *data)
|
||||
if (err) {
|
||||
printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
|
||||
err);
|
||||
device_power_up(PMSG_RESUME);
|
||||
dpm_resume_noirq(PMSG_RESUME);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ static int xen_suspend(void *data)
|
||||
}
|
||||
|
||||
sysdev_resume();
|
||||
device_power_up(PMSG_RESUME);
|
||||
dpm_resume_noirq(PMSG_RESUME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -92,18 +92,18 @@ static void do_suspend(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
err = device_suspend(PMSG_SUSPEND);
|
||||
err = dpm_suspend_start(PMSG_SUSPEND);
|
||||
if (err) {
|
||||
printk(KERN_ERR "xen suspend: device_suspend %d\n", err);
|
||||
printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
printk(KERN_DEBUG "suspending xenstore...\n");
|
||||
xs_suspend();
|
||||
|
||||
err = device_power_down(PMSG_SUSPEND);
|
||||
err = dpm_suspend_noirq(PMSG_SUSPEND);
|
||||
if (err) {
|
||||
printk(KERN_ERR "device_power_down failed: %d\n", err);
|
||||
printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
|
||||
goto resume_devices;
|
||||
}
|
||||
|
||||
@@ -119,10 +119,10 @@ static void do_suspend(void)
|
||||
} else
|
||||
xs_suspend_cancel();
|
||||
|
||||
device_power_up(PMSG_RESUME);
|
||||
dpm_resume_noirq(PMSG_RESUME);
|
||||
|
||||
resume_devices:
|
||||
device_resume(PMSG_RESUME);
|
||||
dpm_resume_end(PMSG_RESUME);
|
||||
|
||||
/* Make sure timer events get retriggered on all CPUs */
|
||||
clock_was_set();
|
||||
|
||||
Reference in New Issue
Block a user