diff options
author | Hans de Goede <hdegoede@redhat.com> | 2015-10-20 11:42:24 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-22 05:47:45 +0300 |
commit | 104eb270e665f4fcd8cb8c8ab4c4d4538c604e92 (patch) | |
tree | 14d46ad4b54ace2e94fd27be1cb49e30ce15a26e /drivers/net/ethernet/allwinner/sun4i-emac.c | |
parent | e754ec69ab69601420eb2ed58ece803d77c93f61 (diff) | |
download | linux-104eb270e665f4fcd8cb8c8ab4c4d4538c604e92.tar.xz |
net: sun4i-emac: Properly free resources on probe failure and remove
Fix sun4i-emac not releasing the following resources:
-iomapped memory not released on probe-failure nor on remove
-clock not getting disabled on probe-failure nor on remove
-sram not being released on remove
And while at it also add error checking to the clk_prepare_enable call
done on probe.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/allwinner/sun4i-emac.c')
-rw-r--r-- | drivers/net/ethernet/allwinner/sun4i-emac.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 48ce83e443c2..8d50314ac3eb 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -847,21 +847,25 @@ static int emac_probe(struct platform_device *pdev) if (ndev->irq == -ENXIO) { netdev_err(ndev, "No irq resource\n"); ret = ndev->irq; - goto out; + goto out_iounmap; } db->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(db->clk)) { ret = PTR_ERR(db->clk); - goto out; + goto out_iounmap; } - clk_prepare_enable(db->clk); + ret = clk_prepare_enable(db->clk); + if (ret) { + dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret); + goto out_iounmap; + } ret = sunxi_sram_claim(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Error couldn't map SRAM to device\n"); - goto out; + goto out_clk_disable_unprepare; } db->phy_node = of_parse_phandle(np, "phy", 0); @@ -910,6 +914,10 @@ static int emac_probe(struct platform_device *pdev) out_release_sram: sunxi_sram_release(&pdev->dev); +out_clk_disable_unprepare: + clk_disable_unprepare(db->clk); +out_iounmap: + iounmap(db->membase); out: dev_err(db->dev, "not found (%d).\n", ret); @@ -921,8 +929,12 @@ out: static int emac_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); + struct emac_board_info *db = netdev_priv(ndev); unregister_netdev(ndev); + sunxi_sram_release(&pdev->dev); + clk_disable_unprepare(db->clk); + iounmap(db->membase); free_netdev(ndev); dev_dbg(&pdev->dev, "released and freed device\n"); |