summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2012-11-29 21:40:32 +0100
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2012-11-29 21:40:32 +0100
commitc8b6817103b23ed42114516fea901c2f61271506 (patch)
treef3a54c55a37cfa02496de62c0f0b89f2a52dc219 /kernel
parent9489e9dcae718d5fde988e4a684a0f55b5f94d17 (diff)
parent35546bd477146b75ae2a9ff2cb9bfcdb0f701015 (diff)
downloadlinux-c8b6817103b23ed42114516fea901c2f61271506.tar.bz2
Merge branch 'pm-qos'
* pm-qos: PM / QoS: Handle device PM QoS flags while removing constraints PM / QoS: Resume device before exposing/hiding PM QoS flags PM / QoS: Document request manipulation requirement for flags PM / QoS: Fix a free error in the dev_pm_qos_constraints_destroy() PM / QoS: Fix the return value of dev_pm_qos_update_request() PM / ACPI: Take device PM QoS flags into account PM / Domains: Check device PM QoS flags in pm_genpd_poweroff() PM / QoS: Make it possible to expose PM QoS device flags to user space PM / QoS: Introduce PM QoS device flags support PM / QoS: Prepare struct dev_pm_qos_request for more request types PM / QoS: Introduce request and constraint data types for PM QoS flags PM / QoS: Prepare device structure for adding more constraint types
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/qos.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 846bd42c7ed1..2ab2819aee65 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -213,6 +213,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
*