| Richard Hughes | bf1db69 | 2008-08-05 13:01:35 -0700 | [diff] [blame] | 1 | PM Quality Of Service Interface. | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 2 |  | 
 | 3 | This interface provides a kernel and user mode interface for registering | 
 | 4 | performance expectations by drivers, subsystems and user space applications on | 
 | 5 | one of the parameters. | 
 | 6 |  | 
| Jean Pihet | e3cba32 | 2011-10-04 21:54:45 +0200 | [diff] [blame] | 7 | Two different PM QoS frameworks are available: | 
 | 8 | 1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput. | 
 | 9 | 2. the per-device PM QoS framework provides the API to manage the per-device latency | 
 | 10 | constraints. | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 11 |  | 
| Richard Hughes | bf1db69 | 2008-08-05 13:01:35 -0700 | [diff] [blame] | 12 | Each parameters have defined units: | 
 | 13 |  * latency: usec | 
 | 14 |  * timeout: usec | 
 | 15 |  * throughput: kbs (kilo bit / sec) | 
 | 16 |  | 
| Jean Pihet | e3cba32 | 2011-10-04 21:54:45 +0200 | [diff] [blame] | 17 |  | 
 | 18 | 1. PM QoS framework | 
 | 19 |  | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 20 | The infrastructure exposes multiple misc device nodes one per implemented | 
 | 21 | parameter.  The set of parameters implement is defined by pm_qos_power_init() | 
 | 22 | and pm_qos_params.h.  This is done because having the available parameters | 
 | 23 | being runtime configurable or changeable from a driver was seen as too easy to | 
 | 24 | abuse. | 
 | 25 |  | 
| Mark Gross | ed77134 | 2010-05-06 01:59:26 +0200 | [diff] [blame] | 26 | For each parameter a list of performance requests is maintained along with | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 27 | an aggregated target value.  The aggregated target value is updated with | 
| Mark Gross | ed77134 | 2010-05-06 01:59:26 +0200 | [diff] [blame] | 28 | changes to the request list or elements of the list.  Typically the | 
 | 29 | aggregated target value is simply the max or min of the request values held | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 30 | in the parameter list elements. | 
| Jean Pihet | e3cba32 | 2011-10-04 21:54:45 +0200 | [diff] [blame] | 31 | Note: the aggregated target value is implemented as an atomic variable so that | 
 | 32 | reading the aggregated value does not require any locking mechanism. | 
 | 33 |  | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 34 |  | 
 | 35 | From kernel mode the use of this interface is simple: | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 36 |  | 
| Jean Pihet | e3cba32 | 2011-10-04 21:54:45 +0200 | [diff] [blame] | 37 | void pm_qos_add_request(handle, param_class, target_value): | 
 | 38 | Will insert an element into the list for that identified PM QoS class with the | 
| Mark Gross | ed77134 | 2010-05-06 01:59:26 +0200 | [diff] [blame] | 39 | target value.  Upon change to this list the new target is recomputed and any | 
 | 40 | registered notifiers are called only if the target value is now different. | 
| Jean Pihet | e3cba32 | 2011-10-04 21:54:45 +0200 | [diff] [blame] | 41 | Clients of pm_qos need to save the returned handle for future use in other | 
 | 42 | pm_qos API functions. | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 43 |  | 
| Mark Gross | ed77134 | 2010-05-06 01:59:26 +0200 | [diff] [blame] | 44 | void pm_qos_update_request(handle, new_target_value): | 
 | 45 | Will update the list element pointed to by the handle with the new target value | 
 | 46 | and recompute the new aggregated target, calling the notification tree if the | 
 | 47 | target is changed. | 
 | 48 |  | 
 | 49 | void pm_qos_remove_request(handle): | 
 | 50 | Will remove the element.  After removal it will update the aggregate target and | 
 | 51 | call the notification tree if the target was changed as a result of removing | 
 | 52 | the request. | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 53 |  | 
| Jean Pihet | e3cba32 | 2011-10-04 21:54:45 +0200 | [diff] [blame] | 54 | int pm_qos_request(param_class): | 
 | 55 | Returns the aggregated value for a given PM QoS class. | 
 | 56 |  | 
 | 57 | int pm_qos_request_active(handle): | 
 | 58 | Returns if the request is still active, i.e. it has not been removed from a | 
 | 59 | PM QoS class constraints list. | 
 | 60 |  | 
 | 61 | int pm_qos_add_notifier(param_class, notifier): | 
 | 62 | Adds a notification callback function to the PM QoS class. The callback is | 
 | 63 | called when the aggregated value for the PM QoS class is changed. | 
 | 64 |  | 
 | 65 | int pm_qos_remove_notifier(int param_class, notifier): | 
 | 66 | Removes the notification callback function for the PM QoS class. | 
 | 67 |  | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 68 |  | 
 | 69 | From user mode: | 
| Mark Gross | ed77134 | 2010-05-06 01:59:26 +0200 | [diff] [blame] | 70 | Only processes can register a pm_qos request.  To provide for automatic | 
 | 71 | cleanup of a process, the interface requires the process to register its | 
 | 72 | parameter requests in the following way: | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 73 |  | 
 | 74 | To register the default pm_qos target for the specific parameter, the process | 
 | 75 | must open one of /dev/[cpu_dma_latency, network_latency, network_throughput] | 
 | 76 |  | 
 | 77 | As long as the device node is held open that process has a registered | 
| Mark Gross | ed77134 | 2010-05-06 01:59:26 +0200 | [diff] [blame] | 78 | request on the parameter. | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 79 |  | 
| Mark Gross | ed77134 | 2010-05-06 01:59:26 +0200 | [diff] [blame] | 80 | To change the requested target value the process needs to write an s32 value to | 
 | 81 | the open device node.  Alternatively the user mode program could write a hex | 
 | 82 | string for the value using 10 char long format e.g. "0x12345678".  This | 
 | 83 | translates to a pm_qos_update_request call. | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 84 |  | 
 | 85 | To remove the user mode request for a target value simply close the device | 
 | 86 | node. | 
 | 87 |  | 
 | 88 |  | 
| Jean Pihet | e3cba32 | 2011-10-04 21:54:45 +0200 | [diff] [blame] | 89 | 2. PM QoS per-device latency framework | 
 | 90 |  | 
 | 91 | For each device a list of performance requests is maintained along with | 
 | 92 | an aggregated target value.  The aggregated target value is updated with | 
 | 93 | changes to the request list or elements of the list.  Typically the | 
 | 94 | aggregated target value is simply the max or min of the request values held | 
 | 95 | in the parameter list elements. | 
 | 96 | Note: the aggregated target value is implemented as an atomic variable so that | 
 | 97 | reading the aggregated value does not require any locking mechanism. | 
 | 98 |  | 
 | 99 |  | 
 | 100 | From kernel mode the use of this interface is the following: | 
 | 101 |  | 
 | 102 | int dev_pm_qos_add_request(device, handle, value): | 
 | 103 | Will insert an element into the list for that identified device with the | 
 | 104 | target value.  Upon change to this list the new target is recomputed and any | 
 | 105 | registered notifiers are called only if the target value is now different. | 
 | 106 | Clients of dev_pm_qos need to save the handle for future use in other | 
 | 107 | dev_pm_qos API functions. | 
 | 108 |  | 
 | 109 | int dev_pm_qos_update_request(handle, new_value): | 
 | 110 | Will update the list element pointed to by the handle with the new target value | 
 | 111 | and recompute the new aggregated target, calling the notification trees if the | 
 | 112 | target is changed. | 
 | 113 |  | 
 | 114 | int dev_pm_qos_remove_request(handle): | 
 | 115 | Will remove the element.  After removal it will update the aggregate target and | 
 | 116 | call the notification trees if the target was changed as a result of removing | 
 | 117 | the request. | 
 | 118 |  | 
 | 119 | s32 dev_pm_qos_read_value(device): | 
 | 120 | Returns the aggregated value for a given device's constraints list. | 
 | 121 |  | 
 | 122 |  | 
 | 123 | Notification mechanisms: | 
 | 124 | The per-device PM QoS framework has 2 different and distinct notification trees: | 
 | 125 | a per-device notification tree and a global notification tree. | 
 | 126 |  | 
 | 127 | int dev_pm_qos_add_notifier(device, notifier): | 
 | 128 | Adds a notification callback function for the device. | 
 | 129 | The callback is called when the aggregated value of the device constraints list | 
 | 130 | is changed. | 
 | 131 |  | 
 | 132 | int dev_pm_qos_remove_notifier(device, notifier): | 
 | 133 | Removes the notification callback function for the device. | 
 | 134 |  | 
 | 135 | int dev_pm_qos_add_global_notifier(notifier): | 
 | 136 | Adds a notification callback function in the global notification tree of the | 
 | 137 | framework. | 
 | 138 | The callback is called when the aggregated value for any device is changed. | 
 | 139 |  | 
 | 140 | int dev_pm_qos_remove_global_notifier(notifier): | 
 | 141 | Removes the notification callback function from the global notification tree | 
 | 142 | of the framework. | 
 | 143 |  | 
 | 144 |  | 
 | 145 | From user mode: | 
 | 146 | No API for user space access to the per-device latency constraints is provided | 
 | 147 | yet - still under discussion. | 
| Mark Gross | d82b351 | 2008-02-04 22:30:08 -0800 | [diff] [blame] | 148 |  |