0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/errno.h>
0018 #include <linux/io.h>
0019 #include <linux/irq.h>
0020 #include <linux/irqdomain.h>
0021 #include <linux/of.h>
0022 #include <linux/of_address.h>
0023 #include <linux/slab.h>
0024
0025 #include "irq-atmel-aic-common.h"
0026
0027 #define AT91_AIC_PRIOR GENMASK(2, 0)
0028 #define AT91_AIC_IRQ_MIN_PRIORITY 0
0029 #define AT91_AIC_IRQ_MAX_PRIORITY 7
0030
0031 #define AT91_AIC_SRCTYPE GENMASK(6, 5)
0032 #define AT91_AIC_SRCTYPE_LOW (0 << 5)
0033 #define AT91_AIC_SRCTYPE_FALLING (1 << 5)
0034 #define AT91_AIC_SRCTYPE_HIGH (2 << 5)
0035 #define AT91_AIC_SRCTYPE_RISING (3 << 5)
0036
0037 struct aic_chip_data {
0038 u32 ext_irqs;
0039 };
0040
0041 static void aic_common_shutdown(struct irq_data *d)
0042 {
0043 struct irq_chip_type *ct = irq_data_get_chip_type(d);
0044
0045 ct->chip.irq_mask(d);
0046 }
0047
0048 int aic_common_set_type(struct irq_data *d, unsigned type, unsigned *val)
0049 {
0050 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
0051 struct aic_chip_data *aic = gc->private;
0052 unsigned aic_type;
0053
0054 switch (type) {
0055 case IRQ_TYPE_LEVEL_HIGH:
0056 aic_type = AT91_AIC_SRCTYPE_HIGH;
0057 break;
0058 case IRQ_TYPE_EDGE_RISING:
0059 aic_type = AT91_AIC_SRCTYPE_RISING;
0060 break;
0061 case IRQ_TYPE_LEVEL_LOW:
0062 if (!(d->mask & aic->ext_irqs))
0063 return -EINVAL;
0064
0065 aic_type = AT91_AIC_SRCTYPE_LOW;
0066 break;
0067 case IRQ_TYPE_EDGE_FALLING:
0068 if (!(d->mask & aic->ext_irqs))
0069 return -EINVAL;
0070
0071 aic_type = AT91_AIC_SRCTYPE_FALLING;
0072 break;
0073 default:
0074 return -EINVAL;
0075 }
0076
0077 *val &= ~AT91_AIC_SRCTYPE;
0078 *val |= aic_type;
0079
0080 return 0;
0081 }
0082
0083 void aic_common_set_priority(int priority, unsigned *val)
0084 {
0085 *val &= ~AT91_AIC_PRIOR;
0086 *val |= priority;
0087 }
0088
0089 int aic_common_irq_domain_xlate(struct irq_domain *d,
0090 struct device_node *ctrlr,
0091 const u32 *intspec,
0092 unsigned int intsize,
0093 irq_hw_number_t *out_hwirq,
0094 unsigned int *out_type)
0095 {
0096 if (WARN_ON(intsize < 3))
0097 return -EINVAL;
0098
0099 if (WARN_ON((intspec[2] < AT91_AIC_IRQ_MIN_PRIORITY) ||
0100 (intspec[2] > AT91_AIC_IRQ_MAX_PRIORITY)))
0101 return -EINVAL;
0102
0103 *out_hwirq = intspec[0];
0104 *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
0105
0106 return 0;
0107 }
0108
0109 static void __init aic_common_ext_irq_of_init(struct irq_domain *domain)
0110 {
0111 struct device_node *node = irq_domain_get_of_node(domain);
0112 struct irq_chip_generic *gc;
0113 struct aic_chip_data *aic;
0114 struct property *prop;
0115 const __be32 *p;
0116 u32 hwirq;
0117
0118 gc = irq_get_domain_generic_chip(domain, 0);
0119
0120 aic = gc->private;
0121 aic->ext_irqs |= 1;
0122
0123 of_property_for_each_u32(node, "atmel,external-irqs", prop, p, hwirq) {
0124 gc = irq_get_domain_generic_chip(domain, hwirq);
0125 if (!gc) {
0126 pr_warn("AIC: external irq %d >= %d skip it\n",
0127 hwirq, domain->revmap_size);
0128 continue;
0129 }
0130
0131 aic = gc->private;
0132 aic->ext_irqs |= (1 << (hwirq % 32));
0133 }
0134 }
0135
0136 #define AT91_RTC_IDR 0x24
0137 #define AT91_RTC_IMR 0x28
0138 #define AT91_RTC_IRQ_MASK 0x1f
0139
0140 void __init aic_common_rtc_irq_fixup(void)
0141 {
0142 struct device_node *np;
0143 void __iomem *regs;
0144
0145 np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-rtc");
0146 if (!np)
0147 np = of_find_compatible_node(NULL, NULL,
0148 "atmel,at91sam9x5-rtc");
0149
0150 if (!np)
0151 return;
0152
0153 regs = of_iomap(np, 0);
0154 of_node_put(np);
0155
0156 if (!regs)
0157 return;
0158
0159 writel(AT91_RTC_IRQ_MASK, regs + AT91_RTC_IDR);
0160
0161 iounmap(regs);
0162 }
0163
0164 #define AT91_RTT_MR 0x00
0165 #define AT91_RTT_ALMIEN (1 << 16)
0166 #define AT91_RTT_RTTINCIEN (1 << 17)
0167
0168 void __init aic_common_rtt_irq_fixup(void)
0169 {
0170 struct device_node *np;
0171 void __iomem *regs;
0172
0173
0174
0175
0176
0177 for_each_compatible_node(np, NULL, "atmel,at91sam9260-rtt") {
0178 regs = of_iomap(np, 0);
0179 if (!regs)
0180 continue;
0181
0182 writel(readl(regs + AT91_RTT_MR) &
0183 ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN),
0184 regs + AT91_RTT_MR);
0185
0186 iounmap(regs);
0187 }
0188 }
0189
0190 static void __init aic_common_irq_fixup(const struct of_device_id *matches)
0191 {
0192 struct device_node *root = of_find_node_by_path("/");
0193 const struct of_device_id *match;
0194
0195 if (!root)
0196 return;
0197
0198 match = of_match_node(matches, root);
0199
0200 if (match) {
0201 void (*fixup)(void) = match->data;
0202 fixup();
0203 }
0204
0205 of_node_put(root);
0206 }
0207
0208 struct irq_domain *__init aic_common_of_init(struct device_node *node,
0209 const struct irq_domain_ops *ops,
0210 const char *name, int nirqs,
0211 const struct of_device_id *matches)
0212 {
0213 struct irq_chip_generic *gc;
0214 struct irq_domain *domain;
0215 struct aic_chip_data *aic;
0216 void __iomem *reg_base;
0217 int nchips;
0218 int ret;
0219 int i;
0220
0221 nchips = DIV_ROUND_UP(nirqs, 32);
0222
0223 reg_base = of_iomap(node, 0);
0224 if (!reg_base)
0225 return ERR_PTR(-ENOMEM);
0226
0227 aic = kcalloc(nchips, sizeof(*aic), GFP_KERNEL);
0228 if (!aic) {
0229 ret = -ENOMEM;
0230 goto err_iounmap;
0231 }
0232
0233 domain = irq_domain_add_linear(node, nchips * 32, ops, aic);
0234 if (!domain) {
0235 ret = -ENOMEM;
0236 goto err_free_aic;
0237 }
0238
0239 ret = irq_alloc_domain_generic_chips(domain, 32, 1, name,
0240 handle_fasteoi_irq,
0241 IRQ_NOREQUEST | IRQ_NOPROBE |
0242 IRQ_NOAUTOEN, 0, 0);
0243 if (ret)
0244 goto err_domain_remove;
0245
0246 for (i = 0; i < nchips; i++) {
0247 gc = irq_get_domain_generic_chip(domain, i * 32);
0248
0249 gc->reg_base = reg_base;
0250
0251 gc->unused = 0;
0252 gc->wake_enabled = ~0;
0253 gc->chip_types[0].type = IRQ_TYPE_SENSE_MASK;
0254 gc->chip_types[0].chip.irq_eoi = irq_gc_eoi;
0255 gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
0256 gc->chip_types[0].chip.irq_shutdown = aic_common_shutdown;
0257 gc->private = &aic[i];
0258 }
0259
0260 aic_common_ext_irq_of_init(domain);
0261 aic_common_irq_fixup(matches);
0262
0263 return domain;
0264
0265 err_domain_remove:
0266 irq_domain_remove(domain);
0267
0268 err_free_aic:
0269 kfree(aic);
0270
0271 err_iounmap:
0272 iounmap(reg_base);
0273
0274 return ERR_PTR(ret);
0275 }