diff options
author | Adam Jiang <chaoj@nvidia.com> | 2013-08-08 17:40:46 +0900 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 13:41:12 -0700 |
commit | b14ea11ae49edf955bbbc1ca3fc8959755cd8d51 (patch) | |
tree | 38036a37ea49f55608a329e20d38f382f6abbe45 /drivers/media/video | |
parent | 7701df6d98e13767dc2a7c9e9914fc92f1291b72 (diff) |
media: video: tegra: Avoid duplicated unmapping
Unmapped DMA buffers should not be unmapped again. Once DTV driver could
not get DMA channel, it should avoid to map memory for DMA operations.
Bug 1313737
Change-Id: I63e3bde6055a76e1fdf96b1fc55ac5254d18f40a
Signed-off-by: Adam Jiang <chaoj@nvidia.com>
Reviewed-on: http://git-master/r/259890
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/tegra/tegra_dtv.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/drivers/media/video/tegra/tegra_dtv.c b/drivers/media/video/tegra/tegra_dtv.c index bc8e5e420727..7ea940cb829b 100644 --- a/drivers/media/video/tegra/tegra_dtv.c +++ b/drivers/media/video/tegra/tegra_dtv.c @@ -911,15 +911,7 @@ static int setup_dma(struct tegra_dtv_context *dtv_ctx) pr_debug("%s called\n", __func__); - for (i = 0; i < stream->num_bufs; i++) { - buf = &stream->bufs[i]; - buf->data_phy = dma_map_single( - dev, buf->data, - stream->buf_size, DMA_FROM_DEVICE); - BUG_ON(!buf->data_phy); - setup_dma_rx_request(&buf->dma_req, stream); - buf->dma_req.dest_addr = buf->data_phy; - } + /* allocate dma channel */ dtv_ctx->stream.dma_chan = tegra_dma_allocate_channel( TEGRA_DMA_MODE_CONTINUOUS_DOUBLE, "tegra_dtv_rx", dtv_ctx->dma_req_sel); @@ -927,12 +919,20 @@ static int setup_dma(struct tegra_dtv_context *dtv_ctx) pr_err("%s : cannot allocate input DMA channel: %ld\n", __func__, PTR_ERR(dtv_ctx->stream.dma_chan)); ret = -ENODEV; - /* release */ - tear_down_dma(dtv_ctx); - return ret; } + /* map buffers */ + for (i = 0; i < stream->num_bufs; i++) { + buf = &stream->bufs[i]; + buf->data_phy = dma_map_single( + dev, buf->data, + stream->buf_size, DMA_FROM_DEVICE); + BUG_ON(!buf->data_phy); + setup_dma_rx_request(&buf->dma_req, stream); + buf->dma_req.dest_addr = buf->data_phy; + } + return ret; } @@ -945,16 +945,18 @@ static void tear_down_dma(struct tegra_dtv_context *dtv_ctx) pr_debug("%s called\n", __func__); - for (i = 0; i < dtv_ctx->stream.num_bufs; i++) { - buf = &stream->bufs[i]; - dma_unmap_single(dev, - buf->data_phy, - stream->buf_size, - DMA_FROM_DEVICE); - buf->data_phy = 0; + if (dtv_ctx->stream.dma_chan) { + for (i = 0; i < dtv_ctx->stream.num_bufs; i++) { + buf = &stream->bufs[i]; + dma_unmap_single(dev, + buf->data_phy, + stream->buf_size, + DMA_FROM_DEVICE); + buf->data_phy = 0; + } + tegra_dma_free_channel(stream->dma_chan); + dtv_ctx->stream.dma_chan = 0; } - tegra_dma_free_channel(stream->dma_chan); - dtv_ctx->stream.dma_chan = 0; } static void free_dtv_buffer(struct dtv_buffer *buf) @@ -1227,11 +1229,15 @@ fail_setup_stream: fail_setup_dma: tear_down_dma(dtv_ctx); fail_no_res: + pm_qos_remove_request(&dtv_ctx->min_cpufreq); + pm_qos_remove_request(&dtv_ctx->cpudma_lat); fail_clk_enable: fail_no_clk: if (clk) clk_put(clk); + pr_warn("%s: DTV probing failed", __func__); + return ret; } @@ -1247,6 +1253,9 @@ static int tegra_dtv_remove(struct platform_device *pdev) tear_down_dma(dtv_ctx); destroy_stream(&dtv_ctx->stream); + pm_qos_remove_request(&dtv_ctx->min_cpufreq); + pm_qos_remove_request(&dtv_ctx->cpudma_lat); + clk_put(dtv_ctx->clk); misc_deregister(&dtv_ctx->miscdev); |