|
@@ -212,6 +212,69 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * pm_qos_flags_remove_req - Remove device PM QoS flags request.
|
|
|
+ * @pqf: Device PM QoS flags set to remove the request from.
|
|
|
+ * @req: Request to remove from the set.
|
|
|
+ */
|
|
|
+static void pm_qos_flags_remove_req(struct pm_qos_flags *pqf,
|
|
|
+ struct pm_qos_flags_request *req)
|
|
|
+{
|
|
|
+ s32 val = 0;
|
|
|
+
|
|
|
+ list_del(&req->node);
|
|
|
+ list_for_each_entry(req, &pqf->list, node)
|
|
|
+ val |= req->flags;
|
|
|
+
|
|
|
+ pqf->effective_flags = val;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * pm_qos_update_flags - Update a set of PM QoS flags.
|
|
|
+ * @pqf: Set of flags to update.
|
|
|
+ * @req: Request to add to the set, to modify, or to remove from the set.
|
|
|
+ * @action: Action to take on the set.
|
|
|
+ * @val: Value of the request to add or modify.
|
|
|
+ *
|
|
|
+ * Update the given set of PM QoS flags and call notifiers if the aggregate
|
|
|
+ * value has changed. Returns 1 if the aggregate constraint value has changed,
|
|
|
+ * 0 otherwise.
|
|
|
+ */
|
|
|
+bool pm_qos_update_flags(struct pm_qos_flags *pqf,
|
|
|
+ struct pm_qos_flags_request *req,
|
|
|
+ enum pm_qos_req_action action, s32 val)
|
|
|
+{
|
|
|
+ unsigned long irqflags;
|
|
|
+ s32 prev_value, curr_value;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&pm_qos_lock, irqflags);
|
|
|
+
|
|
|
+ prev_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags;
|
|
|
+
|
|
|
+ switch (action) {
|
|
|
+ case PM_QOS_REMOVE_REQ:
|
|
|
+ pm_qos_flags_remove_req(pqf, req);
|
|
|
+ break;
|
|
|
+ case PM_QOS_UPDATE_REQ:
|
|
|
+ pm_qos_flags_remove_req(pqf, req);
|
|
|
+ case PM_QOS_ADD_REQ:
|
|
|
+ req->flags = val;
|
|
|
+ INIT_LIST_HEAD(&req->node);
|
|
|
+ list_add_tail(&req->node, &pqf->list);
|
|
|
+ pqf->effective_flags |= val;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ /* no action */
|
|
|
+ ;
|
|
|
+ }
|
|
|
+
|
|
|
+ curr_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags;
|
|
|
+
|
|
|
+ spin_unlock_irqrestore(&pm_qos_lock, irqflags);
|
|
|
+
|
|
|
+ return prev_value != curr_value;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* pm_qos_request - returns current system wide qos expectation
|
|
|
* @pm_qos_class: identification of which qos value is requested
|