]> err.no Git - linux-2.6/blobdiff - include/asm-powerpc/bitops.h
[POWERPC] Fix swapper_pg_dir size when CONFIG_PTE_64BIT=y on FSL_BOOKE
[linux-2.6] / include / asm-powerpc / bitops.h
index 0288144ea024aac5882d92bc47d24af01ee6b706..733b4af7f4f1e7e49269b17856bbf7e47924d7b6 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
-#include <asm/atomic.h>
 #include <asm/asm-compat.h>
 #include <asm/synch.h>
 
@@ -87,6 +90,24 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
        : "cc" );
 }
 
+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");
+}
+
 static __inline__ void change_bit(int nr, volatile unsigned long *addr)
 {
        unsigned long old;
@@ -126,6 +147,27 @@ static __inline__ int test_and_set_bit(unsigned long nr,
        return (old & mask) != 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;
+}
+
 static __inline__ int test_and_clear_bit(unsigned long nr,
                                         volatile unsigned long *addr)
 {
@@ -186,6 +228,12 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
 
 #include <asm-generic/bitops/non-atomic.h>
 
+static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
+{
+       __asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory");
+       __clear_bit(nr, addr);
+}
+
 /*
  * Return the zero-based bit position (LE, not IBM bit numbering) of
  * the most significant 1-bit in a double word.
@@ -209,7 +257,7 @@ int __ilog2_u32(u32 n)
 
 #ifdef __powerpc64__
 static inline __attribute__((const))
-int __ilog2_u64(u32 n)
+int __ilog2_u64(u64 n)
 {
        int bit;
        asm ("cntlzd %0,%1" : "=r" (bit) : "r" (n));