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