1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Based on arch/arm/include/asm/atomic.h
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 1996 Russell King.
6*4882a593Smuzhiyun * Copyright (C) 2002 Deep Blue Solutions Ltd.
7*4882a593Smuzhiyun * Copyright (C) 2012 ARM Ltd.
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun #ifndef __ASM_ATOMIC_H
10*4882a593Smuzhiyun #define __ASM_ATOMIC_H
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/compiler.h>
13*4882a593Smuzhiyun #include <linux/types.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include <asm/barrier.h>
16*4882a593Smuzhiyun #include <asm/cmpxchg.h>
17*4882a593Smuzhiyun #include <asm/lse.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #define ATOMIC_OP(op) \
20*4882a593Smuzhiyun static __always_inline void arch_##op(int i, atomic_t *v) \
21*4882a593Smuzhiyun { \
22*4882a593Smuzhiyun __lse_ll_sc_body(op, i, v); \
23*4882a593Smuzhiyun }
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun ATOMIC_OP(atomic_andnot)
ATOMIC_OP(atomic_or)26*4882a593Smuzhiyun ATOMIC_OP(atomic_or)
27*4882a593Smuzhiyun ATOMIC_OP(atomic_xor)
28*4882a593Smuzhiyun ATOMIC_OP(atomic_add)
29*4882a593Smuzhiyun ATOMIC_OP(atomic_and)
30*4882a593Smuzhiyun ATOMIC_OP(atomic_sub)
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #undef ATOMIC_OP
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define ATOMIC_FETCH_OP(name, op) \
35*4882a593Smuzhiyun static __always_inline int arch_##op##name(int i, atomic_t *v) \
36*4882a593Smuzhiyun { \
37*4882a593Smuzhiyun return __lse_ll_sc_body(op##name, i, v); \
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define ATOMIC_FETCH_OPS(op) \
41*4882a593Smuzhiyun ATOMIC_FETCH_OP(_relaxed, op) \
42*4882a593Smuzhiyun ATOMIC_FETCH_OP(_acquire, op) \
43*4882a593Smuzhiyun ATOMIC_FETCH_OP(_release, op) \
44*4882a593Smuzhiyun ATOMIC_FETCH_OP( , op)
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun ATOMIC_FETCH_OPS(atomic_fetch_andnot)
47*4882a593Smuzhiyun ATOMIC_FETCH_OPS(atomic_fetch_or)
48*4882a593Smuzhiyun ATOMIC_FETCH_OPS(atomic_fetch_xor)
49*4882a593Smuzhiyun ATOMIC_FETCH_OPS(atomic_fetch_add)
50*4882a593Smuzhiyun ATOMIC_FETCH_OPS(atomic_fetch_and)
51*4882a593Smuzhiyun ATOMIC_FETCH_OPS(atomic_fetch_sub)
52*4882a593Smuzhiyun ATOMIC_FETCH_OPS(atomic_add_return)
53*4882a593Smuzhiyun ATOMIC_FETCH_OPS(atomic_sub_return)
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun #undef ATOMIC_FETCH_OP
56*4882a593Smuzhiyun #undef ATOMIC_FETCH_OPS
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun #define ATOMIC64_OP(op) \
59*4882a593Smuzhiyun static __always_inline void arch_##op(long i, atomic64_t *v) \
60*4882a593Smuzhiyun { \
61*4882a593Smuzhiyun __lse_ll_sc_body(op, i, v); \
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun ATOMIC64_OP(atomic64_andnot)
65*4882a593Smuzhiyun ATOMIC64_OP(atomic64_or)
66*4882a593Smuzhiyun ATOMIC64_OP(atomic64_xor)
67*4882a593Smuzhiyun ATOMIC64_OP(atomic64_add)
68*4882a593Smuzhiyun ATOMIC64_OP(atomic64_and)
69*4882a593Smuzhiyun ATOMIC64_OP(atomic64_sub)
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun #undef ATOMIC64_OP
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun #define ATOMIC64_FETCH_OP(name, op) \
74*4882a593Smuzhiyun static __always_inline long arch_##op##name(long i, atomic64_t *v) \
75*4882a593Smuzhiyun { \
76*4882a593Smuzhiyun return __lse_ll_sc_body(op##name, i, v); \
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun #define ATOMIC64_FETCH_OPS(op) \
80*4882a593Smuzhiyun ATOMIC64_FETCH_OP(_relaxed, op) \
81*4882a593Smuzhiyun ATOMIC64_FETCH_OP(_acquire, op) \
82*4882a593Smuzhiyun ATOMIC64_FETCH_OP(_release, op) \
83*4882a593Smuzhiyun ATOMIC64_FETCH_OP( , op)
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun ATOMIC64_FETCH_OPS(atomic64_fetch_andnot)
86*4882a593Smuzhiyun ATOMIC64_FETCH_OPS(atomic64_fetch_or)
87*4882a593Smuzhiyun ATOMIC64_FETCH_OPS(atomic64_fetch_xor)
88*4882a593Smuzhiyun ATOMIC64_FETCH_OPS(atomic64_fetch_add)
89*4882a593Smuzhiyun ATOMIC64_FETCH_OPS(atomic64_fetch_and)
90*4882a593Smuzhiyun ATOMIC64_FETCH_OPS(atomic64_fetch_sub)
91*4882a593Smuzhiyun ATOMIC64_FETCH_OPS(atomic64_add_return)
92*4882a593Smuzhiyun ATOMIC64_FETCH_OPS(atomic64_sub_return)
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun #undef ATOMIC64_FETCH_OP
95*4882a593Smuzhiyun #undef ATOMIC64_FETCH_OPS
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun static __always_inline long arch_atomic64_dec_if_positive(atomic64_t *v)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun return __lse_ll_sc_body(atomic64_dec_if_positive, v);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun #define arch_atomic_read(v) __READ_ONCE((v)->counter)
103*4882a593Smuzhiyun #define arch_atomic_set(v, i) __WRITE_ONCE(((v)->counter), (i))
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun #define arch_atomic_add_return_relaxed arch_atomic_add_return_relaxed
106*4882a593Smuzhiyun #define arch_atomic_add_return_acquire arch_atomic_add_return_acquire
107*4882a593Smuzhiyun #define arch_atomic_add_return_release arch_atomic_add_return_release
108*4882a593Smuzhiyun #define arch_atomic_add_return arch_atomic_add_return
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun #define arch_atomic_sub_return_relaxed arch_atomic_sub_return_relaxed
111*4882a593Smuzhiyun #define arch_atomic_sub_return_acquire arch_atomic_sub_return_acquire
112*4882a593Smuzhiyun #define arch_atomic_sub_return_release arch_atomic_sub_return_release
113*4882a593Smuzhiyun #define arch_atomic_sub_return arch_atomic_sub_return
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun #define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add_relaxed
116*4882a593Smuzhiyun #define arch_atomic_fetch_add_acquire arch_atomic_fetch_add_acquire
117*4882a593Smuzhiyun #define arch_atomic_fetch_add_release arch_atomic_fetch_add_release
118*4882a593Smuzhiyun #define arch_atomic_fetch_add arch_atomic_fetch_add
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun #define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub_relaxed
121*4882a593Smuzhiyun #define arch_atomic_fetch_sub_acquire arch_atomic_fetch_sub_acquire
122*4882a593Smuzhiyun #define arch_atomic_fetch_sub_release arch_atomic_fetch_sub_release
123*4882a593Smuzhiyun #define arch_atomic_fetch_sub arch_atomic_fetch_sub
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun #define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and_relaxed
126*4882a593Smuzhiyun #define arch_atomic_fetch_and_acquire arch_atomic_fetch_and_acquire
127*4882a593Smuzhiyun #define arch_atomic_fetch_and_release arch_atomic_fetch_and_release
128*4882a593Smuzhiyun #define arch_atomic_fetch_and arch_atomic_fetch_and
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun #define arch_atomic_fetch_andnot_relaxed arch_atomic_fetch_andnot_relaxed
131*4882a593Smuzhiyun #define arch_atomic_fetch_andnot_acquire arch_atomic_fetch_andnot_acquire
132*4882a593Smuzhiyun #define arch_atomic_fetch_andnot_release arch_atomic_fetch_andnot_release
133*4882a593Smuzhiyun #define arch_atomic_fetch_andnot arch_atomic_fetch_andnot
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun #define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or_relaxed
136*4882a593Smuzhiyun #define arch_atomic_fetch_or_acquire arch_atomic_fetch_or_acquire
137*4882a593Smuzhiyun #define arch_atomic_fetch_or_release arch_atomic_fetch_or_release
138*4882a593Smuzhiyun #define arch_atomic_fetch_or arch_atomic_fetch_or
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun #define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor_relaxed
141*4882a593Smuzhiyun #define arch_atomic_fetch_xor_acquire arch_atomic_fetch_xor_acquire
142*4882a593Smuzhiyun #define arch_atomic_fetch_xor_release arch_atomic_fetch_xor_release
143*4882a593Smuzhiyun #define arch_atomic_fetch_xor arch_atomic_fetch_xor
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun #define arch_atomic_xchg_relaxed(v, new) \
146*4882a593Smuzhiyun arch_xchg_relaxed(&((v)->counter), (new))
147*4882a593Smuzhiyun #define arch_atomic_xchg_acquire(v, new) \
148*4882a593Smuzhiyun arch_xchg_acquire(&((v)->counter), (new))
149*4882a593Smuzhiyun #define arch_atomic_xchg_release(v, new) \
150*4882a593Smuzhiyun arch_xchg_release(&((v)->counter), (new))
151*4882a593Smuzhiyun #define arch_atomic_xchg(v, new) \
152*4882a593Smuzhiyun arch_xchg(&((v)->counter), (new))
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun #define arch_atomic_cmpxchg_relaxed(v, old, new) \
155*4882a593Smuzhiyun arch_cmpxchg_relaxed(&((v)->counter), (old), (new))
156*4882a593Smuzhiyun #define arch_atomic_cmpxchg_acquire(v, old, new) \
157*4882a593Smuzhiyun arch_cmpxchg_acquire(&((v)->counter), (old), (new))
158*4882a593Smuzhiyun #define arch_atomic_cmpxchg_release(v, old, new) \
159*4882a593Smuzhiyun arch_cmpxchg_release(&((v)->counter), (old), (new))
160*4882a593Smuzhiyun #define arch_atomic_cmpxchg(v, old, new) \
161*4882a593Smuzhiyun arch_cmpxchg(&((v)->counter), (old), (new))
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun #define arch_atomic_andnot arch_atomic_andnot
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun /*
166*4882a593Smuzhiyun * 64-bit arch_atomic operations.
167*4882a593Smuzhiyun */
168*4882a593Smuzhiyun #define ATOMIC64_INIT ATOMIC_INIT
169*4882a593Smuzhiyun #define arch_atomic64_read arch_atomic_read
170*4882a593Smuzhiyun #define arch_atomic64_set arch_atomic_set
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun #define arch_atomic64_add_return_relaxed arch_atomic64_add_return_relaxed
173*4882a593Smuzhiyun #define arch_atomic64_add_return_acquire arch_atomic64_add_return_acquire
174*4882a593Smuzhiyun #define arch_atomic64_add_return_release arch_atomic64_add_return_release
175*4882a593Smuzhiyun #define arch_atomic64_add_return arch_atomic64_add_return
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun #define arch_atomic64_sub_return_relaxed arch_atomic64_sub_return_relaxed
178*4882a593Smuzhiyun #define arch_atomic64_sub_return_acquire arch_atomic64_sub_return_acquire
179*4882a593Smuzhiyun #define arch_atomic64_sub_return_release arch_atomic64_sub_return_release
180*4882a593Smuzhiyun #define arch_atomic64_sub_return arch_atomic64_sub_return
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun #define arch_atomic64_fetch_add_relaxed arch_atomic64_fetch_add_relaxed
183*4882a593Smuzhiyun #define arch_atomic64_fetch_add_acquire arch_atomic64_fetch_add_acquire
184*4882a593Smuzhiyun #define arch_atomic64_fetch_add_release arch_atomic64_fetch_add_release
185*4882a593Smuzhiyun #define arch_atomic64_fetch_add arch_atomic64_fetch_add
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun #define arch_atomic64_fetch_sub_relaxed arch_atomic64_fetch_sub_relaxed
188*4882a593Smuzhiyun #define arch_atomic64_fetch_sub_acquire arch_atomic64_fetch_sub_acquire
189*4882a593Smuzhiyun #define arch_atomic64_fetch_sub_release arch_atomic64_fetch_sub_release
190*4882a593Smuzhiyun #define arch_atomic64_fetch_sub arch_atomic64_fetch_sub
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun #define arch_atomic64_fetch_and_relaxed arch_atomic64_fetch_and_relaxed
193*4882a593Smuzhiyun #define arch_atomic64_fetch_and_acquire arch_atomic64_fetch_and_acquire
194*4882a593Smuzhiyun #define arch_atomic64_fetch_and_release arch_atomic64_fetch_and_release
195*4882a593Smuzhiyun #define arch_atomic64_fetch_and arch_atomic64_fetch_and
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun #define arch_atomic64_fetch_andnot_relaxed arch_atomic64_fetch_andnot_relaxed
198*4882a593Smuzhiyun #define arch_atomic64_fetch_andnot_acquire arch_atomic64_fetch_andnot_acquire
199*4882a593Smuzhiyun #define arch_atomic64_fetch_andnot_release arch_atomic64_fetch_andnot_release
200*4882a593Smuzhiyun #define arch_atomic64_fetch_andnot arch_atomic64_fetch_andnot
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun #define arch_atomic64_fetch_or_relaxed arch_atomic64_fetch_or_relaxed
203*4882a593Smuzhiyun #define arch_atomic64_fetch_or_acquire arch_atomic64_fetch_or_acquire
204*4882a593Smuzhiyun #define arch_atomic64_fetch_or_release arch_atomic64_fetch_or_release
205*4882a593Smuzhiyun #define arch_atomic64_fetch_or arch_atomic64_fetch_or
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun #define arch_atomic64_fetch_xor_relaxed arch_atomic64_fetch_xor_relaxed
208*4882a593Smuzhiyun #define arch_atomic64_fetch_xor_acquire arch_atomic64_fetch_xor_acquire
209*4882a593Smuzhiyun #define arch_atomic64_fetch_xor_release arch_atomic64_fetch_xor_release
210*4882a593Smuzhiyun #define arch_atomic64_fetch_xor arch_atomic64_fetch_xor
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun #define arch_atomic64_xchg_relaxed arch_atomic_xchg_relaxed
213*4882a593Smuzhiyun #define arch_atomic64_xchg_acquire arch_atomic_xchg_acquire
214*4882a593Smuzhiyun #define arch_atomic64_xchg_release arch_atomic_xchg_release
215*4882a593Smuzhiyun #define arch_atomic64_xchg arch_atomic_xchg
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun #define arch_atomic64_cmpxchg_relaxed arch_atomic_cmpxchg_relaxed
218*4882a593Smuzhiyun #define arch_atomic64_cmpxchg_acquire arch_atomic_cmpxchg_acquire
219*4882a593Smuzhiyun #define arch_atomic64_cmpxchg_release arch_atomic_cmpxchg_release
220*4882a593Smuzhiyun #define arch_atomic64_cmpxchg arch_atomic_cmpxchg
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun #define arch_atomic64_andnot arch_atomic64_andnot
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun #define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun #define ARCH_ATOMIC
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun #endif /* __ASM_ATOMIC_H */
229