diff options
author | Patrick McHardy <kaber@trash.net> | 2011-01-14 14:12:37 +0100 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2011-01-14 14:12:37 +0100 |
commit | 0134e89c7bcc9fde1da962c82a120691e185619f (patch) | |
tree | 3e03335cf001019a2687d161e956de4f73379984 /drivers/base/power/main.c | |
parent | c7066f70d9610df0b9406cc635fc09e86136e714 (diff) | |
parent | 6faee60a4e82075853a437831768cc9e2e563e4e (diff) |
Merge branch 'master' of git://1984.lsi.us.es/net-next-2.6
Conflicts:
net/ipv4/route.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'drivers/base/power/main.c')
-rw-r--r-- | drivers/base/power/main.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 31b526661ec..ead3e79d6fc 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -475,20 +475,33 @@ End: */ void dpm_resume_noirq(pm_message_t state) { - struct device *dev; + struct list_head list; ktime_t starttime = ktime_get(); + INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); transition_started = false; - list_for_each_entry(dev, &dpm_list, power.entry) + while (!list_empty(&dpm_list)) { + struct device *dev = to_device(dpm_list.next); + + get_device(dev); if (dev->power.status > DPM_OFF) { int error; dev->power.status = DPM_OFF; + mutex_unlock(&dpm_list_mtx); + error = device_resume_noirq(dev, state); + + mutex_lock(&dpm_list_mtx); if (error) pm_dev_err(dev, state, " early", error); } + if (!list_empty(&dev->power.entry)) + list_move_tail(&dev->power.entry, &list); + put_device(dev); + } + list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); dpm_show_time(starttime, state, "early"); resume_device_irqs(); @@ -789,20 +802,33 @@ End: */ int dpm_suspend_noirq(pm_message_t state) { - struct device *dev; + struct list_head list; ktime_t starttime = ktime_get(); int error = 0; + INIT_LIST_HEAD(&list); suspend_device_irqs(); mutex_lock(&dpm_list_mtx); - list_for_each_entry_reverse(dev, &dpm_list, power.entry) { + while (!list_empty(&dpm_list)) { + struct device *dev = to_device(dpm_list.prev); + + get_device(dev); + mutex_unlock(&dpm_list_mtx); + error = device_suspend_noirq(dev, state); + + mutex_lock(&dpm_list_mtx); if (error) { pm_dev_err(dev, state, " late", error); + put_device(dev); break; } dev->power.status = DPM_OFF_IRQ; + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &list); + put_device(dev); } + list_splice_tail(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); if (error) dpm_resume_noirq(resume_event(state)); |