Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [PATCH] Alchemy: fix edge irq handling
@ 2009-01-20 10:03 Manuel Lauss
  2009-01-21  0:47 ` Kevin Hickey
  0 siblings, 1 reply; 5+ messages in thread
From: Manuel Lauss @ 2009-01-20 10:03 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Linux-MIPS

Introduce separate mack_ack callbacks which really do shut up the
edge-triggered irqs when called.  Without this change, high-frequency
edge interrupts can result in an endless irq storm, hanging the system.

This can be easily triggered for example by setting an irq to falling
edge type and manually connecting the associated pin to ground.

Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net>
---
 arch/mips/alchemy/common/irq.c |   32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index c88c821..60da581 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -320,6 +320,16 @@ static void au1x_ic0_mask(unsigned int irq_nr)
 	au_sync();
 }
 
+static void au1x_ic0_maskack(unsigned int irq_nr)
+{
+	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+	au_writel(1 << bit, IC0_MASKCLR);
+	au_writel(1 << bit, IC0_WAKECLR);
+	au_writel(1 << bit, IC0_FALLINGCLR);
+	au_writel(1 << bit, IC0_RISINGCLR);
+	au_sync();
+}
+
 static void au1x_ic1_mask(unsigned int irq_nr)
 {
 	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
@@ -328,6 +338,16 @@ static void au1x_ic1_mask(unsigned int irq_nr)
 	au_sync();
 }
 
+static void au1x_ic1_maskack(unsigned int irq_nr)
+{
+	unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+	au_writel(1 << bit, IC1_MASKCLR);
+	au_writel(1 << bit, IC1_WAKECLR);
+	au_writel(1 << bit, IC1_FALLINGCLR);
+	au_writel(1 << bit, IC1_RISINGCLR);
+	au_sync();
+}
+
 static void au1x_ic0_ack(unsigned int irq_nr)
 {
 	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
@@ -379,25 +399,21 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
 /*
  * irq_chips for both ICs; this way the mask handlers can be
  * as short as possible.
- *
- * NOTE: the ->ack() callback is used by the handle_edge_irq
- *	 flowhandler only, the ->mask_ack() one by handle_level_irq,
- *	 so no need for an irq_chip for each type of irq (level/edge).
  */
 static struct irq_chip au1x_ic0_chip = {
 	.name		= "Alchemy-IC0",
-	.ack		= au1x_ic0_ack,		/* edge */
+	.ack		= au1x_ic0_ack,
 	.mask		= au1x_ic0_mask,
-	.mask_ack	= au1x_ic0_mask,	/* level */
+	.mask_ack	= au1x_ic0_maskack,
 	.unmask		= au1x_ic0_unmask,
 	.set_type	= au1x_ic_settype,
 };
 
 static struct irq_chip au1x_ic1_chip = {
 	.name		= "Alchemy-IC1",
-	.ack		= au1x_ic1_ack,		/* edge */
+	.ack		= au1x_ic1_ack,
 	.mask		= au1x_ic1_mask,
-	.mask_ack	= au1x_ic1_mask,	/* level */
+	.mask_ack	= au1x_ic1_maskack,
 	.unmask		= au1x_ic1_unmask,
 	.set_type	= au1x_ic_settype,
 	.set_wake	= au1x_ic1_setwake,
-- 
1.6.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-01-27  6:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-20 10:03 [PATCH] Alchemy: fix edge irq handling Manuel Lauss
2009-01-21  0:47 ` Kevin Hickey
2009-01-21  6:48   ` Manuel Lauss
2009-01-27  2:18     ` Kevin Hickey
2009-01-27  6:20       ` Manuel Lauss

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox