1 /* 2 * Copyright (c) 2019 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 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: qdf_periodic_work.h 22 * A simple, periodic work type for repeatedly executing a callback with a 23 * certain frequency. 24 */ 25 26 #ifndef __QDF_PERIODIC_WORK_H 27 #define __QDF_PERIODIC_WORK_H 28 29 #include "i_qdf_periodic_work.h" 30 #include "qdf_status.h" 31 #include "qdf_types.h" 32 33 typedef void (*qdf_periodic_work_cb)(void *context); 34 35 /** 36 * struct qdf_periodic_work - a deferred work type which executes a callback 37 * periodically until stopped 38 * @dwork: OS-specific delayed work 39 * @callback: the callback to be executed periodically 40 * @context: the context to pass to the callback 41 * @msec: the delay between executions in milliseconds 42 */ 43 struct qdf_periodic_work { 44 struct __qdf_opaque_delayed_work dwork; 45 qdf_periodic_work_cb callback; 46 void *context; 47 uint32_t msec; 48 }; 49 50 /** 51 * qdf_periodic_work_create() - initialized a periodic work @pwork 52 * @pwork: the periodic work to initialize 53 * @callback: the callback to be executed periodically 54 * @context: the context to pass to the callback 55 * 56 * Return: QDF_STATUS 57 */ 58 #define qdf_periodic_work_create(pwork, callback, context) \ 59 __qdf_periodic_work_create(pwork, callback, context, __func__, __LINE__) 60 61 qdf_must_check QDF_STATUS 62 __qdf_periodic_work_create(struct qdf_periodic_work *pwork, 63 qdf_periodic_work_cb callback, void *context, 64 const char *func, uint32_t line); 65 66 /** 67 * qdf_periodic_work_destroy() - deinitialize a periodic work @pwork 68 * @pwork: the periodic work to de-initialize 69 * 70 * Return: None 71 */ 72 #define qdf_periodic_work_destroy(pwork) \ 73 __qdf_periodic_work_destroy(pwork, __func__, __LINE__) 74 75 void __qdf_periodic_work_destroy(struct qdf_periodic_work *pwork, 76 const char *func, uint32_t line); 77 78 /** 79 * qdf_periodic_work_start() - begin periodic execution of @pwork callback 80 * @pwork: the periodic work to start 81 * @msec: the delay between executions in milliseconds 82 * 83 * Return: true if started successfully 84 */ 85 bool qdf_periodic_work_start(struct qdf_periodic_work *pwork, uint32_t msec); 86 87 /** 88 * qdf_periodic_work_stop_async() - Asynchronously stop execution of @pwork 89 * @pwork: the periodic work to stop 90 * 91 * When this returns, @pwork is guaranteed to not be queued, *but* its callback 92 * may still be executing. 93 * 94 * This is safe to call from the @pwork callback. 95 * 96 * Return: true if @pwork was previously started 97 */ 98 bool qdf_periodic_work_stop_async(struct qdf_periodic_work *pwork); 99 100 /** 101 * qdf_periodic_work_stop_sync() - Synchronously stop execution of @pwork 102 * @pwork: the periodic work to stop 103 * 104 * When this returns, @pwork is guaranteed to not be queued, and its callback 105 * not executing. 106 * 107 * This will deadlock if called from the @pwork callback. 108 * 109 * Return: true if @pwork was previously started 110 */ 111 bool qdf_periodic_work_stop_sync(struct qdf_periodic_work *pwork); 112 113 #ifdef WLAN_PERIODIC_WORK_DEBUG 114 /** 115 * qdf_periodic_work_check_for_leaks() - assert no periodic work leaks 116 * 117 * Return: None 118 */ 119 void qdf_periodic_work_check_for_leaks(void); 120 121 /** 122 * qdf_periodic_work_feature_init() - global init logic for periodic work 123 * 124 * Return: None 125 */ 126 void qdf_periodic_work_feature_init(void); 127 128 /** 129 * qdf_periodic_work_feature_deinit() - global de-init logic for periodic work 130 * 131 * Return: None 132 */ 133 void qdf_periodic_work_feature_deinit(void); 134 #else 135 static inline void qdf_periodic_work_check_for_leaks(void) { } 136 static inline void qdf_periodic_work_feature_init(void) { } 137 static inline void qdf_periodic_work_feature_deinit(void) { } 138 #endif /* WLAN_PERIODIC_WORK_DEBUG */ 139 140 #endif /* __QDF_PERIODIC_WORK_H */ 141 142