sh: Fix up the SH-4A mutex fastpath semantics.

This fixes up the __mutex_fastpath_xxx() routines to match the semantics
noted in the comment. Previously these were looping rather than doing a
single-pass, which is counter-intuitive, as the slow path takes care of
the looping for us in the event of contention.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/include/asm/mutex-llsc.h b/arch/sh/include/asm/mutex-llsc.h
index 7c75af5..a91990c 100644
--- a/arch/sh/include/asm/mutex-llsc.h
+++ b/arch/sh/include/asm/mutex-llsc.h
@@ -21,16 +21,18 @@
 static inline void
 __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
 {
-	int __res;
+	int __ex_flag, __res;
 
 	__asm__ __volatile__ (
-		"movli.l	@%1, %0	\n"
-		"dt		%0	\n"
-		"movco.l	%0, @%1	\n"
-		: "=&z" (__res)
+		"movli.l	@%2, %0	\n"
+		"add		#-1, %0	\n"
+		"movco.l	%0, @%2	\n"
+		"movt		%1	\n"
+		: "=&z" (__res), "=&r" (__ex_flag)
 		: "r" (&(count)->counter)
 		: "t");
 
+	__res |= !__ex_flag;
 	if (unlikely(__res != 0))
 		fail_fn(count);
 }
@@ -38,16 +40,18 @@
 static inline int
 __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
 {
-	int __res;
+	int __ex_flag, __res;
 
 	__asm__ __volatile__ (
-		"movli.l	@%1, %0	\n"
-		"dt		%0	\n"
-		"movco.l	%0, @%1	\n"
-		: "=&z" (__res)
+		"movli.l	@%2, %0	\n"
+		"add		#-1, %0	\n"
+		"movco.l	%0, @%2	\n"
+		"movt		%1	\n"
+		: "=&z" (__res), "=&r" (__ex_flag)
 		: "r" (&(count)->counter)
 		: "t");
 
+	__res |= !__ex_flag;
 	if (unlikely(__res != 0))
 		__res = fail_fn(count);
 
@@ -57,18 +61,19 @@
 static inline void
 __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
 {
-	int __res;
+	int __ex_flag, __res;
 
 	__asm__ __volatile__ (
-		"1: movli.l	@%1, %0	\n\t"
+		"movli.l	@%2, %0	\n\t"
 		"add		#1, %0	\n\t"
-		"movco.l	%0, @%1 \n\t"
-		"bf		1b\n\t"
-		: "=&z" (__res)
+		"movco.l	%0, @%2 \n\t"
+		"movt		%1	\n\t"
+		: "=&z" (__res), "=&r" (__ex_flag)
 		: "r" (&(count)->counter)
 		: "t");
 
-	if (unlikely(__res <= 0))
+	__res |= !__ex_flag;
+	if (unlikely(__res != 0))
 		fail_fn(count);
 }