diff options
Diffstat (limited to 'drivers/base/power')
-rw-r--r-- | drivers/base/power/resume.c | 8 | ||||
-rw-r--r-- | drivers/base/power/suspend.c | 16 | ||||
-rw-r--r-- | drivers/base/power/sysfs.c | 4 |
3 files changed, 22 insertions, 6 deletions
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index 26468971ef5a..bdd96b03b885 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c @@ -22,6 +22,9 @@ extern int sysdev_resume(void); int resume_device(struct device * dev) { + int error = 0; + + down(&dev->sem); if (dev->power.pm_parent && dev->power.pm_parent->power.power_state) { dev_err(dev, "PM: resume from %d, parent %s still %d\n", @@ -31,9 +34,10 @@ int resume_device(struct device * dev) } if (dev->bus && dev->bus->resume) { dev_dbg(dev,"resuming\n"); - return dev->bus->resume(dev); + error = dev->bus->resume(dev); } - return 0; + up(&dev->sem); + return error; } diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 0ec44ef840be..2ccee3763acf 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c @@ -39,6 +39,7 @@ int suspend_device(struct device * dev, pm_message_t state) { int error = 0; + down(&dev->sem); if (dev->power.power_state) { dev_dbg(dev, "PM: suspend %d-->%d\n", dev->power.power_state, state); @@ -58,7 +59,7 @@ int suspend_device(struct device * dev, pm_message_t state) dev_dbg(dev, "suspending\n"); error = dev->bus->suspend(dev, state); } - + up(&dev->sem); return error; } @@ -113,8 +114,19 @@ int device_suspend(pm_message_t state) put_device(dev); } up(&dpm_list_sem); - if (error) + if (error) { + /* we failed... before resuming, bring back devices from + * dpm_off_irq list back to main dpm_off list, we do want + * to call resume() on them, in case they partially suspended + * despite returning -EAGAIN + */ + while (!list_empty(&dpm_off_irq)) { + struct list_head * entry = dpm_off_irq.next; + list_del(entry); + list_add(entry, &dpm_off); + } dpm_resume(); + } up(&dpm_sem); return error; } diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 6ac96349a8e8..f82b3df9545f 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -24,12 +24,12 @@ * low-power state. */ -static ssize_t state_show(struct device * dev, char * buf) +static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) { return sprintf(buf, "%u\n", dev->power.power_state); } -static ssize_t state_store(struct device * dev, const char * buf, size_t n) +static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) { u32 state; char * rest; |