aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/qos.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-03-12 20:01:39 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-03-13 17:37:14 -0400
commit85dc0b8a4019e38ad4fd0c008f89a5c241805ac2 (patch)
treea73c5864d8ce4a6845e616ade7b8107e181279b6 /drivers/base/power/qos.c
parenta9b542ee607a8afafa9447292394959fc84ea650 (diff)
PM / QoS: Make it possible to expose PM QoS latency constraints
A runtime suspend of a device (e.g. an MMC controller) belonging to a power domain or, in a more complicated scenario, a runtime suspend of another device in the same power domain, may cause power to be removed from the entire domain. In that case, the amount of time necessary to runtime-resume the given device (e.g. the MMC controller) is often substantially greater than the time needed to run its driver's runtime resume callback. That may hurt performance in some situations, because user data may need to wait for the device to become operational, so we should make it possible to prevent that from happening. For this reason, introduce a new sysfs attribute for devices, power/pm_qos_resume_latency_us, allowing user space to specify the upper bound of the time necessary to bring the (runtime-suspended) device up after the resume of it has been requested. However, make that attribute appear only for the devices whose drivers declare support for it by calling the (new) dev_pm_qos_expose_latency_limit() helper function with the appropriate initial value of the attribute. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Reviewed-by: Kevin Hilman <khilman@ti.com> Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/base/power/qos.c')
-rw-r--r--drivers/base/power/qos.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index c5d358837461..71855570922d 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -41,6 +41,7 @@
41#include <linux/mutex.h> 41#include <linux/mutex.h>
42#include <linux/export.h> 42#include <linux/export.h>
43 43
44#include "power.h"
44 45
45static DEFINE_MUTEX(dev_pm_qos_mtx); 46static DEFINE_MUTEX(dev_pm_qos_mtx);
46 47
@@ -166,6 +167,12 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
166 struct dev_pm_qos_request *req, *tmp; 167 struct dev_pm_qos_request *req, *tmp;
167 struct pm_qos_constraints *c; 168 struct pm_qos_constraints *c;
168 169
170 /*
171 * If the device's PM QoS resume latency limit has been exposed to user
172 * space, it has to be hidden at this point.
173 */
174 dev_pm_qos_hide_latency_limit(dev);
175
169 mutex_lock(&dev_pm_qos_mtx); 176 mutex_lock(&dev_pm_qos_mtx);
170 177
171 dev->power.power_state = PMSG_INVALID; 178 dev->power.power_state = PMSG_INVALID;
@@ -445,3 +452,57 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,
445 return error; 452 return error;
446} 453}
447EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); 454EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request);
455
456#ifdef CONFIG_PM_RUNTIME
457static void __dev_pm_qos_drop_user_request(struct device *dev)
458{
459 dev_pm_qos_remove_request(dev->power.pq_req);
460 dev->power.pq_req = 0;
461}
462
463/**
464 * dev_pm_qos_expose_latency_limit - Expose PM QoS latency limit to user space.
465 * @dev: Device whose PM QoS latency limit is to be exposed to user space.
466 * @value: Initial value of the latency limit.
467 */
468int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value)
469{
470 struct dev_pm_qos_request *req;
471 int ret;
472
473 if (!device_is_registered(dev) || value < 0)
474 return -EINVAL;
475
476 if (dev->power.pq_req)
477 return -EEXIST;
478
479 req = kzalloc(sizeof(*req), GFP_KERNEL);
480 if (!req)
481 return -ENOMEM;
482
483 ret = dev_pm_qos_add_request(dev, req, value);
484 if (ret < 0)
485 return ret;
486
487 dev->power.pq_req = req;
488 ret = pm_qos_sysfs_add(dev);
489 if (ret)
490 __dev_pm_qos_drop_user_request(dev);
491
492 return ret;
493}
494EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit);
495
496/**
497 * dev_pm_qos_hide_latency_limit - Hide PM QoS latency limit from user space.
498 * @dev: Device whose PM QoS latency limit is to be hidden from user space.
499 */
500void dev_pm_qos_hide_latency_limit(struct device *dev)
501{
502 if (dev->power.pq_req) {
503 pm_qos_sysfs_remove(dev);
504 __dev_pm_qos_drop_user_request(dev);
505 }
506}
507EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit);
508#endif /* CONFIG_PM_RUNTIME */