[PATCH] Device runtime suspend/resume fixes

From: Todd Poynor
Date: Tue May 25 2004 - 19:14:43 EST


(1) Set device power state at runtime resume (as is done for runtime
suspend) so that a later suspend does not think the device is still
suspended (refusing to suspend it again).

(2) Move devices from the active list to the off list only when
suspending all devices as part of a system suspend, not for runtime
suspend. This matches the resume code, which only moves devices from
off to active during system resume, such that runtime resume currently
doesn't move the suspended device back to the active list. (This also
avoids reordering the device list for runtime suspends; the list is in
order of registration and suspend/resume works best that way -- granted,
more sweeping improvements in how device dependencies are accounted for
in the suspend/resume order are also needed someday.)

Runtime device suspend/resume is in some cases used frequently on
battery-powered embedded devices, to save additional power and to handle
device power state interactions with overall system power state on
certain platforms.

--- linux-2.6.6-orig/drivers/base/power/suspend.c 2004-05-10 11:22:58.000000000 -0700
+++ linux-2.6.6-pm/drivers/base/power/suspend.c 2004-05-23 00:07:51.000000000 -0700
@@ -42,13 +42,6 @@
if (dev->bus && dev->bus->suspend)
error = dev->bus->suspend(dev,state);

- if (!error) {
- list_del(&dev->power.entry);
- list_add(&dev->power.entry,&dpm_off);
- } else if (error == -EAGAIN) {
- list_del(&dev->power.entry);
- list_add(&dev->power.entry,&dpm_off_irq);
- }
return error;
}

@@ -81,12 +74,16 @@
while(!list_empty(&dpm_active)) {
struct list_head * entry = dpm_active.prev;
struct device * dev = to_device(entry);
- if ((error = suspend_device(dev,state))) {
- if (error != -EAGAIN)
- goto Error;
- else
- error = 0;
- }
+ error = suspend_device(dev,state);
+
+ if (!error) {
+ list_del(&dev->power.entry);
+ list_add(&dev->power.entry,&dpm_off);
+ } else if (error == -EAGAIN) {
+ list_del(&dev->power.entry);
+ list_add(&dev->power.entry,&dpm_off_irq);
+ } else
+ goto Error;
}
Done:
up(&dpm_sem);

--- linux-2.6.6-orig/drivers/base/power/runtime.c 2004-05-10 11:22:58.000000000 -0700
+++ linux-2.6.6-pm/drivers/base/power/runtime.c 2004-05-25 16:07:57.254838016 -0700
@@ -12,9 +12,14 @@

static void runtime_resume(struct device * dev)
{
+ int error;
+
if (!dev->power.power_state)
return;
- resume_device(dev);
+ if (!(error = resume_device(dev)))
+ dev->power.power_state = 0;
+
+ return error;
}

--
Todd
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/