1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef _XTENSA_BITOPS_H
14#define _XTENSA_BITOPS_H
15
16#ifdef __KERNEL__
17
18#ifndef _LINUX_BITOPS_H
19#error only <linux/bitops.h> can be included directly
20#endif
21
22#include <asm/processor.h>
23#include <asm/byteorder.h>
24
25#define smp_mb__before_clear_bit() smp_mb()
26#define smp_mb__after_clear_bit() smp_mb()
27
28#include <asm-generic/bitops/non-atomic.h>
29
30#if XCHAL_HAVE_NSA
31
32static inline unsigned long __cntlz (unsigned long x)
33{
34 int lz;
35 asm ("nsau %0, %1" : "=r" (lz) : "r" (x));
36 return lz;
37}
38
39
40
41
42
43
44static inline int ffz(unsigned long x)
45{
46 return 31 - __cntlz(~x & -~x);
47}
48
49
50
51
52
53static inline int __ffs(unsigned long x)
54{
55 return 31 - __cntlz(x & -x);
56}
57
58
59
60
61
62
63
64static inline int ffs(unsigned long x)
65{
66 return 32 - __cntlz(x & -x);
67}
68
69
70
71
72
73
74static inline int fls (unsigned int x)
75{
76 return 32 - __cntlz(x);
77}
78
79
80
81
82
83
84
85static inline unsigned long __fls(unsigned long word)
86{
87 return 31 - __cntlz(word);
88}
89#else
90
91
92
93# include <asm-generic/bitops/ffs.h>
94# include <asm-generic/bitops/__ffs.h>
95# include <asm-generic/bitops/ffz.h>
96# include <asm-generic/bitops/fls.h>
97# include <asm-generic/bitops/__fls.h>
98
99#endif
100
101#include <asm-generic/bitops/fls64.h>
102
103#if XCHAL_HAVE_S32C1I
104
105static inline void set_bit(unsigned int bit, volatile unsigned long *p)
106{
107 unsigned long tmp, value;
108 unsigned long mask = 1UL << (bit & 31);
109
110 p += bit >> 5;
111
112 __asm__ __volatile__(
113 "1: l32i %1, %3, 0\n"
114 " wsr %1, scompare1\n"
115 " or %0, %1, %2\n"
116 " s32c1i %0, %3, 0\n"
117 " bne %0, %1, 1b\n"
118 : "=&a" (tmp), "=&a" (value)
119 : "a" (mask), "a" (p)
120 : "memory");
121}
122
123static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
124{
125 unsigned long tmp, value;
126 unsigned long mask = 1UL << (bit & 31);
127
128 p += bit >> 5;
129
130 __asm__ __volatile__(
131 "1: l32i %1, %3, 0\n"
132 " wsr %1, scompare1\n"
133 " and %0, %1, %2\n"
134 " s32c1i %0, %3, 0\n"
135 " bne %0, %1, 1b\n"
136 : "=&a" (tmp), "=&a" (value)
137 : "a" (~mask), "a" (p)
138 : "memory");
139}
140
141static inline void change_bit(unsigned int bit, volatile unsigned long *p)
142{
143 unsigned long tmp, value;
144 unsigned long mask = 1UL << (bit & 31);
145
146 p += bit >> 5;
147
148 __asm__ __volatile__(
149 "1: l32i %1, %3, 0\n"
150 " wsr %1, scompare1\n"
151 " xor %0, %1, %2\n"
152 " s32c1i %0, %3, 0\n"
153 " bne %0, %1, 1b\n"
154 : "=&a" (tmp), "=&a" (value)
155 : "a" (mask), "a" (p)
156 : "memory");
157}
158
159static inline int
160test_and_set_bit(unsigned int bit, volatile unsigned long *p)
161{
162 unsigned long tmp, value;
163 unsigned long mask = 1UL << (bit & 31);
164
165 p += bit >> 5;
166
167 __asm__ __volatile__(
168 "1: l32i %1, %3, 0\n"
169 " wsr %1, scompare1\n"
170 " or %0, %1, %2\n"
171 " s32c1i %0, %3, 0\n"
172 " bne %0, %1, 1b\n"
173 : "=&a" (tmp), "=&a" (value)
174 : "a" (mask), "a" (p)
175 : "memory");
176
177 return tmp & mask;
178}
179
180static inline int
181test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
182{
183 unsigned long tmp, value;
184 unsigned long mask = 1UL << (bit & 31);
185
186 p += bit >> 5;
187
188 __asm__ __volatile__(
189 "1: l32i %1, %3, 0\n"
190 " wsr %1, scompare1\n"
191 " and %0, %1, %2\n"
192 " s32c1i %0, %3, 0\n"
193 " bne %0, %1, 1b\n"
194 : "=&a" (tmp), "=&a" (value)
195 : "a" (~mask), "a" (p)
196 : "memory");
197
198 return tmp & mask;
199}
200
201static inline int
202test_and_change_bit(unsigned int bit, volatile unsigned long *p)
203{
204 unsigned long tmp, value;
205 unsigned long mask = 1UL << (bit & 31);
206
207 p += bit >> 5;
208
209 __asm__ __volatile__(
210 "1: l32i %1, %3, 0\n"
211 " wsr %1, scompare1\n"
212 " xor %0, %1, %2\n"
213 " s32c1i %0, %3, 0\n"
214 " bne %0, %1, 1b\n"
215 : "=&a" (tmp), "=&a" (value)
216 : "a" (mask), "a" (p)
217 : "memory");
218
219 return tmp & mask;
220}
221
222#else
223
224#include <asm-generic/bitops/atomic.h>
225
226#endif
227
228#include <asm-generic/bitops/find.h>
229#include <asm-generic/bitops/le.h>
230
231#include <asm-generic/bitops/ext2-atomic-setbit.h>
232
233#include <asm-generic/bitops/hweight.h>
234#include <asm-generic/bitops/lock.h>
235#include <asm-generic/bitops/sched.h>
236
237#endif
238
239#endif
240