aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2011-03-23 05:16:06 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-03-23 05:16:00 -0400
commit54eaae3028e6b09de0bd2232a8176fc0d0a2397a (patch)
tree5a557243c1684ad5047614a5b2c19a43dd98b561 /arch/s390
parenta2c9dbe8dbb8591ae6fd142e562813cd95d06609 (diff)
[S390] cmpxchg: implement cmpxchg64()
We have a cmpxchg64_local() implementation but strange enough the SMP capable variant cmpxchg64() is missing. So implement it. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/cmpxchg.h38
1 files changed, 29 insertions, 9 deletions
diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h
index 4052df9030cb..7488e52efa97 100644
--- a/arch/s390/include/asm/cmpxchg.h
+++ b/arch/s390/include/asm/cmpxchg.h
@@ -164,6 +164,33 @@ static inline unsigned long __cmpxchg(void *ptr, unsigned long old,
164 ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ 164 ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \
165 (unsigned long)(n), sizeof(*(ptr)))) 165 (unsigned long)(n), sizeof(*(ptr))))
166 166
167#ifdef CONFIG_64BIT
168#define cmpxchg64(ptr, o, n) \
169({ \
170 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
171 cmpxchg((ptr), (o), (n)); \
172})
173#else /* CONFIG_64BIT */
174static inline unsigned long long __cmpxchg64(void *ptr,
175 unsigned long long old,
176 unsigned long long new)
177{
178 register_pair rp_old = {.pair = old};
179 register_pair rp_new = {.pair = new};
180
181 asm volatile(
182 " cds %0,%2,%1"
183 : "+&d" (rp_old), "=Q" (ptr)
184 : "d" (rp_new), "Q" (ptr)
185 : "cc");
186 return rp_old.pair;
187}
188#define cmpxchg64(ptr, o, n) \
189 ((__typeof__(*(ptr)))__cmpxchg64((ptr), \
190 (unsigned long long)(o), \
191 (unsigned long long)(n)))
192#endif /* CONFIG_64BIT */
193
167#include <asm-generic/cmpxchg-local.h> 194#include <asm-generic/cmpxchg-local.h>
168 195
169static inline unsigned long __cmpxchg_local(void *ptr, 196static inline unsigned long __cmpxchg_local(void *ptr,
@@ -192,14 +219,7 @@ static inline unsigned long __cmpxchg_local(void *ptr,
192#define cmpxchg_local(ptr, o, n) \ 219#define cmpxchg_local(ptr, o, n) \
193 ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ 220 ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
194 (unsigned long)(n), sizeof(*(ptr)))) 221 (unsigned long)(n), sizeof(*(ptr))))
195#ifdef CONFIG_64BIT 222
196#define cmpxchg64_local(ptr, o, n) \ 223#define cmpxchg64_local(ptr, o, n) cmpxchg64((ptr), (o), (n))
197({ \
198 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
199 cmpxchg_local((ptr), (o), (n)); \
200})
201#else
202#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
203#endif
204 224
205#endif /* __ASM_CMPXCHG_H */ 225#endif /* __ASM_CMPXCHG_H */