blob: 34a028a7bcc53c095a2028f2d0cee89cd3835292 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Arnd Bergmann72099ed2009-05-13 22:56:29 +00002#ifndef _ASM_GENERIC_ATOMIC_LONG_H
3#define _ASM_GENERIC_ATOMIC_LONG_H
Christoph Lameterd3cb4872006-01-06 00:11:20 -08004/*
5 * Copyright (C) 2005 Silicon Graphics, Inc.
Christoph Lametercde53532008-07-04 09:59:22 -07006 * Christoph Lameter
Christoph Lameterd3cb4872006-01-06 00:11:20 -08007 *
8 * Allows to provide arch independent atomic definitions without the need to
9 * edit all arch specific atomic.h files.
10 */
11
Andrew Morton5998bf12006-01-08 01:00:29 -080012#include <asm/types.h>
Christoph Lameterd3cb4872006-01-06 00:11:20 -080013
14/*
15 * Suppport for atomic_long_t
16 *
17 * Casts for parameters are avoided for existing atomic functions in order to
18 * avoid issues with cast-as-lval under gcc 4.x and other limitations that the
19 * macros of a platform may have.
20 */
21
22#if BITS_PER_LONG == 64
23
24typedef atomic64_t atomic_long_t;
25
26#define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i)
Will Deacon586b6102015-08-06 17:54:38 +010027#define ATOMIC_LONG_PFX(x) atomic64 ## x
Christoph Lameterd3cb4872006-01-06 00:11:20 -080028
Will Deacon586b6102015-08-06 17:54:38 +010029#else
Christoph Lameterd3cb4872006-01-06 00:11:20 -080030
31typedef atomic_t atomic_long_t;
32
33#define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i)
Will Deacon586b6102015-08-06 17:54:38 +010034#define ATOMIC_LONG_PFX(x) atomic ## x
35
36#endif
37
Will Deacon6d79ef22015-08-06 17:54:39 +010038#define ATOMIC_LONG_READ_OP(mo) \
Peter Zijlstrae3e72ab2015-09-18 13:22:52 +020039static inline long atomic_long_read##mo(const atomic_long_t *l) \
Will Deacon6d79ef22015-08-06 17:54:39 +010040{ \
41 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
42 \
43 return (long)ATOMIC_LONG_PFX(_read##mo)(v); \
Christoph Lameterd3cb4872006-01-06 00:11:20 -080044}
Will Deacon6d79ef22015-08-06 17:54:39 +010045ATOMIC_LONG_READ_OP()
46ATOMIC_LONG_READ_OP(_acquire)
Christoph Lameterd3cb4872006-01-06 00:11:20 -080047
Will Deacon6d79ef22015-08-06 17:54:39 +010048#undef ATOMIC_LONG_READ_OP
Christoph Lameterd3cb4872006-01-06 00:11:20 -080049
Will Deacon6d79ef22015-08-06 17:54:39 +010050#define ATOMIC_LONG_SET_OP(mo) \
51static inline void atomic_long_set##mo(atomic_long_t *l, long i) \
52{ \
53 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
54 \
55 ATOMIC_LONG_PFX(_set##mo)(v, i); \
Christoph Lameterd3cb4872006-01-06 00:11:20 -080056}
Will Deacon6d79ef22015-08-06 17:54:39 +010057ATOMIC_LONG_SET_OP()
58ATOMIC_LONG_SET_OP(_release)
59
60#undef ATOMIC_LONG_SET_OP
61
62#define ATOMIC_LONG_ADD_SUB_OP(op, mo) \
63static inline long \
64atomic_long_##op##_return##mo(long i, atomic_long_t *l) \
65{ \
66 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
67 \
68 return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(i, v); \
69}
70ATOMIC_LONG_ADD_SUB_OP(add,)
71ATOMIC_LONG_ADD_SUB_OP(add, _relaxed)
72ATOMIC_LONG_ADD_SUB_OP(add, _acquire)
73ATOMIC_LONG_ADD_SUB_OP(add, _release)
74ATOMIC_LONG_ADD_SUB_OP(sub,)
75ATOMIC_LONG_ADD_SUB_OP(sub, _relaxed)
76ATOMIC_LONG_ADD_SUB_OP(sub, _acquire)
77ATOMIC_LONG_ADD_SUB_OP(sub, _release)
78
79#undef ATOMIC_LONG_ADD_SUB_OP
80
81#define atomic_long_cmpxchg_relaxed(l, old, new) \
82 (ATOMIC_LONG_PFX(_cmpxchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(l), \
83 (old), (new)))
84#define atomic_long_cmpxchg_acquire(l, old, new) \
85 (ATOMIC_LONG_PFX(_cmpxchg_acquire)((ATOMIC_LONG_PFX(_t) *)(l), \
86 (old), (new)))
87#define atomic_long_cmpxchg_release(l, old, new) \
88 (ATOMIC_LONG_PFX(_cmpxchg_release)((ATOMIC_LONG_PFX(_t) *)(l), \
89 (old), (new)))
90#define atomic_long_cmpxchg(l, old, new) \
91 (ATOMIC_LONG_PFX(_cmpxchg)((ATOMIC_LONG_PFX(_t) *)(l), (old), (new)))
92
93#define atomic_long_xchg_relaxed(v, new) \
94 (ATOMIC_LONG_PFX(_xchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
95#define atomic_long_xchg_acquire(v, new) \
96 (ATOMIC_LONG_PFX(_xchg_acquire)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
97#define atomic_long_xchg_release(v, new) \
98 (ATOMIC_LONG_PFX(_xchg_release)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
99#define atomic_long_xchg(v, new) \
100 (ATOMIC_LONG_PFX(_xchg)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800101
Denys Vlasenkoa644fdf2016-03-17 14:22:41 -0700102static __always_inline void atomic_long_inc(atomic_long_t *l)
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800103{
Will Deacon586b6102015-08-06 17:54:38 +0100104 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800105
Will Deacon586b6102015-08-06 17:54:38 +0100106 ATOMIC_LONG_PFX(_inc)(v);
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800107}
108
Denys Vlasenkoa644fdf2016-03-17 14:22:41 -0700109static __always_inline void atomic_long_dec(atomic_long_t *l)
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800110{
Will Deacon586b6102015-08-06 17:54:38 +0100111 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800112
Will Deacon586b6102015-08-06 17:54:38 +0100113 ATOMIC_LONG_PFX(_dec)(v);
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800114}
115
Peter Zijlstra28aa2bd2016-04-18 00:54:38 +0200116#define ATOMIC_LONG_FETCH_OP(op, mo) \
117static inline long \
118atomic_long_fetch_##op##mo(long i, atomic_long_t *l) \
119{ \
120 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
121 \
122 return (long)ATOMIC_LONG_PFX(_fetch_##op##mo)(i, v); \
123}
124
125ATOMIC_LONG_FETCH_OP(add, )
126ATOMIC_LONG_FETCH_OP(add, _relaxed)
127ATOMIC_LONG_FETCH_OP(add, _acquire)
128ATOMIC_LONG_FETCH_OP(add, _release)
129ATOMIC_LONG_FETCH_OP(sub, )
130ATOMIC_LONG_FETCH_OP(sub, _relaxed)
131ATOMIC_LONG_FETCH_OP(sub, _acquire)
132ATOMIC_LONG_FETCH_OP(sub, _release)
133ATOMIC_LONG_FETCH_OP(and, )
134ATOMIC_LONG_FETCH_OP(and, _relaxed)
135ATOMIC_LONG_FETCH_OP(and, _acquire)
136ATOMIC_LONG_FETCH_OP(and, _release)
137ATOMIC_LONG_FETCH_OP(andnot, )
138ATOMIC_LONG_FETCH_OP(andnot, _relaxed)
139ATOMIC_LONG_FETCH_OP(andnot, _acquire)
140ATOMIC_LONG_FETCH_OP(andnot, _release)
141ATOMIC_LONG_FETCH_OP(or, )
142ATOMIC_LONG_FETCH_OP(or, _relaxed)
143ATOMIC_LONG_FETCH_OP(or, _acquire)
144ATOMIC_LONG_FETCH_OP(or, _release)
145ATOMIC_LONG_FETCH_OP(xor, )
146ATOMIC_LONG_FETCH_OP(xor, _relaxed)
147ATOMIC_LONG_FETCH_OP(xor, _acquire)
148ATOMIC_LONG_FETCH_OP(xor, _release)
149
Davidlohr Buesof0662862016-06-28 14:56:51 -0700150#undef ATOMIC_LONG_FETCH_OP
151
152#define ATOMIC_LONG_FETCH_INC_DEC_OP(op, mo) \
153static inline long \
154atomic_long_fetch_##op##mo(atomic_long_t *l) \
155{ \
156 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
157 \
158 return (long)ATOMIC_LONG_PFX(_fetch_##op##mo)(v); \
159}
160
161ATOMIC_LONG_FETCH_INC_DEC_OP(inc,)
162ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _relaxed)
163ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _acquire)
164ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _release)
165ATOMIC_LONG_FETCH_INC_DEC_OP(dec,)
166ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _relaxed)
167ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _acquire)
168ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _release)
169
170#undef ATOMIC_LONG_FETCH_INC_DEC_OP
171
Peter Zijlstra90fe6512015-09-18 15:04:59 +0200172#define ATOMIC_LONG_OP(op) \
Denys Vlasenkoa644fdf2016-03-17 14:22:41 -0700173static __always_inline void \
Peter Zijlstra90fe6512015-09-18 15:04:59 +0200174atomic_long_##op(long i, atomic_long_t *l) \
175{ \
176 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
177 \
178 ATOMIC_LONG_PFX(_##op)(i, v); \
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800179}
180
Peter Zijlstra90fe6512015-09-18 15:04:59 +0200181ATOMIC_LONG_OP(add)
182ATOMIC_LONG_OP(sub)
183ATOMIC_LONG_OP(and)
Peter Zijlstra28aa2bd2016-04-18 00:54:38 +0200184ATOMIC_LONG_OP(andnot)
Peter Zijlstra90fe6512015-09-18 15:04:59 +0200185ATOMIC_LONG_OP(or)
186ATOMIC_LONG_OP(xor)
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800187
Peter Zijlstra90fe6512015-09-18 15:04:59 +0200188#undef ATOMIC_LONG_OP
Christoph Lameterd3cb4872006-01-06 00:11:20 -0800189
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700190static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
191{
Will Deacon586b6102015-08-06 17:54:38 +0100192 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700193
Will Deacon586b6102015-08-06 17:54:38 +0100194 return ATOMIC_LONG_PFX(_sub_and_test)(i, v);
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700195}
196
197static inline int atomic_long_dec_and_test(atomic_long_t *l)
198{
Will Deacon586b6102015-08-06 17:54:38 +0100199 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700200
Will Deacon586b6102015-08-06 17:54:38 +0100201 return ATOMIC_LONG_PFX(_dec_and_test)(v);
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700202}
203
204static inline int atomic_long_inc_and_test(atomic_long_t *l)
205{
Will Deacon586b6102015-08-06 17:54:38 +0100206 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700207
Will Deacon586b6102015-08-06 17:54:38 +0100208 return ATOMIC_LONG_PFX(_inc_and_test)(v);
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700209}
210
211static inline int atomic_long_add_negative(long i, atomic_long_t *l)
212{
Will Deacon586b6102015-08-06 17:54:38 +0100213 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700214
Will Deacon586b6102015-08-06 17:54:38 +0100215 return ATOMIC_LONG_PFX(_add_negative)(i, v);
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700216}
217
Davidlohr Bueso63ab7bd2015-09-30 13:03:11 -0700218#define ATOMIC_LONG_INC_DEC_OP(op, mo) \
219static inline long \
220atomic_long_##op##_return##mo(atomic_long_t *l) \
221{ \
222 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
223 \
224 return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(v); \
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700225}
Davidlohr Bueso63ab7bd2015-09-30 13:03:11 -0700226ATOMIC_LONG_INC_DEC_OP(inc,)
227ATOMIC_LONG_INC_DEC_OP(inc, _relaxed)
228ATOMIC_LONG_INC_DEC_OP(inc, _acquire)
229ATOMIC_LONG_INC_DEC_OP(inc, _release)
230ATOMIC_LONG_INC_DEC_OP(dec,)
231ATOMIC_LONG_INC_DEC_OP(dec, _relaxed)
232ATOMIC_LONG_INC_DEC_OP(dec, _acquire)
233ATOMIC_LONG_INC_DEC_OP(dec, _release)
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700234
Davidlohr Bueso63ab7bd2015-09-30 13:03:11 -0700235#undef ATOMIC_LONG_INC_DEC_OP
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700236
Mathieu Desnoyers2856f5e2007-05-08 00:34:38 -0700237static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
238{
Will Deacon586b6102015-08-06 17:54:38 +0100239 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
Mathieu Desnoyers2856f5e2007-05-08 00:34:38 -0700240
Will Deacon586b6102015-08-06 17:54:38 +0100241 return (long)ATOMIC_LONG_PFX(_add_unless)(v, a, u);
Mathieu Desnoyers2856f5e2007-05-08 00:34:38 -0700242}
Mathieu Desnoyersbb2382c2007-05-08 00:34:19 -0700243
Will Deacon586b6102015-08-06 17:54:38 +0100244#define atomic_long_inc_not_zero(l) \
245 ATOMIC_LONG_PFX(_inc_not_zero)((ATOMIC_LONG_PFX(_t) *)(l))
Adrian Bunk4b358e22006-12-06 20:40:28 -0800246
Will Deacon4df714b2017-10-12 13:20:48 +0100247#define atomic_long_cond_read_acquire(v, c) \
248 ATOMIC_LONG_PFX(_cond_read_acquire)((ATOMIC_LONG_PFX(_t) *)(v), (c))
249
Arnd Bergmann72099ed2009-05-13 22:56:29 +0000250#endif /* _ASM_GENERIC_ATOMIC_LONG_H */