Seen on ase platform.
Fifos should be flushed if there is data, otherwise it hangs.
Root cause was then seen to be rx overflow, so reduced max rxreq.
Fifos on ase are smaller and perhaps are the cause, so it's open to review
whether this should be specific to ase or all xway.


Signed-off-by: Conor O'Gorman <i...@conorogorman.net>
---
 .../304-fix-spi-xway-wait-ready-timed-out.patch    |   51 ++++++++++++++++++++
 1 files changed, 51 insertions(+), 0 deletions(-)
 create mode 100644 
target/linux/lantiq/patches-3.2/304-fix-spi-xway-wait-ready-timed-out.patch

diff --git 
a/target/linux/lantiq/patches-3.2/304-fix-spi-xway-wait-ready-timed-out.patch 
b/target/linux/lantiq/patches-3.2/304-fix-spi-xway-wait-ready-timed-out.patch
new file mode 100644
index 0000000..2fc4b9b
--- /dev/null
+++ 
b/target/linux/lantiq/patches-3.2/304-fix-spi-xway-wait-ready-timed-out.patch
@@ -0,0 +1,51 @@
+--- a/drivers/spi/spi-xway.c
++++ b/drivers/spi/spi-xway.c
+@@ -272,6 +272,7 @@ static void ltq_spi_reset_fifos(struct l
+ static inline int ltq_spi_wait_ready(struct ltq_spi *hw)
+ {
+       u32 stat;
++      u32 fill;
+       unsigned long timeout;
+ 
+       timeout = jiffies + msecs_to_jiffies(200);
+@@ -281,10 +282,16 @@ static inline int ltq_spi_wait_ready(str
+               if (!(stat & LTQ_SPI_STAT_BSY))
+                       return 0;
+ 
++              fill = ltq_spi_reg_read(hw, LTQ_SPI_FSTAT);
++              if (fill) {
++                      /* help it along with a flush */
++                      ltq_spi_reg_setbit(hw, LTQ_SPI_RXFCON_RXFLU, 
LTQ_SPI_RXFCON);
++                      ltq_spi_reg_setbit(hw, LTQ_SPI_TXFCON_TXFLU, 
LTQ_SPI_TXFCON);
++              }
+               cond_resched();
+       } while (!time_after_eq(jiffies, timeout));
+ 
+-      dev_err(hw->dev, "SPI wait ready timed out stat: %x\n", stat);
++      dev_err(hw->dev, "SPI wait ready timed out %x\n", stat);
+ 
+       return -ETIMEDOUT;
+ }
+@@ -729,11 +736,11 @@ static void ltq_spi_rxreq_set(struct ltq
+        * In RX-only mode the serial clock is activated only after writing
+        * the expected amount of RX bytes into RXREQ register.
+        * To avoid receive overflows at high clocks it is better to request
+-       * only the amount of bytes that fits into all FIFOs. This value
++       * less than the amount of bytes that fits into all FIFOs. This value
+        * depends on the FIFO size implemented in hardware.
+        */
+       rxreq = hw->len - hw->rx_cnt;
+-      rxreq_max = hw->rxfs << 2;
++      rxreq_max = (hw->rxfs-1) << 2;
+       rxreq = min(rxreq_max, rxreq);
+ 
+       if (!rxtodo && rxreq)
+@@ -805,6 +812,8 @@ irqreturn_t ltq_spi_err_irq(int irq, voi
+       /* Disable all interrupts */
+       ltq_spi_reg_clearbit(hw, LTQ_SPI_IRNEN_ALL, LTQ_SPI_IRNEN);
+ 
++      dev_err(hw->dev, "error %x\n", ltq_spi_reg_read(hw, LTQ_SPI_STAT));
++
+       /* Clear all error flags */
+       ltq_spi_reg_write(hw, LTQ_SPI_WHBSTATE_CLR_ERRORS, LTQ_SPI_WHBSTATE);
+ 
-- 
1.7.4.1

_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to