diff options
author | Mathieu Desnoyers <compudj@krystal.dyndns.org> | 2007-05-08 03:34:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:20 -0400 |
commit | 2856f5e31c1413bf6e4f1371e07e17078a5fee5e (patch) | |
tree | 587dfe584f0913813d0cf2414a9378618143db15 /include/asm-frv/system.h | |
parent | 79d365a306c3af53d8a732fec79b76c0b285d816 (diff) |
atomic.h: atomic_add_unless as inline. Remove system.h atomic.h circular dependency
atomic_add_unless as inline. Remove system.h atomic.h circular dependency.
I agree (with Andi Kleen) this typeof is not needed and more error
prone. All the original atomic.h code that uses cmpxchg (which includes
the atomic_add_unless) uses defines instead of inline functions,
probably to circumvent a circular dependency between system.h and
atomic.h on powerpc (which my patch addresses). Therefore, it makes
sense to use inline functions that will provide type checking.
atomic_add_unless as inline. Remove system.h atomic.h circular dependency.
Digging into the FRV architecture shows me that it is also affected by
such a circular dependency. Here is the diff applying this against the
rest of my atomic.h patches.
It applies over the atomic.h standardization patches.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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 */ |