]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - include/asm-mips/bitops.h
bitops: introduce lock ops
[linux-2.6.git] / include / asm-mips / bitops.h
index d995413e11fd87af0844e82b6d10c90e3324b60b..0d3373f649203f14cf51d1e249de35ef2261f223 100644 (file)
 #include <asm/sgidefs.h>
 #include <asm/war.h>
 
-#if (_MIPS_SZLONG == 32)
+#if _MIPS_SZLONG == 32
 #define SZLONG_LOG 5
 #define SZLONG_MASK 31UL
 #define __LL           "ll     "
 #define __SC           "sc     "
 #define __INS          "ins    "
 #define __EXT          "ext    "
-#elif (_MIPS_SZLONG == 64)
+#elif _MIPS_SZLONG == 64
 #define SZLONG_LOG 6
 #define SZLONG_MASK 63UL
 #define __LL           "lld    "
@@ -38,8 +38,8 @@
 /*
  * clear_bit() doesn't provide any barrier for the compiler.
  */
-#define smp_mb__before_clear_bit()     smp_mb()
-#define smp_mb__after_clear_bit()      smp_mb()
+#define smp_mb__before_clear_bit()     smp_llsc_mb()
+#define smp_mb__after_clear_bit()      smp_llsc_mb()
 
 /*
  * set_bit - Atomically set a bit in memory
@@ -238,10 +238,11 @@ static inline int test_and_set_bit(unsigned long nr,
        volatile unsigned long *addr)
 {
        unsigned short bit = nr & SZLONG_MASK;
+       unsigned long res;
 
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-               unsigned long temp, res;
+               unsigned long temp;
 
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
@@ -254,11 +255,9 @@ static inline int test_and_set_bit(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << bit), "m" (*m)
                : "memory");
-
-               return res != 0;
        } else if (cpu_has_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-               unsigned long temp, res;
+               unsigned long temp;
 
                __asm__ __volatile__(
                "       .set    push                                    \n"
@@ -277,25 +276,22 @@ static inline int test_and_set_bit(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << bit), "m" (*m)
                : "memory");
-
-               return res != 0;
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
-               int retval;
                unsigned long flags;
 
                a += nr >> SZLONG_LOG;
                mask = 1UL << bit;
                raw_local_irq_save(flags);
-               retval = (mask & *a) != 0;
+               res = (mask & *a);
                *a |= mask;
                raw_local_irq_restore(flags);
-
-               return retval;
        }
 
-       smp_mb();
+       smp_llsc_mb();
+
+       return res != 0;
 }
 
 /*
@@ -310,10 +306,11 @@ static inline int test_and_clear_bit(unsigned long nr,
        volatile unsigned long *addr)
 {
        unsigned short bit = nr & SZLONG_MASK;
+       unsigned long res;
 
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-               unsigned long temp, res;
+               unsigned long temp;
 
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
@@ -327,12 +324,10 @@ static inline int test_and_clear_bit(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << bit), "m" (*m)
                : "memory");
-
-               return res != 0;
 #ifdef CONFIG_CPU_MIPSR2
        } else if (__builtin_constant_p(nr)) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-               unsigned long temp, res;
+               unsigned long temp;
 
                __asm__ __volatile__(
                "1:     " __LL  "%0, %1         # test_and_clear_bit    \n"
@@ -346,12 +341,10 @@ static inline int test_and_clear_bit(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "ri" (bit), "m" (*m)
                : "memory");
-
-               return res;
 #endif
        } else if (cpu_has_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-               unsigned long temp, res;
+               unsigned long temp;
 
                __asm__ __volatile__(
                "       .set    push                                    \n"
@@ -371,25 +364,22 @@ static inline int test_and_clear_bit(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << bit), "m" (*m)
                : "memory");
-
-               return res != 0;
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
-               int retval;
                unsigned long flags;
 
                a += nr >> SZLONG_LOG;
                mask = 1UL << bit;
                raw_local_irq_save(flags);
-               retval = (mask & *a) != 0;
+               res = (mask & *a);
                *a &= ~mask;
                raw_local_irq_restore(flags);
-
-               return retval;
        }
 
-       smp_mb();
+       smp_llsc_mb();
+
+       return res != 0;
 }
 
 /*
@@ -404,10 +394,11 @@ static inline int test_and_change_bit(unsigned long nr,
        volatile unsigned long *addr)
 {
        unsigned short bit = nr & SZLONG_MASK;
+       unsigned long res;
 
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-               unsigned long temp, res;
+               unsigned long temp;
 
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
@@ -420,11 +411,9 @@ static inline int test_and_change_bit(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << bit), "m" (*m)
                : "memory");
-
-               return res != 0;
        } else if (cpu_has_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-               unsigned long temp, res;
+               unsigned long temp;
 
                __asm__ __volatile__(
                "       .set    push                                    \n"
@@ -443,24 +432,22 @@ static inline int test_and_change_bit(unsigned long nr,
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << bit), "m" (*m)
                : "memory");
-
-               return res != 0;
        } else {
                volatile unsigned long *a = addr;
-               unsigned long mask, retval;
+               unsigned long mask;
                unsigned long flags;
 
                a += nr >> SZLONG_LOG;
                mask = 1UL << bit;
                raw_local_irq_save(flags);
-               retval = (mask & *a) != 0;
+               res = (mask & *a);
                *a ^= mask;
                raw_local_irq_restore(flags);
-
-               return retval;
        }
 
-       smp_mb();
+       smp_llsc_mb();
+
+       return res != 0;
 }
 
 #include <asm-generic/bitops/non-atomic.h>
@@ -474,7 +461,7 @@ static inline int __ilog2(unsigned long x)
        int lz;
 
        if (sizeof(x) == 4) {
-               __asm__ (
+               __asm__(
                "       .set    push                                    \n"
                "       .set    mips32                                  \n"
                "       clz     %0, %1                                  \n"
@@ -487,7 +474,7 @@ static inline int __ilog2(unsigned long x)
 
        BUG_ON(sizeof(x) != 8);
 
-       __asm__ (
+       __asm__(
        "       .set    push                                            \n"
        "       .set    mips64                                          \n"
        "       dclz    %0, %1                                          \n"
@@ -521,7 +508,7 @@ static inline unsigned long __ffs(unsigned long word)
  */
 static inline int fls(int word)
 {
-       __asm__ ("clz %0, %1" : "=r" (word) : "r" (word));
+       __asm__("clz %0, %1" : "=r" (word) : "r" (word));
 
        return 32 - word;
 }
@@ -529,7 +516,7 @@ static inline int fls(int word)
 #if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPS64)
 static inline int fls64(__u64 word)
 {
-       __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word));
+       __asm__("dclz %0, %1" : "=r" (word) : "r" (word));
 
        return 64 - word;
 }
@@ -569,6 +556,7 @@ static inline int ffs(int word)
 
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
 #include <asm-generic/bitops/minix.h>