Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
[pandora-kernel.git] / arch / powerpc / include / asm / bitops.h
index 897eade..56f2f2e 100644 (file)
 #define BITOP_WORD(nr)         ((nr) / BITS_PER_LONG)
 #define BITOP_LE_SWIZZLE       ((BITS_PER_LONG-1) & ~0x7)
 
+/* Macro for generating the ***_bits() functions */
+#define DEFINE_BITOP(fn, op, prefix, postfix)  \
+static __inline__ void fn(unsigned long mask,  \
+               volatile unsigned long *_p)     \
+{                                              \
+       unsigned long old;                      \
+       unsigned long *p = (unsigned long *)_p; \
+       __asm__ __volatile__ (                  \
+       prefix                                  \
+"1:"   PPC_LLARX "%0,0,%3\n"                   \
+       stringify_in_c(op) "%0,%0,%2\n"         \
+       PPC405_ERR77(0,%3)                      \
+       PPC_STLCX "%0,0,%3\n"                   \
+       "bne- 1b\n"                             \
+       postfix                                 \
+       : "=&r" (old), "+m" (*p)                \
+       : "r" (mask), "r" (p)                   \
+       : "cc", "memory");                      \
+}
+
+DEFINE_BITOP(set_bits, or, "", "")
+DEFINE_BITOP(clear_bits, andc, "", "")
+DEFINE_BITOP(clear_bits_unlock, andc, LWSYNC_ON_SMP, "")
+DEFINE_BITOP(change_bits, xor, "", "")
+
 static __inline__ void set_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long old;
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-       __asm__ __volatile__(
-"1:"   PPC_LLARX "%0,0,%3      # set_bit\n"
-       "or     %0,%0,%2\n"
-       PPC405_ERR77(0,%3)
-       PPC_STLCX "%0,0,%3\n"
-       "bne-   1b"
-       : "=&r" (old), "+m" (*p)
-       : "r" (mask), "r" (p)
-       : "cc" );
+       set_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
 }
 
 static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long old;
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-       __asm__ __volatile__(
-"1:"   PPC_LLARX "%0,0,%3      # clear_bit\n"
-       "andc   %0,%0,%2\n"
-       PPC405_ERR77(0,%3)
-       PPC_STLCX "%0,0,%3\n"
-       "bne-   1b"
-       : "=&r" (old), "+m" (*p)
-       : "r" (mask), "r" (p)
-       : "cc" );
+       clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
 }
 
 static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
 {
-       unsigned long old;
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-       __asm__ __volatile__(
-       LWSYNC_ON_SMP
-"1:"   PPC_LLARX "%0,0,%3      # clear_bit_unlock\n"
-       "andc   %0,%0,%2\n"
-       PPC405_ERR77(0,%3)
-       PPC_STLCX "%0,0,%3\n"
-       "bne-   1b"
-       : "=&r" (old), "+m" (*p)
-       : "r" (mask), "r" (p)
-       : "cc", "memory");
+       clear_bits_unlock(BITOP_MASK(nr), addr + BITOP_WORD(nr));
 }
 
 static __inline__ void change_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long old;
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-       __asm__ __volatile__(
-"1:"   PPC_LLARX "%0,0,%3      # change_bit\n"
-       "xor    %0,%0,%2\n"
-       PPC405_ERR77(0,%3)
-       PPC_STLCX "%0,0,%3\n"
-       "bne-   1b"
-       : "=&r" (old), "+m" (*p)
-       : "r" (mask), "r" (p)
-       : "cc" );
+       change_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
+}
+
+/* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output
+ * operands. */
+#define DEFINE_TESTOP(fn, op, prefix, postfix) \
+static __inline__ unsigned long fn(            \
+               unsigned long mask,             \
+               volatile unsigned long *_p)     \
+{                                              \
+       unsigned long old, t;                   \
+       unsigned long *p = (unsigned long *)_p; \
+       __asm__ __volatile__ (                  \
+       prefix                                  \
+"1:"   PPC_LLARX "%0,0,%3\n"                   \
+       stringify_in_c(op) "%1,%0,%2\n"         \
+       PPC405_ERR77(0,%3)                      \
+       PPC_STLCX "%1,0,%3\n"                   \
+       "bne- 1b\n"                             \
+       postfix                                 \
+       : "=&r" (old), "=&r" (t)                \
+       : "r" (mask), "r" (p)                   \
+       : "cc", "memory");                      \
+       return (old & mask);                    \
 }
 
+DEFINE_TESTOP(test_and_set_bits, or, LWSYNC_ON_SMP, ISYNC_ON_SMP)
+DEFINE_TESTOP(test_and_set_bits_lock, or, "", ISYNC_ON_SMP)
+DEFINE_TESTOP(test_and_clear_bits, andc, LWSYNC_ON_SMP, ISYNC_ON_SMP)
+DEFINE_TESTOP(test_and_change_bits, xor, LWSYNC_ON_SMP, ISYNC_ON_SMP)
+
 static __inline__ int test_and_set_bit(unsigned long nr,
                                       volatile unsigned long *addr)
 {
-       unsigned long old, t;
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-       __asm__ __volatile__(
-       LWSYNC_ON_SMP
-"1:"   PPC_LLARX "%0,0,%3              # test_and_set_bit\n"
-       "or     %1,%0,%2 \n"
-       PPC405_ERR77(0,%3)
-       PPC_STLCX "%1,0,%3 \n"
-       "bne-   1b"
-       ISYNC_ON_SMP
-       : "=&r" (old), "=&r" (t)
-       : "r" (mask), "r" (p)
-       : "cc", "memory");
-
-       return (old & mask) != 0;
+       return test_and_set_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
 }
 
 static __inline__ int test_and_set_bit_lock(unsigned long nr,
                                       volatile unsigned long *addr)
 {
-       unsigned long old, t;
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-       __asm__ __volatile__(
-"1:"   PPC_LLARX "%0,0,%3              # test_and_set_bit_lock\n"
-       "or     %1,%0,%2 \n"
-       PPC405_ERR77(0,%3)
-       PPC_STLCX "%1,0,%3 \n"
-       "bne-   1b"
-       ISYNC_ON_SMP
-       : "=&r" (old), "=&r" (t)
-       : "r" (mask), "r" (p)
-       : "cc", "memory");
-
-       return (old & mask) != 0;
+       return test_and_set_bits_lock(BITOP_MASK(nr),
+                               addr + BITOP_WORD(nr)) != 0;
 }
 
 static __inline__ int test_and_clear_bit(unsigned long nr,
                                         volatile unsigned long *addr)
 {
-       unsigned long old, t;
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-       __asm__ __volatile__(
-       LWSYNC_ON_SMP
-"1:"   PPC_LLARX "%0,0,%3              # test_and_clear_bit\n"
-       "andc   %1,%0,%2 \n"
-       PPC405_ERR77(0,%3)
-       PPC_STLCX "%1,0,%3 \n"
-       "bne-   1b"
-       ISYNC_ON_SMP
-       : "=&r" (old), "=&r" (t)
-       : "r" (mask), "r" (p)
-       : "cc", "memory");
-
-       return (old & mask) != 0;
+       return test_and_clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
 }
 
 static __inline__ int test_and_change_bit(unsigned long nr,
                                          volatile unsigned long *addr)
 {
-       unsigned long old, t;
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-       __asm__ __volatile__(
-       LWSYNC_ON_SMP
-"1:"   PPC_LLARX "%0,0,%3              # test_and_change_bit\n"
-       "xor    %1,%0,%2 \n"
-       PPC405_ERR77(0,%3)
-       PPC_STLCX "%1,0,%3 \n"
-       "bne-   1b"
-       ISYNC_ON_SMP
-       : "=&r" (old), "=&r" (t)
-       : "r" (mask), "r" (p)
-       : "cc", "memory");
-
-       return (old & mask) != 0;
-}
-
-static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
-{
-        unsigned long old;
-
-       __asm__ __volatile__(
-"1:"   PPC_LLARX "%0,0,%3         # set_bits\n"
-       "or     %0,%0,%2\n"
-       PPC_STLCX "%0,0,%3\n"
-       "bne-   1b"
-       : "=&r" (old), "+m" (*addr)
-       : "r" (mask), "r" (addr)
-       : "cc");
+       return test_and_change_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
 }
 
 #include <asm-generic/bitops/non-atomic.h>