2 * Copyright (C) 2018 ARM Limited
3 * Copyright (C) 2015 Imagination Technologies
4 * Author: Alex Smith <alex.smith@imgtec.com>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
11 #ifndef __ASM_VDSO_GETTIMEOFDAY_H
12 #define __ASM_VDSO_GETTIMEOFDAY_H
16 #include <linux/compiler.h>
17 #include <linux/time.h>
19 #include <asm/vdso/vdso.h>
20 #include <asm/clocksource.h>
22 #include <asm/unistd.h>
25 #ifdef CONFIG_MIPS_CLOCK_VSYSCALL
27 static __always_inline long gettimeofday_fallback(
28 struct __kernel_old_timeval *_tv,
31 register struct timezone *tz asm("a1") = _tz;
32 register struct __kernel_old_timeval *tv asm("a0") = _tv;
33 register long ret asm("v0");
34 register long nr asm("v0") = __NR_gettimeofday;
35 register long error asm("a3");
39 : "=r" (ret), "=r" (error)
40 : "r" (tv), "r" (tz), "r" (nr)
41 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
42 "$14", "$15", "$24", "$25", "hi", "lo", "memory");
44 return error ? -ret : ret;
49 static __always_inline long gettimeofday_fallback(
50 struct __kernel_old_timeval *_tv,
58 static __always_inline long clock_gettime_fallback(
60 struct __kernel_timespec *_ts)
62 register struct __kernel_timespec *ts asm("a1") = _ts;
63 register clockid_t clkid asm("a0") = _clkid;
64 register long ret asm("v0");
65 #if _MIPS_SIM == _MIPS_SIM_ABI64
66 register long nr asm("v0") = __NR_clock_gettime;
68 register long nr asm("v0") = __NR_clock_gettime64;
70 register long error asm("a3");
74 : "=r" (ret), "=r" (error)
75 : "r" (clkid), "r" (ts), "r" (nr)
76 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
77 "$14", "$15", "$24", "$25", "hi", "lo", "memory");
79 return error ? -ret : ret;
82 #ifdef CONFIG_CSRC_R4K
84 static __always_inline u64 read_r4k_count(void)
100 #ifdef CONFIG_CLKSRC_MIPS_GIC
102 static __always_inline u64 read_gic_count(const struct vdso_data *data)
104 void __iomem *gic = get_gic(data);
108 hi = __raw_readl(gic + sizeof(lo));
109 lo = __raw_readl(gic);
110 hi2 = __raw_readl(gic + sizeof(lo));
113 return (((u64)hi) << 32) + lo;
118 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
120 #ifdef CONFIG_CLKSRC_MIPS_GIC
121 const struct vdso_data *data = get_vdso_data();
125 switch (clock_mode) {
126 #ifdef CONFIG_CSRC_R4K
128 cycle_now = read_r4k_count();
131 #ifdef CONFIG_CLKSRC_MIPS_GIC
133 cycle_now = read_gic_count(data);
144 static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
146 return get_vdso_data();
149 #endif /* !__ASSEMBLY__ */
151 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */