Commit 482bfe2c authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Linus Torvalds

[PATCH] m68k: atomic op fixups

M68k: Add missing atomic operations (from Roman Zippel and me) and replace
`__inline__' by `inline' while we're at it.
Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8f28219b
#ifndef __ARCH_M68K_ATOMIC__ #ifndef __ARCH_M68K_ATOMIC__
#define __ARCH_M68K_ATOMIC__ #define __ARCH_M68K_ATOMIC__
#include <asm/system.h> /* local_irq_XXX() */
/* /*
* Atomic operations that C can't guarantee us. Useful for * Atomic operations that C can't guarantee us. Useful for
* resource counting etc.. * resource counting etc..
...@@ -16,39 +18,121 @@ typedef struct { int counter; } atomic_t; ...@@ -16,39 +18,121 @@ typedef struct { int counter; } atomic_t;
#define atomic_read(v) ((v)->counter) #define atomic_read(v) ((v)->counter)
#define atomic_set(v, i) (((v)->counter) = i) #define atomic_set(v, i) (((v)->counter) = i)
static __inline__ void atomic_add(int i, atomic_t *v) static inline void atomic_add(int i, atomic_t *v)
{ {
__asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i)); __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i));
} }
static __inline__ void atomic_sub(int i, atomic_t *v) static inline void atomic_sub(int i, atomic_t *v)
{ {
__asm__ __volatile__("subl %1,%0" : "+m" (*v) : "id" (i)); __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "id" (i));
} }
static __inline__ void atomic_inc(atomic_t *v) static inline void atomic_inc(atomic_t *v)
{ {
__asm__ __volatile__("addql #1,%0" : "+m" (*v)); __asm__ __volatile__("addql #1,%0" : "+m" (*v));
} }
static __inline__ void atomic_dec(atomic_t *v) static inline void atomic_dec(atomic_t *v)
{ {
__asm__ __volatile__("subql #1,%0" : "+m" (*v)); __asm__ __volatile__("subql #1,%0" : "+m" (*v));
} }
static __inline__ int atomic_dec_and_test(atomic_t *v) static inline int atomic_dec_and_test(atomic_t *v)
{ {
char c; char c;
__asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v)); __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v));
return c != 0; return c != 0;
} }
static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v) static inline int atomic_inc_and_test(atomic_t *v)
{
char c;
__asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v));
return c != 0;
}
#ifdef CONFIG_RMW_INSNS
static inline int atomic_add_return(int i, atomic_t *v)
{
int t, tmp;
__asm__ __volatile__(
"1: movel %2,%1\n"
" addl %3,%1\n"
" casl %2,%1,%0\n"
" jne 1b"
: "+m" (*v), "=&d" (t), "=&d" (tmp)
: "g" (i), "2" (atomic_read(v)));
return t;
}
static inline int atomic_sub_return(int i, atomic_t *v)
{
int t, tmp;
__asm__ __volatile__(
"1: movel %2,%1\n"
" subl %3,%1\n"
" casl %2,%1,%0\n"
" jne 1b"
: "+m" (*v), "=&d" (t), "=&d" (tmp)
: "g" (i), "2" (atomic_read(v)));
return t;
}
#else /* !CONFIG_RMW_INSNS */
static inline int atomic_add_return(int i, atomic_t * v)
{
unsigned long flags;
int t;
local_irq_save(flags);
t = atomic_read(v);
t += i;
atomic_set(v, t);
local_irq_restore(flags);
return t;
}
static inline int atomic_sub_return(int i, atomic_t * v)
{
unsigned long flags;
int t;
local_irq_save(flags);
t = atomic_read(v);
t -= i;
atomic_set(v, t);
local_irq_restore(flags);
return t;
}
#endif /* !CONFIG_RMW_INSNS */
#define atomic_dec_return(v) atomic_sub_return(1, (v))
#define atomic_inc_return(v) atomic_add_return(1, (v))
static inline int atomic_sub_and_test(int i, atomic_t *v)
{
char c;
__asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i));
return c != 0;
}
static inline int atomic_add_negative(int i, atomic_t *v)
{
char c;
__asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i));
return c != 0;
}
static inline void atomic_clear_mask(unsigned long mask, unsigned long *v)
{ {
__asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask))); __asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask)));
} }
static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v) static inline void atomic_set_mask(unsigned long mask, unsigned long *v)
{ {
__asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask)); __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment