diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/power/qos.c | 63 |
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, | |||
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | /** | 215 | /** |
| 216 | * pm_qos_flags_remove_req - Remove device PM QoS flags request. | ||
| 217 | * @pqf: Device PM QoS flags set to remove the request from. | ||
| 218 | * @req: Request to remove from the set. | ||
| 219 | */ | ||
| 220 | static void pm_qos_flags_remove_req(struct pm_qos_flags *pqf, | ||
| 221 | struct pm_qos_flags_request *req) | ||
| 222 | { | ||
| 223 | s32 val = 0; | ||
| 224 | |||
| 225 | list_del(&req->node); | ||
| 226 | list_for_each_entry(req, &pqf->list, node) | ||
| 227 | val |= req->flags; | ||
| 228 | |||
| 229 | pqf->effective_flags = val; | ||
| 230 | } | ||
| 231 | |||
| 232 | /** | ||
| 233 | * pm_qos_update_flags - Update a set of PM QoS flags. | ||
| 234 | * @pqf: Set of flags to update. | ||
| 235 | * @req: Request to add to the set, to modify, or to remove from the set. | ||
| 236 | * @action: Action to take on the set. | ||
| 237 | * @val: Value of the request to add or modify. | ||
| 238 | * | ||
| 239 | * Update the given set of PM QoS flags and call notifiers if the aggregate | ||
| 240 | * value has changed. Returns 1 if the aggregate constraint value has changed, | ||
| 241 | * 0 otherwise. | ||
| 242 | */ | ||
| 243 | bool pm_qos_update_flags(struct pm_qos_flags *pqf, | ||
| 244 | struct pm_qos_flags_request *req, | ||
| 245 | enum pm_qos_req_action action, s32 val) | ||
| 246 | { | ||
| 247 | unsigned long irqflags; | ||
| 248 | s32 prev_value, curr_value; | ||
| 249 | |||
| 250 | spin_lock_irqsave(&pm_qos_lock, irqflags); | ||
| 251 | |||
| 252 | prev_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; | ||
| 253 | |||
| 254 | switch (action) { | ||
| 255 | case PM_QOS_REMOVE_REQ: | ||
| 256 | pm_qos_flags_remove_req(pqf, req); | ||
| 257 | break; | ||
| 258 | case PM_QOS_UPDATE_REQ: | ||
| 259 | pm_qos_flags_remove_req(pqf, req); | ||
| 260 | case PM_QOS_ADD_REQ: | ||
| 261 | req->flags = val; | ||
| 262 | INIT_LIST_HEAD(&req->node); | ||
| 263 | list_add_tail(&req->node, &pqf->list); | ||
| 264 | pqf->effective_flags |= val; | ||
| 265 | break; | ||
| 266 | default: | ||
| 267 | /* no action */ | ||
| 268 | ; | ||
| 269 | } | ||
| 270 | |||
| 271 | curr_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; | ||
| 272 | |||
| 273 | spin_unlock_irqrestore(&pm_qos_lock, irqflags); | ||
| 274 | |||
| 275 | return prev_value != curr_value; | ||
| 276 | } | ||
| 277 | |||
| 278 | /** | ||
| 216 | * pm_qos_request - returns current system wide qos expectation | 279 | * pm_qos_request - returns current system wide qos expectation |
| 217 | * @pm_qos_class: identification of which qos value is requested | 280 | * @pm_qos_class: identification of which qos value is requested |
| 218 | * | 281 | * |
