summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorKevin Cernekee <cernekee@gmail.com>2014-12-25 12:49:05 -0500
committerRalf Baechle <ralf@linux-mips.org>2015-04-01 11:21:37 -0400
commit7b7230e70e9eda75356cf15c450b65b77924486f (patch)
tree240e5446a54d0de5e3caf8566ac39cc01cf7459b /drivers/irqchip
parentca40f1b23df70c6f31b14a5743a6f3b60e862ce1 (diff)
IRQCHIP: bcm7120-l2: Add support for BCM3380-style controllers
These controllers support multiple enable/status pairs (64+ IRQs), can put the enable/status words at different offsets, and do not support multiple parent IRQs. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> Cc: f.fainelli@gmail.com Cc: jaedon.shin@gmail.com Cc: abrestic@chromium.org Cc: tglx@linutronix.de Cc: jason@lakedaemon.net Cc: jogo@openwrt.org Cc: arnd@arndb.de Cc: computersforpeace@gmail.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8843/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-bcm7120-l2.c55
1 files changed, 51 insertions, 4 deletions
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c
index 6a6285897df1..3ba5cc780fcb 100644
--- a/drivers/irqchip/irq-bcm7120-l2.c
+++ b/drivers/irqchip/irq-bcm7120-l2.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/kconfig.h> 16#include <linux/kconfig.h>
17#include <linux/kernel.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/of.h> 19#include <linux/of.h>
19#include <linux/of_irq.h> 20#include <linux/of_irq.h>
@@ -120,10 +121,15 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,
120 /* For multiple parent IRQs with multiple words, this looks like: 121 /* For multiple parent IRQs with multiple words, this looks like:
121 * <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...> 122 * <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...>
122 */ 123 */
123 for (idx = 0; idx < data->n_words; idx++) 124 for (idx = 0; idx < data->n_words; idx++) {
124 data->irq_map_mask[idx] |= 125 if (data->map_mask_prop) {
125 be32_to_cpup(data->map_mask_prop + 126 data->irq_map_mask[idx] |=
126 irq * data->n_words + idx); 127 be32_to_cpup(data->map_mask_prop +
128 irq * data->n_words + idx);
129 } else {
130 data->irq_map_mask[idx] = 0xffffffff;
131 }
132 }
127 133
128 irq_set_handler_data(parent_irq, data); 134 irq_set_handler_data(parent_irq, data);
129 irq_set_chained_handler(parent_irq, bcm7120_l2_intc_irq_handle); 135 irq_set_chained_handler(parent_irq, bcm7120_l2_intc_irq_handle);
@@ -165,6 +171,37 @@ static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn,
165 return 0; 171 return 0;
166} 172}
167 173
174static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn,
175 struct bcm7120_l2_intc_data *data)
176{
177 unsigned int gc_idx;
178
179 for (gc_idx = 0; gc_idx < MAX_WORDS; gc_idx++) {
180 unsigned int map_idx = gc_idx * 2;
181 void __iomem *en = of_iomap(dn, map_idx + 0);
182 void __iomem *stat = of_iomap(dn, map_idx + 1);
183 void __iomem *base = min(en, stat);
184
185 data->map_base[map_idx + 0] = en;
186 data->map_base[map_idx + 1] = stat;
187
188 if (!base)
189 break;
190
191 data->pair_base[gc_idx] = base;
192 data->en_offset[gc_idx] = en - base;
193 data->stat_offset[gc_idx] = stat - base;
194 }
195
196 if (!gc_idx) {
197 pr_err("unable to map registers\n");
198 return -EINVAL;
199 }
200
201 data->n_words = gc_idx;
202 return 0;
203}
204
168int __init bcm7120_l2_intc_probe(struct device_node *dn, 205int __init bcm7120_l2_intc_probe(struct device_node *dn,
169 struct device_node *parent, 206 struct device_node *parent,
170 int (*iomap_regs_fn)(struct device_node *, 207 int (*iomap_regs_fn)(struct device_node *,
@@ -279,5 +316,15 @@ int __init bcm7120_l2_intc_probe_7120(struct device_node *dn,
279 "BCM7120 L2"); 316 "BCM7120 L2");
280} 317}
281 318
319int __init bcm7120_l2_intc_probe_3380(struct device_node *dn,
320 struct device_node *parent)
321{
322 return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380,
323 "BCM3380 L2");
324}
325
282IRQCHIP_DECLARE(bcm7120_l2_intc, "brcm,bcm7120-l2-intc", 326IRQCHIP_DECLARE(bcm7120_l2_intc, "brcm,bcm7120-l2-intc",
283 bcm7120_l2_intc_probe_7120); 327 bcm7120_l2_intc_probe_7120);
328
329IRQCHIP_DECLARE(bcm3380_l2_intc, "brcm,bcm3380-l2-intc",
330 bcm7120_l2_intc_probe_3380);