Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[cascardo/linux.git] / include / asm-mips / hazards.h
index e50c77e..2de638f 100644 (file)
@@ -3,18 +3,19 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2003, 2004 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2003, 04, 07 Ralf Baechle <ralf@linux-mips.org>
  * Copyright (C) MIPS Technologies, Inc.
  *   written by Ralf Baechle <ralf@linux-mips.org>
  */
 #ifndef _ASM_HAZARDS_H
 #define _ASM_HAZARDS_H
 
-
 #ifdef __ASSEMBLY__
 #define ASMMACRO(name, code...) .macro name; code; .endm
 #else
 
+#include <asm/cpu-features.h>
+
 #define ASMMACRO(name, code...)                                                \
 __asm__(".macro " #name "; " #code "; .endm");                         \
                                                                        \
@@ -23,6 +24,11 @@ static inline void name(void)                                                \
        __asm__ __volatile__ (#name);                                   \
 }
 
+/*
+ * MIPS R2 instruction hazard barrier.   Needs to be called as a subroutine.
+ */
+extern void mips_ihb(void);
+
 #endif
 
 ASMMACRO(_ssnop,
@@ -81,6 +87,57 @@ do {                                                                 \
        : "=r" (tmp));                                                  \
 } while (0)
 
+#elif defined(CONFIG_CPU_MIPSR1)
+
+/*
+ * These are slightly complicated by the fact that we guarantee R1 kernels to
+ * run fine on R2 processors.
+ */
+ASMMACRO(mtc0_tlbw_hazard,
+       _ssnop; _ssnop; _ehb
+       )
+ASMMACRO(tlbw_use_hazard,
+       _ssnop; _ssnop; _ssnop; _ehb
+       )
+ASMMACRO(tlb_probe_hazard,
+        _ssnop; _ssnop; _ssnop; _ehb
+       )
+ASMMACRO(irq_enable_hazard,
+        _ssnop; _ssnop; _ssnop; _ehb
+       )
+ASMMACRO(irq_disable_hazard,
+       _ssnop; _ssnop; _ssnop; _ehb
+       )
+ASMMACRO(back_to_back_c0_hazard,
+        _ssnop; _ssnop; _ssnop; _ehb
+       )
+/*
+ * gcc has a tradition of misscompiling the previous construct using the
+ * address of a label as argument to inline assembler.  Gas otoh has the
+ * annoying difference between la and dla which are only usable for 32-bit
+ * rsp. 64-bit code, so can't be used without conditional compilation.
+ * The alterantive is switching the assembler to 64-bit code which happens
+ * to work right even for 32-bit code ...
+ */
+#define __instruction_hazard()                                         \
+do {                                                                   \
+       unsigned long tmp;                                              \
+                                                                       \
+       __asm__ __volatile__(                                           \
+       "       .set    mips64r2                                \n"     \
+       "       dla     %0, 1f                                  \n"     \
+       "       jr.hb   %0                                      \n"     \
+       "       .set    mips0                                   \n"     \
+       "1:                                                     \n"     \
+       : "=r" (tmp));                                                  \
+} while (0)
+
+#define instruction_hazard()                                           \
+do {                                                                   \
+       if (cpu_has_mips_r2)                                            \
+               __instruction_hazard();                                 \
+} while (0)
+
 #elif defined(CONFIG_CPU_R10000)
 
 /*
@@ -167,6 +224,7 @@ ASMMACRO(tlb_probe_hazard,
         nop; nop; nop
        )
 ASMMACRO(irq_enable_hazard,
+        _ssnop; _ssnop; _ssnop;
        )
 ASMMACRO(irq_disable_hazard,
        nop; nop; nop
@@ -178,4 +236,36 @@ ASMMACRO(back_to_back_c0_hazard,
 
 #endif
 
+
+/* FPU hazards */
+
+#if defined(CONFIG_CPU_SB1)
+ASMMACRO(enable_fpu_hazard,
+        .set   push;
+        .set   mips64;
+        .set   noreorder;
+        _ssnop;
+        bnezl  $0, .+4;
+        _ssnop;
+        .set   pop
+)
+ASMMACRO(disable_fpu_hazard,
+)
+
+#elif defined(CONFIG_CPU_MIPSR2)
+ASMMACRO(enable_fpu_hazard,
+        _ehb
+)
+ASMMACRO(disable_fpu_hazard,
+        _ehb
+)
+#else
+ASMMACRO(enable_fpu_hazard,
+        nop; nop; nop; nop
+)
+ASMMACRO(disable_fpu_hazard,
+        _ehb
+)
+#endif
+
 #endif /* _ASM_HAZARDS_H */