]> git.karo-electronics.de Git - linux-beck.git/commitdiff
powerpc/book3e: Resend doorbell exceptions to ourself
authorMichael Ellerman <michael@ellerman.id.au>
Fri, 9 Jul 2010 05:34:00 +0000 (15:34 +1000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 9 Jul 2010 06:11:19 +0000 (16:11 +1000)
If we are soft disabled and receive a doorbell exception we don't process
it immediately. This means we need to check on the way out of irq restore
if there are any doorbell exceptions to process.

The problem is at that point we don't know what our regs are, and that
in turn makes xmon unhappy. To workaround the problem, instead of checking
for and processing doorbells, we check for any doorbells and if there were
any we send ourselves another.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/dbell.h
arch/powerpc/kernel/dbell.c
arch/powerpc/kernel/irq.c

index ced7e487ca273590991d2665fe8fcee29fcf6090..0893ab9343a6a791a77c5262bbcfa56ba79b290b 100644 (file)
@@ -29,6 +29,7 @@ enum ppc_dbell {
 
 extern void doorbell_message_pass(int target, int msg);
 extern void doorbell_exception(struct pt_regs *regs);
+extern void doorbell_check_self(void);
 extern void doorbell_setup_this_cpu(void);
 
 static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag)
index f7b518894c804413f04e205a26a7e3a1c3a9b2f0..3307a52d797fb682269723b240d05402aad26fe1 100644 (file)
@@ -81,6 +81,16 @@ out:
        set_irq_regs(old_regs);
 }
 
+void doorbell_check_self(void)
+{
+       struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info);
+
+       if (!info->messages)
+               return;
+
+       ppc_msgsnd(PPC_DBELL, 0, info->tag);
+}
+
 #else /* CONFIG_SMP */
 void doorbell_exception(struct pt_regs *regs)
 {
index 2f6dc7faf6debd85850b10b0cb70798abe4aa35d..8f96d3198905150a2a325ad0297f8d14336ef587 100644 (file)
@@ -156,8 +156,8 @@ notrace void raw_local_irq_restore(unsigned long en)
                return;
 
 #if defined(CONFIG_BOOKE) && defined(CONFIG_SMP)
-       /* Check for pending doorbell interrupts on SMP */
-       doorbell_exception(NULL);
+       /* Check for pending doorbell interrupts and resend to ourself */
+       doorbell_check_self();
 #endif
 
        /*