diff options
author | Vinod Koul <vinod.koul@linux.intel.com> | 2012-08-05 07:34:33 (GMT) |
---|---|---|
committer | Vinod Koul <vinod.koul@linux.intel.com> | 2012-08-05 07:34:33 (GMT) |
commit | df3d898c9f200e9e08a7b2223136759edb98a01d (patch) | |
tree | 036399507682be0dad2450c5c9533ac57df8f00a /drivers/dma | |
parent | 0d7614f09c1ebdbaa1599a5aba7593f147bf96ee (diff) | |
parent | fed57cd375ece6d271e45d9ad630c7de632e74b6 (diff) | |
download | linux-df3d898c9f200e9e08a7b2223136759edb98a01d.tar.xz |
Merge branch 'for-3.7' into next
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/dw_dmac.c | 53 | ||||
-rw-r--r-- | drivers/dma/dw_dmac_regs.h | 2 | ||||
-rw-r--r-- | drivers/dma/tegra20-apb-dma.c | 18 |
3 files changed, 27 insertions, 46 deletions
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index d3c5a5a..4f4ff13 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1392,26 +1392,17 @@ static int __devinit dw_probe(struct platform_device *pdev) size = sizeof(struct dw_dma); size += pdata->nr_channels * sizeof(struct dw_dma_chan); - dw = kzalloc(size, GFP_KERNEL); + dw = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!dw) return -ENOMEM; - if (!request_mem_region(io->start, DW_REGLEN, pdev->dev.driver->name)) { - err = -EBUSY; - goto err_kfree; - } - - dw->regs = ioremap(io->start, DW_REGLEN); - if (!dw->regs) { - err = -ENOMEM; - goto err_release_r; - } + dw->regs = devm_request_and_ioremap(&pdev->dev, io); + if (!dw->regs) + return -EBUSY; - dw->clk = clk_get(&pdev->dev, "hclk"); - if (IS_ERR(dw->clk)) { - err = PTR_ERR(dw->clk); - goto err_clk; - } + dw->clk = devm_clk_get(&pdev->dev, "hclk"); + if (IS_ERR(dw->clk)) + return PTR_ERR(dw->clk); clk_prepare_enable(dw->clk); /* Calculate all channel mask before DMA setup */ @@ -1423,9 +1414,10 @@ static int __devinit dw_probe(struct platform_device *pdev) /* disable BLOCK interrupts as well */ channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask); - err = request_irq(irq, dw_dma_interrupt, 0, "dw_dmac", dw); + err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0, + "dw_dmac", dw); if (err) - goto err_irq; + return err; platform_set_drvdata(pdev, dw); @@ -1491,30 +1483,16 @@ static int __devinit dw_probe(struct platform_device *pdev) dma_async_device_register(&dw->dma); return 0; - -err_irq: - clk_disable_unprepare(dw->clk); - clk_put(dw->clk); -err_clk: - iounmap(dw->regs); - dw->regs = NULL; -err_release_r: - release_resource(io); -err_kfree: - kfree(dw); - return err; } static int __devexit dw_remove(struct platform_device *pdev) { struct dw_dma *dw = platform_get_drvdata(pdev); struct dw_dma_chan *dwc, *_dwc; - struct resource *io; dw_dma_off(dw); dma_async_device_unregister(&dw->dma); - free_irq(platform_get_irq(pdev, 0), dw); tasklet_kill(&dw->tasklet); list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels, @@ -1523,17 +1501,6 @@ static int __devexit dw_remove(struct platform_device *pdev) channel_clear_bit(dw, CH_EN, dwc->mask); } - clk_disable_unprepare(dw->clk); - clk_put(dw->clk); - - iounmap(dw->regs); - dw->regs = NULL; - - io = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(io->start, DW_REGLEN); - - kfree(dw); - return 0; } diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h index 50830be..f6d92d7 100644 --- a/drivers/dma/dw_dmac_regs.h +++ b/drivers/dma/dw_dmac_regs.h @@ -140,8 +140,6 @@ struct dw_dma_regs { /* Bitfields in CFG */ #define DW_CFG_DMA_EN (1 << 0) -#define DW_REGLEN 0x400 - enum dw_dmac_flags { DW_DMA_IS_CYCLIC = 0, }; diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index d52dbc6..24acd71 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1119,15 +1119,21 @@ struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( static int tegra_dma_alloc_chan_resources(struct dma_chan *dc) { struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + struct tegra_dma *tdma = tdc->tdma; + int ret; dma_cookie_init(&tdc->dma_chan); tdc->config_init = false; - return 0; + ret = clk_prepare_enable(tdma->dma_clk); + if (ret < 0) + dev_err(tdc2dev(tdc), "clk_prepare_enable failed: %d\n", ret); + return ret; } static void tegra_dma_free_chan_resources(struct dma_chan *dc) { struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); + struct tegra_dma *tdma = tdc->tdma; struct tegra_dma_desc *dma_desc; struct tegra_dma_sg_req *sg_req; @@ -1163,6 +1169,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc) list_del(&sg_req->node); kfree(sg_req); } + clk_disable_unprepare(tdma->dma_clk); } /* Tegra20 specific DMA controller information */ @@ -1255,6 +1262,13 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev) } } + /* Enable clock before accessing registers */ + ret = clk_prepare_enable(tdma->dma_clk); + if (ret < 0) { + dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); + goto err_pm_disable; + } + /* Reset DMA controller */ tegra_periph_reset_assert(tdma->dma_clk); udelay(2); @@ -1265,6 +1279,8 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev) tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); + clk_disable_unprepare(tdma->dma_clk); + INIT_LIST_HEAD(&tdma->dma_dev.channels); for (i = 0; i < cdata->nr_channels; i++) { struct tegra_dma_channel *tdc = &tdma->channels[i]; |