|
@@ -229,66 +229,19 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
|
|
|
(unsigned long)(n), \
|
|
|
sizeof(*(ptr))))
|
|
|
|
|
|
-#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
|
|
|
-
|
|
|
-/*
|
|
|
- * Note : ARMv7-M (currently unsupported by Linux) does not support
|
|
|
- * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should
|
|
|
- * not be allowed to use __cmpxchg64.
|
|
|
- */
|
|
|
-static inline unsigned long long __cmpxchg64(volatile void *ptr,
|
|
|
- unsigned long long old,
|
|
|
- unsigned long long new)
|
|
|
-{
|
|
|
- register unsigned long long oldval asm("r0");
|
|
|
- register unsigned long long __old asm("r2") = old;
|
|
|
- register unsigned long long __new asm("r4") = new;
|
|
|
- unsigned long res;
|
|
|
-
|
|
|
- do {
|
|
|
- asm volatile(
|
|
|
- " @ __cmpxchg8\n"
|
|
|
- " ldrexd %1, %H1, [%2]\n"
|
|
|
- " mov %0, #0\n"
|
|
|
- " teq %1, %3\n"
|
|
|
- " teqeq %H1, %H3\n"
|
|
|
- " strexdeq %0, %4, %H4, [%2]\n"
|
|
|
- : "=&r" (res), "=&r" (oldval)
|
|
|
- : "r" (ptr), "Ir" (__old), "r" (__new)
|
|
|
- : "memory", "cc");
|
|
|
- } while (res);
|
|
|
-
|
|
|
- return oldval;
|
|
|
-}
|
|
|
-
|
|
|
-static inline unsigned long long __cmpxchg64_mb(volatile void *ptr,
|
|
|
- unsigned long long old,
|
|
|
- unsigned long long new)
|
|
|
-{
|
|
|
- unsigned long long ret;
|
|
|
-
|
|
|
- smp_mb();
|
|
|
- ret = __cmpxchg64(ptr, old, new);
|
|
|
- smp_mb();
|
|
|
-
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-#define cmpxchg64(ptr,o,n) \
|
|
|
- ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \
|
|
|
- (unsigned long long)(o), \
|
|
|
- (unsigned long long)(n)))
|
|
|
-
|
|
|
-#define cmpxchg64_local(ptr,o,n) \
|
|
|
- ((__typeof__(*(ptr)))__cmpxchg64((ptr), \
|
|
|
- (unsigned long long)(o), \
|
|
|
- (unsigned long long)(n)))
|
|
|
-
|
|
|
-#else /* min ARCH = ARMv6 */
|
|
|
-
|
|
|
-#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
|
|
|
-
|
|
|
-#endif
|
|
|
+#define cmpxchg64(ptr, o, n) \
|
|
|
+ ((__typeof__(*(ptr)))atomic64_cmpxchg(container_of((ptr), \
|
|
|
+ atomic64_t, \
|
|
|
+ counter), \
|
|
|
+ (unsigned long)(o), \
|
|
|
+ (unsigned long)(n)))
|
|
|
+
|
|
|
+#define cmpxchg64_local(ptr, o, n) \
|
|
|
+ ((__typeof__(*(ptr)))local64_cmpxchg(container_of((ptr), \
|
|
|
+ local64_t, \
|
|
|
+ a), \
|
|
|
+ (unsigned long)(o), \
|
|
|
+ (unsigned long)(n)))
|
|
|
|
|
|
#endif /* __LINUX_ARM_ARCH__ >= 6 */
|
|
|
|