summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Yanok <yanok@emcraft.com>2011-12-18 10:02:04 +0000
committerDavid S. Miller <davem@davemloft.net>2011-12-19 16:31:13 -0500
commit7746ab0abb512826540a9a0c917519d11a7bf392 (patch)
tree90ab33782fe835540102eabcdd5b763969a1598e
parent2692ba61a82203404abd7dd2a027bda962861f74 (diff)
downloadlinux-7746ab0abb512826540a9a0c917519d11a7bf392.tar.gz
linux-7746ab0abb512826540a9a0c917519d11a7bf392.tar.bz2
linux-7746ab0abb512826540a9a0c917519d11a7bf392.zip
davinci-cpdma: fix locking issue in cpdma_chan_stop
Free the channel lock before calling __cpdma_chan_process to prevent dead lock. Signed-off-by: Ilya Yanok <yanok@emcraft.com> Tested-by: Ameya Palande <2ameya@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ti/davinci_cpdma.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
index dca9d3369cdd..c97d2f590855 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -836,11 +836,13 @@ int cpdma_chan_stop(struct cpdma_chan *chan)
chan_write(chan, cp, CPDMA_TEARDOWN_VALUE);
/* handle completed packets */
+ spin_unlock_irqrestore(&chan->lock, flags);
do {
ret = __cpdma_chan_process(chan);
if (ret < 0)
break;
} while ((ret & CPDMA_DESC_TD_COMPLETE) == 0);
+ spin_lock_irqsave(&chan->lock, flags);
/* remaining packets haven't been tx/rx'ed, clean them up */
while (chan->head) {