summaryrefslogtreecommitdiff
path: root/arch/powerpc/include/asm/hw_irq.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/include/asm/hw_irq.h')
-rw-r--r--arch/powerpc/include/asm/hw_irq.h49
1 files changed, 46 insertions, 3 deletions
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index ba713f1..29a5a7a 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -89,7 +89,31 @@ static inline bool arch_irqs_disabled(void)
#ifdef CONFIG_PPC_BOOK3E
#define __hard_irq_enable() asm volatile("wrteei 1" : : : "memory")
-#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory")
+
+#ifdef CONFIG_FSL_ERRATUM_A_006198
+static inline void __hard_irq_disable(void)
+{
+ void fsl_erratum_a006198_return(void);
+ unsigned long tmp;
+
+ asm volatile("bl 2f;"
+ "2: mflr %0;"
+ "addi %0, %0, 1f-2b;"
+ "mtlr %0;"
+ "mtspr %1, %4;"
+ "mfmsr %0;"
+ "rlwinm %0, %0, 0, ~%3;"
+ "mtspr %2, %0;"
+ "rfmci;"
+ "1: mtmsr %0" : "=&r" (tmp) :
+ "i" (SPRN_MCSRR0), "i" (SPRN_MCSRR1),
+ "i" (MSR_EE), "r" (*(u64 *)fsl_erratum_a006198_return) :
+ "memory", "lr");
+}
+#else
+#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory");
+#endif
+
#else
#define __hard_irq_enable() __mtmsrd(local_paca->kernel_msr | MSR_EE, 1)
#define __hard_irq_disable() __mtmsrd(local_paca->kernel_msr, 1)
@@ -132,6 +156,8 @@ extern bool prep_irq_for_idle(void);
#define SET_MSR_EE(x) mtmsr(x)
+#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory")
+
static inline unsigned long arch_local_save_flags(void)
{
return mfmsr();
@@ -140,7 +166,24 @@ static inline unsigned long arch_local_save_flags(void)
static inline void arch_local_irq_restore(unsigned long flags)
{
#if defined(CONFIG_BOOKE)
+#ifdef CONFIG_FSL_ERRATUM_A_006198
+ void fsl_erratum_a006198_return(void);
+ unsigned long tmp;
+
+ asm volatile("bl 2f;"
+ "2: mflr %0;"
+ "addi %0, %0, 1f-2b;"
+ "mtlr %0;"
+ "mtspr %1, %3;"
+ "mtspr %2, %4;"
+ "rfmci;"
+ "1: mtmsr %3" : "=&r" (tmp) :
+ "i" (SPRN_MCSRR1), "i" (SPRN_MCSRR0),
+ "r" (flags), "r" (*(u64 *)fsl_erratum_a006198_return) :
+ "memory", "lr");
+#else
asm volatile("wrtee %0" : : "r" (flags) : "memory");
+#endif
#else
mtmsr(flags);
#endif
@@ -150,7 +193,7 @@ static inline unsigned long arch_local_irq_save(void)
{
unsigned long flags = arch_local_save_flags();
#ifdef CONFIG_BOOKE
- asm volatile("wrteei 0" : : : "memory");
+ __hard_irq_disable();
#else
SET_MSR_EE(flags & ~MSR_EE);
#endif
@@ -160,7 +203,7 @@ static inline unsigned long arch_local_irq_save(void)
static inline void arch_local_irq_disable(void)
{
#ifdef CONFIG_BOOKE
- asm volatile("wrteei 0" : : : "memory");
+ __hard_irq_disable();
#else
arch_local_irq_save();
#endif