Thread (34 messages) 34 messages, 6 authors, 2017-08-08
STALE3271d
Revisions (6)
  1. v1 current
  2. v1 [diff vs current]
  3. v3 [diff vs current]
  4. v4 [diff vs current]
  5. v5 [diff vs current]
  6. v6 [diff vs current]

[PATCH 10/18] spi: qup: Fix DMA mode interrupt handling

From: Varadarajan Narayanan <hidden>
Date: 2017-06-14 05:53:55
Also in: linux-arm-msm, linux-spi, lkml
Subsystem: arm/qualcomm mailing list, spi subsystem, the rest · Maintainers: Mark Brown, Linus Torvalds

This is needed for v1, where the i/o completion is not
handled in the dma driver.

Signed-off-by: Andy Gross <redacted>
Signed-off-by: Varadarajan Narayanan <redacted>
---
 drivers/spi/spi-qup.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index 872de28..bd53e82 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -510,9 +510,9 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
 
 	writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS);
 	writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS);
-	writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
 
 	if (!xfer) {
+		writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
 		dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n",
 				    qup_err, spi_err, opflags);
 		return IRQ_HANDLED;
@@ -540,7 +540,15 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
 		error = -EIO;
 	}
 
-	if (!spi_qup_is_dma_xfer(controller->mode)) {
+	if (spi_qup_is_dma_xfer(controller->mode)) {
+		writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
+		if (opflags & QUP_OP_IN_SERVICE_FLAG &&
+		    opflags & QUP_OP_MAX_INPUT_DONE_FLAG)
+			complete(&controller->rxc);
+		if (opflags & QUP_OP_OUT_SERVICE_FLAG &&
+		    opflags & QUP_OP_MAX_OUTPUT_DONE_FLAG)
+			complete(&controller->txc);
+	} else {
 		if (opflags & QUP_OP_IN_SERVICE_FLAG)
 			spi_qup_read(controller, xfer);
 
@@ -553,6 +561,9 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
 	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)
 		complete(&controller->done);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help