Merge git://git.denx.de/u-boot
[oweals/u-boot.git] / arch / sh / include / asm / bitops.h
1 #ifndef __ASM_SH_BITOPS_H
2 #define __ASM_SH_BITOPS_H
3
4 #include <asm-generic/bitops/fls.h>
5 #include <asm-generic/bitops/__fls.h>
6 #include <asm-generic/bitops/fls64.h>
7 #include <asm-generic/bitops/__ffs.h>
8
9 #ifdef __KERNEL__
10 #include <asm/irqflags.h>
11 /* For __swab32 */
12 #include <asm/byteorder.h>
13
14 static inline void set_bit(int nr, volatile void * addr)
15 {
16         int     mask;
17         volatile unsigned int *a = addr;
18         unsigned long flags;
19
20         a += nr >> 5;
21         mask = 1 << (nr & 0x1f);
22         local_irq_save(flags);
23         *a |= mask;
24         local_irq_restore(flags);
25 }
26
27 /*
28  * clear_bit() doesn't provide any barrier for the compiler.
29  */
30 #define smp_mb__before_clear_bit()      barrier()
31 #define smp_mb__after_clear_bit()       barrier()
32 static inline void clear_bit(int nr, volatile void * addr)
33 {
34         int     mask;
35         volatile unsigned int *a = addr;
36         unsigned long flags;
37
38         a += nr >> 5;
39         mask = 1 << (nr & 0x1f);
40         local_irq_save(flags);
41         *a &= ~mask;
42         local_irq_restore(flags);
43 }
44
45 static inline void change_bit(int nr, volatile void * addr)
46 {
47         int     mask;
48         volatile unsigned int *a = addr;
49         unsigned long flags;
50
51         a += nr >> 5;
52         mask = 1 << (nr & 0x1f);
53         local_irq_save(flags);
54         *a ^= mask;
55         local_irq_restore(flags);
56 }
57
58 static inline int test_and_set_bit(int nr, volatile void * addr)
59 {
60         int     mask, retval;
61         volatile unsigned int *a = addr;
62         unsigned long flags;
63
64         a += nr >> 5;
65         mask = 1 << (nr & 0x1f);
66         local_irq_save(flags);
67         retval = (mask & *a) != 0;
68         *a |= mask;
69         local_irq_restore(flags);
70
71         return retval;
72 }
73
74 static inline int test_and_clear_bit(int nr, volatile void * addr)
75 {
76         int     mask, retval;
77         volatile unsigned int *a = addr;
78         unsigned long flags;
79
80         a += nr >> 5;
81         mask = 1 << (nr & 0x1f);
82         local_irq_save(flags);
83         retval = (mask & *a) != 0;
84         *a &= ~mask;
85         local_irq_restore(flags);
86
87         return retval;
88 }
89
90 static inline int test_and_change_bit(int nr, volatile void * addr)
91 {
92         int     mask, retval;
93         volatile unsigned int *a = addr;
94         unsigned long flags;
95
96         a += nr >> 5;
97         mask = 1 << (nr & 0x1f);
98         local_irq_save(flags);
99         retval = (mask & *a) != 0;
100         *a ^= mask;
101         local_irq_restore(flags);
102
103         return retval;
104 }
105
106 static inline unsigned long ffz(unsigned long word)
107 {
108         unsigned long result;
109
110         __asm__("1:\n\t"
111                 "shlr   %1\n\t"
112                 "bt/s   1b\n\t"
113                 " add   #1, %0"
114                 : "=r" (result), "=r" (word)
115                 : "0" (~0L), "1" (word)
116                 : "t");
117         return result;
118 }
119
120 /**
121  * ffs - find first bit in word.
122  * @word: The word to search
123  *
124  * Undefined if no bit exists, so code should check against 0 first.
125  */
126 static inline int ffs (int x)
127 {
128         int r = 1;
129
130         if (!x)
131                 return 0;
132         if (!(x & 0xffff)) {
133                 x >>= 16;
134                 r += 16;
135         }
136         if (!(x & 0xff)) {
137                 x >>= 8;
138                 r += 8;
139         }
140         if (!(x & 0xf)) {
141                 x >>= 4;
142                 r += 4;
143         }
144         if (!(x & 3)) {
145                 x >>= 2;
146                 r += 2;
147         }
148         if (!(x & 1)) {
149                 x >>= 1;
150                 r += 1;
151         }
152         return r;
153 }
154 #define PLATFORM_FFS
155
156 #endif /* __KERNEL__ */
157
158 #endif /* __ASM_SH_BITOPS_H */