Merge branch 'auto' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile...
[pandora-kernel.git] / arch / blackfin / include / asm / bitops.h
1 #ifndef _BLACKFIN_BITOPS_H
2 #define _BLACKFIN_BITOPS_H
3
4 /*
5  * Copyright 1992, Linus Torvalds.
6  */
7
8 #include <linux/compiler.h>
9 #include <asm/byteorder.h>      /* swab32 */
10
11 #ifdef __KERNEL__
12
13 #ifndef _LINUX_BITOPS_H
14 #error only <linux/bitops.h> can be included directly
15 #endif
16
17 #include <asm-generic/bitops/ffs.h>
18 #include <asm-generic/bitops/__ffs.h>
19 #include <asm-generic/bitops/sched.h>
20 #include <asm-generic/bitops/ffz.h>
21
22 #ifdef CONFIG_SMP
23
24 #include <linux/linkage.h>
25
26 asmlinkage int __raw_bit_set_asm(volatile unsigned long *addr, int nr);
27
28 asmlinkage int __raw_bit_clear_asm(volatile unsigned long *addr, int nr);
29
30 asmlinkage int __raw_bit_toggle_asm(volatile unsigned long *addr, int nr);
31
32 asmlinkage int __raw_bit_test_set_asm(volatile unsigned long *addr, int nr);
33
34 asmlinkage int __raw_bit_test_clear_asm(volatile unsigned long *addr, int nr);
35
36 asmlinkage int __raw_bit_test_toggle_asm(volatile unsigned long *addr, int nr);
37
38 asmlinkage int __raw_bit_test_asm(const volatile unsigned long *addr, int nr);
39
40 static inline void set_bit(int nr, volatile unsigned long *addr)
41 {
42         volatile unsigned long *a = addr + (nr >> 5);
43         __raw_bit_set_asm(a, nr & 0x1f);
44 }
45
46 static inline void clear_bit(int nr, volatile unsigned long *addr)
47 {
48         volatile unsigned long *a = addr + (nr >> 5);
49         __raw_bit_clear_asm(a, nr & 0x1f);
50 }
51
52 static inline void change_bit(int nr, volatile unsigned long *addr)
53 {
54         volatile unsigned long *a = addr + (nr >> 5);
55         __raw_bit_toggle_asm(a, nr & 0x1f);
56 }
57
58 static inline int test_bit(int nr, const volatile unsigned long *addr)
59 {
60         volatile const unsigned long *a = addr + (nr >> 5);
61         return __raw_bit_test_asm(a, nr & 0x1f) != 0;
62 }
63
64 static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
65 {
66         volatile unsigned long *a = addr + (nr >> 5);
67         return __raw_bit_test_set_asm(a, nr & 0x1f);
68 }
69
70 static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
71 {
72         volatile unsigned long *a = addr + (nr >> 5);
73         return __raw_bit_test_clear_asm(a, nr & 0x1f);
74 }
75
76 static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
77 {
78         volatile unsigned long *a = addr + (nr >> 5);
79         return __raw_bit_test_toggle_asm(a, nr & 0x1f);
80 }
81
82 #else /* !CONFIG_SMP */
83
84 #include <asm/system.h>         /* save_flags */
85
86 static inline void set_bit(int nr, volatile unsigned long *addr)
87 {
88         int *a = (int *)addr;
89         int mask;
90         unsigned long flags;
91         a += nr >> 5;
92         mask = 1 << (nr & 0x1f);
93         local_irq_save_hw(flags);
94         *a |= mask;
95         local_irq_restore_hw(flags);
96 }
97
98 static inline void clear_bit(int nr, volatile unsigned long *addr)
99 {
100         int *a = (int *)addr;
101         int mask;
102         unsigned long flags;
103         a += nr >> 5;
104         mask = 1 << (nr & 0x1f);
105         local_irq_save_hw(flags);
106         *a &= ~mask;
107         local_irq_restore_hw(flags);
108 }
109
110 static inline void change_bit(int nr, volatile unsigned long *addr)
111 {
112         int mask;
113         unsigned long flags;
114         unsigned long *ADDR = (unsigned long *)addr;
115
116         ADDR += nr >> 5;
117         mask = 1 << (nr & 31);
118         local_irq_save_hw(flags);
119         *ADDR ^= mask;
120         local_irq_restore_hw(flags);
121 }
122
123 static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
124 {
125         int mask, retval;
126         volatile unsigned int *a = (volatile unsigned int *)addr;
127         unsigned long flags;
128
129         a += nr >> 5;
130         mask = 1 << (nr & 0x1f);
131         local_irq_save_hw(flags);
132         retval = (mask & *a) != 0;
133         *a |= mask;
134         local_irq_restore_hw(flags);
135
136         return retval;
137 }
138
139 static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
140 {
141         int mask, retval;
142         volatile unsigned int *a = (volatile unsigned int *)addr;
143         unsigned long flags;
144
145         a += nr >> 5;
146         mask = 1 << (nr & 0x1f);
147         local_irq_save_hw(flags);
148         retval = (mask & *a) != 0;
149         *a &= ~mask;
150         local_irq_restore_hw(flags);
151
152         return retval;
153 }
154
155 static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
156 {
157         int mask, retval;
158         volatile unsigned int *a = (volatile unsigned int *)addr;
159         unsigned long flags;
160
161         a += nr >> 5;
162         mask = 1 << (nr & 0x1f);
163         local_irq_save_hw(flags);
164         retval = (mask & *a) != 0;
165         *a ^= mask;
166         local_irq_restore_hw(flags);
167         return retval;
168 }
169
170 #endif /* CONFIG_SMP */
171
172 /*
173  * clear_bit() doesn't provide any barrier for the compiler.
174  */
175 #define smp_mb__before_clear_bit()      barrier()
176 #define smp_mb__after_clear_bit()       barrier()
177
178 static inline void __set_bit(int nr, volatile unsigned long *addr)
179 {
180         int *a = (int *)addr;
181         int mask;
182
183         a += nr >> 5;
184         mask = 1 << (nr & 0x1f);
185         *a |= mask;
186 }
187
188 static inline void __clear_bit(int nr, volatile unsigned long *addr)
189 {
190         int *a = (int *)addr;
191         int mask;
192
193         a += nr >> 5;
194         mask = 1 << (nr & 0x1f);
195         *a &= ~mask;
196 }
197
198 static inline void __change_bit(int nr, volatile unsigned long *addr)
199 {
200         int mask;
201         unsigned long *ADDR = (unsigned long *)addr;
202
203         ADDR += nr >> 5;
204         mask = 1 << (nr & 31);
205         *ADDR ^= mask;
206 }
207
208 static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
209 {
210         int mask, retval;
211         volatile unsigned int *a = (volatile unsigned int *)addr;
212
213         a += nr >> 5;
214         mask = 1 << (nr & 0x1f);
215         retval = (mask & *a) != 0;
216         *a |= mask;
217         return retval;
218 }
219
220 static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
221 {
222         int mask, retval;
223         volatile unsigned int *a = (volatile unsigned int *)addr;
224
225         a += nr >> 5;
226         mask = 1 << (nr & 0x1f);
227         retval = (mask & *a) != 0;
228         *a &= ~mask;
229         return retval;
230 }
231
232 static inline int __test_and_change_bit(int nr,
233                                             volatile unsigned long *addr)
234 {
235         int mask, retval;
236         volatile unsigned int *a = (volatile unsigned int *)addr;
237
238         a += nr >> 5;
239         mask = 1 << (nr & 0x1f);
240         retval = (mask & *a) != 0;
241         *a ^= mask;
242         return retval;
243 }
244
245 static inline int __test_bit(int nr, const void *addr)
246 {
247         int *a = (int *)addr;
248         int mask;
249
250         a += nr >> 5;
251         mask = 1 << (nr & 0x1f);
252         return ((mask & *a) != 0);
253 }
254
255 #ifndef CONFIG_SMP
256 /*
257  * This routine doesn't need irq save and restore ops in UP
258  * context.
259  */
260 static inline int test_bit(int nr, const void *addr)
261 {
262         return __test_bit(nr, addr);
263 }
264 #endif
265
266 #include <asm-generic/bitops/find.h>
267 #include <asm-generic/bitops/hweight.h>
268 #include <asm-generic/bitops/lock.h>
269
270 #include <asm-generic/bitops/ext2-atomic.h>
271 #include <asm-generic/bitops/ext2-non-atomic.h>
272
273 #include <asm-generic/bitops/minix.h>
274
275 #endif                          /* __KERNEL__ */
276
277 #include <asm-generic/bitops/fls.h>
278 #include <asm-generic/bitops/__fls.h>
279 #include <asm-generic/bitops/fls64.h>
280
281 #endif                          /* _BLACKFIN_BITOPS_H */