Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ec7782c authored by Krzysztof Kozlowski's avatar Krzysztof Kozlowski Committed by Greg Kroah-Hartman
Browse files

pinctrl: samsung: drop pin banks references on error paths



commit 50ebd19e3585b9792e994cfa8cbee8947fe06371 upstream.

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: ab663789 ("pinctrl: samsung: Match pin banks with their device nodes")
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarKrzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Reviewed-by: default avatarSam Protsenko <semen.protsenko@linaro.org>
Reviewed-by: default avatarChanho Park <chanho61.park@samsung.com>
Link: https://lore.kernel.org/r/20220111201426.326777-2-krzysztof.kozlowski@canonical.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 89659bfd
Loading
Loading
Loading
Loading
+23 −7
Original line number Diff line number Diff line
@@ -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,
@@ -1116,19 +1126,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);
@@ -1138,6 +1148,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;
}

/**