summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/amba/bus.c105
-rw-r--r--drivers/mmc/host/mmci.c2
-rw-r--r--drivers/of/platform.c6
3 files changed, 83 insertions, 30 deletions
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 54eaf96ab217..01c2cf4efcdd 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -497,37 +497,22 @@ static void amba_device_release(struct device *dev)
}
/**
- * amba_device_register - register an AMBA device
- * @dev: AMBA device to register
- * @parent: parent memory resource
+ * amba_device_add - add a previously allocated AMBA device structure
+ * @dev: AMBA device allocated by amba_device_alloc
+ * @parent: resource parent for this devices resources
*
- * Setup the AMBA device, reading the cell ID if present.
- * Claim the resource, and register the AMBA device with
- * the Linux device manager.
+ * Claim the resource, and read the device cell ID if not already
+ * initialized. Register the AMBA device with the Linux device
+ * manager.
*/
-int amba_device_register(struct amba_device *dev, struct resource *parent)
+int amba_device_add(struct amba_device *dev, struct resource *parent)
{
u32 size;
void __iomem *tmp;
int i, ret;
- device_initialize(&dev->dev);
-
- /*
- * Copy from device_add
- */
- if (dev->dev.init_name) {
- dev_set_name(&dev->dev, "%s", dev->dev.init_name);
- dev->dev.init_name = NULL;
- }
-
- dev->dev.release = amba_device_release;
- dev->dev.bus = &amba_bustype;
- dev->dev.dma_mask = &dev->dma_mask;
- dev->res.name = dev_name(&dev->dev);
-
- if (!dev->dev.coherent_dma_mask && dev->dma_mask)
- dev_warn(&dev->dev, "coherent dma mask is unset\n");
+ WARN_ON(dev->irq[0] == (unsigned int)-1);
+ WARN_ON(dev->irq[1] == (unsigned int)-1);
ret = request_resource(parent, &dev->res);
if (ret)
@@ -582,9 +567,9 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
if (ret)
goto err_release;
- if (dev->irq[0] != NO_IRQ)
+ if (dev->irq[0] && dev->irq[0] != NO_IRQ)
ret = device_create_file(&dev->dev, &dev_attr_irq0);
- if (ret == 0 && dev->irq[1] != NO_IRQ)
+ if (ret == 0 && dev->irq[1] && dev->irq[1] != NO_IRQ)
ret = device_create_file(&dev->dev, &dev_attr_irq1);
if (ret == 0)
return ret;
@@ -596,6 +581,74 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
err_out:
return ret;
}
+EXPORT_SYMBOL_GPL(amba_device_add);
+
+static void amba_device_initialize(struct amba_device *dev, const char *name)
+{
+ device_initialize(&dev->dev);
+ if (name)
+ dev_set_name(&dev->dev, "%s", name);
+ dev->dev.release = amba_device_release;
+ dev->dev.bus = &amba_bustype;
+ dev->dev.dma_mask = &dev->dma_mask;
+ dev->res.name = dev_name(&dev->dev);
+}
+
+/**
+ * amba_device_alloc - allocate an AMBA device
+ * @name: sysfs name of the AMBA device
+ * @base: base of AMBA device
+ * @size: size of AMBA device
+ *
+ * Allocate and initialize an AMBA device structure. Returns %NULL
+ * on failure.
+ */
+struct amba_device *amba_device_alloc(const char *name, resource_size_t base,
+ size_t size)
+{
+ struct amba_device *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev) {
+ amba_device_initialize(dev, name);
+ dev->res.start = base;
+ dev->res.end = base + size - 1;
+ dev->res.flags = IORESOURCE_MEM;
+ }
+
+ return dev;
+}
+EXPORT_SYMBOL_GPL(amba_device_alloc);
+
+/**
+ * amba_device_register - register an AMBA device
+ * @dev: AMBA device to register
+ * @parent: parent memory resource
+ *
+ * Setup the AMBA device, reading the cell ID if present.
+ * Claim the resource, and register the AMBA device with
+ * the Linux device manager.
+ */
+int amba_device_register(struct amba_device *dev, struct resource *parent)
+{
+ amba_device_initialize(dev, dev->dev.init_name);
+ dev->dev.init_name = NULL;
+
+ if (!dev->dev.coherent_dma_mask && dev->dma_mask)
+ dev_warn(&dev->dev, "coherent dma mask is unset\n");
+
+ return amba_device_add(dev, parent);
+}
+
+/**
+ * amba_device_put - put an AMBA device
+ * @dev: AMBA device to put
+ */
+void amba_device_put(struct amba_device *dev)
+{
+ put_device(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(amba_device_put);
/**
* amba_device_unregister - unregister an AMBA device
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 11e589cd8233..bdfd05517dd5 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1326,7 +1326,7 @@ static int __devinit mmci_probe(struct amba_device *dev,
if (ret)
goto unmap;
- if (dev->irq[1] == NO_IRQ)
+ if (dev->irq[1] == NO_IRQ || !dev->irq[1])
host->singleirq = true;
else {
ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED,
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 20fbebd49db3..343ad29e211c 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -253,7 +253,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
if (!of_device_is_available(node))
return NULL;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = amba_device_alloc(NULL, 0, 0);
if (!dev)
return NULL;
@@ -283,14 +283,14 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
if (ret)
goto err_free;
- ret = amba_device_register(dev, &iomem_resource);
+ ret = amba_device_add(dev, &iomem_resource);
if (ret)
goto err_free;
return dev;
err_free:
- kfree(dev);
+ amba_device_put(dev);
return NULL;
}
#else /* CONFIG_ARM_AMBA */