Skip to content

Commit ba97112

Browse files
committed
BCM2708: armctrl: Add IRQ Device Tree support
Add Device Tree IRQ support for BCM2708. Usage is the same as for irq-bcm2835. See binding document: brcm,bcm2835-armctrl-ic.txt A bank 3 is added to handle GPIO interrupts. This is done because armctrl also handles GPIO interrupts. Signed-off-by: Noralf Tronnes <[email protected]>
1 parent 853bcb0 commit ba97112

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

arch/arm/boot/dts/bcm2708.dtsi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
compatible = "brcm,bcm2708";
55
model = "BCM2708";
66

7+
interrupt-parent = <&intc>;
8+
79
chosen {
810
/*
911
bootargs must be 1024 characters long because the
@@ -17,6 +19,13 @@
1719
#address-cells = <1>;
1820
#size-cells = <1>;
1921
ranges = <0x7e000000 0x20000000 0x02000000>;
22+
23+
intc: interrupt-controller {
24+
compatible = "brcm,bcm2708-armctrl-ic";
25+
reg = <0x7e00b200 0x200>;
26+
interrupt-controller;
27+
#interrupt-cells = <2>;
28+
};
2029
};
2130

2231
clocks {

arch/arm/mach-bcm2708/armctrl.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <linux/version.h>
2424
#include <linux/syscore_ops.h>
2525
#include <linux/interrupt.h>
26+
#include <linux/irqdomain.h>
27+
#include <linux/of.h>
2628

2729
#include <asm/mach/irq.h>
2830
#include <mach/hardware.h>
@@ -79,6 +81,100 @@ static void armctrl_unmask_irq(struct irq_data *d)
7981
}
8082
}
8183

84+
#ifdef CONFIG_OF
85+
86+
#define NR_IRQS_BANK0 21
87+
#define NR_BANKS 3 + 1 /* bank 3 is used for GPIO interrupts */
88+
#define IRQS_PER_BANK 32
89+
90+
/* from drivers/irqchip/irq-bcm2835.c */
91+
static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
92+
const u32 *intspec, unsigned int intsize,
93+
unsigned long *out_hwirq, unsigned int *out_type)
94+
{
95+
if (WARN_ON(intsize != 2))
96+
return -EINVAL;
97+
98+
if (WARN_ON(intspec[0] >= NR_BANKS))
99+
return -EINVAL;
100+
101+
if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
102+
return -EINVAL;
103+
104+
if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
105+
return -EINVAL;
106+
107+
if (intspec[0] == 0)
108+
*out_hwirq = ARM_IRQ0_BASE + intspec[1];
109+
else if (intspec[0] == 1)
110+
*out_hwirq = ARM_IRQ1_BASE + intspec[1];
111+
else if (intspec[0] == 2)
112+
*out_hwirq = ARM_IRQ2_BASE + intspec[1];
113+
else
114+
*out_hwirq = GPIO_IRQ_START + intspec[1];
115+
116+
/* reverse remap_irqs[] */
117+
switch (*out_hwirq) {
118+
case INTERRUPT_VC_JPEG:
119+
*out_hwirq = INTERRUPT_JPEG;
120+
break;
121+
case INTERRUPT_VC_USB:
122+
*out_hwirq = INTERRUPT_USB;
123+
break;
124+
case INTERRUPT_VC_3D:
125+
*out_hwirq = INTERRUPT_3D;
126+
break;
127+
case INTERRUPT_VC_DMA2:
128+
*out_hwirq = INTERRUPT_DMA2;
129+
break;
130+
case INTERRUPT_VC_DMA3:
131+
*out_hwirq = INTERRUPT_DMA3;
132+
break;
133+
case INTERRUPT_VC_I2C:
134+
*out_hwirq = INTERRUPT_I2C;
135+
break;
136+
case INTERRUPT_VC_SPI:
137+
*out_hwirq = INTERRUPT_SPI;
138+
break;
139+
case INTERRUPT_VC_I2SPCM:
140+
*out_hwirq = INTERRUPT_I2SPCM;
141+
break;
142+
case INTERRUPT_VC_SDIO:
143+
*out_hwirq = INTERRUPT_SDIO;
144+
break;
145+
case INTERRUPT_VC_UART:
146+
*out_hwirq = INTERRUPT_UART;
147+
break;
148+
case INTERRUPT_VC_ARASANSDIO:
149+
*out_hwirq = INTERRUPT_ARASANSDIO;
150+
break;
151+
}
152+
153+
*out_type = IRQ_TYPE_NONE;
154+
return 0;
155+
}
156+
157+
static struct irq_domain_ops armctrl_ops = {
158+
.xlate = armctrl_xlate
159+
};
160+
161+
void __init armctrl_dt_init(void)
162+
{
163+
struct device_node *np;
164+
struct irq_domain *domain;
165+
166+
np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
167+
if (!np)
168+
return;
169+
170+
domain = irq_domain_add_legacy(np, NR_IRQS, IRQ_ARMCTRL_START, 0,
171+
&armctrl_ops, NULL);
172+
WARN_ON(!domain);
173+
}
174+
#else
175+
void __init armctrl_dt_init(void) { }
176+
#endif /* CONFIG_OF */
177+
82178
#if defined(CONFIG_PM)
83179

84180
/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
@@ -215,5 +311,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start,
215311

216312
armctrl_pm_register(base, irq_start, resume_sources);
217313
init_FIQ(FIQ_START);
314+
armctrl_dt_init();
218315
return 0;
219316
}

0 commit comments

Comments
 (0)