1 /* 2 * Copyright 1995, Russell King. 3 * Various bits and pieces copyrights include: 4 * Linus Torvalds (test_bit). 5 * 6 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). 7 * 8 * Please note that the code in this file should never be included 9 * from user space. Many of these are not implemented in assembler 10 * since they would be too costly. Also, they require priviledged 11 * instructions (which are not available from user mode) to ensure 12 * that they are atomic. 13 */ 14 15 #ifndef __ASM_ARM_BITOPS_H 16 #define __ASM_ARM_BITOPS_H 17 18 #include <asm-generic/bitops/__ffs.h> 19 20 #ifdef __KERNEL__ 21 22 #include <asm/proc-armv/system.h> 23 24 #define smp_mb__before_clear_bit() do { } while (0) 25 #define smp_mb__after_clear_bit() do { } while (0) 26 27 /* 28 * Function prototypes to keep gcc -Wall happy. 29 */ 30 extern void set_bit(int nr, volatile void * addr); 31 32 extern void clear_bit(int nr, volatile void * addr); 33 34 extern void change_bit(int nr, volatile void * addr); 35 36 static inline void __change_bit(int nr, volatile void *addr) 37 { 38 unsigned long mask = BIT_MASK(nr); 39 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 40 41 *p ^= mask; 42 } 43 44 static inline int __test_and_set_bit(int nr, volatile void *addr) 45 { 46 unsigned long mask = BIT_MASK(nr); 47 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 48 unsigned long old = *p; 49 50 *p = old | mask; 51 return (old & mask) != 0; 52 } 53 54 static inline int test_and_set_bit(int nr, volatile void * addr) 55 { 56 unsigned long flags = 0; 57 int out; 58 59 local_irq_save(flags); 60 out = __test_and_set_bit(nr, addr); 61 local_irq_restore(flags); 62 63 return out; 64 } 65 66 static inline int __test_and_clear_bit(int nr, volatile void *addr) 67 { 68 unsigned long mask = BIT_MASK(nr); 69 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 70 unsigned long old = *p; 71 72 *p = old & ~mask; 73 return (old & mask) != 0; 74 } 75 76 static inline int test_and_clear_bit(int nr, volatile void * addr) 77 { 78 unsigned long flags = 0; 79 int out; 80 81 local_irq_save(flags); 82 out = __test_and_clear_bit(nr, addr); 83 local_irq_restore(flags); 84 85 return out; 86 } 87 88 extern int test_and_change_bit(int nr, volatile void * addr); 89 90 static inline int __test_and_change_bit(int nr, volatile void *addr) 91 { 92 unsigned long mask = BIT_MASK(nr); 93 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 94 unsigned long old = *p; 95 96 *p = old ^ mask; 97 return (old & mask) != 0; 98 } 99 100 /* 101 * This routine doesn't need to be atomic. 102 */ 103 static inline int test_bit(int nr, const void * addr) 104 { 105 return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7)); 106 } 107 108 static inline int __ilog2(unsigned int x) 109 { 110 return generic_fls(x) - 1; 111 } 112 113 #define ffz(x) __ffs(~(x)) 114 115 static inline int find_next_zero_bit(void *addr, int size, int offset) 116 { 117 unsigned long *p = ((unsigned long *)addr) + (offset / BITS_PER_LONG); 118 unsigned long result = offset & ~(BITS_PER_LONG - 1); 119 unsigned long tmp; 120 121 if (offset >= size) 122 return size; 123 size -= result; 124 offset &= (BITS_PER_LONG - 1); 125 if (offset) { 126 tmp = *(p++); 127 tmp |= ~0UL >> (BITS_PER_LONG - offset); 128 if (size < BITS_PER_LONG) 129 goto found_first; 130 if (~tmp) 131 goto found_middle; 132 size -= BITS_PER_LONG; 133 result += BITS_PER_LONG; 134 } 135 while (size & ~(BITS_PER_LONG - 1)) { 136 tmp = *(p++); 137 if (~tmp) 138 goto found_middle; 139 result += BITS_PER_LONG; 140 size -= BITS_PER_LONG; 141 } 142 if (!size) 143 return result; 144 tmp = *p; 145 146 found_first: 147 tmp |= ~0UL << size; 148 found_middle: 149 return result + ffz(tmp); 150 } 151 152 /* 153 * hweightN: returns the hamming weight (i.e. the number 154 * of bits set) of a N-bit word 155 */ 156 157 #define hweight32(x) generic_hweight32(x) 158 #define hweight16(x) generic_hweight16(x) 159 #define hweight8(x) generic_hweight8(x) 160 161 #define find_first_zero_bit(addr, size) \ 162 find_next_zero_bit((addr), (size), 0) 163 164 #define ext2_set_bit test_and_set_bit 165 #define ext2_clear_bit test_and_clear_bit 166 #define ext2_test_bit test_bit 167 #define ext2_find_first_zero_bit find_first_zero_bit 168 #define ext2_find_next_zero_bit find_next_zero_bit 169 170 /* Bitmap functions for the minix filesystem. */ 171 #define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr) 172 #define minix_set_bit(nr,addr) set_bit(nr,addr) 173 #define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr) 174 #define minix_test_bit(nr,addr) test_bit(nr,addr) 175 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) 176 177 #endif /* __KERNEL__ */ 178 179 #include <asm-generic/bitops/__fls.h> 180 #include <asm-generic/bitops/fls.h> 181 #include <asm-generic/bitops/fls64.h> 182 183 #endif /* _ARM_BITOPS_H */ 184