aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2013-11-21 17:13:17 -0500
committerLinus Walleij <linus.walleij@linaro.org>2014-02-13 05:21:34 -0500
commit52d555fffffe6a8c254a71a133151ad8e658dc61 (patch)
tree394791006598657a9208c1b0d976511bef4dbe2a
parent31d951e2c985165a57a4885079d8dbfeed231a26 (diff)
ARM: integrator: register the IM-PD1 VIC
The peripherals on the IM-PD1 has never really been able to properly fire their IRQs to the main FPGA IRQ controller. Cascade it properly and register interrupts for all the devices in the array. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--arch/arm/mach-integrator/Kconfig1
-rw-r--r--arch/arm/mach-integrator/impd1.c45
2 files changed, 37 insertions, 9 deletions
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index abeff25532ab..46be99007529 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -30,6 +30,7 @@ config ARCH_CINTEGRATOR
30config INTEGRATOR_IMPD1 30config INTEGRATOR_IMPD1
31 tristate "Include support for Integrator/IM-PD1" 31 tristate "Include support for Integrator/IM-PD1"
32 depends on ARCH_INTEGRATOR_AP 32 depends on ARCH_INTEGRATOR_AP
33 select ARM_VIC
33 help 34 help
34 The IM-PD1 is an add-on logic module for the Integrator which 35 The IM-PD1 is an add-on logic module for the Integrator which
35 allows ARM(R) Ltd PrimeCells to be developed and evaluated. 36 allows ARM(R) Ltd PrimeCells to be developed and evaluated.
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index aeeae0d79a18..d9b784824808 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -23,6 +23,7 @@
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/platform_data/clk-integrator.h> 24#include <linux/platform_data/clk-integrator.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/irqchip/arm-vic.h>
26 27
27#include <mach/lm.h> 28#include <mach/lm.h>
28#include <mach/impd1.h> 29#include <mach/impd1.h>
@@ -35,6 +36,7 @@ MODULE_PARM_DESC(lmid, "logic module stack position");
35 36
36struct impd1_module { 37struct impd1_module {
37 void __iomem *base; 38 void __iomem *base;
39 void __iomem *vic_base;
38}; 40};
39 41
40void impd1_tweak_control(struct device *dev, u32 mask, u32 val) 42void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
@@ -262,9 +264,6 @@ struct impd1_device {
262 264
263static struct impd1_device impd1_devs[] = { 265static struct impd1_device impd1_devs[] = {
264 { 266 {
265 .offset = 0x03000000,
266 .id = 0x00041190,
267 }, {
268 .offset = 0x00100000, 267 .offset = 0x00100000,
269 .irq = { 1 }, 268 .irq = { 1 },
270 .id = 0x00141011, 269 .id = 0x00141011,
@@ -304,9 +303,15 @@ static struct impd1_device impd1_devs[] = {
304 } 303 }
305}; 304};
306 305
307static int impd1_probe(struct lm_device *dev) 306/*
307 * Valid IRQs: 0 thru 9 and 11, 10 unused.
308 */
309#define IMPD1_VALID_IRQS 0x00000bffU
310
311static int __init impd1_probe(struct lm_device *dev)
308{ 312{
309 struct impd1_module *impd1; 313 struct impd1_module *impd1;
314 int irq_base;
310 int i; 315 int i;
311 316
312 if (dev->id != module_id) 317 if (dev->id != module_id)
@@ -325,23 +330,45 @@ static int impd1_probe(struct lm_device *dev)
325 if (!impd1->base) 330 if (!impd1->base)
326 return -ENOMEM; 331 return -ENOMEM;
327 332
328 lm_set_drvdata(dev, impd1); 333 integrator_impd1_clk_init(impd1->base, dev->id);
334
335 if (!devm_request_mem_region(&dev->dev,
336 dev->resource.start + 0x03000000,
337 SZ_4K, "VIC"))
338 return -EBUSY;
329 339
330 printk("IM-PD1 found at 0x%08lx\n", 340 impd1->vic_base = devm_ioremap(&dev->dev,
331 (unsigned long)dev->resource.start); 341 dev->resource.start + 0x03000000,
342 SZ_4K);
343 if (!impd1->vic_base)
344 return -ENOMEM;
332 345
333 integrator_impd1_clk_init(impd1->base, dev->id); 346 irq_base = vic_init_cascaded(impd1->vic_base, dev->irq,
347 IMPD1_VALID_IRQS, 0);
348
349 lm_set_drvdata(dev, impd1);
350
351 dev_info(&dev->dev, "IM-PD1 found at 0x%08lx\n",
352 (unsigned long)dev->resource.start);
334 353
335 for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { 354 for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
336 struct impd1_device *idev = impd1_devs + i; 355 struct impd1_device *idev = impd1_devs + i;
337 struct amba_device *d; 356 struct amba_device *d;
338 unsigned long pc_base; 357 unsigned long pc_base;
339 char devname[32]; 358 char devname[32];
359 int irq1 = idev->irq[0];
360 int irq2 = idev->irq[1];
361
362 /* Translate IRQs to IM-PD1 local numberspace */
363 if (irq1)
364 irq1 += irq_base;
365 if (irq2)
366 irq2 += irq_base;
340 367
341 pc_base = dev->resource.start + idev->offset; 368 pc_base = dev->resource.start + idev->offset;
342 snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12); 369 snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
343 d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K, 370 d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K,
344 dev->irq, dev->irq, 371 irq1, irq2,
345 idev->platform_data, idev->id, 372 idev->platform_data, idev->id,
346 &dev->resource); 373 &dev->resource);
347 if (IS_ERR(d)) { 374 if (IS_ERR(d)) {