0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/irq.h>
0012 #include <linux/io.h>
0013 #include <linux/irqchip.h>
0014 #include <linux/irqdomain.h>
0015 #include <linux/cpu.h>
0016 #include <linux/of.h>
0017 #include <linux/of_address.h>
0018 #include <linux/of_irq.h>
0019
0020 #define JCORE_AIC_MAX_HWIRQ 127
0021 #define JCORE_AIC1_MIN_HWIRQ 16
0022 #define JCORE_AIC2_MIN_HWIRQ 64
0023
0024 #define JCORE_AIC1_INTPRI_REG 8
0025
0026 static struct irq_chip jcore_aic;
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 static void handle_jcore_irq(struct irq_desc *desc)
0039 {
0040 if (irqd_is_per_cpu(irq_desc_get_irq_data(desc)))
0041 handle_percpu_irq(desc);
0042 else
0043 handle_simple_irq(desc);
0044 }
0045
0046 static int jcore_aic_irqdomain_map(struct irq_domain *d, unsigned int irq,
0047 irq_hw_number_t hwirq)
0048 {
0049 struct irq_chip *aic = d->host_data;
0050
0051 irq_set_chip_and_handler(irq, aic, handle_jcore_irq);
0052
0053 return 0;
0054 }
0055
0056 static const struct irq_domain_ops jcore_aic_irqdomain_ops = {
0057 .map = jcore_aic_irqdomain_map,
0058 .xlate = irq_domain_xlate_onecell,
0059 };
0060
0061 static void noop(struct irq_data *data)
0062 {
0063 }
0064
0065 static int __init aic_irq_of_init(struct device_node *node,
0066 struct device_node *parent)
0067 {
0068 unsigned min_irq = JCORE_AIC2_MIN_HWIRQ;
0069 unsigned dom_sz = JCORE_AIC_MAX_HWIRQ+1;
0070 struct irq_domain *domain;
0071
0072 pr_info("Initializing J-Core AIC\n");
0073
0074
0075 if (of_device_is_compatible(node, "jcore,aic1")) {
0076 unsigned cpu;
0077
0078 for_each_present_cpu(cpu) {
0079 void __iomem *base = of_iomap(node, cpu);
0080
0081 if (!base) {
0082 pr_err("Unable to map AIC for cpu %u\n", cpu);
0083 return -ENOMEM;
0084 }
0085 __raw_writel(0xffffffff, base + JCORE_AIC1_INTPRI_REG);
0086 iounmap(base);
0087 }
0088 min_irq = JCORE_AIC1_MIN_HWIRQ;
0089 }
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 jcore_aic.irq_mask = noop;
0100 jcore_aic.irq_unmask = noop;
0101 jcore_aic.name = "AIC";
0102
0103 domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq,
0104 &jcore_aic_irqdomain_ops,
0105 &jcore_aic);
0106 if (!domain)
0107 return -ENOMEM;
0108
0109 return 0;
0110 }
0111
0112 IRQCHIP_DECLARE(jcore_aic2, "jcore,aic2", aic_irq_of_init);
0113 IRQCHIP_DECLARE(jcore_aic1, "jcore,aic1", aic_irq_of_init);