Given a node offset, the function fdt_get_phandle finds and returns the phandle property defined in this node. The current implementation first tries to read the "phandle" property, then, should this not succeed, tries to read the "linux,phandle" property afterwards (both by using the fdt_getprop function), and returns either one if it is found. This means that we potentially iterate over the properties of the node twice (if the neither the "phandle", nor the "linux,phandle" property is found). Instead of doing this, iterate once over the nodes' properties, and check each one if it is equal to either "phandle" or "linux,phandle", and return the value in either case. Hence, we only iterate over the properties exactly once. Signed-off-by: Mario Six <mario.six@xxxxxxxx> --- libfdt/fdt_ro.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index dfb3236..7d049fb 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -424,19 +424,32 @@ const void *fdt_getprop(const void *fdt, int nodeoffset, uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) { - const fdt32_t *php; + const fdt32_t *php = NULL; int len; + int offset; - /* FIXME: This is a bit sub-optimal, since we potentially scan - * over all the properties twice. */ - php = fdt_getprop(fdt, nodeoffset, "phandle", &len); - if (!php || (len != sizeof(*php))) { - php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); - if (!php || (len != sizeof(*php))) - return 0; + for (offset = fdt_first_property_offset(fdt, nodeoffset); + (offset >= 0); + (offset = fdt_next_property_offset(fdt, offset))) { + const struct fdt_property *prop; + + if (!(prop = fdt_get_property_by_offset(fdt, offset, &len))) { + offset = -FDT_ERR_INTERNAL; + break; + } + if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), + "phandle", strlen("phandle"))) + php = (const fdt32_t *)prop->data; + + if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), + "linux,phandle", strlen("linux,phandle"))) + php = (const fdt32_t *)prop->data; + + if (php) + return fdt32_to_cpu(*php); } - return fdt32_to_cpu(*php); + return 0; } const char *fdt_get_alias_namelen(const void *fdt, -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html