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 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) 33 #include <linux/sched/task_stack.h> 34 #endif 35 36 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) 37 #define setup_deferrable_timer(timer, fn, data) \ 38 __setup_timer((timer), (fn), (data), TIMER_DEFERRABLE) 39 #endif 40 41 /* timer data type */ 42 typedef struct timer_list __qdf_timer_t; 43 44 typedef void (*__qdf_dummy_timer_func_t)(unsigned long arg); 45 46 /** 47 * __qdf_timer_init() - initialize a softirq timer 48 * @timer: Pointer to timer object 49 * @func: Function pointer 50 * @arg: Argument 51 * @type: deferrable or non deferrable timer type 52 * 53 * Timer type QDF_TIMER_TYPE_SW means its a deferrable sw timer which will 54 * not cause CPU wake upon expiry 55 * Timer type QDF_TIMER_TYPE_WAKE_APPS means its a non-deferrable timer which 56 * will cause CPU wake up on expiry 57 * 58 * Return: QDF_STATUS 59 */ 60 static inline QDF_STATUS __qdf_timer_init(struct timer_list *timer, 61 qdf_timer_func_t func, void *arg, 62 QDF_TIMER_TYPE type) 63 { 64 bool is_on_stack = object_is_on_stack(timer); 65 __qdf_dummy_timer_func_t callback = (__qdf_dummy_timer_func_t)func; 66 unsigned long ctx = (unsigned long)arg; 67 68 if (type == QDF_TIMER_TYPE_SW) { 69 if (is_on_stack) 70 setup_deferrable_timer_on_stack(timer, callback, ctx); 71 else 72 setup_deferrable_timer(timer, callback, ctx); 73 } else { 74 if (is_on_stack) 75 setup_timer_on_stack(timer, callback, ctx); 76 else 77 setup_timer(timer, callback, ctx); 78 } 79 80 return QDF_STATUS_SUCCESS; 81 } 82 83 /** 84 * __qdf_timer_start() - start a qdf softirq timer 85 * @timer: Pointer to timer object 86 * @delay: Delay in milliseconds 87 * 88 * Return: None 89 */ 90 static inline void __qdf_timer_start(struct timer_list *timer, uint32_t delay) 91 { 92 timer->expires = jiffies + msecs_to_jiffies(delay); 93 add_timer(timer); 94 } 95 96 /** 97 * __qdf_timer_mod() - modify a timer 98 * @timer: Pointer to timer object 99 * @delay: Delay in milliseconds 100 * 101 * Return: None 102 */ 103 static inline void __qdf_timer_mod(struct timer_list *timer, uint32_t delay) 104 { 105 mod_timer(timer, jiffies + msecs_to_jiffies(delay)); 106 } 107 108 /** 109 * __qdf_timer_stop() - cancel a timer 110 * @timer: Pointer to timer object 111 * 112 * Return: true if timer was cancelled and deactived, 113 * false if timer was cancelled but already got fired. 114 */ 115 static inline bool __qdf_timer_stop(struct timer_list *timer) 116 { 117 if (likely(del_timer(timer))) 118 return 1; 119 else 120 return 0; 121 } 122 123 /** 124 * __qdf_timer_free() - free a qdf timer 125 * @timer: Pointer to timer object 126 * 127 * Return: None 128 */ 129 static inline void __qdf_timer_free(struct timer_list *timer) 130 { 131 del_timer_sync(timer); 132 133 if (object_is_on_stack(timer)) 134 destroy_timer_on_stack(timer); 135 } 136 137 /** 138 * __qdf_sostirq_timer_sync_cancel() - Synchronously canel a timer 139 * @timer: Pointer to timer object 140 * 141 * Synchronization Rules: 142 * 1. caller must make sure timer function will not use 143 * qdf_set_timer to add iteself again. 144 * 2. caller must not hold any lock that timer function 145 * is likely to hold as well. 146 * 3. It can't be called from interrupt context. 147 * 148 * Return: true if timer was cancelled and deactived, 149 * false if timer was cancelled but already got fired. 150 */ 151 static inline bool __qdf_timer_sync_cancel(struct timer_list *timer) 152 { 153 return del_timer_sync(timer); 154 } 155 156 #endif /*_QDF_TIMER_PVT_H*/ 157