1 /* 2 * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: qdf_defer.h 21 * This file abstracts deferred execution API's. 22 */ 23 24 #ifndef __QDF_DEFER_H 25 #define __QDF_DEFER_H 26 27 #include <qdf_types.h> 28 #include <i_qdf_defer.h> 29 30 /** 31 * TODO This implements work queues (worker threads, kernel threads etc.). 32 * Note that there is no cancel on a scheduled work. You cannot free a work 33 * item if its queued. You cannot know if a work item is queued or not unless 34 * its running, hence you know its not queued. 35 * 36 * so if, say, a module is asked to unload itself, how exactly will it make 37 * sure that the work's not queued, for OS'es that dont provide such a 38 * mechanism?? 39 */ 40 41 /* 42 * Representation of a work queue. 43 */ 44 typedef __qdf_work_t qdf_work_t; 45 typedef __qdf_delayed_work_t qdf_delayed_work_t; 46 typedef __qdf_workqueue_t qdf_workqueue_t; 47 48 /* 49 * Representation of a bottom half. 50 */ 51 typedef __qdf_bh_t qdf_bh_t; 52 53 /** 54 * qdf_create_bh - creates the bottom half deferred handler 55 * @bh: pointer to bottom 56 * @func: deferred function to run at bottom half interrupt context. 57 * @arg: argument for the deferred function 58 * Return: none 59 */ 60 static inline void 61 qdf_create_bh(qdf_bh_t *bh, qdf_defer_fn_t func, void *arg) 62 { 63 __qdf_init_bh(bh, func, arg); 64 } 65 66 /** 67 * qdf_sched - schedule a bottom half (DPC) 68 * @bh: pointer to bottom 69 * Return: none 70 */ 71 static inline void qdf_sched_bh(qdf_bh_t *bh) 72 { 73 __qdf_sched_bh(bh); 74 } 75 76 /** 77 * qdf_destroy_bh - destroy the bh (synchronous) 78 * @bh: pointer to bottom 79 * Return: none 80 */ 81 static inline void qdf_destroy_bh(qdf_bh_t *bh) 82 { 83 __qdf_disable_bh(bh); 84 } 85 86 /*********************Non-Interrupt Context deferred Execution***************/ 87 88 /** 89 * qdf_create_work - create a work/task queue, This runs in non-interrupt 90 * context, so can be preempted by H/W & S/W intr 91 * @hdl: OS handle 92 * @work: pointer to work 93 * @func: deferred function to run at bottom half non-interrupt context. 94 * @arg: argument for the deferred function 95 * 96 * Return: QDF status 97 */ 98 static inline QDF_STATUS qdf_create_work(qdf_handle_t hdl, qdf_work_t *work, 99 qdf_defer_fn_t func, void *arg) 100 { 101 return __qdf_init_work(work, func, arg); 102 } 103 104 /** 105 * qdf_create_delayed_work - create a delayed work/task, This runs in 106 * non-interrupt context, so can be preempted by H/W & S/W intr 107 * @work: pointer to work 108 * @func: deferred function to run at bottom half non-interrupt context. 109 * @arg: argument for the deferred function 110 * Return: none 111 */ 112 static inline void qdf_create_delayed_work(qdf_delayed_work_t *work, 113 qdf_defer_fn_t func, 114 void *arg) 115 { 116 __qdf_init_delayed_work(work, func, arg); 117 } 118 119 /** 120 * qdf_create_workqueue - create a workqueue, This runs in non-interrupt 121 * context, so can be preempted by H/W & S/W intr 122 * @name: string 123 * Return: pointer of type qdf_workqueue_t 124 */ 125 static inline qdf_workqueue_t *qdf_create_workqueue(char *name) 126 { 127 return __qdf_create_workqueue(name); 128 } 129 130 /** 131 * qdf_create_singlethread_workqueue() - create a single threaded workqueue 132 * @name: string 133 * 134 * This API creates a dedicated work queue with a single worker thread to avoid 135 * wasting unnecessary resources when works which needs to be submitted in this 136 * queue are not very critical and frequent. 137 * 138 * Return: pointer of type qdf_workqueue_t 139 */ 140 static inline qdf_workqueue_t *qdf_create_singlethread_workqueue(char *name) 141 { 142 return __qdf_create_singlethread_workqueue(name); 143 } 144 145 /** 146 * qdf_alloc_unbound_workqueue - allocate an unbound workqueue 147 * @name: string 148 * 149 * Return: pointer of type qdf_workqueue_t 150 */ 151 static inline qdf_workqueue_t *qdf_alloc_unbound_workqueue(char *name) 152 { 153 return __qdf_alloc_unbound_workqueue(name); 154 } 155 156 /** 157 * qdf_queue_work - Queue the work/task 158 * @hdl: OS handle 159 * @wqueue: pointer to workqueue 160 * @work: pointer to work 161 * Return: none 162 */ 163 static inline void 164 qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work) 165 { 166 return __qdf_queue_work(wqueue, work); 167 } 168 169 /** 170 * qdf_queue_delayed_work - Queue the delayed work/task 171 * @wqueue: pointer to workqueue 172 * @work: pointer to work 173 * @delay: delay interval in milliseconds 174 * Return: none 175 */ 176 static inline void qdf_queue_delayed_work(qdf_workqueue_t *wqueue, 177 qdf_delayed_work_t *work, 178 uint32_t delay) 179 { 180 return __qdf_queue_delayed_work(wqueue, work, delay); 181 } 182 183 /** 184 * qdf_flush_workqueue - flush the workqueue 185 * @hdl: OS handle 186 * @wqueue: pointer to workqueue 187 * Return: none 188 */ 189 static inline void qdf_flush_workqueue(qdf_handle_t hdl, 190 qdf_workqueue_t *wqueue) 191 { 192 return __qdf_flush_workqueue(wqueue); 193 } 194 195 /** 196 * qdf_destroy_workqueue - Destroy the workqueue 197 * @hdl: OS handle 198 * @wqueue: pointer to workqueue 199 * Return: none 200 */ 201 static inline void qdf_destroy_workqueue(qdf_handle_t hdl, 202 qdf_workqueue_t *wqueue) 203 { 204 return __qdf_destroy_workqueue(wqueue); 205 } 206 207 /** 208 * qdf_sched_work - Schedule a deferred task on non-interrupt context 209 * @hdl: OS handle 210 * @work: pointer to work 211 * Retrun: none 212 */ 213 static inline void qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work) 214 { 215 __qdf_sched_work(work); 216 } 217 218 /** 219 * qdf_sched_delayed_work() - Schedule a delayed task 220 * @work: pointer to delayed work 221 * @delay: delay interval in milliseconds 222 * Return: none 223 */ 224 static inline void 225 qdf_sched_delayed_work(qdf_delayed_work_t *work, uint32_t delay) 226 { 227 __qdf_sched_delayed_work(work, delay); 228 } 229 230 /** 231 * qdf_cancel_work() - Cancel a work 232 * @work: pointer to work 233 * 234 * Cancel work and wait for its execution to finish. 235 * This function can be used even if the work re-queues 236 * itself or migrates to another workqueue. On return 237 * from this function, work is guaranteed to be not 238 * pending or executing on any CPU. The caller must 239 * ensure that the workqueue on which work was last 240 * queued can't be destroyed before this function returns. 241 * 242 * Return: true if work was pending, false otherwise 243 */ 244 static inline bool qdf_cancel_work(qdf_work_t *work) 245 { 246 return __qdf_cancel_work(work); 247 } 248 249 /** 250 * qdf_cancel_delayed_work() - Cancel a delayed work 251 * @work: pointer to delayed work 252 * 253 * This is qdf_cancel_work for delayed works. 254 * 255 * Return: true if work was pending, false otherwise 256 */ 257 static inline bool qdf_cancel_delayed_work(qdf_delayed_work_t *work) 258 { 259 return __qdf_cancel_delayed_work(work); 260 } 261 262 /** 263 * qdf_flush_work - Flush a deferred task on non-interrupt context 264 * @work: pointer to work 265 * 266 * Wait until work has finished execution. work is guaranteed to be 267 * idle on return if it hasn't been requeued since flush started. 268 * 269 * Return: none 270 */ 271 static inline void qdf_flush_work(qdf_work_t *work) 272 { 273 __qdf_flush_work(work); 274 } 275 276 /** 277 * qdf_flush_delayed_work() - Flush a delayed work 278 * @work: pointer to delayed work 279 * 280 * This is qdf_flush_work for delayed works. 281 * 282 * Return: none 283 */ 284 static inline void qdf_flush_delayed_work(qdf_delayed_work_t *work) 285 { 286 __qdf_flush_delayed_work(work); 287 } 288 289 /** 290 * qdf_disable_work - disable the deferred task (synchronous) 291 * @work: pointer to work 292 * Return: unsigned int 293 */ 294 static inline uint32_t qdf_disable_work(qdf_work_t *work) 295 { 296 return __qdf_disable_work(work); 297 } 298 299 /** 300 * qdf_destroy_work - destroy the deferred task (synchronous) 301 * @hdl: OS handle 302 * @work: pointer to work 303 * Return: none 304 */ 305 static inline void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work) 306 { 307 __qdf_disable_work(work); 308 } 309 310 #endif /*_QDF_DEFER_H*/ 311