diff options
Diffstat (limited to 'target/linux/ar71xx/patches-3.3/126-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch')
| -rw-r--r-- | target/linux/ar71xx/patches-3.3/126-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch | 154 | 
1 files changed, 154 insertions, 0 deletions
| diff --git a/target/linux/ar71xx/patches-3.3/126-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch b/target/linux/ar71xx/patches-3.3/126-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch new file mode 100644 index 000000000..144acacf4 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/126-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch @@ -0,0 +1,154 @@ +From e69d89040d4884ea4069352338f555694e65fe70 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos <juhosg@openwrt.org> +Date: Fri, 9 Dec 2011 21:30:03 +0100 +Subject: [PATCH 26/35] MIPS: ath79: rework IP2/IP3 interrupt handling + +The current implementation assumes that flushing the +DDR writeback buffer is required for IP2/IP3 interrupts, +however this is not true for all SoCs. + +Use SoC specific IP2/IP3 handlers instead of flushing +the buffers in the dispatcher code. + +Signed-off-by: Gabor Juhos <juhosg@openwrt.org> +Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com> +--- + arch/mips/ath79/irq.c |   92 ++++++++++++++++++++++++++++++++++++++----------- + 1 files changed, 72 insertions(+), 20 deletions(-) + +--- a/arch/mips/ath79/irq.c ++++ b/arch/mips/ath79/irq.c +@@ -1,7 +1,7 @@ + /* +  *  Atheros AR71xx/AR724x/AR913x specific interrupt handling +  * +- *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> ++ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> +  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> +  * +  *  Parts of this file are based on Atheros' 2.6.15 BSP +@@ -23,8 +23,8 @@ + #include <asm/mach-ath79/ar71xx_regs.h> + #include "common.h" +  +-static unsigned int ath79_ip2_flush_reg; +-static unsigned int ath79_ip3_flush_reg; ++static void (*ath79_ip2_handler)(void); ++static void (*ath79_ip3_handler)(void); +  + static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) + { +@@ -152,10 +152,8 @@ asmlinkage void plat_irq_dispatch(void) + 	if (pending & STATUSF_IP7) + 		do_IRQ(ATH79_CPU_IRQ_TIMER); +  +-	else if (pending & STATUSF_IP2) { +-		ath79_ddr_wb_flush(ath79_ip2_flush_reg); +-		do_IRQ(ATH79_CPU_IRQ_IP2); +-	} ++	else if (pending & STATUSF_IP2) ++		ath79_ip2_handler(); +  + 	else if (pending & STATUSF_IP4) + 		do_IRQ(ATH79_CPU_IRQ_GE0); +@@ -163,10 +161,8 @@ asmlinkage void plat_irq_dispatch(void) + 	else if (pending & STATUSF_IP5) + 		do_IRQ(ATH79_CPU_IRQ_GE1); +  +-	else if (pending & STATUSF_IP3) { +-		ath79_ddr_wb_flush(ath79_ip3_flush_reg); +-		do_IRQ(ATH79_CPU_IRQ_USB); +-	} ++	else if (pending & STATUSF_IP3) ++		ath79_ip3_handler(); +  + 	else if (pending & STATUSF_IP6) + 		do_IRQ(ATH79_CPU_IRQ_MISC); +@@ -175,22 +171,78 @@ asmlinkage void plat_irq_dispatch(void) + 		spurious_interrupt(); + } +  ++/* ++ * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for ++ * these devices typically allocate coherent DMA memory, however the ++ * DMA controller may still have some unsynchronized data in the FIFO. ++ * 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); ++	do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ ++static void ar724x_ip2_handler(void) ++{ ++	ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE); ++	do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ ++static void ar913x_ip2_handler(void) ++{ ++	ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC); ++	do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ ++static void ar933x_ip2_handler(void) ++{ ++	ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC); ++	do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ ++static void ar71xx_ip3_handler(void) ++{ ++	ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); ++	do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ ++static void ar724x_ip3_handler(void) ++{ ++	ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB); ++	do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ ++static void ar913x_ip3_handler(void) ++{ ++	ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB); ++	do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ ++static void ar933x_ip3_handler(void) ++{ ++	ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB); ++	do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ + void __init arch_init_irq(void) + { + 	if (soc_is_ar71xx()) { +-		ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI; +-		ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB; ++		ath79_ip2_handler = ar71xx_ip2_handler; ++		ath79_ip3_handler = ar71xx_ip3_handler; + 	} else if (soc_is_ar724x()) { +-		ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE; +-		ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB; ++		ath79_ip2_handler = ar724x_ip2_handler; ++		ath79_ip3_handler = ar724x_ip3_handler; + 	} else if (soc_is_ar913x()) { +-		ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC; +-		ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB; ++		ath79_ip2_handler = ar913x_ip2_handler; ++		ath79_ip3_handler = ar913x_ip3_handler; + 	} else if (soc_is_ar933x()) { +-		ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC; +-		ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB; +-	} else ++		ath79_ip2_handler = ar933x_ip2_handler; ++		ath79_ip3_handler = ar933x_ip3_handler; ++	} else { + 		BUG(); ++	} +  + 	cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; + 	mips_cpu_irq_init(); | 
