summaryrefslogtreecommitdiff
path: root/drivers/media/video
diff options
context:
space:
mode:
authorAdam Jiang <chaoj@nvidia.com>2013-08-08 17:40:46 +0900
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 13:41:12 -0700
commitb14ea11ae49edf955bbbc1ca3fc8959755cd8d51 (patch)
tree38036a37ea49f55608a329e20d38f382f6abbe45 /drivers/media/video
parent7701df6d98e13767dc2a7c9e9914fc92f1291b72 (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.c51
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);