of: restore old handling of cells_name=NULL in of_*_phandle_with_args()
Before commite42ee61017
("of: Let of_for_each_phandle fallback to non-negative cell_count") the iterator functions calling of_for_each_phandle assumed a cell count of 0 if cells_name was NULL. This corner case was missed when implementing the fallback logic ine42ee61017
and resulted in an endless loop. Restore the old behaviour of of_count_phandle_with_args() and of_parse_phandle_with_args() and add a check to of_phandle_iterator_init() to prevent a similar failure as a safety precaution. of_parse_phandle_with_args_map() doesn't need a similar fix as cells_name isn't NULL there. Affected drivers are: - drivers/base/power/domain.c - drivers/base/power/domain.c - drivers/clk/ti/clk-dra7-atl.c - drivers/hwmon/ibmpowernv.c - drivers/i2c/muxes/i2c-demux-pinctrl.c - drivers/iommu/mtk_iommu.c - drivers/net/ethernet/freescale/fman/mac.c - drivers/opp/of.c - drivers/perf/arm_dsu_pmu.c - drivers/regulator/of_regulator.c - drivers/remoteproc/imx_rproc.c - drivers/soc/rockchip/pm_domains.c - sound/soc/fsl/imx-audmix.c - sound/soc/fsl/imx-audmix.c - sound/soc/meson/axg-card.c - sound/soc/samsung/tm2_wm5110.c - sound/soc/samsung/tm2_wm5110.c Thanks to Geert Uytterhoeven for reporting the issue, Peter Rosin for helping pinpoint the actual problem and the testers for confirming this fix. Fixes:e42ee61017
("of: Let of_for_each_phandle fallback to non-negative cell_count") Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Rob Herring <robh@kernel.org>
This commit is contained in:
parent
e65e50ff88
commit
59e9fcf877
@ -1286,6 +1286,13 @@ int of_phandle_iterator_init(struct of_phandle_iterator *it,
|
||||
|
||||
memset(it, 0, sizeof(*it));
|
||||
|
||||
/*
|
||||
* one of cell_count or cells_name must be provided to determine the
|
||||
* argument length.
|
||||
*/
|
||||
if (cell_count < 0 && !cells_name)
|
||||
return -EINVAL;
|
||||
|
||||
list = of_get_property(np, list_name, &size);
|
||||
if (!list)
|
||||
return -ENOENT;
|
||||
@ -1512,10 +1519,17 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
|
||||
const char *cells_name, int index,
|
||||
struct of_phandle_args *out_args)
|
||||
{
|
||||
int cell_count = -1;
|
||||
|
||||
if (index < 0)
|
||||
return -EINVAL;
|
||||
return __of_parse_phandle_with_args(np, list_name, cells_name, -1,
|
||||
index, out_args);
|
||||
|
||||
/* If cells_name is NULL we assume a cell count of 0 */
|
||||
if (!cells_name)
|
||||
cell_count = 0;
|
||||
|
||||
return __of_parse_phandle_with_args(np, list_name, cells_name,
|
||||
cell_count, index, out_args);
|
||||
}
|
||||
EXPORT_SYMBOL(of_parse_phandle_with_args);
|
||||
|
||||
@ -1765,6 +1779,23 @@ int of_count_phandle_with_args(const struct device_node *np, const char *list_na
|
||||
struct of_phandle_iterator it;
|
||||
int rc, cur_index = 0;
|
||||
|
||||
/*
|
||||
* If cells_name is NULL we assume a cell count of 0. This makes
|
||||
* counting the phandles trivial as each 32bit word in the list is a
|
||||
* phandle and no arguments are to consider. So we don't iterate through
|
||||
* the list but just use the length to determine the phandle count.
|
||||
*/
|
||||
if (!cells_name) {
|
||||
const __be32 *list;
|
||||
int size;
|
||||
|
||||
list = of_get_property(np, list_name, &size);
|
||||
if (!list)
|
||||
return -ENOENT;
|
||||
|
||||
return size / sizeof(*list);
|
||||
}
|
||||
|
||||
rc = of_phandle_iterator_init(&it, np, list_name, cells_name, -1);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
Loading…
Reference in New Issue
Block a user