aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-12-16 20:54:26 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-12-20 21:11:12 -0500
commita436b6a19f57656a6557439523923d89eb4a880d (patch)
tree62637a13b7721a775f8aa2af4554c9fc3069f595
parentd89d7ff9edf58cbf8ad0f490694b2edea8eb3a39 (diff)
PM / runtime: Add new helper for conditional usage count incrementation
Introduce a new runtime PM function, pm_runtime_get_if_in_use(), that will increment the device's runtime PM usage counter and return 1 if its status is RPM_ACTIVE and its usage counter is greater than 0 at the same time (0 will be returned otherwise). This is useful for things that should only be done if the device is active (from the runtime PM perspective) and used by somebody (as indicated by the usage counter) already and they are not worth bothering otherwise. Requested-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--Documentation/power/runtime_pm.txt6
-rw-r--r--drivers/base/power/runtime.c24
-rw-r--r--include/linux/pm_runtime.h5
3 files changed, 35 insertions, 0 deletions
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
index 0784bc3a2ab5..7328cf85236c 100644
--- a/Documentation/power/runtime_pm.txt
+++ b/Documentation/power/runtime_pm.txt
@@ -371,6 +371,12 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
371 - increment the device's usage counter, run pm_runtime_resume(dev) and 371 - increment the device's usage counter, run pm_runtime_resume(dev) and
372 return its result 372 return its result
373 373
374 int pm_runtime_get_if_in_use(struct device *dev);
375 - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the
376 runtime PM status is RPM_ACTIVE and the runtime PM usage counter is
377 nonzero, increment the counter and return 1; otherwise return 0 without
378 changing the counter
379
374 void pm_runtime_put_noidle(struct device *dev); 380 void pm_runtime_put_noidle(struct device *dev);
375 - decrement the device's usage counter 381 - decrement the device's usage counter
376 382
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index ab3fcd9f6c98..4c7055009bd6 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -966,6 +966,30 @@ int __pm_runtime_resume(struct device *dev, int rpmflags)
966EXPORT_SYMBOL_GPL(__pm_runtime_resume); 966EXPORT_SYMBOL_GPL(__pm_runtime_resume);
967 967
968/** 968/**
969 * pm_runtime_get_if_in_use - Conditionally bump up the device's usage counter.
970 * @dev: Device to handle.
971 *
972 * Return -EINVAL if runtime PM is disabled for the device.
973 *
974 * If that's not the case and if the device's runtime PM status is RPM_ACTIVE
975 * and the runtime PM usage counter is nonzero, increment the counter and
976 * return 1. Otherwise return 0 without changing the counter.
977 */
978int pm_runtime_get_if_in_use(struct device *dev)
979{
980 unsigned long flags;
981 int retval;
982
983 spin_lock_irqsave(&dev->power.lock, flags);
984 retval = dev->power.disable_depth > 0 ? -EINVAL :
985 dev->power.runtime_status == RPM_ACTIVE
986 && atomic_inc_not_zero(&dev->power.usage_count);
987 spin_unlock_irqrestore(&dev->power.lock, flags);
988 return retval;
989}
990EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use);
991
992/**
969 * __pm_runtime_set_status - Set runtime PM status of a device. 993 * __pm_runtime_set_status - Set runtime PM status of a device.
970 * @dev: Device to handle. 994 * @dev: Device to handle.
971 * @status: New runtime PM status of the device. 995 * @status: New runtime PM status of the device.
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 3bdbb4189780..7af093d6a4dd 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -39,6 +39,7 @@ extern int pm_runtime_force_resume(struct device *dev);
39extern int __pm_runtime_idle(struct device *dev, int rpmflags); 39extern int __pm_runtime_idle(struct device *dev, int rpmflags);
40extern int __pm_runtime_suspend(struct device *dev, int rpmflags); 40extern int __pm_runtime_suspend(struct device *dev, int rpmflags);
41extern int __pm_runtime_resume(struct device *dev, int rpmflags); 41extern int __pm_runtime_resume(struct device *dev, int rpmflags);
42extern int pm_runtime_get_if_in_use(struct device *dev);
42extern int pm_schedule_suspend(struct device *dev, unsigned int delay); 43extern int pm_schedule_suspend(struct device *dev, unsigned int delay);
43extern int __pm_runtime_set_status(struct device *dev, unsigned int status); 44extern int __pm_runtime_set_status(struct device *dev, unsigned int status);
44extern int pm_runtime_barrier(struct device *dev); 45extern int pm_runtime_barrier(struct device *dev);
@@ -143,6 +144,10 @@ static inline int pm_schedule_suspend(struct device *dev, unsigned int delay)
143{ 144{
144 return -ENOSYS; 145 return -ENOSYS;
145} 146}
147static inline int pm_runtime_get_if_in_use(struct device *dev)
148{
149 return -EINVAL;
150}
146static inline int __pm_runtime_set_status(struct device *dev, 151static inline int __pm_runtime_set_status(struct device *dev,
147 unsigned int status) { return 0; } 152 unsigned int status) { return 0; }
148static inline int pm_runtime_barrier(struct device *dev) { return 0; } 153static inline int pm_runtime_barrier(struct device *dev) { return 0; }