]> git.baikalelectronics.ru Git - kernel.git/commitdiff
usb: ehci-orion: Handle errors of clk_prepare_enable() in probe
authorEvgeny Novikov <novikov@ispras.ru>
Wed, 25 Aug 2021 17:09:02 +0000 (20:09 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 Aug 2021 11:09:34 +0000 (13:09 +0200)
ehci_orion_drv_probe() did not account for possible errors of
clk_prepare_enable() that in particular could cause invocation of
clk_disable_unprepare() on clocks that were not prepared/enabled yet,
e.g. in remove or on handling errors of usb_add_hcd() in probe. Though,
there were several patches fixing different issues with clocks in this
driver, they did not solve this problem.

Add handling of errors of clk_prepare_enable() in ehci_orion_drv_probe()
to avoid calls of clk_disable_unprepare() without previous successful
invocation of clk_prepare_enable().

Found by Linux Driver Verification project (linuxtesting.org).

Fixes: a279bbee79fb ("ARM: Orion: EHCI: Add support for enabling clocks")
Co-developed-by: Kirill Shilimanov <kirill.shilimanov@huawei.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Evgeny Novikov <novikov@ispras.ru>
Signed-off-by: Kirill Shilimanov <kirill.shilimanov@huawei.com>
Link: https://lore.kernel.org/r/20210825170902.11234-1-novikov@ispras.ru
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/ehci-orion.c

index a319b1df3011c4e410bc43dc3d8c6d2687082c51..3626758b3e2aa1ccd27881509e97b2b1ff67214a 100644 (file)
@@ -264,8 +264,11 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
         * the clock does not exists.
         */
        priv->clk = devm_clk_get(&pdev->dev, NULL);
-       if (!IS_ERR(priv->clk))
-               clk_prepare_enable(priv->clk);
+       if (!IS_ERR(priv->clk)) {
+               err = clk_prepare_enable(priv->clk);
+               if (err)
+                       goto err_put_hcd;
+       }
 
        priv->phy = devm_phy_optional_get(&pdev->dev, "usb");
        if (IS_ERR(priv->phy)) {
@@ -311,6 +314,7 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
 err_dis_clk:
        if (!IS_ERR(priv->clk))
                clk_disable_unprepare(priv->clk);
+err_put_hcd:
        usb_put_hcd(hcd);
 err:
        dev_err(&pdev->dev, "init %s fail, %d\n",