]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: chipidea: ci_hdrc_imx: implement usb_phy_init() error handling
authorFedor Pchelkin <pchelkin@ispras.ru>
Sun, 16 Mar 2025 10:26:56 +0000 (13:26 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 11 Apr 2025 14:20:52 +0000 (16:20 +0200)
usb_phy_init() may return an error code if e.g. its implementation fails
to prepare/enable some clocks. And properly rollback on probe error path
by calling the counterpart usb_phy_shutdown().

Found by Linux Verification Center (linuxtesting.org).

Fixes: be9cae2479f4 ("usb: chipidea: imx: Fix ULPI on imx53")
Cc: stable <stable@kernel.org>
Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
Acked-by: Peter Chen <peter.chen@kernel.org>
Link: https://lore.kernel.org/r/20250316102658.490340-4-pchelkin@ispras.ru
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/chipidea/ci_hdrc_imx.c

index d942b3c72640eb63aa65b455bd98ed0ba7f14b05..4f8bfd242b5953821b0069192e0bef8f4819f6a6 100644 (file)
@@ -484,7 +484,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
            of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
                pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
                data->override_phy_control = true;
-               usb_phy_init(pdata.usb_phy);
+               ret = usb_phy_init(pdata.usb_phy);
+               if (ret) {
+                       dev_err(dev, "Failed to init phy\n");
+                       goto err_clk;
+               }
        }
 
        if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
@@ -493,7 +497,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        ret = imx_usbmisc_init(data->usbmisc_data);
        if (ret) {
                dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
-               goto err_clk;
+               goto phy_shutdown;
        }
 
        data->ci_pdev = ci_hdrc_add_device(dev,
@@ -502,7 +506,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        if (IS_ERR(data->ci_pdev)) {
                ret = PTR_ERR(data->ci_pdev);
                dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
-               goto err_clk;
+               goto phy_shutdown;
        }
 
        if (data->usbmisc_data) {
@@ -536,6 +540,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 
 disable_device:
        ci_hdrc_remove_device(data->ci_pdev);
+phy_shutdown:
+       if (data->override_phy_control)
+               usb_phy_shutdown(data->phy);
 err_clk:
        clk_disable_unprepare(data->clk_wakeup);
 err_wakeup_clk: