From 56f42242f020254ea1c383694edb072e3a5ca6d6 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 26 Aug 2014 17:33:53 +0200 Subject: fdt: Add resource parsing functions Add the fdt_get_resource() and fdt_get_named_resource() functions which can be used to parse resources (memory regions) from an FDT. A helper to compute the size of a region is also provided. Signed-off-by: Thierry Reding Acked-by: Simon Glass --- lib/fdtdec.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 06d4542029..b3c43be89d 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -708,4 +708,61 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name, return 0; } + +static u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells) +{ + u64 number = 0; + + while (cells--) + number = (number << 32) | fdt32_to_cpu(*ptr++); + + return number; +} + +int fdt_get_resource(const void *fdt, int node, const char *property, + unsigned int index, struct fdt_resource *res) +{ + const fdt32_t *ptr, *end; + int na, ns, len, parent; + unsigned int i = 0; + + parent = fdt_parent_offset(fdt, node); + if (parent < 0) + return parent; + + na = fdt_address_cells(fdt, parent); + ns = fdt_size_cells(fdt, parent); + + ptr = fdt_getprop(fdt, node, property, &len); + if (!ptr) + return len; + + end = ptr + len / sizeof(*ptr); + + while (ptr + na + ns <= end) { + if (i == index) { + res->start = res->end = fdtdec_get_number(ptr, na); + res->end += fdtdec_get_number(&ptr[na], ns) - 1; + return 0; + } + + ptr += na + ns; + i++; + } + + return -FDT_ERR_NOTFOUND; +} + +int fdt_get_named_resource(const void *fdt, int node, const char *property, + const char *prop_names, const char *name, + struct fdt_resource *res) +{ + int index; + + index = fdt_find_string(fdt, node, prop_names, name); + if (index < 0) + return index; + + return fdt_get_resource(fdt, node, property, index, res); +} #endif -- cgit v1.2.1