diff options
Diffstat (limited to 'arch/powerpc/include/asm/hw_irq.h')
-rw-r--r-- | arch/powerpc/include/asm/hw_irq.h | 49 |
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 |