1=============================== 2PM Quality Of Service Interface 3=============================== 4 5This interface provides a kernel and user mode interface for registering 6performance expectations by drivers, subsystems and user space applications on 7one of the parameters. 8 9Two different PM QoS frameworks are available: 10 * CPU latency QoS. 11 * The per-device PM QoS framework provides the API to manage the 12 per-device latency constraints and PM QoS flags. 13 14The latency unit used in the PM QoS framework is the microsecond (usec). 15 16 171. PM QoS framework 18=================== 19 20A global list of CPU latency QoS requests is maintained along with an aggregated 21(effective) target value. The aggregated target value is updated with changes 22to the request list or elements of the list. For CPU latency QoS, the 23aggregated target value is simply the min of the request values held in the list 24elements. 25 26Note: the aggregated target value is implemented as an atomic variable so that 27reading the aggregated value does not require any locking mechanism. 28 29From kernel space the use of this interface is simple: 30 31void cpu_latency_qos_add_request(handle, target_value): 32 Will insert an element into the CPU latency QoS list with the target value. 33 Upon change to this list the new target is recomputed and any registered 34 notifiers are called only if the target value is now different. 35 Clients of PM QoS need to save the returned handle for future use in other 36 PM QoS API functions. 37 38void cpu_latency_qos_update_request(handle, new_target_value): 39 Will update the list element pointed to by the handle with the new target 40 value and recompute the new aggregated target, calling the notification tree 41 if the target is changed. 42 43void cpu_latency_qos_remove_request(handle): 44 Will remove the element. After removal it will update the aggregate target 45 and call the notification tree if the target was changed as a result of 46 removing the request. 47 48int cpu_latency_qos_limit(): 49 Returns the aggregated value for the CPU latency QoS. 50 51int cpu_latency_qos_request_active(handle): 52 Returns if the request is still active, i.e. it has not been removed from the 53 CPU latency QoS list. 54 55 56From user space: 57 58The infrastructure exposes one device node, /dev/cpu_dma_latency, for the CPU 59latency QoS. 60 61Only processes can register a PM QoS request. To provide for automatic 62cleanup of a process, the interface requires the process to register its 63parameter requests as follows. 64 65To register the default PM QoS target for the CPU latency QoS, the process must 66open /dev/cpu_dma_latency. 67 68As long as the device node is held open that process has a registered 69request on the parameter. 70 71To change the requested target value, the process needs to write an s32 value to 72the open device node. Alternatively, it can write a hex string for the value 73using the 10 char long format e.g. "0x12345678". This translates to a 74cpu_latency_qos_update_request() call. 75 76To remove the user mode request for a target value simply close the device 77node. 78 79 802. PM QoS per-device latency and flags framework 81================================================ 82 83For each device, there are three lists of PM QoS requests. Two of them are 84maintained along with the aggregated targets of resume latency and active 85state latency tolerance (in microseconds) and the third one is for PM QoS flags. 86Values are updated in response to changes of the request list. 87 88The target values of resume latency and active state latency tolerance are 89simply the minimum of the request values held in the parameter list elements. 90The PM QoS flags aggregate value is a gather (bitwise OR) of all list elements' 91values. One device PM QoS flag is defined currently: PM_QOS_FLAG_NO_POWER_OFF. 92 93Note: The aggregated target values are implemented in such a way that reading 94the aggregated value does not require any locking mechanism. 95 96 97From kernel mode the use of this interface is the following: 98 99int dev_pm_qos_add_request(device, handle, type, value): 100 Will insert an element into the list for that identified device with the 101 target value. Upon change to this list the new target is recomputed and any 102 registered notifiers are called only if the target value is now different. 103 Clients of dev_pm_qos need to save the handle for future use in other 104 dev_pm_qos API functions. 105 106int dev_pm_qos_update_request(handle, new_value): 107 Will update the list element pointed to by the handle with the new target 108 value and recompute the new aggregated target, calling the notification 109 trees if the target is changed. 110 111int dev_pm_qos_remove_request(handle): 112 Will remove the element. After removal it will update the aggregate target 113 and call the notification trees if the target was changed as a result of 114 removing the request. 115 116s32 dev_pm_qos_read_value(device, type): 117 Returns the aggregated value for a given device's constraints list. 118 119enum pm_qos_flags_status dev_pm_qos_flags(device, mask) 120 Check PM QoS flags of the given device against the given mask of flags. 121 The meaning of the return values is as follows: 122 123 PM_QOS_FLAGS_ALL: 124 All flags from the mask are set 125 PM_QOS_FLAGS_SOME: 126 Some flags from the mask are set 127 PM_QOS_FLAGS_NONE: 128 No flags from the mask are set 129 PM_QOS_FLAGS_UNDEFINED: 130 The device's PM QoS structure has not been initialized 131 or the list of requests is empty. 132 133int dev_pm_qos_add_ancestor_request(dev, handle, type, value) 134 Add a PM QoS request for the first direct ancestor of the given device whose 135 power.ignore_children flag is unset (for DEV_PM_QOS_RESUME_LATENCY requests) 136 or whose power.set_latency_tolerance callback pointer is not NULL (for 137 DEV_PM_QOS_LATENCY_TOLERANCE requests). 138 139int dev_pm_qos_expose_latency_limit(device, value) 140 Add a request to the device's PM QoS list of resume latency constraints and 141 create a sysfs attribute pm_qos_resume_latency_us under the device's power 142 directory allowing user space to manipulate that request. 143 144void dev_pm_qos_hide_latency_limit(device) 145 Drop the request added by dev_pm_qos_expose_latency_limit() from the device's 146 PM QoS list of resume latency constraints and remove sysfs attribute 147 pm_qos_resume_latency_us from the device's power directory. 148 149int dev_pm_qos_expose_flags(device, value) 150 Add a request to the device's PM QoS list of flags and create sysfs attribute 151 pm_qos_no_power_off under the device's power directory allowing user space to 152 change the value of the PM_QOS_FLAG_NO_POWER_OFF flag. 153 154void dev_pm_qos_hide_flags(device) 155 Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS 156 list of flags and remove sysfs attribute pm_qos_no_power_off from the device's 157 power directory. 158 159Notification mechanisms: 160 161The per-device PM QoS framework has a per-device notification tree. 162 163int dev_pm_qos_add_notifier(device, notifier, type): 164 Adds a notification callback function for the device for a particular request 165 type. 166 167 The callback is called when the aggregated value of the device constraints 168 list is changed. 169 170int dev_pm_qos_remove_notifier(device, notifier, type): 171 Removes the notification callback function for the device. 172 173 174Active state latency tolerance 175^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 176 177This device PM QoS type is used to support systems in which hardware may switch 178to energy-saving operation modes on the fly. In those systems, if the operation 179mode chosen by the hardware attempts to save energy in an overly aggressive way, 180it may cause excess latencies to be visible to software, causing it to miss 181certain protocol requirements or target frame or sample rates etc. 182 183If there is a latency tolerance control mechanism for a given device available 184to software, the .set_latency_tolerance callback in that device's dev_pm_info 185structure should be populated. The routine pointed to by it is should implement 186whatever is necessary to transfer the effective requirement value to the 187hardware. 188 189Whenever the effective latency tolerance changes for the device, its 190.set_latency_tolerance() callback will be executed and the effective value will 191be passed to it. If that value is negative, which means that the list of 192latency tolerance requirements for the device is empty, the callback is expected 193to switch the underlying hardware latency tolerance control mechanism to an 194autonomous mode if available. If that value is PM_QOS_LATENCY_ANY, in turn, and 195the hardware supports a special "no requirement" setting, the callback is 196expected to use it. That allows software to prevent the hardware from 197automatically updating the device's latency tolerance in response to its power 198state changes (e.g. during transitions from D3cold to D0), which generally may 199be done in the autonomous latency tolerance control mode. 200 201If .set_latency_tolerance() is present for the device, sysfs attribute 202pm_qos_latency_tolerance_us will be present in the devivce's power directory. 203Then, user space can use that attribute to specify its latency tolerance 204requirement for the device, if any. Writing "any" to it means "no requirement, 205but do not let the hardware control latency tolerance" and writing "auto" to it 206allows the hardware to be switched to the autonomous mode if there are no other 207requirements from the kernel side in the device's list. 208 209Kernel code can use the functions described above along with the 210DEV_PM_QOS_LATENCY_TOLERANCE device PM QoS type to add, remove and update 211latency tolerance requirements for devices. 212