ar71xx: track the correct WAN interface on wnr2000-v4
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-3.18 / 0050-BCM2708-armctrl-Add-IRQ-Device-Tree-support.patch
1 From 6be3809614db2d52724eb4b5193c27d2466142be Mon Sep 17 00:00:00 2001
2 From: notro <notro@tronnes.org>
3 Date: Wed, 9 Jul 2014 14:47:48 +0200
4 Subject: [PATCH 050/114] BCM2708: armctrl: Add IRQ Device Tree support
5
6 Add Device Tree IRQ support for BCM2708.
7 Usage is the same as for irq-bcm2835.
8 See binding document: brcm,bcm2835-armctrl-ic.txt
9
10 A bank 3 is added to handle GPIO interrupts. This is done because
11 armctrl also handles GPIO interrupts.
12
13 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
14
15 BCM2708: armctrl: remove irq bank 3
16
17 irq bank 3 was needed by the pinctrl-bcm2708 and bcm2708_gpio
18 combination. It is no longer required.
19
20 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
21 ---
22 arch/arm/boot/dts/bcm2708.dtsi | 9 ++++
23 arch/arm/mach-bcm2708/armctrl.c | 96 +++++++++++++++++++++++++++++++++++++++++
24 2 files changed, 105 insertions(+)
25
26 --- a/arch/arm/boot/dts/bcm2708.dtsi
27 +++ b/arch/arm/boot/dts/bcm2708.dtsi
28 @@ -4,6 +4,8 @@
29 compatible = "brcm,bcm2708";
30 model = "BCM2708";
31
32 + interrupt-parent = <&intc>;
33 +
34 chosen {
35 /*
36 bootargs must be 1024 characters long because the
37 @@ -17,6 +19,13 @@
38 #address-cells = <1>;
39 #size-cells = <1>;
40 ranges = <0x7e000000 0x20000000 0x02000000>;
41 +
42 + intc: interrupt-controller {
43 + compatible = "brcm,bcm2708-armctrl-ic";
44 + reg = <0x7e00b200 0x200>;
45 + interrupt-controller;
46 + #interrupt-cells = <2>;
47 + };
48 };
49
50 clocks {
51 --- a/arch/arm/mach-bcm2708/armctrl.c
52 +++ b/arch/arm/mach-bcm2708/armctrl.c
53 @@ -23,6 +23,8 @@
54 #include <linux/version.h>
55 #include <linux/syscore_ops.h>
56 #include <linux/interrupt.h>
57 +#include <linux/irqdomain.h>
58 +#include <linux/of.h>
59
60 #include <asm/mach/irq.h>
61 #include <mach/hardware.h>
62 @@ -79,6 +81,99 @@ static void armctrl_unmask_irq(struct ir
63 }
64 }
65
66 +#ifdef CONFIG_OF
67 +
68 +#define NR_IRQS_BANK0 21
69 +#define NR_BANKS 3
70 +#define IRQS_PER_BANK 32
71 +
72 +/* from drivers/irqchip/irq-bcm2835.c */
73 +static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
74 + const u32 *intspec, unsigned int intsize,
75 + unsigned long *out_hwirq, unsigned int *out_type)
76 +{
77 + if (WARN_ON(intsize != 2))
78 + return -EINVAL;
79 +
80 + if (WARN_ON(intspec[0] >= NR_BANKS))
81 + return -EINVAL;
82 +
83 + if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
84 + return -EINVAL;
85 +
86 + if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
87 + return -EINVAL;
88 +
89 + if (intspec[0] == 0)
90 + *out_hwirq = ARM_IRQ0_BASE + intspec[1];
91 + else if (intspec[0] == 1)
92 + *out_hwirq = ARM_IRQ1_BASE + intspec[1];
93 + else
94 + *out_hwirq = ARM_IRQ2_BASE + intspec[1];
95 +
96 + /* reverse remap_irqs[] */
97 + switch (*out_hwirq) {
98 + case INTERRUPT_VC_JPEG:
99 + *out_hwirq = INTERRUPT_JPEG;
100 + break;
101 + case INTERRUPT_VC_USB:
102 + *out_hwirq = INTERRUPT_USB;
103 + break;
104 + case INTERRUPT_VC_3D:
105 + *out_hwirq = INTERRUPT_3D;
106 + break;
107 + case INTERRUPT_VC_DMA2:
108 + *out_hwirq = INTERRUPT_DMA2;
109 + break;
110 + case INTERRUPT_VC_DMA3:
111 + *out_hwirq = INTERRUPT_DMA3;
112 + break;
113 + case INTERRUPT_VC_I2C:
114 + *out_hwirq = INTERRUPT_I2C;
115 + break;
116 + case INTERRUPT_VC_SPI:
117 + *out_hwirq = INTERRUPT_SPI;
118 + break;
119 + case INTERRUPT_VC_I2SPCM:
120 + *out_hwirq = INTERRUPT_I2SPCM;
121 + break;
122 + case INTERRUPT_VC_SDIO:
123 + *out_hwirq = INTERRUPT_SDIO;
124 + break;
125 + case INTERRUPT_VC_UART:
126 + *out_hwirq = INTERRUPT_UART;
127 + break;
128 + case INTERRUPT_VC_ARASANSDIO:
129 + *out_hwirq = INTERRUPT_ARASANSDIO;
130 + break;
131 + }
132 +
133 + *out_type = IRQ_TYPE_NONE;
134 + return 0;
135 +}
136 +
137 +static struct irq_domain_ops armctrl_ops = {
138 + .xlate = armctrl_xlate
139 +};
140 +
141 +void __init armctrl_dt_init(void)
142 +{
143 + struct device_node *np;
144 + struct irq_domain *domain;
145 +
146 + np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
147 + if (!np)
148 + return;
149 +
150 + domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS,
151 + IRQ_ARMCTRL_START, 0,
152 + &armctrl_ops, NULL);
153 + WARN_ON(!domain);
154 +}
155 +#else
156 +void __init armctrl_dt_init(void) { }
157 +#endif /* CONFIG_OF */
158 +
159 #if defined(CONFIG_PM)
160
161 /* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
162 @@ -215,5 +310,6 @@ int __init armctrl_init(void __iomem * b
163
164 armctrl_pm_register(base, irq_start, resume_sources);
165 init_FIQ(FIQ_START);
166 + armctrl_dt_init();
167 return 0;
168 }