Root/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c

1/*
2 * Atheros AR71xx SoC specific interrupt handling
3 *
4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * Parts of this file are based on Atheros 2.6.15 BSP
9 * Parts of this file are based on Atheros 2.6.31 BSP
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published
13 * by the Free Software Foundation.
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20
21#include <asm/irq_cpu.h>
22#include <asm/mipsregs.h>
23
24#include <asm/mach-ar71xx/ar71xx.h>
25
26static void ar71xx_gpio_irq_dispatch(void)
27{
28    void __iomem *base = ar71xx_gpio_base;
29    u32 pending;
30
31    pending = __raw_readl(base + GPIO_REG_INT_PENDING) &
32          __raw_readl(base + GPIO_REG_INT_ENABLE);
33
34    if (pending)
35        do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1);
36    else
37        spurious_interrupt();
38}
39
40static void ar71xx_gpio_irq_unmask(struct irq_data *d)
41{
42    unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE;
43    void __iomem *base = ar71xx_gpio_base;
44    u32 t;
45
46    t = __raw_readl(base + GPIO_REG_INT_ENABLE);
47    __raw_writel(t | (1 << irq), base + GPIO_REG_INT_ENABLE);
48
49    /* flush write */
50    (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
51}
52
53static void ar71xx_gpio_irq_mask(struct irq_data *d)
54{
55    unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE;
56    void __iomem *base = ar71xx_gpio_base;
57    u32 t;
58
59    t = __raw_readl(base + GPIO_REG_INT_ENABLE);
60    __raw_writel(t & ~(1 << irq), base + GPIO_REG_INT_ENABLE);
61
62    /* flush write */
63    (void) __raw_readl(base + GPIO_REG_INT_ENABLE);
64}
65
66static struct irq_chip ar71xx_gpio_irq_chip = {
67    .name = "AR71XX GPIO",
68    .irq_unmask = ar71xx_gpio_irq_unmask,
69    .irq_mask = ar71xx_gpio_irq_mask,
70    .irq_mask_ack = ar71xx_gpio_irq_mask,
71};
72
73static struct irqaction ar71xx_gpio_irqaction = {
74    .handler = no_action,
75    .name = "cascade [AR71XX GPIO]",
76};
77
78#define GPIO_INT_ALL 0xffff
79
80static void __init ar71xx_gpio_irq_init(void)
81{
82    void __iomem *base = ar71xx_gpio_base;
83    int i;
84
85    __raw_writel(0, base + GPIO_REG_INT_ENABLE);
86    __raw_writel(0, base + GPIO_REG_INT_PENDING);
87
88    /* setup type of all GPIO interrupts to level sensitive */
89    __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_TYPE);
90
91    /* setup polarity of all GPIO interrupts to active high */
92    __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_POLARITY);
93
94    for (i = AR71XX_GPIO_IRQ_BASE;
95         i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++)
96        irq_set_chip_and_handler(i, &ar71xx_gpio_irq_chip,
97                     handle_level_irq);
98
99    setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction);
100}
101
102static void ar71xx_misc_irq_dispatch(void)
103{
104    u32 pending;
105
106    pending = ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_STATUS)
107        & ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
108
109    if (pending & MISC_INT_UART)
110        do_IRQ(AR71XX_MISC_IRQ_UART);
111
112    else if (pending & MISC_INT_DMA)
113        do_IRQ(AR71XX_MISC_IRQ_DMA);
114
115    else if (pending & MISC_INT_PERFC)
116        do_IRQ(AR71XX_MISC_IRQ_PERFC);
117
118    else if (pending & MISC_INT_TIMER)
119        do_IRQ(AR71XX_MISC_IRQ_TIMER);
120
121    else if (pending & MISC_INT_OHCI)
122        do_IRQ(AR71XX_MISC_IRQ_OHCI);
123
124    else if (pending & MISC_INT_ERROR)
125        do_IRQ(AR71XX_MISC_IRQ_ERROR);
126
127    else if (pending & MISC_INT_GPIO)
128        ar71xx_gpio_irq_dispatch();
129
130    else if (pending & MISC_INT_WDOG)
131        do_IRQ(AR71XX_MISC_IRQ_WDOG);
132
133    else if (pending & MISC_INT_TIMER2)
134        do_IRQ(AR71XX_MISC_IRQ_TIMER2);
135
136    else if (pending & MISC_INT_TIMER3)
137        do_IRQ(AR71XX_MISC_IRQ_TIMER3);
138
139    else if (pending & MISC_INT_TIMER4)
140        do_IRQ(AR71XX_MISC_IRQ_TIMER4);
141
142    else if (pending & MISC_INT_DDR_PERF)
143        do_IRQ(AR71XX_MISC_IRQ_DDR_PERF);
144
145    else if (pending & MISC_INT_ENET_LINK)
146        do_IRQ(AR71XX_MISC_IRQ_ENET_LINK);
147
148    else
149        spurious_interrupt();
150}
151
152static void ar71xx_misc_irq_unmask(struct irq_data *d)
153{
154    unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE;
155    void __iomem *base = ar71xx_reset_base;
156    u32 t;
157
158    t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
159    __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
160
161    /* flush write */
162    (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
163}
164
165static void ar71xx_misc_irq_mask(struct irq_data *d)
166{
167    unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE;
168    void __iomem *base = ar71xx_reset_base;
169    u32 t;
170
171    t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
172    __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
173
174    /* flush write */
175    (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
176}
177
178static void ar724x_misc_irq_ack(struct irq_data *d)
179{
180    unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE;
181    void __iomem *base = ar71xx_reset_base;
182    u32 t;
183
184    t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
185    __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
186
187    /* flush write */
188    (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
189}
190
191static struct irq_chip ar71xx_misc_irq_chip = {
192    .name = "AR71XX MISC",
193    .irq_unmask = ar71xx_misc_irq_unmask,
194    .irq_mask = ar71xx_misc_irq_mask,
195};
196
197static struct irqaction ar71xx_misc_irqaction = {
198    .handler = no_action,
199    .name = "cascade [AR71XX MISC]",
200};
201
202static void __init ar71xx_misc_irq_init(void)
203{
204    void __iomem *base = ar71xx_reset_base;
205    int i;
206
207    __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
208    __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
209
210    switch (ar71xx_soc) {
211    case AR71XX_SOC_AR7240:
212    case AR71XX_SOC_AR7241:
213    case AR71XX_SOC_AR7242:
214    case AR71XX_SOC_AR9330:
215    case AR71XX_SOC_AR9331:
216    case AR71XX_SOC_AR9341:
217    case AR71XX_SOC_AR9342:
218    case AR71XX_SOC_AR9344:
219        ar71xx_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
220        break;
221    default:
222        ar71xx_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
223        break;
224    }
225
226    for (i = AR71XX_MISC_IRQ_BASE;
227         i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++)
228        irq_set_chip_and_handler(i, &ar71xx_misc_irq_chip,
229                     handle_level_irq);
230
231    setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction);
232}
233
234/*
235 * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
236 * these devices typically allocate coherent DMA memory, however the
237 * DMA controller may still have some unsynchronized data in the FIFO.
238 * Issue a flush in the handlers to ensure that the driver sees
239 * the update.
240 */
241static void ar71xx_ip2_handler(void)
242{
243    ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_PCI);
244    do_IRQ(AR71XX_CPU_IRQ_IP2);
245}
246
247static void ar724x_ip2_handler(void)
248{
249    ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_PCIE);
250    do_IRQ(AR71XX_CPU_IRQ_IP2);
251}
252
253static void ar913x_ip2_handler(void)
254{
255    ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_WMAC);
256    do_IRQ(AR71XX_CPU_IRQ_IP2);
257}
258
259static void ar933x_ip2_handler(void)
260{
261    ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_WMAC);
262    do_IRQ(AR71XX_CPU_IRQ_IP2);
263}
264
265static void ar934x_ip2_handler(void)
266{
267    ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE);
268    do_IRQ(AR71XX_CPU_IRQ_IP2);
269}
270
271static void ar71xx_ip3_handler(void)
272{
273    ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_USB);
274    do_IRQ(AR71XX_CPU_IRQ_USB);
275}
276
277static void ar724x_ip3_handler(void)
278{
279    ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_USB);
280    do_IRQ(AR71XX_CPU_IRQ_USB);
281}
282
283static void ar913x_ip3_handler(void)
284{
285    ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_USB);
286    do_IRQ(AR71XX_CPU_IRQ_USB);
287}
288
289static void ar933x_ip3_handler(void)
290{
291    ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_USB);
292    do_IRQ(AR71XX_CPU_IRQ_USB);
293}
294
295static void ar934x_ip3_handler(void)
296{
297    do_IRQ(AR71XX_CPU_IRQ_USB);
298}
299
300static void (*ip2_handler)(void);
301static void (*ip3_handler)(void);
302
303asmlinkage void plat_irq_dispatch(void)
304{
305    unsigned long pending;
306
307    pending = read_c0_status() & read_c0_cause() & ST0_IM;
308
309    if (pending & STATUSF_IP7)
310        do_IRQ(AR71XX_CPU_IRQ_TIMER);
311
312    else if (pending & STATUSF_IP2)
313        ip2_handler();
314
315    else if (pending & STATUSF_IP4)
316        do_IRQ(AR71XX_CPU_IRQ_GE0);
317
318    else if (pending & STATUSF_IP5)
319        do_IRQ(AR71XX_CPU_IRQ_GE1);
320
321    else if (pending & STATUSF_IP3)
322        ip3_handler();
323
324    else if (pending & STATUSF_IP6)
325        ar71xx_misc_irq_dispatch();
326
327    else
328        spurious_interrupt();
329}
330
331void __init arch_init_irq(void)
332{
333    switch (ar71xx_soc) {
334    case AR71XX_SOC_AR7130:
335    case AR71XX_SOC_AR7141:
336    case AR71XX_SOC_AR7161:
337        ip2_handler = ar71xx_ip2_handler;
338        ip3_handler = ar71xx_ip3_handler;
339        break;
340
341    case AR71XX_SOC_AR7240:
342    case AR71XX_SOC_AR7241:
343    case AR71XX_SOC_AR7242:
344        ip2_handler = ar724x_ip2_handler;
345        ip3_handler = ar724x_ip3_handler;
346        break;
347
348    case AR71XX_SOC_AR9130:
349    case AR71XX_SOC_AR9132:
350        ip2_handler = ar913x_ip2_handler;
351        ip3_handler = ar913x_ip3_handler;
352        break;
353
354    case AR71XX_SOC_AR9330:
355    case AR71XX_SOC_AR9331:
356        ip2_handler = ar933x_ip2_handler;
357        ip3_handler = ar933x_ip3_handler;
358        break;
359
360    case AR71XX_SOC_AR9341:
361    case AR71XX_SOC_AR9342:
362    case AR71XX_SOC_AR9344:
363        ip2_handler = ar934x_ip2_handler;
364        ip3_handler = ar934x_ip3_handler;
365        break;
366
367    default:
368        BUG();
369    }
370
371    mips_cpu_irq_init();
372
373    ar71xx_misc_irq_init();
374
375    cp0_perfcount_irq = AR71XX_MISC_IRQ_PERFC;
376
377    ar71xx_gpio_irq_init();
378}
379

Archive Download this file



interactive