aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2011-06-21 12:59:34 -0400
committerGrant Likely <grant.likely@secretlab.ca>2011-06-21 13:02:37 -0400
commit5de1540b7bc4c23470f86add1e517be41e7fefe2 (patch)
treea1c18d1ec0b7009966f114565424e9bbb31da1c1 /drivers/of
parent29d4f8a4974aacf46b028fa92f9dd3ffdba3e614 (diff)
drivers/amba: create devices from device tree
Add a function to create amba_devices (i.e. primecell peripherals) from device tree nodes. The device tree scanning is done by the of_platform_populate() function which can call of_amba_device_create based on a match table entry. Nodes with a "arm,primecell-periphid" property can override the h/w peripheral id value. Based on the original work by Jeremy Kerr. Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Rob Herring <rob.herring@calxeda.com> Reviewed-by: Arnd Bergmann <arnd@arndb.de> [grant.likely: add Jeremy's original s-o-b line, changes from review comments, and moved all code to drivers/of/platform.c] Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/platform.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 1f4a5d3af76e..4192ddc62638 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -13,6 +13,7 @@
13 */ 13 */
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/amba/bus.h>
16#include <linux/device.h> 17#include <linux/device.h>
17#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
@@ -217,6 +218,71 @@ struct platform_device *of_platform_device_create(struct device_node *np,
217} 218}
218EXPORT_SYMBOL(of_platform_device_create); 219EXPORT_SYMBOL(of_platform_device_create);
219 220
221#ifdef CONFIG_ARM_AMBA
222static struct amba_device *of_amba_device_create(struct device_node *node,
223 const char *bus_id,
224 void *platform_data,
225 struct device *parent)
226{
227 struct amba_device *dev;
228 const void *prop;
229 int i, ret;
230
231 pr_debug("Creating amba device %s\n", node->full_name);
232
233 if (!of_device_is_available(node))
234 return NULL;
235
236 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
237 if (!dev)
238 return NULL;
239
240 /* setup generic device info */
241 dev->dev.coherent_dma_mask = ~0;
242 dev->dev.of_node = of_node_get(node);
243 dev->dev.parent = parent;
244 dev->dev.platform_data = platform_data;
245 if (bus_id)
246 dev_set_name(&dev->dev, "%s", bus_id);
247 else
248 of_device_make_bus_id(&dev->dev);
249
250 /* setup amba-specific device info */
251 dev->dma_mask = ~0;
252
253 /* Allow the HW Peripheral ID to be overridden */
254 prop = of_get_property(node, "arm,primecell-periphid", NULL);
255 if (prop)
256 dev->periphid = of_read_ulong(prop, 1);
257
258 /* Decode the IRQs and address ranges */
259 for (i = 0; i < AMBA_NR_IRQS; i++)
260 dev->irq[i] = irq_of_parse_and_map(node, i);
261
262 ret = of_address_to_resource(node, 0, &dev->res);
263 if (ret)
264 goto err_free;
265
266 ret = amba_device_register(dev, &iomem_resource);
267 if (ret)
268 goto err_free;
269
270 return dev;
271
272err_free:
273 kfree(dev);
274 return NULL;
275}
276#else /* CONFIG_ARM_AMBA */
277static struct amba_device *of_amba_device_create(struct device_node *node,
278 const char *bus_id,
279 void *platform_data,
280 struct device *parent)
281{
282 return NULL;
283}
284#endif /* CONFIG_ARM_AMBA */
285
220/** 286/**
221 * of_platform_bus_create() - Create a device for a node and its children. 287 * of_platform_bus_create() - Create a device for a node and its children.
222 * @bus: device node of the bus to instantiate 288 * @bus: device node of the bus to instantiate
@@ -242,6 +308,11 @@ static int of_platform_bus_create(struct device_node *bus,
242 return 0; 308 return 0;
243 } 309 }
244 310
311 if (of_device_is_compatible(bus, "arm,primecell")) {
312 of_amba_device_create(bus, NULL, NULL, parent);
313 return 0;
314 }
315
245 dev = of_platform_device_create(bus, NULL, parent); 316 dev = of_platform_device_create(bus, NULL, parent);
246 if (!dev || !of_match_node(matches, bus)) 317 if (!dev || !of_match_node(matches, bus))
247 return 0; 318 return 0;