aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)) {