diff options
Diffstat (limited to 'arch/arm/include/asm/cmpxchg.h')
| -rw-r--r-- | arch/arm/include/asm/cmpxchg.h | 71 | 
1 files changed, 12 insertions, 59 deletions
diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h index d41d7cbf0ad..7eb18c1d8d6 100644 --- a/arch/arm/include/asm/cmpxchg.h +++ b/arch/arm/include/asm/cmpxchg.h @@ -229,66 +229,19 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,  				       (unsigned long)(n),		\  				       sizeof(*(ptr)))) -#ifndef CONFIG_CPU_V6	/* min ARCH >= ARMv6K */ - -/* - * Note : ARMv7-M (currently unsupported by Linux) does not support - * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should - * not be allowed to use __cmpxchg64. - */ -static inline unsigned long long __cmpxchg64(volatile void *ptr, -					     unsigned long long old, -					     unsigned long long new) -{ -	register unsigned long long oldval asm("r0"); -	register unsigned long long __old asm("r2") = old; -	register unsigned long long __new asm("r4") = new; -	unsigned long res; - -	do { -		asm volatile( -		"	@ __cmpxchg8\n" -		"	ldrexd	%1, %H1, [%2]\n" -		"	mov	%0, #0\n" -		"	teq	%1, %3\n" -		"	teqeq	%H1, %H3\n" -		"	strexdeq %0, %4, %H4, [%2]\n" -			: "=&r" (res), "=&r" (oldval) -			: "r" (ptr), "Ir" (__old), "r" (__new) -			: "memory", "cc"); -	} while (res); - -	return oldval; -} - -static inline unsigned long long __cmpxchg64_mb(volatile void *ptr, -						unsigned long long old, -						unsigned long long new) -{ -	unsigned long long ret; +#define cmpxchg64(ptr, o, n)						\ +	((__typeof__(*(ptr)))atomic64_cmpxchg(container_of((ptr),	\ +						atomic64_t,		\ +						counter),		\ +					      (unsigned long)(o),	\ +					      (unsigned long)(n))) -	smp_mb(); -	ret = __cmpxchg64(ptr, old, new); -	smp_mb(); - -	return ret; -} - -#define cmpxchg64(ptr,o,n)						\ -	((__typeof__(*(ptr)))__cmpxchg64_mb((ptr),			\ -					    (unsigned long long)(o),	\ -					    (unsigned long long)(n))) - -#define cmpxchg64_local(ptr,o,n)					\ -	((__typeof__(*(ptr)))__cmpxchg64((ptr),				\ -					 (unsigned long long)(o),	\ -					 (unsigned long long)(n))) - -#else /* min ARCH = ARMv6 */ - -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -#endif +#define cmpxchg64_local(ptr, o, n)					\ +	((__typeof__(*(ptr)))local64_cmpxchg(container_of((ptr),	\ +						local64_t,		\ +						a),			\ +					     (unsigned long)(o),	\ +					     (unsigned long)(n)))  #endif	/* __LINUX_ARM_ARCH__ >= 6 */  |