net/davinci_cpdma: don't check for jiffies with interrupts
authorSebastian Siewior <bigeasy@linutronix.de>
Tue, 23 Apr 2013 07:31:35 +0000 (07:31 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 25 Apr 2013 08:11:49 +0000 (04:11 -0400)
__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>
drivers/net/ethernet/ti/davinci_cpdma.c

index ee13dc78430c18f542d4a59dad5d9d09a8256b8c..3e34187997deebad80a8108a3a252cd5b08ea15c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/err.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 
 #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 */