From 817f6d1a13754b043e1a6c1cb713763022860689 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Tue, 23 Apr 2013 07:31:35 +0000 Subject: [PATCH] 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 Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_cpdma.c | 20 ++++++++++++-------- 1 file 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 @@ #include #include #include +#include #include "davinci_cpdma.h" @@ -312,14 +313,16 @@ int cpdma_ctlr_start(struct cpdma_ctlr *ctlr) } if (ctlr->params.has_soft_reset) { - unsigned long timeout = jiffies + HZ/10; + unsigned timeout = 10 * 100; dma_reg_write(ctlr, CPDMA_SOFTRESET, 1); - while (time_before(jiffies, timeout)) { + while (timeout) { if (dma_reg_read(ctlr, CPDMA_SOFTRESET) == 0) break; + udelay(10); + timeout--; } - WARN_ON(!time_before(jiffies, timeout)); + WARN_ON(!timeout); } for (i = 0; i < ctlr->num_chan; i++) { @@ -868,7 +871,7 @@ int cpdma_chan_stop(struct cpdma_chan *chan) struct cpdma_desc_pool *pool = ctlr->pool; unsigned long flags; int ret; - unsigned long timeout; + unsigned timeout; spin_lock_irqsave(&chan->lock, flags); if (chan->state != CPDMA_STATE_ACTIVE) { @@ -883,14 +886,15 @@ int cpdma_chan_stop(struct cpdma_chan *chan) dma_reg_write(ctlr, chan->td, chan_linear(chan)); /* wait for teardown complete */ - timeout = jiffies + HZ/10; /* 100 msec */ - while (time_before(jiffies, timeout)) { + timeout = 100 * 100; /* 100 ms */ + while (timeout) { u32 cp = chan_read(chan, cp); if ((cp & CPDMA_TEARDOWN_VALUE) == CPDMA_TEARDOWN_VALUE) break; - cpu_relax(); + udelay(10); + timeout--; } - WARN_ON(!time_before(jiffies, timeout)); + WARN_ON(!timeout); chan_write(chan, cp, CPDMA_TEARDOWN_VALUE); /* handle completed packets */ -- GitLab