diff options
Diffstat (limited to 'drivers/base/power/qos.c')
| -rw-r--r-- | drivers/base/power/qos.c | 61 | 
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 @@  #include <linux/mutex.h>  #include <linux/export.h> +#include "power.h"  static DEFINE_MUTEX(dev_pm_qos_mtx); @@ -166,6 +167,12 @@ void dev_pm_qos_constraints_destroy(struct device *dev)  	struct dev_pm_qos_request *req, *tmp;  	struct pm_qos_constraints *c; +	/* +	 * If the device's PM QoS resume latency limit has been exposed to user +	 * space, it has to be hidden at this point. +	 */ +	dev_pm_qos_hide_latency_limit(dev); +  	mutex_lock(&dev_pm_qos_mtx);  	dev->power.power_state = PMSG_INVALID; @@ -445,3 +452,57 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,  	return error;  }  EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); + +#ifdef CONFIG_PM_RUNTIME +static void __dev_pm_qos_drop_user_request(struct device *dev) +{ +	dev_pm_qos_remove_request(dev->power.pq_req); +	dev->power.pq_req = 0; +} + +/** + * dev_pm_qos_expose_latency_limit - Expose PM QoS latency limit to user space. + * @dev: Device whose PM QoS latency limit is to be exposed to user space. + * @value: Initial value of the latency limit. + */ +int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) +{ +	struct dev_pm_qos_request *req; +	int ret; + +	if (!device_is_registered(dev) || value < 0) +		return -EINVAL; + +	if (dev->power.pq_req) +		return -EEXIST; + +	req = kzalloc(sizeof(*req), GFP_KERNEL); +	if (!req) +		return -ENOMEM; + +	ret = dev_pm_qos_add_request(dev, req, value); +	if (ret < 0) +		return ret; + +	dev->power.pq_req = req; +	ret = pm_qos_sysfs_add(dev); +	if (ret) +		__dev_pm_qos_drop_user_request(dev); + +	return ret; +} +EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); + +/** + * dev_pm_qos_hide_latency_limit - Hide PM QoS latency limit from user space. + * @dev: Device whose PM QoS latency limit is to be hidden from user space. + */ +void dev_pm_qos_hide_latency_limit(struct device *dev) +{ +	if (dev->power.pq_req) { +		pm_qos_sysfs_remove(dev); +		__dev_pm_qos_drop_user_request(dev); +	} +} +EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit); +#endif /* CONFIG_PM_RUNTIME */ | 
