From 5d61b165c892853f2daf6220d2ec6577487e273a Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 25 Jul 2012 17:34:37 -0600 Subject: of: Allow busses with #size-cells=0 It's quite legitimate for a DT node to specify #size-cells=0. One example is a node that's used to collect a number of non-memory-mapped devices. In that scenario, there may be multiple child nodes with the same name (type) thus necessitating the use of unit addresses in node names, and reg properties: / { regulators { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <0>; regulator@0 { compatible = "regulator-fixed"; reg = <0>; ... }; regulator@1 { compatible = "regulator-fixed"; reg = <1>; ... }; ... }; }; However, #size-cells=0 prevents translation of reg property values into the parent node's address space. In turn, this triggers the kernel to emit error messages during boot, such as: prom_parse: Bad cell count for /regulators/regulator@0 To prevent printing these error messages for legitimate DT content, a number of changes are made: 1) of_get_address()/of_get_pci_address() are modified only to validate the value of #address-cells, and not #size-cells. 2) of_can_translate_address() is added to indicate whether address translation is possible. 3) of_device_make_bus_id() is modified to name devices based on the translated address only where possible, and otherwise fall back to using the (first cell of the) raw untranslated address. 4) of_device_alloc() is modified to create memory resources for a device only if the address can be translated into the CPU's address space. Signed-off-by: Stephen Warren Signed-off-by: Rob Herring --- drivers/of/platform.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/of/platform.c') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index e44f8c2d239..9bdeaf30b17 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -78,6 +78,7 @@ void of_device_make_bus_id(struct device *dev) struct device_node *node = dev->of_node; const u32 *reg; u64 addr; + const __be32 *addrp; int magic; #ifdef CONFIG_PPC_DCR @@ -105,7 +106,15 @@ void of_device_make_bus_id(struct device *dev) */ reg = of_get_property(node, "reg", NULL); if (reg) { - addr = of_translate_address(node, reg); + if (of_can_translate_address(node)) { + addr = of_translate_address(node, reg); + } else { + addrp = of_get_address(node, 0, NULL, NULL); + if (addrp) + addr = of_read_number(addrp, 1); + else + addr = OF_BAD_ADDR; + } if (addr != OF_BAD_ADDR) { dev_set_name(dev, "%llx.%s", (unsigned long long)addr, node->name); @@ -140,8 +149,9 @@ struct platform_device *of_device_alloc(struct device_node *np, return NULL; /* count the io and irq resources */ - while (of_address_to_resource(np, num_reg, &temp_res) == 0) - num_reg++; + if (of_can_translate_address(np)) + while (of_address_to_resource(np, num_reg, &temp_res) == 0) + num_reg++; num_irq = of_irq_count(np); /* Populate the resource table */ -- cgit v1.2.3-70-g09d2