diff options
author | MyungJoo Ham <myungjoo.ham@samsung.com> | 2012-03-28 17:31:24 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-03-28 17:31:24 -0400 |
commit | c4772d192c70b61d52262b0db76f7abd8aeb51c6 (patch) | |
tree | 843ed935b04ed2e2ea8abbafa04f65132f47ba5a /kernel/power | |
parent | a36cf844c543c6193445a7b1492d16e5a8cf376e (diff) |
PM / QoS: add pm_qos_update_request_timeout() API
The new API, pm_qos_update_request_timeout() is to provide a timeout
with pm_qos_update_request.
For example, pm_qos_update_request_timeout(req, 100, 1000), means that
QoS request on req with value 100 will be active for 1000 microseconds.
After 1000 microseconds, the QoS request thru req is reset. If there
were another pm_qos_update_request(req, x) during the 1000 us, this
new request with value x will override as this is another request on the
same req handle. A new request on the same req handle will always
override the previous request whether it is the conventional request or
it is the new timeout request.
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Mark Gross <markgross@thegnar.org>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'kernel/power')
-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); |