xref: /linux/arch/loongarch/include/asm/vdso/gettimeofday.h (revision d30c1683aaecb93d2ab95685dc4300a33d3cea7a)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Author: Huacai Chen <chenhuacai@loongson.cn>
4  *
5  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
6  */
7 #ifndef __ASM_VDSO_GETTIMEOFDAY_H
8 #define __ASM_VDSO_GETTIMEOFDAY_H
9 
10 #ifndef __ASSEMBLER__
11 
12 #include <asm/unistd.h>
13 #include <asm/vdso/vdso.h>
14 
15 #ifdef CONFIG_GENERIC_GETTIMEOFDAY
16 
17 #define VDSO_HAS_CLOCK_GETRES		1
18 
19 static __always_inline long gettimeofday_fallback(
20 				struct __kernel_old_timeval *_tv,
21 				struct timezone *_tz)
22 {
23 	register struct __kernel_old_timeval *tv asm("a0") = _tv;
24 	register struct timezone *tz asm("a1") = _tz;
25 	register long nr asm("a7") = __NR_gettimeofday;
26 	register long ret asm("a0");
27 
28 	asm volatile(
29 	"       syscall 0\n"
30 	: "=r" (ret)
31 	: "r" (nr), "r" (tv), "r" (tz)
32 	: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
33 	  "$t8", "memory");
34 
35 	return ret;
36 }
37 
38 static __always_inline long clock_gettime_fallback(
39 					clockid_t _clkid,
40 					struct __kernel_timespec *_ts)
41 {
42 	register clockid_t clkid asm("a0") = _clkid;
43 	register struct __kernel_timespec *ts asm("a1") = _ts;
44 	register long nr asm("a7") = __NR_clock_gettime;
45 	register long ret asm("a0");
46 
47 	asm volatile(
48 	"       syscall 0\n"
49 	: "=r" (ret)
50 	: "r" (nr), "r" (clkid), "r" (ts)
51 	: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
52 	  "$t8", "memory");
53 
54 	return ret;
55 }
56 
57 static __always_inline int clock_getres_fallback(
58 					clockid_t _clkid,
59 					struct __kernel_timespec *_ts)
60 {
61 	register clockid_t clkid asm("a0") = _clkid;
62 	register struct __kernel_timespec *ts asm("a1") = _ts;
63 	register long nr asm("a7") = __NR_clock_getres;
64 	register long ret asm("a0");
65 
66 	asm volatile(
67 	"       syscall 0\n"
68 	: "=r" (ret)
69 	: "r" (nr), "r" (clkid), "r" (ts)
70 	: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
71 	  "$t8", "memory");
72 
73 	return ret;
74 }
75 
76 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
77 						 const struct vdso_time_data *vd)
78 {
79 	uint64_t count;
80 
81 	__asm__ __volatile__(
82 	"	rdtime.d %0, $zero\n"
83 	: "=r" (count));
84 
85 	return count;
86 }
87 
88 static inline bool loongarch_vdso_hres_capable(void)
89 {
90 	return true;
91 }
92 #define __arch_vdso_hres_capable loongarch_vdso_hres_capable
93 
94 #endif /* CONFIG_GENERIC_GETTIMEOFDAY */
95 
96 #endif /* !__ASSEMBLER__ */
97 
98 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */
99