diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2010-08-25 15:37:38 +0530 |
---|---|---|
committer | Bharat Nihalani <bnihalani@nvidia.com> | 2010-09-03 01:47:23 -0700 |
commit | 2349860b3df60934e6c04a8684cb51e6e1d39549 (patch) | |
tree | 2cd5ba50fccf5d36dd530b5f97f972b38bc1e84a /arch | |
parent | f08615eab12cdfbdf5f30689677ee3b53902a31a (diff) |
[arm/tegra] rm dma: Fixing resource leak issue.
When dma is aborted, all request should be dequeued from
the dma and the allocated memory should be freed.
The allocated resource was not getting freed, fixing this
issue.
Properly checking the return pointer from the allocate_dma.
(cherry picked from commit 02f0e4da9c66fee14f4492fa5b4ec41fd028a56e)
Change-Id: I0dbaeca9b19331458b9aaf91556b7dad1e9b67ee
Reviewed-on: http://git-master/r/5768
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Tested-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c b/arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c index 42e003ed8ec8..03597ec08709 100644 --- a/arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c +++ b/arch/arm/mach-tegra/nvrm/io/common/nvrm_dma.c @@ -176,8 +176,8 @@ NvError NvRmDmaAllocate(NvRmDeviceHandle rm, NvRmDmaHandle *rm_dma, mode = TEGRA_DMA_MODE_ONESHOT; dma->ch = tegra_dma_allocate_channel(mode); - if (!dma->ch) { - e = NvError_Busy; + if (IS_ERR_OR_NULL(dma->ch)) { + e = NvError_DmaChannelNotAvailable; goto fail; } INIT_LIST_HEAD(&dma->req_list); @@ -188,7 +188,7 @@ NvError NvRmDmaAllocate(NvRmDeviceHandle rm, NvRmDmaHandle *rm_dma, return NvSuccess; fail: if (dma) { - if (dma->ch) + if (!IS_ERR_OR_NULL(dma->ch)) tegra_dma_free_channel(dma->ch); kfree(dma); } @@ -277,6 +277,7 @@ NvError NvRmDmaStartDmaTransfer(NvRmDmaHandle dma, NvRmDmaClientBuffer *b, action->req.source_wrap = dst_wrap; } + action->dma_sem = NULL; if (timeout) { action->dma_done = &dma_done; action->req.complete = dma_complete_sync; @@ -342,6 +343,10 @@ void NvRmDmaAbort(NvRmDmaHandle dma) req = &action->req; spin_unlock(&dma->lock); tegra_dma_dequeue_req(dma->ch, req); + if (action->dma_sem) + NvOsSemaphoreDestroy(action->dma_sem); + list_del(&action->node); + kfree(action); spin_lock(&dma->lock); } spin_unlock(&dma->lock); |