From 3b0dba382bf5e3664a5e06de1092cca04cffcd59 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 20 Jun 2012 21:57:45 +0000
Subject: [PATCH] do not use MULTI_IRQ_HANDLER it is bogus on our platform

This caused stalls in the Ethernet DMA block, so until properly
written and sorted out, fallback to the assembly version instead.

SVN-Revision: 32470
---
 .../mach-mcs814x/include/mach/entry-macro.S   | 23 +++++++++++++++++++
 .../files-3.3/arch/arm/mach-mcs814x/irq.c     | 22 +-----------------
 .../mcs814x/patches-3.3/001-platform.patch    |  3 +--
 3 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/entry-macro.S b/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/entry-macro.S
index 9974dad293..eeff72ca64 100644
--- a/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/entry-macro.S
+++ b/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/entry-macro.S
@@ -4,3 +4,26 @@
 
 		.macro arch_ret_to_user, tmp1, tmp2
 		.endm
+
+		.macro  get_irqnr_preamble, base, tmp
+		ldr	\base, =mcs814x_intc_base	@ base virtual address of AIC peripheral
+		ldr	\base, [\base]
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	\tmp, #0x40
+		ldr	\irqstat, [\base, \tmp]
+		tst	\irqstat, \irqstat       @ test if no active IRQ's
+		beq	1002f                    @ if no active irqs return with status 0
+		mov	\irqnr, #0               @ start from irq zero
+		mov	\tmp,   #1               @ the mask initially 1
+1001:
+		tst     \irqstat, \tmp           @ and with mask
+		addeq   \irqnr, \irqnr, #1       @ if  zero then add one to nr
+		moveq   \tmp,   \tmp, lsl #1     @ shift mask one to left
+		beq     1001b                    @ if  zero then loop again
+		mov     \irqstat, \tmp           @ save the return mask
+		mov	\tmp, #0x00		 @ ICR offset
+		str     \irqstat,  [\base, \tmp] @ clear irq with selected mask
+1002:
+                .endm
diff --git a/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c b/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c
index cf86734afb..c8a3c18cfb 100644
--- a/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c
+++ b/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c
@@ -20,7 +20,7 @@
 #define MCS814X_IRQ_MASK	0x20
 #define MCS814X_IRQ_STS0	0x40
 
-static void __iomem *mcs814x_intc_base;
+void __iomem *mcs814x_intc_base;
 
 static void __init mcs814x_alloc_gc(void __iomem *base, unsigned int irq_start,
 					unsigned int num)
@@ -47,26 +47,6 @@ static void __init mcs814x_alloc_gc(void __iomem *base, unsigned int irq_start,
 	__raw_writel(0xffffffff, base + MCS814X_IRQ_ICR);
 }
 
-asmlinkage void __exception_irq_entry mcs814x_handle_irq(struct pt_regs *regs)
-{
-	u32 status, irq;
-
-	do {
-		/* read the status register */
-		status = __raw_readl(mcs814x_intc_base + MCS814X_IRQ_STS0);
-		if (!status)
-			break;
-
-		irq = ffs(status) - 1;
-		status |= (1 << irq);
-		/* clear the interrupt */
-		__raw_writel(status, mcs814x_intc_base + MCS814X_IRQ_ICR);
-		/* call the generic handler */
-		handle_IRQ(irq, regs);
-
-	} while (1);
-}
-
 static const struct of_device_id mcs814x_intc_ids[] = {
 	{ .compatible = "moschip,mcs814x-intc" },
 	{ /* sentinel */ },
diff --git a/target/linux/mcs814x/patches-3.3/001-platform.patch b/target/linux/mcs814x/patches-3.3/001-platform.patch
index dc153a5d4e..fbe79af594 100644
--- a/target/linux/mcs814x/patches-3.3/001-platform.patch
+++ b/target/linux/mcs814x/patches-3.3/001-platform.patch
@@ -1,6 +1,6 @@
 --- a/arch/arm/Kconfig
 +++ b/arch/arm/Kconfig
-@@ -869,6 +869,21 @@ config ARCH_EXYNOS
+@@ -869,6 +869,20 @@ config ARCH_EXYNOS
  	help
  	  Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5)
  
@@ -15,7 +15,6 @@
 +	select CLKDEV_LOOKUP
 +	select ARCH_USES_GETTIMEOFFSET
 +	select NEED_MACH_MEMORY_H
-+	select MULTI_IRQ_HANDLER
 +	help
 +	  Support for Moschip MCS814x SoCs (MCS8140).
 +
-- 
GitLab