summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Frysinger <vapier.adi@gmail.com>2009-04-06 19:00:42 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 08:31:05 -0700
commitaaaf939c573b783398b6af863576322256352f64 (patch)
tree41784ef46eca1e51db79b82877ad9ca173361e76
parent11d6f5995137ba4dc49e9337185ac0a8753f8f69 (diff)
Blackfin SPI Driver: add timeout while waiting for SPIF in dma irq handler
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>
-rw-r--r--drivers/spi/spi_bfin5xx.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 88dee87fc42..e706de1d10c 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -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;