diff options
author | Colin Cross <ccross@android.com> | 2011-06-29 13:56:43 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2011-06-29 13:56:43 -0700 |
commit | 5828e87bbcb3ae1c7741cae1c62b44e4979df429 (patch) | |
tree | 2b678fc60cdeb294435dee64d551cbd03430804d /drivers/base | |
parent | b10049da714e57153cacb7e31efc41a8ba0ae5d2 (diff) | |
parent | e55d4fa96762fd767a3b6d842c904e994db6bb2e (diff) | |
download | kernel_samsung_tuna-5828e87bbcb3ae1c7741cae1c62b44e4979df429.zip kernel_samsung_tuna-5828e87bbcb3ae1c7741cae1c62b44e4979df429.tar.gz kernel_samsung_tuna-5828e87bbcb3ae1c7741cae1c62b44e4979df429.tar.bz2 |
Merge branch 'android-3.0' into android-omap-3.0
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/clock_ops.c | 4 | ||||
-rw-r--r-- | drivers/base/power/main.c | 31 |
2 files changed, 24 insertions, 11 deletions
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index eaa8a85..ad367c4 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -387,7 +387,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, clknb = container_of(nb, struct pm_clk_notifier_block, nb); switch (action) { - case BUS_NOTIFY_ADD_DEVICE: + case BUS_NOTIFY_BIND_DRIVER: if (clknb->con_ids[0]) { for (con_id = clknb->con_ids; *con_id; con_id++) enable_clock(dev, *con_id); @@ -395,7 +395,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, enable_clock(dev, NULL); } break; - case BUS_NOTIFY_DEL_DEVICE: + case BUS_NOTIFY_UNBOUND_DRIVER: if (clknb->con_ids[0]) { for (con_id = clknb->con_ids; *con_id; con_id++) disable_clock(dev, *con_id); diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 5720943..4282d44 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -64,7 +64,8 @@ static int async_error; */ void device_pm_init(struct device *dev) { - dev->power.in_suspend = false; + dev->power.is_prepared = false; + dev->power.is_suspended = false; init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; @@ -98,7 +99,7 @@ void device_pm_add(struct device *dev) pr_debug("PM: Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); mutex_lock(&dpm_list_mtx); - if (dev->parent && dev->parent->power.in_suspend) + if (dev->parent && dev->parent->power.is_prepared) dev_warn(dev, "parent %s should not be sleeping\n", dev_name(dev->parent)); list_add_tail(&dev->power.entry, &dpm_list); @@ -515,11 +516,17 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) TRACE_DEVICE(dev); TRACE_RESUME(0); - if (dev->parent && dev->parent->power.in_suspend) - dpm_wait(dev->parent, async); + dpm_wait(dev->parent, async); device_lock(dev); - dev->power.in_suspend = false; + /* + * This is a fib. But we'll allow new children to be added below + * a resumed device, even if the device hasn't been completed yet. + */ + dev->power.is_prepared = false; + + if (!dev->power.is_suspended) + goto Unlock; if (dev->pwr_domain) { pm_dev_dbg(dev, state, "power domain "); @@ -556,6 +563,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) } End: + dev->power.is_suspended = false; + + Unlock: device_unlock(dev); complete_all(&dev->power.completion); @@ -702,7 +712,7 @@ void dpm_complete(pm_message_t state) struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); - dev->power.in_suspend = false; + dev->power.is_prepared = false; list_move(&dev->power.entry, &list); mutex_unlock(&dpm_list_mtx); @@ -878,11 +888,11 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) device_lock(dev); if (async_error) - goto End; + goto Unlock; if (pm_wakeup_pending()) { async_error = -EBUSY; - goto End; + goto Unlock; } if (dev->pwr_domain) { @@ -920,6 +930,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } End: + dev->power.is_suspended = !error; + + Unlock: device_unlock(dev); del_timer_sync(&timer); @@ -1089,7 +1102,7 @@ int dpm_prepare(pm_message_t state) put_device(dev); break; } - dev->power.in_suspend = true; + dev->power.is_prepared = true; if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); put_device(dev); |