Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: stmmac: dwc-qos: fix clk prepare/enable leak on probe failure

dwc_eth_dwmac_probe() gets bulk clocks, and then prepares and enables
them. Unfortunately, if dwc_eth_dwmac_config_dt() or stmmac_dvr_probe()
fail, we leave the clocks prepared and enabled. Fix this by using
devm_clk_bulk_get_all_enabled() to combine the steps and provide devm
based release of the prepare and enable state.

This also fixes a similar leakin dwc_eth_dwmac_remove() which wasn't
correctly retrieving the struct plat_stmmacenet_data. This becomes
unnecessary.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Simon Horman <horms@kernel.org>
Fixes: a045e40645df ("net: stmmac: refactor clock management in EQoS driver")
Link: https://patch.msgid.link/E1ukM1X-0086qu-Td@rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Russell King (Oracle) and committed by
Jakub Kicinski
89886abd de1e963a

+2 -11
+2 -11
drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
··· 330 330 if (IS_ERR(plat_dat)) 331 331 return PTR_ERR(plat_dat); 332 332 333 - ret = devm_clk_bulk_get_all(&pdev->dev, &plat_dat->clks); 333 + ret = devm_clk_bulk_get_all_enabled(&pdev->dev, &plat_dat->clks); 334 334 if (ret < 0) 335 - return dev_err_probe(&pdev->dev, ret, "Failed to retrieve all required clocks\n"); 335 + return dev_err_probe(&pdev->dev, ret, "Failed to retrieve and enable all required clocks\n"); 336 336 plat_dat->num_clks = ret; 337 - 338 - ret = clk_bulk_prepare_enable(plat_dat->num_clks, plat_dat->clks); 339 - if (ret) 340 - return dev_err_probe(&pdev->dev, ret, "Failed to enable clocks\n"); 341 337 342 338 plat_dat->stmmac_clk = stmmac_pltfr_find_clk(plat_dat, 343 339 data->stmmac_clk_name); ··· 342 346 ret = data->probe(pdev, plat_dat, &stmmac_res); 343 347 if (ret < 0) { 344 348 dev_err_probe(&pdev->dev, ret, "failed to probe subdriver\n"); 345 - clk_bulk_disable_unprepare(plat_dat->num_clks, plat_dat->clks); 346 349 return ret; 347 350 } 348 351 ··· 365 370 static void dwc_eth_dwmac_remove(struct platform_device *pdev) 366 371 { 367 372 const struct dwc_eth_dwmac_data *data = device_get_match_data(&pdev->dev); 368 - struct plat_stmmacenet_data *plat_dat = dev_get_platdata(&pdev->dev); 369 373 370 374 stmmac_dvr_remove(&pdev->dev); 371 375 372 376 if (data->remove) 373 377 data->remove(pdev); 374 - 375 - if (plat_dat) 376 - clk_bulk_disable_unprepare(plat_dat->num_clks, plat_dat->clks); 377 378 } 378 379 379 380 static const struct of_device_id dwc_eth_dwmac_match[] = {