Search up the tree until we find #address-cells/#size-cells. Also only assign outputs if both address and size are found. Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx> --- lib/devicetree.c | 17 +++++++++++++---- lib/devicetree.h | 3 ++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/devicetree.c b/lib/devicetree.c index a5c7f7c69ddfd..d3751e2b7e7f9 100644 --- a/lib/devicetree.c +++ b/lib/devicetree.c @@ -24,21 +24,30 @@ int dt_get_nr_cells(int fdtnode, u32 *nr_address_cells, u32 *nr_size_cells) { const struct fdt_property *prop; u32 *nr_cells; - int len; + int len, nac, nsc; + + while (1) { + prop = fdt_get_property(fdt, fdtnode, "#address-cells", &len); + if (prop != NULL || len != -FDT_ERR_NOTFOUND) + break; + fdtnode = fdt_parent_offset(fdt, fdtnode); + } - prop = fdt_get_property(fdt, fdtnode, "#address-cells", &len); if (prop == NULL) return len; nr_cells = (u32 *)prop->data; - *nr_address_cells = fdt32_to_cpu(*nr_cells); + nac = fdt32_to_cpu(*nr_cells); prop = fdt_get_property(fdt, fdtnode, "#size-cells", &len); if (prop == NULL) return len; nr_cells = (u32 *)prop->data; - *nr_size_cells = fdt32_to_cpu(*nr_cells); + nsc = fdt32_to_cpu(*nr_cells); + + *nr_address_cells = nac; + *nr_size_cells = nsc; return 0; } diff --git a/lib/devicetree.h b/lib/devicetree.h index c8c86eeae28b6..09f2509409615 100644 --- a/lib/devicetree.h +++ b/lib/devicetree.h @@ -168,7 +168,8 @@ extern int dt_pbus_get_base_compatible(const char *compatible, /* * dt_get_nr_cells sets @nr_address_cells and @nr_size_cells to the - * #address-cells and #size-cells properties of @fdtnode + * #address-cells and #size-cells properties of @fdtnode, potentially + * searching up the tree to find them in a parent node. * returns * - zero on success * - a negative FDT_ERR_* value on failure -- 2.4.11 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html