diff options
-rw-r--r-- | arch/arm/mach-integrator/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-integrator/impd1.c | 45 |
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 | |||
30 | config INTEGRATOR_IMPD1 | 30 | config 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 | ||
36 | struct impd1_module { | 37 | struct impd1_module { |
37 | void __iomem *base; | 38 | void __iomem *base; |
39 | void __iomem *vic_base; | ||
38 | }; | 40 | }; |
39 | 41 | ||
40 | void impd1_tweak_control(struct device *dev, u32 mask, u32 val) | 42 | void impd1_tweak_control(struct device *dev, u32 mask, u32 val) |
@@ -262,9 +264,6 @@ struct impd1_device { | |||
262 | 264 | ||
263 | static struct impd1_device impd1_devs[] = { | 265 | static 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 | ||
307 | static 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 | |||
311 | static 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)) { |