Commit 5b366eae authored by Vitalii Mordan's avatar Vitalii Mordan Committed by Jakub Kicinski
Browse files

stmmac: dwmac-intel-plat: fix call balance of tx_clk handling routines



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: 9efc9b2b ("net: stmmac: Add dwmac-intel-plat for GBE driver")
Signed-off-by: default avatarVitalii Mordan <mordan@ispras.ru>
Link: https://patch.msgid.link/20241108173334.2973603-1-mordan@ispras.ru


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent eb94b7bb
Loading
Loading
Loading
Loading
+17 −8
Original line number Diff line number Diff line
@@ -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,6 +170,7 @@ static void intel_eth_plat_remove(struct platform_device *pdev)
	struct intel_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev);

	stmmac_pltfr_remove(pdev);
	if (dwmac->data->tx_clk_en)
		clk_disable_unprepare(dwmac->tx_clk);
}