root/kernel/power/qos.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pm_qos_get_value
  2. pm_qos_read_value
  3. pm_qos_set_value
  4. pm_qos_debug_show
  5. pm_qos_update_target
  6. pm_qos_flags_remove_req
  7. pm_qos_update_flags
  8. pm_qos_request
  9. pm_qos_request_active
  10. __pm_qos_update_request
  11. pm_qos_work_fn
  12. pm_qos_add_request
  13. pm_qos_update_request
  14. pm_qos_update_request_timeout
  15. pm_qos_remove_request
  16. pm_qos_add_notifier
  17. pm_qos_remove_notifier
  18. register_pm_qos_misc
  19. find_pm_qos_object_by_minor
  20. pm_qos_power_open
  21. pm_qos_power_release
  22. pm_qos_power_read
  23. pm_qos_power_write
  24. pm_qos_power_init
  25. freq_constraints_init
  26. freq_qos_read_value
  27. freq_qos_apply
  28. freq_qos_add_request
  29. freq_qos_update_request
  30. freq_qos_remove_request
  31. freq_qos_add_notifier
  32. freq_qos_remove_notifier

   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);

/* [<][>][^][v][top][bottom][index][help] */