diff options
Diffstat (limited to 'arch/arm/include/asm/bitops.h')
| -rw-r--r-- | arch/arm/include/asm/bitops.h | 107 |
1 files changed, 53 insertions, 54 deletions
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index 6b7403fd8f5..56380995f4c 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -24,10 +24,8 @@ #endif #include <linux/compiler.h> -#include <asm/system.h> - -#define smp_mb__before_clear_bit() mb() -#define smp_mb__after_clear_bit() mb() +#include <linux/irqflags.h> +#include <asm/barrier.h> /* * These functions are the basis of our bit ops. @@ -203,8 +201,6 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset); #define find_first_bit(p,sz) _find_first_bit_le(p,sz) #define find_next_bit(p,sz,off) _find_next_bit_le(p,sz,off) -#define WORD_BITOFF_TO_LE(x) ((x)) - #else /* * These are the big endian, atomic definitions. @@ -214,8 +210,6 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset); #define find_first_bit(p,sz) _find_first_bit_be(p,sz) #define find_next_bit(p,sz,off) _find_next_bit_be(p,sz,off) -#define WORD_BITOFF_TO_LE(x) ((x) ^ 0x18) - #endif #if __LINUX_ARM_ARCH__ < 5 @@ -258,92 +252,97 @@ static inline int constant_fls(int x) } /* - * On ARMv5 and above those functions can be implemented around - * the clz instruction for much better code efficiency. + * On ARMv5 and above those functions can be implemented around the + * clz instruction for much better code efficiency. __clz returns + * the number of leading zeros, zero input will return 32, and + * 0x80000000 will return 0. */ - -static inline int fls(int x) +static inline unsigned int __clz(unsigned int x) { - int ret; - - if (__builtin_constant_p(x)) - return constant_fls(x); + unsigned int ret; asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); - ret = 32 - ret; + return ret; } -#define __fls(x) (fls(x) - 1) -#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) -#define __ffs(x) (ffs(x) - 1) -#define ffz(x) __ffs( ~(x) ) - -#endif - -#include <asm-generic/bitops/fls64.h> - -#include <asm-generic/bitops/sched.h> -#include <asm-generic/bitops/hweight.h> -#include <asm-generic/bitops/lock.h> - -static inline void __set_bit_le(int nr, void *addr) +/* + * fls() returns zero if the input is zero, otherwise returns the bit + * position of the last set bit, where the LSB is 1 and MSB is 32. + */ +static inline int fls(int x) { - __set_bit(WORD_BITOFF_TO_LE(nr), addr); -} + if (__builtin_constant_p(x)) + return constant_fls(x); -static inline void __clear_bit_le(int nr, void *addr) -{ - __clear_bit(WORD_BITOFF_TO_LE(nr), addr); + return 32 - __clz(x); } -static inline int __test_and_set_bit_le(int nr, void *addr) +/* + * __fls() returns the bit position of the last bit set, where the + * LSB is 0 and MSB is 31. Zero input is undefined. + */ +static inline unsigned long __fls(unsigned long x) { - return __test_and_set_bit(WORD_BITOFF_TO_LE(nr), addr); + return fls(x) - 1; } -static inline int test_and_set_bit_le(int nr, void *addr) +/* + * ffs() returns zero if the input was zero, otherwise returns the bit + * position of the first set bit, where the LSB is 1 and MSB is 32. + */ +static inline int ffs(int x) { - return test_and_set_bit(WORD_BITOFF_TO_LE(nr), addr); + return fls(x & -x); } -static inline int __test_and_clear_bit_le(int nr, void *addr) +/* + * __ffs() returns the bit position of the first bit set, where the + * LSB is 0 and MSB is 31. Zero input is undefined. + */ +static inline unsigned long __ffs(unsigned long x) { - return __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), addr); + return ffs(x) - 1; } -static inline int test_and_clear_bit_le(int nr, void *addr) -{ - return test_and_clear_bit(WORD_BITOFF_TO_LE(nr), addr); -} +#define ffz(x) __ffs( ~(x) ) -static inline int test_bit_le(int nr, const void *addr) -{ - return test_bit(WORD_BITOFF_TO_LE(nr), addr); -} +#endif + +#include <asm-generic/bitops/fls64.h> + +#include <asm-generic/bitops/sched.h> +#include <asm-generic/bitops/hweight.h> +#include <asm-generic/bitops/lock.h> + +#ifdef __ARMEB__ static inline int find_first_zero_bit_le(const void *p, unsigned size) { return _find_first_zero_bit_le(p, size); } +#define find_first_zero_bit_le find_first_zero_bit_le static inline int find_next_zero_bit_le(const void *p, int size, int offset) { return _find_next_zero_bit_le(p, size, offset); } +#define find_next_zero_bit_le find_next_zero_bit_le static inline int find_next_bit_le(const void *p, int size, int offset) { return _find_next_bit_le(p, size, offset); } +#define find_next_bit_le find_next_bit_le + +#endif + +#include <asm-generic/bitops/le.h> /* * Ext2 is defined to use little-endian byte ordering. */ -#define ext2_set_bit_atomic(lock, nr, p) \ - test_and_set_bit_le(nr, p) -#define ext2_clear_bit_atomic(lock, nr, p) \ - test_and_clear_bit_le(nr, p) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* __KERNEL__ */ |
