1 /* 2 * Copyright (c) 2015 Intel Corporation. 3 * Copyright (c) 2021 Nordic Semiconductor ASA 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #ifndef ZEPHYR_INCLUDE_PM_DEVICE_RUNTIME_H_ 9 #define ZEPHYR_INCLUDE_PM_DEVICE_RUNTIME_H_ 10 11 #include <zephyr/device.h> 12 #include <zephyr/kernel.h> 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /** 19 * @brief Device Runtime Power Management API 20 * @defgroup subsys_pm_device_runtime Device Runtime 21 * @ingroup subsys_pm 22 * @{ 23 */ 24 25 #if defined(CONFIG_PM_DEVICE_RUNTIME) || defined(__DOXYGEN__) 26 /** 27 * @brief Automatically enable device runtime based on devicetree properties 28 * 29 * @note Must not be called from application code. See the 30 * zephyr,pm-device-runtime-auto property in pm.yaml and z_sys_init_run_level. 31 * 32 * @param dev Device instance. 33 * 34 * @retval 0 If the device runtime PM is enabled successfully or it has not 35 * been requested for this device in devicetree. 36 * @retval -errno Other negative errno, result of enabled device runtime PM. 37 */ 38 int pm_device_runtime_auto_enable(const struct device *dev); 39 40 /** 41 * @brief Enable device runtime PM 42 * 43 * This function will enable runtime PM on the given device. If the device is 44 * in #PM_DEVICE_STATE_ACTIVE state, the device will be suspended. 45 * 46 * @funcprops \pre_kernel_ok 47 * 48 * @param dev Device instance. 49 * 50 * @retval 0 If the device runtime PM is enabled successfully. 51 * @retval -EBUSY If device is busy. 52 * @retval -ENOTSUP If the device does not support PM. 53 * @retval -errno Other negative errno, result of suspending the device. 54 * 55 * @see pm_device_init_suspended() 56 */ 57 int pm_device_runtime_enable(const struct device *dev); 58 59 /** 60 * @brief Disable device runtime PM 61 * 62 * If the device is currently suspended it will be resumed. 63 * 64 * @funcprops \pre_kernel_ok 65 * 66 * @param dev Device instance. 67 * 68 * @retval 0 If the device runtime PM is disabled successfully. 69 * @retval -ENOTSUP If the device does not support PM. 70 * @retval -errno Other negative errno, result of resuming the device. 71 */ 72 int pm_device_runtime_disable(const struct device *dev); 73 74 /** 75 * @brief Resume a device based on usage count. 76 * 77 * This function will resume the device if the device is suspended (usage count 78 * equal to 0). In case of a resume failure, usage count and device state will 79 * be left unchanged. In all other cases, usage count will be incremented. 80 * 81 * If the device is still being suspended as a result of calling 82 * pm_device_runtime_put_async(), this function will wait for the operation to 83 * finish to then resume the device. 84 * 85 * @note It is safe to use this function in contexts where blocking is not 86 * allowed, e.g. ISR, provided the device PM implementation does not block. 87 * 88 * @funcprops \pre_kernel_ok 89 * 90 * @param dev Device instance. 91 * 92 * @retval 0 If it succeeds. In case device runtime PM is not enabled or not 93 * available this function will be a no-op and will also return 0. 94 * @retval -EWOUDBLOCK If call would block but it is not allowed (e.g. in ISR). 95 * @retval -errno Other negative errno, result of the PM action callback. 96 */ 97 int pm_device_runtime_get(const struct device *dev); 98 99 /** 100 * @brief Suspend a device based on usage count. 101 * 102 * This function will suspend the device if the device is no longer required 103 * (usage count equal to 0). In case of suspend failure, usage count and device 104 * state will be left unchanged. In all other cases, usage count will be 105 * decremented (down to 0). 106 * 107 * @funcprops \pre_kernel_ok 108 * 109 * @param dev Device instance. 110 * 111 * @retval 0 If it succeeds. In case device runtime PM is not enabled or not 112 * available this function will be a no-op and will also return 0. 113 * @retval -EALREADY If device is already suspended (can only happen if get/put 114 * calls are unbalanced). 115 * @retval -errno Other negative errno, result of the action callback. 116 * 117 * @see pm_device_runtime_put_async() 118 */ 119 int pm_device_runtime_put(const struct device *dev); 120 121 /** 122 * @brief Suspend a device based on usage count (asynchronously). 123 * 124 * This function will schedule the device suspension if the device is no longer 125 * required (usage count equal to 0). In all other cases, usage count will be 126 * decremented (down to 0). 127 * 128 * @note Asynchronous operations are not supported when in pre-kernel mode. In 129 * this case, the function will be blocking (equivalent to 130 * pm_device_runtime_put()). 131 * 132 * @funcprops \pre_kernel_ok, \async, \isr_ok 133 * 134 * @param dev Device instance. 135 * @param delay Minimum amount of time before triggering the action. 136 * 137 * @retval 0 If it succeeds. In case device runtime PM is not enabled or not 138 * available this function will be a no-op and will also return 0. 139 * @retval -EBUSY If the device is busy. 140 * @retval -EALREADY If device is already suspended (can only happen if get/put 141 * calls are unbalanced). 142 * 143 * @see pm_device_runtime_put() 144 */ 145 int pm_device_runtime_put_async(const struct device *dev, k_timeout_t delay); 146 147 /** 148 * @brief Check if device runtime is enabled for a given device. 149 * 150 * @funcprops \pre_kernel_ok 151 * 152 * @param dev Device instance. 153 * 154 * @retval true If device has device runtime PM enabled. 155 * @retval false If the device has device runtime PM disabled. 156 * 157 * @see pm_device_runtime_enable() 158 */ 159 bool pm_device_runtime_is_enabled(const struct device *dev); 160 161 /** 162 * @brief Return the current device usage counter. 163 * 164 * @param dev Device instance. 165 * 166 * @returns the current usage counter. 167 * @retval -ENOTSUP If the device is not using runtime PM. 168 * @retval -ENOSYS If the runtime PM is not enabled at all. 169 */ 170 int pm_device_runtime_usage(const struct device *dev); 171 172 #else 173 174 static inline int pm_device_runtime_auto_enable(const struct device *dev) 175 { 176 ARG_UNUSED(dev); 177 return 0; 178 } 179 180 static inline int pm_device_runtime_enable(const struct device *dev) 181 { 182 ARG_UNUSED(dev); 183 return 0; 184 } 185 186 static inline int pm_device_runtime_disable(const struct device *dev) 187 { 188 ARG_UNUSED(dev); 189 return 0; 190 } 191 192 static inline int pm_device_runtime_get(const struct device *dev) 193 { 194 ARG_UNUSED(dev); 195 return 0; 196 } 197 198 static inline int pm_device_runtime_put(const struct device *dev) 199 { 200 ARG_UNUSED(dev); 201 return 0; 202 } 203 204 static inline int pm_device_runtime_put_async(const struct device *dev, 205 k_timeout_t delay) 206 { 207 ARG_UNUSED(dev); 208 ARG_UNUSED(delay); 209 return 0; 210 } 211 212 static inline bool pm_device_runtime_is_enabled(const struct device *dev) 213 { 214 ARG_UNUSED(dev); 215 return false; 216 } 217 218 static inline int pm_device_runtime_usage(const struct device *dev) 219 { 220 ARG_UNUSED(dev); 221 return -ENOSYS; 222 } 223 224 #endif 225 226 /** @} */ 227 228 #ifdef __cplusplus 229 } 230 #endif 231 232 #endif /* ZEPHYR_INCLUDE_PM_DEVICE_RUNTIME_H_ */ 233