1 /* 2 * Atmel AT91 AIC (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_AIC_IRQS 32 38 39 #define AT91_AIC_SMR(n) ((n) * 4) 40 41 #define AT91_AIC_SVR(n) (0x80 + ((n) * 4)) 42 #define AT91_AIC_IVR 0x100 43 #define AT91_AIC_FVR 0x104 44 #define AT91_AIC_ISR 0x108 45 46 #define AT91_AIC_IPR 0x10c 47 #define AT91_AIC_IMR 0x110 48 #define AT91_AIC_CISR 0x114 49 50 #define AT91_AIC_IECR 0x120 51 #define AT91_AIC_IDCR 0x124 52 #define AT91_AIC_ICCR 0x128 53 #define AT91_AIC_ISCR 0x12c 54 #define AT91_AIC_EOICR 0x130 55 #define AT91_AIC_SPU 0x134 56 #define AT91_AIC_DCR 0x138 57 58 static struct irq_domain *aic_domain; 59 60 static void __exception_irq_entry aic_handle(struct pt_regs *regs) 61 { 62 struct irq_domain_chip_generic *dgc = aic_domain->gc; 63 struct irq_chip_generic *gc = dgc->gc[0]; 64 u32 irqnr; 65 u32 irqstat; 66 67 irqnr = irq_reg_readl(gc, AT91_AIC_IVR); 68 irqstat = irq_reg_readl(gc, AT91_AIC_ISR); 69 70 if (!irqstat) 71 irq_reg_writel(gc, 0, AT91_AIC_EOICR); 72 else 73 generic_handle_domain_irq(aic_domain, irqnr); 74 } 75 76 static int aic_retrigger(struct irq_data *d) 77 { 78 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 79 80 /* Enable interrupt on AIC5 */ 81 irq_gc_lock(gc); 82 irq_reg_writel(gc, d->mask, AT91_AIC_ISCR); 83 irq_gc_unlock(gc); 84 85 return 1; 86 } 87 88 static int aic_set_type(struct irq_data *d, unsigned type) 89 { 90 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 91 unsigned int smr; 92 int ret; 93 94 smr = irq_reg_readl(gc, AT91_AIC_SMR(d->hwirq)); 95 ret = aic_common_set_type(d, type, &smr); 96 if (ret) 97 return ret; 98 99 irq_reg_writel(gc, smr, AT91_AIC_SMR(d->hwirq)); 100 101 return 0; 102 } 103 104 #ifdef CONFIG_PM 105 static void aic_suspend(struct irq_data *d) 106 { 107 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 108 109 irq_gc_lock(gc); 110 irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IDCR); 111 irq_reg_writel(gc, gc->wake_active, AT91_AIC_IECR); 112 irq_gc_unlock(gc); 113 } 114 115 static void aic_resume(struct irq_data *d) 116 { 117 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 118 119 irq_gc_lock(gc); 120 irq_reg_writel(gc, gc->wake_active, AT91_AIC_IDCR); 121 irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IECR); 122 irq_gc_unlock(gc); 123 } 124 125 static void aic_pm_shutdown(struct irq_data *d) 126 { 127 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 128 129 irq_gc_lock(gc); 130 irq_reg_writel(gc, 0xffffffff, AT91_AIC_IDCR); 131 irq_reg_writel(gc, 0xffffffff, AT91_AIC_ICCR); 132 irq_gc_unlock(gc); 133 } 134 #else 135 #define aic_suspend NULL 136 #define aic_resume NULL 137 #define aic_pm_shutdown NULL 138 #endif /* CONFIG_PM */ 139 140 static void __init aic_hw_init(struct irq_domain *domain) 141 { 142 struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0); 143 int i; 144 145 /* 146 * Perform 8 End Of Interrupt Command to make sure AIC 147 * will not Lock out nIRQ 148 */ 149 for (i = 0; i < 8; i++) 150 irq_reg_writel(gc, 0, AT91_AIC_EOICR); 151 152 /* 153 * Spurious Interrupt ID in Spurious Vector Register. 154 * When there is no current interrupt, the IRQ Vector Register 155 * reads the value stored in AIC_SPU 156 */ 157 irq_reg_writel(gc, 0xffffffff, AT91_AIC_SPU); 158 159 /* No debugging in AIC: Debug (Protect) Control Register */ 160 irq_reg_writel(gc, 0, AT91_AIC_DCR); 161 162 /* Disable and clear all interrupts initially */ 163 irq_reg_writel(gc, 0xffffffff, AT91_AIC_IDCR); 164 irq_reg_writel(gc, 0xffffffff, AT91_AIC_ICCR); 165 166 for (i = 0; i < 32; i++) 167 irq_reg_writel(gc, i, AT91_AIC_SVR(i)); 168 } 169 170 static int aic_irq_domain_xlate(struct irq_domain *d, 171 struct device_node *ctrlr, 172 const u32 *intspec, unsigned int intsize, 173 irq_hw_number_t *out_hwirq, 174 unsigned int *out_type) 175 { 176 struct irq_domain_chip_generic *dgc = d->gc; 177 struct irq_chip_generic *gc; 178 unsigned long flags; 179 unsigned smr; 180 int idx; 181 int ret; 182 183 if (!dgc) 184 return -EINVAL; 185 186 ret = aic_common_irq_domain_xlate(d, ctrlr, intspec, intsize, 187 out_hwirq, out_type); 188 if (ret) 189 return ret; 190 191 idx = intspec[0] / dgc->irqs_per_chip; 192 if (idx >= dgc->num_chips) 193 return -EINVAL; 194 195 gc = dgc->gc[idx]; 196 197 irq_gc_lock_irqsave(gc, flags); 198 smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq)); 199 aic_common_set_priority(intspec[2], &smr); 200 irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq)); 201 irq_gc_unlock_irqrestore(gc, flags); 202 203 return ret; 204 } 205 206 static const struct irq_domain_ops aic_irq_ops = { 207 .map = irq_map_generic_chip, 208 .xlate = aic_irq_domain_xlate, 209 }; 210 211 static void __init at91rm9200_aic_irq_fixup(void) 212 { 213 aic_common_rtc_irq_fixup(); 214 } 215 216 static void __init at91sam9260_aic_irq_fixup(void) 217 { 218 aic_common_rtt_irq_fixup(); 219 } 220 221 static void __init at91sam9g45_aic_irq_fixup(void) 222 { 223 aic_common_rtc_irq_fixup(); 224 aic_common_rtt_irq_fixup(); 225 } 226 227 static const struct of_device_id aic_irq_fixups[] __initconst = { 228 { .compatible = "atmel,at91rm9200", .data = at91rm9200_aic_irq_fixup }, 229 { .compatible = "atmel,at91sam9g45", .data = at91sam9g45_aic_irq_fixup }, 230 { .compatible = "atmel,at91sam9n12", .data = at91rm9200_aic_irq_fixup }, 231 { .compatible = "atmel,at91sam9rl", .data = at91sam9g45_aic_irq_fixup }, 232 { .compatible = "atmel,at91sam9x5", .data = at91rm9200_aic_irq_fixup }, 233 { .compatible = "atmel,at91sam9260", .data = at91sam9260_aic_irq_fixup }, 234 { .compatible = "atmel,at91sam9261", .data = at91sam9260_aic_irq_fixup }, 235 { .compatible = "atmel,at91sam9263", .data = at91sam9260_aic_irq_fixup }, 236 { .compatible = "atmel,at91sam9g20", .data = at91sam9260_aic_irq_fixup }, 237 { /* sentinel */ }, 238 }; 239 240 static int __init aic_of_init(struct device_node *node, 241 struct device_node *parent) 242 { 243 struct irq_chip_generic *gc; 244 struct irq_domain *domain; 245 246 if (aic_domain) 247 return -EEXIST; 248 249 domain = aic_common_of_init(node, &aic_irq_ops, "atmel-aic", 250 NR_AIC_IRQS, aic_irq_fixups); 251 if (IS_ERR(domain)) 252 return PTR_ERR(domain); 253 254 aic_domain = domain; 255 gc = irq_get_domain_generic_chip(domain, 0); 256 257 gc->chip_types[0].regs.eoi = AT91_AIC_EOICR; 258 gc->chip_types[0].regs.enable = AT91_AIC_IECR; 259 gc->chip_types[0].regs.disable = AT91_AIC_IDCR; 260 gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg; 261 gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg; 262 gc->chip_types[0].chip.irq_retrigger = aic_retrigger; 263 gc->chip_types[0].chip.irq_set_type = aic_set_type; 264 gc->chip_types[0].chip.irq_suspend = aic_suspend; 265 gc->chip_types[0].chip.irq_resume = aic_resume; 266 gc->chip_types[0].chip.irq_pm_shutdown = aic_pm_shutdown; 267 268 aic_hw_init(domain); 269 set_handle_irq(aic_handle); 270 271 return 0; 272 } 273 IRQCHIP_DECLARE(at91rm9200_aic, "atmel,at91rm9200-aic", aic_of_init); 274