aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Rini <trini@kernel.crashing.org>2006-09-26 22:28:20 -0400
committerPaul Mundt <lethal@linux-sh.org>2006-09-26 22:28:20 -0400
commite4e3b5ccd77226c9c4dbb0737106b868dfc182d9 (patch)
tree8401beac23ca03f79c52094ea10139658661769d
parent0c91c1a7012911e4b0180a1c1ae258e2b706f987 (diff)
sh: Add a simple cmpxchg().
We didn't have one of these before, a simple implementation borrowed from MIPS as well as the __HAVE_ARCH_CMPXCHG bits. Signed-off-by: Tom Rini <trini@kernel.crashing.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--include/asm-sh/system.h40
1 files changed, 40 insertions, 0 deletions
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index ad35ad4958f4..e89728d405d8 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -6,6 +6,7 @@
6 * Copyright (C) 2002 Paul Mundt 6 * Copyright (C) 2002 Paul Mundt
7 */ 7 */
8 8
9#include <asm/types.h>
9 10
10/* 11/*
11 * switch_to() should switch tasks to task nr n, first 12 * switch_to() should switch tasks to task nr n, first
@@ -260,6 +261,45 @@ static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int
260 return x; 261 return x;
261} 262}
262 263
264static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
265 unsigned long new)
266{
267 __u32 retval;
268 unsigned long flags;
269
270 local_irq_save(flags);
271 retval = *m;
272 if (retval == old)
273 *m = new;
274 local_irq_restore(flags); /* implies memory barrier */
275 return retval;
276}
277
278/* This function doesn't exist, so you'll get a linker error
279 * if something tries to do an invalid cmpxchg(). */
280extern void __cmpxchg_called_with_bad_pointer(void);
281
282#define __HAVE_ARCH_CMPXCHG 1
283
284static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
285 unsigned long new, int size)
286{
287 switch (size) {
288 case 4:
289 return __cmpxchg_u32(ptr, old, new);
290 }
291 __cmpxchg_called_with_bad_pointer();
292 return old;
293}
294
295#define cmpxchg(ptr,o,n) \
296 ({ \
297 __typeof__(*(ptr)) _o_ = (o); \
298 __typeof__(*(ptr)) _n_ = (n); \
299 (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
300 (unsigned long)_n_, sizeof(*(ptr))); \
301 })
302
263/* XXX 303/* XXX
264 * disable hlt during certain critical i/o operations 304 * disable hlt during certain critical i/o operations
265 */ 305 */