MIPS: ralink: add mt7628an support
[deliverable/linux.git] / arch / mips / include / asm / bitops.h
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 1994 - 1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (c) 1999, 2000 Silicon Graphics, Inc.
8 */
9 #ifndef _ASM_BITOPS_H
10 #define _ASM_BITOPS_H
11
12 #ifndef _LINUX_BITOPS_H
13 #error only <linux/bitops.h> can be included directly
14 #endif
15
16 #include <linux/compiler.h>
17 #include <linux/types.h>
18 #include <asm/barrier.h>
19 #include <asm/byteorder.h> /* sigh ... */
20 #include <asm/cpu-features.h>
21 #include <asm/sgidefs.h>
22 #include <asm/war.h>
23
24 #if _MIPS_SZLONG == 32
25 #define SZLONG_LOG 5
26 #define SZLONG_MASK 31UL
27 #define __LL "ll "
28 #define __SC "sc "
29 #define __INS "ins "
30 #define __EXT "ext "
31 #elif _MIPS_SZLONG == 64
32 #define SZLONG_LOG 6
33 #define SZLONG_MASK 63UL
34 #define __LL "lld "
35 #define __SC "scd "
36 #define __INS "dins "
37 #define __EXT "dext "
38 #endif
39
40 /*
41 * These are the "slower" versions of the functions and are in bitops.c.
42 * These functions call raw_local_irq_{save,restore}().
43 */
44 void __mips_set_bit(unsigned long nr, volatile unsigned long *addr);
45 void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr);
46 void __mips_change_bit(unsigned long nr, volatile unsigned long *addr);
47 int __mips_test_and_set_bit(unsigned long nr,
48 volatile unsigned long *addr);
49 int __mips_test_and_set_bit_lock(unsigned long nr,
50 volatile unsigned long *addr);
51 int __mips_test_and_clear_bit(unsigned long nr,
52 volatile unsigned long *addr);
53 int __mips_test_and_change_bit(unsigned long nr,
54 volatile unsigned long *addr);
55
56
57 /*
58 * set_bit - Atomically set a bit in memory
59 * @nr: the bit to set
60 * @addr: the address to start counting from
61 *
62 * This function is atomic and may not be reordered. See __set_bit()
63 * if you do not require the atomic guarantees.
64 * Note that @nr may be almost arbitrarily large; this function is not
65 * restricted to acting on a single-word quantity.
66 */
67 static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
68 {
69 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
70 int bit = nr & SZLONG_MASK;
71 unsigned long temp;
72
73 if (kernel_uses_llsc && R10000_LLSC_WAR) {
74 __asm__ __volatile__(
75 " .set arch=r4000 \n"
76 "1: " __LL "%0, %1 # set_bit \n"
77 " or %0, %2 \n"
78 " " __SC "%0, %1 \n"
79 " beqzl %0, 1b \n"
80 " .set mips0 \n"
81 : "=&r" (temp), "=m" (*m)
82 : "ir" (1UL << bit), "m" (*m));
83 #ifdef CONFIG_CPU_MIPSR2
84 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
85 do {
86 __asm__ __volatile__(
87 " " __LL "%0, %1 # set_bit \n"
88 " " __INS "%0, %3, %2, 1 \n"
89 " " __SC "%0, %1 \n"
90 : "=&r" (temp), "+m" (*m)
91 : "ir" (bit), "r" (~0));
92 } while (unlikely(!temp));
93 #endif /* CONFIG_CPU_MIPSR2 */
94 } else if (kernel_uses_llsc) {
95 do {
96 __asm__ __volatile__(
97 " .set arch=r4000 \n"
98 " " __LL "%0, %1 # set_bit \n"
99 " or %0, %2 \n"
100 " " __SC "%0, %1 \n"
101 " .set mips0 \n"
102 : "=&r" (temp), "+m" (*m)
103 : "ir" (1UL << bit));
104 } while (unlikely(!temp));
105 } else
106 __mips_set_bit(nr, addr);
107 }
108
109 /*
110 * clear_bit - Clears a bit in memory
111 * @nr: Bit to clear
112 * @addr: Address to start counting from
113 *
114 * clear_bit() is atomic and may not be reordered. However, it does
115 * not contain a memory barrier, so if it is used for locking purposes,
116 * you should call smp_mb__before_atomic() and/or smp_mb__after_atomic()
117 * in order to ensure changes are visible on other processors.
118 */
119 static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
120 {
121 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
122 int bit = nr & SZLONG_MASK;
123 unsigned long temp;
124
125 if (kernel_uses_llsc && R10000_LLSC_WAR) {
126 __asm__ __volatile__(
127 " .set arch=r4000 \n"
128 "1: " __LL "%0, %1 # clear_bit \n"
129 " and %0, %2 \n"
130 " " __SC "%0, %1 \n"
131 " beqzl %0, 1b \n"
132 " .set mips0 \n"
133 : "=&r" (temp), "+m" (*m)
134 : "ir" (~(1UL << bit)));
135 #ifdef CONFIG_CPU_MIPSR2
136 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
137 do {
138 __asm__ __volatile__(
139 " " __LL "%0, %1 # clear_bit \n"
140 " " __INS "%0, $0, %2, 1 \n"
141 " " __SC "%0, %1 \n"
142 : "=&r" (temp), "+m" (*m)
143 : "ir" (bit));
144 } while (unlikely(!temp));
145 #endif /* CONFIG_CPU_MIPSR2 */
146 } else if (kernel_uses_llsc) {
147 do {
148 __asm__ __volatile__(
149 " .set arch=r4000 \n"
150 " " __LL "%0, %1 # clear_bit \n"
151 " and %0, %2 \n"
152 " " __SC "%0, %1 \n"
153 " .set mips0 \n"
154 : "=&r" (temp), "+m" (*m)
155 : "ir" (~(1UL << bit)));
156 } while (unlikely(!temp));
157 } else
158 __mips_clear_bit(nr, addr);
159 }
160
161 /*
162 * clear_bit_unlock - Clears a bit in memory
163 * @nr: Bit to clear
164 * @addr: Address to start counting from
165 *
166 * clear_bit() is atomic and implies release semantics before the memory
167 * operation. It can be used for an unlock.
168 */
169 static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
170 {
171 smp_mb__before_atomic();
172 clear_bit(nr, addr);
173 }
174
175 /*
176 * change_bit - Toggle a bit in memory
177 * @nr: Bit to change
178 * @addr: Address to start counting from
179 *
180 * change_bit() is atomic and may not be reordered.
181 * Note that @nr may be almost arbitrarily large; this function is not
182 * restricted to acting on a single-word quantity.
183 */
184 static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
185 {
186 int bit = nr & SZLONG_MASK;
187
188 if (kernel_uses_llsc && R10000_LLSC_WAR) {
189 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
190 unsigned long temp;
191
192 __asm__ __volatile__(
193 " .set arch=r4000 \n"
194 "1: " __LL "%0, %1 # change_bit \n"
195 " xor %0, %2 \n"
196 " " __SC "%0, %1 \n"
197 " beqzl %0, 1b \n"
198 " .set mips0 \n"
199 : "=&r" (temp), "+m" (*m)
200 : "ir" (1UL << bit));
201 } else if (kernel_uses_llsc) {
202 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
203 unsigned long temp;
204
205 do {
206 __asm__ __volatile__(
207 " .set arch=r4000 \n"
208 " " __LL "%0, %1 # change_bit \n"
209 " xor %0, %2 \n"
210 " " __SC "%0, %1 \n"
211 " .set mips0 \n"
212 : "=&r" (temp), "+m" (*m)
213 : "ir" (1UL << bit));
214 } while (unlikely(!temp));
215 } else
216 __mips_change_bit(nr, addr);
217 }
218
219 /*
220 * test_and_set_bit - Set a bit and return its old value
221 * @nr: Bit to set
222 * @addr: Address to count from
223 *
224 * This operation is atomic and cannot be reordered.
225 * It also implies a memory barrier.
226 */
227 static inline int test_and_set_bit(unsigned long nr,
228 volatile unsigned long *addr)
229 {
230 int bit = nr & SZLONG_MASK;
231 unsigned long res;
232
233 smp_mb__before_llsc();
234
235 if (kernel_uses_llsc && R10000_LLSC_WAR) {
236 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
237 unsigned long temp;
238
239 __asm__ __volatile__(
240 " .set arch=r4000 \n"
241 "1: " __LL "%0, %1 # test_and_set_bit \n"
242 " or %2, %0, %3 \n"
243 " " __SC "%2, %1 \n"
244 " beqzl %2, 1b \n"
245 " and %2, %0, %3 \n"
246 " .set mips0 \n"
247 : "=&r" (temp), "+m" (*m), "=&r" (res)
248 : "r" (1UL << bit)
249 : "memory");
250 } else if (kernel_uses_llsc) {
251 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
252 unsigned long temp;
253
254 do {
255 __asm__ __volatile__(
256 " .set arch=r4000 \n"
257 " " __LL "%0, %1 # test_and_set_bit \n"
258 " or %2, %0, %3 \n"
259 " " __SC "%2, %1 \n"
260 " .set mips0 \n"
261 : "=&r" (temp), "+m" (*m), "=&r" (res)
262 : "r" (1UL << bit)
263 : "memory");
264 } while (unlikely(!res));
265
266 res = temp & (1UL << bit);
267 } else
268 res = __mips_test_and_set_bit(nr, addr);
269
270 smp_llsc_mb();
271
272 return res != 0;
273 }
274
275 /*
276 * test_and_set_bit_lock - Set a bit and return its old value
277 * @nr: Bit to set
278 * @addr: Address to count from
279 *
280 * This operation is atomic and implies acquire ordering semantics
281 * after the memory operation.
282 */
283 static inline int test_and_set_bit_lock(unsigned long nr,
284 volatile unsigned long *addr)
285 {
286 int bit = nr & SZLONG_MASK;
287 unsigned long res;
288
289 if (kernel_uses_llsc && R10000_LLSC_WAR) {
290 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
291 unsigned long temp;
292
293 __asm__ __volatile__(
294 " .set arch=r4000 \n"
295 "1: " __LL "%0, %1 # test_and_set_bit \n"
296 " or %2, %0, %3 \n"
297 " " __SC "%2, %1 \n"
298 " beqzl %2, 1b \n"
299 " and %2, %0, %3 \n"
300 " .set mips0 \n"
301 : "=&r" (temp), "+m" (*m), "=&r" (res)
302 : "r" (1UL << bit)
303 : "memory");
304 } else if (kernel_uses_llsc) {
305 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
306 unsigned long temp;
307
308 do {
309 __asm__ __volatile__(
310 " .set arch=r4000 \n"
311 " " __LL "%0, %1 # test_and_set_bit \n"
312 " or %2, %0, %3 \n"
313 " " __SC "%2, %1 \n"
314 " .set mips0 \n"
315 : "=&r" (temp), "+m" (*m), "=&r" (res)
316 : "r" (1UL << bit)
317 : "memory");
318 } while (unlikely(!res));
319
320 res = temp & (1UL << bit);
321 } else
322 res = __mips_test_and_set_bit_lock(nr, addr);
323
324 smp_llsc_mb();
325
326 return res != 0;
327 }
328 /*
329 * test_and_clear_bit - Clear a bit and return its old value
330 * @nr: Bit to clear
331 * @addr: Address to count from
332 *
333 * This operation is atomic and cannot be reordered.
334 * It also implies a memory barrier.
335 */
336 static inline int test_and_clear_bit(unsigned long nr,
337 volatile unsigned long *addr)
338 {
339 int bit = nr & SZLONG_MASK;
340 unsigned long res;
341
342 smp_mb__before_llsc();
343
344 if (kernel_uses_llsc && R10000_LLSC_WAR) {
345 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
346 unsigned long temp;
347
348 __asm__ __volatile__(
349 " .set arch=r4000 \n"
350 "1: " __LL "%0, %1 # test_and_clear_bit \n"
351 " or %2, %0, %3 \n"
352 " xor %2, %3 \n"
353 " " __SC "%2, %1 \n"
354 " beqzl %2, 1b \n"
355 " and %2, %0, %3 \n"
356 " .set mips0 \n"
357 : "=&r" (temp), "+m" (*m), "=&r" (res)
358 : "r" (1UL << bit)
359 : "memory");
360 #ifdef CONFIG_CPU_MIPSR2
361 } else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
362 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
363 unsigned long temp;
364
365 do {
366 __asm__ __volatile__(
367 " " __LL "%0, %1 # test_and_clear_bit \n"
368 " " __EXT "%2, %0, %3, 1 \n"
369 " " __INS "%0, $0, %3, 1 \n"
370 " " __SC "%0, %1 \n"
371 : "=&r" (temp), "+m" (*m), "=&r" (res)
372 : "ir" (bit)
373 : "memory");
374 } while (unlikely(!temp));
375 #endif
376 } else if (kernel_uses_llsc) {
377 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
378 unsigned long temp;
379
380 do {
381 __asm__ __volatile__(
382 " .set arch=r4000 \n"
383 " " __LL "%0, %1 # test_and_clear_bit \n"
384 " or %2, %0, %3 \n"
385 " xor %2, %3 \n"
386 " " __SC "%2, %1 \n"
387 " .set mips0 \n"
388 : "=&r" (temp), "+m" (*m), "=&r" (res)
389 : "r" (1UL << bit)
390 : "memory");
391 } while (unlikely(!res));
392
393 res = temp & (1UL << bit);
394 } else
395 res = __mips_test_and_clear_bit(nr, addr);
396
397 smp_llsc_mb();
398
399 return res != 0;
400 }
401
402 /*
403 * test_and_change_bit - Change a bit and return its old value
404 * @nr: Bit to change
405 * @addr: Address to count from
406 *
407 * This operation is atomic and cannot be reordered.
408 * It also implies a memory barrier.
409 */
410 static inline int test_and_change_bit(unsigned long nr,
411 volatile unsigned long *addr)
412 {
413 int bit = nr & SZLONG_MASK;
414 unsigned long res;
415
416 smp_mb__before_llsc();
417
418 if (kernel_uses_llsc && R10000_LLSC_WAR) {
419 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
420 unsigned long temp;
421
422 __asm__ __volatile__(
423 " .set arch=r4000 \n"
424 "1: " __LL "%0, %1 # test_and_change_bit \n"
425 " xor %2, %0, %3 \n"
426 " " __SC "%2, %1 \n"
427 " beqzl %2, 1b \n"
428 " and %2, %0, %3 \n"
429 " .set mips0 \n"
430 : "=&r" (temp), "+m" (*m), "=&r" (res)
431 : "r" (1UL << bit)
432 : "memory");
433 } else if (kernel_uses_llsc) {
434 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
435 unsigned long temp;
436
437 do {
438 __asm__ __volatile__(
439 " .set arch=r4000 \n"
440 " " __LL "%0, %1 # test_and_change_bit \n"
441 " xor %2, %0, %3 \n"
442 " " __SC "\t%2, %1 \n"
443 " .set mips0 \n"
444 : "=&r" (temp), "+m" (*m), "=&r" (res)
445 : "r" (1UL << bit)
446 : "memory");
447 } while (unlikely(!res));
448
449 res = temp & (1UL << bit);
450 } else
451 res = __mips_test_and_change_bit(nr, addr);
452
453 smp_llsc_mb();
454
455 return res != 0;
456 }
457
458 #include <asm-generic/bitops/non-atomic.h>
459
460 /*
461 * __clear_bit_unlock - Clears a bit in memory
462 * @nr: Bit to clear
463 * @addr: Address to start counting from
464 *
465 * __clear_bit() is non-atomic and implies release semantics before the memory
466 * operation. It can be used for an unlock if no other CPUs can concurrently
467 * modify other bits in the word.
468 */
469 static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
470 {
471 smp_mb();
472 __clear_bit(nr, addr);
473 }
474
475 /*
476 * Return the bit position (0..63) of the most significant 1 bit in a word
477 * Returns -1 if no 1 bit exists
478 */
479 static inline unsigned long __fls(unsigned long word)
480 {
481 int num;
482
483 if (BITS_PER_LONG == 32 &&
484 __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
485 __asm__(
486 " .set push \n"
487 " .set mips32 \n"
488 " clz %0, %1 \n"
489 " .set pop \n"
490 : "=r" (num)
491 : "r" (word));
492
493 return 31 - num;
494 }
495
496 if (BITS_PER_LONG == 64 &&
497 __builtin_constant_p(cpu_has_mips64) && cpu_has_mips64) {
498 __asm__(
499 " .set push \n"
500 " .set mips64 \n"
501 " dclz %0, %1 \n"
502 " .set pop \n"
503 : "=r" (num)
504 : "r" (word));
505
506 return 63 - num;
507 }
508
509 num = BITS_PER_LONG - 1;
510
511 #if BITS_PER_LONG == 64
512 if (!(word & (~0ul << 32))) {
513 num -= 32;
514 word <<= 32;
515 }
516 #endif
517 if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
518 num -= 16;
519 word <<= 16;
520 }
521 if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
522 num -= 8;
523 word <<= 8;
524 }
525 if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
526 num -= 4;
527 word <<= 4;
528 }
529 if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
530 num -= 2;
531 word <<= 2;
532 }
533 if (!(word & (~0ul << (BITS_PER_LONG-1))))
534 num -= 1;
535 return num;
536 }
537
538 /*
539 * __ffs - find first bit in word.
540 * @word: The word to search
541 *
542 * Returns 0..SZLONG-1
543 * Undefined if no bit exists, so code should check against 0 first.
544 */
545 static inline unsigned long __ffs(unsigned long word)
546 {
547 return __fls(word & -word);
548 }
549
550 /*
551 * fls - find last bit set.
552 * @word: The word to search
553 *
554 * This is defined the same way as ffs.
555 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
556 */
557 static inline int fls(int x)
558 {
559 int r;
560
561 if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
562 __asm__(
563 " .set push \n"
564 " .set mips32 \n"
565 " clz %0, %1 \n"
566 " .set pop \n"
567 : "=r" (x)
568 : "r" (x));
569
570 return 32 - x;
571 }
572
573 r = 32;
574 if (!x)
575 return 0;
576 if (!(x & 0xffff0000u)) {
577 x <<= 16;
578 r -= 16;
579 }
580 if (!(x & 0xff000000u)) {
581 x <<= 8;
582 r -= 8;
583 }
584 if (!(x & 0xf0000000u)) {
585 x <<= 4;
586 r -= 4;
587 }
588 if (!(x & 0xc0000000u)) {
589 x <<= 2;
590 r -= 2;
591 }
592 if (!(x & 0x80000000u)) {
593 x <<= 1;
594 r -= 1;
595 }
596 return r;
597 }
598
599 #include <asm-generic/bitops/fls64.h>
600
601 /*
602 * ffs - find first bit set.
603 * @word: The word to search
604 *
605 * This is defined the same way as
606 * the libc and compiler builtin ffs routines, therefore
607 * differs in spirit from the above ffz (man ffs).
608 */
609 static inline int ffs(int word)
610 {
611 if (!word)
612 return 0;
613
614 return fls(word & -word);
615 }
616
617 #include <asm-generic/bitops/ffz.h>
618 #include <asm-generic/bitops/find.h>
619
620 #ifdef __KERNEL__
621
622 #include <asm-generic/bitops/sched.h>
623
624 #include <asm/arch_hweight.h>
625 #include <asm-generic/bitops/const_hweight.h>
626
627 #include <asm-generic/bitops/le.h>
628 #include <asm-generic/bitops/ext2-atomic.h>
629
630 #endif /* __KERNEL__ */
631
632 #endif /* _ASM_BITOPS_H */
This page took 0.055532 seconds and 5 git commands to generate.