1 /* 2 * Copyright (c) 2014-2021 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_time 21 * This file provides OS dependent time API's. 22 */ 23 24 #ifndef _I_QDF_TIME_H 25 #define _I_QDF_TIME_H 26 27 #include <linux/version.h> 28 #include <linux/jiffies.h> 29 #include <linux/delay.h> 30 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) 31 #include <linux/sched/clock.h> 32 #else 33 #include <linux/sched.h> 34 #endif 35 #include <linux/ktime.h> 36 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) 37 #include <linux/timekeeping.h> 38 #else 39 #include <linux/hrtimer.h> 40 #endif 41 #ifdef MSM_PLATFORM 42 #include <asm/arch_timer.h> 43 #endif 44 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) 45 #include <linux/sched/clock.h> 46 #else 47 #include <linux/sched.h> 48 #endif 49 50 typedef unsigned long __qdf_time_t; 51 typedef ktime_t __qdf_ktime_t; 52 53 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) 54 typedef struct timespec64 __qdf_timespec_t; 55 #else 56 typedef struct timeval __qdf_timespec_t; 57 #endif 58 59 typedef struct work_struct __qdf_work_struct_t; 60 61 /** 62 * __qdf_ns_to_ktime() - Converts nanoseconds to a ktime object 63 * @ns: time in nanoseconds 64 * 65 * Return: nanoseconds as ktime object 66 */ 67 static inline ktime_t __qdf_ns_to_ktime(uint64_t ns) 68 { 69 return ns_to_ktime(ns); 70 } 71 72 /** 73 * __qdf_ktime_add() - Adds two ktime objects and returns 74 * a ktime object 75 * @time1: time as ktime object 76 * @time2: time as ktime object 77 * 78 * Return: sum of ktime objects as ktime object 79 */ 80 static inline ktime_t __qdf_ktime_add(ktime_t ktime1, ktime_t ktime2) 81 { 82 return ktime_add(ktime1, ktime2); 83 } 84 85 /** 86 * __qdf_ktime_get() - Gets the current time as ktime object 87 * 88 * Return: current time as ktime object 89 */ 90 static inline ktime_t __qdf_ktime_get(void) 91 { 92 return ktime_get(); 93 } 94 95 /** 96 * __qdf_ktime_real_get() - Gets the current wall clock as ktime object 97 * 98 * Return: current wall clock as ktime object 99 */ 100 static inline ktime_t __qdf_ktime_real_get(void) 101 { 102 return ktime_get_real(); 103 } 104 105 /** 106 * __qdf_ktime_add_ns() - Adds ktime object and nanoseconds value and 107 * returns the ktime object 108 * 109 * Return: ktime object 110 */ 111 static inline ktime_t __qdf_ktime_add_ns(ktime_t ktime, int64_t ns) 112 { 113 return ktime_add_ns(ktime, ns); 114 } 115 116 /** 117 * __qdf_ktime_to_ns() - convert ktime to nanoseconds 118 * @ktime: time as ktime object 119 * @ns: time in nanoseconds 120 * 121 * Return: ktime in nanoseconds 122 */ 123 static inline int64_t __qdf_ktime_to_ns(ktime_t ktime) 124 { 125 return ktime_to_ns(ktime); 126 } 127 128 /** 129 * __qdf_ktime_to_ms() - convert ktime to milliseconds 130 * @ktime: time as ktime object 131 * 132 * Return: ktime in milliseconds 133 */ 134 static inline int64_t __qdf_ktime_to_ms(ktime_t ktime) 135 { 136 return ktime_to_ms(ktime); 137 } 138 139 140 /** 141 * __qdf_system_ticks() - get system ticks 142 * 143 * Return: system tick in jiffies 144 */ 145 static inline __qdf_time_t __qdf_system_ticks(void) 146 { 147 return jiffies; 148 } 149 150 #define __qdf_system_ticks_per_sec HZ 151 152 /** 153 * __qdf_system_ticks_to_msecs() - convert system ticks into milli seconds 154 * @ticks: System ticks 155 * 156 * Return: system tick converted into milli seconds 157 */ 158 static inline uint32_t __qdf_system_ticks_to_msecs(unsigned long ticks) 159 { 160 return jiffies_to_msecs(ticks); 161 } 162 163 /** 164 * __qdf_system_msecs_to_ticks() - convert milli seconds into system ticks 165 * @msecs: Milli seconds 166 * 167 * Return: milli seconds converted into system ticks 168 */ 169 static inline __qdf_time_t __qdf_system_msecs_to_ticks(uint32_t msecs) 170 { 171 return msecs_to_jiffies(msecs); 172 } 173 174 /** 175 * __qdf_get_system_uptime() - get system uptime 176 * 177 * Return: system uptime in jiffies 178 */ 179 static inline __qdf_time_t __qdf_get_system_uptime(void) 180 { 181 return jiffies; 182 } 183 184 static inline unsigned long __qdf_get_system_timestamp(void) 185 { 186 return (jiffies / HZ) * 1000 + (jiffies % HZ) * (1000 / HZ); 187 } 188 189 #ifdef CONFIG_ARM 190 /** 191 * __qdf_udelay() - delay execution for given microseconds 192 * @usecs: Micro seconds to delay 193 * 194 * Return: none 195 */ 196 static inline void __qdf_udelay(uint32_t usecs) 197 { 198 /* 199 * This is in support of XScale build. They have a limit on the udelay 200 * value, so we have to make sure we don't approach the limit 201 */ 202 uint32_t mticks; 203 uint32_t leftover; 204 int i; 205 /* slice into 1024 usec chunks (simplifies calculation) */ 206 mticks = usecs >> 10; 207 leftover = usecs - (mticks << 10); 208 for (i = 0; i < mticks; i++) 209 udelay(1024); 210 udelay(leftover); 211 } 212 #else 213 static inline void __qdf_udelay(uint32_t usecs) 214 { 215 /* Normal Delay functions. Time specified in microseconds */ 216 udelay(usecs); 217 } 218 #endif 219 220 /** 221 * __qdf_mdelay() - delay execution for given milliseconds 222 * @usecs: Milliseconds to delay 223 * 224 * Return: none 225 */ 226 static inline void __qdf_mdelay(uint32_t msecs) 227 { 228 mdelay(msecs); 229 } 230 231 /** 232 * __qdf_system_time_after() - Check if a is later than b 233 * @a: Time stamp value a 234 * @b: Time stamp value b 235 * 236 * Return: 237 * true if a < b else false 238 */ 239 static inline bool __qdf_system_time_after(__qdf_time_t a, __qdf_time_t b) 240 { 241 return (long)(b) - (long)(a) < 0; 242 } 243 244 /** 245 * __qdf_system_time_before() - Check if a is before b 246 * @a: Time stamp value a 247 * @b: Time stamp value b 248 * 249 * Return: 250 * true if a is before b else false 251 */ 252 static inline bool __qdf_system_time_before(__qdf_time_t a, __qdf_time_t b) 253 { 254 return __qdf_system_time_after(b, a); 255 } 256 257 /** 258 * __qdf_system_time_after_eq() - Check if a atleast as recent as b, if not 259 * later 260 * @a: Time stamp value a 261 * @b: Time stamp value b 262 * 263 * Return: 264 * true if a >= b else false 265 */ 266 static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b) 267 { 268 return (long)(a) - (long)(b) >= 0; 269 } 270 271 /** 272 * qdf_sched_clock() - use light weight timer to get timestamp 273 * 274 * Return: timestamp in ns 275 */ 276 static inline uint64_t __qdf_sched_clock(void) 277 { 278 return sched_clock(); 279 } 280 281 /** 282 * __qdf_get_monotonic_boottime() - get monotonic kernel boot time 283 * This API is similar to qdf_get_system_boottime but it includes 284 * time spent in suspend. 285 * 286 * Return: Time in microseconds 287 */ 288 static inline uint64_t __qdf_get_monotonic_boottime(void) 289 { 290 return (uint64_t)ktime_to_us(ktime_get_boottime()); 291 } 292 293 #if defined (MSM_PLATFORM) 294 295 /** 296 * __qdf_get_log_timestamp() - get msm timer ticks 297 * 298 * Returns QTIMER(19.2 MHz) clock ticks. To convert it into seconds 299 * divide it by 19200. 300 * 301 * Return: QTIMER(19.2 MHz) clock ticks 302 */ 303 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) 304 static inline uint64_t __qdf_get_log_timestamp(void) 305 { 306 return __arch_counter_get_cntvct(); 307 } 308 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 309 static inline uint64_t __qdf_get_log_timestamp(void) 310 { 311 return arch_counter_get_cntvct(); 312 } 313 #else 314 static inline uint64_t __qdf_get_log_timestamp(void) 315 { 316 return arch_counter_get_cntpct(); 317 } 318 #endif /* LINUX_VERSION_CODE */ 319 #else 320 321 /** 322 * __qdf_get_log_timestamp - get time stamp for logging 323 * 324 * Return: system tick for non MSM platfroms 325 */ 326 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) 327 static inline uint64_t __qdf_get_log_timestamp(void) 328 { 329 struct timespec64 ts; 330 331 ktime_get_ts64(&ts); 332 333 return ((uint64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 334 } 335 #else 336 static inline uint64_t __qdf_get_log_timestamp(void) 337 { 338 struct timespec ts; 339 340 ktime_get_ts(&ts); 341 342 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 343 } 344 #endif 345 #endif 346 347 /** 348 * __qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds 349 * 350 * __qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds 351 * that have elapsed since the system was booted. It also includes the time when 352 * system was suspended. 353 * 354 * Return: 355 * The time since system booted in nanoseconds 356 */ 357 358 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) 359 static inline uint64_t __qdf_get_bootbased_boottime_ns(void) 360 { 361 return ktime_get_boottime_ns(); 362 } 363 364 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) 365 static inline uint64_t __qdf_get_bootbased_boottime_ns(void) 366 { 367 return ktime_get_boot_ns(); 368 } 369 370 #else 371 static inline uint64_t __qdf_get_bootbased_boottime_ns(void) 372 { 373 return ktime_to_ns(ktime_get_boottime()); 374 } 375 #endif 376 377 /** 378 * __qdf_time_ms_to_ktime() - Converts milliseconds to a ktime object 379 * @ms: time in milliseconds 380 * 381 * Return: milliseconds as ktime object 382 */ 383 static inline ktime_t __qdf_time_ms_to_ktime(uint64_t ms) 384 { 385 return ms_to_ktime(ms); 386 } 387 388 /** 389 * __qdf_time_ktime_real_get() - Gets the current wall clock as ktime object 390 * 391 * Return: current wall clock as ktime object 392 */ 393 static inline ktime_t __qdf_time_ktime_real_get(void) 394 { 395 return ktime_get_real(); 396 } 397 398 /** 399 * __qdf_time_sched_clock() - schedule clock 400 * 401 * Return: returns current time in nanosec units. 402 */ 403 static inline unsigned long long __qdf_time_sched_clock(void) 404 { 405 return sched_clock(); 406 } 407 408 /** 409 * __qdf_time_ktime_sub() - Subtract two ktime objects and returns 410 * a ktime object 411 * @time1: time as ktime object 412 * @time2: time as ktime object 413 * 414 * Return: subtraction of ktime objects as ktime object 415 */ 416 static inline ktime_t __qdf_time_ktime_sub(ktime_t ktime1, ktime_t ktime2) 417 { 418 return ktime_sub(ktime1, ktime2); 419 } 420 421 /** 422 * __qdf_time_ktime_set() - Set a ktime_t variable from a seconds/nanoseconds 423 * value 424 * @secs: seconds to set 425 * @nsecs: nanoseconds to set 426 * 427 * Return: The ktime_t representation of the value. 428 */ 429 static inline ktime_t __qdf_time_ktime_set(const s64 secs, 430 const unsigned long nsecs) 431 { 432 return ktime_set(secs, nsecs); 433 } 434 435 /** 436 * __qdf_time_ktime_to_us() - Convert the ktime_t object into microseconds 437 * @ktime: time as ktime_t object 438 * 439 * Return: ktime_t in microseconds 440 */ 441 static inline int64_t __qdf_time_ktime_to_us(ktime_t ktime) 442 { 443 return ktime_to_us(ktime); 444 } 445 446 /** 447 * __qdf_time_ktime_get_real_time() - Get the time of day in qdf_timespec_t 448 * @ts: pointer to the qdf_timespec_t to be set 449 * 450 * Return: none 451 */ 452 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) 453 static inline void __qdf_time_ktime_get_real_time(__qdf_timespec_t *ts) 454 { 455 ktime_get_real_ts64(ts); 456 } 457 #else 458 static inline void __qdf_time_ktime_get_real_time(__qdf_timespec_t *ts) 459 { 460 do_gettimeofday(ts); 461 } 462 #endif 463 464 #endif 465