Subject: [PATCH] [POWERPC] Fix QEIC->MPIC cascading

From: Anton Vorontsov <[email-masked]>
Date: Thu, 20 Sep 2007 17:02:44 +0400

set_irq_chained_handler overwrites MPIC's handle_irq function
(handle_fasteoi_irq) thus MPIC never gets eoi event from the
cascaded IRQ. This situation hangs MPIC on MPC8568E.

Patch adds flow level "end" handler to the MPIC, and QEIC calls
it when QEIC's interrupt processing finished.

Signed-off-by: Anton Vorontsov <[email-masked]>
---
 arch/powerpc/sysdev/mpic.c         |    3 +++
 arch/powerpc/sysdev/qe_lib/qe_ic.c |    6 ++++++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 8de29f2..bee2d5b 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -846,6 +846,7 @@ static struct irq_chip mpic_irq_chip = {
 	.mask		= mpic_mask_irq,
 	.unmask		= mpic_unmask_irq,
 	.eoi		= mpic_end_irq,
+	.end		= mpic_end_irq,
 	.set_type	= mpic_set_irq_type,
 };
 
@@ -854,6 +855,7 @@ static struct irq_chip mpic_ipi_chip = {
 	.mask		= mpic_mask_ipi,
 	.unmask		= mpic_unmask_ipi,
 	.eoi		= mpic_end_ipi,
+	.end		= mpic_end_ipi,
 };
 #endif /* CONFIG_SMP */
 
@@ -864,6 +866,7 @@ static struct irq_chip mpic_irq_ht_chip = {
 	.mask		= mpic_mask_irq,
 	.unmask		= mpic_unmask_ht_irq,
 	.eoi		= mpic_end_ht_irq,
+	.end		= mpic_end_ht_irq,
 	.set_type	= mpic_set_irq_type,
 };
 #endif /* CONFIG_MPIC_U3_HT_IRQS */
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 55e6f39..8e743e0 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -328,6 +328,9 @@ void qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc)
 
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
+
+	if (desc->chip->end)
+		desc->chip->end(irq);
 }
 
 void qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc)
@@ -337,6 +340,9 @@ void qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc)
 
 	if (cascade_irq != NO_IRQ)
 		generic_handle_irq(cascade_irq);
+
+	if (desc->chip->end)
+		desc->chip->end(irq);
 }
 
 void __init qe_ic_init(struct device_node *node, unsigned int flags)
-- 
1.5.0.6