diff options
Diffstat (limited to 'include/asm-frv/system.h')
-rw-r--r-- | include/asm-frv/system.h | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h index 1166899317d7..be303b3eef40 100644 --- a/include/asm-frv/system.h +++ b/include/asm-frv/system.h | |||
@@ -13,7 +13,6 @@ | |||
13 | #define _ASM_SYSTEM_H | 13 | #define _ASM_SYSTEM_H |
14 | 14 | ||
15 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
16 | #include <asm/atomic.h> | ||
17 | 16 | ||
18 | struct thread_struct; | 17 | struct thread_struct; |
19 | 18 | ||
@@ -197,4 +196,73 @@ extern void free_initmem(void); | |||
197 | 196 | ||
198 | #define arch_align_stack(x) (x) | 197 | #define arch_align_stack(x) (x) |
199 | 198 | ||
199 | /*****************************************************************************/ | ||
200 | /* | ||
201 | * compare and conditionally exchange value with memory | ||
202 | * - if (*ptr == test) then orig = *ptr; *ptr = test; | ||
203 | * - if (*ptr != test) then orig = *ptr; | ||
204 | */ | ||
205 | #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS | ||
206 | |||
207 | #define cmpxchg(ptr, test, new) \ | ||
208 | ({ \ | ||
209 | __typeof__(ptr) __xg_ptr = (ptr); \ | ||
210 | __typeof__(*(ptr)) __xg_orig, __xg_tmp; \ | ||
211 | __typeof__(*(ptr)) __xg_test = (test); \ | ||
212 | __typeof__(*(ptr)) __xg_new = (new); \ | ||
213 | \ | ||
214 | switch (sizeof(__xg_orig)) { \ | ||
215 | case 4: \ | ||
216 | asm volatile( \ | ||
217 | "0: \n" \ | ||
218 | " orcc gr0,gr0,gr0,icc3 \n" \ | ||
219 | " ckeq icc3,cc7 \n" \ | ||
220 | " ld.p %M0,%1 \n" \ | ||
221 | " orcr cc7,cc7,cc3 \n" \ | ||
222 | " sub%I4cc %1,%4,%2,icc0 \n" \ | ||
223 | " bne icc0,#0,1f \n" \ | ||
224 | " cst.p %3,%M0 ,cc3,#1 \n" \ | ||
225 | " corcc gr29,gr29,gr0 ,cc3,#1 \n" \ | ||
226 | " beq icc3,#0,0b \n" \ | ||
227 | "1: \n" \ | ||
228 | : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \ | ||
229 | : "r"(__xg_new), "NPr"(__xg_test) \ | ||
230 | : "memory", "cc7", "cc3", "icc3", "icc0" \ | ||
231 | ); \ | ||
232 | break; \ | ||
233 | \ | ||
234 | default: \ | ||
235 | __xg_orig = 0; \ | ||
236 | asm volatile("break"); \ | ||
237 | break; \ | ||
238 | } \ | ||
239 | \ | ||
240 | __xg_orig; \ | ||
241 | }) | ||
242 | |||
243 | #else | ||
244 | |||
245 | extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new); | ||
246 | |||
247 | #define cmpxchg(ptr, test, new) \ | ||
248 | ({ \ | ||
249 | __typeof__(ptr) __xg_ptr = (ptr); \ | ||
250 | __typeof__(*(ptr)) __xg_orig; \ | ||
251 | __typeof__(*(ptr)) __xg_test = (test); \ | ||
252 | __typeof__(*(ptr)) __xg_new = (new); \ | ||
253 | \ | ||
254 | switch (sizeof(__xg_orig)) { \ | ||
255 | case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break; \ | ||
256 | default: \ | ||
257 | __xg_orig = 0; \ | ||
258 | asm volatile("break"); \ | ||
259 | break; \ | ||
260 | } \ | ||
261 | \ | ||
262 | __xg_orig; \ | ||
263 | }) | ||
264 | |||
265 | #endif | ||
266 | |||
267 | |||
200 | #endif /* _ASM_SYSTEM_H */ | 268 | #endif /* _ASM_SYSTEM_H */ |