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