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 __ASSEMBLY__
11
12#include <asm/unistd.h>
13#include <asm/vdso/vdso.h>
14
15#define VDSO_HAS_CLOCK_GETRES		1
16
17static __always_inline long gettimeofday_fallback(
18				struct __kernel_old_timeval *_tv,
19				struct timezone *_tz)
20{
21	register struct __kernel_old_timeval *tv asm("a0") = _tv;
22	register struct timezone *tz asm("a1") = _tz;
23	register long nr asm("a7") = __NR_gettimeofday;
24	register long ret asm("a0");
25
26	asm volatile(
27	"       syscall 0\n"
28	: "+r" (ret)
29	: "r" (nr), "r" (tv), "r" (tz)
30	: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
31	  "$t8", "memory");
32
33	return ret;
34}
35
36static __always_inline long clock_gettime_fallback(
37					clockid_t _clkid,
38					struct __kernel_timespec *_ts)
39{
40	register clockid_t clkid asm("a0") = _clkid;
41	register struct __kernel_timespec *ts asm("a1") = _ts;
42	register long nr asm("a7") = __NR_clock_gettime;
43	register long ret asm("a0");
44
45	asm volatile(
46	"       syscall 0\n"
47	: "+r" (ret)
48	: "r" (nr), "r" (clkid), "r" (ts)
49	: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
50	  "$t8", "memory");
51
52	return ret;
53}
54
55static __always_inline int clock_getres_fallback(
56					clockid_t _clkid,
57					struct __kernel_timespec *_ts)
58{
59	register clockid_t clkid asm("a0") = _clkid;
60	register struct __kernel_timespec *ts asm("a1") = _ts;
61	register long nr asm("a7") = __NR_clock_getres;
62	register long ret asm("a0");
63
64	asm volatile(
65	"       syscall 0\n"
66	: "+r" (ret)
67	: "r" (nr), "r" (clkid), "r" (ts)
68	: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
69	  "$t8", "memory");
70
71	return ret;
72}
73
74static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
75						 const struct vdso_data *vd)
76{
77	uint64_t count;
78
79	__asm__ __volatile__(
80	"	rdtime.d %0, $zero\n"
81	: "=r" (count));
82
83	return count;
84}
85
86static inline bool loongarch_vdso_hres_capable(void)
87{
88	return true;
89}
90#define __arch_vdso_hres_capable loongarch_vdso_hres_capable
91
92static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
93{
94	return (const struct vdso_data *)get_vdso_data();
95}
96
97#ifdef CONFIG_TIME_NS
98static __always_inline
99const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
100{
101	return (const struct vdso_data *)(get_vdso_data() + VVAR_TIMENS_PAGE_OFFSET * PAGE_SIZE);
102}
103#endif
104#endif /* !__ASSEMBLY__ */
105
106#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
107