]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
stmmac: dwmac-intel-plat: fix call balance of tx_clk handling routines
authorVitalii Mordan <mordan@ispras.ru>
Fri, 8 Nov 2024 17:33:34 +0000 (20:33 +0300)
committerJakub Kicinski <kuba@kernel.org>
Thu, 14 Nov 2024 03:52:24 +0000 (19:52 -0800)
If the clock dwmac->tx_clk was not enabled in intel_eth_plat_probe,
it should not be disabled in any path.

Conversely, if it was enabled in intel_eth_plat_probe, it must be disabled
in all error paths to ensure proper cleanup.

Found by Linux Verification Center (linuxtesting.org) with Klever.

Fixes: 9efc9b2b04c7 ("net: stmmac: Add dwmac-intel-plat for GBE driver")
Signed-off-by: Vitalii Mordan <mordan@ispras.ru>
Link: https://patch.msgid.link/20241108173334.2973603-1-mordan@ispras.ru
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c

index d68f0c4e7835053298ef2e70b7a81e6282a80f3a..9739bc9867c51486c86e5fb86cda747b12c47253 100644 (file)
@@ -108,7 +108,12 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
                        if (IS_ERR(dwmac->tx_clk))
                                return PTR_ERR(dwmac->tx_clk);
 
-                       clk_prepare_enable(dwmac->tx_clk);
+                       ret = clk_prepare_enable(dwmac->tx_clk);
+                       if (ret) {
+                               dev_err(&pdev->dev,
+                                       "Failed to enable tx_clk\n");
+                               return ret;
+                       }
 
                        /* Check and configure TX clock rate */
                        rate = clk_get_rate(dwmac->tx_clk);
@@ -119,7 +124,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
                                if (ret) {
                                        dev_err(&pdev->dev,
                                                "Failed to set tx_clk\n");
-                                       return ret;
+                                       goto err_tx_clk_disable;
                                }
                        }
                }
@@ -133,7 +138,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
                        if (ret) {
                                dev_err(&pdev->dev,
                                        "Failed to set clk_ptp_ref\n");
-                               return ret;
+                               goto err_tx_clk_disable;
                        }
                }
        }
@@ -149,12 +154,15 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
        }
 
        ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-       if (ret) {
-               clk_disable_unprepare(dwmac->tx_clk);
-               return ret;
-       }
+       if (ret)
+               goto err_tx_clk_disable;
 
        return 0;
+
+err_tx_clk_disable:
+       if (dwmac->data->tx_clk_en)
+               clk_disable_unprepare(dwmac->tx_clk);
+       return ret;
 }
 
 static void intel_eth_plat_remove(struct platform_device *pdev)
@@ -162,7 +170,8 @@ static void intel_eth_plat_remove(struct platform_device *pdev)
        struct intel_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev);
 
        stmmac_pltfr_remove(pdev);
-       clk_disable_unprepare(dwmac->tx_clk);
+       if (dwmac->data->tx_clk_en)
+               clk_disable_unprepare(dwmac->tx_clk);
 }
 
 static struct platform_driver intel_eth_plat_driver = {