fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / asm-mips / atomic.h
index 2c8b853..c1a2409 100644 (file)
@@ -9,22 +9,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 97, 99, 2000, 03, 04 by Ralf Baechle
+ * Copyright (C) 1996, 97, 99, 2000, 03, 04, 06 by Ralf Baechle
  */
-
-/*
- * As workaround for the ATOMIC_DEC_AND_LOCK / atomic_dec_and_lock mess in
- * <linux/spinlock.h> we have to include <linux/spinlock.h> outside the
- * main big wrapper ...
- */
-#include <linux/config.h>
-#include <linux/spinlock.h>
-
 #ifndef _ASM_ATOMIC_H
 #define _ASM_ATOMIC_H
 
+#include <linux/irqflags.h>
+#include <asm/barrier.h>
 #include <asm/cpu-features.h>
-#include <asm/interrupt.h>
 #include <asm/war.h>
 
 typedef struct { volatile int counter; } atomic_t;
@@ -139,6 +131,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
 {
        unsigned long result;
 
+       smp_mb();
+
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long temp;
 
@@ -149,7 +143,6 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
                "       sc      %0, %2                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       addu    %0, %1, %3                              \n"
-               "       sync                                            \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -164,7 +157,6 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
                "       sc      %0, %2                                  \n"
                "       beqz    %0, 1b                                  \n"
                "       addu    %0, %1, %3                              \n"
-               "       sync                                            \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -179,6 +171,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
                local_irq_restore(flags);
        }
 
+       smp_mb();
+
        return result;
 }
 
@@ -186,6 +180,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
 {
        unsigned long result;
 
+       smp_mb();
+
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long temp;
 
@@ -196,7 +192,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
                "       sc      %0, %2                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       subu    %0, %1, %3                              \n"
-               "       sync                                            \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -211,7 +206,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
                "       sc      %0, %2                                  \n"
                "       beqz    %0, 1b                                  \n"
                "       subu    %0, %1, %3                              \n"
-               "       sync                                            \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -226,6 +220,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
                local_irq_restore(flags);
        }
 
+       smp_mb();
+
        return result;
 }
 
@@ -241,6 +237,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 {
        unsigned long result;
 
+       smp_mb();
+
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long temp;
 
@@ -254,7 +252,6 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
                "       beqzl   %0, 1b                                  \n"
                "        subu   %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
-               "       sync                                            \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -273,7 +270,6 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
                "       beqz    %0, 1b                                  \n"
                "        subu   %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
-               "       sync                                            \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -290,6 +286,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
                local_irq_restore(flags);
        }
 
+       smp_mb();
+
        return result;
 }
 
@@ -384,7 +382,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 
 #ifdef CONFIG_64BIT
 
-typedef struct { volatile __s64 counter; } atomic64_t;
+typedef struct { volatile long counter; } atomic64_t;
 
 #define ATOMIC64_INIT(i)    { (i) }
 
@@ -493,6 +491,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
 {
        unsigned long result;
 
+       smp_mb();
+
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long temp;
 
@@ -503,7 +503,6 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
                "       scd     %0, %2                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       addu    %0, %1, %3                              \n"
-               "       sync                                            \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -518,7 +517,6 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
                "       scd     %0, %2                                  \n"
                "       beqz    %0, 1b                                  \n"
                "       addu    %0, %1, %3                              \n"
-               "       sync                                            \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -533,6 +531,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
                local_irq_restore(flags);
        }
 
+       smp_mb();
+
        return result;
 }
 
@@ -540,6 +540,8 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
 {
        unsigned long result;
 
+       smp_mb();
+
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long temp;
 
@@ -550,7 +552,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
                "       scd     %0, %2                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       subu    %0, %1, %3                              \n"
-               "       sync                                            \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -565,7 +566,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
                "       scd     %0, %2                                  \n"
                "       beqz    %0, 1b                                  \n"
                "       subu    %0, %1, %3                              \n"
-               "       sync                                            \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -580,6 +580,8 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
                local_irq_restore(flags);
        }
 
+       smp_mb();
+
        return result;
 }
 
@@ -595,6 +597,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
 {
        unsigned long result;
 
+       smp_mb();
+
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long temp;
 
@@ -608,7 +612,6 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
                "       beqzl   %0, 1b                                  \n"
                "        dsubu  %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
-               "       sync                                            \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -627,7 +630,6 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
                "       beqz    %0, 1b                                  \n"
                "        dsubu  %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
-               "       sync                                            \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -644,6 +646,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
                local_irq_restore(flags);
        }
 
+       smp_mb();
+
        return result;
 }