of: restore old handling of cells_name=NULL in of_*_phandle_with_args()
Before commit e42ee61017f5 ("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 in
e42ee61017f5 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: e42ee61017f5 ("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>
Change-Id: I684efc01df23ea32c578c1da4f8ea6fcf6f03ced
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:
committed by
Łukasz Patron
parent
0c77b8d49c
commit
0d1856835c
@@ -1241,6 +1241,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;
|
||||
@@ -1467,10 +1474,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);
|
||||
|
||||
@@ -1721,6 +1735,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;
|
||||
|
||||
Reference in New Issue
Block a user