1 /* 2 * Copyright (c) 2014-2020 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_workqueue_t qdf_workqueue_t; 46 47 /* 48 * Representation of a bottom half. 49 */ 50 typedef __qdf_bh_t qdf_bh_t; 51 52 /** 53 * qdf_create_bh - creates the bottom half deferred handler 54 * @bh: pointer to bottom 55 * @func: deferred function to run at bottom half interrupt context. 56 * @arg: argument for the deferred function 57 * Return: none 58 */ 59 static inline void 60 qdf_create_bh(qdf_bh_t *bh, qdf_defer_fn_t func, void *arg) 61 { 62 __qdf_init_bh(bh, func, arg); 63 } 64 65 /** 66 * qdf_sched - schedule a bottom half (DPC) 67 * @bh: pointer to bottom 68 * Return: none 69 */ 70 static inline void qdf_sched_bh(qdf_bh_t *bh) 71 { 72 __qdf_sched_bh(bh); 73 } 74 75 /** 76 * qdf_destroy_bh - destroy the bh (synchronous) 77 * @bh: pointer to bottom 78 * Return: none 79 */ 80 static inline void qdf_destroy_bh(qdf_bh_t *bh) 81 { 82 __qdf_disable_bh(bh); 83 } 84 85 /*********************Non-Interrupt Context deferred Execution***************/ 86 87 /** 88 * qdf_create_work - create a work/task queue, This runs in non-interrupt 89 * context, so can be preempted by H/W & S/W intr 90 * @hdl: OS handle 91 * @work: pointer to work 92 * @func: deferred function to run at bottom half non-interrupt context. 93 * @arg: argument for the deferred function 94 * 95 * Return: QDF status 96 */ 97 static inline QDF_STATUS qdf_create_work(qdf_handle_t hdl, qdf_work_t *work, 98 qdf_defer_fn_t func, void *arg) 99 { 100 return __qdf_init_work(work, func, arg); 101 } 102 103 /** 104 * qdf_create_workqueue - create a workqueue, This runs in non-interrupt 105 * context, so can be preempted by H/W & S/W intr 106 * @name: string 107 * Return: pointer of type qdf_workqueue_t 108 */ 109 static inline qdf_workqueue_t *qdf_create_workqueue(char *name) 110 { 111 return __qdf_create_workqueue(name); 112 } 113 114 /** 115 * qdf_create_singlethread_workqueue() - create a single threaded workqueue 116 * @name: string 117 * 118 * This API creates a dedicated work queue with a single worker thread to avoid 119 * wasting unnecessary resources when works which needs to be submitted in this 120 * queue are not very critical and frequent. 121 * 122 * Return: pointer of type qdf_workqueue_t 123 */ 124 static inline qdf_workqueue_t *qdf_create_singlethread_workqueue(char *name) 125 { 126 return __qdf_create_singlethread_workqueue(name); 127 } 128 129 /** 130 * qdf_alloc_high_prior_ordered_workqueue - alloc high-prior ordered workqueue 131 * @name: string 132 * 133 * Return: pointer of type qdf_workqueue_t 134 */ 135 static inline 136 qdf_workqueue_t *qdf_alloc_high_prior_ordered_workqueue(char *name) 137 { 138 return __qdf_alloc_high_prior_ordered_workqueue(name); 139 } 140 141 /** 142 * qdf_alloc_unbound_workqueue - allocate an unbound workqueue 143 * @name: string 144 * 145 * Return: pointer of type qdf_workqueue_t 146 */ 147 static inline qdf_workqueue_t *qdf_alloc_unbound_workqueue(char *name) 148 { 149 return __qdf_alloc_unbound_workqueue(name); 150 } 151 152 /** 153 * qdf_queue_work - Queue the work/task 154 * @hdl: OS handle 155 * @wqueue: pointer to workqueue 156 * @work: pointer to work 157 * Return: none 158 */ 159 static inline void 160 qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work) 161 { 162 return __qdf_queue_work(wqueue, work); 163 } 164 165 /** 166 * qdf_flush_workqueue - flush the workqueue 167 * @hdl: OS handle 168 * @wqueue: pointer to workqueue 169 * Return: none 170 */ 171 static inline void qdf_flush_workqueue(qdf_handle_t hdl, 172 qdf_workqueue_t *wqueue) 173 { 174 return __qdf_flush_workqueue(wqueue); 175 } 176 177 /** 178 * qdf_destroy_workqueue - Destroy the workqueue 179 * @hdl: OS handle 180 * @wqueue: pointer to workqueue 181 * Return: none 182 */ 183 static inline void qdf_destroy_workqueue(qdf_handle_t hdl, 184 qdf_workqueue_t *wqueue) 185 { 186 return __qdf_destroy_workqueue(wqueue); 187 } 188 189 /** 190 * qdf_sched_work - Schedule a deferred task on non-interrupt context 191 * @hdl: OS handle 192 * @work: pointer to work 193 * Retrun: none 194 */ 195 static inline void qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work) 196 { 197 __qdf_sched_work(work); 198 } 199 200 /** 201 * qdf_cancel_work() - Cancel a work 202 * @work: pointer to work 203 * 204 * Cancel work and wait for its execution to finish. 205 * This function can be used even if the work re-queues 206 * itself or migrates to another workqueue. On return 207 * from this function, work is guaranteed to be not 208 * pending or executing on any CPU. The caller must 209 * ensure that the workqueue on which work was last 210 * queued can't be destroyed before this function returns. 211 * 212 * Return: true if work was pending, false otherwise 213 */ 214 static inline bool qdf_cancel_work(qdf_work_t *work) 215 { 216 return __qdf_cancel_work(work); 217 } 218 219 /** 220 * qdf_flush_work - Flush a deferred task on non-interrupt context 221 * @work: pointer to work 222 * 223 * Wait until work has finished execution. work is guaranteed to be 224 * idle on return if it hasn't been requeued since flush started. 225 * 226 * Return: none 227 */ 228 static inline void qdf_flush_work(qdf_work_t *work) 229 { 230 __qdf_flush_work(work); 231 } 232 233 /** 234 * qdf_disable_work - disable the deferred task (synchronous) 235 * @work: pointer to work 236 * Return: unsigned int 237 */ 238 static inline uint32_t qdf_disable_work(qdf_work_t *work) 239 { 240 return __qdf_disable_work(work); 241 } 242 243 /** 244 * qdf_destroy_work - destroy the deferred task (synchronous) 245 * @hdl: OS handle 246 * @work: pointer to work 247 * Return: none 248 */ 249 static inline void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work) 250 { 251 __qdf_disable_work(work); 252 } 253 254 #endif /*_QDF_DEFER_H*/ 255