aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2015-07-27 11:03:56 -0400
committerLee Jones <lee.jones@linaro.org>2015-07-28 03:50:41 -0400
commit13b2c4a0c3b1cd37ee6bcfbb5b6e2b94e9a75364 (patch)
tree016216659f73b115aeaaa4ce712021dd67e2c551
parentbc0195aad0daa2ad5b0d76cce22b167bc3435590 (diff)
PM / QoS: Make it possible to expose device latency tolerance to userspace
Typically when a device is created the bus core it belongs to (for example PCI) does not know if the device supports things like latency tolerance. This is left to the driver that binds to the device in question. However, at that time the device has already been created and there is no way to set its dev->power.set_latency_tolerance anymore. So follow what has been done for other PM QoS attributes as well and allow drivers to expose and hide latency tolerance from userspace, if the device supports it. Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/base/power/power.h2
-rw-r--r--drivers/base/power/qos.c37
-rw-r--r--drivers/base/power/sysfs.c11
-rw-r--r--include/linux/pm_qos.h5
4 files changed, 55 insertions, 0 deletions
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index f1a5d95e7b20..998fa6b23084 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -73,6 +73,8 @@ extern int pm_qos_sysfs_add_resume_latency(struct device *dev);
73extern void pm_qos_sysfs_remove_resume_latency(struct device *dev); 73extern void pm_qos_sysfs_remove_resume_latency(struct device *dev);
74extern int pm_qos_sysfs_add_flags(struct device *dev); 74extern int pm_qos_sysfs_add_flags(struct device *dev);
75extern void pm_qos_sysfs_remove_flags(struct device *dev); 75extern void pm_qos_sysfs_remove_flags(struct device *dev);
76extern int pm_qos_sysfs_add_latency_tolerance(struct device *dev);
77extern void pm_qos_sysfs_remove_latency_tolerance(struct device *dev);
76 78
77#else /* CONFIG_PM */ 79#else /* CONFIG_PM */
78 80
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index e56d538d039e..7f3646e459cb 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -883,3 +883,40 @@ int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val)
883 mutex_unlock(&dev_pm_qos_mtx); 883 mutex_unlock(&dev_pm_qos_mtx);
884 return ret; 884 return ret;
885} 885}
886
887/**
888 * dev_pm_qos_expose_latency_tolerance - Expose latency tolerance to userspace
889 * @dev: Device whose latency tolerance to expose
890 */
891int dev_pm_qos_expose_latency_tolerance(struct device *dev)
892{
893 int ret;
894
895 if (!dev->power.set_latency_tolerance)
896 return -EINVAL;
897
898 mutex_lock(&dev_pm_qos_sysfs_mtx);
899 ret = pm_qos_sysfs_add_latency_tolerance(dev);
900 mutex_unlock(&dev_pm_qos_sysfs_mtx);
901
902 return ret;
903}
904EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_tolerance);
905
906/**
907 * dev_pm_qos_hide_latency_tolerance - Hide latency tolerance from userspace
908 * @dev: Device whose latency tolerance to hide
909 */
910void dev_pm_qos_hide_latency_tolerance(struct device *dev)
911{
912 mutex_lock(&dev_pm_qos_sysfs_mtx);
913 pm_qos_sysfs_remove_latency_tolerance(dev);
914 mutex_unlock(&dev_pm_qos_sysfs_mtx);
915
916 /* Remove the request from user space now */
917 pm_runtime_get_sync(dev);
918 dev_pm_qos_update_user_latency_tolerance(dev,
919 PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT);
920 pm_runtime_put(dev);
921}
922EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_tolerance);
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index d2be3f9c211c..a7b46798c81d 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -738,6 +738,17 @@ void pm_qos_sysfs_remove_flags(struct device *dev)
738 sysfs_unmerge_group(&dev->kobj, &pm_qos_flags_attr_group); 738 sysfs_unmerge_group(&dev->kobj, &pm_qos_flags_attr_group);
739} 739}
740 740
741int pm_qos_sysfs_add_latency_tolerance(struct device *dev)
742{
743 return sysfs_merge_group(&dev->kobj,
744 &pm_qos_latency_tolerance_attr_group);
745}
746
747void pm_qos_sysfs_remove_latency_tolerance(struct device *dev)
748{
749 sysfs_unmerge_group(&dev->kobj, &pm_qos_latency_tolerance_attr_group);
750}
751
741void rpm_sysfs_remove(struct device *dev) 752void rpm_sysfs_remove(struct device *dev)
742{ 753{
743 sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group); 754 sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group);
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 7b3ae0cffc05..0f65d36c2a75 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -161,6 +161,8 @@ void dev_pm_qos_hide_flags(struct device *dev);
161int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set); 161int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set);
162s32 dev_pm_qos_get_user_latency_tolerance(struct device *dev); 162s32 dev_pm_qos_get_user_latency_tolerance(struct device *dev);
163int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val); 163int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val);
164int dev_pm_qos_expose_latency_tolerance(struct device *dev);
165void dev_pm_qos_hide_latency_tolerance(struct device *dev);
164 166
165static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev) 167static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev)
166{ 168{
@@ -229,6 +231,9 @@ static inline s32 dev_pm_qos_get_user_latency_tolerance(struct device *dev)
229 { return PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; } 231 { return PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; }
230static inline int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val) 232static inline int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val)
231 { return 0; } 233 { return 0; }
234static inline int dev_pm_qos_expose_latency_tolerance(struct device *dev)
235 { return 0; }
236static inline void dev_pm_qos_hide_latency_tolerance(struct device *dev) {}
232 237
233static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev) { return 0; } 238static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev) { return 0; }
234static inline s32 dev_pm_qos_requested_flags(struct device *dev) { return 0; } 239static inline s32 dev_pm_qos_requested_flags(struct device *dev) { return 0; }