aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/include/asm/bitops-llsc.h
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-21 15:52:04 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-21 15:52:04 +1100
commita02efb906d12c9d4eb2ab7c59049ba9545e5412d (patch)
treebf1f6467978ec63a22f42299ecac2ee7f7e73336 /arch/sh/include/asm/bitops-llsc.h
parent84dfcb4b318463cd4883b6a19937824f49aee564 (diff)
parent2515ddc6db8eb49a79f0fe5e67ff09ac7c81eab4 (diff)
Merge commit 'origin' into master
Manual merge of: arch/powerpc/Kconfig arch/powerpc/include/asm/page.h
Diffstat (limited to 'arch/sh/include/asm/bitops-llsc.h')
-rw-r--r--arch/sh/include/asm/bitops-llsc.h144
1 files changed, 144 insertions, 0 deletions
diff --git a/arch/sh/include/asm/bitops-llsc.h b/arch/sh/include/asm/bitops-llsc.h
new file mode 100644
index 00000000000..43b8e1a8239
--- /dev/null
+++ b/arch/sh/include/asm/bitops-llsc.h
@@ -0,0 +1,144 @@
+#ifndef __ASM_SH_BITOPS_LLSC_H
+#define __ASM_SH_BITOPS_LLSC_H
+
+static inline void set_bit(int nr, volatile void * addr)
+{
+ int mask;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! set_bit \n\t"
+ "or %3, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ : "=&z" (tmp), "=r" (a)
+ : "1" (a), "r" (mask)
+ : "t", "memory"
+ );
+}
+
+static inline void clear_bit(int nr, volatile void * addr)
+{
+ int mask;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! clear_bit \n\t"
+ "and %3, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ : "=&z" (tmp), "=r" (a)
+ : "1" (a), "r" (~mask)
+ : "t", "memory"
+ );
+}
+
+static inline void change_bit(int nr, volatile void * addr)
+{
+ int mask;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! change_bit \n\t"
+ "xor %3, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ : "=&z" (tmp), "=r" (a)
+ : "1" (a), "r" (mask)
+ : "t", "memory"
+ );
+}
+
+static inline int test_and_set_bit(int nr, volatile void * addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! test_and_set_bit \n\t"
+ "mov %0, %2 \n\t"
+ "or %4, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ "and %4, %2 \n\t"
+ : "=&z" (tmp), "=r" (a), "=&r" (retval)
+ : "1" (a), "r" (mask)
+ : "t", "memory"
+ );
+
+ return retval != 0;
+}
+
+static inline int test_and_clear_bit(int nr, volatile void * addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! test_and_clear_bit \n\t"
+ "mov %0, %2 \n\t"
+ "and %5, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ "and %4, %2 \n\t"
+ "synco \n\t"
+ : "=&z" (tmp), "=r" (a), "=&r" (retval)
+ : "1" (a), "r" (mask), "r" (~mask)
+ : "t", "memory"
+ );
+
+ return retval != 0;
+}
+
+static inline int test_and_change_bit(int nr, volatile void * addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! test_and_change_bit \n\t"
+ "mov %0, %2 \n\t"
+ "xor %4, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ "and %4, %2 \n\t"
+ "synco \n\t"
+ : "=&z" (tmp), "=r" (a), "=&r" (retval)
+ : "1" (a), "r" (mask)
+ : "t", "memory"
+ );
+
+ return retval != 0;
+}
+
+#endif /* __ASM_SH_BITOPS_LLSC_H */