Commit 6f15a2a0 authored by Christophe JAILLET's avatar Christophe JAILLET Committed by Greg Kroah-Hartman
Browse files

usb: bdc: Fix a resource leak in the error handling path of 'bdc_probe()'



If an error occurs after a successful 'clk_prepare_enable()' call, it must
be undone by a corresponding 'clk_disable_unprepare()' call.
This call is already present in the remove function.

Add this call in the error handling path and reorder the code so that the
'clk_prepare_enable()' call happens later in the function.
The goal is to have as much managed resources functions as possible
before the 'clk_prepare_enable()' call in order to keep the error handling
path simple.

While at it, remove the now unneeded 'clk' variable.

Fixes: c87dca04 ("usb: bdc: Add clock enable for new chips with a separate BDC clock")
Acked-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarChristophe JAILLET <christophe.jaillet@wanadoo.fr>
Link: https://lore.kernel.org/r/f8a4a6897deb0c8cb2e576580790303550f15fcd.1629314734.git.christophe.jaillet@wanadoo.fr


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d2f42e09
Loading
Loading
Loading
Loading
+13 −14
Original line number Diff line number Diff line
@@ -488,27 +488,14 @@ static int bdc_probe(struct platform_device *pdev)
	int irq;
	u32 temp;
	struct device *dev = &pdev->dev;
	struct clk *clk;
	int phy_num;

	dev_dbg(dev, "%s()\n", __func__);

	clk = devm_clk_get_optional(dev, "sw_usbd");
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	ret = clk_prepare_enable(clk);
	if (ret) {
		dev_err(dev, "could not enable clock\n");
		return ret;
	}

	bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL);
	if (!bdc)
		return -ENOMEM;

	bdc->clk = clk;

	bdc->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(bdc->regs))
		return PTR_ERR(bdc->regs);
@@ -545,10 +532,20 @@ static int bdc_probe(struct platform_device *pdev)
		}
	}

	bdc->clk = devm_clk_get_optional(dev, "sw_usbd");
	if (IS_ERR(bdc->clk))
		return PTR_ERR(bdc->clk);

	ret = clk_prepare_enable(bdc->clk);
	if (ret) {
		dev_err(dev, "could not enable clock\n");
		return ret;
	}

	ret = bdc_phy_init(bdc);
	if (ret) {
		dev_err(bdc->dev, "BDC phy init failure:%d\n", ret);
		return ret;
		goto disable_clk;
	}

	temp = bdc_readl(bdc->regs, BDC_BDCCAP1);
@@ -581,6 +578,8 @@ static int bdc_probe(struct platform_device *pdev)
	bdc_hw_exit(bdc);
phycleanup:
	bdc_phy_exit(bdc);
disable_clk:
	clk_disable_unprepare(bdc->clk);
	return ret;
}