Skip to content

Commit fbbf2b3

Browse files
author
Jason Cooper
committed
Merge branch 'irqchip/jcore' into irqchip/core
2 parents cae750b + 21118df commit fbbf2b3

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
J-Core Advanced Interrupt Controller
2+
3+
Required properties:
4+
5+
- compatible: Should be "jcore,aic1" for the (obsolete) first-generation aic
6+
with 8 interrupt lines with programmable priorities, or "jcore,aic2" for
7+
the "aic2" core with 64 interrupts.
8+
9+
- reg: Memory region(s) for configuration. For SMP, there should be one
10+
region per cpu, indexed by the sequential, zero-based hardware cpu
11+
number.
12+
13+
- interrupt-controller: Identifies the node as an interrupt controller
14+
15+
- #interrupt-cells: Specifies the number of cells needed to encode an
16+
interrupt source. The value shall be 1.
17+
18+
19+
Example:
20+
21+
aic: interrupt-controller@200 {
22+
compatible = "jcore,aic2";
23+
reg = < 0x200 0x30 0x500 0x30 >;
24+
interrupt-controller;
25+
#interrupt-cells = <1>;
26+
};

drivers/irqchip/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ config PIC32_EVIC
156156
select GENERIC_IRQ_CHIP
157157
select IRQ_DOMAIN
158158

159+
config JCORE_AIC
160+
bool "J-Core integrated AIC"
161+
depends on OF && (SUPERH || COMPILE_TEST)
162+
select IRQ_DOMAIN
163+
help
164+
Support for the J-Core integrated AIC.
165+
159166
config RENESAS_INTC_IRQPIN
160167
bool
161168
select IRQ_DOMAIN

drivers/irqchip/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ obj-$(CONFIG_I8259) += irq-i8259.o
4040
obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o
4141
obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o
4242
obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o
43+
obj-$(CONFIG_JCORE_AIC) += irq-jcore-aic.o
4344
obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o
4445
obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
4546
obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o

drivers/irqchip/irq-jcore-aic.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* J-Core SoC AIC driver
3+
*
4+
* Copyright (C) 2015-2016 Smart Energy Instruments, Inc.
5+
*
6+
* This file is subject to the terms and conditions of the GNU General Public
7+
* License. See the file "COPYING" in the main directory of this archive
8+
* for more details.
9+
*/
10+
11+
#include <linux/irq.h>
12+
#include <linux/io.h>
13+
#include <linux/irqchip.h>
14+
#include <linux/irqdomain.h>
15+
#include <linux/cpu.h>
16+
#include <linux/of.h>
17+
#include <linux/of_address.h>
18+
#include <linux/of_irq.h>
19+
20+
#define JCORE_AIC_MAX_HWIRQ 127
21+
#define JCORE_AIC1_MIN_HWIRQ 16
22+
#define JCORE_AIC2_MIN_HWIRQ 64
23+
24+
#define JCORE_AIC1_INTPRI_REG 8
25+
26+
static struct irq_chip jcore_aic;
27+
28+
static int jcore_aic_irqdomain_map(struct irq_domain *d, unsigned int irq,
29+
irq_hw_number_t hwirq)
30+
{
31+
struct irq_chip *aic = d->host_data;
32+
33+
irq_set_chip_and_handler(irq, aic, handle_simple_irq);
34+
35+
return 0;
36+
}
37+
38+
static const struct irq_domain_ops jcore_aic_irqdomain_ops = {
39+
.map = jcore_aic_irqdomain_map,
40+
.xlate = irq_domain_xlate_onecell,
41+
};
42+
43+
static void noop(struct irq_data *data)
44+
{
45+
}
46+
47+
static int __init aic_irq_of_init(struct device_node *node,
48+
struct device_node *parent)
49+
{
50+
unsigned min_irq = JCORE_AIC2_MIN_HWIRQ;
51+
unsigned dom_sz = JCORE_AIC_MAX_HWIRQ+1;
52+
struct irq_domain *domain;
53+
54+
pr_info("Initializing J-Core AIC\n");
55+
56+
/* AIC1 needs priority initialization to receive interrupts. */
57+
if (of_device_is_compatible(node, "jcore,aic1")) {
58+
unsigned cpu;
59+
60+
for_each_present_cpu(cpu) {
61+
void __iomem *base = of_iomap(node, cpu);
62+
63+
if (!base) {
64+
pr_err("Unable to map AIC for cpu %u\n", cpu);
65+
return -ENOMEM;
66+
}
67+
__raw_writel(0xffffffff, base + JCORE_AIC1_INTPRI_REG);
68+
iounmap(base);
69+
}
70+
min_irq = JCORE_AIC1_MIN_HWIRQ;
71+
}
72+
73+
/*
74+
* The irq chip framework requires either mask/unmask or enable/disable
75+
* function pointers to be provided, but the hardware does not have any
76+
* such mechanism; the only interrupt masking is at the cpu level and
77+
* it affects all interrupts. We provide dummy mask/unmask. The hardware
78+
* handles all interrupt control and clears pending status when the cpu
79+
* accepts the interrupt.
80+
*/
81+
jcore_aic.irq_mask = noop;
82+
jcore_aic.irq_unmask = noop;
83+
jcore_aic.name = "AIC";
84+
85+
domain = irq_domain_add_linear(node, dom_sz, &jcore_aic_irqdomain_ops,
86+
&jcore_aic);
87+
if (!domain)
88+
return -ENOMEM;
89+
irq_create_strict_mappings(domain, min_irq, min_irq, dom_sz - min_irq);
90+
91+
return 0;
92+
}
93+
94+
IRQCHIP_DECLARE(jcore_aic2, "jcore,aic2", aic_irq_of_init);
95+
IRQCHIP_DECLARE(jcore_aic1, "jcore,aic1", aic_irq_of_init);

0 commit comments

Comments
 (0)