summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-pl022.c
diff options
context:
space:
mode:
authorJiwei Sun <jiwei.sun@windriver.com>2019-01-17 22:32:29 -0500
committerMark Brown <broonie@kernel.org>2019-01-28 13:23:04 -0500
commit7aef2b646b24247d880a353e09d4e10614a61cd6 (patch)
tree2044cf9a54f92ee9d7e2c51e64982d405f0ff0bf /drivers/spi/spi-pl022.c
parent2e236bafab11b063069a8b12793f1986862963b0 (diff)
spi: pl022: add a message state STATE_TIMEOUT for timeout transfer
When transfer timeout, give -EAGAIN to the message's status, and it can make the spi device driver choose repeated transimation or not. And if transfer timeout, output some useful information for tracing the issue. Signed-off-by: Jiwei Sun <jiwei.sun@windriver.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-pl022.c')
-rw-r--r--drivers/spi/spi-pl022.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 0c793e31d60f..26684178786f 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -253,6 +253,7 @@
253#define STATE_RUNNING ((void *) 1) 253#define STATE_RUNNING ((void *) 1)
254#define STATE_DONE ((void *) 2) 254#define STATE_DONE ((void *) 2)
255#define STATE_ERROR ((void *) -1) 255#define STATE_ERROR ((void *) -1)
256#define STATE_TIMEOUT ((void *) -2)
256 257
257/* 258/*
258 * SSP State - Whether Enabled or Disabled 259 * SSP State - Whether Enabled or Disabled
@@ -1484,6 +1485,30 @@ err_config_dma:
1484 writew(irqflags, SSP_IMSC(pl022->virtbase)); 1485 writew(irqflags, SSP_IMSC(pl022->virtbase));
1485} 1486}
1486 1487
1488static void print_current_status(struct pl022 *pl022)
1489{
1490 u32 read_cr0;
1491 u16 read_cr1, read_dmacr, read_sr;
1492
1493 if (pl022->vendor->extended_cr)
1494 read_cr0 = readl(SSP_CR0(pl022->virtbase));
1495 else
1496 read_cr0 = readw(SSP_CR0(pl022->virtbase));
1497 read_cr1 = readw(SSP_CR1(pl022->virtbase));
1498 read_dmacr = readw(SSP_DMACR(pl022->virtbase));
1499 read_sr = readw(SSP_SR(pl022->virtbase));
1500
1501 dev_warn(&pl022->adev->dev, "spi-pl022 CR0: %x\n", read_cr0);
1502 dev_warn(&pl022->adev->dev, "spi-pl022 CR1: %x\n", read_cr1);
1503 dev_warn(&pl022->adev->dev, "spi-pl022 DMACR: %x\n", read_dmacr);
1504 dev_warn(&pl022->adev->dev, "spi-pl022 SR: %x\n", read_sr);
1505 dev_warn(&pl022->adev->dev,
1506 "spi-pl022 exp_fifo_level/fifodepth: %u/%d\n",
1507 pl022->exp_fifo_level,
1508 pl022->vendor->fifodepth);
1509
1510}
1511
1487static void do_polling_transfer(struct pl022 *pl022) 1512static void do_polling_transfer(struct pl022 *pl022)
1488{ 1513{
1489 struct spi_message *message = NULL; 1514 struct spi_message *message = NULL;
@@ -1535,7 +1560,8 @@ static void do_polling_transfer(struct pl022 *pl022)
1535 if (time_after(time, timeout)) { 1560 if (time_after(time, timeout)) {
1536 dev_warn(&pl022->adev->dev, 1561 dev_warn(&pl022->adev->dev,
1537 "%s: timeout!\n", __func__); 1562 "%s: timeout!\n", __func__);
1538 message->state = STATE_ERROR; 1563 message->state = STATE_TIMEOUT;
1564 print_current_status(pl022);
1539 goto out; 1565 goto out;
1540 } 1566 }
1541 cpu_relax(); 1567 cpu_relax();
@@ -1553,6 +1579,8 @@ out:
1553 /* Handle end of message */ 1579 /* Handle end of message */
1554 if (message->state == STATE_DONE) 1580 if (message->state == STATE_DONE)
1555 message->status = 0; 1581 message->status = 0;
1582 else if (message->state == STATE_TIMEOUT)
1583 message->status = -EAGAIN;
1556 else 1584 else
1557 message->status = -EIO; 1585 message->status = -EIO;
1558 1586