| /* |
| * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /** |
| * DOC: i_qdf_time |
| * This file provides OS dependent time API's. |
| */ |
| |
| #ifndef _I_QDF_TIME_H |
| #define _I_QDF_TIME_H |
| |
| #include <linux/version.h> |
| #include <linux/jiffies.h> |
| #include <linux/delay.h> |
| #include <linux/ktime.h> |
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) |
| #include <linux/timekeeping.h> |
| #else |
| #include <linux/hrtimer.h> |
| #endif |
| #ifdef MSM_PLATFORM |
| #include <asm/arch_timer.h> |
| #endif |
| #ifdef CONFIG_CNSS |
| #include <net/cnss.h> |
| #endif |
| |
| typedef unsigned long __qdf_time_t; |
| typedef ktime_t __qdf_ktime_t; |
| |
| /** |
| * __qdf_ns_to_ktime() - Converts nanoseconds to a ktime object |
| * @ns: time in nanoseconds |
| * |
| * Return: nanoseconds as ktime object |
| */ |
| static inline ktime_t __qdf_ns_to_ktime(uint64_t ns) |
| { |
| return ns_to_ktime(ns); |
| } |
| |
| /** |
| * __qdf_ktime_add() - Adds two ktime objects and returns |
| * a ktime object |
| * @time1: time as ktime object |
| * @time2: time as ktime object |
| * |
| * Return: sum of ktime objects as ktime object |
| */ |
| static inline ktime_t __qdf_ktime_add(ktime_t ktime1, ktime_t ktime2) |
| { |
| return ktime_add(ktime1, ktime2); |
| } |
| |
| /** |
| * __qdf_ktime_get() - Gets the current time as ktime object |
| * |
| * Return: current time as ktime object |
| */ |
| static inline ktime_t __qdf_ktime_get(void) |
| { |
| return ktime_get(); |
| } |
| |
| /** |
| * __qdf_ktime_add_ns() - Adds ktime object and nanoseconds value and |
| * returns the ktime object |
| * |
| * Return: ktime object |
| */ |
| static inline ktime_t __qdf_ktime_add_ns(ktime_t ktime, int64_t ns) |
| { |
| return ktime_add_ns(ktime, ns); |
| } |
| |
| /** |
| * __qdf_ktime_to_ns() - convert ktime to nanoseconds |
| * @ktime: time as ktime object |
| * @ns: time in nanoseconds |
| * |
| * Return: ktime in nanoseconds |
| */ |
| static inline int64_t __qdf_ktime_to_ns(ktime_t ktime) |
| { |
| return ktime_to_ns(ktime); |
| } |
| |
| /** |
| * __qdf_ktime_to_ms() - convert ktime to milliseconds |
| * @ktime: time as ktime object |
| * |
| * Return: ktime in milliseconds |
| */ |
| static inline int64_t __qdf_ktime_to_ms(ktime_t ktime) |
| { |
| return ktime_to_ms(ktime); |
| } |
| |
| |
| /** |
| * __qdf_system_ticks() - get system ticks |
| * |
| * Return: system tick in jiffies |
| */ |
| static inline __qdf_time_t __qdf_system_ticks(void) |
| { |
| return jiffies; |
| } |
| |
| #define __qdf_system_ticks_per_sec HZ |
| |
| /** |
| * __qdf_system_ticks_to_msecs() - convert system ticks into milli seconds |
| * @ticks: System ticks |
| * |
| * Return: system tick converted into milli seconds |
| */ |
| static inline uint32_t __qdf_system_ticks_to_msecs(unsigned long ticks) |
| { |
| return jiffies_to_msecs(ticks); |
| } |
| |
| /** |
| * __qdf_system_msecs_to_ticks() - convert milli seconds into system ticks |
| * @msecs: Milli seconds |
| * |
| * Return: milli seconds converted into system ticks |
| */ |
| static inline __qdf_time_t __qdf_system_msecs_to_ticks(uint32_t msecs) |
| { |
| return msecs_to_jiffies(msecs); |
| } |
| |
| /** |
| * __qdf_get_system_uptime() - get system uptime |
| * |
| * Return: system uptime in jiffies |
| */ |
| static inline __qdf_time_t __qdf_get_system_uptime(void) |
| { |
| return jiffies; |
| } |
| |
| static inline unsigned long __qdf_get_system_timestamp(void) |
| { |
| return (jiffies / HZ) * 1000 + (jiffies % HZ) * (1000 / HZ); |
| } |
| |
| #ifdef CONFIG_ARM |
| /** |
| * __qdf_udelay() - delay execution for given microseconds |
| * @usecs: Micro seconds to delay |
| * |
| * Return: none |
| */ |
| static inline void __qdf_udelay(uint32_t usecs) |
| { |
| /* |
| * This is in support of XScale build. They have a limit on the udelay |
| * value, so we have to make sure we don't approach the limit |
| */ |
| uint32_t mticks; |
| uint32_t leftover; |
| int i; |
| /* slice into 1024 usec chunks (simplifies calculation) */ |
| mticks = usecs >> 10; |
| leftover = usecs - (mticks << 10); |
| for (i = 0; i < mticks; i++) |
| udelay(1024); |
| udelay(leftover); |
| } |
| #else |
| static inline void __qdf_udelay(uint32_t usecs) |
| { |
| /* Normal Delay functions. Time specified in microseconds */ |
| udelay(usecs); |
| } |
| #endif |
| |
| /** |
| * __qdf_mdelay() - delay execution for given milliseconds |
| * @usecs: Milliseconds to delay |
| * |
| * Return: none |
| */ |
| static inline void __qdf_mdelay(uint32_t msecs) |
| { |
| mdelay(msecs); |
| } |
| |
| /** |
| * __qdf_system_time_after() - Check if a is later than b |
| * @a: Time stamp value a |
| * @b: Time stamp value b |
| * |
| * Return: |
| * true if a < b else false |
| */ |
| static inline bool __qdf_system_time_after(__qdf_time_t a, __qdf_time_t b) |
| { |
| return (long)(b) - (long)(a) < 0; |
| } |
| |
| /** |
| * __qdf_system_time_before() - Check if a is before b |
| * @a: Time stamp value a |
| * @b: Time stamp value b |
| * |
| * Return: |
| * true if a is before b else false |
| */ |
| static inline bool __qdf_system_time_before(__qdf_time_t a, __qdf_time_t b) |
| { |
| return __qdf_system_time_after(b, a); |
| } |
| |
| /** |
| * __qdf_system_time_after_eq() - Check if a atleast as recent as b, if not |
| * later |
| * @a: Time stamp value a |
| * @b: Time stamp value b |
| * |
| * Return: |
| * true if a >= b else false |
| */ |
| static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b) |
| { |
| return (long)(a) - (long)(b) >= 0; |
| } |
| |
| /** |
| * __qdf_get_monotonic_boottime() - get monotonic kernel boot time |
| * This API is similar to qdf_get_system_boottime but it includes |
| * time spent in suspend. |
| * |
| * Return: Time in microseconds |
| */ |
| static inline uint64_t __qdf_get_monotonic_boottime(void) |
| { |
| struct timespec ts; |
| |
| get_monotonic_boottime(&ts); |
| |
| return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); |
| } |
| |
| #if defined (MSM_PLATFORM) |
| |
| /** |
| * __qdf_get_log_timestamp() - get msm timer ticks |
| * |
| * Returns QTIMER(19.2 MHz) clock ticks. To convert it into seconds |
| * divide it by 19200. |
| * |
| * Return: QTIMER(19.2 MHz) clock ticks |
| */ |
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) |
| static inline uint64_t __qdf_get_log_timestamp(void) |
| { |
| return arch_counter_get_cntvct(); |
| } |
| #else |
| static inline uint64_t __qdf_get_log_timestamp(void) |
| { |
| return arch_counter_get_cntpct(); |
| } |
| #endif /* LINUX_VERSION_CODE */ |
| #else |
| |
| /** |
| * __qdf_get_log_timestamp - get time stamp for logging |
| * |
| * Return: system tick for non MSM platfroms |
| */ |
| static inline uint64_t __qdf_get_log_timestamp(void) |
| { |
| struct timespec ts; |
| |
| ktime_get_ts(&ts); |
| |
| return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); |
| } |
| #endif |
| |
| /** |
| * __qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds |
| * |
| * __qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds |
| * that have elapsed since the system was booted. It also includes the time when |
| * system was suspended. |
| * |
| * Return: |
| * The time since system booted in nanoseconds |
| */ |
| |
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) |
| static inline uint64_t __qdf_get_bootbased_boottime_ns(void) |
| { |
| return ktime_get_boot_ns(); |
| } |
| |
| #else |
| static inline uint64_t __qdf_get_bootbased_boottime_ns(void) |
| { |
| return ktime_to_ns(ktime_get_boottime()); |
| } |
| #endif |
| |
| #endif |