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