aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2012-03-14 05:45:24 -0400
committerRalf Baechle <ralf@linux-mips.org>2012-05-15 11:49:08 -0400
commit4dbcbdf8135def8f704b130305721bdd42a8078b (patch)
treef6b8dec7781a7ece62f55af354ba6f5e49d37fdb /arch/mips
parent5b5b544ed32a1b6ad4d7706fcee530eb67670e71 (diff)
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> Cc: linux-mips@linux-mips.org Cc: mcgrof@infradead.org Patchwork: https://patchwork.linux-mips.org/patch/3509/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/ath79/irq.c92
1 files changed, 72 insertions, 20 deletions
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index 1b073de44680..9f87ade52956 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Atheros AR71xx/AR724x/AR913x specific interrupt handling 2 * Atheros AR71xx/AR724x/AR913x specific interrupt handling
3 * 3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> 4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 * 6 *
7 * Parts of this file are based on Atheros' 2.6.15 BSP 7 * Parts of this file are based on Atheros' 2.6.15 BSP
@@ -23,8 +23,8 @@
23#include <asm/mach-ath79/ar71xx_regs.h> 23#include <asm/mach-ath79/ar71xx_regs.h>
24#include "common.h" 24#include "common.h"
25 25
26static unsigned int ath79_ip2_flush_reg; 26static void (*ath79_ip2_handler)(void);
27static unsigned int ath79_ip3_flush_reg; 27static void (*ath79_ip3_handler)(void);
28 28
29static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) 29static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
30{ 30{
@@ -152,10 +152,8 @@ asmlinkage void plat_irq_dispatch(void)
152 if (pending & STATUSF_IP7) 152 if (pending & STATUSF_IP7)
153 do_IRQ(ATH79_CPU_IRQ_TIMER); 153 do_IRQ(ATH79_CPU_IRQ_TIMER);
154 154
155 else if (pending & STATUSF_IP2) { 155 else if (pending & STATUSF_IP2)
156 ath79_ddr_wb_flush(ath79_ip2_flush_reg); 156 ath79_ip2_handler();
157 do_IRQ(ATH79_CPU_IRQ_IP2);
158 }
159 157
160 else if (pending & STATUSF_IP4) 158 else if (pending & STATUSF_IP4)
161 do_IRQ(ATH79_CPU_IRQ_GE0); 159 do_IRQ(ATH79_CPU_IRQ_GE0);
@@ -163,10 +161,8 @@ asmlinkage void plat_irq_dispatch(void)
163 else if (pending & STATUSF_IP5) 161 else if (pending & STATUSF_IP5)
164 do_IRQ(ATH79_CPU_IRQ_GE1); 162 do_IRQ(ATH79_CPU_IRQ_GE1);
165 163
166 else if (pending & STATUSF_IP3) { 164 else if (pending & STATUSF_IP3)
167 ath79_ddr_wb_flush(ath79_ip3_flush_reg); 165 ath79_ip3_handler();
168 do_IRQ(ATH79_CPU_IRQ_USB);
169 }
170 166
171 else if (pending & STATUSF_IP6) 167 else if (pending & STATUSF_IP6)
172 do_IRQ(ATH79_CPU_IRQ_MISC); 168 do_IRQ(ATH79_CPU_IRQ_MISC);
@@ -175,22 +171,78 @@ asmlinkage void plat_irq_dispatch(void)
175 spurious_interrupt(); 171 spurious_interrupt();
176} 172}
177 173
174/*
175 * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
176 * these devices typically allocate coherent DMA memory, however the
177 * DMA controller may still have some unsynchronized data in the FIFO.
178 * Issue a flush in the handlers to ensure that the driver sees
179 * the update.
180 */
181static void ar71xx_ip2_handler(void)
182{
183 ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI);
184 do_IRQ(ATH79_CPU_IRQ_IP2);
185}
186
187static void ar724x_ip2_handler(void)
188{
189 ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE);
190 do_IRQ(ATH79_CPU_IRQ_IP2);
191}
192
193static void ar913x_ip2_handler(void)
194{
195 ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC);
196 do_IRQ(ATH79_CPU_IRQ_IP2);
197}
198
199static void ar933x_ip2_handler(void)
200{
201 ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC);
202 do_IRQ(ATH79_CPU_IRQ_IP2);
203}
204
205static void ar71xx_ip3_handler(void)
206{
207 ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB);
208 do_IRQ(ATH79_CPU_IRQ_USB);
209}
210
211static void ar724x_ip3_handler(void)
212{
213 ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB);
214 do_IRQ(ATH79_CPU_IRQ_USB);
215}
216
217static void ar913x_ip3_handler(void)
218{
219 ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB);
220 do_IRQ(ATH79_CPU_IRQ_USB);
221}
222
223static void ar933x_ip3_handler(void)
224{
225 ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB);
226 do_IRQ(ATH79_CPU_IRQ_USB);
227}
228
178void __init arch_init_irq(void) 229void __init arch_init_irq(void)
179{ 230{
180 if (soc_is_ar71xx()) { 231 if (soc_is_ar71xx()) {
181 ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI; 232 ath79_ip2_handler = ar71xx_ip2_handler;
182 ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB; 233 ath79_ip3_handler = ar71xx_ip3_handler;
183 } else if (soc_is_ar724x()) { 234 } else if (soc_is_ar724x()) {
184 ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE; 235 ath79_ip2_handler = ar724x_ip2_handler;
185 ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB; 236 ath79_ip3_handler = ar724x_ip3_handler;
186 } else if (soc_is_ar913x()) { 237 } else if (soc_is_ar913x()) {
187 ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC; 238 ath79_ip2_handler = ar913x_ip2_handler;
188 ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB; 239 ath79_ip3_handler = ar913x_ip3_handler;
189 } else if (soc_is_ar933x()) { 240 } else if (soc_is_ar933x()) {
190 ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC; 241 ath79_ip2_handler = ar933x_ip2_handler;
191 ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB; 242 ath79_ip3_handler = ar933x_ip3_handler;
192 } else 243 } else {
193 BUG(); 244 BUG();
245 }
194 246
195 cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; 247 cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
196 mips_cpu_irq_init(); 248 mips_cpu_irq_init();