xref: /wlan-dirver/qca-wifi-host-cmn/qdf/linux/src/i_qdf_timer.h (revision d78dedc9dd8c4ee677ac1649d1d42f2a7c3cc1b7)
1 /*
2  * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: i_qdf_timer
21  * This file provides OS dependent timer API's.
22  */
23 
24 #ifndef _I_QDF_TIMER_H
25 #define _I_QDF_TIMER_H
26 
27 #include <linux/version.h>
28 #include <linux/delay.h>
29 #include <linux/timer.h>
30 #include <linux/jiffies.h>
31 #include <qdf_types.h>
32 
33 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
34 #define setup_deferrable_timer(timer, fn, data)                                \
35 	__setup_timer((timer), (fn), (data), TIMER_DEFERRABLE)
36 #endif
37 
38 /* timer data type */
39 typedef struct timer_list __qdf_timer_t;
40 
41 typedef void (*__qdf_dummy_timer_func_t)(unsigned long arg);
42 
43 /**
44  * __qdf_timer_init() - initialize a softirq timer
45  * @hdl: OS handle
46  * @timer: Pointer to timer object
47  * @func: Function pointer
48  * @arg: Argument
49  * @type: deferrable or non deferrable timer type
50  *
51  * Timer type QDF_TIMER_TYPE_SW means its a deferrable sw timer which will
52  * not cause CPU wake upon expiry
53  * Timer type QDF_TIMER_TYPE_WAKE_APPS means its a non-deferrable timer which
54  * will cause CPU wake up on expiry
55  *
56  * Return: QDF_STATUS
57  */
58 static inline QDF_STATUS __qdf_timer_init(qdf_handle_t hdl,
59 					  struct timer_list *timer,
60 					  qdf_timer_func_t func, void *arg,
61 					  QDF_TIMER_TYPE type)
62 {
63 	if (type == QDF_TIMER_TYPE_SW) {
64 		if (object_is_on_stack(timer))
65 			setup_deferrable_timer_on_stack(
66 			    timer, (__qdf_dummy_timer_func_t)func,
67 			    (unsigned long)arg);
68 		else
69 			setup_deferrable_timer(timer,
70 					       (__qdf_dummy_timer_func_t)func,
71 					       (unsigned long)arg);
72 	} else {
73 		if (object_is_on_stack(timer))
74 			setup_timer_on_stack(timer,
75 					     (__qdf_dummy_timer_func_t)func,
76 					     (unsigned long)arg);
77 		else
78 			setup_timer(timer, (__qdf_dummy_timer_func_t)func,
79 				    (unsigned long)arg);
80 	}
81 
82 	return QDF_STATUS_SUCCESS;
83 }
84 
85 /**
86  * __qdf_timer_start() - start a qdf softirq timer
87  * @timer: Pointer to timer object
88  * @delay: Delay in milli seconds
89  *
90  * Return: QDF_STATUS
91  */
92 static inline QDF_STATUS __qdf_timer_start(struct timer_list *timer,
93 					   uint32_t delay)
94 {
95 	timer->expires = jiffies + msecs_to_jiffies(delay);
96 	add_timer(timer);
97 
98 	return QDF_STATUS_SUCCESS;
99 }
100 
101 /**
102  * __qdf_timer_mod() - modify a timer
103  * @timer: Pointer to timer object
104  * @delay: Delay in milli seconds
105  *
106  * Return: QDF_STATUS
107  */
108 static inline QDF_STATUS __qdf_timer_mod(struct timer_list *timer,
109 					 uint32_t delay)
110 {
111 	mod_timer(timer, jiffies + msecs_to_jiffies(delay));
112 
113 	return QDF_STATUS_SUCCESS;
114 }
115 
116 /**
117  * __qdf_timer_stop() - cancel a timer
118  * @timer: Pointer to timer object
119  *
120  * Return: true if timer was cancelled and deactived,
121  * false if timer was cancelled but already got fired.
122  */
123 static inline bool __qdf_timer_stop(struct timer_list *timer)
124 {
125 	if (likely(del_timer(timer)))
126 		return 1;
127 	else
128 		return 0;
129 }
130 
131 /**
132  * __qdf_timer_free() - free a qdf timer
133  * @timer: Pointer to timer object
134  *
135  * Return: None
136  */
137 static inline void __qdf_timer_free(struct timer_list *timer)
138 {
139 	del_timer_sync(timer);
140 
141 	if (object_is_on_stack(timer))
142 		destroy_timer_on_stack(timer);
143 }
144 
145 /**
146  * __qdf_sostirq_timer_sync_cancel() - Synchronously canel a timer
147  * @timer: Pointer to timer object
148  *
149  * Synchronization Rules:
150  * 1. caller must make sure timer function will not use
151  *    qdf_set_timer to add iteself again.
152  * 2. caller must not hold any lock that timer function
153  *    is likely to hold as well.
154  * 3. It can't be called from interrupt context.
155  *
156  * Return: true if timer was cancelled and deactived,
157  * false if timer was cancelled but already got fired.
158  */
159 static inline bool __qdf_timer_sync_cancel(struct timer_list *timer)
160 {
161 	return del_timer_sync(timer);
162 }
163 
164 #endif /*_QDF_TIMER_PVT_H*/
165