From a7bcae591f595a727feea9a5a389756015579072 Mon Sep 17 00:00:00 2001 From: Nishka Dasgupta Date: Thu, 15 Aug 2019 11:52:18 +0530 Subject: of: unittest: Add of_node_put() before return The local variable np in function of_unittest_platform_populate takes the return value of of_find_node_by_path, which gets a node but does not put it. If np is not put before return it may cause a memory leak. Hence put np before a return statement. Issue found with Coccinelle. Signed-off-by: Nishka Dasgupta Signed-off-by: Rob Herring --- drivers/of/unittest.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index e6b175370f2e..480a21e2ed39 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1044,8 +1044,10 @@ static void __init of_unittest_platform_populate(void) test_bus = platform_device_register_full(&test_bus_info); rc = PTR_ERR_OR_ZERO(test_bus); unittest(!rc, "testbus registration failed; rc=%i\n", rc); - if (rc) + if (rc) { + of_node_put(np); return; + } test_bus->dev.of_node = np; /* -- cgit v1.2.3-59-g8ed1b From e42ee61017f58cd91cb9e30001450be3981e0e83 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sat, 24 Aug 2019 15:28:46 +0200 Subject: of: Let of_for_each_phandle fallback to non-negative cell_count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Referencing device tree nodes from a property allows to pass arguments. This is for example used for referencing gpios. This looks as follows: gpio_ctrl: gpio-controller { #gpio-cells = <2> ... } someothernode { gpios = <&gpio_ctrl 5 0 &gpio_ctrl 3 0>; ... } To know the number of arguments this must be either fixed, or the referenced node is checked for a $cells_name (here: "#gpio-cells") property and with this information the start of the second reference can be determined. Currently regulators are referenced with no additional arguments. To allow some optional arguments without having to change all referenced nodes this change introduces a way to specify a default cell_count. So when a phandle is parsed we check for the $cells_name property and use it as before if present. If it is not present we fall back to cells_count if non-negative and only fail if cells_count is smaller than zero. Signed-off-by: Uwe Kleine-König Signed-off-by: Rob Herring --- drivers/of/base.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/base.c b/drivers/of/base.c index 55e7f5bb0549..2f25d2dfecfa 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1335,11 +1335,20 @@ int of_phandle_iterator_next(struct of_phandle_iterator *it) if (of_property_read_u32(it->node, it->cells_name, &count)) { - pr_err("%pOF: could not get %s for %pOF\n", - it->parent, - it->cells_name, - it->node); - goto err; + /* + * If both cell_count and cells_name is given, + * fall back to cell_count in absence + * of the cells_name property + */ + if (it->cell_count >= 0) { + count = it->cell_count; + } else { + pr_err("%pOF: could not get %s for %pOF\n", + it->parent, + it->cells_name, + it->node); + goto err; + } } } else { count = it->cell_count; @@ -1505,7 +1514,7 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na { if (index < 0) return -EINVAL; - return __of_parse_phandle_with_args(np, list_name, cells_name, 0, + return __of_parse_phandle_with_args(np, list_name, cells_name, -1, index, out_args); } EXPORT_SYMBOL(of_parse_phandle_with_args); @@ -1588,7 +1597,7 @@ int of_parse_phandle_with_args_map(const struct device_node *np, if (!pass_name) goto free; - ret = __of_parse_phandle_with_args(np, list_name, cells_name, 0, index, + ret = __of_parse_phandle_with_args(np, list_name, cells_name, -1, index, out_args); if (ret) goto free; @@ -1756,7 +1765,7 @@ 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; - rc = of_phandle_iterator_init(&it, np, list_name, cells_name, 0); + rc = of_phandle_iterator_init(&it, np, list_name, cells_name, -1); if (rc) return rc; -- cgit v1.2.3-59-g8ed1b From 59e9fcf8772bd97b6d681706fb8c9a972500c524 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 18 Sep 2019 10:47:48 +0200 Subject: of: restore old handling of cells_name=NULL in of_*_phandle_with_args() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Geert Uytterhoeven Signed-off-by: Uwe Kleine-König Signed-off-by: Rob Herring --- drivers/of/base.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/base.c b/drivers/of/base.c index 2f25d2dfecfa..1d667eb730e1 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -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; -- cgit v1.2.3-59-g8ed1b