1 /*
2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 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_threads
22 * QCA driver framework (QDF) thread related APIs
23 */
24
25 #if !defined(__QDF_THREADS_H)
26 #define __QDF_THREADS_H
27
28 #include <qdf_types.h>
29 #include "i_qdf_threads.h"
30
31 typedef __qdf_thread_t qdf_thread_t;
32 typedef QDF_STATUS (*qdf_thread_func)(void *context);
33
34 /* Function declarations and documentation */
35
36 void qdf_sleep(uint32_t ms_interval);
37
38 void qdf_sleep_us(uint32_t us_interval);
39
40 void qdf_busy_wait(uint32_t us_interval);
41
42 /**
43 * qdf_set_wake_up_idle() - set wakeup idle value
44 * @idle: true/false value for wake up idle
45 *
46 * Return: none
47 */
48 void qdf_set_wake_up_idle(bool idle);
49
50 /**
51 * qdf_set_user_nice() - set thread's nice value
52 * @thread: pointer to thread
53 * @nice: nice value
54 *
55 * Return: void
56 */
57 void qdf_set_user_nice(qdf_thread_t *thread, long nice);
58
59 /**
60 * qdf_create_thread() - create a kernel thread
61 * @thread_handler: pointer to thread handler
62 * @data: data
63 * @thread_name: thread name
64 *
65 * Return: pointer to created kernel thread on success else NULL
66 */
67 qdf_thread_t *qdf_create_thread(int (*thread_handler)(void *data), void *data,
68 const char thread_name[]);
69
70 /**
71 * qdf_thread_run() - run the given function in a new thread
72 *
73 * You must call qdf_thread_join() to avoid a reasource leak!
74 * For more flexibility, use qdf_create_thread() instead.
75 * @callback: callback function
76 * @context: context
77 *
78 * Return: a new qdf_thread pointer
79 */
80 qdf_thread_t *qdf_thread_run(qdf_thread_func callback, void *context);
81
82 /**
83 * qdf_thread_join() - signal and wait for a thread to stop
84 * @thread: pointer to thread
85 *
86 * This sets a flag that the given thread can check to see if it should exit.
87 * The thread can check to see if this flag has been set by calling
88 * qdf_thread_should_stop().
89 *
90 * Return: QDF_STATUS - the return value from the thread function
91 */
92 QDF_STATUS qdf_thread_join(qdf_thread_t *thread);
93
94 /**
95 * qdf_thread_should_stop() - true if the current thread was signalled to stop
96 *
97 * If qdf_thread_join() has been called on the current thread, this API returns
98 * true. Otherwise, this returns false.
99 *
100 * Return: true if the current thread should stop
101 */
102 bool qdf_thread_should_stop(void);
103
104 /**
105 * qdf_wake_up_process() - wake up given thread
106 * @thread: pointer to thread which needs to be woken up
107 *
108 * Return: none
109 */
110 int qdf_wake_up_process(qdf_thread_t *thread);
111
112 /**
113 * qdf_print_thread_trace() - prints the stack trace of the given thread
114 * @thread: the thread for which the stack trace will be printed
115 *
116 * Return: None
117 */
118 void qdf_print_thread_trace(qdf_thread_t *thread);
119
120 /**
121 * qdf_get_current_task() - get current task struct
122 *
123 * Return: pointer to task struct
124 */
125 qdf_thread_t *qdf_get_current_task(void);
126
127 /**
128 * qdf_get_current_pid() - get current task's process id
129 *
130 * Return: current task's process id (int)
131 */
132 int qdf_get_current_pid(void);
133
134 /**
135 * qdf_get_current_comm() - get current task's command name
136 *
137 * Return: current task's command name(char *)
138 */
139 const char *qdf_get_current_comm(void);
140
141 /**
142 * qdf_thread_set_cpus_allowed_mask() - set cpu mask for a particular thread
143 * @thread: thread for which new cpu mask is set
144 * @new_mask: new cpu mask to be set for the thread
145 *
146 * Return: None
147 */
148 void
149 qdf_thread_set_cpus_allowed_mask(qdf_thread_t *thread, qdf_cpu_mask *new_mask);
150
151 /**
152 * qdf_cpumask_clear() - clear all cpus in a cpumask
153 * @dstp: cpumask pointer
154 *
155 * Return: None
156 */
157 void qdf_cpumask_clear(qdf_cpu_mask *dstp);
158
159 /**
160 * qdf_cpumask_set_cpu() - set a cpu in a cpumask
161 * @cpu: cpu number
162 * @dstp: cpumask pointer
163 *
164 * Return: None
165 */
166 void qdf_cpumask_set_cpu(unsigned int cpu, qdf_cpu_mask *dstp);
167
168 /**
169 * qdf_cpumask_setall - set all cpus
170 * @dstp: cpumask pointer
171 *
172 * Return: None
173 */
174 void qdf_cpumask_setall(qdf_cpu_mask *dstp);
175
176 /**
177 * qdf_cpumask_clear_cpu() - clear a cpu in a cpumask
178 * @cpu: cpu number
179 * @dstp: cpumask pointer
180 *
181 * Return: None
182 */
183 void qdf_cpumask_clear_cpu(unsigned int cpu, qdf_cpu_mask *dstp);
184
185 /**
186 * qdf_cpumask_empty - Check if cpu_mask is empty
187 * @srcp: cpumask pointer
188 *
189 * Return: true or false
190 *
191 */
192 bool qdf_cpumask_empty(const qdf_cpu_mask *srcp);
193
194 /**
195 * qdf_cpumask_copy - Copy srcp cpumask to dstp
196 * @srcp: source cpumask pointer
197 * @dstp: destination cpumask pointer
198 *
199 * Return: None
200 *
201 */
202 void qdf_cpumask_copy(qdf_cpu_mask *dstp,
203 const qdf_cpu_mask *srcp);
204
205 /**
206 * qdf_cpumask_or - set *dstp = *src1p | *src2p
207 * @dstp: the cpumask result
208 * @src1p: the first input
209 * @src2p: the second input
210 *
211 * Return: None
212 */
213 void qdf_cpumask_or(qdf_cpu_mask *dstp, qdf_cpu_mask *src1p,
214 qdf_cpu_mask *src2p);
215
216 /**
217 * qdf_thread_cpumap_print_to_pagebuf - copies the cpumask into the buffer
218 * either as comma-separated list of cpus or hex values of cpumask
219 * @list: indicates whether the cpumap is list or not
220 * @new_mask: the cpumask to copy
221 * @new_mask_str: the buffer to copy into
222 *
223 * This functions copies the cpu mask set for the thread by
224 * qdf_thread_set_cpus_allowed_mask() to new_mask_str
225 *
226 * Return: None
227 */
228 void
229 qdf_thread_cpumap_print_to_pagebuf(bool list, char *new_mask_str,
230 qdf_cpu_mask *new_mask);
231
232 /**
233 * qdf_cpumask_and - *dstp = *src1p & *src2p
234 * @dstp: the cpumask result
235 * @src1p: the first input
236 * @src2p: the second input
237 *
238 * Return: If *@dstp is empty, returns false, else returns true
239 */
240 bool
241 qdf_cpumask_and(qdf_cpu_mask *dstp, const qdf_cpu_mask *src1p,
242 const qdf_cpu_mask *src2p);
243
244 /**
245 * qdf_cpumask_andnot - *dstp = *src1p & ~*src2p
246 * @dstp: the cpumask result
247 * @src1p: the first input
248 * @src2p: the second input
249 *
250 * Return: If *@dstp is empty, returns false, else returns true
251 */
252 bool
253 qdf_cpumask_andnot(qdf_cpu_mask *dstp, const qdf_cpu_mask *src1p,
254 const qdf_cpu_mask *src2p);
255
256 /**
257 * qdf_cpumask_equal - *src1p == *src2p
258 * @src1p: the first input
259 * @src2p: the second input
260 *
261 * Return: If *@src1p == *@src2p return true, else return false
262 */
263 bool
264 qdf_cpumask_equal(const qdf_cpu_mask *src1p, const qdf_cpu_mask *src2p);
265
266 /**
267 * qdf_cpumask_complement - *dstp = ~*srcp
268 * @dstp: the cpumask result
269 * @srcp: the input to invert
270 *
271 * Return: None
272 */
273 void
274 qdf_cpumask_complement(qdf_cpu_mask *dstp, const qdf_cpu_mask *srcp);
275
276 #if defined(WALT_GET_CPU_TAKEN_SUPPORT) && IS_ENABLED(CONFIG_SCHED_WALT)
277 /**
278 * qdf_walt_get_cpus_taken - Get taken CPUs
279 *
280 * Return: Taken CPUs
281 */
282 qdf_cpu_mask qdf_walt_get_cpus_taken(void);
283
284 /*
285 * qdf_walt_get_cpus_taken_supported: walt_get_cpus_taken supported
286 *
287 * Return: true if walt_get_cpus_taken API is supported
288 */
289 static inline bool
qdf_walt_get_cpus_taken_supported(void)290 qdf_walt_get_cpus_taken_supported(void)
291 {
292 return true;
293 }
294 #else
295 static inline
qdf_walt_get_cpus_taken(void)296 qdf_cpu_mask qdf_walt_get_cpus_taken(void)
297 {
298 qdf_cpu_mask mask;
299
300 qdf_cpumask_clear(&mask);
301
302 return mask;
303 }
304
305 static inline bool
qdf_walt_get_cpus_taken_supported(void)306 qdf_walt_get_cpus_taken_supported(void)
307 {
308 return false;
309 }
310 #endif
311 #endif /* __QDF_THREADS_H */
312