| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 1 | /* | 
 | 2 |  * PowerPC atomic bit operations. | 
 | 3 |  * | 
 | 4 |  * Merged version by David Gibson <david@gibson.dropbear.id.au>. | 
 | 5 |  * Based on ppc64 versions by: Dave Engebretsen, Todd Inglett, Don | 
 | 6 |  * Reed, Pat McCarthy, Peter Bergner, Anton Blanchard.  They | 
 | 7 |  * originally took it from the ppc32 code. | 
 | 8 |  * | 
 | 9 |  * Within a word, bits are numbered LSB first.  Lot's of places make | 
 | 10 |  * this assumption by directly testing bits with (val & (1<<nr)). | 
 | 11 |  * This can cause confusion for large (> 1 word) bitmaps on a | 
 | 12 |  * big-endian system because, unlike little endian, the number of each | 
 | 13 |  * bit depends on the word size. | 
 | 14 |  * | 
 | 15 |  * The bitop functions are defined to work on unsigned longs, so for a | 
 | 16 |  * ppc64 system the bits end up numbered: | 
 | 17 |  *   |63..............0|127............64|191...........128|255...........196| | 
 | 18 |  * and on ppc32: | 
 | 19 |  *   |31.....0|63....31|95....64|127...96|159..128|191..160|223..192|255..224| | 
 | 20 |  * | 
 | 21 |  * There are a few little-endian macros used mostly for filesystem | 
 | 22 |  * bitmaps, these work on similar bit arrays layouts, but | 
 | 23 |  * byte-oriented: | 
 | 24 |  *   |7...0|15...8|23...16|31...24|39...32|47...40|55...48|63...56| | 
 | 25 |  * | 
 | 26 |  * The main difference is that bit 3-5 (64b) or 3-4 (32b) in the bit | 
 | 27 |  * number field needs to be reversed compared to the big-endian bit | 
 | 28 |  * fields. This can be achieved by XOR with 0x38 (64b) or 0x18 (32b). | 
 | 29 |  * | 
 | 30 |  * This program is free software; you can redistribute it and/or | 
 | 31 |  * modify it under the terms of the GNU General Public License | 
 | 32 |  * as published by the Free Software Foundation; either version | 
 | 33 |  * 2 of the License, or (at your option) any later version. | 
 | 34 |  */ | 
 | 35 |  | 
 | 36 | #ifndef _ASM_POWERPC_BITOPS_H | 
 | 37 | #define _ASM_POWERPC_BITOPS_H | 
 | 38 |  | 
 | 39 | #ifdef __KERNEL__ | 
 | 40 |  | 
| Jiri Slaby | 0624517 | 2007-10-18 23:40:26 -0700 | [diff] [blame] | 41 | #ifndef _LINUX_BITOPS_H | 
 | 42 | #error only <linux/bitops.h> can be included directly | 
 | 43 | #endif | 
 | 44 |  | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 45 | #include <linux/compiler.h> | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 46 | #include <asm/asm-compat.h> | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 47 | #include <asm/synch.h> | 
 | 48 |  | 
 | 49 | /* | 
 | 50 |  * clear_bit doesn't imply a memory barrier | 
 | 51 |  */ | 
 | 52 | #define smp_mb__before_clear_bit()	smp_mb() | 
 | 53 | #define smp_mb__after_clear_bit()	smp_mb() | 
 | 54 |  | 
 | 55 | #define BITOP_MASK(nr)		(1UL << ((nr) % BITS_PER_LONG)) | 
 | 56 | #define BITOP_WORD(nr)		((nr) / BITS_PER_LONG) | 
 | 57 | #define BITOP_LE_SWIZZLE	((BITS_PER_LONG-1) & ~0x7) | 
 | 58 |  | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 59 | static __inline__ void set_bit(int nr, volatile unsigned long *addr) | 
 | 60 | { | 
 | 61 | 	unsigned long old; | 
 | 62 | 	unsigned long mask = BITOP_MASK(nr); | 
 | 63 | 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 
 | 64 |  | 
 | 65 | 	__asm__ __volatile__( | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 66 | "1:"	PPC_LLARX "%0,0,%3	# set_bit\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 67 | 	"or	%0,%0,%2\n" | 
 | 68 | 	PPC405_ERR77(0,%3) | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 69 | 	PPC_STLCX "%0,0,%3\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 70 | 	"bne-	1b" | 
| Linus Torvalds | e2a3d40 | 2006-07-08 15:00:28 -0700 | [diff] [blame] | 71 | 	: "=&r" (old), "+m" (*p) | 
 | 72 | 	: "r" (mask), "r" (p) | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 73 | 	: "cc" ); | 
 | 74 | } | 
 | 75 |  | 
 | 76 | static __inline__ void clear_bit(int nr, volatile unsigned long *addr) | 
 | 77 | { | 
 | 78 | 	unsigned long old; | 
 | 79 | 	unsigned long mask = BITOP_MASK(nr); | 
 | 80 | 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 
 | 81 |  | 
 | 82 | 	__asm__ __volatile__( | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 83 | "1:"	PPC_LLARX "%0,0,%3	# clear_bit\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 84 | 	"andc	%0,%0,%2\n" | 
 | 85 | 	PPC405_ERR77(0,%3) | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 86 | 	PPC_STLCX "%0,0,%3\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 87 | 	"bne-	1b" | 
| Linus Torvalds | e2a3d40 | 2006-07-08 15:00:28 -0700 | [diff] [blame] | 88 | 	: "=&r" (old), "+m" (*p) | 
 | 89 | 	: "r" (mask), "r" (p) | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 90 | 	: "cc" ); | 
 | 91 | } | 
 | 92 |  | 
| Nick Piggin | 66ffb04 | 2007-10-18 03:06:53 -0700 | [diff] [blame] | 93 | static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr) | 
 | 94 | { | 
 | 95 | 	unsigned long old; | 
 | 96 | 	unsigned long mask = BITOP_MASK(nr); | 
 | 97 | 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 
 | 98 |  | 
 | 99 | 	__asm__ __volatile__( | 
 | 100 | 	LWSYNC_ON_SMP | 
 | 101 | "1:"	PPC_LLARX "%0,0,%3	# clear_bit_unlock\n" | 
 | 102 | 	"andc	%0,%0,%2\n" | 
 | 103 | 	PPC405_ERR77(0,%3) | 
 | 104 | 	PPC_STLCX "%0,0,%3\n" | 
 | 105 | 	"bne-	1b" | 
 | 106 | 	: "=&r" (old), "+m" (*p) | 
 | 107 | 	: "r" (mask), "r" (p) | 
 | 108 | 	: "cc", "memory"); | 
 | 109 | } | 
 | 110 |  | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 111 | static __inline__ void change_bit(int nr, volatile unsigned long *addr) | 
 | 112 | { | 
 | 113 | 	unsigned long old; | 
 | 114 | 	unsigned long mask = BITOP_MASK(nr); | 
 | 115 | 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 
 | 116 |  | 
 | 117 | 	__asm__ __volatile__( | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 118 | "1:"	PPC_LLARX "%0,0,%3	# change_bit\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 119 | 	"xor	%0,%0,%2\n" | 
 | 120 | 	PPC405_ERR77(0,%3) | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 121 | 	PPC_STLCX "%0,0,%3\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 122 | 	"bne-	1b" | 
| Linus Torvalds | e2a3d40 | 2006-07-08 15:00:28 -0700 | [diff] [blame] | 123 | 	: "=&r" (old), "+m" (*p) | 
 | 124 | 	: "r" (mask), "r" (p) | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 125 | 	: "cc" ); | 
 | 126 | } | 
 | 127 |  | 
 | 128 | static __inline__ int test_and_set_bit(unsigned long nr, | 
 | 129 | 				       volatile unsigned long *addr) | 
 | 130 | { | 
 | 131 | 	unsigned long old, t; | 
 | 132 | 	unsigned long mask = BITOP_MASK(nr); | 
 | 133 | 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 
 | 134 |  | 
 | 135 | 	__asm__ __volatile__( | 
| Anton Blanchard | 144b9c1 | 2006-01-13 15:37:17 +1100 | [diff] [blame] | 136 | 	LWSYNC_ON_SMP | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 137 | "1:"	PPC_LLARX "%0,0,%3		# test_and_set_bit\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 138 | 	"or	%1,%0,%2 \n" | 
 | 139 | 	PPC405_ERR77(0,%3) | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 140 | 	PPC_STLCX "%1,0,%3 \n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 141 | 	"bne-	1b" | 
 | 142 | 	ISYNC_ON_SMP | 
 | 143 | 	: "=&r" (old), "=&r" (t) | 
 | 144 | 	: "r" (mask), "r" (p) | 
 | 145 | 	: "cc", "memory"); | 
 | 146 |  | 
 | 147 | 	return (old & mask) != 0; | 
 | 148 | } | 
 | 149 |  | 
| Nick Piggin | 66ffb04 | 2007-10-18 03:06:53 -0700 | [diff] [blame] | 150 | static __inline__ int test_and_set_bit_lock(unsigned long nr, | 
 | 151 | 				       volatile unsigned long *addr) | 
 | 152 | { | 
 | 153 | 	unsigned long old, t; | 
 | 154 | 	unsigned long mask = BITOP_MASK(nr); | 
 | 155 | 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 
 | 156 |  | 
 | 157 | 	__asm__ __volatile__( | 
 | 158 | "1:"	PPC_LLARX "%0,0,%3		# test_and_set_bit_lock\n" | 
 | 159 | 	"or	%1,%0,%2 \n" | 
 | 160 | 	PPC405_ERR77(0,%3) | 
 | 161 | 	PPC_STLCX "%1,0,%3 \n" | 
 | 162 | 	"bne-	1b" | 
 | 163 | 	ISYNC_ON_SMP | 
 | 164 | 	: "=&r" (old), "=&r" (t) | 
 | 165 | 	: "r" (mask), "r" (p) | 
 | 166 | 	: "cc", "memory"); | 
 | 167 |  | 
 | 168 | 	return (old & mask) != 0; | 
 | 169 | } | 
 | 170 |  | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 171 | static __inline__ int test_and_clear_bit(unsigned long nr, | 
 | 172 | 					 volatile unsigned long *addr) | 
 | 173 | { | 
 | 174 | 	unsigned long old, t; | 
 | 175 | 	unsigned long mask = BITOP_MASK(nr); | 
 | 176 | 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 
 | 177 |  | 
 | 178 | 	__asm__ __volatile__( | 
| Anton Blanchard | 144b9c1 | 2006-01-13 15:37:17 +1100 | [diff] [blame] | 179 | 	LWSYNC_ON_SMP | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 180 | "1:"	PPC_LLARX "%0,0,%3		# test_and_clear_bit\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 181 | 	"andc	%1,%0,%2 \n" | 
 | 182 | 	PPC405_ERR77(0,%3) | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 183 | 	PPC_STLCX "%1,0,%3 \n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 184 | 	"bne-	1b" | 
 | 185 | 	ISYNC_ON_SMP | 
 | 186 | 	: "=&r" (old), "=&r" (t) | 
 | 187 | 	: "r" (mask), "r" (p) | 
 | 188 | 	: "cc", "memory"); | 
 | 189 |  | 
 | 190 | 	return (old & mask) != 0; | 
 | 191 | } | 
 | 192 |  | 
 | 193 | static __inline__ int test_and_change_bit(unsigned long nr, | 
 | 194 | 					  volatile unsigned long *addr) | 
 | 195 | { | 
 | 196 | 	unsigned long old, t; | 
 | 197 | 	unsigned long mask = BITOP_MASK(nr); | 
 | 198 | 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | 
 | 199 |  | 
 | 200 | 	__asm__ __volatile__( | 
| Anton Blanchard | 144b9c1 | 2006-01-13 15:37:17 +1100 | [diff] [blame] | 201 | 	LWSYNC_ON_SMP | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 202 | "1:"	PPC_LLARX "%0,0,%3		# test_and_change_bit\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 203 | 	"xor	%1,%0,%2 \n" | 
 | 204 | 	PPC405_ERR77(0,%3) | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 205 | 	PPC_STLCX "%1,0,%3 \n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 206 | 	"bne-	1b" | 
 | 207 | 	ISYNC_ON_SMP | 
 | 208 | 	: "=&r" (old), "=&r" (t) | 
 | 209 | 	: "r" (mask), "r" (p) | 
 | 210 | 	: "cc", "memory"); | 
 | 211 |  | 
 | 212 | 	return (old & mask) != 0; | 
 | 213 | } | 
 | 214 |  | 
 | 215 | static __inline__ void set_bits(unsigned long mask, unsigned long *addr) | 
 | 216 | { | 
 | 217 |         unsigned long old; | 
 | 218 |  | 
 | 219 | 	__asm__ __volatile__( | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 220 | "1:"	PPC_LLARX "%0,0,%3         # set_bits\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 221 | 	"or	%0,%0,%2\n" | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 222 | 	PPC_STLCX "%0,0,%3\n" | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 223 | 	"bne-	1b" | 
| Linus Torvalds | e2a3d40 | 2006-07-08 15:00:28 -0700 | [diff] [blame] | 224 | 	: "=&r" (old), "+m" (*addr) | 
 | 225 | 	: "r" (mask), "r" (addr) | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 226 | 	: "cc"); | 
 | 227 | } | 
 | 228 |  | 
| Akinobu Mita | e779b2f | 2006-03-26 01:39:33 -0800 | [diff] [blame] | 229 | #include <asm-generic/bitops/non-atomic.h> | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 230 |  | 
| Nick Piggin | 66ffb04 | 2007-10-18 03:06:53 -0700 | [diff] [blame] | 231 | static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr) | 
 | 232 | { | 
 | 233 | 	__asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory"); | 
 | 234 | 	__clear_bit(nr, addr); | 
 | 235 | } | 
 | 236 |  | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 237 | /* | 
 | 238 |  * Return the zero-based bit position (LE, not IBM bit numbering) of | 
 | 239 |  * the most significant 1-bit in a double word. | 
 | 240 |  */ | 
| David Howells | ef55d53 | 2006-12-08 02:37:53 -0800 | [diff] [blame] | 241 | static __inline__ __attribute__((const)) | 
 | 242 | int __ilog2(unsigned long x) | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 243 | { | 
 | 244 | 	int lz; | 
 | 245 |  | 
| David Gibson | 3ddfbcf | 2005-11-10 12:56:55 +1100 | [diff] [blame] | 246 | 	asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x)); | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 247 | 	return BITS_PER_LONG - 1 - lz; | 
 | 248 | } | 
 | 249 |  | 
| David Howells | ef55d53 | 2006-12-08 02:37:53 -0800 | [diff] [blame] | 250 | static inline __attribute__((const)) | 
 | 251 | int __ilog2_u32(u32 n) | 
 | 252 | { | 
 | 253 | 	int bit; | 
 | 254 | 	asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n)); | 
 | 255 | 	return 31 - bit; | 
 | 256 | } | 
 | 257 |  | 
 | 258 | #ifdef __powerpc64__ | 
 | 259 | static inline __attribute__((const)) | 
| David Howells | 0224169 | 2006-12-11 13:16:05 +0000 | [diff] [blame] | 260 | int __ilog2_u64(u64 n) | 
| David Howells | ef55d53 | 2006-12-08 02:37:53 -0800 | [diff] [blame] | 261 | { | 
 | 262 | 	int bit; | 
 | 263 | 	asm ("cntlzd %0,%1" : "=r" (bit) : "r" (n)); | 
 | 264 | 	return 63 - bit; | 
 | 265 | } | 
 | 266 | #endif | 
 | 267 |  | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 268 | /* | 
 | 269 |  * Determines the bit position of the least significant 0 bit in the | 
 | 270 |  * specified double word. The returned bit position will be | 
 | 271 |  * zero-based, starting from the right side (63/31 - 0). | 
 | 272 |  */ | 
 | 273 | static __inline__ unsigned long ffz(unsigned long x) | 
 | 274 | { | 
 | 275 | 	/* no zero exists anywhere in the 8 byte area. */ | 
 | 276 | 	if ((x = ~x) == 0) | 
 | 277 | 		return BITS_PER_LONG; | 
 | 278 |  | 
 | 279 | 	/* | 
 | 280 | 	 * Calculate the bit position of the least signficant '1' bit in x | 
 | 281 | 	 * (since x has been changed this will actually be the least signficant | 
 | 282 | 	 * '0' bit in * the original x).  Note: (x & -x) gives us a mask that | 
 | 283 | 	 * is the least significant * (RIGHT-most) 1-bit of the value in x. | 
 | 284 | 	 */ | 
 | 285 | 	return __ilog2(x & -x); | 
 | 286 | } | 
 | 287 |  | 
 | 288 | static __inline__ int __ffs(unsigned long x) | 
 | 289 | { | 
 | 290 | 	return __ilog2(x & -x); | 
 | 291 | } | 
 | 292 |  | 
 | 293 | /* | 
 | 294 |  * ffs: find first bit set. This is defined the same way as | 
 | 295 |  * the libc and compiler builtin ffs routines, therefore | 
 | 296 |  * differs in spirit from the above ffz (man ffs). | 
 | 297 |  */ | 
 | 298 | static __inline__ int ffs(int x) | 
 | 299 | { | 
 | 300 | 	unsigned long i = (unsigned long)x; | 
 | 301 | 	return __ilog2(i & -i) + 1; | 
 | 302 | } | 
 | 303 |  | 
 | 304 | /* | 
 | 305 |  * fls: find last (most-significant) bit set. | 
 | 306 |  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. | 
 | 307 |  */ | 
 | 308 | static __inline__ int fls(unsigned int x) | 
 | 309 | { | 
 | 310 | 	int lz; | 
 | 311 |  | 
 | 312 | 	asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x)); | 
 | 313 | 	return 32 - lz; | 
 | 314 | } | 
| Paul Mackerras | 9f264be | 2008-04-18 14:26:08 +1000 | [diff] [blame] | 315 |  | 
| Alexander van Heukelum | 56a6b1e | 2008-03-15 18:31:49 +0100 | [diff] [blame] | 316 | static __inline__ unsigned long __fls(unsigned long x) | 
 | 317 | { | 
 | 318 | 	return __ilog2(x); | 
 | 319 | } | 
 | 320 |  | 
| Paul Mackerras | 9f264be | 2008-04-18 14:26:08 +1000 | [diff] [blame] | 321 | /* | 
 | 322 |  * 64-bit can do this using one cntlzd (count leading zeroes doubleword) | 
 | 323 |  * instruction; for 32-bit we use the generic version, which does two | 
 | 324 |  * 32-bit fls calls. | 
 | 325 |  */ | 
 | 326 | #ifdef __powerpc64__ | 
 | 327 | static __inline__ int fls64(__u64 x) | 
 | 328 | { | 
 | 329 | 	int lz; | 
 | 330 |  | 
 | 331 | 	asm ("cntlzd %0,%1" : "=r" (lz) : "r" (x)); | 
 | 332 | 	return 64 - lz; | 
 | 333 | } | 
 | 334 | #else | 
| Akinobu Mita | e779b2f | 2006-03-26 01:39:33 -0800 | [diff] [blame] | 335 | #include <asm-generic/bitops/fls64.h> | 
| Paul Mackerras | 9f264be | 2008-04-18 14:26:08 +1000 | [diff] [blame] | 336 | #endif /* __powerpc64__ */ | 
 | 337 |  | 
| Akinobu Mita | e779b2f | 2006-03-26 01:39:33 -0800 | [diff] [blame] | 338 | #include <asm-generic/bitops/hweight.h> | 
| Alexander van Heukelum | 47b9d9b | 2008-04-16 15:55:08 +0200 | [diff] [blame] | 339 | #include <asm-generic/bitops/find.h> | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 340 |  | 
 | 341 | /* Little-endian versions */ | 
 | 342 |  | 
 | 343 | static __inline__ int test_le_bit(unsigned long nr, | 
 | 344 | 				  __const__ unsigned long *addr) | 
 | 345 | { | 
 | 346 | 	__const__ unsigned char	*tmp = (__const__ unsigned char *) addr; | 
 | 347 | 	return (tmp[nr >> 3] >> (nr & 7)) & 1; | 
 | 348 | } | 
 | 349 |  | 
 | 350 | #define __set_le_bit(nr, addr) \ | 
 | 351 | 	__set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr)) | 
 | 352 | #define __clear_le_bit(nr, addr) \ | 
 | 353 | 	__clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr)) | 
 | 354 |  | 
 | 355 | #define test_and_set_le_bit(nr, addr) \ | 
 | 356 | 	test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr)) | 
 | 357 | #define test_and_clear_le_bit(nr, addr) \ | 
 | 358 | 	test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr)) | 
 | 359 |  | 
 | 360 | #define __test_and_set_le_bit(nr, addr) \ | 
 | 361 | 	__test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr)) | 
 | 362 | #define __test_and_clear_le_bit(nr, addr) \ | 
 | 363 | 	__test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr)) | 
 | 364 |  | 
| Jon Mason | 0a9cb46 | 2006-05-19 15:35:32 -0500 | [diff] [blame] | 365 | #define find_first_zero_le_bit(addr, size) generic_find_next_zero_le_bit((addr), (size), 0) | 
 | 366 | unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 367 | 				    unsigned long size, unsigned long offset); | 
 | 368 |  | 
| Aneesh Kumar K.V | aa02ad6 | 2008-01-28 23:58:27 -0500 | [diff] [blame] | 369 | unsigned long generic_find_next_le_bit(const unsigned long *addr, | 
 | 370 | 				    unsigned long size, unsigned long offset); | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 371 | /* Bitmap functions for the ext2 filesystem */ | 
 | 372 |  | 
 | 373 | #define ext2_set_bit(nr,addr) \ | 
 | 374 | 	__test_and_set_le_bit((nr), (unsigned long*)addr) | 
 | 375 | #define ext2_clear_bit(nr, addr) \ | 
 | 376 | 	__test_and_clear_le_bit((nr), (unsigned long*)addr) | 
 | 377 |  | 
 | 378 | #define ext2_set_bit_atomic(lock, nr, addr) \ | 
 | 379 | 	test_and_set_le_bit((nr), (unsigned long*)addr) | 
 | 380 | #define ext2_clear_bit_atomic(lock, nr, addr) \ | 
 | 381 | 	test_and_clear_le_bit((nr), (unsigned long*)addr) | 
 | 382 |  | 
 | 383 | #define ext2_test_bit(nr, addr)      test_le_bit((nr),(unsigned long*)addr) | 
 | 384 |  | 
 | 385 | #define ext2_find_first_zero_bit(addr, size) \ | 
 | 386 | 	find_first_zero_le_bit((unsigned long*)addr, size) | 
 | 387 | #define ext2_find_next_zero_bit(addr, size, off) \ | 
| Jon Mason | 0a9cb46 | 2006-05-19 15:35:32 -0500 | [diff] [blame] | 388 | 	generic_find_next_zero_le_bit((unsigned long*)addr, size, off) | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 389 |  | 
| Aneesh Kumar K.V | aa02ad6 | 2008-01-28 23:58:27 -0500 | [diff] [blame] | 390 | #define ext2_find_next_bit(addr, size, off) \ | 
 | 391 | 	generic_find_next_le_bit((unsigned long *)addr, size, off) | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 392 | /* Bitmap functions for the minix filesystem.  */ | 
 | 393 |  | 
 | 394 | #define minix_test_and_set_bit(nr,addr) \ | 
 | 395 | 	__test_and_set_le_bit(nr, (unsigned long *)addr) | 
 | 396 | #define minix_set_bit(nr,addr) \ | 
 | 397 | 	__set_le_bit(nr, (unsigned long *)addr) | 
 | 398 | #define minix_test_and_clear_bit(nr,addr) \ | 
 | 399 | 	__test_and_clear_le_bit(nr, (unsigned long *)addr) | 
 | 400 | #define minix_test_bit(nr,addr) \ | 
 | 401 | 	test_le_bit(nr, (unsigned long *)addr) | 
 | 402 |  | 
 | 403 | #define minix_find_first_zero_bit(addr,size) \ | 
 | 404 | 	find_first_zero_le_bit((unsigned long *)addr, size) | 
 | 405 |  | 
| Akinobu Mita | e779b2f | 2006-03-26 01:39:33 -0800 | [diff] [blame] | 406 | #include <asm-generic/bitops/sched.h> | 
| David Gibson | a0e60b2 | 2005-11-01 17:28:10 +1100 | [diff] [blame] | 407 |  | 
 | 408 | #endif /* __KERNEL__ */ | 
 | 409 |  | 
 | 410 | #endif /* _ASM_POWERPC_BITOPS_H */ |