• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Atomics xchg/cmpxchg for PKUnity SoC and UniCore ISA
4  *
5  * Copyright (C) 2001-2012 GUAN Xue-tao
6  */
7 #ifndef __UNICORE_CMPXCHG_H__
8 #define __UNICORE_CMPXCHG_H__
9 
10 /*
11  * Generate a link failure on undefined symbol if the pointer points to a value
12  * of unsupported size.
13  */
14 extern void __xchg_bad_pointer(void);
15 
__xchg(unsigned long x,volatile void * ptr,int size)16 static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
17 		int size)
18 {
19 	unsigned long ret;
20 
21 	switch (size) {
22 	case 1:
23 		asm volatile("swapb	%0, %1, [%2]"
24 			: "=&r" (ret)
25 			: "r" (x), "r" (ptr)
26 			: "memory", "cc");
27 		break;
28 	case 4:
29 		asm volatile("swapw	%0, %1, [%2]"
30 			: "=&r" (ret)
31 			: "r" (x), "r" (ptr)
32 			: "memory", "cc");
33 		break;
34 	default:
35 		__xchg_bad_pointer();
36 	}
37 
38 	return ret;
39 }
40 
41 #define xchg(ptr, x) \
42 	((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
43 
44 #include <asm-generic/cmpxchg-local.h>
45 
46 /*
47  * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
48  * them available.
49  */
50 #define cmpxchg_local(ptr, o, n)					\
51 		((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr),	\
52 		(unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
53 #define cmpxchg64_local(ptr, o, n)					\
54 		__cmpxchg64_local_generic((ptr), (o), (n))
55 
56 #include <asm-generic/cmpxchg.h>
57 
58 #endif /* __UNICORE_CMPXCHG_H__ */
59