diff options
Diffstat (limited to 'arch/powerpc/include/asm/atomic.h')
| -rw-r--r-- | arch/powerpc/include/asm/atomic.h | 95 | 
1 files changed, 95 insertions, 0 deletions
| diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h new file mode 100644 index 000000000..23f22df1b --- /dev/null +++ b/arch/powerpc/include/asm/atomic.h @@ -0,0 +1,95 @@ +/* + * PowerPC atomic operations + */ + +#ifndef _ASM_PPC_ATOMIC_H_ +#define _ASM_PPC_ATOMIC_H_ + +#include <linux/config.h> + +#ifdef CONFIG_SMP +typedef struct { volatile int counter; } atomic_t; +#else +typedef struct { int counter; } atomic_t; +#endif + +#define ATOMIC_INIT(i)	{ (i) } + +#define atomic_read(v)		((v)->counter) +#define atomic_set(v,i)		(((v)->counter) = (i)) + +extern void atomic_clear_mask(unsigned long mask, unsigned long *addr); +extern void atomic_set_mask(unsigned long mask, unsigned long *addr); + +extern __inline__ int atomic_add_return(int a, atomic_t *v) +{ +	int t; + +	__asm__ __volatile__("\n\ +1:	lwarx	%0,0,%3\n\ +	add	%0,%2,%0\n\ +	stwcx.	%0,0,%3\n\ +	bne-	1b" +	: "=&r" (t), "=m" (*v) +	: "r" (a), "r" (v), "m" (*v) +	: "cc"); + +	return t; +} + +extern __inline__ int atomic_sub_return(int a, atomic_t *v) +{ +	int t; + +	__asm__ __volatile__("\n\ +1:	lwarx	%0,0,%3\n\ +	subf	%0,%2,%0\n\ +	stwcx.	%0,0,%3\n\ +	bne-	1b" +	: "=&r" (t), "=m" (*v) +	: "r" (a), "r" (v), "m" (*v) +	: "cc"); + +	return t; +} + +extern __inline__ int atomic_inc_return(atomic_t *v) +{ +	int t; + +	__asm__ __volatile__("\n\ +1:	lwarx	%0,0,%2\n\ +	addic	%0,%0,1\n\ +	stwcx.	%0,0,%2\n\ +	bne-	1b" +	: "=&r" (t), "=m" (*v) +	: "r" (v), "m" (*v) +	: "cc"); + +	return t; +} + +extern __inline__ int atomic_dec_return(atomic_t *v) +{ +	int t; + +	__asm__ __volatile__("\n\ +1:	lwarx	%0,0,%2\n\ +	addic	%0,%0,-1\n\ +	stwcx.	%0,0,%2\n\ +	bne	1b" +	: "=&r" (t), "=m" (*v) +	: "r" (v), "m" (*v) +	: "cc"); + +	return t; +} + +#define atomic_add(a, v)		((void) atomic_add_return((a), (v))) +#define atomic_sub(a, v)		((void) atomic_sub_return((a), (v))) +#define atomic_sub_and_test(a, v)	(atomic_sub_return((a), (v)) == 0) +#define atomic_inc(v)			((void) atomic_inc_return((v))) +#define atomic_dec(v)			((void) atomic_dec_return((v))) +#define atomic_dec_and_test(v)		(atomic_dec_return((v)) == 0) + +#endif /* _ASM_PPC_ATOMIC_H_ */ |