diff options
author | David S. Miller <davem@davemloft.net> | 2013-08-01 16:14:29 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-01 16:14:29 -0700 |
commit | c1fc20aa16b3d0c52d88fffb3eca6981f3f82ca7 (patch) | |
tree | 8665b171f1deed2f0335c0261a9c9c63c98cbf2f | |
parent | 8b09be5f173759c87159b2f300c18f2ace9587de (diff) | |
parent | aa10181bdac99a623517f0f2bfa14cd98c749246 (diff) |
Merge branch 'for-davem' of git://gitorious.org/linux-can/linux-can-next
Marc Kleine-Budde says:
====================
this is a pull-request for net-next/master. It consists of two patches
by Fabio Estevam. Them first convert the flexcan driver to use
devm_ioremap_resource(), the second adds return value checking for
clk_prepare_enable().
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/can/flexcan.c | 81 |
1 files changed, 32 insertions, 49 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 7b0be0910f4..c48174ed49c 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -850,12 +850,17 @@ static int flexcan_open(struct net_device *dev) struct flexcan_priv *priv = netdev_priv(dev); int err; - clk_prepare_enable(priv->clk_ipg); - clk_prepare_enable(priv->clk_per); + err = clk_prepare_enable(priv->clk_ipg); + if (err) + return err; + + err = clk_prepare_enable(priv->clk_per); + if (err) + goto out_disable_ipg; err = open_candev(dev); if (err) - goto out; + goto out_disable_per; err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); if (err) @@ -875,8 +880,9 @@ static int flexcan_open(struct net_device *dev) out_close: close_candev(dev); - out: + out_disable_per: clk_disable_unprepare(priv->clk_per); + out_disable_ipg: clk_disable_unprepare(priv->clk_ipg); return err; @@ -933,8 +939,13 @@ static int register_flexcandev(struct net_device *dev) struct flexcan_regs __iomem *regs = priv->base; u32 reg, err; - clk_prepare_enable(priv->clk_ipg); - clk_prepare_enable(priv->clk_per); + err = clk_prepare_enable(priv->clk_ipg); + if (err) + return err; + + err = clk_prepare_enable(priv->clk_per); + if (err) + goto out_disable_ipg; /* select "bus clock", chip must be disabled */ flexcan_chip_disable(priv); @@ -959,15 +970,16 @@ static int register_flexcandev(struct net_device *dev) if (!(reg & FLEXCAN_MCR_FEN)) { netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); err = -ENODEV; - goto out; + goto out_disable_per; } err = register_candev(dev); - out: + out_disable_per: /* disable core and turn off clocks */ flexcan_chip_disable(priv); clk_disable_unprepare(priv->clk_per); + out_disable_ipg: clk_disable_unprepare(priv->clk_ipg); return err; @@ -1001,7 +1013,6 @@ static int flexcan_probe(struct platform_device *pdev) struct resource *mem; struct clk *clk_ipg = NULL, *clk_per = NULL; void __iomem *base; - resource_size_t mem_size; int err, irq; u32 clock_freq = 0; @@ -1013,43 +1024,25 @@ static int flexcan_probe(struct platform_device *pdev) clk_ipg = devm_clk_get(&pdev->dev, "ipg"); if (IS_ERR(clk_ipg)) { dev_err(&pdev->dev, "no ipg clock defined\n"); - err = PTR_ERR(clk_ipg); - goto failed_clock; + return PTR_ERR(clk_ipg); } clock_freq = clk_get_rate(clk_ipg); clk_per = devm_clk_get(&pdev->dev, "per"); if (IS_ERR(clk_per)) { dev_err(&pdev->dev, "no per clock defined\n"); - err = PTR_ERR(clk_per); - goto failed_clock; + return PTR_ERR(clk_per); } } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!mem || irq <= 0) { - err = -ENODEV; - goto failed_get; - } + if (irq <= 0) + return -ENODEV; - mem_size = resource_size(mem); - if (!request_mem_region(mem->start, mem_size, pdev->name)) { - err = -EBUSY; - goto failed_get; - } - - base = ioremap(mem->start, mem_size); - if (!base) { - err = -ENOMEM; - goto failed_map; - } - - dev = alloc_candev(sizeof(struct flexcan_priv), 1); - if (!dev) { - err = -ENOMEM; - goto failed_alloc; - } + base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(base)) + return PTR_ERR(base); of_id = of_match_device(flexcan_of_match, &pdev->dev); if (of_id) { @@ -1058,10 +1051,13 @@ static int flexcan_probe(struct platform_device *pdev) devtype_data = (struct flexcan_devtype_data *) pdev->id_entry->driver_data; } else { - err = -ENODEV; - goto failed_devtype; + return -ENODEV; } + dev = alloc_candev(sizeof(struct flexcan_priv), 1); + if (!dev) + return -ENOMEM; + dev->netdev_ops = &flexcan_netdev_ops; dev->irq = irq; dev->flags |= IFF_ECHO; @@ -1104,28 +1100,15 @@ static int flexcan_probe(struct platform_device *pdev) return 0; failed_register: - failed_devtype: free_candev(dev); - failed_alloc: - iounmap(base); - failed_map: - release_mem_region(mem->start, mem_size); - failed_get: - failed_clock: return err; } static int flexcan_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); - struct flexcan_priv *priv = netdev_priv(dev); - struct resource *mem; unregister_flexcandev(dev); - iounmap(priv->base); - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, resource_size(mem)); free_candev(dev); |