summaryrefslogtreecommitdiff
path: root/arch/arm/mach-integrator
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-integrator')
-rw-r--r--arch/arm/mach-integrator/Kconfig3
-rw-r--r--arch/arm/mach-integrator/impd1.c81
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c19
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c6
4 files changed, 63 insertions, 46 deletions
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index 271a255864d2..ba43321001d8 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -30,6 +30,9 @@ config ARCH_CINTEGRATOR
config INTEGRATOR_IMPD1
tristate "Include support for Integrator/IM-PD1"
depends on ARCH_INTEGRATOR_AP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_VIC
+ select GPIO_PL061 if GPIOLIB
help
The IM-PD1 is an add-on logic module for the Integrator which
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 9f82f9dcbb98..d9b784824808 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -23,6 +23,7 @@
#include <linux/io.h>
#include <linux/platform_data/clk-integrator.h>
#include <linux/slab.h>
+#include <linux/irqchip/arm-vic.h>
#include <mach/lm.h>
#include <mach/impd1.h>
@@ -35,6 +36,7 @@ MODULE_PARM_DESC(lmid, "logic module stack position");
struct impd1_module {
void __iomem *base;
+ void __iomem *vic_base;
};
void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
@@ -262,9 +264,6 @@ struct impd1_device {
static struct impd1_device impd1_devs[] = {
{
- .offset = 0x03000000,
- .id = 0x00041190,
- }, {
.offset = 0x00100000,
.irq = { 1 },
.id = 0x00141011,
@@ -304,46 +303,72 @@ static struct impd1_device impd1_devs[] = {
}
};
-static int impd1_probe(struct lm_device *dev)
+/*
+ * Valid IRQs: 0 thru 9 and 11, 10 unused.
+ */
+#define IMPD1_VALID_IRQS 0x00000bffU
+
+static int __init impd1_probe(struct lm_device *dev)
{
struct impd1_module *impd1;
- int i, ret;
+ int irq_base;
+ int i;
if (dev->id != module_id)
return -EINVAL;
- if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers"))
+ if (!devm_request_mem_region(&dev->dev, dev->resource.start,
+ SZ_4K, "LM registers"))
return -EBUSY;
- impd1 = kzalloc(sizeof(struct impd1_module), GFP_KERNEL);
- if (!impd1) {
- ret = -ENOMEM;
- goto release_lm;
- }
+ impd1 = devm_kzalloc(&dev->dev, sizeof(struct impd1_module),
+ GFP_KERNEL);
+ if (!impd1)
+ return -ENOMEM;
- impd1->base = ioremap(dev->resource.start, SZ_4K);
- if (!impd1->base) {
- ret = -ENOMEM;
- goto free_impd1;
- }
+ impd1->base = devm_ioremap(&dev->dev, dev->resource.start, SZ_4K);
+ if (!impd1->base)
+ return -ENOMEM;
- lm_set_drvdata(dev, impd1);
+ integrator_impd1_clk_init(impd1->base, dev->id);
- printk("IM-PD1 found at 0x%08lx\n",
- (unsigned long)dev->resource.start);
+ if (!devm_request_mem_region(&dev->dev,
+ dev->resource.start + 0x03000000,
+ SZ_4K, "VIC"))
+ return -EBUSY;
- integrator_impd1_clk_init(impd1->base, dev->id);
+ impd1->vic_base = devm_ioremap(&dev->dev,
+ dev->resource.start + 0x03000000,
+ SZ_4K);
+ if (!impd1->vic_base)
+ return -ENOMEM;
+
+ irq_base = vic_init_cascaded(impd1->vic_base, dev->irq,
+ IMPD1_VALID_IRQS, 0);
+
+ lm_set_drvdata(dev, impd1);
+
+ dev_info(&dev->dev, "IM-PD1 found at 0x%08lx\n",
+ (unsigned long)dev->resource.start);
for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
struct impd1_device *idev = impd1_devs + i;
struct amba_device *d;
unsigned long pc_base;
char devname[32];
+ int irq1 = idev->irq[0];
+ int irq2 = idev->irq[1];
+
+ /* Translate IRQs to IM-PD1 local numberspace */
+ if (irq1)
+ irq1 += irq_base;
+ if (irq2)
+ irq2 += irq_base;
pc_base = dev->resource.start + idev->offset;
snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K,
- dev->irq, dev->irq,
+ irq1, irq2,
idev->platform_data, idev->id,
&dev->resource);
if (IS_ERR(d)) {
@@ -353,14 +378,6 @@ static int impd1_probe(struct lm_device *dev)
}
return 0;
-
- free_impd1:
- if (impd1 && impd1->base)
- iounmap(impd1->base);
- kfree(impd1);
- release_lm:
- release_mem_region(dev->resource.start, SZ_4K);
- return ret;
}
static int impd1_remove_one(struct device *dev, void *data)
@@ -371,16 +388,10 @@ static int impd1_remove_one(struct device *dev, void *data)
static void impd1_remove(struct lm_device *dev)
{
- struct impd1_module *impd1 = lm_get_drvdata(dev);
-
device_for_each_child(&dev->dev, NULL, impd1_remove_one);
integrator_impd1_clk_exit(dev->id);
lm_set_drvdata(dev, NULL);
-
- iounmap(impd1->base);
- kfree(impd1);
- release_mem_region(dev->resource.start, SZ_4K);
}
static struct lm_driver impd1_driver = {
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index e4f27f0e56ac..cc0857cab2e1 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -42,6 +42,7 @@
#include <linux/sys_soc.h>
#include <linux/termios.h>
#include <linux/sched_clock.h>
+#include <linux/clk-provider.h>
#include <mach/hardware.h>
#include <mach/platform.h>
@@ -402,10 +403,7 @@ static void __init ap_of_timer_init(void)
struct clk *clk;
unsigned long rate;
- clk = clk_get_sys("ap_timer", NULL);
- BUG_ON(IS_ERR(clk));
- clk_prepare_enable(clk);
- rate = clk_get_rate(clk);
+ of_clk_init(NULL);
err = of_property_read_string(of_aliases,
"arm,timer-primary", &path);
@@ -415,6 +413,12 @@ static void __init ap_of_timer_init(void)
base = of_iomap(node, 0);
if (WARN_ON(!base))
return;
+
+ clk = of_clk_get(node, 0);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+
writel(0, base + TIMER_CTRL);
integrator_clocksource_init(rate, base);
@@ -427,6 +431,12 @@ static void __init ap_of_timer_init(void)
if (WARN_ON(!base))
return;
irq = irq_of_parse_and_map(node, 0);
+
+ clk = of_clk_get(node, 0);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+
writel(0, base + TIMER_CTRL);
integrator_clockevent_init(rate, base, irq);
}
@@ -440,7 +450,6 @@ static void __init ap_init_irq_of(void)
{
cm_init();
of_irq_init(fpga_irq_of_match);
- integrator_clk_init(false);
}
/* For the Device Tree, add in the UART callbacks as AUXDATA */
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index a3ef961e4a93..0ad5f60598c8 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -23,7 +23,6 @@
#include <linux/irqchip/versatile-fpga.h>
#include <linux/gfp.h>
#include <linux/mtd/physmap.h>
-#include <linux/platform_data/clk-integrator.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
@@ -33,8 +32,6 @@
#include <mach/platform.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
-#include <asm/hardware/icst.h>
#include <mach/lm.h>
@@ -43,8 +40,6 @@
#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <asm/hardware/timer-sp.h>
-
#include <plat/clcd.h>
#include <plat/sched_clock.h>
@@ -250,7 +245,6 @@ static void __init intcp_init_irq_of(void)
{
cm_init();
of_irq_init(fpga_irq_of_match);
- integrator_clk_init(true);
}
/*