summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/include')
-rw-r--r--arch/powerpc/include/asm/exception-64s.h4
-rw-r--r--arch/powerpc/include/asm/hw_irq.h30
-rw-r--r--arch/powerpc/include/asm/irqflags.h4
3 files changed, 27 insertions, 11 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 69c4e3d35e02..a21adcb75fc6 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -499,9 +499,9 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
#define __SOFTEN_TEST(h, vec) \
lbz r10,PACASOFTIRQEN(r13); \
- cmpwi r10,IRQS_DISABLED; \
+ andi. r10,r10,IRQS_DISABLED; \
li r10,SOFTEN_VALUE_##vec; \
- beq masked_##h##interrupt
+ bne masked_##h##interrupt
#define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec)
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 52afb1595cb0..f96280ee9540 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -31,8 +31,8 @@
/*
* flags for paca->soft_enabled
*/
-#define IRQS_ENABLED 1
-#define IRQS_DISABLED 0
+#define IRQS_ENABLED 0
+#define IRQS_DISABLED 1
#endif /* CONFIG_PPC64 */
@@ -68,6 +68,18 @@ static inline notrace unsigned long soft_enabled_return(void)
*/
static inline notrace void soft_enabled_set(unsigned long enable)
{
+#ifdef CONFIG_TRACE_IRQFLAGS
+ /*
+ * mask must always include LINUX bit if any are set, and
+ * interrupts don't get replayed until the Linux interrupt is
+ * unmasked. This could be changed to replay partial unmasks
+ * in future, which would allow Linux masks to nest inside
+ * other masks, among other things. For now, be very dumb and
+ * simple.
+ */
+ WARN_ON(mask && !(mask & IRQS_DISABLED));
+#endif
+
asm volatile(
"stb %0,%1(13)"
:
@@ -76,15 +88,19 @@ static inline notrace void soft_enabled_set(unsigned long enable)
: "memory");
}
-static inline notrace unsigned long soft_enabled_set_return(unsigned long enable)
+static inline notrace unsigned long soft_enabled_set_return(unsigned long mask)
{
unsigned long flags;
+#ifdef CONFIG_TRACE_IRQFLAGS
+ WARN_ON(mask && !(mask & IRQS_DISABLED));
+#endif
+
asm volatile(
"lbz %0,%1(13); stb %2,%1(13)"
: "=&r" (flags)
: "i" (offsetof(struct paca_struct, soft_enabled)),
- "r" (enable)
+ "r" (mask)
: "memory");
return flags;
@@ -114,7 +130,7 @@ static inline unsigned long arch_local_irq_save(void)
static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
- return flags == IRQS_DISABLED;
+ return flags & IRQS_DISABLED;
}
static inline bool arch_irqs_disabled(void)
@@ -133,7 +149,7 @@ static inline bool arch_irqs_disabled(void)
#define hard_irq_disable() do { \
unsigned long flags; \
__hard_irq_disable(); \
- flags = soft_enabled_set_return(IRQS_DISABLED); \
+ flags = soft_enabled_set_return(IRQS_DISABLED);\
local_paca->irq_happened |= PACA_IRQ_HARD_DIS; \
if (!arch_irqs_disabled_flags(flags)) \
trace_hardirqs_off(); \
@@ -158,7 +174,7 @@ static inline void may_hard_irq_enable(void)
static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
{
- return (regs->softe == IRQS_DISABLED);
+ return (regs->softe & IRQS_DISABLED);
}
extern bool prep_irq_for_idle(void);
diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h
index 8d9fdc84828d..f1ec012232d9 100644
--- a/arch/powerpc/include/asm/irqflags.h
+++ b/arch/powerpc/include/asm/irqflags.h
@@ -49,11 +49,11 @@
#define RECONCILE_IRQ_STATE(__rA, __rB) \
lbz __rA,PACASOFTIRQEN(r13); \
lbz __rB,PACAIRQHAPPENED(r13); \
- cmpwi cr0,__rA,IRQS_DISABLED;\
+ andi. __rA,__rA,IRQS_DISABLED;\
li __rA,IRQS_DISABLED; \
ori __rB,__rB,PACA_IRQ_HARD_DIS; \
stb __rB,PACAIRQHAPPENED(r13); \
- beq 44f; \
+ bne 44f; \
stb __rA,PACASOFTIRQEN(r13); \
TRACE_DISABLE_INTS; \
44: