mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-28 17:48:58 +00:00
62 lines
2.0 KiB
Diff
62 lines
2.0 KiB
Diff
|
From 543618f5388d487ba88e3d5304c161fc3ccf61d1 Mon Sep 17 00:00:00 2001
|
||
|
From: Matthew McClintock <mmcclint@codeaurora.org>
|
||
|
Date: Thu, 10 Mar 2016 16:44:55 -0600
|
||
|
Subject: [PATCH 10/37] 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.
|
||
|
|
||
|
Signed-off-by: Matthew McClintock <mmcclint@codeaurora.org>
|
||
|
---
|
||
|
drivers/spi/spi-qup.c | 15 +++++++++------
|
||
|
1 file changed, 9 insertions(+), 6 deletions(-)
|
||
|
|
||
|
--- a/drivers/spi/spi-qup.c
|
||
|
+++ b/drivers/spi/spi-qup.c
|
||
|
@@ -507,6 +507,7 @@ static irqreturn_t spi_qup_qup_irq(int i
|
||
|
u32 opflags, qup_err, spi_err;
|
||
|
unsigned long flags;
|
||
|
int error = 0;
|
||
|
+ bool done = 0;
|
||
|
|
||
|
spin_lock_irqsave(&controller->lock, flags);
|
||
|
xfer = controller->xfer;
|
||
|
@@ -565,16 +566,19 @@ static irqreturn_t spi_qup_qup_irq(int i
|
||
|
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;
|
||
|
@@ -767,7 +771,6 @@ static int spi_qup_transfer_one(struct s
|
||
|
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);
|