summaryrefslogtreecommitdiff
path: root/drivers/net/fec.c
diff options
context:
space:
mode:
authorJeremiah Lott <jeremiah.lott@timesys.com>2009-09-23 11:21:54 -0400
committerJeremiah Lott <jeremiah.lott@timesys.com>2009-09-23 11:21:54 -0400
commitc50b1342c67a30129effa255fcc3759306e64d70 (patch)
tree147490ee9e8bda280af5f7c2e2f3361d9af31d10 /drivers/net/fec.c
parentef92d03b49ab3949cabccf48f503f44e99c6c40a (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.c37
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);