You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'pm-qos'
* pm-qos: sh_mmcif / PM: Use PM QoS latency constraint tmio_mmc / PM: Use PM QoS latency constraint PM / QoS: Make it possible to expose PM QoS latency constraints
This commit is contained in:
@@ -71,6 +71,8 @@ extern void dpm_sysfs_remove(struct device *dev);
|
||||
extern void rpm_sysfs_remove(struct device *dev);
|
||||
extern int wakeup_sysfs_add(struct device *dev);
|
||||
extern void wakeup_sysfs_remove(struct device *dev);
|
||||
extern int pm_qos_sysfs_add(struct device *dev);
|
||||
extern void pm_qos_sysfs_remove(struct device *dev);
|
||||
|
||||
#else /* CONFIG_PM */
|
||||
|
||||
@@ -79,5 +81,7 @@ static inline void dpm_sysfs_remove(struct device *dev) {}
|
||||
static inline void rpm_sysfs_remove(struct device *dev) {}
|
||||
static inline int wakeup_sysfs_add(struct device *dev) { return 0; }
|
||||
static inline void wakeup_sysfs_remove(struct device *dev) {}
|
||||
static inline int pm_qos_sysfs_add(struct device *dev) { return 0; }
|
||||
static inline void pm_qos_sysfs_remove(struct device *dev) {}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/jiffies.h>
|
||||
@@ -217,6 +218,31 @@ static ssize_t autosuspend_delay_ms_store(struct device *dev,
|
||||
static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show,
|
||||
autosuspend_delay_ms_store);
|
||||
|
||||
static ssize_t pm_qos_latency_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", dev->power.pq_req->node.prio);
|
||||
}
|
||||
|
||||
static ssize_t pm_qos_latency_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t n)
|
||||
{
|
||||
s32 value;
|
||||
int ret;
|
||||
|
||||
if (kstrtos32(buf, 0, &value))
|
||||
return -EINVAL;
|
||||
|
||||
if (value < 0)
|
||||
return -EINVAL;
|
||||
|
||||
ret = dev_pm_qos_update_request(dev->power.pq_req, value);
|
||||
return ret < 0 ? ret : n;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(pm_qos_resume_latency_us, 0644,
|
||||
pm_qos_latency_show, pm_qos_latency_store);
|
||||
#endif /* CONFIG_PM_RUNTIME */
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -490,6 +516,17 @@ static struct attribute_group pm_runtime_attr_group = {
|
||||
.attrs = runtime_attrs,
|
||||
};
|
||||
|
||||
static struct attribute *pm_qos_attrs[] = {
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
&dev_attr_pm_qos_resume_latency_us.attr,
|
||||
#endif /* CONFIG_PM_RUNTIME */
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group pm_qos_attr_group = {
|
||||
.name = power_group_name,
|
||||
.attrs = pm_qos_attrs,
|
||||
};
|
||||
|
||||
int dpm_sysfs_add(struct device *dev)
|
||||
{
|
||||
int rc;
|
||||
@@ -530,6 +567,16 @@ void wakeup_sysfs_remove(struct device *dev)
|
||||
sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group);
|
||||
}
|
||||
|
||||
int pm_qos_sysfs_add(struct device *dev)
|
||||
{
|
||||
return sysfs_merge_group(&dev->kobj, &pm_qos_attr_group);
|
||||
}
|
||||
|
||||
void pm_qos_sysfs_remove(struct device *dev)
|
||||
{
|
||||
sysfs_unmerge_group(&dev->kobj, &pm_qos_attr_group);
|
||||
}
|
||||
|
||||
void rpm_sysfs_remove(struct device *dev)
|
||||
{
|
||||
sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group);
|
||||
|
||||
Reference in New Issue
Block a user