diff options
author | Jeremiah Lott <jeremiah.lott@timesys.com> | 2009-09-23 11:21:54 -0400 |
---|---|---|
committer | Jeremiah Lott <jeremiah.lott@timesys.com> | 2009-09-23 11:21:54 -0400 |
commit | c50b1342c67a30129effa255fcc3759306e64d70 (patch) | |
tree | 147490ee9e8bda280af5f7c2e2f3361d9af31d10 /drivers/net/fec.c | |
parent | ef92d03b49ab3949cabccf48f503f44e99c6c40a (diff) |
Fix race condition in fec driver where interrupt occuring during driver probe caused a kernel panic.2.6.31-mx27lite-200909231148
Diffstat (limited to 'drivers/net/fec.c')
-rw-r--r-- | drivers/net/fec.c | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index c9fd82d3a80d..721761a4428e 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1879,6 +1879,21 @@ fec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); + fep->clk = clk_get(&pdev->dev, "fec_clk"); + if (IS_ERR(fep->clk)) { + ret = PTR_ERR(fep->clk); + goto failed_clk; + } + clk_enable(fep->clk); + + ret = fec_enet_init(ndev, 0); + if (ret) + goto failed_init; + + ret = register_netdev(ndev); + if (ret) + goto failed_register; + /* This device has up to three irqs on some platforms */ for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); @@ -1895,34 +1910,14 @@ fec_probe(struct platform_device *pdev) } } - fep->clk = clk_get(&pdev->dev, "fec_clk"); - if (IS_ERR(fep->clk)) { - ret = PTR_ERR(fep->clk); - goto failed_clk; - } - clk_enable(fep->clk); - - ret = fec_enet_init(ndev, 0); - if (ret) - goto failed_init; - - ret = register_netdev(ndev); - if (ret) - goto failed_register; - return 0; +failed_irq: failed_register: failed_init: clk_disable(fep->clk); clk_put(fep->clk); failed_clk: - for (i = 0; i < 3; i++) { - irq = platform_get_irq(pdev, i); - if (irq > 0) - free_irq(irq, ndev); - } -failed_irq: iounmap((void __iomem *)ndev->base_addr); failed_ioremap: free_netdev(ndev); |