Skip to content

Commit

Permalink
sh: Add a simple cmpxchg().
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tom Rini authored and Paul Mundt committed Sep 27, 2006
1 parent 0c91c1a commit e4e3b5c
Showing 1 changed file with 40 additions and 0 deletions.
40 changes: 40 additions & 0 deletions include/asm-sh/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Copyright (C) 2002 Paul Mundt
*/

#include <asm/types.h>

/*
* switch_to() should switch tasks to task nr n, first
Expand Down Expand Up @@ -260,6 +261,45 @@ static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int
return x;
}

static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
unsigned long new)
{
__u32 retval;
unsigned long flags;

local_irq_save(flags);
retval = *m;
if (retval == old)
*m = new;
local_irq_restore(flags); /* implies memory barrier */
return retval;
}

/* This function doesn't exist, so you'll get a linker error
* if something tries to do an invalid cmpxchg(). */
extern void __cmpxchg_called_with_bad_pointer(void);

#define __HAVE_ARCH_CMPXCHG 1

static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
unsigned long new, int size)
{
switch (size) {
case 4:
return __cmpxchg_u32(ptr, old, new);
}
__cmpxchg_called_with_bad_pointer();
return old;
}

#define cmpxchg(ptr,o,n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
__typeof__(*(ptr)) _n_ = (n); \
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
(unsigned long)_n_, sizeof(*(ptr))); \
})

/* XXX
* disable hlt during certain critical i/o operations
*/
Expand Down

0 comments on commit e4e3b5c

Please sign in to comment.