mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 07:34:12 +08:00
net: stmmac: dwmac-sun8i: Fix probe error handling
stmmac_pltfr_remove does three things in one function, making it inapproprate for unwinding the steps in the probe function. Currently, a failure before the call to stmmac_dvr_probe would leak OF node references due to missing a call to stmmac_remove_config_dt. And an error in stmmac_dvr_probe would cause the driver to attempt to remove a netdevice that was never added. Fix these by reordering the init and splitting out the error handling steps. Fixes:9f93ac8d40
("net-next: stmmac: Add dwmac-sun8i") Fixes:40a1dcee2d
("net: ethernet: dwmac-sun8i: Use the correct function in exit path") Signed-off-by: Samuel Holland <samuel@sholland.org> Reviewed-by: Chen-Yu Tsai <wens@csie.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
55b7ab1178
commit
7eeecc4b1f
@ -1134,10 +1134,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
|
||||
if (IS_ERR(plat_dat))
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
|
||||
if (!gmac)
|
||||
return -ENOMEM;
|
||||
@ -1201,11 +1197,15 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
||||
ret = of_get_phy_mode(dev->of_node, &interface);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
plat_dat->interface = interface;
|
||||
|
||||
plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
|
||||
if (IS_ERR(plat_dat))
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
/* platform data specifying hardware features and callbacks.
|
||||
* hardware features were copied from Allwinner drivers.
|
||||
*/
|
||||
plat_dat->interface = interface;
|
||||
plat_dat->rx_coe = STMMAC_RX_COE_TYPE2;
|
||||
plat_dat->tx_coe = 1;
|
||||
plat_dat->has_sun8i = true;
|
||||
@ -1216,7 +1216,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
||||
|
||||
ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto dwmac_deconfig;
|
||||
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (ret)
|
||||
@ -1230,7 +1230,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
||||
if (gmac->variant->soc_has_internal_phy) {
|
||||
ret = get_ephy_nodes(priv);
|
||||
if (ret)
|
||||
goto dwmac_exit;
|
||||
goto dwmac_remove;
|
||||
ret = sun8i_dwmac_register_mdio_mux(priv);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register mux\n");
|
||||
@ -1239,15 +1239,20 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
||||
} else {
|
||||
ret = sun8i_dwmac_reset(priv);
|
||||
if (ret)
|
||||
goto dwmac_exit;
|
||||
goto dwmac_remove;
|
||||
}
|
||||
|
||||
return ret;
|
||||
dwmac_mux:
|
||||
sun8i_dwmac_unset_syscon(gmac);
|
||||
dwmac_remove:
|
||||
stmmac_dvr_remove(&pdev->dev);
|
||||
dwmac_exit:
|
||||
stmmac_pltfr_remove(pdev);
|
||||
return ret;
|
||||
sun8i_dwmac_exit(pdev, gmac);
|
||||
dwmac_deconfig:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id sun8i_dwmac_match[] = {
|
||||
|
Loading…
Reference in New Issue
Block a user