From: Geert Uytterhoeven M68k: Add missing implementation of cmpxchg() (from Andreas Schwab, Roman Zippel and me) --- 25-akpm/include/asm-m68k/system.h | 36 ++++++++++++++++++++++++++++++++++++ 1 files changed, 36 insertions(+) diff -puN include/asm-m68k/system.h~m68k-411 include/asm-m68k/system.h --- 25/include/asm-m68k/system.h~m68k-411 Fri Feb 20 15:12:20 2004 +++ 25-akpm/include/asm-m68k/system.h Fri Feb 20 15:12:20 2004 @@ -158,6 +158,42 @@ static inline unsigned long __xchg(unsig } #endif +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + */ +#ifdef CONFIG_RMW_INSNS +#define __HAVE_ARCH_CMPXCHG 1 + +static inline unsigned long __cmpxchg(volatile void *p, unsigned long old, + unsigned long new, int size) +{ + switch (size) { + case 1: + __asm__ __volatile__ ("casb %0,%2,%1" + : "=d" (old), "=m" (*(char *)p) + : "d" (new), "0" (old), "m" (*(char *)p)); + break; + case 2: + __asm__ __volatile__ ("casw %0,%2,%1" + : "=d" (old), "=m" (*(short *)p) + : "d" (new), "0" (old), "m" (*(short *)p)); + break; + case 4: + __asm__ __volatile__ ("casl %0,%2,%1" + : "=d" (old), "=m" (*(int *)p) + : "d" (new), "0" (old), "m" (*(int *)p)); + break; + } + return old; +} + +#define cmpxchg(ptr,o,n)\ + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ + (unsigned long)(n),sizeof(*(ptr)))) +#endif + #endif /* __KERNEL__ */ #endif /* _M68K_SYSTEM_H */ _