diff options
author | Shridhar Rasal <srasal@nvidia.com> | 2013-11-19 12:45:45 +0530 |
---|---|---|
committer | Sachin Nikam <snikam@nvidia.com> | 2013-12-25 21:28:29 -0800 |
commit | 813e42b9ba004632970153d645107d060018b79c (patch) | |
tree | 970c79956d81504d2d01381dfa91075a1fbe7518 /drivers/base | |
parent | a0601537faa4493d8a3633ed27c97f3a1d3ee16c (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.c | 24 |
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); |