summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-integrator/Makefile2
-rw-r--r--arch/arm/mach-integrator/core.c30
-rw-r--r--arch/arm/mach-integrator/impd1.c61
-rw-r--r--arch/arm/mach-integrator/lm.c92
-rw-r--r--include/asm-arm/arch-integrator/lm.h23
5 files changed, 171 insertions, 37 deletions
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
index bfd77c270a06..c126c5307174 100644
--- a/arch/arm/mach-integrator/Makefile
+++ b/arch/arm/mach-integrator/Makefile
@@ -4,7 +4,7 @@
# Object file lists.
-obj-y := core.o time.o
+obj-y := core.o lm.o time.o
obj-$(CONFIG_LEDS) += leds.o
obj-$(CONFIG_PCI) += pci_v3.o pci.o
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index c7e7eb4a9c43..67d0fc309304 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -34,6 +34,8 @@
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_kmi.h>
+#include <asm/arch/lm.h>
+
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
@@ -46,6 +48,7 @@
* just for now).
*/
#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
+#define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE)
#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
/*
@@ -66,7 +69,7 @@
* f1a00000 1a000000 Debug LEDs
* f1b00000 1b000000 GPIO
*/
-
+
static struct map_desc integrator_io_desc[] __initdata = {
{ IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE },
{ IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE },
@@ -89,7 +92,7 @@ static void __init integrator_map_io(void)
iotable_init(integrator_io_desc, ARRAY_SIZE(integrator_io_desc));
}
-#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) )
+#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) )
static void sc_mask_irq(unsigned int irq)
{
@@ -161,6 +164,7 @@ static struct amba_device *amba_devs[] __initdata = {
static int __init register_devices(void)
{
+ unsigned long sc_dec;
int i;
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
@@ -169,6 +173,28 @@ static int __init register_devices(void)
amba_device_register(d, &iomem_resource);
}
+ sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
+ for (i = 0; i < 4; i++) {
+ struct lm_device *lmdev;
+
+ if ((sc_dec & (16 << i)) == 0)
+ continue;
+
+ lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL);
+ if (!lmdev)
+ continue;
+
+ memset(lmdev, 0, sizeof(struct lm_device));
+
+ lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
+ lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
+ lmdev->resource.flags = IORESOURCE_MEM;
+ lmdev->irq = IRQ_EXPINT0 + i;
+ lmdev->id = i;
+
+ lm_device_register(lmdev);
+ }
+
return 0;
}
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 15e2e27da2de..1fc9d9535ab8 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -10,7 +10,7 @@
* This file provides the core support for the IM-PD1 module.
*
* Module / boot parameters.
- * id=n impd1.id=n - set the logic module position in stack to 'n'
+ * lmid=n impd1.lmid=n - set the logic module position in stack to 'n'
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -21,17 +21,15 @@
#include <asm/io.h>
#include <asm/hardware/icst525.h>
#include <asm/hardware/amba.h>
+#include <asm/arch/lm.h>
#include <asm/arch/impd1.h>
#include <asm/sizes.h>
static int module_id;
-module_param_named(lmid, module_id, int, 0);
+module_param_named(lmid, module_id, int, 0444);
MODULE_PARM_DESC(lmid, "logic module stack position");
-#define ROM_OFFSET 0x0fffff00
-#define ROM_SIZE 256
-
struct impd1_module {
void *base;
};
@@ -142,17 +140,15 @@ static struct impd1_device impd1_devs[] = {
}
};
-static int impd1_probe(struct device *dev)
+static int impd1_probe(struct lm_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct resource *res = &pdev->resource[0];
struct impd1_module *impd1;
int i, ret;
- if (pdev->id != module_id)
+ if (dev->id != module_id)
return -EINVAL;
- if (!request_mem_region(res->start, SZ_4K, "LM registers"))
+ if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers"))
return -EBUSY;
impd1 = kmalloc(sizeof(struct impd1_module), GFP_KERNEL);
@@ -162,22 +158,22 @@ static int impd1_probe(struct device *dev)
}
memset(impd1, 0, sizeof(struct impd1_module));
- impd1->base = ioremap(res->start, SZ_4K);
+ impd1->base = ioremap(dev->resource.start, SZ_4K);
if (!impd1->base) {
ret = -ENOMEM;
goto free_impd1;
}
- dev_set_drvdata(dev, impd1);
+ lm_set_drvdata(dev, impd1);
- printk("IM-PD1 found at 0x%08lx\n", res->start);
+ printk("IM-PD1 found at 0x%08lx\n", 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;
- pc_base = res->start + idev->offset;
+ pc_base = dev->resource.start + idev->offset;
d = kmalloc(sizeof(struct amba_device), GFP_KERNEL);
if (!d)
@@ -186,16 +182,16 @@ static int impd1_probe(struct device *dev)
memset(d, 0, sizeof(struct amba_device));
snprintf(d->dev.bus_id, sizeof(d->dev.bus_id),
- "lm%x:%5.5lx", pdev->id, idev->offset >> 12);
+ "lm%x:%5.5lx", dev->id, idev->offset >> 12);
- d->dev.parent = &pdev->dev;
- d->res.start = res->start + idev->offset;
+ d->dev.parent = &dev->dev;
+ d->res.start = dev->resource.start + idev->offset;
d->res.end = d->res.start + SZ_4K - 1;
d->res.flags = IORESOURCE_MEM;
- d->irq = pdev->resource[1].start;
+ d->irq = dev->irq;
d->periphid = idev->id;
- ret = amba_device_register(d, res);
+ ret = amba_device_register(d, &dev->resource);
if (ret) {
printk("unable to register device %s: %d\n",
d->dev.bus_id, ret);
@@ -211,47 +207,44 @@ static int impd1_probe(struct device *dev)
if (impd1)
kfree(impd1);
release_lm:
- release_mem_region(res->start, SZ_4K);
+ release_mem_region(dev->resource.start, SZ_4K);
return ret;
}
-static int impd1_remove(struct device *dev)
+static void impd1_remove(struct lm_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct resource *res = &pdev->resource[0];
- struct impd1_module *impd1 = dev_get_drvdata(dev);
+ struct impd1_module *impd1 = lm_get_drvdata(dev);
struct list_head *l, *n;
- list_for_each_safe(l, n, &dev->children) {
+ list_for_each_safe(l, n, &dev->dev.children) {
struct device *d = list_to_dev(l);
device_unregister(d);
}
- dev_set_drvdata(dev, NULL);
+ lm_set_drvdata(dev, NULL);
iounmap(impd1->base);
kfree(impd1);
- release_mem_region(res->start, SZ_4K);
-
- return 0;
+ release_mem_region(dev->resource.start, SZ_4K);
}
-static struct device_driver impd1_driver = {
- .name = "lm",
- .bus = &platform_bus_type,
+static struct lm_driver impd1_driver = {
+ .drv = {
+ .name = "impd1",
+ },
.probe = impd1_probe,
.remove = impd1_remove,
};
static int __init impd1_init(void)
{
- return driver_register(&impd1_driver);
+ return lm_driver_register(&impd1_driver);
}
static void __exit impd1_exit(void)
{
- driver_unregister(&impd1_driver);
+ lm_driver_unregister(&impd1_driver);
}
module_init(impd1_init);
diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c
new file mode 100644
index 000000000000..86051e509cfd
--- /dev/null
+++ b/arch/arm/mach-integrator/lm.c
@@ -0,0 +1,92 @@
+/*
+ * linux/arch/arm/mach-integrator/lm.c
+ *
+ * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/arch/lm.h>
+
+#define to_lm_device(d) container_of(d, struct lm_device, dev)
+#define to_lm_driver(d) container_of(d, struct lm_driver, drv)
+
+static int lm_match(struct device *dev, struct device_driver *drv)
+{
+ return 1;
+}
+
+static struct bus_type lm_bustype = {
+ .name = "logicmodule",
+ .match = lm_match,
+// .suspend = lm_suspend,
+// .resume = lm_resume,
+};
+
+static int __init lm_init(void)
+{
+ return bus_register(&lm_bustype);
+}
+
+postcore_initcall(lm_init);
+
+static int lm_bus_probe(struct device *dev)
+{
+ struct lm_device *lmdev = to_lm_device(dev);
+ struct lm_driver *lmdrv = to_lm_driver(dev->driver);
+
+ return lmdrv->probe(lmdev);
+}
+
+static int lm_bus_remove(struct device *dev)
+{
+ struct lm_device *lmdev = to_lm_device(dev);
+ struct lm_driver *lmdrv = to_lm_driver(dev->driver);
+
+ lmdrv->remove(lmdev);
+ return 0;
+}
+
+int lm_driver_register(struct lm_driver *drv)
+{
+ drv->drv.bus = &lm_bustype;
+ drv->drv.probe = lm_bus_probe;
+ drv->drv.remove = lm_bus_remove;
+
+ return driver_register(&drv->drv);
+}
+
+void lm_driver_unregister(struct lm_driver *drv)
+{
+ driver_unregister(&drv->drv);
+}
+
+static void lm_device_release(struct device *dev)
+{
+ struct lm_device *d = to_lm_device(dev);
+
+ kfree(d);
+}
+
+int lm_device_register(struct lm_device *dev)
+{
+ int ret;
+
+ dev->dev.release = lm_device_release;
+ dev->dev.bus = &lm_bustype;
+
+ snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "lm%d", dev->id);
+ dev->resource.name = dev->dev.bus_id;
+
+ ret = request_resource(&iomem_resource, &dev->resource);
+ if (ret == 0) {
+ ret = device_register(&dev->dev);
+ if (ret)
+ release_resource(&dev->resource);
+ }
+ return ret;
+}
diff --git a/include/asm-arm/arch-integrator/lm.h b/include/asm-arm/arch-integrator/lm.h
new file mode 100644
index 000000000000..d792b112974c
--- /dev/null
+++ b/include/asm-arm/arch-integrator/lm.h
@@ -0,0 +1,23 @@
+
+struct lm_device {
+ struct device dev;
+ struct resource resource;
+ unsigned int irq;
+ unsigned int id;
+};
+
+struct lm_driver {
+ struct device_driver drv;
+ int (*probe)(struct lm_device *);
+ void (*remove)(struct lm_device *);
+ int (*suspend)(struct lm_device *, u32);
+ int (*resume)(struct lm_device *);
+};
+
+int lm_driver_register(struct lm_driver *drv);
+void lm_driver_unregister(struct lm_driver *drv);
+
+int lm_device_register(struct lm_device *dev);
+
+#define lm_get_drvdata(lm) dev_get_drvdata(&(lm)->dev)
+#define lm_set_drvdata(lm,d) dev_set_drvdata(&(lm)->dev, d)