1 #ifndef __ASM_SH_BITOPS_H 2 #define __ASM_SH_BITOPS_H 3 4 #include <asm-generic/bitops/fls.h> 5 #include <asm-generic/bitops/__fls.h> 6 #include <asm-generic/bitops/fls64.h> 7 #include <asm-generic/bitops/__ffs.h> 8 9 #ifdef __KERNEL__ 10 #include <asm/irqflags.h> 11 /* For __swab32 */ 12 #include <asm/byteorder.h> 13 14 static inline void set_bit(int nr, volatile void * addr) 15 { 16 int mask; 17 volatile unsigned int *a = addr; 18 unsigned long flags; 19 20 a += nr >> 5; 21 mask = 1 << (nr & 0x1f); 22 local_irq_save(flags); 23 *a |= mask; 24 local_irq_restore(flags); 25 } 26 27 /* 28 * clear_bit() doesn't provide any barrier for the compiler. 29 */ 30 #define smp_mb__before_clear_bit() barrier() 31 #define smp_mb__after_clear_bit() barrier() 32 static inline void clear_bit(int nr, volatile void * addr) 33 { 34 int mask; 35 volatile unsigned int *a = addr; 36 unsigned long flags; 37 38 a += nr >> 5; 39 mask = 1 << (nr & 0x1f); 40 local_irq_save(flags); 41 *a &= ~mask; 42 local_irq_restore(flags); 43 } 44 45 static inline void change_bit(int nr, volatile void * addr) 46 { 47 int mask; 48 volatile unsigned int *a = addr; 49 unsigned long flags; 50 51 a += nr >> 5; 52 mask = 1 << (nr & 0x1f); 53 local_irq_save(flags); 54 *a ^= mask; 55 local_irq_restore(flags); 56 } 57 58 static inline int test_and_set_bit(int nr, volatile void * addr) 59 { 60 int mask, retval; 61 volatile unsigned int *a = addr; 62 unsigned long flags; 63 64 a += nr >> 5; 65 mask = 1 << (nr & 0x1f); 66 local_irq_save(flags); 67 retval = (mask & *a) != 0; 68 *a |= mask; 69 local_irq_restore(flags); 70 71 return retval; 72 } 73 74 static inline int test_and_clear_bit(int nr, volatile void * addr) 75 { 76 int mask, retval; 77 volatile unsigned int *a = addr; 78 unsigned long flags; 79 80 a += nr >> 5; 81 mask = 1 << (nr & 0x1f); 82 local_irq_save(flags); 83 retval = (mask & *a) != 0; 84 *a &= ~mask; 85 local_irq_restore(flags); 86 87 return retval; 88 } 89 90 static inline int test_and_change_bit(int nr, volatile void * addr) 91 { 92 int mask, retval; 93 volatile unsigned int *a = addr; 94 unsigned long flags; 95 96 a += nr >> 5; 97 mask = 1 << (nr & 0x1f); 98 local_irq_save(flags); 99 retval = (mask & *a) != 0; 100 *a ^= mask; 101 local_irq_restore(flags); 102 103 return retval; 104 } 105 106 static inline unsigned long ffz(unsigned long word) 107 { 108 unsigned long result; 109 110 __asm__("1:\n\t" 111 "shlr %1\n\t" 112 "bt/s 1b\n\t" 113 " add #1, %0" 114 : "=r" (result), "=r" (word) 115 : "0" (~0L), "1" (word) 116 : "t"); 117 return result; 118 } 119 120 /** 121 * ffs - find first bit in word. 122 * @word: The word to search 123 * 124 * Undefined if no bit exists, so code should check against 0 first. 125 */ 126 static inline int ffs (int x) 127 { 128 int r = 1; 129 130 if (!x) 131 return 0; 132 if (!(x & 0xffff)) { 133 x >>= 16; 134 r += 16; 135 } 136 if (!(x & 0xff)) { 137 x >>= 8; 138 r += 8; 139 } 140 if (!(x & 0xf)) { 141 x >>= 4; 142 r += 4; 143 } 144 if (!(x & 3)) { 145 x >>= 2; 146 r += 2; 147 } 148 if (!(x & 1)) { 149 x >>= 1; 150 r += 1; 151 } 152 return r; 153 } 154 #define PLATFORM_FFS 155 156 #endif /* __KERNEL__ */ 157 158 #endif /* __ASM_SH_BITOPS_H */ 159