Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Mika Westerberg and committed by
Lee Jones
13b2c4a0 bc0195aa

+55
+2
drivers/base/power/power.h
··· 73 73 extern void pm_qos_sysfs_remove_resume_latency(struct device *dev); 74 74 extern int pm_qos_sysfs_add_flags(struct device *dev); 75 75 extern void pm_qos_sysfs_remove_flags(struct device *dev); 76 + extern int pm_qos_sysfs_add_latency_tolerance(struct device *dev); 77 + extern void pm_qos_sysfs_remove_latency_tolerance(struct device *dev); 76 78 77 79 #else /* CONFIG_PM */ 78 80
+37
drivers/base/power/qos.c
··· 883 883 mutex_unlock(&dev_pm_qos_mtx); 884 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 + */ 891 + int 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 + } 904 + EXPORT_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 + */ 910 + void 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 + } 922 + EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_tolerance);
+11
drivers/base/power/sysfs.c
··· 738 738 sysfs_unmerge_group(&dev->kobj, &pm_qos_flags_attr_group); 739 739 } 740 740 741 + int 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 + 747 + void pm_qos_sysfs_remove_latency_tolerance(struct device *dev) 748 + { 749 + sysfs_unmerge_group(&dev->kobj, &pm_qos_latency_tolerance_attr_group); 750 + } 751 + 741 752 void rpm_sysfs_remove(struct device *dev) 742 753 { 743 754 sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group);
+5
include/linux/pm_qos.h
··· 161 161 int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set); 162 162 s32 dev_pm_qos_get_user_latency_tolerance(struct device *dev); 163 163 int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val); 164 + int dev_pm_qos_expose_latency_tolerance(struct device *dev); 165 + void dev_pm_qos_hide_latency_tolerance(struct device *dev); 164 166 165 167 static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev) 166 168 { ··· 231 229 { return PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; } 232 230 static inline int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val) 233 231 { return 0; } 232 + static inline int dev_pm_qos_expose_latency_tolerance(struct device *dev) 233 + { return 0; } 234 + static inline void dev_pm_qos_hide_latency_tolerance(struct device *dev) {} 234 235 235 236 static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev) { return 0; } 236 237 static inline s32 dev_pm_qos_requested_flags(struct device *dev) { return 0; }