Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / arch / arm / include / asm / atomic.h
index da1c77d39327963ab10e633aeb8809aac7da2dec..62d2cb53b06935aed4430bf33c6a127239801ff1 100644 (file)
@@ -12,6 +12,7 @@
 #define __ASM_ARM_ATOMIC_H
 
 #include <linux/compiler.h>
+#include <linux/prefetch.h>
 #include <linux/types.h>
 #include <linux/irqflags.h>
 #include <asm/barrier.h>
@@ -41,6 +42,7 @@ static inline void atomic_add(int i, atomic_t *v)
        unsigned long tmp;
        int result;
 
+       prefetchw(&v->counter);
        __asm__ __volatile__("@ atomic_add\n"
 "1:    ldrex   %0, [%3]\n"
 "      add     %0, %0, %4\n"
@@ -79,6 +81,7 @@ static inline void atomic_sub(int i, atomic_t *v)
        unsigned long tmp;
        int result;
 
+       prefetchw(&v->counter);
        __asm__ __volatile__("@ atomic_sub\n"
 "1:    ldrex   %0, [%3]\n"
 "      sub     %0, %0, %4\n"
@@ -114,7 +117,8 @@ static inline int atomic_sub_return(int i, atomic_t *v)
 
 static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
 {
-       unsigned long oldval, res;
+       int oldval;
+       unsigned long res;
 
        smp_mb();
 
@@ -134,21 +138,6 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
        return oldval;
 }
 
-static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
-{
-       unsigned long tmp, tmp2;
-
-       __asm__ __volatile__("@ atomic_clear_mask\n"
-"1:    ldrex   %0, [%3]\n"
-"      bic     %0, %0, %4\n"
-"      strex   %1, %0, [%3]\n"
-"      teq     %1, #0\n"
-"      bne     1b"
-       : "=&r" (tmp), "=&r" (tmp2), "+Qo" (*addr)
-       : "r" (addr), "Ir" (mask)
-       : "cc");
-}
-
 #else /* ARM_ARCH_6 */
 
 #ifdef CONFIG_SMP
@@ -197,15 +186,6 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
        return ret;
 }
 
-static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
-{
-       unsigned long flags;
-
-       raw_local_irq_save(flags);
-       *addr &= ~mask;
-       raw_local_irq_restore(flags);
-}
-
 #endif /* __LINUX_ARM_ARCH__ */
 
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
@@ -238,15 +218,15 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
 
 #ifndef CONFIG_GENERIC_ATOMIC64
 typedef struct {
-       u64 __aligned(8) counter;
+       long long counter;
 } atomic64_t;
 
 #define ATOMIC64_INIT(i) { (i) }
 
 #ifdef CONFIG_ARM_LPAE
-static inline u64 atomic64_read(const atomic64_t *v)
+static inline long long atomic64_read(const atomic64_t *v)
 {
-       u64 result;
+       long long result;
 
        __asm__ __volatile__("@ atomic64_read\n"
 "      ldrd    %0, %H0, [%1]"
@@ -257,7 +237,7 @@ static inline u64 atomic64_read(const atomic64_t *v)
        return result;
 }
 
-static inline void atomic64_set(atomic64_t *v, u64 i)
+static inline void atomic64_set(atomic64_t *v, long long i)
 {
        __asm__ __volatile__("@ atomic64_set\n"
 "      strd    %2, %H2, [%1]"
@@ -266,9 +246,9 @@ static inline void atomic64_set(atomic64_t *v, u64 i)
        );
 }
 #else
-static inline u64 atomic64_read(const atomic64_t *v)
+static inline long long atomic64_read(const atomic64_t *v)
 {
-       u64 result;
+       long long result;
 
        __asm__ __volatile__("@ atomic64_read\n"
 "      ldrexd  %0, %H0, [%1]"
@@ -279,10 +259,11 @@ static inline u64 atomic64_read(const atomic64_t *v)
        return result;
 }
 
-static inline void atomic64_set(atomic64_t *v, u64 i)
+static inline void atomic64_set(atomic64_t *v, long long i)
 {
-       u64 tmp;
+       long long tmp;
 
+       prefetchw(&v->counter);
        __asm__ __volatile__("@ atomic64_set\n"
 "1:    ldrexd  %0, %H0, [%2]\n"
 "      strexd  %0, %3, %H3, [%2]\n"
@@ -294,15 +275,16 @@ static inline void atomic64_set(atomic64_t *v, u64 i)
 }
 #endif
 
-static inline void atomic64_add(u64 i, atomic64_t *v)
+static inline void atomic64_add(long long i, atomic64_t *v)
 {
-       u64 result;
+       long long result;
        unsigned long tmp;
 
+       prefetchw(&v->counter);
        __asm__ __volatile__("@ atomic64_add\n"
 "1:    ldrexd  %0, %H0, [%3]\n"
-"      adds    %0, %0, %4\n"
-"      adc     %H0, %H0, %H4\n"
+"      adds    %Q0, %Q0, %Q4\n"
+"      adc     %R0, %R0, %R4\n"
 "      strexd  %1, %0, %H0, [%3]\n"
 "      teq     %1, #0\n"
 "      bne     1b"
@@ -311,17 +293,17 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
        : "cc");
 }
 
-static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+static inline long long atomic64_add_return(long long i, atomic64_t *v)
 {
-       u64 result;
+       long long result;
        unsigned long tmp;
 
        smp_mb();
 
        __asm__ __volatile__("@ atomic64_add_return\n"
 "1:    ldrexd  %0, %H0, [%3]\n"
-"      adds    %0, %0, %4\n"
-"      adc     %H0, %H0, %H4\n"
+"      adds    %Q0, %Q0, %Q4\n"
+"      adc     %R0, %R0, %R4\n"
 "      strexd  %1, %0, %H0, [%3]\n"
 "      teq     %1, #0\n"
 "      bne     1b"
@@ -334,15 +316,16 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
        return result;
 }
 
-static inline void atomic64_sub(u64 i, atomic64_t *v)
+static inline void atomic64_sub(long long i, atomic64_t *v)
 {
-       u64 result;
+       long long result;
        unsigned long tmp;
 
+       prefetchw(&v->counter);
        __asm__ __volatile__("@ atomic64_sub\n"
 "1:    ldrexd  %0, %H0, [%3]\n"
-"      subs    %0, %0, %4\n"
-"      sbc     %H0, %H0, %H4\n"
+"      subs    %Q0, %Q0, %Q4\n"
+"      sbc     %R0, %R0, %R4\n"
 "      strexd  %1, %0, %H0, [%3]\n"
 "      teq     %1, #0\n"
 "      bne     1b"
@@ -351,17 +334,17 @@ static inline void atomic64_sub(u64 i, atomic64_t *v)
        : "cc");
 }
 
-static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
+static inline long long atomic64_sub_return(long long i, atomic64_t *v)
 {
-       u64 result;
+       long long result;
        unsigned long tmp;
 
        smp_mb();
 
        __asm__ __volatile__("@ atomic64_sub_return\n"
 "1:    ldrexd  %0, %H0, [%3]\n"
-"      subs    %0, %0, %4\n"
-"      sbc     %H0, %H0, %H4\n"
+"      subs    %Q0, %Q0, %Q4\n"
+"      sbc     %R0, %R0, %R4\n"
 "      strexd  %1, %0, %H0, [%3]\n"
 "      teq     %1, #0\n"
 "      bne     1b"
@@ -374,9 +357,10 @@ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
        return result;
 }
 
-static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
+static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
+                                       long long new)
 {
-       u64 oldval;
+       long long oldval;
        unsigned long res;
 
        smp_mb();
@@ -398,9 +382,9 @@ static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
        return oldval;
 }
 
-static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
 {
-       u64 result;
+       long long result;
        unsigned long tmp;
 
        smp_mb();
@@ -419,18 +403,18 @@ static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
        return result;
 }
 
-static inline u64 atomic64_dec_if_positive(atomic64_t *v)
+static inline long long atomic64_dec_if_positive(atomic64_t *v)
 {
-       u64 result;
+       long long result;
        unsigned long tmp;
 
        smp_mb();
 
        __asm__ __volatile__("@ atomic64_dec_if_positive\n"
 "1:    ldrexd  %0, %H0, [%3]\n"
-"      subs    %0, %0, #1\n"
-"      sbc     %H0, %H0, #0\n"
-"      teq     %H0, #0\n"
+"      subs    %Q0, %Q0, #1\n"
+"      sbc     %R0, %R0, #0\n"
+"      teq     %R0, #0\n"
 "      bmi     2f\n"
 "      strexd  %1, %0, %H0, [%3]\n"
 "      teq     %1, #0\n"
@@ -445,9 +429,9 @@ static inline u64 atomic64_dec_if_positive(atomic64_t *v)
        return result;
 }
 
-static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
 {
-       u64 val;
+       long long val;
        unsigned long tmp;
        int ret = 1;
 
@@ -459,8 +443,8 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
 "      teqeq   %H0, %H5\n"
 "      moveq   %1, #0\n"
 "      beq     2f\n"
-"      adds    %0, %0, %6\n"
-"      adc     %H0, %H0, %H6\n"
+"      adds    %Q0, %Q0, %Q6\n"
+"      adc     %R0, %R0, %R6\n"
 "      strexd  %2, %0, %H0, [%4]\n"
 "      teq     %2, #0\n"
 "      bne     1b\n"