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
qdf_periodic_work_check_for_leaks(void)135 static inline void qdf_periodic_work_check_for_leaks(void) { }
qdf_periodic_work_feature_init(void)136 static inline void qdf_periodic_work_feature_init(void) { }
qdf_periodic_work_feature_deinit(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