diff options
Diffstat (limited to 'kernel/power/qos.c')
| -rw-r--r-- | kernel/power/qos.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 587dddeebf15..a394297f8b2f 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | 44 | ||
| 45 | #include <linux/uaccess.h> | 45 | #include <linux/uaccess.h> |
| 46 | #include <linux/export.h> | 46 | #include <linux/export.h> |
| 47 | #include <trace/events/power.h> | ||
| 47 | 48 | ||
| 48 | /* | 49 | /* |
| 49 | * locking rule: all changes to constraints or notifiers lists | 50 | * locking rule: all changes to constraints or notifiers lists |
| @@ -202,6 +203,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, | |||
| 202 | 203 | ||
| 203 | spin_unlock_irqrestore(&pm_qos_lock, flags); | 204 | spin_unlock_irqrestore(&pm_qos_lock, flags); |
| 204 | 205 | ||
| 206 | trace_pm_qos_update_target(action, prev_value, curr_value); | ||
| 205 | if (prev_value != curr_value) { | 207 | if (prev_value != curr_value) { |
| 206 | blocking_notifier_call_chain(c->notifiers, | 208 | blocking_notifier_call_chain(c->notifiers, |
| 207 | (unsigned long)curr_value, | 209 | (unsigned long)curr_value, |
| @@ -272,6 +274,7 @@ bool pm_qos_update_flags(struct pm_qos_flags *pqf, | |||
| 272 | 274 | ||
| 273 | spin_unlock_irqrestore(&pm_qos_lock, irqflags); | 275 | spin_unlock_irqrestore(&pm_qos_lock, irqflags); |
| 274 | 276 | ||
| 277 | trace_pm_qos_update_flags(action, prev_value, curr_value); | ||
| 275 | return prev_value != curr_value; | 278 | return prev_value != curr_value; |
| 276 | } | 279 | } |
| 277 | 280 | ||
| @@ -293,6 +296,17 @@ int pm_qos_request_active(struct pm_qos_request *req) | |||
| 293 | } | 296 | } |
| 294 | EXPORT_SYMBOL_GPL(pm_qos_request_active); | 297 | EXPORT_SYMBOL_GPL(pm_qos_request_active); |
| 295 | 298 | ||
| 299 | static void __pm_qos_update_request(struct pm_qos_request *req, | ||
| 300 | s32 new_value) | ||
| 301 | { | ||
| 302 | trace_pm_qos_update_request(req->pm_qos_class, new_value); | ||
| 303 | |||
| 304 | if (new_value != req->node.prio) | ||
| 305 | pm_qos_update_target( | ||
| 306 | pm_qos_array[req->pm_qos_class]->constraints, | ||
| 307 | &req->node, PM_QOS_UPDATE_REQ, new_value); | ||
| 308 | } | ||
| 309 | |||
| 296 | /** | 310 | /** |
| 297 | * pm_qos_work_fn - the timeout handler of pm_qos_update_request_timeout | 311 | * pm_qos_work_fn - the timeout handler of pm_qos_update_request_timeout |
| 298 | * @work: work struct for the delayed work (timeout) | 312 | * @work: work struct for the delayed work (timeout) |
| @@ -305,7 +319,7 @@ static void pm_qos_work_fn(struct work_struct *work) | |||
| 305 | struct pm_qos_request, | 319 | struct pm_qos_request, |
| 306 | work); | 320 | work); |
| 307 | 321 | ||
| 308 | pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE); | 322 | __pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE); |
| 309 | } | 323 | } |
| 310 | 324 | ||
| 311 | /** | 325 | /** |
| @@ -333,6 +347,7 @@ void pm_qos_add_request(struct pm_qos_request *req, | |||
| 333 | } | 347 | } |
| 334 | req->pm_qos_class = pm_qos_class; | 348 | req->pm_qos_class = pm_qos_class; |
| 335 | INIT_DELAYED_WORK(&req->work, pm_qos_work_fn); | 349 | INIT_DELAYED_WORK(&req->work, pm_qos_work_fn); |
| 350 | trace_pm_qos_add_request(pm_qos_class, value); | ||
| 336 | pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints, | 351 | pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints, |
| 337 | &req->node, PM_QOS_ADD_REQ, value); | 352 | &req->node, PM_QOS_ADD_REQ, value); |
| 338 | } | 353 | } |
| @@ -360,11 +375,7 @@ void pm_qos_update_request(struct pm_qos_request *req, | |||
| 360 | } | 375 | } |
| 361 | 376 | ||
| 362 | cancel_delayed_work_sync(&req->work); | 377 | cancel_delayed_work_sync(&req->work); |
| 363 | 378 | __pm_qos_update_request(req, new_value); | |
| 364 | if (new_value != req->node.prio) | ||
| 365 | pm_qos_update_target( | ||
| 366 | pm_qos_array[req->pm_qos_class]->constraints, | ||
| 367 | &req->node, PM_QOS_UPDATE_REQ, new_value); | ||
| 368 | } | 379 | } |
| 369 | EXPORT_SYMBOL_GPL(pm_qos_update_request); | 380 | EXPORT_SYMBOL_GPL(pm_qos_update_request); |
| 370 | 381 | ||
| @@ -387,6 +398,8 @@ void pm_qos_update_request_timeout(struct pm_qos_request *req, s32 new_value, | |||
| 387 | 398 | ||
| 388 | cancel_delayed_work_sync(&req->work); | 399 | cancel_delayed_work_sync(&req->work); |
| 389 | 400 | ||
| 401 | trace_pm_qos_update_request_timeout(req->pm_qos_class, | ||
| 402 | new_value, timeout_us); | ||
| 390 | if (new_value != req->node.prio) | 403 | if (new_value != req->node.prio) |
| 391 | pm_qos_update_target( | 404 | pm_qos_update_target( |
| 392 | pm_qos_array[req->pm_qos_class]->constraints, | 405 | pm_qos_array[req->pm_qos_class]->constraints, |
| @@ -416,6 +429,7 @@ void pm_qos_remove_request(struct pm_qos_request *req) | |||
| 416 | 429 | ||
| 417 | cancel_delayed_work_sync(&req->work); | 430 | cancel_delayed_work_sync(&req->work); |
| 418 | 431 | ||
| 432 | trace_pm_qos_remove_request(req->pm_qos_class, PM_QOS_DEFAULT_VALUE); | ||
| 419 | pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints, | 433 | pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints, |
| 420 | &req->node, PM_QOS_REMOVE_REQ, | 434 | &req->node, PM_QOS_REMOVE_REQ, |
| 421 | PM_QOS_DEFAULT_VALUE); | 435 | PM_QOS_DEFAULT_VALUE); |
| @@ -477,7 +491,7 @@ static int find_pm_qos_object_by_minor(int minor) | |||
| 477 | { | 491 | { |
| 478 | int pm_qos_class; | 492 | int pm_qos_class; |
| 479 | 493 | ||
| 480 | for (pm_qos_class = 0; | 494 | for (pm_qos_class = PM_QOS_CPU_DMA_LATENCY; |
| 481 | pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) { | 495 | pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) { |
| 482 | if (minor == | 496 | if (minor == |
| 483 | pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor) | 497 | pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor) |
| @@ -491,7 +505,7 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp) | |||
| 491 | long pm_qos_class; | 505 | long pm_qos_class; |
| 492 | 506 | ||
| 493 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); | 507 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); |
| 494 | if (pm_qos_class >= 0) { | 508 | if (pm_qos_class >= PM_QOS_CPU_DMA_LATENCY) { |
| 495 | struct pm_qos_request *req = kzalloc(sizeof(*req), GFP_KERNEL); | 509 | struct pm_qos_request *req = kzalloc(sizeof(*req), GFP_KERNEL); |
| 496 | if (!req) | 510 | if (!req) |
| 497 | return -ENOMEM; | 511 | return -ENOMEM; |
| @@ -584,7 +598,7 @@ static int __init pm_qos_power_init(void) | |||
| 584 | 598 | ||
| 585 | BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES); | 599 | BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES); |
| 586 | 600 | ||
| 587 | for (i = 1; i < PM_QOS_NUM_CLASSES; i++) { | 601 | for (i = PM_QOS_CPU_DMA_LATENCY; i < PM_QOS_NUM_CLASSES; i++) { |
| 588 | ret = register_pm_qos_misc(pm_qos_array[i]); | 602 | ret = register_pm_qos_misc(pm_qos_array[i]); |
| 589 | if (ret < 0) { | 603 | if (ret < 0) { |
| 590 | printk(KERN_ERR "pm_qos_param: %s setup failed\n", | 604 | printk(KERN_ERR "pm_qos_param: %s setup failed\n", |
