diff options
author | Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | 2008-02-07 03:16:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 11:42:32 -0500 |
commit | fe4130131ef9e55763fd634a02b1db9290dbbe5a (patch) | |
tree | 523a97bd9f3b9302edfb80c5175ec9a528c1b807 | |
parent | 85fdbe1b4b33b797321bfadf706b355e7cca6165 (diff) |
Add cmpxchg_local to s390
Use the standard __cmpxchg for every type that can be updated atomically.
Use the new generic cmpxchg_local (disables interrupt) for other types.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/asm-s390/system.h | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index 44bda786eef7..15aba30601a3 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h | |||
@@ -201,9 +201,9 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size) | |||
201 | 201 | ||
202 | #define __HAVE_ARCH_CMPXCHG 1 | 202 | #define __HAVE_ARCH_CMPXCHG 1 |
203 | 203 | ||
204 | #define cmpxchg(ptr,o,n)\ | 204 | #define cmpxchg(ptr, o, n) \ |
205 | ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ | 205 | ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ |
206 | (unsigned long)(n),sizeof(*(ptr)))) | 206 | (unsigned long)(n), sizeof(*(ptr)))) |
207 | 207 | ||
208 | extern void __cmpxchg_called_with_bad_pointer(void); | 208 | extern void __cmpxchg_called_with_bad_pointer(void); |
209 | 209 | ||
@@ -355,6 +355,44 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |||
355 | 355 | ||
356 | #include <linux/irqflags.h> | 356 | #include <linux/irqflags.h> |
357 | 357 | ||
358 | #include <asm-generic/cmpxchg-local.h> | ||
359 | |||
360 | static inline unsigned long __cmpxchg_local(volatile void *ptr, | ||
361 | unsigned long old, | ||
362 | unsigned long new, int size) | ||
363 | { | ||
364 | switch (size) { | ||
365 | case 1: | ||
366 | case 2: | ||
367 | case 4: | ||
368 | #ifdef __s390x__ | ||
369 | case 8: | ||
370 | #endif | ||
371 | return __cmpxchg(ptr, old, new, size); | ||
372 | default: | ||
373 | return __cmpxchg_local_generic(ptr, old, new, size); | ||
374 | } | ||
375 | |||
376 | return old; | ||
377 | } | ||
378 | |||
379 | /* | ||
380 | * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make | ||
381 | * them available. | ||
382 | */ | ||
383 | #define cmpxchg_local(ptr, o, n) \ | ||
384 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ | ||
385 | (unsigned long)(n), sizeof(*(ptr)))) | ||
386 | #ifdef __s390x__ | ||
387 | #define cmpxchg64_local(ptr, o, n) \ | ||
388 | ({ \ | ||
389 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | ||
390 | cmpxchg_local((ptr), (o), (n)); \ | ||
391 | }) | ||
392 | #else | ||
393 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | ||
394 | #endif | ||
395 | |||
358 | /* | 396 | /* |
359 | * Use to set psw mask except for the first byte which | 397 | * Use to set psw mask except for the first byte which |
360 | * won't be changed by this function. | 398 | * won't be changed by this function. |