]>
Commit | Line | Data |
---|---|---|
11595172 SK |
1 | /* |
2 | * Copyright (C) 2014 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi> | |
3 | * | |
4 | * This file is licensed under the terms of the GNU General Public License | |
5 | * version 2. This program is licensed "as is" without any warranty of any | |
6 | * kind, whether express or implied. | |
7 | */ | |
8 | ||
9 | #ifndef __ASM_OPENRISC_CMPXCHG_H | |
10 | #define __ASM_OPENRISC_CMPXCHG_H | |
11 | ||
12 | #include <linux/types.h> | |
13 | ||
14 | /* | |
15 | * This function doesn't exist, so you'll get a linker error | |
16 | * if something tries to do an invalid cmpxchg(). | |
17 | */ | |
18 | extern void __cmpxchg_called_with_bad_pointer(void); | |
19 | ||
20 | #define __HAVE_ARCH_CMPXCHG 1 | |
21 | ||
22 | static inline unsigned long | |
23 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |
24 | { | |
25 | if (size != 4) { | |
26 | __cmpxchg_called_with_bad_pointer(); | |
27 | return old; | |
28 | } | |
29 | ||
30 | __asm__ __volatile__( | |
31 | "1: l.lwa %0, 0(%1) \n" | |
32 | " l.sfeq %0, %2 \n" | |
33 | " l.bnf 2f \n" | |
34 | " l.nop \n" | |
35 | " l.swa 0(%1), %3 \n" | |
36 | " l.bnf 1b \n" | |
37 | " l.nop \n" | |
38 | "2: \n" | |
39 | : "=&r"(old) | |
40 | : "r"(ptr), "r"(old), "r"(new) | |
41 | : "cc", "memory"); | |
42 | ||
43 | return old; | |
44 | } | |
45 | ||
46 | #define cmpxchg(ptr, o, n) \ | |
47 | ({ \ | |
48 | (__typeof__(*(ptr))) __cmpxchg((ptr), \ | |
49 | (unsigned long)(o), \ | |
50 | (unsigned long)(n), \ | |
51 | sizeof(*(ptr))); \ | |
52 | }) | |
53 | ||
54 | /* | |
55 | * This function doesn't exist, so you'll get a linker error if | |
56 | * something tries to do an invalidly-sized xchg(). | |
57 | */ | |
58 | extern void __xchg_called_with_bad_pointer(void); | |
59 | ||
60 | static inline unsigned long __xchg(unsigned long val, volatile void *ptr, | |
61 | int size) | |
62 | { | |
63 | if (size != 4) { | |
64 | __xchg_called_with_bad_pointer(); | |
65 | return val; | |
66 | } | |
67 | ||
68 | __asm__ __volatile__( | |
69 | "1: l.lwa %0, 0(%1) \n" | |
70 | " l.swa 0(%1), %2 \n" | |
71 | " l.bnf 1b \n" | |
72 | " l.nop \n" | |
73 | : "=&r"(val) | |
74 | : "r"(ptr), "r"(val) | |
75 | : "cc", "memory"); | |
76 | ||
77 | return val; | |
78 | } | |
79 | ||
8af42949 SH |
80 | #define xchg(ptr, with) \ |
81 | ({ \ | |
82 | (__typeof__(*(ptr))) __xchg((unsigned long)(with), \ | |
83 | (ptr), \ | |
84 | sizeof(*(ptr))); \ | |
85 | }) | |
11595172 SK |
86 | |
87 | #endif /* __ASM_OPENRISC_CMPXCHG_H */ |