diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2012-06-16 15:20:11 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-07-03 19:06:25 +0200 |
commit | 6e797a078824b30afbfae6cc4b1c2b21c51761ef (patch) | |
tree | 7f58824b2c1e62b954683900024a5b97a4d30b4d /drivers/cpuidle | |
parent | cpuidle: move field disable from per-driver to per-cpu (diff) | |
download | linux-6e797a078824b30afbfae6cc4b1c2b21c51761ef.tar.xz linux-6e797a078824b30afbfae6cc4b1c2b21c51761ef.zip |
PM / cpuidle: Add driver reference counter
Add a reference counter for the cpuidle driver, so that it can't
be unregistered when it is in use.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r-- | drivers/cpuidle/driver.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 40cd3f3024df..58bf3b1ac9c4 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -16,6 +16,7 @@ static struct cpuidle_driver *cpuidle_curr_driver; DEFINE_SPINLOCK(cpuidle_driver_lock); +int cpuidle_driver_refcount; static void __cpuidle_register_driver(struct cpuidle_driver *drv) { @@ -89,8 +90,34 @@ void cpuidle_unregister_driver(struct cpuidle_driver *drv) } spin_lock(&cpuidle_driver_lock); - cpuidle_curr_driver = NULL; + + if (!WARN_ON(cpuidle_driver_refcount > 0)) + cpuidle_curr_driver = NULL; + spin_unlock(&cpuidle_driver_lock); } EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); + +struct cpuidle_driver *cpuidle_driver_ref(void) +{ + struct cpuidle_driver *drv; + + spin_lock(&cpuidle_driver_lock); + + drv = cpuidle_curr_driver; + cpuidle_driver_refcount++; + + spin_unlock(&cpuidle_driver_lock); + return drv; +} + +void cpuidle_driver_unref(void) +{ + spin_lock(&cpuidle_driver_lock); + + if (!WARN_ON(cpuidle_driver_refcount <= 0)) + cpuidle_driver_refcount--; + + spin_unlock(&cpuidle_driver_lock); +} |