diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-06-08 13:48:14 (GMT) |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-07-05 22:14:29 (GMT) |
commit | 94c0931983ee9d1cd96c32d52ac64c17464f0bbd (patch) | |
tree | 188c9d7ef9dfb560563078d6d2f3872291686f58 /drivers/of | |
parent | 5fd200f3b351183b5489cef69961c60af9cead2f (diff) | |
download | linux-94c0931983ee9d1cd96c32d52ac64c17464f0bbd.tar.xz |
of: Merge of_device_alloc() and of_device_make_bus_id()
This patch merges the common routines of_device_alloc() and
of_device_make_bus_id() from powerpc and microblaze.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
CC: Michal Simek <monstr@monstr.eu>
CC: Grant Likely <grant.likely@secretlab.ca>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Stephen Rothwell <sfr@canb.auug.org.au>
CC: microblaze-uclinux@itee.uq.edu.au
CC: linuxppc-dev@ozlabs.org
CC: devicetree-discuss@lists.ozlabs.org
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/platform.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index d9c81e9..ea87a3c 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -408,6 +408,93 @@ EXPORT_SYMBOL(of_unregister_driver); */ /** + * of_device_make_bus_id - Use the device node data to assign a unique name + * @dev: pointer to device structure that is linked to a device tree node + * + * This routine will first try using either the dcr-reg or the reg property + * value to derive a unique name. As a last resort it will use the node + * name followed by a unique number. + */ +static void of_device_make_bus_id(struct device *dev) +{ + static atomic_t bus_no_reg_magic; + struct device_node *node = dev->of_node; + const u32 *reg; + u64 addr; + int magic; + +#ifdef CONFIG_PPC_DCR + /* + * If it's a DCR based device, use 'd' for native DCRs + * and 'D' for MMIO DCRs. + */ + reg = of_get_property(node, "dcr-reg", NULL); + if (reg) { +#ifdef CONFIG_PPC_DCR_NATIVE + dev_set_name(dev, "d%x.%s", *reg, node->name); +#else /* CONFIG_PPC_DCR_NATIVE */ + u64 addr = of_translate_dcr_address(node, *reg, NULL); + if (addr != OF_BAD_ADDR) { + dev_set_name(dev, "D%llx.%s", + (unsigned long long)addr, node->name); + return; + } +#endif /* !CONFIG_PPC_DCR_NATIVE */ + } +#endif /* CONFIG_PPC_DCR */ + + /* + * For MMIO, get the physical address + */ + reg = of_get_property(node, "reg", NULL); + if (reg) { + addr = of_translate_address(node, reg); + if (addr != OF_BAD_ADDR) { + dev_set_name(dev, "%llx.%s", + (unsigned long long)addr, node->name); + return; + } + } + + /* + * No BusID, use the node name and add a globally incremented + * counter (and pray...) + */ + magic = atomic_add_return(1, &bus_no_reg_magic); + dev_set_name(dev, "%s.%d", node->name, magic - 1); +} + +/** + * of_device_alloc - Allocate and initialize an of_device + * @np: device node to assign to device + * @bus_id: Name to assign to the device. May be null to use default name. + * @parent: Parent device. + */ +struct of_device *of_device_alloc(struct device_node *np, + const char *bus_id, + struct device *parent) +{ + struct of_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->dev.of_node = of_node_get(np); + dev->dev.dma_mask = &dev->archdata.dma_mask; + dev->dev.parent = parent; + dev->dev.release = of_release_dev; + + if (bus_id) + dev_set_name(&dev->dev, "%s", bus_id); + else + of_device_make_bus_id(&dev->dev); + + return dev; +} +EXPORT_SYMBOL(of_device_alloc); + +/** * of_platform_device_create - Alloc, initialize and register an of_device * @np: pointer to node to create device for * @bus_id: name to assign device |