1 /* 2 * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #ifndef __HIF_RUNTIME_PM_H__ 19 #define __HIF_RUNTIME_PM_H__ 20 21 #ifdef FEATURE_RUNTIME_PM 22 #include <linux/pm_runtime.h> 23 24 /** 25 * enum hif_rtpm_state - Driver States for Runtime Power Management 26 * @HIF_RTPM_STATE_NONE: runtime pm is off 27 * @HIF_RTPM_STATE_ON: runtime pm is active and link is active 28 * @HIF_RTPM_STATE_RESUMING: a runtime resume is in progress 29 * @HIF_RTPM_STATE_RESUMING_LINKUP: Link is up during resume 30 * @HIF_RTPM_STATE_SUSPENDING: a runtime suspend is in progress 31 * @HIF_RTPM_STATE_SUSPENDED: the driver is runtime suspended 32 */ 33 enum hif_rtpm_state { 34 HIF_RTPM_STATE_NONE, 35 HIF_RTPM_STATE_ON, 36 HIF_RTPM_STATE_RESUMING_LINKUP, 37 HIF_RTPM_STATE_RESUMING, 38 HIF_RTPM_STATE_SUSPENDING, 39 HIF_RTPM_STATE_SUSPENDED, 40 }; 41 42 /** 43 * struct hif_rtpm_state_stats - Runtime PM stats 44 * @resume_count: count of resume calls done 45 * @suspend_count: count of suspend calls done 46 * @suspend_err_count: count of suspend calls failed 47 * @resume_ts: Last resume call timestamp 48 * @suspend_ts: Last suspend call timestamp 49 * @suspend_err_ts: Last suspend call fail timestamp 50 * @last_busy_ts: Last busy timestamp marked 51 * @request_resume_ts: Last request resume done timestamp 52 * @request_resume_ts: Client ID requesting resume 53 */ 54 struct hif_rtpm_state_stats { 55 uint32_t resume_count; 56 uint32_t suspend_count; 57 uint32_t suspend_err_count; 58 uint64_t resume_ts; 59 uint64_t suspend_ts; 60 uint64_t suspend_err_ts; 61 uint64_t last_busy_ts; 62 uint32_t last_busy_id; 63 void *last_busy_marker; 64 uint64_t request_resume_ts; 65 uint64_t request_resume_id; 66 uint32_t prevent_suspend; 67 uint32_t allow_suspend; 68 uint32_t runtime_get_err; 69 }; 70 71 /** 72 * struct hif_rtpm_client - Runtime PM client structure 73 * @hif_rtpm_cbk: Callback during resume if get called at suspend and failed 74 * @prevent_multiple_get: Client restricted to not calling get and put calls 75 * simultaneously 76 * @active_count: current active status of client 77 * @get_count: count of get calls by this client 78 * @put_count: count of put calls by this client 79 * @get_ts: Last get called timestamp 80 * @put_ts: Last put called timestamp 81 * @request_resume_ts: client request resume timestamp 82 */ 83 struct hif_rtpm_client { 84 void (*hif_rtpm_cbk)(void); 85 qdf_atomic_t active_count; 86 qdf_atomic_t get_count; 87 qdf_atomic_t put_count; 88 uint32_t last_busy_cnt; 89 uint64_t get_ts; 90 uint64_t put_ts; 91 uint64_t last_busy_ts; 92 }; 93 94 /** 95 * struct hif_rtpm_ctx - Runtime power management context 96 * @runtime_lock: Lock to sync state changes with get calls 97 * @runtime_suspend_lock: Suspend lock 98 * @client_count: Number of clients currently registered 99 * @clients: clients registered to use runtime PM module 100 * @pm_state: Current runtime pm state 101 * @pending_job: bitmap to set the client job to be called at resume 102 * @monitor_wake_intr: Monitor waking MSI for runtime PM 103 * @stats: Runtime PM stats 104 * @pm_entry: debug fs entry 105 */ 106 struct hif_rtpm_ctx { 107 bool enable_rpm; 108 struct device *dev; 109 qdf_spinlock_t runtime_lock; 110 qdf_spinlock_t runtime_suspend_lock; 111 unsigned int client_count; 112 struct hif_rtpm_client *clients[HIF_RTPM_ID_MAX]; 113 qdf_spinlock_t prevent_list_lock; 114 struct list_head prevent_list; 115 uint32_t prevent_cnt; 116 qdf_atomic_t pm_state; 117 unsigned long pending_job; 118 qdf_atomic_t monitor_wake_intr; 119 struct hif_rtpm_state_stats stats; 120 struct dentry *pm_dentry; 121 }; 122 123 /** 124 * __hif_rtpm_enabled() - Check if runtime pm is enabled from kernel 125 * @dev: device structure 126 * 127 * Return: true if enabled. 128 */ 129 static inline bool __hif_rtpm_enabled(struct device *dev) 130 { 131 return pm_runtime_enabled(dev); 132 } 133 134 /** 135 * __hif_rtpm_get() - Increment dev usage count and call resume function 136 * @dev: device structure 137 * 138 * Increments usage count and internally queue resume work 139 * 140 * Return: 1 if state is active. 0 if resume is requested. Error otherwise. 141 */ 142 static inline int __hif_rtpm_get(struct device *dev) 143 { 144 return pm_runtime_get(dev); 145 } 146 147 /** 148 * __hif_rtpm_get_noresume() - Only increment dev usage count 149 * @dev: device structure 150 * 151 * Return: Void 152 */ 153 static inline void __hif_rtpm_get_noresume(struct device *dev) 154 { 155 pm_runtime_get_noresume(dev); 156 } 157 158 /** 159 * __hif_rtpm_get_sync() - Increment usage count and set state to active 160 * @dev: device structure 161 * 162 * Return: 1 if state is already active, 0 if state active was done. 163 * Error otherwise. 164 */ 165 static inline int __hif_rtpm_get_sync(struct device *dev) 166 { 167 return pm_runtime_get_sync(dev); 168 } 169 170 /** 171 * __hif_rtpm_put_auto() - Decrement usage count and call suspend function 172 * @dev: device structure 173 * 174 * Decrements usage count and queue suspend work if usage count is 0 175 * 176 * Return: 0 if success. Error otherwise. 177 */ 178 static inline int __hif_rtpm_put_auto(struct device *dev) 179 { 180 return pm_runtime_put_autosuspend(dev); 181 } 182 183 /** 184 * __hif_rtpm_put_noidle() - Decrement usage count 185 * @dev: device structure 186 * 187 * Return: void 188 */ 189 static inline void __hif_rtpm_put_noidle(struct device *dev) 190 { 191 pm_runtime_put_noidle(dev); 192 } 193 194 /** 195 * __hif_rtpm_put_sync_suspend() - Decrement usage count 196 * @dev: device structure 197 * 198 * Decrement usage_count of device and if 0 synchrounsly call suspend function 199 * 200 * Return: 0 if success. Error otherwise 201 */ 202 static inline int __hif_rtpm_put_sync_suspend(struct device *dev) 203 { 204 return pm_runtime_put_sync_suspend(dev); 205 } 206 207 /** 208 * __hif_rtpm_mark_last_busy() - Mark last busy timestamp 209 * @dev: device structure 210 * 211 * Return: Void 212 */ 213 static inline void __hif_rtpm_mark_last_busy(struct device *dev) 214 { 215 pm_runtime_mark_last_busy(dev); 216 } 217 218 /** 219 * __hif_rtpm_resume() - Do Runtime PM Resume of bus 220 * dev: device structure 221 * 222 * Return: 0 if success. Error otherwise 223 */ 224 static inline int __hif_rtpm_resume(struct device *dev) 225 { 226 return pm_runtime_resume(dev); 227 } 228 229 /** 230 * __hif_rtpm_request_resume() - Queue resume work 231 * dev: device structure 232 * 233 * Return: 1 if already active. 0 if successfully queued. Error otherwise 234 */ 235 static inline int __hif_rtpm_request_resume(struct device *dev) 236 { 237 return pm_request_resume(dev); 238 } 239 240 /** 241 * hif_rtpm_open() - initialize runtime pm 242 * @scn: hif ctx 243 * 244 * Return: None 245 */ 246 void hif_rtpm_open(struct hif_softc *scn); 247 248 /** 249 * hif_rtpm_close() - close runtime pm 250 * @scn: hif ctx 251 * 252 * ensure runtime_pm is stopped before closing the driver 253 * 254 * Return: None 255 */ 256 void hif_rtpm_close(struct hif_softc *scn); 257 258 /** 259 * hif_rtpm_start() - start the runtime pm 260 * @scn: hif context 261 * 262 * After this call, runtime pm will be active. 263 * 264 * Return: None 265 */ 266 void hif_rtpm_start(struct hif_softc *scn); 267 268 /** 269 * hif_rtpm_stop() - stop runtime pm 270 * @scn: hif context 271 * 272 * Turns off runtime pm and frees corresponding resources 273 * that were acquired by hif_rtpm_start(). 274 * 275 * Return: None 276 */ 277 void hif_rtpm_stop(struct hif_softc *scn); 278 #else 279 static inline void hif_rtpm_open(struct hif_softc *scn) {} 280 static inline void hif_rtpm_close(struct hif_softc *scn) {} 281 static inline void hif_rtpm_start(struct hif_softc *scn) {} 282 static inline void hif_rtpm_stop(struct hif_softc *scn) {} 283 #endif /* FEATURE_RUNTIME_PM */ 284 #endif /* __HIF_RUNTIME_PM_H__ */ 285