diff options
author | Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | 2022-01-11 21:13:59 +0100 |
---|---|---|
committer | Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | 2022-01-23 12:21:56 +0100 |
commit | 50ebd19e3585b9792e994cfa8cbee8947fe06371 (patch) | |
tree | b4eed7d4dc440ba48ccec1587ef5b5c405b8c0d4 /drivers/pinctrl/samsung | |
parent | e783362eb54cd99b2cac8b3a9aeac942e6f6ac07 (diff) | |
download | linux-50ebd19e3585b9792e994cfa8cbee8947fe06371.tar.bz2 |
pinctrl: samsung: drop pin banks references on error paths
The driver iterates over its devicetree children with
for_each_child_of_node() and stores for later found node pointer. This
has to be put in error paths to avoid leak during re-probing.
Fixes: ab663789d697 ("pinctrl: samsung: Match pin banks with their device nodes")
Cc: <stable@vger.kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org>
Reviewed-by: Chanho Park <chanho61.park@samsung.com>
Link: https://lore.kernel.org/r/20220111201426.326777-2-krzysztof.kozlowski@canonical.com
Diffstat (limited to 'drivers/pinctrl/samsung')
-rw-r--r-- | drivers/pinctrl/samsung/pinctrl-samsung.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 0f6e9305fec5..c4175fea7d74 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1002,6 +1002,16 @@ samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev) return &(of_data->ctrl[id]); } +static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d) +{ + struct samsung_pin_bank *bank; + unsigned int i; + + bank = d->pin_banks; + for (i = 0; i < d->nr_banks; ++i, ++bank) + of_node_put(bank->of_node); +} + /* retrieve the soc specific data */ static const struct samsung_pin_ctrl * samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, @@ -1117,19 +1127,19 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) if (ctrl->retention_data) { drvdata->retention_ctrl = ctrl->retention_data->init(drvdata, ctrl->retention_data); - if (IS_ERR(drvdata->retention_ctrl)) - return PTR_ERR(drvdata->retention_ctrl); + if (IS_ERR(drvdata->retention_ctrl)) { + ret = PTR_ERR(drvdata->retention_ctrl); + goto err_put_banks; + } } ret = samsung_pinctrl_register(pdev, drvdata); if (ret) - return ret; + goto err_put_banks; ret = samsung_gpiolib_register(pdev, drvdata); - if (ret) { - samsung_pinctrl_unregister(pdev, drvdata); - return ret; - } + if (ret) + goto err_unregister; if (ctrl->eint_gpio_init) ctrl->eint_gpio_init(drvdata); @@ -1139,6 +1149,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) platform_set_drvdata(pdev, drvdata); return 0; + +err_unregister: + samsung_pinctrl_unregister(pdev, drvdata); +err_put_banks: + samsung_banks_of_node_put(drvdata); + return ret; } /* |