single_add_gpio_func() calls ofnode_parse_phandle_with_args() once per
gpio-range entry. With a flat device tree, every call re-iterates the
property from index 0 and, because cellname is set, performs an
fdt_node_offset_by_phandle() (a full-FDT scan) at every step. The total
cost is therefore quadratic in the number of entries and proportional to
the size of the device tree.
The impact depends on when the pinctrl is probed. On the J722S EVM
defconfig, pinctrl@f4000 (main_pmx0, the SoC's stock 7-entry gpio-range)
is probed after relocation (caches on): single_add_gpio_func() takes
~18 ms there and ~1 ms with this change. When the node is probed before
relocation (caches off) the same parse takes hundreds of ms; on a board
that probes it pre-relocation and runs LPDDR4 clocked down it reached
723 ms, cut to 22 ms here. Any pinctrl-single user with a populated
gpio-range property pays this cost.
The phandle target is never dereferenced by this function (only the
argument cells are stored), so resolve it only for the first entry to
learn the per-entry cell count, then read the argument cells directly
with ofnode_read_u32_index() and allocate the ranges in one block. A
zero phandle still terminates the list, as in the original loop. This
follows the existing pinctrl-single,gpio-range usage observed in current
DTs, where entries use the same provider and therefore a uniform
per-entry cell count.
Signed-off-by: Jordi Trepat Mur <yordy1902@gmail.com>
Reviewed-by: Anshul Dalal <anshuld@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>