summaryrefslogtreecommitdiff
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorEvgeny Novikov <novikov@ispras.ru>2021-08-25 20:09:02 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-09-22 11:41:22 +0200
commitf29692cf8c81ebd7da6c45aee39557539d263a3f (patch)
tree10afc3bd0366bd3d20686ced0beb8482e1307030 /drivers/usb/host
parentd00fa22f6cc93fed40f8d2b9f4b58ea58375d3e2 (diff)
usb: ehci-orion: Handle errors of clk_prepare_enable() in probe
[ Upstream commit 4720f1bf4ee4a784d9ece05420ba33c9222a3004 ] 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: 8c869edaee07 ("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-orion.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index ee8d5faa0194..3eecf47d4e89 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -218,8 +218,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)) {
@@ -280,6 +283,7 @@ err_phy_init:
err_phy_get:
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",