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 #define VDSO_HAS_CLOCK_GETRES 1
27 #define __VDSO_USE_SYSCALL ULLONG_MAX
29 static __always_inline
long gettimeofday_fallback(
30 struct __kernel_old_timeval
*_tv
,
33 register struct timezone
*tz
asm("a1") = _tz
;
34 register struct __kernel_old_timeval
*tv
asm("a0") = _tv
;
35 register long ret
asm("v0");
36 register long nr
asm("v0") = __NR_gettimeofday
;
37 register long error
asm("a3");
41 : "=r" (ret
), "=r" (error
)
42 : "r" (tv
), "r" (tz
), "r" (nr
)
43 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
44 "$14", "$15", "$24", "$25", "hi", "lo", "memory");
46 return error
? -ret
: ret
;
49 static __always_inline
long clock_gettime_fallback(
51 struct __kernel_timespec
*_ts
)
53 register struct __kernel_timespec
*ts
asm("a1") = _ts
;
54 register clockid_t clkid
asm("a0") = _clkid
;
55 register long ret
asm("v0");
56 #if _MIPS_SIM == _MIPS_SIM_ABI64
57 register long nr
asm("v0") = __NR_clock_gettime
;
59 register long nr
asm("v0") = __NR_clock_gettime64
;
61 register long error
asm("a3");
65 : "=r" (ret
), "=r" (error
)
66 : "r" (clkid
), "r" (ts
), "r" (nr
)
67 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
68 "$14", "$15", "$24", "$25", "hi", "lo", "memory");
70 return error
? -ret
: ret
;
73 static __always_inline
int clock_getres_fallback(
75 struct __kernel_timespec
*_ts
)
77 register struct __kernel_timespec
*ts
asm("a1") = _ts
;
78 register clockid_t clkid
asm("a0") = _clkid
;
79 register long ret
asm("v0");
80 #if _MIPS_SIM == _MIPS_SIM_ABI64
81 register long nr
asm("v0") = __NR_clock_getres
;
83 register long nr
asm("v0") = __NR_clock_getres_time64
;
85 register long error
asm("a3");
89 : "=r" (ret
), "=r" (error
)
90 : "r" (clkid
), "r" (ts
), "r" (nr
)
91 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
92 "$14", "$15", "$24", "$25", "hi", "lo", "memory");
94 return error
? -ret
: ret
;
97 #if _MIPS_SIM != _MIPS_SIM_ABI64
99 static __always_inline
long clock_gettime32_fallback(
101 struct old_timespec32
*_ts
)
103 register struct old_timespec32
*ts
asm("a1") = _ts
;
104 register clockid_t clkid
asm("a0") = _clkid
;
105 register long ret
asm("v0");
106 register long nr
asm("v0") = __NR_clock_gettime
;
107 register long error
asm("a3");
111 : "=r" (ret
), "=r" (error
)
112 : "r" (clkid
), "r" (ts
), "r" (nr
)
113 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
114 "$14", "$15", "$24", "$25", "hi", "lo", "memory");
116 return error
? -ret
: ret
;
119 static __always_inline
int clock_getres32_fallback(
121 struct old_timespec32
*_ts
)
123 register struct old_timespec32
*ts
asm("a1") = _ts
;
124 register clockid_t clkid
asm("a0") = _clkid
;
125 register long ret
asm("v0");
126 register long nr
asm("v0") = __NR_clock_getres
;
127 register long error
asm("a3");
131 : "=r" (ret
), "=r" (error
)
132 : "r" (clkid
), "r" (ts
), "r" (nr
)
133 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
134 "$14", "$15", "$24", "$25", "hi", "lo", "memory");
136 return error
? -ret
: ret
;
140 #ifdef CONFIG_CSRC_R4K
142 static __always_inline u64
read_r4k_count(void)
146 __asm__
__volatile__(
158 #ifdef CONFIG_CLKSRC_MIPS_GIC
160 static __always_inline u64
read_gic_count(const struct vdso_data
*data
)
162 void __iomem
*gic
= get_gic(data
);
166 hi
= __raw_readl(gic
+ sizeof(lo
));
167 lo
= __raw_readl(gic
);
168 hi2
= __raw_readl(gic
+ sizeof(lo
));
171 return (((u64
)hi
) << 32) + lo
;
176 static __always_inline u64
__arch_get_hw_counter(s32 clock_mode
)
178 #ifdef CONFIG_CLKSRC_MIPS_GIC
179 const struct vdso_data
*data
= get_vdso_data();
183 switch (clock_mode
) {
184 #ifdef CONFIG_CSRC_R4K
186 cycle_now
= read_r4k_count();
189 #ifdef CONFIG_CLKSRC_MIPS_GIC
191 cycle_now
= read_gic_count(data
);
195 cycle_now
= __VDSO_USE_SYSCALL
;
202 static __always_inline
const struct vdso_data
*__arch_get_vdso_data(void)
204 return get_vdso_data();
207 #endif /* !__ASSEMBLY__ */
209 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */