1
2
3
4
5
6
7
8#ifndef __ASM_AVR32_BITOPS_H
9#define __ASM_AVR32_BITOPS_H
10
11#ifndef _LINUX_BITOPS_H
12#error only <linux/bitops.h> can be included directly
13#endif
14
15#include <asm/byteorder.h>
16#include <asm/barrier.h>
17
18
19
20
21
22
23
24
25
26
27
28
29static inline void set_bit(int nr, volatile void * addr)
30{
31 unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
32 unsigned long tmp;
33
34 if (__builtin_constant_p(nr)) {
35 asm volatile(
36 "1: ssrf 5\n"
37 " ld.w %0, %2\n"
38 " sbr %0, %3\n"
39 " stcond %1, %0\n"
40 " brne 1b"
41 : "=&r"(tmp), "=o"(*p)
42 : "m"(*p), "i"(nr)
43 : "cc");
44 } else {
45 unsigned long mask = 1UL << (nr % BITS_PER_LONG);
46 asm volatile(
47 "1: ssrf 5\n"
48 " ld.w %0, %2\n"
49 " or %0, %3\n"
50 " stcond %1, %0\n"
51 " brne 1b"
52 : "=&r"(tmp), "=o"(*p)
53 : "m"(*p), "r"(mask)
54 : "cc");
55 }
56}
57
58
59
60
61
62
63
64
65
66
67
68static inline void clear_bit(int nr, volatile void * addr)
69{
70 unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
71 unsigned long tmp;
72
73 if (__builtin_constant_p(nr)) {
74 asm volatile(
75 "1: ssrf 5\n"
76 " ld.w %0, %2\n"
77 " cbr %0, %3\n"
78 " stcond %1, %0\n"
79 " brne 1b"
80 : "=&r"(tmp), "=o"(*p)
81 : "m"(*p), "i"(nr)
82 : "cc");
83 } else {
84 unsigned long mask = 1UL << (nr % BITS_PER_LONG);
85 asm volatile(
86 "1: ssrf 5\n"
87 " ld.w %0, %2\n"
88 " andn %0, %3\n"
89 " stcond %1, %0\n"
90 " brne 1b"
91 : "=&r"(tmp), "=o"(*p)
92 : "m"(*p), "r"(mask)
93 : "cc");
94 }
95}
96
97
98
99
100
101
102
103
104
105
106static inline void change_bit(int nr, volatile void * addr)
107{
108 unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
109 unsigned long mask = 1UL << (nr % BITS_PER_LONG);
110 unsigned long tmp;
111
112 asm volatile(
113 "1: ssrf 5\n"
114 " ld.w %0, %2\n"
115 " eor %0, %3\n"
116 " stcond %1, %0\n"
117 " brne 1b"
118 : "=&r"(tmp), "=o"(*p)
119 : "m"(*p), "r"(mask)
120 : "cc");
121}
122
123
124
125
126
127
128
129
130
131static inline int test_and_set_bit(int nr, volatile void * addr)
132{
133 unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
134 unsigned long mask = 1UL << (nr % BITS_PER_LONG);
135 unsigned long tmp, old;
136
137 if (__builtin_constant_p(nr)) {
138 asm volatile(
139 "1: ssrf 5\n"
140 " ld.w %0, %3\n"
141 " mov %2, %0\n"
142 " sbr %0, %4\n"
143 " stcond %1, %0\n"
144 " brne 1b"
145 : "=&r"(tmp), "=o"(*p), "=&r"(old)
146 : "m"(*p), "i"(nr)
147 : "memory", "cc");
148 } else {
149 asm volatile(
150 "1: ssrf 5\n"
151 " ld.w %2, %3\n"
152 " or %0, %2, %4\n"
153 " stcond %1, %0\n"
154 " brne 1b"
155 : "=&r"(tmp), "=o"(*p), "=&r"(old)
156 : "m"(*p), "r"(mask)
157 : "memory", "cc");
158 }
159
160 return (old & mask) != 0;
161}
162
163
164
165
166
167
168
169
170
171static inline int test_and_clear_bit(int nr, volatile void * addr)
172{
173 unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
174 unsigned long mask = 1UL << (nr % BITS_PER_LONG);
175 unsigned long tmp, old;
176
177 if (__builtin_constant_p(nr)) {
178 asm volatile(
179 "1: ssrf 5\n"
180 " ld.w %0, %3\n"
181 " mov %2, %0\n"
182 " cbr %0, %4\n"
183 " stcond %1, %0\n"
184 " brne 1b"
185 : "=&r"(tmp), "=o"(*p), "=&r"(old)
186 : "m"(*p), "i"(nr)
187 : "memory", "cc");
188 } else {
189 asm volatile(
190 "1: ssrf 5\n"
191 " ld.w %0, %3\n"
192 " mov %2, %0\n"
193 " andn %0, %4\n"
194 " stcond %1, %0\n"
195 " brne 1b"
196 : "=&r"(tmp), "=o"(*p), "=&r"(old)
197 : "m"(*p), "r"(mask)
198 : "memory", "cc");
199 }
200
201 return (old & mask) != 0;
202}
203
204
205
206
207
208
209
210
211
212static inline int test_and_change_bit(int nr, volatile void * addr)
213{
214 unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
215 unsigned long mask = 1UL << (nr % BITS_PER_LONG);
216 unsigned long tmp, old;
217
218 asm volatile(
219 "1: ssrf 5\n"
220 " ld.w %2, %3\n"
221 " eor %0, %2, %4\n"
222 " stcond %1, %0\n"
223 " brne 1b"
224 : "=&r"(tmp), "=o"(*p), "=&r"(old)
225 : "m"(*p), "r"(mask)
226 : "memory", "cc");
227
228 return (old & mask) != 0;
229}
230
231#include <asm-generic/bitops/non-atomic.h>
232
233
234static inline unsigned long __ffs(unsigned long word)
235{
236 unsigned long result;
237
238 asm("brev %1\n\t"
239 "clz %0,%1"
240 : "=r"(result), "=&r"(word)
241 : "1"(word));
242 return result;
243}
244
245
246static inline unsigned long ffz(unsigned long word)
247{
248 return __ffs(~word);
249}
250
251
252static inline int fls(unsigned long word)
253{
254 unsigned long result;
255
256 asm("clz %0,%1" : "=r"(result) : "r"(word));
257 return 32 - result;
258}
259
260static inline int __fls(unsigned long word)
261{
262 return fls(word) - 1;
263}
264
265unsigned long find_first_zero_bit(const unsigned long *addr,
266 unsigned long size);
267#define find_first_zero_bit find_first_zero_bit
268
269unsigned long find_next_zero_bit(const unsigned long *addr,
270 unsigned long size,
271 unsigned long offset);
272#define find_next_zero_bit find_next_zero_bit
273
274unsigned long find_first_bit(const unsigned long *addr,
275 unsigned long size);
276#define find_first_bit find_first_bit
277
278unsigned long find_next_bit(const unsigned long *addr,
279 unsigned long size,
280 unsigned long offset);
281#define find_next_bit find_next_bit
282
283
284
285
286
287
288
289
290
291static inline int ffs(unsigned long word)
292{
293 if(word == 0)
294 return 0;
295 return __ffs(word) + 1;
296}
297
298#include <asm-generic/bitops/fls64.h>
299#include <asm-generic/bitops/sched.h>
300#include <asm-generic/bitops/hweight.h>
301#include <asm-generic/bitops/lock.h>
302
303extern unsigned long find_next_zero_bit_le(const void *addr,
304 unsigned long size, unsigned long offset);
305#define find_next_zero_bit_le find_next_zero_bit_le
306
307extern unsigned long find_next_bit_le(const void *addr,
308 unsigned long size, unsigned long offset);
309#define find_next_bit_le find_next_bit_le
310
311#include <asm-generic/bitops/le.h>
312#include <asm-generic/bitops/ext2-atomic.h>
313
314#endif
315