[OpenWrt-Devel] [PATCH] ipq806x: fix spi read issues observed with SMP enabled

Mathieu Olivari mathieu at codeaurora.org
Mon Feb 23 23:36:23 EST 2015


This change is fixing the issues observed when booting from NOR flash
with SMP enabled.

Error logs below:
building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of
xref (0 dead, 0 orphan) found.
m25p80 spi32766.0: SPI transfer failed: -110
spi_master spi32766: failed to transfer one message from queue
jffs2: Write of 873 bytes at 0x019001e8 failed. returned 0, retlen 792

Patch is cherry-picked from here:
https://www.codeaurora.org/cgit/quic/qsdk/oss/kernel/linux-msm/commit/drivers/spi/spi-qup.c?h=coconut_20140924&id=4faba89e3ffbb1c5f6232651375b9b3212b50f02

More details in the patch file.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 .../003-spi-qup-Ensure-done-detection.patch        | 56 ++++++++++++++++++++++
 1 file changed, 56 insertions(+)
 create mode 100644 target/linux/ipq806x/patches/003-spi-qup-Ensure-done-detection.patch

diff --git a/target/linux/ipq806x/patches/003-spi-qup-Ensure-done-detection.patch b/target/linux/ipq806x/patches/003-spi-qup-Ensure-done-detection.patch
new file mode 100644
index 0000000..7052227
--- /dev/null
+++ b/target/linux/ipq806x/patches/003-spi-qup-Ensure-done-detection.patch
@@ -0,0 +1,56 @@
+From 4faba89e3ffbb1c5f6232651375b9b3212b50f02 Mon Sep 17 00:00:00 2001
+From: Andy Gross <agross at codeaurora.org>
+Date: Thu, 15 Jan 2015 17:56:02 -0800
+Subject: [PATCH] spi: qup: Ensure done detection
+
+This patch fixes an issue where a SPI transaction has completed, but the done
+condition is missed.  This occurs because at the time of interrupt the
+MAX_INPUT_DONE_FLAG is not asserted.  However, in the process of reading blocks
+of data from the FIFO, the last portion of data comes in.
+
+The opflags read at the beginning of the irq handler no longer matches the
+current opflag state.  To get around this condition, the block read function
+should update the opflags so that done detection is correct after the return.
+
+Change-Id: If109e0eeb432f96000d765c4b34dbb2269f8093f
+Signed-off-by: Andy Gross <agross at codeaurora.org>
+---
+ drivers/spi/spi-qup.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -298,7 +298,7 @@ static void spi_qup_fifo_write(struct sp
+ }
+ 
+ static void spi_qup_block_read(struct spi_qup *controller,
+-	struct spi_transfer *xfer)
++	struct spi_transfer *xfer, u32 *opflags)
+ {
+ 	u32 data;
+ 	u32 reads_per_blk = controller->in_blk_sz >> 2;
+@@ -327,10 +327,12 @@ static void spi_qup_block_read(struct sp
+ 
+ 	/*
+ 	 * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
+-	 * reads, it has to be cleared again at the very end
++	 * reads, it has to be cleared again at the very end.  However, be sure
++	 * to refresh opflags value because MAX_INPUT_DONE_FLAG may now be
++	 * present and this is used to determine if transaction is complete
+ 	 */
+-	if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
+-		QUP_OP_MAX_INPUT_DONE_FLAG)
++	*opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
++	if (*opflags & QUP_OP_MAX_INPUT_DONE_FLAG)
+ 		writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
+ 			controller->base + QUP_OPERATIONAL);
+ 
+@@ -633,7 +635,7 @@ static irqreturn_t spi_qup_qup_irq(int i
+ 	if (!controller->use_dma) {
+ 		if (opflags & QUP_OP_IN_SERVICE_FLAG) {
+ 			if (opflags & QUP_OP_IN_BLOCK_READ_REQ)
+-				spi_qup_block_read(controller, xfer);
++				spi_qup_block_read(controller, xfer, &opflags);
+ 			else
+ 				spi_qup_fifo_read(controller, xfer);
+ 		}
-- 
1.9.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list