diff options
Diffstat (limited to 'arch/frv/include/asm/atomic.h')
-rw-r--r-- | arch/frv/include/asm/atomic.h | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h index 0409d981fd39..00a57af79afc 100644 --- a/arch/frv/include/asm/atomic.h +++ b/arch/frv/include/asm/atomic.h | |||
@@ -121,10 +121,72 @@ static inline void atomic_dec(atomic_t *v) | |||
121 | #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) | 121 | #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) |
122 | #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) | 122 | #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) |
123 | 123 | ||
124 | /* | ||
125 | * 64-bit atomic ops | ||
126 | */ | ||
127 | typedef struct { | ||
128 | volatile long long counter; | ||
129 | } atomic64_t; | ||
130 | |||
131 | #define ATOMIC64_INIT(i) { (i) } | ||
132 | |||
133 | static inline long long atomic64_read(atomic64_t *v) | ||
134 | { | ||
135 | long long counter; | ||
136 | |||
137 | asm("ldd%I1 %M1,%0" | ||
138 | : "=e"(counter) | ||
139 | : "m"(v->counter)); | ||
140 | return counter; | ||
141 | } | ||
142 | |||
143 | static inline void atomic64_set(atomic64_t *v, long long i) | ||
144 | { | ||
145 | asm volatile("std%I0 %1,%M0" | ||
146 | : "=m"(v->counter) | ||
147 | : "e"(i)); | ||
148 | } | ||
149 | |||
150 | extern long long atomic64_inc_return(atomic64_t *v); | ||
151 | extern long long atomic64_dec_return(atomic64_t *v); | ||
152 | extern long long atomic64_add_return(long long i, atomic64_t *v); | ||
153 | extern long long atomic64_sub_return(long long i, atomic64_t *v); | ||
154 | |||
155 | static inline long long atomic64_add_negative(long long i, atomic64_t *v) | ||
156 | { | ||
157 | return atomic64_add_return(i, v) < 0; | ||
158 | } | ||
159 | |||
160 | static inline void atomic64_add(long long i, atomic64_t *v) | ||
161 | { | ||
162 | atomic64_add_return(i, v); | ||
163 | } | ||
164 | |||
165 | static inline void atomic64_sub(long long i, atomic64_t *v) | ||
166 | { | ||
167 | atomic64_sub_return(i, v); | ||
168 | } | ||
169 | |||
170 | static inline void atomic64_inc(atomic64_t *v) | ||
171 | { | ||
172 | atomic64_inc_return(v); | ||
173 | } | ||
174 | |||
175 | static inline void atomic64_dec(atomic64_t *v) | ||
176 | { | ||
177 | atomic64_dec_return(v); | ||
178 | } | ||
179 | |||
180 | #define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0) | ||
181 | #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) | ||
182 | #define atomic64_inc_and_test(v) (atomic64_inc_return((v)) == 0) | ||
183 | |||
124 | /*****************************************************************************/ | 184 | /*****************************************************************************/ |
125 | /* | 185 | /* |
126 | * exchange value with memory | 186 | * exchange value with memory |
127 | */ | 187 | */ |
188 | extern uint64_t __xchg_64(uint64_t i, volatile void *v); | ||
189 | |||
128 | #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS | 190 | #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS |
129 | 191 | ||
130 | #define xchg(ptr, x) \ | 192 | #define xchg(ptr, x) \ |
@@ -174,8 +236,10 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v); | |||
174 | 236 | ||
175 | #define tas(ptr) (xchg((ptr), 1)) | 237 | #define tas(ptr) (xchg((ptr), 1)) |
176 | 238 | ||
177 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) | 239 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&(v)->counter, old, new)) |
178 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 240 | #define atomic_xchg(v, new) (xchg(&(v)->counter, new)) |
241 | #define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter)) | ||
242 | #define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter)) | ||
179 | 243 | ||
180 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | 244 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
181 | { | 245 | { |