blob: 75fee2f7d9f240b3c98d5080a35016eca8e60399 [file] [log] [blame]
Bryan Wu1394f032007-05-06 14:50:22 -07001#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 */
Bryan Wu1394f032007-05-06 14:50:22 -070010
11#ifdef __KERNEL__
12
Jiri Slaby06245172007-10-18 23:40:26 -070013#ifndef _LINUX_BITOPS_H
14#error only <linux/bitops.h> can be included directly
15#endif
16
Bryan Wu1394f032007-05-06 14:50:22 -070017#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
Graf Yang6b3087c2009-01-07 23:14:39 +080022#ifdef CONFIG_SMP
23
24#include <linux/linkage.h>
25
26asmlinkage int __raw_bit_set_asm(volatile unsigned long *addr, int nr);
27
28asmlinkage int __raw_bit_clear_asm(volatile unsigned long *addr, int nr);
29
30asmlinkage int __raw_bit_toggle_asm(volatile unsigned long *addr, int nr);
31
32asmlinkage int __raw_bit_test_set_asm(volatile unsigned long *addr, int nr);
33
34asmlinkage int __raw_bit_test_clear_asm(volatile unsigned long *addr, int nr);
35
36asmlinkage int __raw_bit_test_toggle_asm(volatile unsigned long *addr, int nr);
37
38asmlinkage int __raw_bit_test_asm(const volatile unsigned long *addr, int nr);
39
40static 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
46static 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
52static 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
58static 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
64static 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
70static 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
76static 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
86static inline void set_bit(int nr, volatile unsigned long *addr)
Bryan Wu1394f032007-05-06 14:50:22 -070087{
88 int *a = (int *)addr;
89 int mask;
90 unsigned long flags;
Bryan Wu1394f032007-05-06 14:50:22 -070091 a += nr >> 5;
92 mask = 1 << (nr & 0x1f);
Yi Li6a01f232009-01-07 23:14:39 +080093 local_irq_save_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -070094 *a |= mask;
Yi Li6a01f232009-01-07 23:14:39 +080095 local_irq_restore_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -070096}
97
Graf Yang6b3087c2009-01-07 23:14:39 +080098static inline void clear_bit(int nr, volatile unsigned long *addr)
Bryan Wu1394f032007-05-06 14:50:22 -070099{
100 int *a = (int *)addr;
101 int mask;
102 unsigned long flags;
103 a += nr >> 5;
104 mask = 1 << (nr & 0x1f);
Yi Li6a01f232009-01-07 23:14:39 +0800105 local_irq_save_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700106 *a &= ~mask;
Yi Li6a01f232009-01-07 23:14:39 +0800107 local_irq_restore_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700108}
109
Graf Yang6b3087c2009-01-07 23:14:39 +0800110static inline void change_bit(int nr, volatile unsigned long *addr)
Bryan Wu1394f032007-05-06 14:50:22 -0700111{
Mike Frysingerf9ee3ab2009-06-08 09:51:30 -0400112 int mask;
113 unsigned long flags;
Bryan Wu1394f032007-05-06 14:50:22 -0700114 unsigned long *ADDR = (unsigned long *)addr;
115
116 ADDR += nr >> 5;
117 mask = 1 << (nr & 31);
Yi Li6a01f232009-01-07 23:14:39 +0800118 local_irq_save_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700119 *ADDR ^= mask;
Yi Li6a01f232009-01-07 23:14:39 +0800120 local_irq_restore_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700121}
122
Graf Yang6b3087c2009-01-07 23:14:39 +0800123static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
Bryan Wu1394f032007-05-06 14:50:22 -0700124{
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);
Yi Li6a01f232009-01-07 23:14:39 +0800131 local_irq_save_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700132 retval = (mask & *a) != 0;
133 *a |= mask;
Yi Li6a01f232009-01-07 23:14:39 +0800134 local_irq_restore_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700135
136 return retval;
137}
138
Graf Yang6b3087c2009-01-07 23:14:39 +0800139static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
Bryan Wu1394f032007-05-06 14:50:22 -0700140{
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);
Yi Li6a01f232009-01-07 23:14:39 +0800147 local_irq_save_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700148 retval = (mask & *a) != 0;
149 *a &= ~mask;
Yi Li6a01f232009-01-07 23:14:39 +0800150 local_irq_restore_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700151
152 return retval;
153}
154
Graf Yang6b3087c2009-01-07 23:14:39 +0800155static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
Bryan Wu1394f032007-05-06 14:50:22 -0700156{
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);
Yi Li6a01f232009-01-07 23:14:39 +0800163 local_irq_save_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700164 retval = (mask & *a) != 0;
165 *a ^= mask;
Yi Li6a01f232009-01-07 23:14:39 +0800166 local_irq_restore_hw(flags);
Bryan Wu1394f032007-05-06 14:50:22 -0700167 return retval;
168}
169
Graf Yang6b3087c2009-01-07 23:14:39 +0800170#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
178static 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
188static 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
198static 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
208static 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
220static 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
232static inline int __test_and_change_bit(int nr,
Bryan Wu1394f032007-05-06 14:50:22 -0700233 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
Graf Yang6b3087c2009-01-07 23:14:39 +0800245static inline int __test_bit(int nr, const void *addr)
Bryan Wu1394f032007-05-06 14:50:22 -0700246{
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
Graf Yang6b3087c2009-01-07 23:14:39 +0800255#ifndef CONFIG_SMP
256/*
257 * This routine doesn't need irq save and restore ops in UP
258 * context.
259 */
260static inline int test_bit(int nr, const void *addr)
261{
262 return __test_bit(nr, addr);
263}
264#endif
Bryan Wu1394f032007-05-06 14:50:22 -0700265
266#include <asm-generic/bitops/find.h>
267#include <asm-generic/bitops/hweight.h>
Nick Piggin26333572007-10-18 03:06:39 -0700268#include <asm-generic/bitops/lock.h>
Bryan Wu1394f032007-05-06 14:50:22 -0700269
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>
Rusty Russellccec25f2009-01-01 10:12:17 +1030278#include <asm-generic/bitops/__fls.h>
Bryan Wu1394f032007-05-06 14:50:22 -0700279#include <asm-generic/bitops/fls64.h>
280
281#endif /* _BLACKFIN_BITOPS_H */