Blackfin SPI Driver: add timeout while waiting for SPIF in dma irq handler
authorMike Frysinger <vapier.adi@gmail.com>
Tue, 7 Apr 2009 02:00:42 +0000 (19:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 7 Apr 2009 15:31:05 +0000 (08:31 -0700)
The "while" endless loop will cause the system hang if hardware error, so
we add timeout control to make the system alive.

Signed-off-by: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/spi/spi_bfin5xx.c

index 88dee87fc420fa81dc310d3ad18e68a46ef31ca8..e706de1d10c840ee6d8730cd12eec15c3ee1704f 100644 (file)
@@ -557,6 +557,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
        struct driver_data *drv_data = dev_id;
        struct chip_data *chip = drv_data->cur_chip;
        struct spi_message *msg = drv_data->cur_msg;
+       unsigned long timeout;
        unsigned short dmastat = get_dma_curr_irqstat(drv_data->dma_channel);
        u16 spistat = read_STAT(drv_data);
 
@@ -582,8 +583,17 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
                        cpu_relax();
        }
 
+       dev_dbg(&drv_data->pdev->dev,
+               "in dma_irq_handler dmastat:0x%x spistat:0x%x\n",
+               dmastat, read_STAT(drv_data));
+
+       timeout = jiffies + HZ;
        while (!(read_STAT(drv_data) & SPIF))
-               cpu_relax();
+               if (!time_before(jiffies, timeout)) {
+                       dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF");
+                       break;
+               } else
+                       cpu_relax();
 
        if ((dmastat & DMA_ERR) && (spistat & RBSY)) {
                msg->state = ERROR_STATE;