diff options
Diffstat (limited to 'arch/unicore32/include/asm/cmpxchg.h')
| -rw-r--r-- | arch/unicore32/include/asm/cmpxchg.h | 61 | 
1 files changed, 61 insertions, 0 deletions
diff --git a/arch/unicore32/include/asm/cmpxchg.h b/arch/unicore32/include/asm/cmpxchg.h new file mode 100644 index 00000000000..8e797ad4fa2 --- /dev/null +++ b/arch/unicore32/include/asm/cmpxchg.h @@ -0,0 +1,61 @@ +/* + * Atomics xchg/cmpxchg for PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2012 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __UNICORE_CMPXCHG_H__ +#define __UNICORE_CMPXCHG_H__ + +/* + * Generate a link failure on undefined symbol if the pointer points to a value + * of unsupported size. + */ +extern void __xchg_bad_pointer(void); + +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, +		int size) +{ +	unsigned long ret; + +	switch (size) { +	case 1: +		asm volatile("swapb	%0, %1, [%2]" +			: "=&r" (ret) +			: "r" (x), "r" (ptr) +			: "memory", "cc"); +		break; +	case 4: +		asm volatile("swapw	%0, %1, [%2]" +			: "=&r" (ret) +			: "r" (x), "r" (ptr) +			: "memory", "cc"); +		break; +	default: +		__xchg_bad_pointer(); +	} + +	return ret; +} + +#define xchg(ptr, x) \ +	((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) + +#include <asm-generic/cmpxchg-local.h> + +/* + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make + * them available. + */ +#define cmpxchg_local(ptr, o, n)					\ +		((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr),	\ +		(unsigned long)(o), (unsigned long)(n), sizeof(*(ptr)))) +#define cmpxchg64_local(ptr, o, n)					\ +		__cmpxchg64_local_generic((ptr), (o), (n)) + +#include <asm-generic/cmpxchg.h> + +#endif /* __UNICORE_CMPXCHG_H__ */  | 
