04d58fcd3da0c5afdb3aac8eb82a19568d21da73
[15.05/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 diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi
27 index 50da059..a06f5b8 100644
28 --- a/arch/arm/boot/dts/bcm2708.dtsi
29 +++ b/arch/arm/boot/dts/bcm2708.dtsi
30 @@ -4,6 +4,8 @@
31         compatible = "brcm,bcm2708";
32         model = "BCM2708";
33  
34 +       interrupt-parent = <&intc>;
35 +
36         chosen {
37                 /*
38                    bootargs must be 1024 characters long because the
39 @@ -17,6 +19,13 @@
40                 #address-cells = <1>;
41                 #size-cells = <1>;
42                 ranges = <0x7e000000 0x20000000 0x02000000>;
43 +
44 +               intc: interrupt-controller {
45 +                       compatible = "brcm,bcm2708-armctrl-ic";
46 +                       reg = <0x7e00b200 0x200>;
47 +                       interrupt-controller;
48 +                       #interrupt-cells = <2>;
49 +               };
50         };
51  
52         clocks {
53 diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c
54 index 96fa9b9..74bacb3 100644
55 --- a/arch/arm/mach-bcm2708/armctrl.c
56 +++ b/arch/arm/mach-bcm2708/armctrl.c
57 @@ -23,6 +23,8 @@
58  #include <linux/version.h>
59  #include <linux/syscore_ops.h>
60  #include <linux/interrupt.h>
61 +#include <linux/irqdomain.h>
62 +#include <linux/of.h>
63  
64  #include <asm/mach/irq.h>
65  #include <mach/hardware.h>
66 @@ -79,6 +81,99 @@ static void armctrl_unmask_irq(struct irq_data *d)
67         }
68  }
69  
70 +#ifdef CONFIG_OF
71 +
72 +#define NR_IRQS_BANK0           21
73 +#define NR_BANKS                3
74 +#define IRQS_PER_BANK           32
75 +
76 +/* from drivers/irqchip/irq-bcm2835.c */
77 +static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
78 +        const u32 *intspec, unsigned int intsize,
79 +        unsigned long *out_hwirq, unsigned int *out_type)
80 +{
81 +        if (WARN_ON(intsize != 2))
82 +                return -EINVAL;
83 +
84 +        if (WARN_ON(intspec[0] >= NR_BANKS))
85 +                return -EINVAL;
86 +
87 +        if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
88 +                return -EINVAL;
89 +
90 +        if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
91 +                return -EINVAL;
92 +
93 +       if (intspec[0] == 0)
94 +               *out_hwirq = ARM_IRQ0_BASE + intspec[1];
95 +       else if (intspec[0] == 1)
96 +               *out_hwirq = ARM_IRQ1_BASE + intspec[1];
97 +       else
98 +               *out_hwirq = ARM_IRQ2_BASE + intspec[1];
99 +
100 +       /* reverse remap_irqs[] */
101 +       switch (*out_hwirq) {
102 +       case INTERRUPT_VC_JPEG:
103 +               *out_hwirq = INTERRUPT_JPEG;
104 +               break;
105 +       case INTERRUPT_VC_USB:
106 +               *out_hwirq = INTERRUPT_USB;
107 +               break;
108 +       case INTERRUPT_VC_3D:
109 +               *out_hwirq = INTERRUPT_3D;
110 +               break;
111 +       case INTERRUPT_VC_DMA2:
112 +               *out_hwirq = INTERRUPT_DMA2;
113 +               break;
114 +       case INTERRUPT_VC_DMA3:
115 +               *out_hwirq = INTERRUPT_DMA3;
116 +               break;
117 +       case INTERRUPT_VC_I2C:
118 +               *out_hwirq = INTERRUPT_I2C;
119 +               break;
120 +       case INTERRUPT_VC_SPI:
121 +               *out_hwirq = INTERRUPT_SPI;
122 +               break;
123 +       case INTERRUPT_VC_I2SPCM:
124 +               *out_hwirq = INTERRUPT_I2SPCM;
125 +               break;
126 +       case INTERRUPT_VC_SDIO:
127 +               *out_hwirq = INTERRUPT_SDIO;
128 +               break;
129 +       case INTERRUPT_VC_UART:
130 +               *out_hwirq = INTERRUPT_UART;
131 +               break;
132 +       case INTERRUPT_VC_ARASANSDIO:
133 +               *out_hwirq = INTERRUPT_ARASANSDIO;
134 +               break;
135 +       }
136 +
137 +        *out_type = IRQ_TYPE_NONE;
138 +        return 0;
139 +}
140 +
141 +static struct irq_domain_ops armctrl_ops = {
142 +        .xlate = armctrl_xlate
143 +};
144 +
145 +void __init armctrl_dt_init(void)
146 +{
147 +       struct device_node *np;
148 +       struct irq_domain *domain;
149 +
150 +       np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
151 +       if (!np)
152 +               return;
153 +
154 +       domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS,
155 +                                       IRQ_ARMCTRL_START, 0,
156 +                                       &armctrl_ops, NULL);
157 +        WARN_ON(!domain);
158 +}
159 +#else
160 +void __init armctrl_dt_init(void) { }
161 +#endif /* CONFIG_OF */
162 +
163  #if defined(CONFIG_PM)
164  
165  /* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
166 @@ -215,5 +310,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start,
167  
168         armctrl_pm_register(base, irq_start, resume_sources);
169         init_FIQ(FIQ_START);
170 +       armctrl_dt_init();
171         return 0;
172  }
173 -- 
174 1.8.3.2
175