aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/ti
diff options
context:
space:
mode:
authorSebastian Siewior <bigeasy@linutronix.de>2013-04-24 04:48:23 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-25 04:12:29 -0400
commitd1bd9acfa3419dc9d5c32589b34a370ca6ae100e (patch)
tree71f1e076abd4d043f5eadb83b8c252fd5d6c02b5 /drivers/net/ethernet/ti
parent4bc21d4162366bb892dc1a4a92110c656e2622ca (diff)
net/cpsw: make sure modules remove does not leak any ressources
This driver does not clean up properly after leaving. Here is a list: - Use unregister_netdev(). free_netdev() is good but not enough - Use the above also on the other ndev in case of dual mac - Free data.slave_data. The name of the strucre makes it look like it is platform_data but it is not. It is just a trick! - Free all irqs. Again: freeing one irq is good start, but freeing all of them is better. With this rmmod & modprobe of cpsw seems to work. The remaining issue is: |WARNING: at fs/sysfs/dir.c:536 sysfs_add_one+0x9c/0xd4() |sysfs: cannot create duplicate filename '/devices/ocp.2/4a100000.ethernet/4a101000.mdio' |WARNING: at lib/kobject.c:196 kobject_add_internal+0x1a4/0x1c8() comming from of_platform_populate() and I am not sure that this belongs here. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Acked-by: Mugunthan V N <mugunthanvnm@ti.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ti')
-rw-r--r--drivers/net/ethernet/ti/cpsw.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index d9f5e74cdcfc..93a60e238146 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1632,7 +1632,7 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev,
1632 1632
1633static int cpsw_probe(struct platform_device *pdev) 1633static int cpsw_probe(struct platform_device *pdev)
1634{ 1634{
1635 struct cpsw_platform_data *data = pdev->dev.platform_data; 1635 struct cpsw_platform_data *data;
1636 struct net_device *ndev; 1636 struct net_device *ndev;
1637 struct cpsw_priv *priv; 1637 struct cpsw_priv *priv;
1638 struct cpdma_params dma_params; 1638 struct cpdma_params dma_params;
@@ -1845,7 +1845,7 @@ static int cpsw_probe(struct platform_device *pdev)
1845 goto clean_ale_ret; 1845 goto clean_ale_ret;
1846 } 1846 }
1847 priv->irqs_table[k] = i; 1847 priv->irqs_table[k] = i;
1848 priv->num_irqs = k; 1848 priv->num_irqs = k + 1;
1849 } 1849 }
1850 k++; 1850 k++;
1851 } 1851 }
@@ -1883,7 +1883,8 @@ static int cpsw_probe(struct platform_device *pdev)
1883 return 0; 1883 return 0;
1884 1884
1885clean_irq_ret: 1885clean_irq_ret:
1886 free_irq(ndev->irq, priv); 1886 for (i = 0; i < priv->num_irqs; i++)
1887 free_irq(priv->irqs_table[i], priv);
1887clean_ale_ret: 1888clean_ale_ret:
1888 cpsw_ale_destroy(priv->ale); 1889 cpsw_ale_destroy(priv->ale);
1889clean_dma_ret: 1890clean_dma_ret:
@@ -1906,7 +1907,8 @@ clean_slave_ret:
1906 pm_runtime_disable(&pdev->dev); 1907 pm_runtime_disable(&pdev->dev);
1907 kfree(priv->slaves); 1908 kfree(priv->slaves);
1908clean_ndev_ret: 1909clean_ndev_ret:
1909 free_netdev(ndev); 1910 kfree(priv->data.slave_data);
1911 free_netdev(priv->ndev);
1910 return ret; 1912 return ret;
1911} 1913}
1912 1914
@@ -1914,12 +1916,17 @@ static int cpsw_remove(struct platform_device *pdev)
1914{ 1916{
1915 struct net_device *ndev = platform_get_drvdata(pdev); 1917 struct net_device *ndev = platform_get_drvdata(pdev);
1916 struct cpsw_priv *priv = netdev_priv(ndev); 1918 struct cpsw_priv *priv = netdev_priv(ndev);
1919 int i;
1917 1920
1918 pr_info("removing device");
1919 platform_set_drvdata(pdev, NULL); 1921 platform_set_drvdata(pdev, NULL);
1922 if (priv->data.dual_emac)
1923 unregister_netdev(cpsw_get_slave_ndev(priv, 1));
1924 unregister_netdev(ndev);
1920 1925
1921 cpts_unregister(priv->cpts); 1926 cpts_unregister(priv->cpts);
1922 free_irq(ndev->irq, priv); 1927 for (i = 0; i < priv->num_irqs; i++)
1928 free_irq(priv->irqs_table[i], priv);
1929
1923 cpsw_ale_destroy(priv->ale); 1930 cpsw_ale_destroy(priv->ale);
1924 cpdma_chan_destroy(priv->txch); 1931 cpdma_chan_destroy(priv->txch);
1925 cpdma_chan_destroy(priv->rxch); 1932 cpdma_chan_destroy(priv->rxch);
@@ -1933,8 +1940,10 @@ static int cpsw_remove(struct platform_device *pdev)
1933 pm_runtime_disable(&pdev->dev); 1940 pm_runtime_disable(&pdev->dev);
1934 clk_put(priv->clk); 1941 clk_put(priv->clk);
1935 kfree(priv->slaves); 1942 kfree(priv->slaves);
1943 kfree(priv->data.slave_data);
1944 if (priv->data.dual_emac)
1945 free_netdev(cpsw_get_slave_ndev(priv, 1));
1936 free_netdev(ndev); 1946 free_netdev(ndev);
1937
1938 return 0; 1947 return 0;
1939} 1948}
1940 1949