From: Geert Uytterhoeven <geert@linux-m68k.org>

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 */

_