0001 ===============================
0002 PM Quality Of Service Interface
0003 ===============================
0004
0005 This interface provides a kernel and user mode interface for registering
0006 performance expectations by drivers, subsystems and user space applications on
0007 one of the parameters.
0008
0009 Two different PM QoS frameworks are available:
0010 * CPU latency QoS.
0011 * The per-device PM QoS framework provides the API to manage the
0012 per-device latency constraints and PM QoS flags.
0013
0014 The latency unit used in the PM QoS framework is the microsecond (usec).
0015
0016
0017 1. PM QoS framework
0018 ===================
0019
0020 A global list of CPU latency QoS requests is maintained along with an aggregated
0021 (effective) target value. The aggregated target value is updated with changes
0022 to the request list or elements of the list. For CPU latency QoS, the
0023 aggregated target value is simply the min of the request values held in the list
0024 elements.
0025
0026 Note: the aggregated target value is implemented as an atomic variable so that
0027 reading the aggregated value does not require any locking mechanism.
0028
0029 From kernel space the use of this interface is simple:
0030
0031 void cpu_latency_qos_add_request(handle, target_value):
0032 Will insert an element into the CPU latency QoS list with the target value.
0033 Upon change to this list the new target is recomputed and any registered
0034 notifiers are called only if the target value is now different.
0035 Clients of PM QoS need to save the returned handle for future use in other
0036 PM QoS API functions.
0037
0038 void cpu_latency_qos_update_request(handle, new_target_value):
0039 Will update the list element pointed to by the handle with the new target
0040 value and recompute the new aggregated target, calling the notification tree
0041 if the target is changed.
0042
0043 void cpu_latency_qos_remove_request(handle):
0044 Will remove the element. After removal it will update the aggregate target
0045 and call the notification tree if the target was changed as a result of
0046 removing the request.
0047
0048 int cpu_latency_qos_limit():
0049 Returns the aggregated value for the CPU latency QoS.
0050
0051 int cpu_latency_qos_request_active(handle):
0052 Returns if the request is still active, i.e. it has not been removed from the
0053 CPU latency QoS list.
0054
0055 int cpu_latency_qos_add_notifier(notifier):
0056 Adds a notification callback function to the CPU latency QoS. The callback is
0057 called when the aggregated value for the CPU latency QoS is changed.
0058
0059 int cpu_latency_qos_remove_notifier(notifier):
0060 Removes the notification callback function from the CPU latency QoS.
0061
0062
0063 From user space:
0064
0065 The infrastructure exposes one device node, /dev/cpu_dma_latency, for the CPU
0066 latency QoS.
0067
0068 Only processes can register a PM QoS request. To provide for automatic
0069 cleanup of a process, the interface requires the process to register its
0070 parameter requests as follows.
0071
0072 To register the default PM QoS target for the CPU latency QoS, the process must
0073 open /dev/cpu_dma_latency.
0074
0075 As long as the device node is held open that process has a registered
0076 request on the parameter.
0077
0078 To change the requested target value, the process needs to write an s32 value to
0079 the open device node. Alternatively, it can write a hex string for the value
0080 using the 10 char long format e.g. "0x12345678". This translates to a
0081 cpu_latency_qos_update_request() call.
0082
0083 To remove the user mode request for a target value simply close the device
0084 node.
0085
0086
0087 2. PM QoS per-device latency and flags framework
0088 ================================================
0089
0090 For each device, there are three lists of PM QoS requests. Two of them are
0091 maintained along with the aggregated targets of resume latency and active
0092 state latency tolerance (in microseconds) and the third one is for PM QoS flags.
0093 Values are updated in response to changes of the request list.
0094
0095 The target values of resume latency and active state latency tolerance are
0096 simply the minimum of the request values held in the parameter list elements.
0097 The PM QoS flags aggregate value is a gather (bitwise OR) of all list elements'
0098 values. One device PM QoS flag is defined currently: PM_QOS_FLAG_NO_POWER_OFF.
0099
0100 Note: The aggregated target values are implemented in such a way that reading
0101 the aggregated value does not require any locking mechanism.
0102
0103
0104 From kernel mode the use of this interface is the following:
0105
0106 int dev_pm_qos_add_request(device, handle, type, value):
0107 Will insert an element into the list for that identified device with the
0108 target value. Upon change to this list the new target is recomputed and any
0109 registered notifiers are called only if the target value is now different.
0110 Clients of dev_pm_qos need to save the handle for future use in other
0111 dev_pm_qos API functions.
0112
0113 int dev_pm_qos_update_request(handle, new_value):
0114 Will update the list element pointed to by the handle with the new target
0115 value and recompute the new aggregated target, calling the notification
0116 trees if the target is changed.
0117
0118 int dev_pm_qos_remove_request(handle):
0119 Will remove the element. After removal it will update the aggregate target
0120 and call the notification trees if the target was changed as a result of
0121 removing the request.
0122
0123 s32 dev_pm_qos_read_value(device, type):
0124 Returns the aggregated value for a given device's constraints list.
0125
0126 enum pm_qos_flags_status dev_pm_qos_flags(device, mask)
0127 Check PM QoS flags of the given device against the given mask of flags.
0128 The meaning of the return values is as follows:
0129
0130 PM_QOS_FLAGS_ALL:
0131 All flags from the mask are set
0132 PM_QOS_FLAGS_SOME:
0133 Some flags from the mask are set
0134 PM_QOS_FLAGS_NONE:
0135 No flags from the mask are set
0136 PM_QOS_FLAGS_UNDEFINED:
0137 The device's PM QoS structure has not been initialized
0138 or the list of requests is empty.
0139
0140 int dev_pm_qos_add_ancestor_request(dev, handle, type, value)
0141 Add a PM QoS request for the first direct ancestor of the given device whose
0142 power.ignore_children flag is unset (for DEV_PM_QOS_RESUME_LATENCY requests)
0143 or whose power.set_latency_tolerance callback pointer is not NULL (for
0144 DEV_PM_QOS_LATENCY_TOLERANCE requests).
0145
0146 int dev_pm_qos_expose_latency_limit(device, value)
0147 Add a request to the device's PM QoS list of resume latency constraints and
0148 create a sysfs attribute pm_qos_resume_latency_us under the device's power
0149 directory allowing user space to manipulate that request.
0150
0151 void dev_pm_qos_hide_latency_limit(device)
0152 Drop the request added by dev_pm_qos_expose_latency_limit() from the device's
0153 PM QoS list of resume latency constraints and remove sysfs attribute
0154 pm_qos_resume_latency_us from the device's power directory.
0155
0156 int dev_pm_qos_expose_flags(device, value)
0157 Add a request to the device's PM QoS list of flags and create sysfs attribute
0158 pm_qos_no_power_off under the device's power directory allowing user space to
0159 change the value of the PM_QOS_FLAG_NO_POWER_OFF flag.
0160
0161 void dev_pm_qos_hide_flags(device)
0162 Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS
0163 list of flags and remove sysfs attribute pm_qos_no_power_off from the device's
0164 power directory.
0165
0166 Notification mechanisms:
0167
0168 The per-device PM QoS framework has a per-device notification tree.
0169
0170 int dev_pm_qos_add_notifier(device, notifier, type):
0171 Adds a notification callback function for the device for a particular request
0172 type.
0173
0174 The callback is called when the aggregated value of the device constraints
0175 list is changed.
0176
0177 int dev_pm_qos_remove_notifier(device, notifier, type):
0178 Removes the notification callback function for the device.
0179
0180
0181 Active state latency tolerance
0182 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0183
0184 This device PM QoS type is used to support systems in which hardware may switch
0185 to energy-saving operation modes on the fly. In those systems, if the operation
0186 mode chosen by the hardware attempts to save energy in an overly aggressive way,
0187 it may cause excess latencies to be visible to software, causing it to miss
0188 certain protocol requirements or target frame or sample rates etc.
0189
0190 If there is a latency tolerance control mechanism for a given device available
0191 to software, the .set_latency_tolerance callback in that device's dev_pm_info
0192 structure should be populated. The routine pointed to by it is should implement
0193 whatever is necessary to transfer the effective requirement value to the
0194 hardware.
0195
0196 Whenever the effective latency tolerance changes for the device, its
0197 .set_latency_tolerance() callback will be executed and the effective value will
0198 be passed to it. If that value is negative, which means that the list of
0199 latency tolerance requirements for the device is empty, the callback is expected
0200 to switch the underlying hardware latency tolerance control mechanism to an
0201 autonomous mode if available. If that value is PM_QOS_LATENCY_ANY, in turn, and
0202 the hardware supports a special "no requirement" setting, the callback is
0203 expected to use it. That allows software to prevent the hardware from
0204 automatically updating the device's latency tolerance in response to its power
0205 state changes (e.g. during transitions from D3cold to D0), which generally may
0206 be done in the autonomous latency tolerance control mode.
0207
0208 If .set_latency_tolerance() is present for the device, sysfs attribute
0209 pm_qos_latency_tolerance_us will be present in the devivce's power directory.
0210 Then, user space can use that attribute to specify its latency tolerance
0211 requirement for the device, if any. Writing "any" to it means "no requirement,
0212 but do not let the hardware control latency tolerance" and writing "auto" to it
0213 allows the hardware to be switched to the autonomous mode if there are no other
0214 requirements from the kernel side in the device's list.
0215
0216 Kernel code can use the functions described above along with the
0217 DEV_PM_QOS_LATENCY_TOLERANCE device PM QoS type to add, remove and update
0218 latency tolerance requirements for devices.