1 /*
2  * Copyright (c) 2014-2018, 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_hrtimer
22  * This file abstracts high resolution timers running in hardware context.
23  */
24 
25 #ifndef _QDF_HRTIMER_H
26 #define _QDF_HRTIMER_H
27 
28 #include <qdf_types.h>
29 #include <i_qdf_hrtimer.h>
30 #include <qdf_time.h>
31 
32 /* Context independent hrtimer object */
33 typedef __qdf_hrtimer_data_t qdf_hrtimer_data_t;
34 
35 /* Platform independent timer callback function */
36 typedef enum qdf_hrtimer_restart_status(*qdf_hrtimer_func_t)
37 					(qdf_hrtimer_data_t *timer);
38 
39 #ifdef ENHANCED_OS_ABSTRACTION
40 /**
41  * qdf_hrtimer_start() - Starts hrtimer in given context
42  * @timer: pointer to the qdf_hrtimer_data_t object
43  * @interval: interval to forward as qdf_ktime_t object
44  * @mode: mode of qdf_hrtimer_data_t
45  *
46  * Starts hrtimer in given context
47  *
48  * Return: void
49  */
50 void qdf_hrtimer_start(qdf_hrtimer_data_t *timer, qdf_ktime_t interval,
51 		       enum qdf_hrtimer_mode mode);
52 
53 /**
54  * qdf_hrtimer_cancel() - Cancels hrtimer in given context
55  * @timer: pointer to the qdf_hrtimer_data_t object
56  *
57  * Cancels hrtimer in given context
58  *
59  * Return: int
60  */
61 int qdf_hrtimer_cancel(qdf_hrtimer_data_t *timer);
62 
63 /**
64  * qdf_hrtimer_init() - init hrtimer based on context
65  * @timer: pointer to the qdf_hrtimer_data_t object
66  * @callback: callback function to be fired
67  * @clock: clock type
68  * @mode: mode of qdf_hrtimer_data_t
69  * @ctx: interrupt context mode
70  *
71  * starts hrtimer in a context passed as per qdf_context_mode
72  *
73  * Return: void
74  */
75 void qdf_hrtimer_init(qdf_hrtimer_data_t *timer,
76 		      qdf_hrtimer_func_t callback,
77 		      enum qdf_clock_id clock,
78 		      enum qdf_hrtimer_mode mode,
79 		      enum qdf_context_mode ctx);
80 
81 /**
82  * qdf_time_ms_to_ktime() - Converts milliseconds to a qdf_ktime_t object
83  * @ms: time in milliseconds
84  *
85  * Return: milliseconds as ktime object
86  */
87 qdf_ktime_t qdf_time_ms_to_ktime(uint64_t ms);
88 
89 /**
90  * qdf_hrtimer_kill() - kills hrtimer in given context
91  * @timer: pointer to the hrtimer object
92  *
93  * kills hrtimer in given context
94  *
95  * Return: void
96  */
97 void qdf_hrtimer_kill(__qdf_hrtimer_data_t *timer);
98 
99 /**
100  * qdf_hrtimer_get_remaining() - check remaining time in the timer
101  * @timer: pointer to the qdf_hrtimer_data_t object
102  *
103  * check whether the timer is on one of the queues
104  *
105  * Return: remaining time as qdf_ktime_t object
106  */
107 qdf_ktime_t qdf_hrtimer_get_remaining(qdf_hrtimer_data_t *timer);
108 
109 /**
110  * qdf_hrtimer_is_queued() - check whether the timer is on one of the queues
111  * @timer: pointer to the qdf_hrtimer_data_t object
112  *
113  * check whether the timer is on one of the queues
114  *
115  * Return: false when the timer was not in queue
116  *         true when the timer was in queue
117  */
118 bool qdf_hrtimer_is_queued(qdf_hrtimer_data_t *timer);
119 
120 /**
121  * qdf_hrtimer_callback_running() - check if callback is running
122  * @timer: pointer to the qdf_hrtimer_data_t object
123  *
124  * check whether the timer is running the callback function
125  *
126  * Return: false when callback is not running
127  *         true when callback is running
128  */
129 bool qdf_hrtimer_callback_running(qdf_hrtimer_data_t *timer);
130 
131 /**
132  * qdf_hrtimer_active() - check if timer is active
133  * @timer: pointer to the qdf_hrtimer_data_t object
134  *
135  * Check if timer is active. A timer is active, when it is enqueued into
136  * the rbtree or the callback function is running.
137  *
138  * Return: false if timer is not active
139  *         true if timer is active
140  */
141 bool qdf_hrtimer_active(qdf_hrtimer_data_t *timer);
142 
143 /**
144  * qdf_hrtimer_cb_get_time() - get remaining time in callback
145  * @timer: pointer to the qdf_hrtimer_data_t object
146  *
147  * Get remaining time in the hrtimer callback
148  *
149  * Return: time remaining as qdf_ktime_t object
150  */
151 qdf_ktime_t qdf_hrtimer_cb_get_time(qdf_hrtimer_data_t *timer);
152 
153 /**
154  * qdf_hrtimer_forward() - forward the hrtimer
155  * @timer: pointer to the qdf_hrtimer_data_t object
156  * @now: current time as qdf_ktime_t object
157  * @interval: interval to forward as qdf_ktime_t object
158  *
159  * Forward the timer expiry so it will expire in the future
160  *
161  * Return: the number of overruns
162  */
163 uint64_t qdf_hrtimer_forward(qdf_hrtimer_data_t *timer,
164 			     qdf_ktime_t now,
165 			     qdf_ktime_t interval);
166 
167 void qdf_hrtimer_add_expires(qdf_hrtimer_data_t *timer, qdf_ktime_t interval);
168 #else
169 /**
170  * qdf_hrtimer_start() - Starts hrtimer in given context
171  * @timer: pointer to the qdf_hrtimer_data_t object
172  * @interval: interval to forward as qdf_ktime_t object
173  * @mode: mode of qdf_hrtimer_data_t
174  *
175  * Starts hrtimer in given context
176  *
177  * Return: void
178  */
179 static inline
qdf_hrtimer_start(qdf_hrtimer_data_t * timer,qdf_ktime_t interval,enum qdf_hrtimer_mode mode)180 void qdf_hrtimer_start(qdf_hrtimer_data_t *timer, qdf_ktime_t interval,
181 		       enum qdf_hrtimer_mode mode)
182 {
183 	__qdf_hrtimer_start(timer, interval, mode);
184 }
185 
186 /**
187  * qdf_hrtimer_cancel() - Cancels hrtimer in given context
188  * @timer: pointer to the qdf_hrtimer_data_t object
189  *
190  * Cancels hrtimer in given context
191  *
192  * Return: int
193  */
194 static inline
qdf_hrtimer_cancel(qdf_hrtimer_data_t * timer)195 int qdf_hrtimer_cancel(qdf_hrtimer_data_t *timer)
196 {
197 	return __qdf_hrtimer_cancel(timer);
198 }
199 
200 /**
201  * qdf_hrtimer_init() - init hrtimer based on context
202  * @timer: pointer to the qdf_hrtimer_data_t object
203  * @callback: callback function to be fired
204  * @clock: clock type
205  * @mode: mode of qdf_hrtimer_data_t
206  * @ctx: interrupt context mode
207  *
208  * starts hrtimer in a context passed as per qdf_context_mode
209  *
210  * Return: void
211  */
qdf_hrtimer_init(qdf_hrtimer_data_t * timer,qdf_hrtimer_func_t callback,enum qdf_clock_id clock,enum qdf_hrtimer_mode mode,enum qdf_context_mode ctx)212 static inline void qdf_hrtimer_init(qdf_hrtimer_data_t *timer,
213 				    qdf_hrtimer_func_t callback,
214 				    enum qdf_clock_id clock,
215 				    enum qdf_hrtimer_mode mode,
216 				    enum qdf_context_mode ctx)
217 {
218 	__qdf_hrtimer_init(timer, callback, clock, mode, ctx);
219 }
220 
221 /**
222  * qdf_time_ms_to_ktime() - Converts milliseconds to a qdf_ktime_t object
223  * @ms: time in milliseconds
224  *
225  * Return: milliseconds as qdf_ktime_t object
226  */
qdf_time_ms_to_ktime(uint64_t ms)227 static inline qdf_ktime_t qdf_time_ms_to_ktime(uint64_t ms)
228 {
229 	return __qdf_time_ms_to_ktime(ms);
230 }
231 
232 /**
233  * qdf_hrtimer_kill() - kills hrtimer in given context
234  * @timer: pointer to the hrtimer object
235  *
236  * kills hrtimer in given context
237  *
238  * Return: void
239  */
240 static inline
qdf_hrtimer_kill(__qdf_hrtimer_data_t * timer)241 void qdf_hrtimer_kill(__qdf_hrtimer_data_t *timer)
242 {
243 	 __qdf_hrtimer_kill(timer);
244 }
245 
246 /**
247  * qdf_hrtimer_get_remaining() - check remaining time in the timer
248  * @timer: pointer to the qdf_hrtimer_data_t object
249  *
250  * check whether the timer is on one of the queues
251  *
252  * Return: remaining time as qdf_ktime_t object
253  */
qdf_hrtimer_get_remaining(qdf_hrtimer_data_t * timer)254 static inline qdf_ktime_t qdf_hrtimer_get_remaining(qdf_hrtimer_data_t *timer)
255 {
256 	return __qdf_hrtimer_get_remaining(timer);
257 }
258 
259 /**
260  * qdf_hrtimer_is_queued() - check whether the timer is on one of the queues
261  * @timer: pointer to the qdf_hrtimer_data_t object
262  *
263  * check whether the timer is on one of the queues
264  *
265  * Return: false when the timer was not in queue
266  *         true when the timer was in queue
267  */
qdf_hrtimer_is_queued(qdf_hrtimer_data_t * timer)268 static inline bool qdf_hrtimer_is_queued(qdf_hrtimer_data_t *timer)
269 {
270 	return __qdf_hrtimer_is_queued(timer);
271 }
272 
273 /**
274  * qdf_hrtimer_callback_running() - check if callback is running
275  * @timer: pointer to the qdf_hrtimer_data_t object
276  *
277  * check whether the timer is running the callback function
278  *
279  * Return: false when callback is not running
280  *         true when callback is running
281  */
qdf_hrtimer_callback_running(qdf_hrtimer_data_t * timer)282 static inline bool qdf_hrtimer_callback_running(qdf_hrtimer_data_t *timer)
283 {
284 	return __qdf_hrtimer_callback_running(timer);
285 }
286 
287 /**
288  * qdf_hrtimer_active() - check if timer is active
289  * @timer: pointer to the qdf_hrtimer_data_t object
290  *
291  * Check if timer is active. A timer is active, when it is enqueued into
292  * the rbtree or the callback function is running.
293  *
294  * Return: false if timer is not active
295  *         true if timer is active
296  */
qdf_hrtimer_active(qdf_hrtimer_data_t * timer)297 static inline bool qdf_hrtimer_active(qdf_hrtimer_data_t *timer)
298 {
299 	return __qdf_hrtimer_active(timer);
300 }
301 
302 /**
303  * qdf_hrtimer_cb_get_time() - get remaining time in callback
304  * @timer: pointer to the qdf_hrtimer_data_t object
305  *
306  * Get remaining time in the hrtimer callback
307  *
308  * Return: time remaining as qdf_ktime_t object
309  */
qdf_hrtimer_cb_get_time(qdf_hrtimer_data_t * timer)310 static inline qdf_ktime_t qdf_hrtimer_cb_get_time(qdf_hrtimer_data_t *timer)
311 {
312 	return __qdf_hrtimer_cb_get_time(timer);
313 }
314 
315 /**
316  * qdf_hrtimer_forward() - forward the hrtimer
317  * @timer: pointer to the qdf_hrtimer_data_t object
318  * @now: current time as qdf_ktime_t object
319  * @interval: interval to forward as qdf_ktime_t object
320  *
321  * Forward the timer expiry so it will expire in the future
322  *
323  * Return: the number of overruns
324  */
qdf_hrtimer_forward(qdf_hrtimer_data_t * timer,qdf_ktime_t now,qdf_ktime_t interval)325 static inline uint64_t qdf_hrtimer_forward(qdf_hrtimer_data_t *timer,
326 					   qdf_ktime_t now,
327 					   qdf_ktime_t interval)
328 {
329 	return __qdf_hrtimer_forward(timer, now, interval);
330 }
331 
332 /**
333  * qdf_hrtimer_add_expires() - Add expiry to hrtimer with given interval
334  * @timer: pointer to the qdf_hrtimer_data_t object
335  * @interval: interval to add as qdf_ktime_t object
336  *
337  * Add the timer expiry so it will expire in the future
338  *
339  * Return: None
340  */
341 static inline
qdf_hrtimer_add_expires(qdf_hrtimer_data_t * timer,qdf_ktime_t interval)342 void qdf_hrtimer_add_expires(qdf_hrtimer_data_t *timer, qdf_ktime_t interval)
343 {
344 	return __qdf_hrtimer_add_expires(timer, interval);
345 }
346 
347 #endif
348 
349 #endif /* _QDF_HRTIMER_H */
350