On Thu, Feb 22, 2024 at 05:32:10PM +1100, David Gibson wrote: > On Fri, Feb 16, 2024 at 07:19:20PM +0100, Uwe Kleine-König wrote: > > +static int overlay_update_node_conflicting_references(void *fdto, int tree_node, > > + int fixup_node, > > + uint32_t fdt_phandle, > > + uint32_t fdto_phandle) > > +{ > > + int fixup_prop; > > + int fixup_child; > > + int ret; > > + > > + fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { > > + > > + const fdt32_t *fixup_val; > > + const char *tree_val; > > + const char *name; > > + int fixup_len; > > + int tree_len; > > + int i; > > + > > + fixup_val = fdt_getprop_by_offset(fdto, fixup_prop, > > + &name, &fixup_len); > > + if (!fixup_val) > > + return fixup_len; > > + > > + if (fixup_len % sizeof(uint32_t)) > > + return -FDT_ERR_BADOVERLAY; > > + fixup_len /= sizeof(uint32_t); > > + > > + tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); > > + if (!tree_val) { > > + if (tree_len == -FDT_ERR_NOTFOUND) > > + return -FDT_ERR_BADOVERLAY; > > + > > + return tree_len; > > + } > > + > > + for (i = 0; i < fixup_len; i++) { > > + fdt32_t adj_val; > > + uint32_t poffset; > > + > > + poffset = fdt32_to_cpu(fixup_val[i]); > > You can use fdt32_ld_() here to slightly simplify this I don't see what you suggest here. fixup_val is assigned to in fdt_getprop_by_offset() which I need to get fixup_len and then fixup_val is already around. If you still think this could be improved, please be more explicit. > > + > > + /* > > + * phandles to fixup can be unaligned. > > + * > > + * Use a memcpy for the architectures that do > > + * not support unaligned accesses. > > + */ > > + memcpy(&adj_val, tree_val + poffset, sizeof(adj_val)); > > And here you can use fdt32_ld() which has unaligned access handling > built in. > > > + > > + if (fdt32_to_cpu(adj_val) == fdto_phandle) { > > + > > + adj_val = cpu_to_fdt32(fdt_phandle); > > + > > + ret = fdt_setprop_inplace_namelen_partial(fdto, > > + tree_node, > > + name, > > + strlen(name), > > + poffset, > > + &adj_val, > > + sizeof(adj_val)); > > + if (ret == -FDT_ERR_NOSPACE) > > + return -FDT_ERR_BADOVERLAY; > > + > > + if (ret) > > + return ret; > > And here you can use fdt32_st() on (tree_val + poffset), avoiding > quite some complexity. There is some complexity because tree_val is a const char * (as this is what fdt_getprop() returns) and fdt32_st() obviously doens't take a const pointer. If you want to play around with that, the code is mostly a copy of overlay_update_local_node_references() which could benefit from your suggestions in the same way. Can I lure you in improving overlay_update_local_node_references()? Then I could copy from the improved function for my patch. (Or maybe refactor the function to take a function as parameter which is uint32_t delta; uint32_t increase_by_delta(uint32_t phandle) { return phandle + delta; } for the overlay_update_local_node_references() case and uint32_t fdt_phandle; uint32_t fdto_phandle; uint32_t resolve_fdt_conflict(uint32_t phandle) { if (phandle == fdto_phandle) return fdt_phandle; else return phandle; } for my function (maybe passing the data stored in global vars here in a context parameter). Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |