Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[sfrench/cifs-2.6.git] / include / asm-mips / irqflags.h
index 43ca09a3a3d0ca2735b6f0b364c0190cee2569c4..af3b07dfad4be2fea39a75522347ac81ed0a8b3f 100644 (file)
 
 #include <asm/hazards.h>
 
+/*
+ * CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY does prompt replay of deferred IPIs,
+ * at the cost of branch and call overhead on each local_irq_restore()
+ */
+
+#ifdef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
+
+extern void smtc_ipi_replay(void);
+
+#define irq_restore_epilog(flags)                              \
+do {                                                           \
+       if (!(flags & 0x0400))                                  \
+               smtc_ipi_replay();                              \
+} while (0)
+
+#else
+
+#define irq_restore_epilog(ignore) do { } while (0)
+
+#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */
+
 __asm__ (
        "       .macro  raw_local_irq_enable                            \n"
        "       .set    push                                            \n"
@@ -193,6 +214,7 @@ do {                                                                        \
                : "=r" (__tmp1)                                         \
                : "0" (flags)                                           \
                : "memory");                                            \
+       irq_restore_epilog(flags);                                      \
 } while(0)
 
 static inline int raw_irqs_disabled_flags(unsigned long flags)
@@ -213,12 +235,37 @@ static inline int raw_irqs_disabled_flags(unsigned long flags)
  * Do the CPU's IRQ-state tracing from assembly code.
  */
 #ifdef CONFIG_TRACE_IRQFLAGS
+/* Reload some registers clobbered by trace_hardirqs_on */
+#ifdef CONFIG_64BIT
+# define TRACE_IRQS_RELOAD_REGS                                                \
+       LONG_L  $11, PT_R11(sp);                                        \
+       LONG_L  $10, PT_R10(sp);                                        \
+       LONG_L  $9, PT_R9(sp);                                          \
+       LONG_L  $8, PT_R8(sp);                                          \
+       LONG_L  $7, PT_R7(sp);                                          \
+       LONG_L  $6, PT_R6(sp);                                          \
+       LONG_L  $5, PT_R5(sp);                                          \
+       LONG_L  $4, PT_R4(sp);                                          \
+       LONG_L  $2, PT_R2(sp)
+#else
+# define TRACE_IRQS_RELOAD_REGS                                                \
+       LONG_L  $7, PT_R7(sp);                                          \
+       LONG_L  $6, PT_R6(sp);                                          \
+       LONG_L  $5, PT_R5(sp);                                          \
+       LONG_L  $4, PT_R4(sp);                                          \
+       LONG_L  $2, PT_R2(sp)
+#endif
 # define TRACE_IRQS_ON                                                 \
+       CLI;    /* make sure trace_hardirqs_on() is called in kernel level */ \
        jal     trace_hardirqs_on
+# define TRACE_IRQS_ON_RELOAD                                          \
+       TRACE_IRQS_ON;                                                  \
+       TRACE_IRQS_RELOAD_REGS
 # define TRACE_IRQS_OFF                                                        \
        jal     trace_hardirqs_off
 #else
 # define TRACE_IRQS_ON
+# define TRACE_IRQS_ON_RELOAD
 # define TRACE_IRQS_OFF
 #endif