diff options
Diffstat (limited to 'arch/mips/ath79/irq.c')
-rw-r--r-- | arch/mips/ath79/irq.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 9f87ade52956..90d09fc15398 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c | |||
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR71xx/AR724x/AR913x specific interrupt handling | 2 | * Atheros AR71xx/AR724x/AR913x specific interrupt handling |
3 | * | 3 | * |
4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
4 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
6 | * | 7 | * |
7 | * Parts of this file are based on Atheros' 2.6.15 BSP | 8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP |
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License version 2 as published | 11 | * under the terms of the GNU General Public License version 2 as published |
@@ -129,7 +130,7 @@ static void __init ath79_misc_irq_init(void) | |||
129 | 130 | ||
130 | if (soc_is_ar71xx() || soc_is_ar913x()) | 131 | if (soc_is_ar71xx() || soc_is_ar913x()) |
131 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; | 132 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; |
132 | else if (soc_is_ar724x() || soc_is_ar933x()) | 133 | else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x()) |
133 | ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; | 134 | ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; |
134 | else | 135 | else |
135 | BUG(); | 136 | BUG(); |
@@ -143,6 +144,39 @@ static void __init ath79_misc_irq_init(void) | |||
143 | irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); | 144 | irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); |
144 | } | 145 | } |
145 | 146 | ||
147 | static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) | ||
148 | { | ||
149 | u32 status; | ||
150 | |||
151 | disable_irq_nosync(irq); | ||
152 | |||
153 | status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); | ||
154 | |||
155 | if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { | ||
156 | ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE); | ||
157 | generic_handle_irq(ATH79_IP2_IRQ(0)); | ||
158 | } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { | ||
159 | ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC); | ||
160 | generic_handle_irq(ATH79_IP2_IRQ(1)); | ||
161 | } else { | ||
162 | spurious_interrupt(); | ||
163 | } | ||
164 | |||
165 | enable_irq(irq); | ||
166 | } | ||
167 | |||
168 | static void ar934x_ip2_irq_init(void) | ||
169 | { | ||
170 | int i; | ||
171 | |||
172 | for (i = ATH79_IP2_IRQ_BASE; | ||
173 | i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) | ||
174 | irq_set_chip_and_handler(i, &dummy_irq_chip, | ||
175 | handle_level_irq); | ||
176 | |||
177 | irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch); | ||
178 | } | ||
179 | |||
146 | asmlinkage void plat_irq_dispatch(void) | 180 | asmlinkage void plat_irq_dispatch(void) |
147 | { | 181 | { |
148 | unsigned long pending; | 182 | unsigned long pending; |
@@ -202,6 +236,11 @@ static void ar933x_ip2_handler(void) | |||
202 | do_IRQ(ATH79_CPU_IRQ_IP2); | 236 | do_IRQ(ATH79_CPU_IRQ_IP2); |
203 | } | 237 | } |
204 | 238 | ||
239 | static void ar934x_ip2_handler(void) | ||
240 | { | ||
241 | do_IRQ(ATH79_CPU_IRQ_IP2); | ||
242 | } | ||
243 | |||
205 | static void ar71xx_ip3_handler(void) | 244 | static void ar71xx_ip3_handler(void) |
206 | { | 245 | { |
207 | ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); | 246 | ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); |
@@ -226,6 +265,12 @@ static void ar933x_ip3_handler(void) | |||
226 | do_IRQ(ATH79_CPU_IRQ_USB); | 265 | do_IRQ(ATH79_CPU_IRQ_USB); |
227 | } | 266 | } |
228 | 267 | ||
268 | static void ar934x_ip3_handler(void) | ||
269 | { | ||
270 | ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB); | ||
271 | do_IRQ(ATH79_CPU_IRQ_USB); | ||
272 | } | ||
273 | |||
229 | void __init arch_init_irq(void) | 274 | void __init arch_init_irq(void) |
230 | { | 275 | { |
231 | if (soc_is_ar71xx()) { | 276 | if (soc_is_ar71xx()) { |
@@ -240,6 +285,9 @@ void __init arch_init_irq(void) | |||
240 | } else if (soc_is_ar933x()) { | 285 | } else if (soc_is_ar933x()) { |
241 | ath79_ip2_handler = ar933x_ip2_handler; | 286 | ath79_ip2_handler = ar933x_ip2_handler; |
242 | ath79_ip3_handler = ar933x_ip3_handler; | 287 | ath79_ip3_handler = ar933x_ip3_handler; |
288 | } else if (soc_is_ar934x()) { | ||
289 | ath79_ip2_handler = ar934x_ip2_handler; | ||
290 | ath79_ip3_handler = ar934x_ip3_handler; | ||
243 | } else { | 291 | } else { |
244 | BUG(); | 292 | BUG(); |
245 | } | 293 | } |
@@ -247,4 +295,7 @@ void __init arch_init_irq(void) | |||
247 | cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; | 295 | cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; |
248 | mips_cpu_irq_init(); | 296 | mips_cpu_irq_init(); |
249 | ath79_misc_irq_init(); | 297 | ath79_misc_irq_init(); |
298 | |||
299 | if (soc_is_ar934x()) | ||
300 | ar934x_ip2_irq_init(); | ||
250 | } | 301 | } |