summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorShridhar Rasal <srasal@nvidia.com>2013-11-19 12:45:45 +0530
committerSachin Nikam <snikam@nvidia.com>2013-12-25 21:28:29 -0800
commit813e42b9ba004632970153d645107d060018b79c (patch)
tree970c79956d81504d2d01381dfa91075a1fbe7518 /drivers/base
parenta0601537faa4493d8a3633ed27c97f3a1d3ee16c (diff)
PM/ runtime : Add WARN_ON for usage_cnt dec
- Added WARN_ON for usage count decrement when it is already zero. bug 1410313 Change-Id: I6ea8a1760d188b09c295eac6d8a63f74e2132ed8 Signed-off-by: Shridhar Rasal <srasal@nvidia.com> Reviewed-on: http://git-master/r/332797 Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/runtime.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index b43424c3ea0d..c7e60041fbfb 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
* Copyright (C) 2010 Alan Stern <stern@rowland.harvard.edu>
+ * Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
*
* This file is released under the GPLv2.
*/
@@ -873,6 +874,21 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay)
}
EXPORT_SYMBOL_GPL(pm_schedule_suspend);
+static bool pm_runtime_usage_cnt_dec(struct device *dev, bool test)
+{
+ bool ret = false;
+
+ if (!WARN_ON(atomic_read(&dev->power.usage_count) == 0)) {
+ if (test)
+ ret = !!atomic_dec_and_test(&dev->power.usage_count);
+ else
+ atomic_dec(&dev->power.usage_count);
+ } else {
+ dev_warn(dev, "Unexpected usage count decrement\n");
+ }
+ return ret;
+}
+
/**
* __pm_runtime_idle - Entry point for runtime idle operations.
* @dev: Device to send idle notification for.
@@ -893,7 +909,7 @@ int __pm_runtime_idle(struct device *dev, int rpmflags)
might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
if (rpmflags & RPM_GET_PUT) {
- if (!atomic_dec_and_test(&dev->power.usage_count))
+ if (!pm_runtime_usage_cnt_dec(dev, 1))
return 0;
}
@@ -925,7 +941,7 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags)
might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
if (rpmflags & RPM_GET_PUT) {
- if (!atomic_dec_and_test(&dev->power.usage_count))
+ if (!pm_runtime_usage_cnt_dec(dev, 1))
return 0;
}
@@ -1232,7 +1248,7 @@ void pm_runtime_allow(struct device *dev)
goto out;
dev->power.runtime_auto = true;
- if (atomic_dec_and_test(&dev->power.usage_count))
+ pm_runtime_usage_cnt_dec(dev, 1);
rpm_idle(dev, RPM_AUTO);
out:
@@ -1309,7 +1325,7 @@ static void update_autosuspend(struct device *dev, int old_delay, int old_use)
/* If it used to be prevented then allow it. */
if (old_use && old_delay < 0)
- atomic_dec(&dev->power.usage_count);
+ pm_runtime_usage_cnt_dec(dev, 0);
/* Maybe we can autosuspend now. */
rpm_idle(dev, RPM_AUTO);