forked from mirrors/linux
		
	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: 9efc9b2b04 ("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>
			
			
This commit is contained in:
		
							parent
							
								
									eb94b7bb10
								
							
						
					
					
						commit
						5b366eae71
					
				
					 1 changed files with 17 additions and 8 deletions
				
			
		|  | @ -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 = { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Vitalii Mordan
						Vitalii Mordan