d7e4b9babb
Signed-off-by: John Crispin <john@phrozen.org>
67 lines
2.2 KiB
Diff
67 lines
2.2 KiB
Diff
From b69e5e855aaae2dd9f7fc6f4a40af8e6e0cf98ee Mon Sep 17 00:00:00 2001
|
|
From: Matthew McClintock <mmcclint@codeaurora.org>
|
|
Date: Thu, 10 Mar 2016 16:44:55 -0600
|
|
Subject: [PATCH] spi: qup: properly detect extra interrupts
|
|
|
|
It's possible for a SPI transaction to complete and get another
|
|
interrupt and have it processed on the same spi_transfer before the
|
|
transfer_one can set it to NULL.
|
|
|
|
This masks unexpected interrupts, so let's set the spi_transfer to
|
|
NULL in the interrupt once the transaction is done. So we can
|
|
properly detect these bad interrupts and print warning messages.
|
|
|
|
Change-Id: I0e70ed59fb50e5c48a72a38f74bd178b17c9f24d
|
|
Signed-off-by: Matthew McClintock <mmcclint@codeaurora.org>
|
|
---
|
|
drivers/spi/spi-qup.c | 15 +++++++++------
|
|
1 file changed, 9 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
|
|
index e487416..45e30c7 100644
|
|
--- a/drivers/spi/spi-qup.c
|
|
+++ b/drivers/spi/spi-qup.c
|
|
@@ -509,6 +509,7 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
|
|
u32 opflags, qup_err, spi_err;
|
|
unsigned long flags;
|
|
int error = 0;
|
|
+ bool done = 0;
|
|
|
|
spin_lock_irqsave(&controller->lock, flags);
|
|
xfer = controller->xfer;
|
|
@@ -567,16 +568,19 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
|
|
spi_qup_write(controller, xfer);
|
|
}
|
|
|
|
- spin_lock_irqsave(&controller->lock, flags);
|
|
- controller->error = error;
|
|
- controller->xfer = xfer;
|
|
- spin_unlock_irqrestore(&controller->lock, flags);
|
|
-
|
|
/* re-read opflags as flags may have changed due to actions above */
|
|
opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
|
|
|
|
if ((controller->rx_bytes == xfer->len &&
|
|
(opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) || error)
|
|
+ done = true;
|
|
+
|
|
+ spin_lock_irqsave(&controller->lock, flags);
|
|
+ controller->error = error;
|
|
+ controller->xfer = done ? NULL : xfer;
|
|
+ spin_unlock_irqrestore(&controller->lock, flags);
|
|
+
|
|
+ if (done)
|
|
complete(&controller->done);
|
|
|
|
return IRQ_HANDLED;
|
|
@@ -769,7 +773,6 @@ static int spi_qup_transfer_one(struct spi_master *master,
|
|
exit:
|
|
spi_qup_set_state(controller, QUP_STATE_RESET);
|
|
spin_lock_irqsave(&controller->lock, flags);
|
|
- controller->xfer = NULL;
|
|
if (!ret)
|
|
ret = controller->error;
|
|
spin_unlock_irqrestore(&controller->lock, flags);
|
|
--
|
|
2.7.2
|
|
|