From f1c5232f4d5c06b341341304de02596ca3d83c62 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 15 Jan 2015 12:19:20 +0000
Subject: [PATCH] ar71xx: fix disable_irq() on chained irq handlers

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

SVN-Revision: 43974
---
 ...6-MIPS-ath79-fix-chained-irq-disable.patch | 93 +++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 target/linux/ar71xx/patches-3.14/736-MIPS-ath79-fix-chained-irq-disable.patch

diff --git a/target/linux/ar71xx/patches-3.14/736-MIPS-ath79-fix-chained-irq-disable.patch b/target/linux/ar71xx/patches-3.14/736-MIPS-ath79-fix-chained-irq-disable.patch
new file mode 100644
index 0000000000..8cb38d3971
--- /dev/null
+++ b/target/linux/ar71xx/patches-3.14/736-MIPS-ath79-fix-chained-irq-disable.patch
@@ -0,0 +1,93 @@
+--- a/arch/mips/ath79/irq.c
++++ b/arch/mips/ath79/irq.c
+@@ -26,6 +26,8 @@
+ 
+ static void (*ath79_ip2_handler)(void);
+ static void (*ath79_ip3_handler)(void);
++static struct irq_chip ip2_chip;
++static struct irq_chip ip3_chip;
+ 
+ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
+ {
+@@ -149,8 +151,7 @@ static void ar934x_ip2_irq_init(void)
+ 
+ 	for (i = ATH79_IP2_IRQ_BASE;
+ 	     i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
+-		irq_set_chip_and_handler(i, &dummy_irq_chip,
+-					 handle_level_irq);
++		irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq);
+ 
+ 	irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch);
+ }
+@@ -224,15 +225,13 @@ static void qca955x_irq_init(void)
+ 
+ 	for (i = ATH79_IP2_IRQ_BASE;
+ 	     i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
+-		irq_set_chip_and_handler(i, &dummy_irq_chip,
+-					 handle_level_irq);
++		irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq);
+ 
+ 	irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch);
+ 
+ 	for (i = ATH79_IP3_IRQ_BASE;
+ 	     i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++)
+-		irq_set_chip_and_handler(i, &dummy_irq_chip,
+-					 handle_level_irq);
++		irq_set_chip_and_handler(i, &ip3_chip, handle_level_irq);
+ 
+ 	irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
+ }
+@@ -313,15 +312,13 @@ static void qca956x_irq_init(void)
+ 
+ 	for (i = ATH79_IP2_IRQ_BASE;
+ 	     i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
+-		irq_set_chip_and_handler(i, &dummy_irq_chip,
+-					 handle_level_irq);
++		irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq);
+ 
+ 	irq_set_chained_handler(ATH79_CPU_IRQ(2), qca956x_ip2_irq_dispatch);
+ 
+ 	for (i = ATH79_IP3_IRQ_BASE;
+ 	     i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++)
+-		irq_set_chip_and_handler(i, &dummy_irq_chip,
+-					 handle_level_irq);
++		irq_set_chip_and_handler(i, &ip3_chip, handle_level_irq);
+ 
+ 	irq_set_chained_handler(ATH79_CPU_IRQ(3), qca956x_ip3_irq_dispatch);
+ 
+@@ -430,8 +427,35 @@ static void ar934x_ip3_handler(void)
+ 	do_IRQ(ATH79_CPU_IRQ(3));
+ }
+ 
++static void ath79_ip2_disable(struct irq_data *data)
++{
++	disable_irq(ATH79_CPU_IRQ(2));
++}
++
++static void ath79_ip2_enable(struct irq_data *data)
++{
++	enable_irq(ATH79_CPU_IRQ(2));
++}
++
++static void ath79_ip3_disable(struct irq_data *data)
++{
++	disable_irq(ATH79_CPU_IRQ(3));
++}
++
++static void ath79_ip3_enable(struct irq_data *data)
++{
++	enable_irq(ATH79_CPU_IRQ(3));
++}
++
+ void __init arch_init_irq(void)
+ {
++	ip2_chip = dummy_irq_chip;
++	ip3_chip = dummy_irq_chip;
++	ip2_chip.irq_disable = ath79_ip2_disable;
++	ip2_chip.irq_enable = ath79_ip2_enable;
++	ip3_chip.irq_disable = ath79_ip3_disable;
++	ip3_chip.irq_enable = ath79_ip3_enable;
++
+ 	if (soc_is_ar71xx()) {
+ 		ath79_ip2_handler = ar71xx_ip2_handler;
+ 		ath79_ip3_handler = ar71xx_ip3_handler;
-- 
2.30.2