usb: bdc: Fix a resource leak in the error handling path of 'bdc_probe()'
authorChristophe JAILLET <christophe.jaillet@wanadoo.fr>
Wed, 18 Aug 2021 19:32:49 +0000 (21:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 Aug 2021 11:34:52 +0000 (13:34 +0200)
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: c87dca047849 ("usb: bdc: Add clock enable for new chips with a separate BDC clock")
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Link: https://lore.kernel.org/r/f8a4a6897deb0c8cb2e576580790303550f15fcd.1629314734.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/udc/bdc/bdc_core.c

index 251db57..fa1a390 100644 (file)
@@ -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 @@ cleanup:
        bdc_hw_exit(bdc);
 phycleanup:
        bdc_phy_exit(bdc);
+disable_clk:
+       clk_disable_unprepare(bdc->clk);
        return ret;
 }