ar71xx: use AR8327 on the DB120 board
[openwrt.git] / target / linux / ar71xx / patches-3.3 / 126-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch
1 From e69d89040d4884ea4069352338f555694e65fe70 Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Fri, 9 Dec 2011 21:30:03 +0100
4 Subject: [PATCH 26/35] MIPS: ath79: rework IP2/IP3 interrupt handling
5
6 The current implementation assumes that flushing the
7 DDR writeback buffer is required for IP2/IP3 interrupts,
8 however this is not true for all SoCs.
9
10 Use SoC specific IP2/IP3 handlers instead of flushing
11 the buffers in the dispatcher code.
12
13 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
14 Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
15 ---
16  arch/mips/ath79/irq.c |   92 ++++++++++++++++++++++++++++++++++++++-----------
17  1 files changed, 72 insertions(+), 20 deletions(-)
18
19 --- a/arch/mips/ath79/irq.c
20 +++ b/arch/mips/ath79/irq.c
21 @@ -1,7 +1,7 @@
22  /*
23   *  Atheros AR71xx/AR724x/AR913x specific interrupt handling
24   *
25 - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
26 + *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
27   *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
28   *
29   *  Parts of this file are based on Atheros' 2.6.15 BSP
30 @@ -23,8 +23,8 @@
31  #include <asm/mach-ath79/ar71xx_regs.h>
32  #include "common.h"
33  
34 -static unsigned int ath79_ip2_flush_reg;
35 -static unsigned int ath79_ip3_flush_reg;
36 +static void (*ath79_ip2_handler)(void);
37 +static void (*ath79_ip3_handler)(void);
38  
39  static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
40  {
41 @@ -152,10 +152,8 @@ asmlinkage void plat_irq_dispatch(void)
42         if (pending & STATUSF_IP7)
43                 do_IRQ(ATH79_CPU_IRQ_TIMER);
44  
45 -       else if (pending & STATUSF_IP2) {
46 -               ath79_ddr_wb_flush(ath79_ip2_flush_reg);
47 -               do_IRQ(ATH79_CPU_IRQ_IP2);
48 -       }
49 +       else if (pending & STATUSF_IP2)
50 +               ath79_ip2_handler();
51  
52         else if (pending & STATUSF_IP4)
53                 do_IRQ(ATH79_CPU_IRQ_GE0);
54 @@ -163,10 +161,8 @@ asmlinkage void plat_irq_dispatch(void)
55         else if (pending & STATUSF_IP5)
56                 do_IRQ(ATH79_CPU_IRQ_GE1);
57  
58 -       else if (pending & STATUSF_IP3) {
59 -               ath79_ddr_wb_flush(ath79_ip3_flush_reg);
60 -               do_IRQ(ATH79_CPU_IRQ_USB);
61 -       }
62 +       else if (pending & STATUSF_IP3)
63 +               ath79_ip3_handler();
64  
65         else if (pending & STATUSF_IP6)
66                 do_IRQ(ATH79_CPU_IRQ_MISC);
67 @@ -175,22 +171,78 @@ asmlinkage void plat_irq_dispatch(void)
68                 spurious_interrupt();
69  }
70  
71 +/*
72 + * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
73 + * these devices typically allocate coherent DMA memory, however the
74 + * DMA controller may still have some unsynchronized data in the FIFO.
75 + * Issue a flush in the handlers to ensure that the driver sees
76 + * the update.
77 + */
78 +static void ar71xx_ip2_handler(void)
79 +{
80 +       ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI);
81 +       do_IRQ(ATH79_CPU_IRQ_IP2);
82 +}
83 +
84 +static void ar724x_ip2_handler(void)
85 +{
86 +       ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE);
87 +       do_IRQ(ATH79_CPU_IRQ_IP2);
88 +}
89 +
90 +static void ar913x_ip2_handler(void)
91 +{
92 +       ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC);
93 +       do_IRQ(ATH79_CPU_IRQ_IP2);
94 +}
95 +
96 +static void ar933x_ip2_handler(void)
97 +{
98 +       ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC);
99 +       do_IRQ(ATH79_CPU_IRQ_IP2);
100 +}
101 +
102 +static void ar71xx_ip3_handler(void)
103 +{
104 +       ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB);
105 +       do_IRQ(ATH79_CPU_IRQ_USB);
106 +}
107 +
108 +static void ar724x_ip3_handler(void)
109 +{
110 +       ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB);
111 +       do_IRQ(ATH79_CPU_IRQ_USB);
112 +}
113 +
114 +static void ar913x_ip3_handler(void)
115 +{
116 +       ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB);
117 +       do_IRQ(ATH79_CPU_IRQ_USB);
118 +}
119 +
120 +static void ar933x_ip3_handler(void)
121 +{
122 +       ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB);
123 +       do_IRQ(ATH79_CPU_IRQ_USB);
124 +}
125 +
126  void __init arch_init_irq(void)
127  {
128         if (soc_is_ar71xx()) {
129 -               ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
130 -               ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB;
131 +               ath79_ip2_handler = ar71xx_ip2_handler;
132 +               ath79_ip3_handler = ar71xx_ip3_handler;
133         } else if (soc_is_ar724x()) {
134 -               ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
135 -               ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB;
136 +               ath79_ip2_handler = ar724x_ip2_handler;
137 +               ath79_ip3_handler = ar724x_ip3_handler;
138         } else if (soc_is_ar913x()) {
139 -               ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
140 -               ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
141 +               ath79_ip2_handler = ar913x_ip2_handler;
142 +               ath79_ip3_handler = ar913x_ip3_handler;
143         } else if (soc_is_ar933x()) {
144 -               ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC;
145 -               ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB;
146 -       } else
147 +               ath79_ip2_handler = ar933x_ip2_handler;
148 +               ath79_ip3_handler = ar933x_ip3_handler;
149 +       } else {
150                 BUG();
151 +       }
152  
153         cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
154         mips_cpu_irq_init();