1 /*
2 * Atmel AT91 AIC5 (Advanced Interrupt Controller) driver
3 *
4 * Copyright (C) 2004 SAN People
5 * Copyright (C) 2004 ATMEL
6 * Copyright (C) Rick Bronson
7 * Copyright (C) 2014 Free Electrons
8 *
9 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 */
15
16 #include <linux/init.h>
17 #include <linux/module.h>
18 #include <linux/mm.h>
19 #include <linux/bitmap.h>
20 #include <linux/types.h>
21 #include <linux/irq.h>
22 #include <linux/irqchip.h>
23 #include <linux/of.h>
24 #include <linux/of_address.h>
25 #include <linux/of_irq.h>
26 #include <linux/irqdomain.h>
27 #include <linux/err.h>
28 #include <linux/slab.h>
29 #include <linux/io.h>
30
31 #include <asm/exception.h>
32 #include <asm/mach/irq.h>
33
34 #include "irq-atmel-aic-common.h"
35
36 /* Number of irq lines managed by AIC */
37 #define NR_AIC5_IRQS 128
38
39 #define AT91_AIC5_SSR 0x0
40 #define AT91_AIC5_INTSEL_MSK (0x7f << 0)
41
42 #define AT91_AIC5_SMR 0x4
43
44 #define AT91_AIC5_SVR 0x8
45 #define AT91_AIC5_IVR 0x10
46 #define AT91_AIC5_FVR 0x14
47 #define AT91_AIC5_ISR 0x18
48
49 #define AT91_AIC5_IPR0 0x20
50 #define AT91_AIC5_IPR1 0x24
51 #define AT91_AIC5_IPR2 0x28
52 #define AT91_AIC5_IPR3 0x2c
53 #define AT91_AIC5_IMR 0x30
54 #define AT91_AIC5_CISR 0x34
55
56 #define AT91_AIC5_IECR 0x40
57 #define AT91_AIC5_IDCR 0x44
58 #define AT91_AIC5_ICCR 0x48
59 #define AT91_AIC5_ISCR 0x4c
60 #define AT91_AIC5_EOICR 0x38
61 #define AT91_AIC5_SPU 0x3c
62 #define AT91_AIC5_DCR 0x6c
63
64 #define AT91_AIC5_FFER 0x50
65 #define AT91_AIC5_FFDR 0x54
66 #define AT91_AIC5_FFSR 0x58
67
68 static struct irq_domain *aic5_domain;
69
aic5_handle(struct pt_regs * regs)70 static void __exception_irq_entry aic5_handle(struct pt_regs *regs)
71 {
72 struct irq_chip_generic *bgc = irq_get_domain_generic_chip(aic5_domain, 0);
73 u32 irqnr;
74 u32 irqstat;
75
76 irqnr = irq_reg_readl(bgc, AT91_AIC5_IVR);
77 irqstat = irq_reg_readl(bgc, AT91_AIC5_ISR);
78
79 if (!irqstat)
80 irq_reg_writel(bgc, 0, AT91_AIC5_EOICR);
81 else
82 generic_handle_domain_irq(aic5_domain, irqnr);
83 }
84
aic5_mask(struct irq_data * d)85 static void aic5_mask(struct irq_data *d)
86 {
87 struct irq_domain *domain = d->domain;
88 struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
89 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
90
91 /*
92 * Disable interrupt on AIC5. We always take the lock of the
93 * first irq chip as all chips share the same registers.
94 */
95 guard(raw_spinlock)(&bgc->lock);
96 irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
97 irq_reg_writel(gc, 1, AT91_AIC5_IDCR);
98 gc->mask_cache &= ~d->mask;
99 }
100
aic5_unmask(struct irq_data * d)101 static void aic5_unmask(struct irq_data *d)
102 {
103 struct irq_domain *domain = d->domain;
104 struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
105 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
106
107 /*
108 * Enable interrupt on AIC5. We always take the lock of the
109 * first irq chip as all chips share the same registers.
110 */
111 guard(raw_spinlock)(&bgc->lock);
112 irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
113 irq_reg_writel(gc, 1, AT91_AIC5_IECR);
114 gc->mask_cache |= d->mask;
115 }
116
aic5_retrigger(struct irq_data * d)117 static int aic5_retrigger(struct irq_data *d)
118 {
119 struct irq_domain *domain = d->domain;
120 struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
121
122 /* Enable interrupt on AIC5 */
123 guard(raw_spinlock)(&bgc->lock);
124 irq_reg_writel(bgc, d->hwirq, AT91_AIC5_SSR);
125 irq_reg_writel(bgc, 1, AT91_AIC5_ISCR);
126 return 1;
127 }
128
aic5_set_type(struct irq_data * d,unsigned type)129 static int aic5_set_type(struct irq_data *d, unsigned type)
130 {
131 struct irq_domain *domain = d->domain;
132 struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
133 unsigned int smr;
134 int ret;
135
136 guard(raw_spinlock)(&bgc->lock);
137 irq_reg_writel(bgc, d->hwirq, AT91_AIC5_SSR);
138 smr = irq_reg_readl(bgc, AT91_AIC5_SMR);
139 ret = aic_common_set_type(d, type, &smr);
140 if (!ret)
141 irq_reg_writel(bgc, smr, AT91_AIC5_SMR);
142 return ret;
143 }
144
145 #ifdef CONFIG_PM
146 static u32 *smr_cache;
147
aic5_suspend(struct irq_data * d)148 static void aic5_suspend(struct irq_data *d)
149 {
150 struct irq_domain *domain = d->domain;
151 struct irq_domain_chip_generic *dgc = domain->gc;
152 struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
153 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
154 int i;
155 u32 mask;
156
157 if (smr_cache)
158 for (i = 0; i < domain->revmap_size; i++) {
159 irq_reg_writel(bgc, i, AT91_AIC5_SSR);
160 smr_cache[i] = irq_reg_readl(bgc, AT91_AIC5_SMR);
161 }
162
163 guard(raw_spinlock)(&bgc->lock);
164 for (i = 0; i < dgc->irqs_per_chip; i++) {
165 mask = 1 << i;
166 if ((mask & gc->mask_cache) == (mask & gc->wake_active))
167 continue;
168
169 irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
170 if (mask & gc->wake_active)
171 irq_reg_writel(bgc, 1, AT91_AIC5_IECR);
172 else
173 irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
174 }
175 }
176
aic5_resume(struct irq_data * d)177 static void aic5_resume(struct irq_data *d)
178 {
179 struct irq_domain *domain = d->domain;
180 struct irq_domain_chip_generic *dgc = domain->gc;
181 struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
182 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
183 int i;
184 u32 mask;
185
186 guard(raw_spinlock)(&bgc->lock);
187
188 if (smr_cache) {
189 irq_reg_writel(bgc, 0xffffffff, AT91_AIC5_SPU);
190 for (i = 0; i < domain->revmap_size; i++) {
191 irq_reg_writel(bgc, i, AT91_AIC5_SSR);
192 irq_reg_writel(bgc, i, AT91_AIC5_SVR);
193 irq_reg_writel(bgc, smr_cache[i], AT91_AIC5_SMR);
194 }
195 }
196
197 for (i = 0; i < dgc->irqs_per_chip; i++) {
198 mask = 1 << i;
199
200 if (!smr_cache &&
201 ((mask & gc->mask_cache) == (mask & gc->wake_active)))
202 continue;
203
204 irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
205 if (mask & gc->mask_cache)
206 irq_reg_writel(bgc, 1, AT91_AIC5_IECR);
207 else
208 irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
209 }
210 }
211
aic5_pm_shutdown(struct irq_data * d)212 static void aic5_pm_shutdown(struct irq_data *d)
213 {
214 struct irq_domain *domain = d->domain;
215 struct irq_domain_chip_generic *dgc = domain->gc;
216 struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
217 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
218 int i;
219
220 guard(raw_spinlock)(&bgc->lock);
221 for (i = 0; i < dgc->irqs_per_chip; i++) {
222 irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
223 irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
224 irq_reg_writel(bgc, 1, AT91_AIC5_ICCR);
225 }
226 }
227 #else
228 #define aic5_suspend NULL
229 #define aic5_resume NULL
230 #define aic5_pm_shutdown NULL
231 #endif /* CONFIG_PM */
232
aic5_hw_init(struct irq_domain * domain)233 static void __init aic5_hw_init(struct irq_domain *domain)
234 {
235 struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
236 int i;
237
238 /*
239 * Perform 8 End Of Interrupt Command to make sure AIC
240 * will not Lock out nIRQ
241 */
242 for (i = 0; i < 8; i++)
243 irq_reg_writel(gc, 0, AT91_AIC5_EOICR);
244
245 /*
246 * Spurious Interrupt ID in Spurious Vector Register.
247 * When there is no current interrupt, the IRQ Vector Register
248 * reads the value stored in AIC_SPU
249 */
250 irq_reg_writel(gc, 0xffffffff, AT91_AIC5_SPU);
251
252 /* No debugging in AIC: Debug (Protect) Control Register */
253 irq_reg_writel(gc, 0, AT91_AIC5_DCR);
254
255 /* Disable and clear all interrupts initially */
256 for (i = 0; i < domain->revmap_size; i++) {
257 irq_reg_writel(gc, i, AT91_AIC5_SSR);
258 irq_reg_writel(gc, i, AT91_AIC5_SVR);
259 irq_reg_writel(gc, 1, AT91_AIC5_IDCR);
260 irq_reg_writel(gc, 1, AT91_AIC5_ICCR);
261 }
262 }
263
aic5_irq_domain_xlate(struct irq_domain * d,struct device_node * ctrlr,const u32 * intspec,unsigned int intsize,irq_hw_number_t * out_hwirq,unsigned int * out_type)264 static int aic5_irq_domain_xlate(struct irq_domain *d,
265 struct device_node *ctrlr,
266 const u32 *intspec, unsigned int intsize,
267 irq_hw_number_t *out_hwirq,
268 unsigned int *out_type)
269 {
270 struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0);
271 unsigned smr;
272 int ret;
273
274 if (!bgc)
275 return -EINVAL;
276
277 ret = aic_common_irq_domain_xlate(d, ctrlr, intspec, intsize,
278 out_hwirq, out_type);
279 if (ret)
280 return ret;
281
282 guard(raw_spinlock_irq)(&bgc->lock);
283 irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR);
284 smr = irq_reg_readl(bgc, AT91_AIC5_SMR);
285 aic_common_set_priority(intspec[2], &smr);
286 irq_reg_writel(bgc, smr, AT91_AIC5_SMR);
287 return ret;
288 }
289
290 static const struct irq_domain_ops aic5_irq_ops = {
291 .map = irq_map_generic_chip,
292 .xlate = aic5_irq_domain_xlate,
293 };
294
sama5d3_aic_irq_fixup(void)295 static void __init sama5d3_aic_irq_fixup(void)
296 {
297 aic_common_rtc_irq_fixup();
298 }
299
sam9x60_aic_irq_fixup(void)300 static void __init sam9x60_aic_irq_fixup(void)
301 {
302 aic_common_rtc_irq_fixup();
303 aic_common_rtt_irq_fixup();
304 }
305
306 static const struct of_device_id aic5_irq_fixups[] __initconst = {
307 { .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup },
308 { .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup },
309 { .compatible = "microchip,sam9x60", .data = sam9x60_aic_irq_fixup },
310 { .compatible = "microchip,sam9x7", .data = sam9x60_aic_irq_fixup },
311 { /* sentinel */ },
312 };
313
aic5_of_init(struct device_node * node,struct device_node * parent,int nirqs)314 static int __init aic5_of_init(struct device_node *node,
315 struct device_node *parent,
316 int nirqs)
317 {
318 struct irq_chip_generic *gc;
319 struct irq_domain *domain;
320 int nchips;
321 int i;
322
323 if (nirqs > NR_AIC5_IRQS)
324 return -EINVAL;
325
326 if (aic5_domain)
327 return -EEXIST;
328
329 domain = aic_common_of_init(node, &aic5_irq_ops, "atmel-aic5",
330 nirqs, aic5_irq_fixups);
331 if (IS_ERR(domain))
332 return PTR_ERR(domain);
333
334 aic5_domain = domain;
335 nchips = aic5_domain->revmap_size / 32;
336 for (i = 0; i < nchips; i++) {
337 gc = irq_get_domain_generic_chip(domain, i * 32);
338
339 gc->chip_types[0].regs.eoi = AT91_AIC5_EOICR;
340 gc->chip_types[0].chip.irq_mask = aic5_mask;
341 gc->chip_types[0].chip.irq_unmask = aic5_unmask;
342 gc->chip_types[0].chip.irq_retrigger = aic5_retrigger;
343 gc->chip_types[0].chip.irq_set_type = aic5_set_type;
344 gc->chip_types[0].chip.irq_suspend = aic5_suspend;
345 gc->chip_types[0].chip.irq_resume = aic5_resume;
346 gc->chip_types[0].chip.irq_pm_shutdown = aic5_pm_shutdown;
347 }
348
349 aic5_hw_init(domain);
350 set_handle_irq(aic5_handle);
351
352 return 0;
353 }
354
355 #define NR_SAMA5D2_IRQS 77
356
sama5d2_aic5_of_init(struct device_node * node,struct device_node * parent)357 static int __init sama5d2_aic5_of_init(struct device_node *node,
358 struct device_node *parent)
359 {
360 #ifdef CONFIG_PM
361 smr_cache = kcalloc(DIV_ROUND_UP(NR_SAMA5D2_IRQS, 32) * 32,
362 sizeof(*smr_cache), GFP_KERNEL);
363 if (!smr_cache)
364 return -ENOMEM;
365 #endif
366
367 return aic5_of_init(node, parent, NR_SAMA5D2_IRQS);
368 }
369 IRQCHIP_DECLARE(sama5d2_aic5, "atmel,sama5d2-aic", sama5d2_aic5_of_init);
370
371 #define NR_SAMA5D3_IRQS 48
372
sama5d3_aic5_of_init(struct device_node * node,struct device_node * parent)373 static int __init sama5d3_aic5_of_init(struct device_node *node,
374 struct device_node *parent)
375 {
376 return aic5_of_init(node, parent, NR_SAMA5D3_IRQS);
377 }
378 IRQCHIP_DECLARE(sama5d3_aic5, "atmel,sama5d3-aic", sama5d3_aic5_of_init);
379
380 #define NR_SAMA5D4_IRQS 68
381
sama5d4_aic5_of_init(struct device_node * node,struct device_node * parent)382 static int __init sama5d4_aic5_of_init(struct device_node *node,
383 struct device_node *parent)
384 {
385 return aic5_of_init(node, parent, NR_SAMA5D4_IRQS);
386 }
387 IRQCHIP_DECLARE(sama5d4_aic5, "atmel,sama5d4-aic", sama5d4_aic5_of_init);
388
389 #define NR_SAM9X60_IRQS 50
390
sam9x60_aic5_of_init(struct device_node * node,struct device_node * parent)391 static int __init sam9x60_aic5_of_init(struct device_node *node,
392 struct device_node *parent)
393 {
394 return aic5_of_init(node, parent, NR_SAM9X60_IRQS);
395 }
396 IRQCHIP_DECLARE(sam9x60_aic5, "microchip,sam9x60-aic", sam9x60_aic5_of_init);
397
398 #define NR_SAM9X7_IRQS 70
399
sam9x7_aic5_of_init(struct device_node * node,struct device_node * parent)400 static int __init sam9x7_aic5_of_init(struct device_node *node, struct device_node *parent)
401 {
402 return aic5_of_init(node, parent, NR_SAM9X7_IRQS);
403 }
404 IRQCHIP_DECLARE(sam9x7_aic5, "microchip,sam9x7-aic", sam9x7_aic5_of_init);
405