--- /dev/null
+From 1690e8f8efdeedbd23bb34a3bc5803c34f2d3f66 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Tue, 29 Jan 2013 16:13:17 +0000
+Subject: [PATCH] MIPS: ath79: simplify MISC IRQ handling
+
+commit 9c099c4e79b67d5578ce8142e6214950be4fcf43 upstream.
+
+The current code uses multiple if statements for
+demultiplexing the different interrupt sources.
+Additionally, the MISC interrupt controller has
+32 interrupt sources and the current code does not
+handles all of them.
+
+Get rid of the if statements and process all interrupt
+sources in a loop to fix these issues.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+Patchwork: http://patchwork.linux-mips.org/patch/4874/
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ath79/irq.c | 45 +++++++-------------------------
+ arch/mips/include/asm/mach-ath79/irq.h | 1 +
+ 2 files changed, 10 insertions(+), 36 deletions(-)
+
+--- a/arch/mips/ath79/irq.c
++++ b/arch/mips/ath79/irq.c
+@@ -35,44 +35,17 @@ static void ath79_misc_irq_handler(unsig
+ pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+- if (pending & MISC_INT_UART)
+- generic_handle_irq(ATH79_MISC_IRQ_UART);
+-
+- else if (pending & MISC_INT_DMA)
+- generic_handle_irq(ATH79_MISC_IRQ_DMA);
+-
+- else if (pending & MISC_INT_PERFC)
+- generic_handle_irq(ATH79_MISC_IRQ_PERFC);
+-
+- else if (pending & MISC_INT_TIMER)
+- generic_handle_irq(ATH79_MISC_IRQ_TIMER);
+-
+- else if (pending & MISC_INT_TIMER2)
+- generic_handle_irq(ATH79_MISC_IRQ_TIMER2);
+-
+- else if (pending & MISC_INT_TIMER3)
+- generic_handle_irq(ATH79_MISC_IRQ_TIMER3);
+-
+- else if (pending & MISC_INT_TIMER4)
+- generic_handle_irq(ATH79_MISC_IRQ_TIMER4);
+-
+- else if (pending & MISC_INT_OHCI)
+- generic_handle_irq(ATH79_MISC_IRQ_OHCI);
+-
+- else if (pending & MISC_INT_ERROR)
+- generic_handle_irq(ATH79_MISC_IRQ_ERROR);
+-
+- else if (pending & MISC_INT_GPIO)
+- generic_handle_irq(ATH79_MISC_IRQ_GPIO);
+-
+- else if (pending & MISC_INT_WDOG)
+- generic_handle_irq(ATH79_MISC_IRQ_WDOG);
++ if (!pending) {
++ spurious_interrupt();
++ return;
++ }
+
+- else if (pending & MISC_INT_ETHSW)
+- generic_handle_irq(ATH79_MISC_IRQ_ETHSW);
++ while (pending) {
++ int bit = __ffs(pending);
+
+- else
+- spurious_interrupt();
++ generic_handle_irq(ATH79_MISC_IRQ(bit));
++ pending &= ~BIT(bit);
++ }
+ }
+
+ static void ar71xx_misc_irq_unmask(struct irq_data *d)
+--- a/arch/mips/include/asm/mach-ath79/irq.h
++++ b/arch/mips/include/asm/mach-ath79/irq.h
+@@ -14,6 +14,7 @@
+
+ #define ATH79_MISC_IRQ_BASE 8
+ #define ATH79_MISC_IRQ_COUNT 32
++#define ATH79_MISC_IRQ(_x) (ATH79_MISC_IRQ_BASE + (_x))
+
+ #define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT)
+ #define ATH79_PCI_IRQ_COUNT 6
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
-@@ -130,7 +130,10 @@ static void __init ath79_misc_irq_init(v
+@@ -103,7 +103,10 @@ static void __init ath79_misc_irq_init(v
if (soc_is_ar71xx() || soc_is_ar913x())
ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
else
BUG();
-@@ -177,6 +180,88 @@ static void ar934x_ip2_irq_init(void)
+@@ -150,6 +153,88 @@ static void ar934x_ip2_irq_init(void)
irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch);
}
asmlinkage void plat_irq_dispatch(void)
{
unsigned long pending;
-@@ -212,6 +297,17 @@ asmlinkage void plat_irq_dispatch(void)
+@@ -185,6 +270,17 @@ asmlinkage void plat_irq_dispatch(void)
* Issue a flush in the handlers to ensure that the driver sees
* the update.
*/
static void ar71xx_ip2_handler(void)
{
ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI);
-@@ -236,11 +332,6 @@ static void ar933x_ip2_handler(void)
+@@ -209,11 +305,6 @@ static void ar933x_ip2_handler(void)
do_IRQ(ATH79_CPU_IRQ_IP2);
}
static void ar71xx_ip3_handler(void)
{
ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB);
-@@ -286,8 +377,11 @@ void __init arch_init_irq(void)
+@@ -259,8 +350,11 @@ void __init arch_init_irq(void)
ath79_ip2_handler = ar933x_ip2_handler;
ath79_ip3_handler = ar933x_ip3_handler;
} else if (soc_is_ar934x()) {
} else {
BUG();
}
-@@ -298,4 +392,6 @@ void __init arch_init_irq(void)
+@@ -271,4 +365,6 @@ void __init arch_init_irq(void)
if (soc_is_ar934x())
ar934x_ip2_irq_init();
#define ATH79_MISC_IRQ_BASE 8
#define ATH79_MISC_IRQ_COUNT 32
-@@ -23,8 +23,13 @@
+@@ -24,8 +24,13 @@
#define ATH79_IP2_IRQ_COUNT 2
#define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x))
+++ /dev/null
---- a/arch/mips/ath79/irq.c
-+++ b/arch/mips/ath79/irq.c
-@@ -35,44 +35,17 @@ static void ath79_misc_irq_handler(unsig
- pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
- __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-
-- if (pending & MISC_INT_UART)
-- generic_handle_irq(ATH79_MISC_IRQ_UART);
--
-- else if (pending & MISC_INT_DMA)
-- generic_handle_irq(ATH79_MISC_IRQ_DMA);
--
-- else if (pending & MISC_INT_PERFC)
-- generic_handle_irq(ATH79_MISC_IRQ_PERFC);
--
-- else if (pending & MISC_INT_TIMER)
-- generic_handle_irq(ATH79_MISC_IRQ_TIMER);
--
-- else if (pending & MISC_INT_TIMER2)
-- generic_handle_irq(ATH79_MISC_IRQ_TIMER2);
--
-- else if (pending & MISC_INT_TIMER3)
-- generic_handle_irq(ATH79_MISC_IRQ_TIMER3);
--
-- else if (pending & MISC_INT_TIMER4)
-- generic_handle_irq(ATH79_MISC_IRQ_TIMER4);
--
-- else if (pending & MISC_INT_OHCI)
-- generic_handle_irq(ATH79_MISC_IRQ_OHCI);
--
-- else if (pending & MISC_INT_ERROR)
-- generic_handle_irq(ATH79_MISC_IRQ_ERROR);
--
-- else if (pending & MISC_INT_GPIO)
-- generic_handle_irq(ATH79_MISC_IRQ_GPIO);
--
-- else if (pending & MISC_INT_WDOG)
-- generic_handle_irq(ATH79_MISC_IRQ_WDOG);
-+ if (!pending) {
-+ spurious_interrupt();
-+ return;
-+ }
-
-- else if (pending & MISC_INT_ETHSW)
-- generic_handle_irq(ATH79_MISC_IRQ_ETHSW);
-+ while (pending) {
-+ int bit = __ffs(pending);
-
-- else
-- spurious_interrupt();
-+ generic_handle_irq(ATH79_MISC_IRQ(bit));
-+ pending &= ~BIT(bit);
-+ }
- }
-
- static void ar71xx_misc_irq_unmask(struct irq_data *d)
---- a/arch/mips/include/asm/mach-ath79/irq.h
-+++ b/arch/mips/include/asm/mach-ath79/irq.h
-@@ -14,6 +14,7 @@
-
- #define ATH79_MISC_IRQ_BASE 8
- #define ATH79_MISC_IRQ_COUNT 32
-+#define ATH79_MISC_IRQ(_x) (ATH79_MISC_IRQ_BASE + (_x))
-
- #define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT)
- #define ATH79_PCI_IRQ_COUNT 6