PM: QoS: Introduce frequency QoS

Introduce frequency QoS, based on the "raw" low-level PM QoS, to
represent min and max frequency requests and aggregate constraints.

The min and max frequency requests are to be represented by
struct freq_qos_request objects and the aggregate constraints are to
be represented by struct freq_constraints objects.  The latter are
expected to be initialized with the help of freq_constraints_init().

The freq_qos_read_value() helper is defined to retrieve the aggregate
constraints values from a given struct freq_constraints object and
there are the freq_qos_add_request(), freq_qos_update_request() and
freq_qos_remove_request() helpers to manipulate the min and max
frequency requests.  It is assumed that the the helpers will not
run concurrently with each other for the same struct freq_qos_request
object, so if that may be the case, their uses must ensure proper
synchronization between them (e.g. through locking).

In addition, freq_qos_add_notifier() and freq_qos_remove_notifier()
are provided to add and remove notifiers that will trigger on aggregate
constraint changes to and from a given struct freq_constraints object,
respectively.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
This commit is contained in:
Rafael J. Wysocki
2019-10-16 12:41:24 +02:00
parent 7d194c2100
commit 77751a466e
2 changed files with 284 additions and 0 deletions

View File

@@ -267,4 +267,48 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev)
}
#endif
#define FREQ_QOS_MIN_DEFAULT_VALUE 0
#define FREQ_QOS_MAX_DEFAULT_VALUE (-1)
enum freq_qos_req_type {
FREQ_QOS_MIN = 1,
FREQ_QOS_MAX,
};
struct freq_constraints {
struct pm_qos_constraints min_freq;
struct blocking_notifier_head min_freq_notifiers;
struct pm_qos_constraints max_freq;
struct blocking_notifier_head max_freq_notifiers;
};
struct freq_qos_request {
enum freq_qos_req_type type;
struct plist_node pnode;
struct freq_constraints *qos;
};
static inline int freq_qos_request_active(struct freq_qos_request *req)
{
return !IS_ERR_OR_NULL(req->qos);
}
void freq_constraints_init(struct freq_constraints *qos);
s32 freq_qos_read_value(struct freq_constraints *qos,
enum freq_qos_req_type type);
int freq_qos_add_request(struct freq_constraints *qos,
struct freq_qos_request *req,
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_add_notifier(struct freq_constraints *qos,
enum freq_qos_req_type type,
struct notifier_block *notifier);
int freq_qos_remove_notifier(struct freq_constraints *qos,
enum freq_qos_req_type type,
struct notifier_block *notifier);
#endif