Received: from mail.onstor.com (66.201.51.107) by exch1.onstor.net
 (10.0.0.225) with Microsoft SMTP Server id 8.1.311.2; Tue, 20 Jan 2009
 02:08:02 -0800
Received: from dalesmta2-3.messageone.com ([129.41.169.249]) by
 mail.onstor.com with Microsoft SMTPSVC(6.0.3790.3959);	 Tue, 20 Jan 2009
 02:08:01 -0800
Received: from ftp.linux-mips.org (ftp.linux-mips.org [213.58.128.207])	by
 dalesmta2-3.messageone.com (8.13.8/8.13.8) with ESMTP id n0KA80bT017337	for
 <andy.sharp@onstor.com>; Tue, 20 Jan 2009 04:08:00 -0600
Received: from localhost.localdomain ([127.0.0.1]:30850 "EHLO
	ftp.linux-mips.org") by ftp.linux-mips.org with ESMTP	id S21366209AbZATKEN
 (ORCPT <rfc822;andy.sharp@onstor.com>);	Tue, 20 Jan 2009 10:04:13 +0000
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 20 Jan 2009 10:03:56
 +0000 (GMT)
Received: from fnoeppeil36.netpark.at ([217.175.205.164]:7629 "EHLO
	roarinelk.homelinux.net") by ftp.linux-mips.org with ESMTP	id
 S21366208AbZATKDy (ORCPT <rfc822;linux-mips@linux-mips.org>);	Tue, 20 Jan
 2009 10:03:54 +0000
Received: (qmail 19003 invoked by uid 1000); 20 Jan 2009 11:03:53 +0100
From: Manuel Lauss <mano@roarinelk.homelinux.net>
To: Ralf Baechle <ralf@linux-mips.org>
CC: Linux-MIPS <linux-mips@linux-mips.org>
Sender: "linux-mips-bounce@linux-mips.org" <linux-mips-bounce@linux-mips.org>
Date: Tue, 20 Jan 2009 02:03:53 -0800
Subject: [PATCH] Alchemy: fix edge irq handling
Thread-Topic: [PATCH] Alchemy: fix edge irq handling
Thread-Index: Acl65vsUc9rOnghnRayh655k9+FDZQ==
Message-ID: <20090120100353.GA18971@roarinelk.homelinux.net>
Accept-Language: en-US
Content-Language: en-US
X-MS-Exchange-Organization-AuthAs: Internal
X-MS-Exchange-Organization-AuthMechanism: 0b
X-MS-Exchange-Organization-AuthSource: exch1.onstor.net
X-MS-Has-Attach:
X-Auto-Response-Suppress: All
X-MS-TNEF-Correlator:
x-originalarrivaltime: 20 Jan 2009 10:08:01.0713 (UTC)
 FILETIME=[FA4C2210:01C97AE6]
user-agent: Mutt/1.5.16 (2007-06-09)
errors-to: linux-mips-bounce@linux-mips.org
x-ems-proccessed: 2K3Xl1OQTInXD6xxuA8z3Q==
x-ems-stamp: 8N9/G1M4P0GK7MuFa4JdWA==
x-messageone-virus-version: vendor=fsecure
 engine=4.65.7400:2.4.4,1.2.40,4.0.164
 definitions=2009-01-20_02:2009-01-18,2009-01-20,2009-01-20 signatures=0
x-messageone-virus-scanned: Clean
x-messageone-envelope-sender: linux-mips-bounce@linux-mips.org
x-messageone-spam-details: rule=m773emszm_notspam policy=m773emszm score=0
 spamscore=0 ipscore=0 phishscore=0 bulkscore=0 adultscore=0 classifier=spam
 adjust=0 reason=mlx engine=3.1.0-0810130000 definitions=main-0901200017
x-messageone-spam-score: 0
x-messageone-spam-bar:
x-list: linux-mips
x-archive-position: 21784
x-ecartis-version: Ecartis v1.0.0
x-original-sender: mano@roarinelk.homelinux.net
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0

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();
 }
=20
+static void au1x_ic0_maskack(unsigned int irq_nr)
+{
+	unsigned int bit =3D 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 =3D irq_nr - AU1000_INTC1_INT_BASE;
@@ -328,6 +338,16 @@ static void au1x_ic1_mask(unsigned int irq_nr)
 	au_sync();
 }
=20
+static void au1x_ic1_maskack(unsigned int irq_nr)
+{
+	unsigned int bit =3D 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 =3D irq_nr - AU1000_INTC0_INT_BASE;
@@ -379,25 +399,21 @@ static int au1x_ic1_setwake(unsigned int irq, unsigne=
d 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 =3D {
 	.name		=3D "Alchemy-IC0",
-	.ack		=3D au1x_ic0_ack,		/* edge */
+	.ack		=3D au1x_ic0_ack,
 	.mask		=3D au1x_ic0_mask,
-	.mask_ack	=3D au1x_ic0_mask,	/* level */
+	.mask_ack	=3D au1x_ic0_maskack,
 	.unmask		=3D au1x_ic0_unmask,
 	.set_type	=3D au1x_ic_settype,
 };
=20
 static struct irq_chip au1x_ic1_chip =3D {
 	.name		=3D "Alchemy-IC1",
-	.ack		=3D au1x_ic1_ack,		/* edge */
+	.ack		=3D au1x_ic1_ack,
 	.mask		=3D au1x_ic1_mask,
-	.mask_ack	=3D au1x_ic1_mask,	/* level */
+	.mask_ack	=3D au1x_ic1_maskack,
 	.unmask		=3D au1x_ic1_unmask,
 	.set_type	=3D au1x_ic_settype,
 	.set_wake	=3D au1x_ic1_setwake,
--=20
1.6.1


