diff options
author | Sandeep Paulraj <s-paulraj@ti.com> | 2009-09-20 13:47:03 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-11-25 10:21:26 -0800 |
commit | cc93fc3f34552e791e480ac21a17eceb9c0e26f2 (patch) | |
tree | 26382d737a5c986bd06fc340c85829b162723d09 | |
parent | dc4c05a5131d691ccbc06c2e670385127871bdbe (diff) | |
download | op-kernel-dev-cc93fc3f34552e791e480ac21a17eceb9c0e26f2.zip op-kernel-dev-cc93fc3f34552e791e480ac21a17eceb9c0e26f2.tar.gz |
DaVinci: EDMA: Fix Bug while obtaining contiguous params
The reserve_contiguous_params function is used to reserve
a set of contiguous PARAMs. If we do not find a complete
set of contiguous PARAMs, the functions still has to free
every PARAM that it found to be free in the process of finding a
complete set and thus marked as "in use".
This patch mainly deals with correctly handling the
freeing of PARAMs.
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r-- | arch/arm/mach-davinci/dma.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index 8eda4c3..b097592 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -515,17 +515,30 @@ static int reserve_contiguous_params(int ctlr, unsigned int id, { int i, j; unsigned int count = num_params; + int stop_param = start_param; + DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY); for (i = start_param; i < edma_info[ctlr]->num_slots; ++i) { j = EDMA_CHAN_SLOT(i); - if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) + if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) { + /* Record our current beginning slot */ + if (count == num_params) + stop_param = i; + count--; + set_bit(j, tmp_inuse); + if (count == 0) break; - else if (id == EDMA_CONT_PARAMS_FIXED_EXACT) - break; - else - count = num_params; + } else { + clear_bit(j, tmp_inuse); + + if (id == EDMA_CONT_PARAMS_FIXED_EXACT) { + stop_param = i; + break; + } else + count = num_params; + } } /* @@ -534,12 +547,15 @@ static int reserve_contiguous_params(int ctlr, unsigned int id, * of contiguous parameter RAMs but do not find the exact number * requested as we may reach the total number of parameter RAMs */ - if (count) { - for (j = i - num_params + count + 1; j <= i ; ++j) + if (i == edma_info[ctlr]->num_slots) + stop_param = i; + + for (j = start_param; j < stop_param; j++) + if (test_bit(j, tmp_inuse)) clear_bit(j, edma_info[ctlr]->edma_inuse); + if (count) return -EBUSY; - } for (j = i - num_params + 1; j <= i; ++j) memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j), |