Linux 4.5-rc1
[linux-drm-fsl-dcu.git] / arch / mips / ath79 / irq.c
1 /*
2  *  Atheros AR71xx/AR724x/AR913x specific interrupt handling
3  *
4  *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5  *  Copyright (C) 2008-2011 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/2.6.31 BSP
9  *
10  *  This program is free software; you can redistribute it and/or modify it
11  *  under the terms of the GNU General Public License version 2 as published
12  *  by the Free Software Foundation.
13  */
14
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/interrupt.h>
18 #include <linux/irqchip.h>
19 #include <linux/of_irq.h>
20
21 #include <asm/irq_cpu.h>
22 #include <asm/mipsregs.h>
23
24 #include <asm/mach-ath79/ath79.h>
25 #include <asm/mach-ath79/ar71xx_regs.h>
26 #include "common.h"
27 #include "machtypes.h"
28
29 static void __init ath79_misc_intc_domain_init(
30         struct device_node *node, int irq);
31
32 static void ath79_misc_irq_handler(struct irq_desc *desc)
33 {
34         struct irq_domain *domain = irq_desc_get_handler_data(desc);
35         void __iomem *base = domain->host_data;
36         u32 pending;
37
38         pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
39                   __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
40
41         if (!pending) {
42                 spurious_interrupt();
43                 return;
44         }
45
46         while (pending) {
47                 int bit = __ffs(pending);
48
49                 generic_handle_irq(irq_linear_revmap(domain, bit));
50                 pending &= ~BIT(bit);
51         }
52 }
53
54 static void ar71xx_misc_irq_unmask(struct irq_data *d)
55 {
56         void __iomem *base = irq_data_get_irq_chip_data(d);
57         unsigned int irq = d->hwirq;
58         u32 t;
59
60         t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
61         __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
62
63         /* flush write */
64         __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
65 }
66
67 static void ar71xx_misc_irq_mask(struct irq_data *d)
68 {
69         void __iomem *base = irq_data_get_irq_chip_data(d);
70         unsigned int irq = d->hwirq;
71         u32 t;
72
73         t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
74         __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
75
76         /* flush write */
77         __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
78 }
79
80 static void ar724x_misc_irq_ack(struct irq_data *d)
81 {
82         void __iomem *base = irq_data_get_irq_chip_data(d);
83         unsigned int irq = d->hwirq;
84         u32 t;
85
86         t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
87         __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
88
89         /* flush write */
90         __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
91 }
92
93 static struct irq_chip ath79_misc_irq_chip = {
94         .name           = "MISC",
95         .irq_unmask     = ar71xx_misc_irq_unmask,
96         .irq_mask       = ar71xx_misc_irq_mask,
97 };
98
99 static void __init ath79_misc_irq_init(void)
100 {
101         if (soc_is_ar71xx() || soc_is_ar913x())
102                 ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
103         else if (soc_is_ar724x() ||
104                  soc_is_ar933x() ||
105                  soc_is_ar934x() ||
106                  soc_is_qca955x())
107                 ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
108         else
109                 BUG();
110
111         ath79_misc_intc_domain_init(NULL, ATH79_CPU_IRQ(6));
112 }
113
114 static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
115 {
116         u32 status;
117
118         status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);
119
120         if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) {
121                 ath79_ddr_wb_flush(3);
122                 generic_handle_irq(ATH79_IP2_IRQ(0));
123         } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) {
124                 ath79_ddr_wb_flush(4);
125                 generic_handle_irq(ATH79_IP2_IRQ(1));
126         } else {
127                 spurious_interrupt();
128         }
129 }
130
131 static void ar934x_ip2_irq_init(void)
132 {
133         int i;
134
135         for (i = ATH79_IP2_IRQ_BASE;
136              i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
137                 irq_set_chip_and_handler(i, &dummy_irq_chip,
138                                          handle_level_irq);
139
140         irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch);
141 }
142
143 static void qca955x_ip2_irq_dispatch(struct irq_desc *desc)
144 {
145         u32 status;
146
147         status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
148         status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL;
149
150         if (status == 0) {
151                 spurious_interrupt();
152                 return;
153         }
154
155         if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) {
156                 /* TODO: flush DDR? */
157                 generic_handle_irq(ATH79_IP2_IRQ(0));
158         }
159
160         if (status & QCA955X_EXT_INT_WMAC_ALL) {
161                 /* TODO: flush DDR? */
162                 generic_handle_irq(ATH79_IP2_IRQ(1));
163         }
164 }
165
166 static void qca955x_ip3_irq_dispatch(struct irq_desc *desc)
167 {
168         u32 status;
169
170         status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
171         status &= QCA955X_EXT_INT_PCIE_RC2_ALL |
172                   QCA955X_EXT_INT_USB1 |
173                   QCA955X_EXT_INT_USB2;
174
175         if (status == 0) {
176                 spurious_interrupt();
177                 return;
178         }
179
180         if (status & QCA955X_EXT_INT_USB1) {
181                 /* TODO: flush DDR? */
182                 generic_handle_irq(ATH79_IP3_IRQ(0));
183         }
184
185         if (status & QCA955X_EXT_INT_USB2) {
186                 /* TODO: flush DDR? */
187                 generic_handle_irq(ATH79_IP3_IRQ(1));
188         }
189
190         if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) {
191                 /* TODO: flush DDR? */
192                 generic_handle_irq(ATH79_IP3_IRQ(2));
193         }
194 }
195
196 static void qca955x_irq_init(void)
197 {
198         int i;
199
200         for (i = ATH79_IP2_IRQ_BASE;
201              i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
202                 irq_set_chip_and_handler(i, &dummy_irq_chip,
203                                          handle_level_irq);
204
205         irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch);
206
207         for (i = ATH79_IP3_IRQ_BASE;
208              i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++)
209                 irq_set_chip_and_handler(i, &dummy_irq_chip,
210                                          handle_level_irq);
211
212         irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
213 }
214
215 /*
216  * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
217  * these devices typically allocate coherent DMA memory, however the
218  * DMA controller may still have some unsynchronized data in the FIFO.
219  * Issue a flush in the handlers to ensure that the driver sees
220  * the update.
221  *
222  * This array map the interrupt lines to the DDR write buffer channels.
223  */
224
225 static unsigned irq_wb_chan[8] = {
226         -1, -1, -1, -1, -1, -1, -1, -1,
227 };
228
229 asmlinkage void plat_irq_dispatch(void)
230 {
231         unsigned long pending;
232         int irq;
233
234         pending = read_c0_status() & read_c0_cause() & ST0_IM;
235
236         if (!pending) {
237                 spurious_interrupt();
238                 return;
239         }
240
241         pending >>= CAUSEB_IP;
242         while (pending) {
243                 irq = fls(pending) - 1;
244                 if (irq < ARRAY_SIZE(irq_wb_chan) && irq_wb_chan[irq] != -1)
245                         ath79_ddr_wb_flush(irq_wb_chan[irq]);
246                 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
247                 pending &= ~BIT(irq);
248         }
249 }
250
251 static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
252 {
253         irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
254         irq_set_chip_data(irq, d->host_data);
255         return 0;
256 }
257
258 static const struct irq_domain_ops misc_irq_domain_ops = {
259         .xlate = irq_domain_xlate_onecell,
260         .map = misc_map,
261 };
262
263 static void __init ath79_misc_intc_domain_init(
264         struct device_node *node, int irq)
265 {
266         void __iomem *base = ath79_reset_base;
267         struct irq_domain *domain;
268
269         domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
270                         ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, base);
271         if (!domain)
272                 panic("Failed to add MISC irqdomain");
273
274         /* Disable and clear all interrupts */
275         __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
276         __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
277
278         irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
279 }
280
281 static int __init ath79_misc_intc_of_init(
282         struct device_node *node, struct device_node *parent)
283 {
284         int irq;
285
286         irq = irq_of_parse_and_map(node, 0);
287         if (!irq)
288                 panic("Failed to get MISC IRQ");
289
290         ath79_misc_intc_domain_init(node, irq);
291         return 0;
292 }
293
294 static int __init ar7100_misc_intc_of_init(
295         struct device_node *node, struct device_node *parent)
296 {
297         ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
298         return ath79_misc_intc_of_init(node, parent);
299 }
300
301 IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc",
302                 ar7100_misc_intc_of_init);
303
304 static int __init ar7240_misc_intc_of_init(
305         struct device_node *node, struct device_node *parent)
306 {
307         ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
308         return ath79_misc_intc_of_init(node, parent);
309 }
310
311 IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc",
312                 ar7240_misc_intc_of_init);
313
314 static int __init ar79_cpu_intc_of_init(
315         struct device_node *node, struct device_node *parent)
316 {
317         int err, i, count;
318
319         /* Fill the irq_wb_chan table */
320         count = of_count_phandle_with_args(
321                 node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells");
322
323         for (i = 0; i < count; i++) {
324                 struct of_phandle_args args;
325                 u32 irq = i;
326
327                 of_property_read_u32_index(
328                         node, "qca,ddr-wb-channel-interrupts", i, &irq);
329                 if (irq >= ARRAY_SIZE(irq_wb_chan))
330                         continue;
331
332                 err = of_parse_phandle_with_args(
333                         node, "qca,ddr-wb-channels",
334                         "#qca,ddr-wb-channel-cells",
335                         i, &args);
336                 if (err)
337                         return err;
338
339                 irq_wb_chan[irq] = args.args[0];
340                 pr_info("IRQ: Set flush channel of IRQ%d to %d\n",
341                         irq, args.args[0]);
342         }
343
344         return mips_cpu_irq_of_init(node, parent);
345 }
346 IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
347                 ar79_cpu_intc_of_init);
348
349 void __init arch_init_irq(void)
350 {
351         if (mips_machtype == ATH79_MACH_GENERIC_OF) {
352                 irqchip_init();
353                 return;
354         }
355
356         if (soc_is_ar71xx() || soc_is_ar724x() ||
357             soc_is_ar913x() || soc_is_ar933x()) {
358                 irq_wb_chan[2] = 3;
359                 irq_wb_chan[3] = 2;
360         } else if (soc_is_ar934x()) {
361                 irq_wb_chan[3] = 2;
362         }
363
364         mips_cpu_irq_init();
365         ath79_misc_irq_init();
366
367         if (soc_is_ar934x())
368                 ar934x_ip2_irq_init();
369         else if (soc_is_qca955x())
370                 qca955x_irq_init();
371 }