1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * This module exposes the interface to kernel space for specifying 4 * QoS dependencies. It provides infrastructure for registration of: 5 * 6 * Dependents on a QoS value : register requests 7 * Watchers of QoS value : get notified when target QoS value changes 8 * 9 * This QoS design is best effort based. Dependents register their QoS needs. 10 * Watchers register to keep track of the current QoS needs of the system. 11 * 12 * There are 3 basic classes of QoS parameter: latency, timeout, throughput 13 * each have defined units: 14 * latency: usec 15 * timeout: usec <-- currently not used. 16 * throughput: kbs (kilo byte / sec) 17 * 18 * There are lists of pm_qos_objects each one wrapping requests, notifiers 19 * 20 * User mode requests on a QOS parameter register themselves to the 21 * subsystem by opening the device node /dev/... and writing there request to 22 * the node. As long as the process holds a file handle open to the node the 23 * client continues to be accounted for. Upon file release the usermode 24 * request is removed and a new qos target is computed. This way when the 25 * request that the application has is cleaned up when closes the file 26 * pointer or exits the pm_qos_object will get an opportunity to clean up. 27 * 28 * Mark Gross <mgross@linux.intel.com> 29 */ 30 31 /*#define DEBUG*/ 32 33 #include <linux/pm_qos.h> 34 #include <linux/sched.h> 35 #include <linux/spinlock.h> 36 #include <linux/slab.h> 37 #include <linux/time.h> 38 #include <linux/fs.h> 39 #include <linux/device.h> 40 #include <linux/miscdevice.h> 41 #include <linux/string.h> 42 #include <linux/platform_device.h> 43 #include <linux/init.h> 44 #include <linux/kernel.h> 45 #include <linux/debugfs.h> 46 #include <linux/seq_file.h> 47 48 #include <linux/uaccess.h> 49 #include <linux/export.h> 50 #include <trace/events/power.h> 51 52 /* 53 * locking rule: all changes to constraints or notifiers lists 54 * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock 55 * held, taken with _irqsave. One lock to rule them all 56 */ 57 struct pm_qos_object { 58 struct pm_qos_constraints *constraints; 59 struct miscdevice pm_qos_power_miscdev; 60 char *name; 61 }; 62 63 static DEFINE_SPINLOCK(pm_qos_lock); 64 65 static struct pm_qos_object null_pm_qos; 66 67 static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier); 68 static struct pm_qos_constraints cpu_dma_constraints = { 69 .list = PLIST_HEAD_INIT(cpu_dma_constraints.list), 70 .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, 71 .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, 72 .no_constraint_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, 73 .type = PM_QOS_MIN, 74 .notifiers = &cpu_dma_lat_notifier, 75 }; 76 static struct pm_qos_object cpu_dma_pm_qos = { 77 .constraints = &cpu_dma_constraints, 78 .name = "cpu_dma_latency", 79 }; 80 81 static struct pm_qos_object *pm_qos_array[] = { 82 &null_pm_qos, 83 &cpu_dma_pm_qos, 84 }; 85 86 static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, 87 size_t count, loff_t *f_pos); 88 static ssize_t pm_qos_power_read(struct file *filp, char __user *buf, 89 size_t count, loff_t *f_pos); 90 static int pm_qos_power_open(struct inode *inode, struct file *filp); 91 static int pm_qos_power_release(struct inode *inode, struct file *filp); 92 93 static const struct file_operations pm_qos_power_fops = { 94 .write = pm_qos_power_write, 95 .read = pm_qos_power_read, 96 .open = pm_qos_power_open, 97 .release = pm_qos_power_release, 98 .llseek = noop_llseek, 99 }; 100 101 /* unlocked internal variant */ 102 static inline int pm_qos_get_value(struct pm_qos_constraints *c) 103 { 104 struct plist_node *node; 105 int total_value = 0; 106 107 if (plist_head_empty(&c->list)) 108 return c->no_constraint_value; 109 110 switch (c->type) { 111 case PM_QOS_MIN: 112 return plist_first(&c->list)->prio; 113 114 case PM_QOS_MAX: 115 return plist_last(&c->list)->prio; 116 117 case PM_QOS_SUM: 118 plist_for_each(node, &c->list) 119 total_value += node->prio; 120 121 return total_value; 122 123 default: 124 /* runtime check for not using enum */ 125 BUG(); 126 return PM_QOS_DEFAULT_VALUE; 127 } 128 } 129 130 s32 pm_qos_read_value(struct pm_qos_constraints *c) 131 { 132 return c->target_value; 133 } 134 135 static inline void pm_qos_set_value(struct pm_qos_constraints *c, s32 value) 136 { 137 c->target_value = value; 138 } 139 140 static int pm_qos_debug_show(struct seq_file *s, void *unused) 141 { 142 struct pm_qos_object *qos = (struct pm_qos_object *)s->private; 143 struct pm_qos_constraints *c; 144 struct pm_qos_request *req; 145 char *type; 146 unsigned long flags; 147 int tot_reqs = 0; 148 int active_reqs = 0; 149 150 if (IS_ERR_OR_NULL(qos)) { 151 pr_err("%s: bad qos param!\n", __func__); 152 return -EINVAL; 153 } 154 c = qos->constraints; 155 if (IS_ERR_OR_NULL(c)) { 156 pr_err("%s: Bad constraints on qos?\n", __func__); 157 return -EINVAL; 158 } 159 160 /* Lock to ensure we have a snapshot */ 161 spin_lock_irqsave(&pm_qos_lock, flags); 162 if (plist_head_empty(&c->list)) { 163 seq_puts(s, "Empty!\n"); 164 goto out; 165 } 166 167 switch (c->type) { 168 case PM_QOS_MIN: 169 type = "Minimum"; 170 break; 171 case PM_QOS_MAX: 172 type = "Maximum"; 173 break; 174 case PM_QOS_SUM: 175 type = "Sum"; 176 break; 177 default: 178 type = "Unknown"; 179 } 180 181 plist_for_each_entry(req, &c->list, node) { 182 char *state = "Default"; 183 184 if ((req->node).prio != c->default_value) { 185 active_reqs++; 186 state = "Active"; 187 } 188 tot_reqs++; 189 seq_printf(s, "%d: %d: %s\n", tot_reqs, 190 (req->node).prio, state); 191 } 192 193 seq_printf(s, "Type=%s, Value=%d, Requests: active=%d / total=%d\n", 194 type, pm_qos_get_value(c), active_reqs, tot_reqs); 195 196 out: 197 spin_unlock_irqrestore(&pm_qos_lock, flags); 198 return 0; 199 } 200 201 DEFINE_SHOW_ATTRIBUTE(pm_qos_debug); 202 203 /** 204 * pm_qos_update_target - manages the constraints list and calls the notifiers 205 * if needed 206 * @c: constraints data struct 207 * @node: request to add to the list, to update or to remove 208 * @action: action to take on the constraints list 209 * @value: value of the request to add or update 210 * 211 * This function returns 1 if the aggregated constraint value has changed, 0 212 * otherwise. 213 */ 214 int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, 215 enum pm_qos_req_action action, int value) 216 { 217 unsigned long flags; 218 int prev_value, curr_value, new_value; 219 int ret; 220 221 spin_lock_irqsave(&pm_qos_lock, flags); 222 prev_value = pm_qos_get_value(c); 223 if (value == PM_QOS_DEFAULT_VALUE) 224 new_value = c->default_value; 225 else 226 new_value = value; 227 228 switch (action) { 229 case PM_QOS_REMOVE_REQ: 230 plist_del(node, &c->list); 231 break; 232 case PM_QOS_UPDATE_REQ: 233 /* 234 * to change the list, we atomically remove, reinit 235 * with new value and add, then see if the extremal 236 * changed 237 */ 238 plist_del(node, &c->list); 239 /* fall through */ 240 case PM_QOS_ADD_REQ: 241 plist_node_init(node, new_value); 242 plist_add(node, &c->list); 243 break; 244 default: 245 /* no action */ 246 ; 247 } 248 249 curr_value = pm_qos_get_value(c); 250 pm_qos_set_value(c, curr_value); 251 252 spin_unlock_irqrestore(&pm_qos_lock, flags); 253 254 trace_pm_qos_update_target(action, prev_value, curr_value); 255 if (prev_value != curr_value) { 256 ret = 1; 257 if (c->notifiers) 258 blocking_notifier_call_chain(c->notifiers, 259 (unsigned long)curr_value, 260 NULL); 261 } else { 262 ret = 0; 263 } 264 return ret; 265 } 266 267 /** 268 * pm_qos_flags_remove_req - Remove device PM QoS flags request. 269 * @pqf: Device PM QoS flags set to remove the request from. 270 * @req: Request to remove from the set. 271 */ 272 static void pm_qos_flags_remove_req(struct pm_qos_flags *pqf, 273 struct pm_qos_flags_request *req) 274 { 275 s32 val = 0; 276 277 list_del(&req->node); 278 list_for_each_entry(req, &pqf->list, node) 279 val |= req->flags; 280 281 pqf->effective_flags = val; 282 } 283 284 /** 285 * pm_qos_update_flags - Update a set of PM QoS flags. 286 * @pqf: Set of flags to update. 287 * @req: Request to add to the set, to modify, or to remove from the set. 288 * @action: Action to take on the set. 289 * @val: Value of the request to add or modify. 290 * 291 * Update the given set of PM QoS flags and call notifiers if the aggregate 292 * value has changed. Returns 1 if the aggregate constraint value has changed, 293 * 0 otherwise. 294 */ 295 bool pm_qos_update_flags(struct pm_qos_flags *pqf, 296 struct pm_qos_flags_request *req, 297 enum pm_qos_req_action action, s32 val) 298 { 299 unsigned long irqflags; 300 s32 prev_value, curr_value; 301 302 spin_lock_irqsave(&pm_qos_lock, irqflags); 303 304 prev_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; 305 306 switch (action) { 307 case PM_QOS_REMOVE_REQ: 308 pm_qos_flags_remove_req(pqf, req); 309 break; 310 case PM_QOS_UPDATE_REQ: 311 pm_qos_flags_remove_req(pqf, req); 312 /* fall through */ 313 case PM_QOS_ADD_REQ: 314 req->flags = val; 315 INIT_LIST_HEAD(&req->node); 316 list_add_tail(&req->node, &pqf->list); 317 pqf->effective_flags |= val; 318 break; 319 default: 320 /* no action */ 321 ; 322 } 323 324 curr_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; 325 326 spin_unlock_irqrestore(&pm_qos_lock, irqflags); 327 328 trace_pm_qos_update_flags(action, prev_value, curr_value); 329 return prev_value != curr_value; 330 } 331 332 /** 333 * pm_qos_request - returns current system wide qos expectation 334 * @pm_qos_class: identification of which qos value is requested 335 * 336 * This function returns the current target value. 337 */ 338 int pm_qos_request(int pm_qos_class) 339 { 340 return pm_qos_read_value(pm_qos_array[pm_qos_class]->constraints); 341 } 342 EXPORT_SYMBOL_GPL(pm_qos_request); 343 344 int pm_qos_request_active(struct pm_qos_request *req) 345 { 346 return req->pm_qos_class != 0; 347 } 348 EXPORT_SYMBOL_GPL(pm_qos_request_active); 349 350 static void __pm_qos_update_request(struct pm_qos_request *req, 351 s32 new_value) 352 { 353 trace_pm_qos_update_request(req->pm_qos_class, new_value); 354 355 if (new_value != req->node.prio) 356 pm_qos_update_target( 357 pm_qos_array[req->pm_qos_class]->constraints, 358 &req->node, PM_QOS_UPDATE_REQ, new_value); 359 } 360 361 /** 362 * pm_qos_work_fn - the timeout handler of pm_qos_update_request_timeout 363 * @work: work struct for the delayed work (timeout) 364 * 365 * This cancels the timeout request by falling back to the default at timeout. 366 */ 367 static void pm_qos_work_fn(struct work_struct *work) 368 { 369 struct pm_qos_request *req = container_of(to_delayed_work(work), 370 struct pm_qos_request, 371 work); 372 373 __pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE); 374 } 375 376 /** 377 * pm_qos_add_request - inserts new qos request into the list 378 * @req: pointer to a preallocated handle 379 * @pm_qos_class: identifies which list of qos request to use 380 * @value: defines the qos request 381 * 382 * This function inserts a new entry in the pm_qos_class list of requested qos 383 * performance characteristics. It recomputes the aggregate QoS expectations 384 * for the pm_qos_class of parameters and initializes the pm_qos_request 385 * handle. Caller needs to save this handle for later use in updates and 386 * removal. 387 */ 388 389 void pm_qos_add_request(struct pm_qos_request *req, 390 int pm_qos_class, s32 value) 391 { 392 if (!req) /*guard against callers passing in null */ 393 return; 394 395 if (pm_qos_request_active(req)) { 396 WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n"); 397 return; 398 } 399 req->pm_qos_class = pm_qos_class; 400 INIT_DELAYED_WORK(&req->work, pm_qos_work_fn); 401 trace_pm_qos_add_request(pm_qos_class, value); 402 pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints, 403 &req->node, PM_QOS_ADD_REQ, value); 404 } 405 EXPORT_SYMBOL_GPL(pm_qos_add_request); 406 407 /** 408 * pm_qos_update_request - modifies an existing qos request 409 * @req : handle to list element holding a pm_qos request to use 410 * @value: defines the qos request 411 * 412 * Updates an existing qos request for the pm_qos_class of parameters along 413 * with updating the target pm_qos_class value. 414 * 415 * Attempts are made to make this code callable on hot code paths. 416 */ 417 void pm_qos_update_request(struct pm_qos_request *req, 418 s32 new_value) 419 { 420 if (!req) /*guard against callers passing in null */ 421 return; 422 423 if (!pm_qos_request_active(req)) { 424 WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n"); 425 return; 426 } 427 428 cancel_delayed_work_sync(&req->work); 429 __pm_qos_update_request(req, new_value); 430 } 431 EXPORT_SYMBOL_GPL(pm_qos_update_request); 432 433 /** 434 * pm_qos_update_request_timeout - modifies an existing qos request temporarily. 435 * @req : handle to list element holding a pm_qos request to use 436 * @new_value: defines the temporal qos request 437 * @timeout_us: the effective duration of this qos request in usecs. 438 * 439 * After timeout_us, this qos request is cancelled automatically. 440 */ 441 void pm_qos_update_request_timeout(struct pm_qos_request *req, s32 new_value, 442 unsigned long timeout_us) 443 { 444 if (!req) 445 return; 446 if (WARN(!pm_qos_request_active(req), 447 "%s called for unknown object.", __func__)) 448 return; 449 450 cancel_delayed_work_sync(&req->work); 451 452 trace_pm_qos_update_request_timeout(req->pm_qos_class, 453 new_value, timeout_us); 454 if (new_value != req->node.prio) 455 pm_qos_update_target( 456 pm_qos_array[req->pm_qos_class]->constraints, 457 &req->node, PM_QOS_UPDATE_REQ, new_value); 458 459 schedule_delayed_work(&req->work, usecs_to_jiffies(timeout_us)); 460 } 461 462 /** 463 * pm_qos_remove_request - modifies an existing qos request 464 * @req: handle to request list element 465 * 466 * Will remove pm qos request from the list of constraints and 467 * recompute the current target value for the pm_qos_class. Call this 468 * on slow code paths. 469 */ 470 void pm_qos_remove_request(struct pm_qos_request *req) 471 { 472 if (!req) /*guard against callers passing in null */ 473 return; 474 /* silent return to keep pcm code cleaner */ 475 476 if (!pm_qos_request_active(req)) { 477 WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n"); 478 return; 479 } 480 481 cancel_delayed_work_sync(&req->work); 482 483 trace_pm_qos_remove_request(req->pm_qos_class, PM_QOS_DEFAULT_VALUE); 484 pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints, 485 &req->node, PM_QOS_REMOVE_REQ, 486 PM_QOS_DEFAULT_VALUE); 487 memset(req, 0, sizeof(*req)); 488 } 489 EXPORT_SYMBOL_GPL(pm_qos_remove_request); 490 491 /** 492 * pm_qos_add_notifier - sets notification entry for changes to target value 493 * @pm_qos_class: identifies which qos target changes should be notified. 494 * @notifier: notifier block managed by caller. 495 * 496 * will register the notifier into a notification chain that gets called 497 * upon changes to the pm_qos_class target value. 498 */ 499 int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier) 500 { 501 int retval; 502 503 retval = blocking_notifier_chain_register( 504 pm_qos_array[pm_qos_class]->constraints->notifiers, 505 notifier); 506 507 return retval; 508 } 509 EXPORT_SYMBOL_GPL(pm_qos_add_notifier); 510 511 /** 512 * pm_qos_remove_notifier - deletes notification entry from chain. 513 * @pm_qos_class: identifies which qos target changes are notified. 514 * @notifier: notifier block to be removed. 515 * 516 * will remove the notifier from the notification chain that gets called 517 * upon changes to the pm_qos_class target value. 518 */ 519 int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) 520 { 521 int retval; 522 523 retval = blocking_notifier_chain_unregister( 524 pm_qos_array[pm_qos_class]->constraints->notifiers, 525 notifier); 526 527 return retval; 528 } 529 EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); 530 531 /* User space interface to PM QoS classes via misc devices */ 532 static int register_pm_qos_misc(struct pm_qos_object *qos, struct dentry *d) 533 { 534 qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR; 535 qos->pm_qos_power_miscdev.name = qos->name; 536 qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops; 537 538 debugfs_create_file(qos->name, S_IRUGO, d, (void *)qos, 539 &pm_qos_debug_fops); 540 541 return misc_register(&qos->pm_qos_power_miscdev); 542 } 543 544 static int find_pm_qos_object_by_minor(int minor) 545 { 546 int pm_qos_class; 547 548 for (pm_qos_class = PM_QOS_CPU_DMA_LATENCY; 549 pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) { 550 if (minor == 551 pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor) 552 return pm_qos_class; 553 } 554 return -1; 555 } 556 557 static int pm_qos_power_open(struct inode *inode, struct file *filp) 558 { 559 long pm_qos_class; 560 561 pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); 562 if (pm_qos_class >= PM_QOS_CPU_DMA_LATENCY) { 563 struct pm_qos_request *req = kzalloc(sizeof(*req), GFP_KERNEL); 564 if (!req) 565 return -ENOMEM; 566 567 pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE); 568 filp->private_data = req; 569 570 return 0; 571 } 572 return -EPERM; 573 } 574 575 static int pm_qos_power_release(struct inode *inode, struct file *filp) 576 { 577 struct pm_qos_request *req; 578 579 req = filp->private_data; 580 pm_qos_remove_request(req); 581 kfree(req); 582 583 return 0; 584 } 585 586 587 static ssize_t pm_qos_power_read(struct file *filp, char __user *buf, 588 size_t count, loff_t *f_pos) 589 { 590 s32 value; 591 unsigned long flags; 592 struct pm_qos_request *req = filp->private_data; 593 594 if (!req) 595 return -EINVAL; 596 if (!pm_qos_request_active(req)) 597 return -EINVAL; 598 599 spin_lock_irqsave(&pm_qos_lock, flags); 600 value = pm_qos_get_value(pm_qos_array[req->pm_qos_class]->constraints); 601 spin_unlock_irqrestore(&pm_qos_lock, flags); 602 603 return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32)); 604 } 605 606 static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, 607 size_t count, loff_t *f_pos) 608 { 609 s32 value; 610 struct pm_qos_request *req; 611 612 if (count == sizeof(s32)) { 613 if (copy_from_user(&value, buf, sizeof(s32))) 614 return -EFAULT; 615 } else { 616 int ret; 617 618 ret = kstrtos32_from_user(buf, count, 16, &value); 619 if (ret) 620 return ret; 621 } 622 623 req = filp->private_data; 624 pm_qos_update_request(req, value); 625 626 return count; 627 } 628 629 630 static int __init pm_qos_power_init(void) 631 { 632 int ret = 0; 633 int i; 634 struct dentry *d; 635 636 BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES); 637 638 d = debugfs_create_dir("pm_qos", NULL); 639 640 for (i = PM_QOS_CPU_DMA_LATENCY; i < PM_QOS_NUM_CLASSES; i++) { 641 ret = register_pm_qos_misc(pm_qos_array[i], d); 642 if (ret < 0) { 643 pr_err("%s: %s setup failed\n", 644 __func__, pm_qos_array[i]->name); 645 return ret; 646 } 647 } 648 649 return ret; 650 } 651 652 late_initcall(pm_qos_power_init); 653 654 /* Definitions related to the frequency QoS below. */ 655 656 /** 657 * freq_constraints_init - Initialize frequency QoS constraints. 658 * @qos: Frequency QoS constraints to initialize. 659 */ 660 void freq_constraints_init(struct freq_constraints *qos) 661 { 662 struct pm_qos_constraints *c; 663 664 c = &qos->min_freq; 665 plist_head_init(&c->list); 666 c->target_value = FREQ_QOS_MIN_DEFAULT_VALUE; 667 c->default_value = FREQ_QOS_MIN_DEFAULT_VALUE; 668 c->no_constraint_value = FREQ_QOS_MIN_DEFAULT_VALUE; 669 c->type = PM_QOS_MAX; 670 c->notifiers = &qos->min_freq_notifiers; 671 BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers); 672 673 c = &qos->max_freq; 674 plist_head_init(&c->list); 675 c->target_value = FREQ_QOS_MAX_DEFAULT_VALUE; 676 c->default_value = FREQ_QOS_MAX_DEFAULT_VALUE; 677 c->no_constraint_value = FREQ_QOS_MAX_DEFAULT_VALUE; 678 c->type = PM_QOS_MIN; 679 c->notifiers = &qos->max_freq_notifiers; 680 BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers); 681 } 682 683 /** 684 * freq_qos_read_value - Get frequency QoS constraint for a given list. 685 * @qos: Constraints to evaluate. 686 * @type: QoS request type. 687 */ 688 s32 freq_qos_read_value(struct freq_constraints *qos, 689 enum freq_qos_req_type type) 690 { 691 s32 ret; 692 693 switch (type) { 694 case FREQ_QOS_MIN: 695 ret = IS_ERR_OR_NULL(qos) ? 696 FREQ_QOS_MIN_DEFAULT_VALUE : 697 pm_qos_read_value(&qos->min_freq); 698 break; 699 case FREQ_QOS_MAX: 700 ret = IS_ERR_OR_NULL(qos) ? 701 FREQ_QOS_MAX_DEFAULT_VALUE : 702 pm_qos_read_value(&qos->max_freq); 703 break; 704 default: 705 WARN_ON(1); 706 ret = 0; 707 } 708 709 return ret; 710 } 711 712 /** 713 * freq_qos_apply - Add/modify/remove frequency QoS request. 714 * @req: Constraint request to apply. 715 * @action: Action to perform (add/update/remove). 716 * @value: Value to assign to the QoS request. 717 */ 718 static int freq_qos_apply(struct freq_qos_request *req, 719 enum pm_qos_req_action action, s32 value) 720 { 721 int ret; 722 723 switch(req->type) { 724 case FREQ_QOS_MIN: 725 ret = pm_qos_update_target(&req->qos->min_freq, &req->pnode, 726 action, value); 727 break; 728 case FREQ_QOS_MAX: 729 ret = pm_qos_update_target(&req->qos->max_freq, &req->pnode, 730 action, value); 731 break; 732 default: 733 ret = -EINVAL; 734 } 735 736 return ret; 737 } 738 739 /** 740 * freq_qos_add_request - Insert new frequency QoS request into a given list. 741 * @qos: Constraints to update. 742 * @req: Preallocated request object. 743 * @type: Request type. 744 * @value: Request value. 745 * 746 * Insert a new entry into the @qos list of requests, recompute the effective 747 * QoS constraint value for that list and initialize the @req object. The 748 * caller needs to save that object for later use in updates and removal. 749 * 750 * Return 1 if the effective constraint value has changed, 0 if the effective 751 * constraint value has not changed, or a negative error code on failures. 752 */ 753 int freq_qos_add_request(struct freq_constraints *qos, 754 struct freq_qos_request *req, 755 enum freq_qos_req_type type, s32 value) 756 { 757 int ret; 758 759 if (IS_ERR_OR_NULL(qos) || !req) 760 return -EINVAL; 761 762 if (WARN(freq_qos_request_active(req), 763 "%s() called for active request\n", __func__)) 764 return -EINVAL; 765 766 req->qos = qos; 767 req->type = type; 768 ret = freq_qos_apply(req, PM_QOS_ADD_REQ, value); 769 if (ret < 0) { 770 req->qos = NULL; 771 req->type = 0; 772 } 773 774 return ret; 775 } 776 EXPORT_SYMBOL_GPL(freq_qos_add_request); 777 778 /** 779 * freq_qos_update_request - Modify existing frequency QoS request. 780 * @req: Request to modify. 781 * @new_value: New request value. 782 * 783 * Update an existing frequency QoS request along with the effective constraint 784 * value for the list of requests it belongs to. 785 * 786 * Return 1 if the effective constraint value has changed, 0 if the effective 787 * constraint value has not changed, or a negative error code on failures. 788 */ 789 int freq_qos_update_request(struct freq_qos_request *req, s32 new_value) 790 { 791 if (!req) 792 return -EINVAL; 793 794 if (WARN(!freq_qos_request_active(req), 795 "%s() called for unknown object\n", __func__)) 796 return -EINVAL; 797 798 if (req->pnode.prio == new_value) 799 return 0; 800 801 return freq_qos_apply(req, PM_QOS_UPDATE_REQ, new_value); 802 } 803 EXPORT_SYMBOL_GPL(freq_qos_update_request); 804 805 /** 806 * freq_qos_remove_request - Remove frequency QoS request from its list. 807 * @req: Request to remove. 808 * 809 * Remove the given frequency QoS request from the list of constraints it 810 * belongs to and recompute the effective constraint value for that list. 811 * 812 * Return 1 if the effective constraint value has changed, 0 if the effective 813 * constraint value has not changed, or a negative error code on failures. 814 */ 815 int freq_qos_remove_request(struct freq_qos_request *req) 816 { 817 int ret; 818 819 if (!req) 820 return -EINVAL; 821 822 if (WARN(!freq_qos_request_active(req), 823 "%s() called for unknown object\n", __func__)) 824 return -EINVAL; 825 826 ret = freq_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); 827 req->qos = NULL; 828 req->type = 0; 829 830 return ret; 831 } 832 EXPORT_SYMBOL_GPL(freq_qos_remove_request); 833 834 /** 835 * freq_qos_add_notifier - Add frequency QoS change notifier. 836 * @qos: List of requests to add the notifier to. 837 * @type: Request type. 838 * @notifier: Notifier block to add. 839 */ 840 int freq_qos_add_notifier(struct freq_constraints *qos, 841 enum freq_qos_req_type type, 842 struct notifier_block *notifier) 843 { 844 int ret; 845 846 if (IS_ERR_OR_NULL(qos) || !notifier) 847 return -EINVAL; 848 849 switch (type) { 850 case FREQ_QOS_MIN: 851 ret = blocking_notifier_chain_register(qos->min_freq.notifiers, 852 notifier); 853 break; 854 case FREQ_QOS_MAX: 855 ret = blocking_notifier_chain_register(qos->max_freq.notifiers, 856 notifier); 857 break; 858 default: 859 WARN_ON(1); 860 ret = -EINVAL; 861 } 862 863 return ret; 864 } 865 EXPORT_SYMBOL_GPL(freq_qos_add_notifier); 866 867 /** 868 * freq_qos_remove_notifier - Remove frequency QoS change notifier. 869 * @qos: List of requests to remove the notifier from. 870 * @type: Request type. 871 * @notifier: Notifier block to remove. 872 */ 873 int freq_qos_remove_notifier(struct freq_constraints *qos, 874 enum freq_qos_req_type type, 875 struct notifier_block *notifier) 876 { 877 int ret; 878 879 if (IS_ERR_OR_NULL(qos) || !notifier) 880 return -EINVAL; 881 882 switch (type) { 883 case FREQ_QOS_MIN: 884 ret = blocking_notifier_chain_unregister(qos->min_freq.notifiers, 885 notifier); 886 break; 887 case FREQ_QOS_MAX: 888 ret = blocking_notifier_chain_unregister(qos->max_freq.notifiers, 889 notifier); 890 break; 891 default: 892 WARN_ON(1); 893 ret = -EINVAL; 894 } 895 896 return ret; 897 } 898 EXPORT_SYMBOL_GPL(freq_qos_remove_notifier); 899