GNU Linux-libre 6.8.9-gnu
[releases.git] / arch / sparc / include / asm / vvar.h
1 /*
2  * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
3  */
4
5 #ifndef _ASM_SPARC_VVAR_DATA_H
6 #define _ASM_SPARC_VVAR_DATA_H
7
8 #include <asm/clocksource.h>
9 #include <asm/processor.h>
10 #include <asm/barrier.h>
11 #include <linux/time.h>
12 #include <linux/types.h>
13
14 struct vvar_data {
15         unsigned int seq;
16
17         int vclock_mode;
18         struct { /* extract of a clocksource struct */
19                 u64     cycle_last;
20                 u64     mask;
21                 int     mult;
22                 int     shift;
23         } clock;
24         /* open coded 'struct timespec' */
25         u64             wall_time_sec;
26         u64             wall_time_snsec;
27         u64             monotonic_time_snsec;
28         u64             monotonic_time_sec;
29         u64             monotonic_time_coarse_sec;
30         u64             monotonic_time_coarse_nsec;
31         u64             wall_time_coarse_sec;
32         u64             wall_time_coarse_nsec;
33
34         int             tz_minuteswest;
35         int             tz_dsttime;
36 };
37
38 extern struct vvar_data *vvar_data;
39 extern int vdso_fix_stick;
40
41 static inline unsigned int vvar_read_begin(const struct vvar_data *s)
42 {
43         unsigned int ret;
44
45 repeat:
46         ret = READ_ONCE(s->seq);
47         if (unlikely(ret & 1)) {
48                 cpu_relax();
49                 goto repeat;
50         }
51         smp_rmb(); /* Finish all reads before we return seq */
52         return ret;
53 }
54
55 static inline int vvar_read_retry(const struct vvar_data *s,
56                                         unsigned int start)
57 {
58         smp_rmb(); /* Finish all reads before checking the value of seq */
59         return unlikely(s->seq != start);
60 }
61
62 static inline void vvar_write_begin(struct vvar_data *s)
63 {
64         ++s->seq;
65         smp_wmb(); /* Makes sure that increment of seq is reflected */
66 }
67
68 static inline void vvar_write_end(struct vvar_data *s)
69 {
70         smp_wmb(); /* Makes the value of seq current before we increment */
71         ++s->seq;
72 }
73
74
75 #endif /* _ASM_SPARC_VVAR_DATA_H */