diff options
author | Colin Cross <ccross@android.com> | 2011-08-10 11:41:59 -0500 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2011-09-23 20:08:51 -0700 |
commit | b1d0d5fe07a4c96d791f3126bbfc8d0131d1aa32 (patch) | |
tree | ca627d7b2417dceb578d742ed11d7ed7edc7edc7 | |
parent | 3e59ce0fde3735d6e35be08b3d766031913bfb68 (diff) | |
download | kernel_samsung_tuna-b1d0d5fe07a4c96d791f3126bbfc8d0131d1aa32.zip kernel_samsung_tuna-b1d0d5fe07a4c96d791f3126bbfc8d0131d1aa32.tar.gz kernel_samsung_tuna-b1d0d5fe07a4c96d791f3126bbfc8d0131d1aa32.tar.bz2 |
PM: runtime: add might_sleep to PM runtime functions
The list of functions that can be called in atomic context is
non-intuitive (pm_runtime_put_sync can not, but
pm_runtime_put_sync_suspend can, if pm_runtime_irq_safe has
been called?). The code is actively misleading - the entry
points all start with spin_lock_irqsave, suggesting they
are safe to call in atomic context, but may later
enable interrupts.
Add might_sleep_if to all the __pm_runtime_* entry points
to enforce correct usage.
Also add pm_runtime_put_sync_autosuspend to the list of
functions that can be called in atomic context.
Change-Id: Icac17a10d77c64d44bd2761a91a588dfd1d0c6f0
Signed-off-by: Colin Cross <ccross@android.com>
-rw-r--r-- | Documentation/power/runtime_pm.txt | 1 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 9 |
2 files changed, 10 insertions, 0 deletions
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index b24875b..22852b3 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -469,6 +469,7 @@ pm_runtime_autosuspend() pm_runtime_resume() pm_runtime_get_sync() pm_runtime_put_sync_suspend() +pm_runtime_put_sync_autosuspend() 5. Run-time PM Initialization, Device Probing and Removal diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 0d4587b..577f4fd 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -732,6 +732,8 @@ int __pm_runtime_idle(struct device *dev, int rpmflags) unsigned long flags; int retval; + might_sleep_if(!(rpmflags & RPM_ASYNC)); + if (rpmflags & RPM_GET_PUT) { if (!atomic_dec_and_test(&dev->power.usage_count)) return 0; @@ -761,6 +763,8 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags) unsigned long flags; int retval; + might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); + if (rpmflags & RPM_GET_PUT) { if (!atomic_dec_and_test(&dev->power.usage_count)) return 0; @@ -789,6 +793,8 @@ int __pm_runtime_resume(struct device *dev, int rpmflags) unsigned long flags; int retval; + might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); + if (rpmflags & RPM_GET_PUT) atomic_inc(&dev->power.usage_count); @@ -978,6 +984,7 @@ EXPORT_SYMBOL_GPL(pm_runtime_barrier); */ void __pm_runtime_disable(struct device *dev, bool check_resume) { + might_sleep(); spin_lock_irq(&dev->power.lock); if (dev->power.disable_depth > 0) { @@ -1184,6 +1191,8 @@ void __pm_runtime_use_autosuspend(struct device *dev, bool use) { int old_delay, old_use; + might_sleep(); + spin_lock_irq(&dev->power.lock); old_delay = dev->power.autosuspend_delay; old_use = dev->power.use_autosuspend; |