Use correct spelling of "U-Boot"
[platform/kernel/u-boot.git] / arch / blackfin / include / asm / bitops.h
1 /*
2  * U-Boot - bitops.h Routines for bit operations
3  *
4  * Copyright (c) 2005-2007 Analog Devices Inc.
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #ifndef _BLACKFIN_BITOPS_H
10 #define _BLACKFIN_BITOPS_H
11
12 /*
13  * Copyright 1992, Linus Torvalds.
14  */
15
16 #include <asm/byteorder.h>
17 #include <asm/system.h>
18 #include <asm-generic/bitops/fls.h>
19 #include <asm-generic/bitops/__fls.h>
20 #include <asm-generic/bitops/fls64.h>
21 #include <asm-generic/bitops/__ffs.h>
22
23 #ifdef __KERNEL__
24 /*
25  * Function prototypes to keep gcc -Wall happy
26  */
27
28 /*
29  * The __ functions are not atomic
30  */
31
32 /*
33  * ffz = Find First Zero in word. Undefined if no zero exists,
34  * so code should check against ~0UL first..
35  */
36 static __inline__ unsigned long ffz(unsigned long word)
37 {
38         unsigned long result = 0;
39
40         while (word & 1) {
41                 result++;
42                 word >>= 1;
43         }
44         return result;
45 }
46
47 static __inline__ void set_bit(int nr, volatile void *addr)
48 {
49         int *a = (int *)addr;
50         int mask;
51         unsigned long flags;
52
53         a += nr >> 5;
54         mask = 1 << (nr & 0x1f);
55         local_irq_save(flags);
56         *a |= mask;
57         local_irq_restore(flags);
58 }
59
60 static __inline__ void __set_bit(int nr, volatile void *addr)
61 {
62         int *a = (int *)addr;
63         int mask;
64
65         a += nr >> 5;
66         mask = 1 << (nr & 0x1f);
67         *a |= mask;
68 }
69 #define PLATFORM__SET_BIT
70
71 /*
72  * clear_bit() doesn't provide any barrier for the compiler.
73  */
74 #define smp_mb__before_clear_bit()      barrier()
75 #define smp_mb__after_clear_bit()       barrier()
76
77 static __inline__ void clear_bit(int nr, volatile void *addr)
78 {
79         int *a = (int *)addr;
80         int mask;
81         unsigned long flags;
82
83         a += nr >> 5;
84         mask = 1 << (nr & 0x1f);
85         local_irq_save(flags);
86         *a &= ~mask;
87         local_irq_restore(flags);
88 }
89
90 static __inline__ void change_bit(int nr, volatile void *addr)
91 {
92         int mask, flags;
93         unsigned long *ADDR = (unsigned long *)addr;
94
95         ADDR += nr >> 5;
96         mask = 1 << (nr & 31);
97         local_irq_save(flags);
98         *ADDR ^= mask;
99         local_irq_restore(flags);
100 }
101
102 static __inline__ void __change_bit(int nr, volatile void *addr)
103 {
104         int mask;
105         unsigned long *ADDR = (unsigned long *)addr;
106
107         ADDR += nr >> 5;
108         mask = 1 << (nr & 31);
109         *ADDR ^= mask;
110 }
111
112 static __inline__ int test_and_set_bit(int nr, volatile void *addr)
113 {
114         int mask, retval;
115         volatile unsigned int *a = (volatile unsigned int *)addr;
116         unsigned long flags;
117
118         a += nr >> 5;
119         mask = 1 << (nr & 0x1f);
120         local_irq_save(flags);
121         retval = (mask & *a) != 0;
122         *a |= mask;
123         local_irq_restore(flags);
124
125         return retval;
126 }
127
128 static __inline__ int __test_and_set_bit(int nr, volatile void *addr)
129 {
130         int mask, retval;
131         volatile unsigned int *a = (volatile unsigned int *)addr;
132
133         a += nr >> 5;
134         mask = 1 << (nr & 0x1f);
135         retval = (mask & *a) != 0;
136         *a |= mask;
137         return retval;
138 }
139
140 static __inline__ int test_and_clear_bit(int nr, volatile void *addr)
141 {
142         int mask, retval;
143         volatile unsigned int *a = (volatile unsigned int *)addr;
144         unsigned long flags;
145
146         a += nr >> 5;
147         mask = 1 << (nr & 0x1f);
148         local_irq_save(flags);
149         retval = (mask & *a) != 0;
150         *a &= ~mask;
151         local_irq_restore(flags);
152
153         return retval;
154 }
155
156 static __inline__ int __test_and_clear_bit(int nr, volatile void *addr)
157 {
158         int mask, retval;
159         volatile unsigned int *a = (volatile unsigned int *)addr;
160
161         a += nr >> 5;
162         mask = 1 << (nr & 0x1f);
163         retval = (mask & *a) != 0;
164         *a &= ~mask;
165         return retval;
166 }
167
168 static __inline__ int test_and_change_bit(int nr, volatile void *addr)
169 {
170         int mask, retval;
171         volatile unsigned int *a = (volatile unsigned int *)addr;
172         unsigned long flags;
173
174         a += nr >> 5;
175         mask = 1 << (nr & 0x1f);
176         local_irq_save(flags);
177         retval = (mask & *a) != 0;
178         *a ^= mask;
179         local_irq_restore(flags);
180
181         return retval;
182 }
183
184 static __inline__ int __test_and_change_bit(int nr, volatile void *addr)
185 {
186         int mask, retval;
187         volatile unsigned int *a = (volatile unsigned int *)addr;
188
189         a += nr >> 5;
190         mask = 1 << (nr & 0x1f);
191         retval = (mask & *a) != 0;
192         *a ^= mask;
193         return retval;
194 }
195
196 /*
197  * This routine doesn't need to be atomic.
198  */
199 static __inline__ int __constant_test_bit(int nr, const volatile void *addr)
200 {
201         return ((1UL << (nr & 31)) &
202                 (((const volatile unsigned int *)addr)[nr >> 5])) != 0;
203 }
204
205 static __inline__ int __test_bit(int nr, volatile void *addr)
206 {
207         int *a = (int *)addr;
208         int mask;
209
210         a += nr >> 5;
211         mask = 1 << (nr & 0x1f);
212         return ((mask & *a) != 0);
213 }
214
215 #define test_bit(nr,addr) \
216 (__builtin_constant_p(nr) ? \
217  __constant_test_bit((nr),(addr)) : \
218  __test_bit((nr),(addr)))
219
220 #define find_first_zero_bit(addr, size) \
221         find_next_zero_bit((addr), (size), 0)
222
223 static __inline__ int find_next_zero_bit(void *addr, int size, int offset)
224 {
225         unsigned long *p = ((unsigned long *)addr) + (offset >> 5);
226         unsigned long result = offset & ~31UL;
227         unsigned long tmp;
228
229         if (offset >= size)
230                 return size;
231         size -= result;
232         offset &= 31UL;
233         if (offset) {
234                 tmp = *(p++);
235                 tmp |= ~0UL >> (32 - offset);
236                 if (size < 32)
237                         goto found_first;
238                 if (~tmp)
239                         goto found_middle;
240                 size -= 32;
241                 result += 32;
242         }
243         while (size & ~31UL) {
244                 if (~(tmp = *(p++)))
245                         goto found_middle;
246                 result += 32;
247                 size -= 32;
248         }
249         if (!size)
250                 return result;
251         tmp = *p;
252
253       found_first:
254         tmp |= ~0UL >> size;
255       found_middle:
256         return result + ffz(tmp);
257 }
258
259 /*
260  * hweightN: returns the hamming weight (i.e. the number
261  * of bits set) of a N-bit word
262  */
263
264 #define hweight32(x)    generic_hweight32(x)
265 #define hweight16(x)    generic_hweight16(x)
266 #define hweight8(x)     generic_hweight8(x)
267
268 static __inline__ int ext2_set_bit(int nr, volatile void *addr)
269 {
270         int mask, retval;
271         unsigned long flags;
272         volatile unsigned char *ADDR = (unsigned char *)addr;
273
274         ADDR += nr >> 3;
275         mask = 1 << (nr & 0x07);
276         local_irq_save(flags);
277         retval = (mask & *ADDR) != 0;
278         *ADDR |= mask;
279         local_irq_restore(flags);
280         return retval;
281 }
282
283 static __inline__ int ext2_clear_bit(int nr, volatile void *addr)
284 {
285         int mask, retval;
286         unsigned long flags;
287         volatile unsigned char *ADDR = (unsigned char *)addr;
288
289         ADDR += nr >> 3;
290         mask = 1 << (nr & 0x07);
291         local_irq_save(flags);
292         retval = (mask & *ADDR) != 0;
293         *ADDR &= ~mask;
294         local_irq_restore(flags);
295         return retval;
296 }
297
298 static __inline__ int ext2_test_bit(int nr, const volatile void *addr)
299 {
300         int mask;
301         const volatile unsigned char *ADDR = (const unsigned char *)addr;
302
303         ADDR += nr >> 3;
304         mask = 1 << (nr & 0x07);
305         return ((mask & *ADDR) != 0);
306 }
307
308 #define ext2_find_first_zero_bit(addr, size) \
309         ext2_find_next_zero_bit((addr), (size), 0)
310
311 static __inline__ unsigned long ext2_find_next_zero_bit(void *addr,
312                                                         unsigned long size,
313                                                         unsigned long offset)
314 {
315         unsigned long *p = ((unsigned long *)addr) + (offset >> 5);
316         unsigned long result = offset & ~31UL;
317         unsigned long tmp;
318
319         if (offset >= size)
320                 return size;
321         size -= result;
322         offset &= 31UL;
323         if (offset) {
324                 tmp = *(p++);
325                 tmp |= ~0UL >> (32 - offset);
326                 if (size < 32)
327                         goto found_first;
328                 if (~tmp)
329                         goto found_middle;
330                 size -= 32;
331                 result += 32;
332         }
333         while (size & ~31UL) {
334                 if (~(tmp = *(p++)))
335                         goto found_middle;
336                 result += 32;
337                 size -= 32;
338         }
339         if (!size)
340                 return result;
341         tmp = *p;
342
343       found_first:
344         tmp |= ~0UL >> size;
345       found_middle:
346         return result + ffz(tmp);
347 }
348
349 /* Bitmap functions for the minix filesystem. */
350 #define minix_test_and_set_bit(nr,addr)         test_and_set_bit(nr,addr)
351 #define minix_set_bit(nr,addr)                  set_bit(nr,addr)
352 #define minix_test_and_clear_bit(nr,addr)       test_and_clear_bit(nr,addr)
353 #define minix_test_bit(nr,addr)                 test_bit(nr,addr)
354 #define minix_find_first_zero_bit(addr,size)    find_first_zero_bit(addr,size)
355
356 #endif
357
358 #endif