diff options
Diffstat (limited to 'kernel/power/qos.c')
| -rw-r--r-- | kernel/power/qos.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/kernel/power/qos.c b/kernel/power/qos.c index d6d6dbd1ecc0..6a031e684026 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c | |||
| @@ -230,6 +230,21 @@ int pm_qos_request_active(struct pm_qos_request *req) | |||
| 230 | EXPORT_SYMBOL_GPL(pm_qos_request_active); | 230 | EXPORT_SYMBOL_GPL(pm_qos_request_active); |
| 231 | 231 | ||
| 232 | /** | 232 | /** |
| 233 | * pm_qos_work_fn - the timeout handler of pm_qos_update_request_timeout | ||
| 234 | * @work: work struct for the delayed work (timeout) | ||
| 235 | * | ||
| 236 | * This cancels the timeout request by falling back to the default at timeout. | ||
| 237 | */ | ||
| 238 | static void pm_qos_work_fn(struct work_struct *work) | ||
| 239 | { | ||
| 240 | struct pm_qos_request *req = container_of(to_delayed_work(work), | ||
| 241 | struct pm_qos_request, | ||
| 242 | work); | ||
| 243 | |||
| 244 | pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE); | ||
| 245 | } | ||
| 246 | |||
| 247 | /** | ||
| 233 | * pm_qos_add_request - inserts new qos request into the list | 248 | * pm_qos_add_request - inserts new qos request into the list |
| 234 | * @req: pointer to a preallocated handle | 249 | * @req: pointer to a preallocated handle |
| 235 | * @pm_qos_class: identifies which list of qos request to use | 250 | * @pm_qos_class: identifies which list of qos request to use |
| @@ -253,6 +268,7 @@ void pm_qos_add_request(struct pm_qos_request *req, | |||
| 253 | return; | 268 | return; |
| 254 | } | 269 | } |
| 255 | req->pm_qos_class = pm_qos_class; | 270 | req->pm_qos_class = pm_qos_class; |
| 271 | INIT_DELAYED_WORK(&req->work, pm_qos_work_fn); | ||
| 256 | pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints, | 272 | pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints, |
| 257 | &req->node, PM_QOS_ADD_REQ, value); | 273 | &req->node, PM_QOS_ADD_REQ, value); |
| 258 | } | 274 | } |
| @@ -279,6 +295,9 @@ void pm_qos_update_request(struct pm_qos_request *req, | |||
| 279 | return; | 295 | return; |
| 280 | } | 296 | } |
| 281 | 297 | ||
| 298 | if (delayed_work_pending(&req->work)) | ||
| 299 | cancel_delayed_work_sync(&req->work); | ||
| 300 | |||
| 282 | if (new_value != req->node.prio) | 301 | if (new_value != req->node.prio) |
| 283 | pm_qos_update_target( | 302 | pm_qos_update_target( |
| 284 | pm_qos_array[req->pm_qos_class]->constraints, | 303 | pm_qos_array[req->pm_qos_class]->constraints, |
| @@ -287,6 +306,34 @@ void pm_qos_update_request(struct pm_qos_request *req, | |||
| 287 | EXPORT_SYMBOL_GPL(pm_qos_update_request); | 306 | EXPORT_SYMBOL_GPL(pm_qos_update_request); |
| 288 | 307 | ||
| 289 | /** | 308 | /** |
| 309 | * pm_qos_update_request_timeout - modifies an existing qos request temporarily. | ||
| 310 | * @req : handle to list element holding a pm_qos request to use | ||
| 311 | * @new_value: defines the temporal qos request | ||
| 312 | * @timeout_us: the effective duration of this qos request in usecs. | ||
| 313 | * | ||
| 314 | * After timeout_us, this qos request is cancelled automatically. | ||
| 315 | */ | ||
| 316 | void pm_qos_update_request_timeout(struct pm_qos_request *req, s32 new_value, | ||
| 317 | unsigned long timeout_us) | ||
| 318 | { | ||
| 319 | if (!req) | ||
| 320 | return; | ||
| 321 | if (WARN(!pm_qos_request_active(req), | ||
| 322 | "%s called for unknown object.", __func__)) | ||
| 323 | return; | ||
| 324 | |||
| 325 | if (delayed_work_pending(&req->work)) | ||
| 326 | cancel_delayed_work_sync(&req->work); | ||
| 327 | |||
| 328 | if (new_value != req->node.prio) | ||
| 329 | pm_qos_update_target( | ||
| 330 | pm_qos_array[req->pm_qos_class]->constraints, | ||
| 331 | &req->node, PM_QOS_UPDATE_REQ, new_value); | ||
| 332 | |||
| 333 | schedule_delayed_work(&req->work, usecs_to_jiffies(timeout_us)); | ||
| 334 | } | ||
| 335 | |||
| 336 | /** | ||
| 290 | * pm_qos_remove_request - modifies an existing qos request | 337 | * pm_qos_remove_request - modifies an existing qos request |
| 291 | * @req: handle to request list element | 338 | * @req: handle to request list element |
| 292 | * | 339 | * |
| @@ -305,6 +352,9 @@ void pm_qos_remove_request(struct pm_qos_request *req) | |||
| 305 | return; | 352 | return; |
| 306 | } | 353 | } |
| 307 | 354 | ||
| 355 | if (delayed_work_pending(&req->work)) | ||
| 356 | cancel_delayed_work_sync(&req->work); | ||
| 357 | |||
| 308 | pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints, | 358 | pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints, |
| 309 | &req->node, PM_QOS_REMOVE_REQ, | 359 | &req->node, PM_QOS_REMOVE_REQ, |
| 310 | PM_QOS_DEFAULT_VALUE); | 360 | PM_QOS_DEFAULT_VALUE); |
