1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ALPHA_CMPXCHG_H
3 #define _ALPHA_CMPXCHG_H
4 
5 /*
6  * Atomic exchange routines.
7  */
8 
9 #define ____xchg(type, args...)		__xchg ## type ## _local(args)
10 #define ____cmpxchg(type, args...)	__cmpxchg ## type ## _local(args)
11 #include <asm/xchg.h>
12 
13 #define xchg_local(ptr, x)						\
14 ({									\
15 	__typeof__(*(ptr)) _x_ = (x);					\
16 	(__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_,	\
17 				       sizeof(*(ptr)));			\
18 })
19 
20 #define arch_cmpxchg_local(ptr, o, n)					\
21 ({									\
22 	__typeof__(*(ptr)) _o_ = (o);					\
23 	__typeof__(*(ptr)) _n_ = (n);					\
24 	(__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,	\
25 					  (unsigned long)_n_,		\
26 					  sizeof(*(ptr)));		\
27 })
28 
29 #define arch_cmpxchg64_local(ptr, o, n)					\
30 ({									\
31 	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
32 	cmpxchg_local((ptr), (o), (n));					\
33 })
34 
35 #undef ____xchg
36 #undef ____cmpxchg
37 #define ____xchg(type, args...)		__xchg ##type(args)
38 #define ____cmpxchg(type, args...)	__cmpxchg ##type(args)
39 #include <asm/xchg.h>
40 
41 /*
42  * The leading and the trailing memory barriers guarantee that these
43  * operations are fully ordered.
44  */
45 #define arch_xchg(ptr, x)						\
46 ({									\
47 	__typeof__(*(ptr)) __ret;					\
48 	__typeof__(*(ptr)) _x_ = (x);					\
49 	smp_mb();							\
50 	__ret = (__typeof__(*(ptr)))					\
51 		__xchg((ptr), (unsigned long)_x_, sizeof(*(ptr)));	\
52 	smp_mb();							\
53 	__ret;								\
54 })
55 
56 #define arch_cmpxchg(ptr, o, n)						\
57 ({									\
58 	__typeof__(*(ptr)) __ret;					\
59 	__typeof__(*(ptr)) _o_ = (o);					\
60 	__typeof__(*(ptr)) _n_ = (n);					\
61 	smp_mb();							\
62 	__ret = (__typeof__(*(ptr))) __cmpxchg((ptr),			\
63 		(unsigned long)_o_, (unsigned long)_n_, sizeof(*(ptr)));\
64 	smp_mb();							\
65 	__ret;								\
66 })
67 
68 #define arch_cmpxchg64(ptr, o, n)					\
69 ({									\
70 	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
71 	arch_cmpxchg((ptr), (o), (n));					\
72 })
73 
74 #undef ____cmpxchg
75 
76 #endif /* _ALPHA_CMPXCHG_H */
77