aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Siewior <bigeasy@linutronix.de>2013-04-23 03:31:35 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-25 04:11:49 -0400
commit817f6d1a13754b043e1a6c1cb713763022860689 (patch)
tree80488896dae65d080e4463f2bf79efb8a0f9c617
parent2bac7cb316d1327c457a715bac5fd56bbc42bc63 (diff)
net/davinci_cpdma: don't check for jiffies with interrupts
__cpdma_chan_process() holds the lock with interrupts off (and its caller as well), same goes for cpdma_ctlr_start(). With interrupts off, jiffies will not make any progress and if the wait condition never gets true we wait for ever. Tgis patch adds a a simple udelay and counting down attempt. Acked-by: Mugunthan V N <mugunthanvnm@ti.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ti/davinci_cpdma.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
index ee13dc78430c..3e34187997de 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -20,6 +20,7 @@
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/delay.h>
23 24
24#include "davinci_cpdma.h" 25#include "davinci_cpdma.h"
25 26
@@ -312,14 +313,16 @@ int cpdma_ctlr_start(struct cpdma_ctlr *ctlr)
312 } 313 }
313 314
314 if (ctlr->params.has_soft_reset) { 315 if (ctlr->params.has_soft_reset) {
315 unsigned long timeout = jiffies + HZ/10; 316 unsigned timeout = 10 * 100;
316 317
317 dma_reg_write(ctlr, CPDMA_SOFTRESET, 1); 318 dma_reg_write(ctlr, CPDMA_SOFTRESET, 1);
318 while (time_before(jiffies, timeout)) { 319 while (timeout) {
319 if (dma_reg_read(ctlr, CPDMA_SOFTRESET) == 0) 320 if (dma_reg_read(ctlr, CPDMA_SOFTRESET) == 0)
320 break; 321 break;
322 udelay(10);
323 timeout--;
321 } 324 }
322 WARN_ON(!time_before(jiffies, timeout)); 325 WARN_ON(!timeout);
323 } 326 }
324 327
325 for (i = 0; i < ctlr->num_chan; i++) { 328 for (i = 0; i < ctlr->num_chan; i++) {
@@ -868,7 +871,7 @@ int cpdma_chan_stop(struct cpdma_chan *chan)
868 struct cpdma_desc_pool *pool = ctlr->pool; 871 struct cpdma_desc_pool *pool = ctlr->pool;
869 unsigned long flags; 872 unsigned long flags;
870 int ret; 873 int ret;
871 unsigned long timeout; 874 unsigned timeout;
872 875
873 spin_lock_irqsave(&chan->lock, flags); 876 spin_lock_irqsave(&chan->lock, flags);
874 if (chan->state != CPDMA_STATE_ACTIVE) { 877 if (chan->state != CPDMA_STATE_ACTIVE) {
@@ -883,14 +886,15 @@ int cpdma_chan_stop(struct cpdma_chan *chan)
883 dma_reg_write(ctlr, chan->td, chan_linear(chan)); 886 dma_reg_write(ctlr, chan->td, chan_linear(chan));
884 887
885 /* wait for teardown complete */ 888 /* wait for teardown complete */
886 timeout = jiffies + HZ/10; /* 100 msec */ 889 timeout = 100 * 100; /* 100 ms */
887 while (time_before(jiffies, timeout)) { 890 while (timeout) {
888 u32 cp = chan_read(chan, cp); 891 u32 cp = chan_read(chan, cp);
889 if ((cp & CPDMA_TEARDOWN_VALUE) == CPDMA_TEARDOWN_VALUE) 892 if ((cp & CPDMA_TEARDOWN_VALUE) == CPDMA_TEARDOWN_VALUE)
890 break; 893 break;
891 cpu_relax(); 894 udelay(10);
895 timeout--;
892 } 896 }
893 WARN_ON(!time_before(jiffies, timeout)); 897 WARN_ON(!timeout);
894 chan_write(chan, cp, CPDMA_TEARDOWN_VALUE); 898 chan_write(chan, cp, CPDMA_TEARDOWN_VALUE);
895 899
896 /* handle completed packets */ 900 /* handle completed packets */