]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - include/linux/bitops.h
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / include / linux / bitops.h
index 7d41ae62ccf7ead43fe4a468d6b58624410b7836..e724310298610bb7c1230ecff1c8d158df28c6d4 100755 (executable)
@@ -1,6 +1,7 @@
 #ifndef _LINUX_BITOPS_H
 #define _LINUX_BITOPS_H
 
+#include <asm/types.h>
 
 /*
  * ffs: find first bit set. This is defined the same way as
@@ -37,6 +38,43 @@ static inline int generic_ffs(int x)
        return r;
 }
 
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+static inline int generic_fls(int x)
+{
+       int r = 32;
+
+       if (!x)
+               return 0;
+       if (!(x & 0xffff0000u)) {
+               x <<= 16;
+               r -= 16;
+       }
+       if (!(x & 0xff000000u)) {
+               x <<= 8;
+               r -= 8;
+       }
+       if (!(x & 0xf0000000u)) {
+               x <<= 4;
+               r -= 4;
+       }
+       if (!(x & 0xc0000000u)) {
+               x <<= 2;
+               r -= 2;
+       }
+       if (!(x & 0x80000000u)) {
+               x <<= 1;
+               r -= 1;
+       }
+       return r;
+}
+
+
 /*
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
@@ -66,7 +104,52 @@ static inline unsigned int generic_hweight8(unsigned int w)
        return (res & 0x0F) + ((res >> 4) & 0x0F);
 }
 
+#define BIT_MASK(nr)           (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr)           ((nr) / BITS_PER_LONG)
+
 #include <asm/bitops.h>
 
+/* linux/include/asm-generic/bitops/non-atomic.h */
+
+#ifndef PLATFORM__SET_BIT
+# define __set_bit generic_set_bit
+#endif
+
+#ifndef PLATFORM__CLEAR_BIT
+# define __clear_bit generic_clear_bit
+#endif
+
+#ifndef PLATFORM_FFS
+# define ffs generic_ffs
+#endif
+
+#ifndef PLATFORM_FLS
+# define fls generic_fls
+#endif
+
+/**
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike set_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+static inline void generic_set_bit(int nr, volatile unsigned long *addr)
+{
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+       *p  |= mask;
+}
+
+static inline void generic_clear_bit(int nr, volatile unsigned long *addr)
+{
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+       *p &= ~mask;
+}
 
 #endif