diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2011-03-23 05:16:06 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2011-03-23 05:16:00 -0400 |
commit | 54eaae3028e6b09de0bd2232a8176fc0d0a2397a (patch) | |
tree | 5a557243c1684ad5047614a5b2c19a43dd98b561 | |
parent | a2c9dbe8dbb8591ae6fd142e562813cd95d06609 (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>
-rw-r--r-- | arch/s390/include/asm/cmpxchg.h | 38 |
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 */ | ||
174 | static 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 | ||
169 | static inline unsigned long __cmpxchg_local(void *ptr, | 196 | static 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 */ |