1 /* 2 * Copyright (c) 2014-2019 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_unbound_workqueue - allocate an unbound workqueue 131 * @name: string 132 * 133 * Return: pointer of type qdf_workqueue_t 134 */ 135 static inline qdf_workqueue_t *qdf_alloc_unbound_workqueue(char *name) 136 { 137 return __qdf_alloc_unbound_workqueue(name); 138 } 139 140 /** 141 * qdf_queue_work - Queue the work/task 142 * @hdl: OS handle 143 * @wqueue: pointer to workqueue 144 * @work: pointer to work 145 * Return: none 146 */ 147 static inline void 148 qdf_queue_work(qdf_handle_t hdl, qdf_workqueue_t *wqueue, qdf_work_t *work) 149 { 150 return __qdf_queue_work(wqueue, work); 151 } 152 153 /** 154 * qdf_flush_workqueue - flush the workqueue 155 * @hdl: OS handle 156 * @wqueue: pointer to workqueue 157 * Return: none 158 */ 159 static inline void qdf_flush_workqueue(qdf_handle_t hdl, 160 qdf_workqueue_t *wqueue) 161 { 162 return __qdf_flush_workqueue(wqueue); 163 } 164 165 /** 166 * qdf_destroy_workqueue - Destroy the workqueue 167 * @hdl: OS handle 168 * @wqueue: pointer to workqueue 169 * Return: none 170 */ 171 static inline void qdf_destroy_workqueue(qdf_handle_t hdl, 172 qdf_workqueue_t *wqueue) 173 { 174 return __qdf_destroy_workqueue(wqueue); 175 } 176 177 /** 178 * qdf_sched_work - Schedule a deferred task on non-interrupt context 179 * @hdl: OS handle 180 * @work: pointer to work 181 * Retrun: none 182 */ 183 static inline void qdf_sched_work(qdf_handle_t hdl, qdf_work_t *work) 184 { 185 __qdf_sched_work(work); 186 } 187 188 /** 189 * qdf_cancel_work() - Cancel a work 190 * @work: pointer to work 191 * 192 * Cancel work and wait for its execution to finish. 193 * This function can be used even if the work re-queues 194 * itself or migrates to another workqueue. On return 195 * from this function, work is guaranteed to be not 196 * pending or executing on any CPU. The caller must 197 * ensure that the workqueue on which work was last 198 * queued can't be destroyed before this function returns. 199 * 200 * Return: true if work was pending, false otherwise 201 */ 202 static inline bool qdf_cancel_work(qdf_work_t *work) 203 { 204 return __qdf_cancel_work(work); 205 } 206 207 /** 208 * qdf_flush_work - Flush a deferred task on non-interrupt context 209 * @work: pointer to work 210 * 211 * Wait until work has finished execution. work is guaranteed to be 212 * idle on return if it hasn't been requeued since flush started. 213 * 214 * Return: none 215 */ 216 static inline void qdf_flush_work(qdf_work_t *work) 217 { 218 __qdf_flush_work(work); 219 } 220 221 /** 222 * qdf_disable_work - disable the deferred task (synchronous) 223 * @work: pointer to work 224 * Return: unsigned int 225 */ 226 static inline uint32_t qdf_disable_work(qdf_work_t *work) 227 { 228 return __qdf_disable_work(work); 229 } 230 231 /** 232 * qdf_destroy_work - destroy the deferred task (synchronous) 233 * @hdl: OS handle 234 * @work: pointer to work 235 * Return: none 236 */ 237 static inline void qdf_destroy_work(qdf_handle_t hdl, qdf_work_t *work) 238 { 239 __qdf_disable_work(work); 240 } 241 242 #endif /*_QDF_DEFER_H*/ 243