On Wed, Mar 14, 2018 at 8:41 AM, Mario Six <mario.six@xxxxxxxx> wrote: > 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))) { Use fdt_for_each_property_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 -- 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