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