1 /* 2 * Copyright (c) 2014-2017 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_queue_work - Queue the work/task 147 * @hdl: OS handle 148 * @wqueue: pointer to workqueue 149 * @work: pointer to work 150 * Return: none 151 */ 152 static inline void 153 qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work) 154 { 155 return __qdf_queue_work(wqueue, work); 156 } 157 158 /** 159 * qdf_queue_delayed_work - Queue the delayed work/task 160 * @wqueue: pointer to workqueue 161 * @work: pointer to work 162 * @delay: delay interval in milliseconds 163 * Return: none 164 */ 165 static inline void qdf_queue_delayed_work(qdf_workqueue_t *wqueue, 166 qdf_delayed_work_t *work, 167 uint32_t delay) 168 { 169 return __qdf_queue_delayed_work(wqueue, work, delay); 170 } 171 172 /** 173 * qdf_flush_workqueue - flush the workqueue 174 * @hdl: OS handle 175 * @wqueue: pointer to workqueue 176 * Return: none 177 */ 178 static inline void qdf_flush_workqueue(qdf_handle_t hdl, 179 qdf_workqueue_t *wqueue) 180 { 181 return __qdf_flush_workqueue(wqueue); 182 } 183 184 /** 185 * qdf_destroy_workqueue - Destroy the workqueue 186 * @hdl: OS handle 187 * @wqueue: pointer to workqueue 188 * Return: none 189 */ 190 static inline void qdf_destroy_workqueue(qdf_handle_t hdl, 191 qdf_workqueue_t *wqueue) 192 { 193 return __qdf_destroy_workqueue(wqueue); 194 } 195 196 /** 197 * qdf_sched_work - Schedule a deferred task on non-interrupt context 198 * @hdl: OS handle 199 * @work: pointer to work 200 * Retrun: none 201 */ 202 static inline void qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work) 203 { 204 __qdf_sched_work(work); 205 } 206 207 /** 208 * qdf_sched_delayed_work() - Schedule a delayed task 209 * @work: pointer to delayed work 210 * @delay: delay interval in milliseconds 211 * Return: none 212 */ 213 static inline void 214 qdf_sched_delayed_work(qdf_delayed_work_t *work, uint32_t delay) 215 { 216 __qdf_sched_delayed_work(work, delay); 217 } 218 219 /** 220 * qdf_cancel_work() - Cancel a work 221 * @work: pointer to work 222 * 223 * Cancel work and wait for its execution to finish. 224 * This function can be used even if the work re-queues 225 * itself or migrates to another workqueue. On return 226 * from this function, work is guaranteed to be not 227 * pending or executing on any CPU. The caller must 228 * ensure that the workqueue on which work was last 229 * queued can't be destroyed before this function returns. 230 * 231 * Return: true if work was pending, false otherwise 232 */ 233 static inline bool qdf_cancel_work(qdf_work_t *work) 234 { 235 return __qdf_cancel_work(work); 236 } 237 238 /** 239 * qdf_cancel_delayed_work() - Cancel a delayed work 240 * @work: pointer to delayed work 241 * 242 * This is qdf_cancel_work for delayed works. 243 * 244 * Return: true if work was pending, false otherwise 245 */ 246 static inline bool qdf_cancel_delayed_work(qdf_delayed_work_t *work) 247 { 248 return __qdf_cancel_delayed_work(work); 249 } 250 251 /** 252 * qdf_flush_work - Flush a deferred task on non-interrupt context 253 * @work: pointer to work 254 * 255 * Wait until work has finished execution. work is guaranteed to be 256 * idle on return if it hasn't been requeued since flush started. 257 * 258 * Return: none 259 */ 260 static inline void qdf_flush_work(qdf_work_t *work) 261 { 262 __qdf_flush_work(work); 263 } 264 265 /** 266 * qdf_flush_delayed_work() - Flush a delayed work 267 * @work: pointer to delayed work 268 * 269 * This is qdf_flush_work for delayed works. 270 * 271 * Return: none 272 */ 273 static inline void qdf_flush_delayed_work(qdf_delayed_work_t *work) 274 { 275 __qdf_flush_delayed_work(work); 276 } 277 278 /** 279 * qdf_disable_work - disable the deferred task (synchronous) 280 * @work: pointer to work 281 * Return: unsigned int 282 */ 283 static inline uint32_t qdf_disable_work(qdf_work_t *work) 284 { 285 return __qdf_disable_work(work); 286 } 287 288 /** 289 * qdf_destroy_work - destroy the deferred task (synchronous) 290 * @hdl: OS handle 291 * @work: pointer to work 292 * Return: none 293 */ 294 static inline void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work) 295 { 296 __qdf_disable_work(work); 297 } 298 299 #endif /*_QDF_DEFER_H*/ 300