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