|
@@ -115,6 +115,24 @@ static inline notrace unsigned long irq_soft_mask_set_return(unsigned long mask)
|
|
|
return flags;
|
|
|
}
|
|
|
|
|
|
+static inline notrace unsigned long irq_soft_mask_or_return(unsigned long mask)
|
|
|
+{
|
|
|
+ unsigned long flags, tmp;
|
|
|
+
|
|
|
+ asm volatile(
|
|
|
+ "lbz %0,%2(13); or %1,%0,%3; stb %1,%2(13)"
|
|
|
+ : "=&r" (flags), "=r" (tmp)
|
|
|
+ : "i" (offsetof(struct paca_struct, irq_soft_mask)),
|
|
|
+ "r" (mask)
|
|
|
+ : "memory");
|
|
|
+
|
|
|
+#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
|
|
|
+ WARN_ON((mask | flags) && !((mask | flags) & IRQS_DISABLED));
|
|
|
+#endif
|
|
|
+
|
|
|
+ return flags;
|
|
|
+}
|
|
|
+
|
|
|
static inline unsigned long arch_local_save_flags(void)
|
|
|
{
|
|
|
return irq_soft_mask_return();
|
|
@@ -147,6 +165,55 @@ static inline bool arch_irqs_disabled(void)
|
|
|
return arch_irqs_disabled_flags(arch_local_save_flags());
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_PPC_BOOK3S
|
|
|
+/*
|
|
|
+ * To support disabling and enabling of irq with PMI, set of
|
|
|
+ * new powerpc_local_irq_pmu_save() and powerpc_local_irq_restore()
|
|
|
+ * functions are added. These macros are implemented using generic
|
|
|
+ * linux local_irq_* code from include/linux/irqflags.h.
|
|
|
+ */
|
|
|
+#define raw_local_irq_pmu_save(flags) \
|
|
|
+ do { \
|
|
|
+ typecheck(unsigned long, flags); \
|
|
|
+ flags = irq_soft_mask_or_return(IRQS_DISABLED | \
|
|
|
+ IRQS_PMI_DISABLED); \
|
|
|
+ } while(0)
|
|
|
+
|
|
|
+#define raw_local_irq_pmu_restore(flags) \
|
|
|
+ do { \
|
|
|
+ typecheck(unsigned long, flags); \
|
|
|
+ arch_local_irq_restore(flags); \
|
|
|
+ } while(0)
|
|
|
+
|
|
|
+#ifdef CONFIG_TRACE_IRQFLAGS
|
|
|
+#define powerpc_local_irq_pmu_save(flags) \
|
|
|
+ do { \
|
|
|
+ raw_local_irq_pmu_save(flags); \
|
|
|
+ trace_hardirqs_off(); \
|
|
|
+ } while(0)
|
|
|
+#define powerpc_local_irq_pmu_restore(flags) \
|
|
|
+ do { \
|
|
|
+ if (raw_irqs_disabled_flags(flags)) { \
|
|
|
+ raw_local_irq_pmu_restore(flags); \
|
|
|
+ trace_hardirqs_off(); \
|
|
|
+ } else { \
|
|
|
+ trace_hardirqs_on(); \
|
|
|
+ raw_local_irq_pmu_restore(flags); \
|
|
|
+ } \
|
|
|
+ } while(0)
|
|
|
+#else
|
|
|
+#define powerpc_local_irq_pmu_save(flags) \
|
|
|
+ do { \
|
|
|
+ raw_local_irq_pmu_save(flags); \
|
|
|
+ } while(0)
|
|
|
+#define powerpc_local_irq_pmu_restore(flags) \
|
|
|
+ do { \
|
|
|
+ raw_local_irq_pmu_restore(flags); \
|
|
|
+ } while (0)
|
|
|
+#endif /* CONFIG_TRACE_IRQFLAGS */
|
|
|
+
|
|
|
+#endif /* CONFIG_PPC_BOOK3S */
|
|
|
+
|
|
|
#ifdef CONFIG_PPC_BOOK3E
|
|
|
#define __hard_irq_enable() asm volatile("wrteei 1" : : : "memory")
|
|
|
#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory")
|