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); | |||
| 22 | 22 | ||
| 23 | int resume_device(struct device * dev) | 23 | int resume_device(struct device * dev) |
| 24 | { | 24 | { |
| 25 | int error = 0; | ||
| 26 | |||
| 27 | down(&dev->sem); | ||
| 25 | if (dev->power.pm_parent | 28 | if (dev->power.pm_parent |
| 26 | && dev->power.pm_parent->power.power_state) { | 29 | && dev->power.pm_parent->power.power_state) { |
| 27 | dev_err(dev, "PM: resume from %d, parent %s still %d\n", | 30 | dev_err(dev, "PM: resume from %d, parent %s still %d\n", |
| @@ -31,9 +34,10 @@ int resume_device(struct device * dev) | |||
| 31 | } | 34 | } |
| 32 | if (dev->bus && dev->bus->resume) { | 35 | if (dev->bus && dev->bus->resume) { |
| 33 | dev_dbg(dev,"resuming\n"); | 36 | dev_dbg(dev,"resuming\n"); |
| 34 | return dev->bus->resume(dev); | 37 | error = dev->bus->resume(dev); |
| 35 | } | 38 | } |
| 36 | return 0; | 39 | up(&dev->sem); |
| 40 | return error; | ||
| 37 | } | 41 | } |
| 38 | 42 | ||
| 39 | 43 | ||
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) | |||
| 39 | { | 39 | { |
| 40 | int error = 0; | 40 | int error = 0; |
| 41 | 41 | ||
| 42 | down(&dev->sem); | ||
| 42 | if (dev->power.power_state) { | 43 | if (dev->power.power_state) { |
| 43 | dev_dbg(dev, "PM: suspend %d-->%d\n", | 44 | dev_dbg(dev, "PM: suspend %d-->%d\n", |
| 44 | dev->power.power_state, state); | 45 | dev->power.power_state, state); |
| @@ -58,7 +59,7 @@ int suspend_device(struct device * dev, pm_message_t state) | |||
| 58 | dev_dbg(dev, "suspending\n"); | 59 | dev_dbg(dev, "suspending\n"); |
| 59 | error = dev->bus->suspend(dev, state); | 60 | error = dev->bus->suspend(dev, state); |
| 60 | } | 61 | } |
| 61 | 62 | up(&dev->sem); | |
| 62 | return error; | 63 | return error; |
| 63 | } | 64 | } |
| 64 | 65 | ||
| @@ -113,8 +114,19 @@ int device_suspend(pm_message_t state) | |||
| 113 | put_device(dev); | 114 | put_device(dev); |
| 114 | } | 115 | } |
| 115 | up(&dpm_list_sem); | 116 | up(&dpm_list_sem); |
| 116 | if (error) | 117 | if (error) { |
| 118 | /* we failed... before resuming, bring back devices from | ||
| 119 | * dpm_off_irq list back to main dpm_off list, we do want | ||
| 120 | * to call resume() on them, in case they partially suspended | ||
| 121 | * despite returning -EAGAIN | ||
| 122 | */ | ||
| 123 | while (!list_empty(&dpm_off_irq)) { | ||
| 124 | struct list_head * entry = dpm_off_irq.next; | ||
| 125 | list_del(entry); | ||
| 126 | list_add(entry, &dpm_off); | ||
| 127 | } | ||
| 117 | dpm_resume(); | 128 | dpm_resume(); |
| 129 | } | ||
| 118 | up(&dpm_sem); | 130 | up(&dpm_sem); |
| 119 | return error; | 131 | return error; |
| 120 | } | 132 | } |
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 @@ | |||
| 24 | * low-power state. | 24 | * low-power state. |
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | static ssize_t state_show(struct device * dev, char * buf) | 27 | static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) |
| 28 | { | 28 | { |
| 29 | return sprintf(buf, "%u\n", dev->power.power_state); | 29 | return sprintf(buf, "%u\n", dev->power.power_state); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | static ssize_t state_store(struct device * dev, const char * buf, size_t n) | 32 | static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) |
| 33 | { | 33 | { |
| 34 | u32 state; | 34 | u32 state; |
| 35 | char * rest; | 35 | char * rest; |
