diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2012-11-10 20:47:25 -0500 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2012-12-19 00:10:22 -0500 |
commit | e5a9f6adba79ce2732330fc6d045e98959af8962 (patch) | |
tree | c808e6e5d68d93c4635401c06584c4b9ddc0b1e6 /arch/xtensa/include | |
parent | 219b1e4c61c108731bb665962231b1fa057f6c71 (diff) |
xtensa: add s32c1i-based bitops implementations
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'arch/xtensa/include')
-rw-r--r-- | arch/xtensa/include/asm/bitops.h | 127 |
1 files changed, 126 insertions, 1 deletions
diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h index 5270197ddd36..84afe58d5d37 100644 --- a/arch/xtensa/include/asm/bitops.h +++ b/arch/xtensa/include/asm/bitops.h | |||
@@ -29,7 +29,6 @@ | |||
29 | #define smp_mb__before_clear_bit() barrier() | 29 | #define smp_mb__before_clear_bit() barrier() |
30 | #define smp_mb__after_clear_bit() barrier() | 30 | #define smp_mb__after_clear_bit() barrier() |
31 | 31 | ||
32 | #include <asm-generic/bitops/atomic.h> | ||
33 | #include <asm-generic/bitops/non-atomic.h> | 32 | #include <asm-generic/bitops/non-atomic.h> |
34 | 33 | ||
35 | #if XCHAL_HAVE_NSA | 34 | #if XCHAL_HAVE_NSA |
@@ -104,6 +103,132 @@ static inline unsigned long __fls(unsigned long word) | |||
104 | #endif | 103 | #endif |
105 | 104 | ||
106 | #include <asm-generic/bitops/fls64.h> | 105 | #include <asm-generic/bitops/fls64.h> |
106 | |||
107 | #if XCHAL_HAVE_S32C1I | ||
108 | |||
109 | static inline void set_bit(unsigned int bit, volatile unsigned long *p) | ||
110 | { | ||
111 | unsigned long tmp, value; | ||
112 | unsigned long mask = 1UL << (bit & 31); | ||
113 | |||
114 | p += bit >> 5; | ||
115 | |||
116 | __asm__ __volatile__( | ||
117 | "1: l32i %1, %3, 0\n" | ||
118 | " wsr %1, scompare1\n" | ||
119 | " or %0, %1, %2\n" | ||
120 | " s32c1i %0, %3, 0\n" | ||
121 | " bne %0, %1, 1b\n" | ||
122 | : "=&a" (tmp), "=&a" (value) | ||
123 | : "a" (mask), "a" (p) | ||
124 | : "memory"); | ||
125 | } | ||
126 | |||
127 | static inline void clear_bit(unsigned int bit, volatile unsigned long *p) | ||
128 | { | ||
129 | unsigned long tmp, value; | ||
130 | unsigned long mask = 1UL << (bit & 31); | ||
131 | |||
132 | p += bit >> 5; | ||
133 | |||
134 | __asm__ __volatile__( | ||
135 | "1: l32i %1, %3, 0\n" | ||
136 | " wsr %1, scompare1\n" | ||
137 | " and %0, %1, %2\n" | ||
138 | " s32c1i %0, %3, 0\n" | ||
139 | " bne %0, %1, 1b\n" | ||
140 | : "=&a" (tmp), "=&a" (value) | ||
141 | : "a" (~mask), "a" (p) | ||
142 | : "memory"); | ||
143 | } | ||
144 | |||
145 | static inline void change_bit(unsigned int bit, volatile unsigned long *p) | ||
146 | { | ||
147 | unsigned long tmp, value; | ||
148 | unsigned long mask = 1UL << (bit & 31); | ||
149 | |||
150 | p += bit >> 5; | ||
151 | |||
152 | __asm__ __volatile__( | ||
153 | "1: l32i %1, %3, 0\n" | ||
154 | " wsr %1, scompare1\n" | ||
155 | " xor %0, %1, %2\n" | ||
156 | " s32c1i %0, %3, 0\n" | ||
157 | " bne %0, %1, 1b\n" | ||
158 | : "=&a" (tmp), "=&a" (value) | ||
159 | : "a" (mask), "a" (p) | ||
160 | : "memory"); | ||
161 | } | ||
162 | |||
163 | static inline int | ||
164 | test_and_set_bit(unsigned int bit, volatile unsigned long *p) | ||
165 | { | ||
166 | unsigned long tmp, value; | ||
167 | unsigned long mask = 1UL << (bit & 31); | ||
168 | |||
169 | p += bit >> 5; | ||
170 | |||
171 | __asm__ __volatile__( | ||
172 | "1: l32i %1, %3, 0\n" | ||
173 | " wsr %1, scompare1\n" | ||
174 | " or %0, %1, %2\n" | ||
175 | " s32c1i %0, %3, 0\n" | ||
176 | " bne %0, %1, 1b\n" | ||
177 | : "=&a" (tmp), "=&a" (value) | ||
178 | : "a" (mask), "a" (p) | ||
179 | : "memory"); | ||
180 | |||
181 | return tmp & mask; | ||
182 | } | ||
183 | |||
184 | static inline int | ||
185 | test_and_clear_bit(unsigned int bit, volatile unsigned long *p) | ||
186 | { | ||
187 | unsigned long tmp, value; | ||
188 | unsigned long mask = 1UL << (bit & 31); | ||
189 | |||
190 | p += bit >> 5; | ||
191 | |||
192 | __asm__ __volatile__( | ||
193 | "1: l32i %1, %3, 0\n" | ||
194 | " wsr %1, scompare1\n" | ||
195 | " and %0, %1, %2\n" | ||
196 | " s32c1i %0, %3, 0\n" | ||
197 | " bne %0, %1, 1b\n" | ||
198 | : "=&a" (tmp), "=&a" (value) | ||
199 | : "a" (~mask), "a" (p) | ||
200 | : "memory"); | ||
201 | |||
202 | return tmp & mask; | ||
203 | } | ||
204 | |||
205 | static inline int | ||
206 | test_and_change_bit(unsigned int bit, volatile unsigned long *p) | ||
207 | { | ||
208 | unsigned long tmp, value; | ||
209 | unsigned long mask = 1UL << (bit & 31); | ||
210 | |||
211 | p += bit >> 5; | ||
212 | |||
213 | __asm__ __volatile__( | ||
214 | "1: l32i %1, %3, 0\n" | ||
215 | " wsr %1, scompare1\n" | ||
216 | " xor %0, %1, %2\n" | ||
217 | " s32c1i %0, %3, 0\n" | ||
218 | " bne %0, %1, 1b\n" | ||
219 | : "=&a" (tmp), "=&a" (value) | ||
220 | : "a" (mask), "a" (p) | ||
221 | : "memory"); | ||
222 | |||
223 | return tmp & mask; | ||
224 | } | ||
225 | |||
226 | #else | ||
227 | |||
228 | #include <asm-generic/bitops/atomic.h> | ||
229 | |||
230 | #endif /* XCHAL_HAVE_S32C1I */ | ||
231 | |||
107 | #include <asm-generic/bitops/find.h> | 232 | #include <asm-generic/bitops/find.h> |
108 | #include <asm-generic/bitops/le.h> | 233 | #include <asm-generic/bitops/le.h> |
109 | 234 | ||