This source file includes following definitions.
- __atomic_add_unless
- __atomic_add_unless
1
2
3 #ifndef __ASM_CSKY_ATOMIC_H
4 #define __ASM_CSKY_ATOMIC_H
5
6 #include <linux/version.h>
7 #include <asm/cmpxchg.h>
8 #include <asm/barrier.h>
9
10 #ifdef CONFIG_CPU_HAS_LDSTEX
11
12 #define __atomic_add_unless __atomic_add_unless
13 static inline int __atomic_add_unless(atomic_t *v, int a, int u)
14 {
15 unsigned long tmp, ret;
16
17 smp_mb();
18
19 asm volatile (
20 "1: ldex.w %0, (%3) \n"
21 " mov %1, %0 \n"
22 " cmpne %0, %4 \n"
23 " bf 2f \n"
24 " add %0, %2 \n"
25 " stex.w %0, (%3) \n"
26 " bez %0, 1b \n"
27 "2: \n"
28 : "=&r" (tmp), "=&r" (ret)
29 : "r" (a), "r"(&v->counter), "r"(u)
30 : "memory");
31
32 if (ret != u)
33 smp_mb();
34
35 return ret;
36 }
37
38 #define ATOMIC_OP(op, c_op) \
39 static inline void atomic_##op(int i, atomic_t *v) \
40 { \
41 unsigned long tmp; \
42 \
43 asm volatile ( \
44 "1: ldex.w %0, (%2) \n" \
45 " " #op " %0, %1 \n" \
46 " stex.w %0, (%2) \n" \
47 " bez %0, 1b \n" \
48 : "=&r" (tmp) \
49 : "r" (i), "r"(&v->counter) \
50 : "memory"); \
51 }
52
53 #define ATOMIC_OP_RETURN(op, c_op) \
54 static inline int atomic_##op##_return(int i, atomic_t *v) \
55 { \
56 unsigned long tmp, ret; \
57 \
58 smp_mb(); \
59 asm volatile ( \
60 "1: ldex.w %0, (%3) \n" \
61 " " #op " %0, %2 \n" \
62 " mov %1, %0 \n" \
63 " stex.w %0, (%3) \n" \
64 " bez %0, 1b \n" \
65 : "=&r" (tmp), "=&r" (ret) \
66 : "r" (i), "r"(&v->counter) \
67 : "memory"); \
68 smp_mb(); \
69 \
70 return ret; \
71 }
72
73 #define ATOMIC_FETCH_OP(op, c_op) \
74 static inline int atomic_fetch_##op(int i, atomic_t *v) \
75 { \
76 unsigned long tmp, ret; \
77 \
78 smp_mb(); \
79 asm volatile ( \
80 "1: ldex.w %0, (%3) \n" \
81 " mov %1, %0 \n" \
82 " " #op " %0, %2 \n" \
83 " stex.w %0, (%3) \n" \
84 " bez %0, 1b \n" \
85 : "=&r" (tmp), "=&r" (ret) \
86 : "r" (i), "r"(&v->counter) \
87 : "memory"); \
88 smp_mb(); \
89 \
90 return ret; \
91 }
92
93 #else
94
95 #include <linux/irqflags.h>
96
97 #define __atomic_add_unless __atomic_add_unless
98 static inline int __atomic_add_unless(atomic_t *v, int a, int u)
99 {
100 unsigned long tmp, ret, flags;
101
102 raw_local_irq_save(flags);
103
104 asm volatile (
105 " ldw %0, (%3) \n"
106 " mov %1, %0 \n"
107 " cmpne %0, %4 \n"
108 " bf 2f \n"
109 " add %0, %2 \n"
110 " stw %0, (%3) \n"
111 "2: \n"
112 : "=&r" (tmp), "=&r" (ret)
113 : "r" (a), "r"(&v->counter), "r"(u)
114 : "memory");
115
116 raw_local_irq_restore(flags);
117
118 return ret;
119 }
120
121 #define ATOMIC_OP(op, c_op) \
122 static inline void atomic_##op(int i, atomic_t *v) \
123 { \
124 unsigned long tmp, flags; \
125 \
126 raw_local_irq_save(flags); \
127 \
128 asm volatile ( \
129 " ldw %0, (%2) \n" \
130 " " #op " %0, %1 \n" \
131 " stw %0, (%2) \n" \
132 : "=&r" (tmp) \
133 : "r" (i), "r"(&v->counter) \
134 : "memory"); \
135 \
136 raw_local_irq_restore(flags); \
137 }
138
139 #define ATOMIC_OP_RETURN(op, c_op) \
140 static inline int atomic_##op##_return(int i, atomic_t *v) \
141 { \
142 unsigned long tmp, ret, flags; \
143 \
144 raw_local_irq_save(flags); \
145 \
146 asm volatile ( \
147 " ldw %0, (%3) \n" \
148 " " #op " %0, %2 \n" \
149 " stw %0, (%3) \n" \
150 " mov %1, %0 \n" \
151 : "=&r" (tmp), "=&r" (ret) \
152 : "r" (i), "r"(&v->counter) \
153 : "memory"); \
154 \
155 raw_local_irq_restore(flags); \
156 \
157 return ret; \
158 }
159
160 #define ATOMIC_FETCH_OP(op, c_op) \
161 static inline int atomic_fetch_##op(int i, atomic_t *v) \
162 { \
163 unsigned long tmp, ret, flags; \
164 \
165 raw_local_irq_save(flags); \
166 \
167 asm volatile ( \
168 " ldw %0, (%3) \n" \
169 " mov %1, %0 \n" \
170 " " #op " %0, %2 \n" \
171 " stw %0, (%3) \n" \
172 : "=&r" (tmp), "=&r" (ret) \
173 : "r" (i), "r"(&v->counter) \
174 : "memory"); \
175 \
176 raw_local_irq_restore(flags); \
177 \
178 return ret; \
179 }
180
181 #endif
182
183 #define atomic_add_return atomic_add_return
184 ATOMIC_OP_RETURN(add, +)
185 #define atomic_sub_return atomic_sub_return
186 ATOMIC_OP_RETURN(sub, -)
187
188 #define atomic_fetch_add atomic_fetch_add
189 ATOMIC_FETCH_OP(add, +)
190 #define atomic_fetch_sub atomic_fetch_sub
191 ATOMIC_FETCH_OP(sub, -)
192 #define atomic_fetch_and atomic_fetch_and
193 ATOMIC_FETCH_OP(and, &)
194 #define atomic_fetch_or atomic_fetch_or
195 ATOMIC_FETCH_OP(or, |)
196 #define atomic_fetch_xor atomic_fetch_xor
197 ATOMIC_FETCH_OP(xor, ^)
198
199 #define atomic_and atomic_and
200 ATOMIC_OP(and, &)
201 #define atomic_or atomic_or
202 ATOMIC_OP(or, |)
203 #define atomic_xor atomic_xor
204 ATOMIC_OP(xor, ^)
205
206 #undef ATOMIC_FETCH_OP
207 #undef ATOMIC_OP_RETURN
208 #undef ATOMIC_OP
209
210 #include <asm-generic/atomic.h>
211
212 #endif