1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Power Management Quality of Service (PM QoS) support base. 4 * 5 * Copyright (C) 2020 Intel Corporation 6 * 7 * Authors: 8 * Mark Gross <mgross@linux.intel.com> 9 * Rafael J. Wysocki <rafael.j.wysocki@intel.com> 10 * 11 * Provided here is an interface for specifying PM QoS dependencies. It allows 12 * entities depending on QoS constraints to register their requests which are 13 * aggregated as appropriate to produce effective constraints (target values) 14 * that can be monitored by entities needing to respect them, either by polling 15 * or through a built-in notification mechanism. 16 * 17 * In addition to the basic functionality, more specific interfaces for managing 18 * global CPU latency QoS requests and frequency QoS requests are provided. 19 */ 20 21 /*#define DEBUG*/ 22 23 #include <linux/pm_qos.h> 24 #include <linux/sched.h> 25 #include <linux/spinlock.h> 26 #include <linux/slab.h> 27 #include <linux/time.h> 28 #include <linux/fs.h> 29 #include <linux/device.h> 30 #include <linux/miscdevice.h> 31 #include <linux/string.h> 32 #include <linux/platform_device.h> 33 #include <linux/init.h> 34 #include <linux/kernel.h> 35 #include <linux/debugfs.h> 36 #include <linux/seq_file.h> 37 38 #include <linux/uaccess.h> 39 #include <linux/export.h> 40 #include <trace/events/power.h> 41 42 /* 43 * locking rule: all changes to constraints or notifiers lists 44 * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock 45 * held, taken with _irqsave. One lock to rule them all 46 */ 47 static DEFINE_SPINLOCK(pm_qos_lock); 48 49 /** 50 * pm_qos_read_value - Return the current effective constraint value. 51 * @c: List of PM QoS constraint requests. 52 */ 53 s32 pm_qos_read_value(struct pm_qos_constraints *c) 54 { 55 return READ_ONCE(c->target_value); 56 } 57 58 static int pm_qos_get_value(struct pm_qos_constraints *c) 59 { 60 if (plist_head_empty(&c->list)) 61 return c->no_constraint_value; 62 63 switch (c->type) { 64 case PM_QOS_MIN: 65 return plist_first(&c->list)->prio; 66 67 case PM_QOS_MAX: 68 return plist_last(&c->list)->prio; 69 70 default: 71 WARN(1, "Unknown PM QoS type in %s\n", __func__); 72 return PM_QOS_DEFAULT_VALUE; 73 } 74 } 75 76 static void pm_qos_set_value(struct pm_qos_constraints *c, s32 value) 77 { 78 WRITE_ONCE(c->target_value, value); 79 } 80 81 /** 82 * pm_qos_update_target - Update a list of PM QoS constraint requests. 83 * @c: List of PM QoS requests. 84 * @node: Target list entry. 85 * @action: Action to carry out (add, update or remove). 86 * @value: New request value for the target list entry. 87 * 88 * Update the given list of PM QoS constraint requests, @c, by carrying an 89 * @action involving the @node list entry and @value on it. 90 * 91 * The recognized values of @action are PM_QOS_ADD_REQ (store @value in @node 92 * and add it to the list), PM_QOS_UPDATE_REQ (remove @node from the list, store 93 * @value in it and add it to the list again), and PM_QOS_REMOVE_REQ (remove 94 * @node from the list, ignore @value). 95 * 96 * Return: 1 if the aggregate constraint value has changed, 0 otherwise. 97 */ 98 int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, 99 enum pm_qos_req_action action, int value) 100 { 101 int prev_value, curr_value, new_value; 102 unsigned long flags; 103 104 spin_lock_irqsave(&pm_qos_lock, flags); 105 106 prev_value = pm_qos_get_value(c); 107 if (value == PM_QOS_DEFAULT_VALUE) 108 new_value = c->default_value; 109 else 110 new_value = value; 111 112 switch (action) { 113 case PM_QOS_REMOVE_REQ: 114 plist_del(node, &c->list); 115 break; 116 case PM_QOS_UPDATE_REQ: 117 /* 118 * To change the list, atomically remove, reinit with new value 119 * and add, then see if the aggregate has changed. 120 */ 121 plist_del(node, &c->list); 122 fallthrough; 123 case PM_QOS_ADD_REQ: 124 plist_node_init(node, new_value); 125 plist_add(node, &c->list); 126 break; 127 default: 128 /* no action */ 129 ; 130 } 131 132 curr_value = pm_qos_get_value(c); 133 pm_qos_set_value(c, curr_value); 134 135 spin_unlock_irqrestore(&pm_qos_lock, flags); 136 137 trace_pm_qos_update_target(action, prev_value, curr_value); 138 139 if (prev_value == curr_value) 140 return 0; 141 142 if (c->notifiers) 143 blocking_notifier_call_chain(c->notifiers, curr_value, NULL); 144 145 return 1; 146 } 147 148 /** 149 * pm_qos_flags_remove_req - Remove device PM QoS flags request. 150 * @pqf: Device PM QoS flags set to remove the request from. 151 * @req: Request to remove from the set. 152 */ 153 static void pm_qos_flags_remove_req(struct pm_qos_flags *pqf, 154 struct pm_qos_flags_request *req) 155 { 156 s32 val = 0; 157 158 list_del(&req->node); 159 list_for_each_entry(req, &pqf->list, node) 160 val |= req->flags; 161 162 pqf->effective_flags = val; 163 } 164 165 /** 166 * pm_qos_update_flags - Update a set of PM QoS flags. 167 * @pqf: Set of PM QoS flags to update. 168 * @req: Request to add to the set, to modify, or to remove from the set. 169 * @action: Action to take on the set. 170 * @val: Value of the request to add or modify. 171 * 172 * Return: 1 if the aggregate constraint value has changed, 0 otherwise. 173 */ 174 bool pm_qos_update_flags(struct pm_qos_flags *pqf, 175 struct pm_qos_flags_request *req, 176 enum pm_qos_req_action action, s32 val) 177 { 178 unsigned long irqflags; 179 s32 prev_value, curr_value; 180 181 spin_lock_irqsave(&pm_qos_lock, irqflags); 182 183 prev_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; 184 185 switch (action) { 186 case PM_QOS_REMOVE_REQ: 187 pm_qos_flags_remove_req(pqf, req); 188 break; 189 case PM_QOS_UPDATE_REQ: 190 pm_qos_flags_remove_req(pqf, req); 191 fallthrough; 192 case PM_QOS_ADD_REQ: 193 req->flags = val; 194 INIT_LIST_HEAD(&req->node); 195 list_add_tail(&req->node, &pqf->list); 196 pqf->effective_flags |= val; 197 break; 198 default: 199 /* no action */ 200 ; 201 } 202 203 curr_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; 204 205 spin_unlock_irqrestore(&pm_qos_lock, irqflags); 206 207 trace_pm_qos_update_flags(action, prev_value, curr_value); 208 209 return prev_value != curr_value; 210 } 211 212 #ifdef CONFIG_CPU_IDLE 213 /* Definitions related to the CPU latency QoS. */ 214 215 static struct pm_qos_constraints cpu_latency_constraints = { 216 .list = PLIST_HEAD_INIT(cpu_latency_constraints.list), 217 .target_value = PM_QOS_CPU_LATENCY_DEFAULT_VALUE, 218 .default_value = PM_QOS_CPU_LATENCY_DEFAULT_VALUE, 219 .no_constraint_value = PM_QOS_CPU_LATENCY_DEFAULT_VALUE, 220 .type = PM_QOS_MIN, 221 }; 222 223 static inline bool cpu_latency_qos_value_invalid(s32 value) 224 { 225 return value < 0 && value != PM_QOS_DEFAULT_VALUE; 226 } 227 228 /** 229 * cpu_latency_qos_limit - Return current system-wide CPU latency QoS limit. 230 */ 231 s32 cpu_latency_qos_limit(void) 232 { 233 return pm_qos_read_value(&cpu_latency_constraints); 234 } 235 236 /** 237 * cpu_latency_qos_request_active - Check the given PM QoS request. 238 * @req: PM QoS request to check. 239 * 240 * Return: 'true' if @req has been added to the CPU latency QoS list, 'false' 241 * otherwise. 242 */ 243 bool cpu_latency_qos_request_active(struct pm_qos_request *req) 244 { 245 return req->qos == &cpu_latency_constraints; 246 } 247 EXPORT_SYMBOL_GPL(cpu_latency_qos_request_active); 248 249 static void cpu_latency_qos_apply(struct pm_qos_request *req, 250 enum pm_qos_req_action action, s32 value) 251 { 252 int ret = pm_qos_update_target(req->qos, &req->node, action, value); 253 if (ret > 0) 254 wake_up_all_idle_cpus(); 255 } 256 257 /** 258 * cpu_latency_qos_add_request - Add new CPU latency QoS request. 259 * @req: Pointer to a preallocated handle. 260 * @value: Requested constraint value. 261 * 262 * Use @value to initialize the request handle pointed to by @req, insert it as 263 * a new entry to the CPU latency QoS list and recompute the effective QoS 264 * constraint for that list. 265 * 266 * Callers need to save the handle for later use in updates and removal of the 267 * QoS request represented by it. 268 */ 269 void cpu_latency_qos_add_request(struct pm_qos_request *req, s32 value) 270 { 271 if (!req || cpu_latency_qos_value_invalid(value)) 272 return; 273 274 if (cpu_latency_qos_request_active(req)) { 275 WARN(1, KERN_ERR "%s called for already added request\n", __func__); 276 return; 277 } 278 279 trace_pm_qos_add_request(value); 280 281 req->qos = &cpu_latency_constraints; 282 cpu_latency_qos_apply(req, PM_QOS_ADD_REQ, value); 283 } 284 EXPORT_SYMBOL_GPL(cpu_latency_qos_add_request); 285 286 /** 287 * cpu_latency_qos_update_request - Modify existing CPU latency QoS request. 288 * @req : QoS request to update. 289 * @new_value: New requested constraint value. 290 * 291 * Use @new_value to update the QoS request represented by @req in the CPU 292 * latency QoS list along with updating the effective constraint value for that 293 * list. 294 */ 295 void cpu_latency_qos_update_request(struct pm_qos_request *req, s32 new_value) 296 { 297 if (!req || cpu_latency_qos_value_invalid(new_value)) 298 return; 299 300 if (!cpu_latency_qos_request_active(req)) { 301 WARN(1, KERN_ERR "%s called for unknown object\n", __func__); 302 return; 303 } 304 305 trace_pm_qos_update_request(new_value); 306 307 if (new_value == req->node.prio) 308 return; 309 310 cpu_latency_qos_apply(req, PM_QOS_UPDATE_REQ, new_value); 311 } 312 EXPORT_SYMBOL_GPL(cpu_latency_qos_update_request); 313 314 /** 315 * cpu_latency_qos_remove_request - Remove existing CPU latency QoS request. 316 * @req: QoS request to remove. 317 * 318 * Remove the CPU latency QoS request represented by @req from the CPU latency 319 * QoS list along with updating the effective constraint value for that list. 320 */ 321 void cpu_latency_qos_remove_request(struct pm_qos_request *req) 322 { 323 if (!req) 324 return; 325 326 if (!cpu_latency_qos_request_active(req)) { 327 WARN(1, KERN_ERR "%s called for unknown object\n", __func__); 328 return; 329 } 330 331 trace_pm_qos_remove_request(PM_QOS_DEFAULT_VALUE); 332 333 cpu_latency_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); 334 memset(req, 0, sizeof(*req)); 335 } 336 EXPORT_SYMBOL_GPL(cpu_latency_qos_remove_request); 337 338 /* User space interface to the CPU latency QoS via misc device. */ 339 340 static int cpu_latency_qos_open(struct inode *inode, struct file *filp) 341 { 342 struct pm_qos_request *req; 343 344 req = kzalloc_obj(*req); 345 if (!req) 346 return -ENOMEM; 347 348 cpu_latency_qos_add_request(req, PM_QOS_DEFAULT_VALUE); 349 filp->private_data = req; 350 351 return 0; 352 } 353 354 static int cpu_latency_qos_release(struct inode *inode, struct file *filp) 355 { 356 struct pm_qos_request *req = filp->private_data; 357 358 filp->private_data = NULL; 359 360 cpu_latency_qos_remove_request(req); 361 kfree(req); 362 363 return 0; 364 } 365 366 static ssize_t cpu_latency_qos_read(struct file *filp, char __user *buf, 367 size_t count, loff_t *f_pos) 368 { 369 struct pm_qos_request *req = filp->private_data; 370 unsigned long flags; 371 s32 value; 372 373 if (!req || !cpu_latency_qos_request_active(req)) 374 return -EINVAL; 375 376 spin_lock_irqsave(&pm_qos_lock, flags); 377 value = pm_qos_get_value(&cpu_latency_constraints); 378 spin_unlock_irqrestore(&pm_qos_lock, flags); 379 380 return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32)); 381 } 382 383 static ssize_t cpu_latency_qos_write(struct file *filp, const char __user *buf, 384 size_t count, loff_t *f_pos) 385 { 386 s32 value; 387 388 if (count == sizeof(s32)) { 389 if (copy_from_user(&value, buf, sizeof(s32))) 390 return -EFAULT; 391 } else { 392 int ret; 393 394 ret = kstrtos32_from_user(buf, count, 16, &value); 395 if (ret) 396 return ret; 397 } 398 399 cpu_latency_qos_update_request(filp->private_data, value); 400 401 return count; 402 } 403 404 static const struct file_operations cpu_latency_qos_fops = { 405 .write = cpu_latency_qos_write, 406 .read = cpu_latency_qos_read, 407 .open = cpu_latency_qos_open, 408 .release = cpu_latency_qos_release, 409 .llseek = noop_llseek, 410 }; 411 412 static struct miscdevice cpu_latency_qos_miscdev = { 413 .minor = MISC_DYNAMIC_MINOR, 414 .name = "cpu_dma_latency", 415 .fops = &cpu_latency_qos_fops, 416 }; 417 418 #ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP 419 /* The CPU system wakeup latency QoS. */ 420 static struct pm_qos_constraints cpu_wakeup_latency_constraints = { 421 .list = PLIST_HEAD_INIT(cpu_wakeup_latency_constraints.list), 422 .target_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT, 423 .default_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT, 424 .no_constraint_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT, 425 .type = PM_QOS_MIN, 426 }; 427 428 /** 429 * cpu_wakeup_latency_qos_limit - Current CPU system wakeup latency QoS limit. 430 * 431 * Returns the current CPU system wakeup latency QoS limit that may have been 432 * requested by user space. 433 */ 434 s32 cpu_wakeup_latency_qos_limit(void) 435 { 436 return pm_qos_read_value(&cpu_wakeup_latency_constraints); 437 } 438 439 static int cpu_wakeup_latency_qos_open(struct inode *inode, struct file *filp) 440 { 441 struct pm_qos_request *req; 442 443 req = kzalloc_obj(*req); 444 if (!req) 445 return -ENOMEM; 446 447 req->qos = &cpu_wakeup_latency_constraints; 448 pm_qos_update_target(req->qos, &req->node, PM_QOS_ADD_REQ, 449 PM_QOS_RESUME_LATENCY_NO_CONSTRAINT); 450 filp->private_data = req; 451 452 return 0; 453 } 454 455 static int cpu_wakeup_latency_qos_release(struct inode *inode, 456 struct file *filp) 457 { 458 struct pm_qos_request *req = filp->private_data; 459 460 filp->private_data = NULL; 461 pm_qos_update_target(req->qos, &req->node, PM_QOS_REMOVE_REQ, 462 PM_QOS_RESUME_LATENCY_NO_CONSTRAINT); 463 kfree(req); 464 465 return 0; 466 } 467 468 static ssize_t cpu_wakeup_latency_qos_read(struct file *filp, char __user *buf, 469 size_t count, loff_t *f_pos) 470 { 471 s32 value = pm_qos_read_value(&cpu_wakeup_latency_constraints); 472 473 return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32)); 474 } 475 476 static ssize_t cpu_wakeup_latency_qos_write(struct file *filp, 477 const char __user *buf, 478 size_t count, loff_t *f_pos) 479 { 480 struct pm_qos_request *req = filp->private_data; 481 s32 value; 482 483 if (count == sizeof(s32)) { 484 if (copy_from_user(&value, buf, sizeof(s32))) 485 return -EFAULT; 486 } else { 487 int ret; 488 489 ret = kstrtos32_from_user(buf, count, 16, &value); 490 if (ret) 491 return ret; 492 } 493 494 if (value < 0) 495 return -EINVAL; 496 497 pm_qos_update_target(req->qos, &req->node, PM_QOS_UPDATE_REQ, value); 498 499 return count; 500 } 501 502 static const struct file_operations cpu_wakeup_latency_qos_fops = { 503 .open = cpu_wakeup_latency_qos_open, 504 .release = cpu_wakeup_latency_qos_release, 505 .read = cpu_wakeup_latency_qos_read, 506 .write = cpu_wakeup_latency_qos_write, 507 .llseek = noop_llseek, 508 }; 509 510 static struct miscdevice cpu_wakeup_latency_qos_miscdev = { 511 .minor = MISC_DYNAMIC_MINOR, 512 .name = "cpu_wakeup_latency", 513 .fops = &cpu_wakeup_latency_qos_fops, 514 }; 515 #endif /* CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP */ 516 517 static int __init cpu_latency_qos_init(void) 518 { 519 int ret; 520 521 ret = misc_register(&cpu_latency_qos_miscdev); 522 if (ret < 0) { 523 pr_err("%s: %s setup failed\n", __func__, 524 cpu_latency_qos_miscdev.name); 525 return ret; 526 } 527 528 #ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP 529 ret = misc_register(&cpu_wakeup_latency_qos_miscdev); 530 if (ret < 0) { 531 pr_err("%s: %s setup failed\n", __func__, 532 cpu_wakeup_latency_qos_miscdev.name); 533 misc_deregister(&cpu_latency_qos_miscdev); 534 return ret; 535 } 536 #endif 537 538 return 0; 539 } 540 late_initcall(cpu_latency_qos_init); 541 #endif /* CONFIG_CPU_IDLE */ 542 543 /* Definitions related to the frequency QoS below. */ 544 545 static inline bool freq_qos_value_invalid(s32 value) 546 { 547 return value < 0 && value != PM_QOS_DEFAULT_VALUE; 548 } 549 550 /** 551 * freq_constraints_init - Initialize frequency QoS constraints. 552 * @qos: Frequency QoS constraints to initialize. 553 */ 554 void freq_constraints_init(struct freq_constraints *qos) 555 { 556 struct pm_qos_constraints *c; 557 558 c = &qos->min_freq; 559 plist_head_init(&c->list); 560 c->target_value = FREQ_QOS_MIN_DEFAULT_VALUE; 561 c->default_value = FREQ_QOS_MIN_DEFAULT_VALUE; 562 c->no_constraint_value = FREQ_QOS_MIN_DEFAULT_VALUE; 563 c->type = PM_QOS_MAX; 564 c->notifiers = &qos->min_freq_notifiers; 565 BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers); 566 567 c = &qos->max_freq; 568 plist_head_init(&c->list); 569 c->target_value = FREQ_QOS_MAX_DEFAULT_VALUE; 570 c->default_value = FREQ_QOS_MAX_DEFAULT_VALUE; 571 c->no_constraint_value = FREQ_QOS_MAX_DEFAULT_VALUE; 572 c->type = PM_QOS_MIN; 573 c->notifiers = &qos->max_freq_notifiers; 574 BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers); 575 } 576 577 /** 578 * freq_qos_read_value - Get frequency QoS constraint for a given list. 579 * @qos: Constraints to evaluate. 580 * @type: QoS request type. 581 */ 582 s32 freq_qos_read_value(struct freq_constraints *qos, 583 enum freq_qos_req_type type) 584 { 585 s32 ret; 586 587 switch (type) { 588 case FREQ_QOS_MIN: 589 ret = IS_ERR_OR_NULL(qos) ? 590 FREQ_QOS_MIN_DEFAULT_VALUE : 591 pm_qos_read_value(&qos->min_freq); 592 break; 593 case FREQ_QOS_MAX: 594 ret = IS_ERR_OR_NULL(qos) ? 595 FREQ_QOS_MAX_DEFAULT_VALUE : 596 pm_qos_read_value(&qos->max_freq); 597 break; 598 default: 599 WARN_ON(1); 600 ret = 0; 601 } 602 603 return ret; 604 } 605 606 /** 607 * freq_qos_apply - Add/modify/remove frequency QoS request. 608 * @req: Constraint request to apply. 609 * @action: Action to perform (add/update/remove). 610 * @value: Value to assign to the QoS request. 611 * 612 * This is only meant to be called from inside pm_qos, not drivers. 613 */ 614 int freq_qos_apply(struct freq_qos_request *req, 615 enum pm_qos_req_action action, s32 value) 616 { 617 int ret; 618 619 switch(req->type) { 620 case FREQ_QOS_MIN: 621 ret = pm_qos_update_target(&req->qos->min_freq, &req->pnode, 622 action, value); 623 break; 624 case FREQ_QOS_MAX: 625 ret = pm_qos_update_target(&req->qos->max_freq, &req->pnode, 626 action, value); 627 break; 628 default: 629 ret = -EINVAL; 630 } 631 632 return ret; 633 } 634 635 /** 636 * freq_qos_add_request - Insert new frequency QoS request into a given list. 637 * @qos: Constraints to update. 638 * @req: Preallocated request object. 639 * @type: Request type. 640 * @value: Request value. 641 * 642 * Insert a new entry into the @qos list of requests, recompute the effective 643 * QoS constraint value for that list and initialize the @req object. The 644 * caller needs to save that object for later use in updates and removal. 645 * 646 * Return 1 if the effective constraint value has changed, 0 if the effective 647 * constraint value has not changed, or a negative error code on failures. 648 */ 649 int freq_qos_add_request(struct freq_constraints *qos, 650 struct freq_qos_request *req, 651 enum freq_qos_req_type type, s32 value) 652 { 653 int ret; 654 655 if (IS_ERR_OR_NULL(qos) || !req || freq_qos_value_invalid(value)) 656 return -EINVAL; 657 658 if (WARN(freq_qos_request_active(req), 659 "%s() called for active request\n", __func__)) 660 return -EINVAL; 661 662 req->qos = qos; 663 req->type = type; 664 ret = freq_qos_apply(req, PM_QOS_ADD_REQ, value); 665 if (ret < 0) { 666 req->qos = NULL; 667 req->type = 0; 668 } 669 670 return ret; 671 } 672 EXPORT_SYMBOL_GPL(freq_qos_add_request); 673 674 /** 675 * freq_qos_update_request - Modify existing frequency QoS request. 676 * @req: Request to modify. 677 * @new_value: New request value. 678 * 679 * Update an existing frequency QoS request along with the effective constraint 680 * value for the list of requests it belongs to. 681 * 682 * Return 1 if the effective constraint value has changed, 0 if the effective 683 * constraint value has not changed, or a negative error code on failures. 684 */ 685 int freq_qos_update_request(struct freq_qos_request *req, s32 new_value) 686 { 687 if (!req || freq_qos_value_invalid(new_value)) 688 return -EINVAL; 689 690 if (WARN(!freq_qos_request_active(req), 691 "%s() called for unknown object\n", __func__)) 692 return -EINVAL; 693 694 if (req->pnode.prio == new_value) 695 return 0; 696 697 return freq_qos_apply(req, PM_QOS_UPDATE_REQ, new_value); 698 } 699 EXPORT_SYMBOL_GPL(freq_qos_update_request); 700 701 /** 702 * freq_qos_remove_request - Remove frequency QoS request from its list. 703 * @req: Request to remove. 704 * 705 * Remove the given frequency QoS request from the list of constraints it 706 * belongs to and recompute the effective constraint value for that list. 707 * 708 * Return 1 if the effective constraint value has changed, 0 if the effective 709 * constraint value has not changed, or a negative error code on failures. 710 */ 711 int freq_qos_remove_request(struct freq_qos_request *req) 712 { 713 int ret; 714 715 if (!req) 716 return -EINVAL; 717 718 if (WARN(!freq_qos_request_active(req), 719 "%s() called for unknown object\n", __func__)) 720 return -EINVAL; 721 722 ret = freq_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); 723 req->qos = NULL; 724 req->type = 0; 725 726 return ret; 727 } 728 EXPORT_SYMBOL_GPL(freq_qos_remove_request); 729 730 /** 731 * freq_qos_add_notifier - Add frequency QoS change notifier. 732 * @qos: List of requests to add the notifier to. 733 * @type: Request type. 734 * @notifier: Notifier block to add. 735 */ 736 int freq_qos_add_notifier(struct freq_constraints *qos, 737 enum freq_qos_req_type type, 738 struct notifier_block *notifier) 739 { 740 int ret; 741 742 if (IS_ERR_OR_NULL(qos) || !notifier) 743 return -EINVAL; 744 745 switch (type) { 746 case FREQ_QOS_MIN: 747 ret = blocking_notifier_chain_register(qos->min_freq.notifiers, 748 notifier); 749 break; 750 case FREQ_QOS_MAX: 751 ret = blocking_notifier_chain_register(qos->max_freq.notifiers, 752 notifier); 753 break; 754 default: 755 WARN_ON(1); 756 ret = -EINVAL; 757 } 758 759 return ret; 760 } 761 EXPORT_SYMBOL_GPL(freq_qos_add_notifier); 762 763 /** 764 * freq_qos_remove_notifier - Remove frequency QoS change notifier. 765 * @qos: List of requests to remove the notifier from. 766 * @type: Request type. 767 * @notifier: Notifier block to remove. 768 */ 769 int freq_qos_remove_notifier(struct freq_constraints *qos, 770 enum freq_qos_req_type type, 771 struct notifier_block *notifier) 772 { 773 int ret; 774 775 if (IS_ERR_OR_NULL(qos) || !notifier) 776 return -EINVAL; 777 778 switch (type) { 779 case FREQ_QOS_MIN: 780 ret = blocking_notifier_chain_unregister(qos->min_freq.notifiers, 781 notifier); 782 break; 783 case FREQ_QOS_MAX: 784 ret = blocking_notifier_chain_unregister(qos->max_freq.notifiers, 785 notifier); 786 break; 787 default: 788 WARN_ON(1); 789 ret = -EINVAL; 790 } 791 792 return ret; 793 } 794 EXPORT_SYMBOL_GPL(freq_qos_remove_notifier); 795