Initial commit
[kk_librfid.git] / firmware / include / asm / .svn / text-base / bitops.h.svn-base
blob337d800d3b5c3b8b8fb637c89380848a7f7b750c
1 /*
2  * Copyright 1995, Russell King.
3  * Various bits and pieces copyrights include:
4  *  Linus Torvalds (test_bit).
5  * Big endian support: Copyright 2001, Nicolas Pitre
6  *  reworked by rmk.
7  *
8  * bit 0 is the LSB of an "unsigned long" quantity.
9  *
10  * Please note that the code in this file should never be included
11  * from user space.  Many of these are not implemented in assembler
12  * since they would be too costly.  Also, they require privileged
13  * instructions (which are not available from user mode) to ensure
14  * that they are atomic.
15  */
17 #ifndef __ASM_ARM_BITOPS_H
18 #define __ASM_ARM_BITOPS_H
20 #include <asm/system.h>
22 #define smp_mb__before_clear_bit()      mb()
23 #define smp_mb__after_clear_bit()       mb()
26  * These functions are the basis of our bit ops.
27  *
28  * First, the atomic bitops. These use native endian.
29  */
30 static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
32         unsigned long flags;
33         unsigned long mask = 1UL << (bit & 31);
35         p += bit >> 5;
37         local_irq_save(flags);
38         *p |= mask;
39         local_irq_restore(flags);
42 static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
44         unsigned long flags;
45         unsigned long mask = 1UL << (bit & 31);
47         p += bit >> 5;
49         local_irq_save(flags);
50         *p &= ~mask;
51         local_irq_restore(flags);
54 static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
56         unsigned long flags;
57         unsigned long mask = 1UL << (bit & 31);
59         p += bit >> 5;
61         local_irq_save(flags);
62         *p ^= mask;
63         local_irq_restore(flags);
66 static inline int
67 ____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
69         unsigned long flags;
70         unsigned int res;
71         unsigned long mask = 1UL << (bit & 31);
73         p += bit >> 5;
75         local_irq_save(flags);
76         res = *p;
77         *p = res | mask;
78         local_irq_restore(flags);
80         return res & mask;
83 static inline int
84 ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
86         unsigned long flags;
87         unsigned int res;
88         unsigned long mask = 1UL << (bit & 31);
90         p += bit >> 5;
92         local_irq_save(flags);
93         res = *p;
94         *p = res & ~mask;
95         local_irq_restore(flags);
97         return res & mask;
100 static inline int
101 ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
103         unsigned long flags;
104         unsigned int res;
105         unsigned long mask = 1UL << (bit & 31);
107         p += bit >> 5;
109         local_irq_save(flags);
110         res = *p;
111         *p = res ^ mask;
112         local_irq_restore(flags);
114         return res & mask;
117 //#include <asm-generic/bitops/non-atomic.h>
120  *  A note about Endian-ness.
121  *  -------------------------
123  * When the ARM is put into big endian mode via CR15, the processor
124  * merely swaps the order of bytes within words, thus:
126  *          ------------ physical data bus bits -----------
127  *          D31 ... D24  D23 ... D16  D15 ... D8  D7 ... D0
128  * little     byte 3       byte 2       byte 1      byte 0
129  * big        byte 0       byte 1       byte 2      byte 3
131  * This means that reading a 32-bit word at address 0 returns the same
132  * value irrespective of the endian mode bit.
134  * Peripheral devices should be connected with the data bus reversed in
135  * "Big Endian" mode.  ARM Application Note 61 is applicable, and is
136  * available from http://www.arm.com/.
138  * The following assumes that the data bus connectivity for big endian
139  * mode has been followed.
141  * Note that bit 0 is defined to be 32-bit word bit 0, not byte 0 bit 0.
142  */
145  * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
146  */
147 extern void _set_bit_le(int nr, volatile unsigned long * p);
148 extern void _clear_bit_le(int nr, volatile unsigned long * p);
149 extern void _change_bit_le(int nr, volatile unsigned long * p);
150 extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
151 extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
152 extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
153 extern int _find_first_zero_bit_le(const void * p, unsigned size);
154 extern int _find_next_zero_bit_le(const void * p, int size, int offset);
155 extern int _find_first_bit_le(const unsigned long *p, unsigned size);
156 extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
159  * Big endian assembly bitops.  nr = 0 -> byte 3 bit 0.
160  */
161 extern void _set_bit_be(int nr, volatile unsigned long * p);
162 extern void _clear_bit_be(int nr, volatile unsigned long * p);
163 extern void _change_bit_be(int nr, volatile unsigned long * p);
164 extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
165 extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
166 extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
167 extern int _find_first_zero_bit_be(const void * p, unsigned size);
168 extern int _find_next_zero_bit_be(const void * p, int size, int offset);
169 extern int _find_first_bit_be(const unsigned long *p, unsigned size);
170 extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
173  * The __* form of bitops are non-atomic and may be reordered.
174  */
175 #define ATOMIC_BITOP_LE(name,nr,p)              \
176         (__builtin_constant_p(nr) ?             \
177          ____atomic_##name(nr, p) :             \
178          _##name##_le(nr,p))
180 #define ATOMIC_BITOP_BE(name,nr,p)              \
181         (__builtin_constant_p(nr) ?             \
182          ____atomic_##name(nr, p) :             \
183          _##name##_be(nr,p))
185 #define NONATOMIC_BITOP(name,nr,p)              \
186         (____nonatomic_##name(nr, p))
189  * These are the little endian, atomic definitions.
190  */
191 #define set_bit(nr,p)                   ATOMIC_BITOP_LE(set_bit,nr,p)
192 #define clear_bit(nr,p)                 ATOMIC_BITOP_LE(clear_bit,nr,p)
193 #define change_bit(nr,p)                ATOMIC_BITOP_LE(change_bit,nr,p)
194 #define test_and_set_bit(nr,p)          ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
195 #define test_and_clear_bit(nr,p)        ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
196 #define test_and_change_bit(nr,p)       ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
197 #define find_first_zero_bit(p,sz)       _find_first_zero_bit_le(p,sz)
198 #define find_next_zero_bit(p,sz,off)    _find_next_zero_bit_le(p,sz,off)
199 #define find_first_bit(p,sz)            _find_first_bit_le(p,sz)
200 #define find_next_bit(p,sz,off)         _find_next_bit_le(p,sz,off)
202 #define WORD_BITOFF_TO_LE(x)            ((x))
204 #if 0
205 #include <asm-generic/bitops/ffz.h>
206 #include <asm-generic/bitops/__ffs.h>
207 #include <asm-generic/bitops/fls.h>
208 #include <asm-generic/bitops/ffs.h>
210 #include <asm-generic/bitops/fls64.h>
212 #include <asm-generic/bitops/sched.h>
213 #include <asm-generic/bitops/hweight.h>
214 #endif
216 #define BITS_PER_LONG           32
217 #define BITOP_MASK(nr)          (1UL << ((nr) % BITS_PER_LONG))
218 #define BITOP_WORD(nr)          ((nr) / BITS_PER_LONG)
220 static inline int test_bit(int nr, const volatile unsigned long *addr)
222         return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
225 #endif /* _ARM_BITOPS_H */