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 /include | |
| 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>
Diffstat (limited to 'include')
| -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. |
