xref: /openbmc/linux/arch/ia64/include/asm/atomic.h (revision d12157ef)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
27f30491cSTony Luck #ifndef _ASM_IA64_ATOMIC_H
37f30491cSTony Luck #define _ASM_IA64_ATOMIC_H
47f30491cSTony Luck 
57f30491cSTony Luck /*
67f30491cSTony Luck  * Atomic operations that C can't guarantee us.  Useful for
77f30491cSTony Luck  * resource counting etc..
87f30491cSTony Luck  *
97f30491cSTony Luck  * NOTE: don't mess with the types below!  The "unsigned long" and
107f30491cSTony Luck  * "int" types were carefully placed so as to ensure proper operation
117f30491cSTony Luck  * of the macros.
127f30491cSTony Luck  *
137f30491cSTony Luck  * Copyright (C) 1998, 1999, 2002-2003 Hewlett-Packard Co
147f30491cSTony Luck  *	David Mosberger-Tang <davidm@hpl.hp.com>
157f30491cSTony Luck  */
167f30491cSTony Luck #include <linux/types.h>
177f30491cSTony Luck 
187f30491cSTony Luck #include <asm/intrinsics.h>
190cd64efbSPeter Zijlstra #include <asm/barrier.h>
207f30491cSTony Luck 
217f30491cSTony Luck 
22a1193655STony Luck #define ATOMIC64_INIT(i)	{ (i) }
237f30491cSTony Luck 
24*f84f1b9cSMark Rutland #define arch_atomic_read(v)	READ_ONCE((v)->counter)
25*f84f1b9cSMark Rutland #define arch_atomic64_read(v)	READ_ONCE((v)->counter)
267f30491cSTony Luck 
27*f84f1b9cSMark Rutland #define arch_atomic_set(v,i)	WRITE_ONCE(((v)->counter), (i))
28*f84f1b9cSMark Rutland #define arch_atomic64_set(v,i)	WRITE_ONCE(((v)->counter), (i))
297f30491cSTony Luck 
3008be2dabSPeter Zijlstra #define ATOMIC_OP(op, c_op)						\
3108be2dabSPeter Zijlstra static __inline__ int							\
3208be2dabSPeter Zijlstra ia64_atomic_##op (int i, atomic_t *v)					\
3308be2dabSPeter Zijlstra {									\
3408be2dabSPeter Zijlstra 	__s32 old, new;							\
3508be2dabSPeter Zijlstra 	CMPXCHG_BUGCHECK_DECL						\
3608be2dabSPeter Zijlstra 									\
3708be2dabSPeter Zijlstra 	do {								\
3808be2dabSPeter Zijlstra 		CMPXCHG_BUGCHECK(v);					\
39*f84f1b9cSMark Rutland 		old = arch_atomic_read(v);				\
4008be2dabSPeter Zijlstra 		new = old c_op i;					\
4108be2dabSPeter Zijlstra 	} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); \
4208be2dabSPeter Zijlstra 	return new;							\
437f30491cSTony Luck }
447f30491cSTony Luck 
45cc102507SPeter Zijlstra #define ATOMIC_FETCH_OP(op, c_op)					\
46cc102507SPeter Zijlstra static __inline__ int							\
47cc102507SPeter Zijlstra ia64_atomic_fetch_##op (int i, atomic_t *v)				\
48cc102507SPeter Zijlstra {									\
49cc102507SPeter Zijlstra 	__s32 old, new;							\
50cc102507SPeter Zijlstra 	CMPXCHG_BUGCHECK_DECL						\
51cc102507SPeter Zijlstra 									\
52cc102507SPeter Zijlstra 	do {								\
53cc102507SPeter Zijlstra 		CMPXCHG_BUGCHECK(v);					\
54*f84f1b9cSMark Rutland 		old = arch_atomic_read(v);				\
55cc102507SPeter Zijlstra 		new = old c_op i;					\
56cc102507SPeter Zijlstra 	} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); \
57cc102507SPeter Zijlstra 	return old;							\
58cc102507SPeter Zijlstra }
59cc102507SPeter Zijlstra 
60cc102507SPeter Zijlstra #define ATOMIC_OPS(op, c_op)						\
61cc102507SPeter Zijlstra 	ATOMIC_OP(op, c_op)						\
62cc102507SPeter Zijlstra 	ATOMIC_FETCH_OP(op, c_op)
63cc102507SPeter Zijlstra 
64cc102507SPeter Zijlstra ATOMIC_OPS(add, +)
65cc102507SPeter Zijlstra ATOMIC_OPS(sub, -)
667f30491cSTony Luck 
674b664e73SMatthew Wilcox #ifdef __OPTIMIZE__
682879b65fSMatthew Wilcox #define __ia64_atomic_const(i)						\
692879b65fSMatthew Wilcox 	static const int __ia64_atomic_p = __builtin_constant_p(i) ?	\
704b664e73SMatthew Wilcox 		((i) == 1 || (i) == 4 || (i) == 8 || (i) == 16 ||	\
712879b65fSMatthew Wilcox 		 (i) == -1 || (i) == -4 || (i) == -8 || (i) == -16) : 0;\
722879b65fSMatthew Wilcox 	__ia64_atomic_p
732879b65fSMatthew Wilcox #else
742879b65fSMatthew Wilcox #define __ia64_atomic_const(i)	0
752879b65fSMatthew Wilcox #endif
764b664e73SMatthew Wilcox 
77*f84f1b9cSMark Rutland #define arch_atomic_add_return(i,v)					\
7808be2dabSPeter Zijlstra ({									\
792879b65fSMatthew Wilcox 	int __ia64_aar_i = (i);						\
802879b65fSMatthew Wilcox 	__ia64_atomic_const(i)						\
812879b65fSMatthew Wilcox 		? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter)	\
822879b65fSMatthew Wilcox 		: ia64_atomic_add(__ia64_aar_i, v);			\
8308be2dabSPeter Zijlstra })
8408be2dabSPeter Zijlstra 
85*f84f1b9cSMark Rutland #define arch_atomic_sub_return(i,v)					\
8608be2dabSPeter Zijlstra ({									\
872879b65fSMatthew Wilcox 	int __ia64_asr_i = (i);						\
882879b65fSMatthew Wilcox 	__ia64_atomic_const(i)						\
892879b65fSMatthew Wilcox 		? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter)	\
902879b65fSMatthew Wilcox 		: ia64_atomic_sub(__ia64_asr_i, v);			\
9108be2dabSPeter Zijlstra })
9208be2dabSPeter Zijlstra 
93*f84f1b9cSMark Rutland #define arch_atomic_fetch_add(i,v)					\
94cc102507SPeter Zijlstra ({									\
95cc102507SPeter Zijlstra 	int __ia64_aar_i = (i);						\
962879b65fSMatthew Wilcox 	__ia64_atomic_const(i)						\
97cc102507SPeter Zijlstra 		? ia64_fetchadd(__ia64_aar_i, &(v)->counter, acq)	\
98cc102507SPeter Zijlstra 		: ia64_atomic_fetch_add(__ia64_aar_i, v);		\
99cc102507SPeter Zijlstra })
10070ed4739SPeter Zijlstra 
101*f84f1b9cSMark Rutland #define arch_atomic_fetch_sub(i,v)					\
102cc102507SPeter Zijlstra ({									\
103cc102507SPeter Zijlstra 	int __ia64_asr_i = (i);						\
1042879b65fSMatthew Wilcox 	__ia64_atomic_const(i)						\
105cc102507SPeter Zijlstra 		? ia64_fetchadd(-__ia64_asr_i, &(v)->counter, acq)	\
106cc102507SPeter Zijlstra 		: ia64_atomic_fetch_sub(__ia64_asr_i, v);		\
107cc102507SPeter Zijlstra })
10870ed4739SPeter Zijlstra 
109cc102507SPeter Zijlstra ATOMIC_FETCH_OP(and, &)
110cc102507SPeter Zijlstra ATOMIC_FETCH_OP(or, |)
111cc102507SPeter Zijlstra ATOMIC_FETCH_OP(xor, ^)
112cc102507SPeter Zijlstra 
113*f84f1b9cSMark Rutland #define arch_atomic_and(i,v)	(void)ia64_atomic_fetch_and(i,v)
114*f84f1b9cSMark Rutland #define arch_atomic_or(i,v)	(void)ia64_atomic_fetch_or(i,v)
115*f84f1b9cSMark Rutland #define arch_atomic_xor(i,v)	(void)ia64_atomic_fetch_xor(i,v)
116cc102507SPeter Zijlstra 
117*f84f1b9cSMark Rutland #define arch_atomic_fetch_and(i,v)	ia64_atomic_fetch_and(i,v)
118*f84f1b9cSMark Rutland #define arch_atomic_fetch_or(i,v)	ia64_atomic_fetch_or(i,v)
119*f84f1b9cSMark Rutland #define arch_atomic_fetch_xor(i,v)	ia64_atomic_fetch_xor(i,v)
120cc102507SPeter Zijlstra 
121cc102507SPeter Zijlstra #undef ATOMIC_OPS
122cc102507SPeter Zijlstra #undef ATOMIC_FETCH_OP
12370ed4739SPeter Zijlstra #undef ATOMIC_OP
12470ed4739SPeter Zijlstra 
12508be2dabSPeter Zijlstra #define ATOMIC64_OP(op, c_op)						\
126d84e28d2SMark Rutland static __inline__ s64							\
127d84e28d2SMark Rutland ia64_atomic64_##op (s64 i, atomic64_t *v)				\
12808be2dabSPeter Zijlstra {									\
129d84e28d2SMark Rutland 	s64 old, new;							\
13008be2dabSPeter Zijlstra 	CMPXCHG_BUGCHECK_DECL						\
13108be2dabSPeter Zijlstra 									\
13208be2dabSPeter Zijlstra 	do {								\
13308be2dabSPeter Zijlstra 		CMPXCHG_BUGCHECK(v);					\
134*f84f1b9cSMark Rutland 		old = arch_atomic64_read(v);				\
13508be2dabSPeter Zijlstra 		new = old c_op i;					\
13608be2dabSPeter Zijlstra 	} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old); \
13708be2dabSPeter Zijlstra 	return new;							\
1387f30491cSTony Luck }
1397f30491cSTony Luck 
140cc102507SPeter Zijlstra #define ATOMIC64_FETCH_OP(op, c_op)					\
141d84e28d2SMark Rutland static __inline__ s64							\
142d84e28d2SMark Rutland ia64_atomic64_fetch_##op (s64 i, atomic64_t *v)				\
143cc102507SPeter Zijlstra {									\
144d84e28d2SMark Rutland 	s64 old, new;							\
145cc102507SPeter Zijlstra 	CMPXCHG_BUGCHECK_DECL						\
146cc102507SPeter Zijlstra 									\
147cc102507SPeter Zijlstra 	do {								\
148cc102507SPeter Zijlstra 		CMPXCHG_BUGCHECK(v);					\
149*f84f1b9cSMark Rutland 		old = arch_atomic64_read(v);				\
150cc102507SPeter Zijlstra 		new = old c_op i;					\
151cc102507SPeter Zijlstra 	} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old); \
152cc102507SPeter Zijlstra 	return old;							\
153cc102507SPeter Zijlstra }
154cc102507SPeter Zijlstra 
155cc102507SPeter Zijlstra #define ATOMIC64_OPS(op, c_op)						\
156cc102507SPeter Zijlstra 	ATOMIC64_OP(op, c_op)						\
157cc102507SPeter Zijlstra 	ATOMIC64_FETCH_OP(op, c_op)
158cc102507SPeter Zijlstra 
159cc102507SPeter Zijlstra ATOMIC64_OPS(add, +)
160cc102507SPeter Zijlstra ATOMIC64_OPS(sub, -)
1617f30491cSTony Luck 
162*f84f1b9cSMark Rutland #define arch_atomic64_add_return(i,v)					\
16308be2dabSPeter Zijlstra ({									\
164d84e28d2SMark Rutland 	s64 __ia64_aar_i = (i);						\
1652879b65fSMatthew Wilcox 	__ia64_atomic_const(i)						\
16608be2dabSPeter Zijlstra 		? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter)	\
16708be2dabSPeter Zijlstra 		: ia64_atomic64_add(__ia64_aar_i, v);			\
16808be2dabSPeter Zijlstra })
1697f30491cSTony Luck 
170*f84f1b9cSMark Rutland #define arch_atomic64_sub_return(i,v)					\
17108be2dabSPeter Zijlstra ({									\
172d84e28d2SMark Rutland 	s64 __ia64_asr_i = (i);						\
1732879b65fSMatthew Wilcox 	__ia64_atomic_const(i)						\
17408be2dabSPeter Zijlstra 		? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter)	\
17508be2dabSPeter Zijlstra 		: ia64_atomic64_sub(__ia64_asr_i, v);			\
17608be2dabSPeter Zijlstra })
1777f30491cSTony Luck 
178*f84f1b9cSMark Rutland #define arch_atomic64_fetch_add(i,v)					\
179cc102507SPeter Zijlstra ({									\
180d84e28d2SMark Rutland 	s64 __ia64_aar_i = (i);						\
1812879b65fSMatthew Wilcox 	__ia64_atomic_const(i)						\
182cc102507SPeter Zijlstra 		? ia64_fetchadd(__ia64_aar_i, &(v)->counter, acq)	\
183cc102507SPeter Zijlstra 		: ia64_atomic64_fetch_add(__ia64_aar_i, v);		\
184cc102507SPeter Zijlstra })
18570ed4739SPeter Zijlstra 
186*f84f1b9cSMark Rutland #define arch_atomic64_fetch_sub(i,v)					\
187cc102507SPeter Zijlstra ({									\
188d84e28d2SMark Rutland 	s64 __ia64_asr_i = (i);						\
1892879b65fSMatthew Wilcox 	__ia64_atomic_const(i)						\
190cc102507SPeter Zijlstra 		? ia64_fetchadd(-__ia64_asr_i, &(v)->counter, acq)	\
191cc102507SPeter Zijlstra 		: ia64_atomic64_fetch_sub(__ia64_asr_i, v);		\
192cc102507SPeter Zijlstra })
19370ed4739SPeter Zijlstra 
194cc102507SPeter Zijlstra ATOMIC64_FETCH_OP(and, &)
195cc102507SPeter Zijlstra ATOMIC64_FETCH_OP(or, |)
196cc102507SPeter Zijlstra ATOMIC64_FETCH_OP(xor, ^)
197cc102507SPeter Zijlstra 
198*f84f1b9cSMark Rutland #define arch_atomic64_and(i,v)	(void)ia64_atomic64_fetch_and(i,v)
199*f84f1b9cSMark Rutland #define arch_atomic64_or(i,v)	(void)ia64_atomic64_fetch_or(i,v)
200*f84f1b9cSMark Rutland #define arch_atomic64_xor(i,v)	(void)ia64_atomic64_fetch_xor(i,v)
201cc102507SPeter Zijlstra 
202*f84f1b9cSMark Rutland #define arch_atomic64_fetch_and(i,v)	ia64_atomic64_fetch_and(i,v)
203*f84f1b9cSMark Rutland #define arch_atomic64_fetch_or(i,v)	ia64_atomic64_fetch_or(i,v)
204*f84f1b9cSMark Rutland #define arch_atomic64_fetch_xor(i,v)	ia64_atomic64_fetch_xor(i,v)
205cc102507SPeter Zijlstra 
206cc102507SPeter Zijlstra #undef ATOMIC64_OPS
207cc102507SPeter Zijlstra #undef ATOMIC64_FETCH_OP
20870ed4739SPeter Zijlstra #undef ATOMIC64_OP
20970ed4739SPeter Zijlstra 
210*f84f1b9cSMark Rutland #define arch_atomic_add(i,v)		(void)arch_atomic_add_return((i), (v))
211*f84f1b9cSMark Rutland #define arch_atomic_sub(i,v)		(void)arch_atomic_sub_return((i), (v))
2127f30491cSTony Luck 
213*f84f1b9cSMark Rutland #define arch_atomic64_add(i,v)		(void)arch_atomic64_add_return((i), (v))
214*f84f1b9cSMark Rutland #define arch_atomic64_sub(i,v)		(void)arch_atomic64_sub_return((i), (v))
2157f30491cSTony Luck 
2167f30491cSTony Luck #endif /* _ASM_IA64_ATOMIC_H */
217