PM / QoS: Restore DEV_PM_QOS_MIN/MAX_FREQUENCY
Support for adding per-device frequency limits was removed in
commit 2aac8bdf7a
("PM: QoS: Drop frequency QoS types from device PM QoS")
after cpufreq switched to use a new "freq_constraints" construct.
Restore support for per-device freq limits but base this upon
freq_constraints. This is primarily meant to be used by the devfreq
subsystem.
This removes the "static" marking on freq_qos_apply but does not export
it for modules.
Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Tested-by: Matthias Kaehlcke <mka@chromium.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
342035f66c
commit
36a8015f89
@ -115,10 +115,20 @@ s32 dev_pm_qos_read_value(struct device *dev, enum dev_pm_qos_req_type type)
|
||||
|
||||
spin_lock_irqsave(&dev->power.lock, flags);
|
||||
|
||||
if (type == DEV_PM_QOS_RESUME_LATENCY) {
|
||||
switch (type) {
|
||||
case DEV_PM_QOS_RESUME_LATENCY:
|
||||
ret = IS_ERR_OR_NULL(qos) ? PM_QOS_RESUME_LATENCY_NO_CONSTRAINT
|
||||
: pm_qos_read_value(&qos->resume_latency);
|
||||
} else {
|
||||
break;
|
||||
case DEV_PM_QOS_MIN_FREQUENCY:
|
||||
ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE
|
||||
: freq_qos_read_value(&qos->freq, FREQ_QOS_MIN);
|
||||
break;
|
||||
case DEV_PM_QOS_MAX_FREQUENCY:
|
||||
ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE
|
||||
: freq_qos_read_value(&qos->freq, FREQ_QOS_MAX);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
ret = 0;
|
||||
}
|
||||
@ -159,6 +169,10 @@ static int apply_constraint(struct dev_pm_qos_request *req,
|
||||
req->dev->power.set_latency_tolerance(req->dev, value);
|
||||
}
|
||||
break;
|
||||
case DEV_PM_QOS_MIN_FREQUENCY:
|
||||
case DEV_PM_QOS_MAX_FREQUENCY:
|
||||
ret = freq_qos_apply(&req->data.freq, action, value);
|
||||
break;
|
||||
case DEV_PM_QOS_FLAGS:
|
||||
ret = pm_qos_update_flags(&qos->flags, &req->data.flr,
|
||||
action, value);
|
||||
@ -209,6 +223,8 @@ static int dev_pm_qos_constraints_allocate(struct device *dev)
|
||||
c->no_constraint_value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT;
|
||||
c->type = PM_QOS_MIN;
|
||||
|
||||
freq_constraints_init(&qos->freq);
|
||||
|
||||
INIT_LIST_HEAD(&qos->flags.list);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
@ -269,6 +285,20 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
|
||||
memset(req, 0, sizeof(*req));
|
||||
}
|
||||
|
||||
c = &qos->freq.min_freq;
|
||||
plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
|
||||
apply_constraint(req, PM_QOS_REMOVE_REQ,
|
||||
PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE);
|
||||
memset(req, 0, sizeof(*req));
|
||||
}
|
||||
|
||||
c = &qos->freq.max_freq;
|
||||
plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
|
||||
apply_constraint(req, PM_QOS_REMOVE_REQ,
|
||||
PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
|
||||
memset(req, 0, sizeof(*req));
|
||||
}
|
||||
|
||||
f = &qos->flags;
|
||||
list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) {
|
||||
apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
|
||||
@ -314,11 +344,22 @@ static int __dev_pm_qos_add_request(struct device *dev,
|
||||
ret = dev_pm_qos_constraints_allocate(dev);
|
||||
|
||||
trace_dev_pm_qos_add_request(dev_name(dev), type, value);
|
||||
if (!ret) {
|
||||
req->dev = dev;
|
||||
req->type = type;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
req->dev = dev;
|
||||
req->type = type;
|
||||
if (req->type == DEV_PM_QOS_MIN_FREQUENCY)
|
||||
ret = freq_qos_add_request(&dev->power.qos->freq,
|
||||
&req->data.freq,
|
||||
FREQ_QOS_MIN, value);
|
||||
else if (req->type == DEV_PM_QOS_MAX_FREQUENCY)
|
||||
ret = freq_qos_add_request(&dev->power.qos->freq,
|
||||
&req->data.freq,
|
||||
FREQ_QOS_MAX, value);
|
||||
else
|
||||
ret = apply_constraint(req, PM_QOS_ADD_REQ, value);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -382,6 +423,10 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,
|
||||
case DEV_PM_QOS_LATENCY_TOLERANCE:
|
||||
curr_value = req->data.pnode.prio;
|
||||
break;
|
||||
case DEV_PM_QOS_MIN_FREQUENCY:
|
||||
case DEV_PM_QOS_MAX_FREQUENCY:
|
||||
curr_value = req->data.freq.pnode.prio;
|
||||
break;
|
||||
case DEV_PM_QOS_FLAGS:
|
||||
curr_value = req->data.flr.flags;
|
||||
break;
|
||||
@ -507,6 +552,14 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier,
|
||||
ret = blocking_notifier_chain_register(dev->power.qos->resume_latency.notifiers,
|
||||
notifier);
|
||||
break;
|
||||
case DEV_PM_QOS_MIN_FREQUENCY:
|
||||
ret = freq_qos_add_notifier(&dev->power.qos->freq,
|
||||
FREQ_QOS_MIN, notifier);
|
||||
break;
|
||||
case DEV_PM_QOS_MAX_FREQUENCY:
|
||||
ret = freq_qos_add_notifier(&dev->power.qos->freq,
|
||||
FREQ_QOS_MAX, notifier);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
ret = -EINVAL;
|
||||
@ -546,6 +599,14 @@ int dev_pm_qos_remove_notifier(struct device *dev,
|
||||
ret = blocking_notifier_chain_unregister(dev->power.qos->resume_latency.notifiers,
|
||||
notifier);
|
||||
break;
|
||||
case DEV_PM_QOS_MIN_FREQUENCY:
|
||||
ret = freq_qos_remove_notifier(&dev->power.qos->freq,
|
||||
FREQ_QOS_MIN, notifier);
|
||||
break;
|
||||
case DEV_PM_QOS_MAX_FREQUENCY:
|
||||
ret = freq_qos_remove_notifier(&dev->power.qos->freq,
|
||||
FREQ_QOS_MAX, notifier);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
ret = -EINVAL;
|
||||
|
@ -34,6 +34,8 @@ enum pm_qos_flags_status {
|
||||
#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY
|
||||
#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS PM_QOS_LATENCY_ANY_NS
|
||||
#define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0
|
||||
#define PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE 0
|
||||
#define PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE FREQ_QOS_MAX_DEFAULT_VALUE
|
||||
#define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1)
|
||||
|
||||
#define PM_QOS_FLAG_NO_POWER_OFF (1 << 0)
|
||||
@ -101,6 +103,8 @@ struct freq_qos_request {
|
||||
enum dev_pm_qos_req_type {
|
||||
DEV_PM_QOS_RESUME_LATENCY = 1,
|
||||
DEV_PM_QOS_LATENCY_TOLERANCE,
|
||||
DEV_PM_QOS_MIN_FREQUENCY,
|
||||
DEV_PM_QOS_MAX_FREQUENCY,
|
||||
DEV_PM_QOS_FLAGS,
|
||||
};
|
||||
|
||||
@ -109,6 +113,7 @@ struct dev_pm_qos_request {
|
||||
union {
|
||||
struct plist_node pnode;
|
||||
struct pm_qos_flags_request flr;
|
||||
struct freq_qos_request freq;
|
||||
} data;
|
||||
struct device *dev;
|
||||
};
|
||||
@ -116,6 +121,7 @@ struct dev_pm_qos_request {
|
||||
struct dev_pm_qos {
|
||||
struct pm_qos_constraints resume_latency;
|
||||
struct pm_qos_constraints latency_tolerance;
|
||||
struct freq_constraints freq;
|
||||
struct pm_qos_flags flags;
|
||||
struct dev_pm_qos_request *resume_latency_req;
|
||||
struct dev_pm_qos_request *latency_tolerance_req;
|
||||
@ -214,6 +220,10 @@ static inline s32 dev_pm_qos_read_value(struct device *dev,
|
||||
switch (type) {
|
||||
case DEV_PM_QOS_RESUME_LATENCY:
|
||||
return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
|
||||
case DEV_PM_QOS_MIN_FREQUENCY:
|
||||
return PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE;
|
||||
case DEV_PM_QOS_MAX_FREQUENCY:
|
||||
return PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
@ -293,6 +303,8 @@ int freq_qos_add_request(struct freq_constraints *qos,
|
||||
enum freq_qos_req_type type, s32 value);
|
||||
int freq_qos_update_request(struct freq_qos_request *req, s32 new_value);
|
||||
int freq_qos_remove_request(struct freq_qos_request *req);
|
||||
int freq_qos_apply(struct freq_qos_request *req,
|
||||
enum pm_qos_req_action action, s32 value);
|
||||
|
||||
int freq_qos_add_notifier(struct freq_constraints *qos,
|
||||
enum freq_qos_req_type type,
|
||||
|
@ -714,8 +714,10 @@ s32 freq_qos_read_value(struct freq_constraints *qos,
|
||||
* @req: Constraint request to apply.
|
||||
* @action: Action to perform (add/update/remove).
|
||||
* @value: Value to assign to the QoS request.
|
||||
*
|
||||
* This is only meant to be called from inside pm_qos, not drivers.
|
||||
*/
|
||||
static int freq_qos_apply(struct freq_qos_request *req,
|
||||
int freq_qos_apply(struct freq_qos_request *req,
|
||||
enum pm_qos_req_action action, s32 value)
|
||||
{
|
||||
int ret;
|
||||
|
Loading…
Reference in New Issue
Block a user