ath79: fix jffs2 read fail issue for TP-Link TL-WR2543N
You shouldn't need to modify spi-nor at all, and rather let the spi-ath79 driver set a maximum message length (see the max_message_size() callback) (based on a property).
The spi-nor driver then should do the right thing and split reads automatically.
You shouldn't need to modify spi-nor at all, and rather let the spi-ath79 driver set a maximum message length (see the
max_message_size()callback) (based on a property).The spi-nor driver then should do the right thing and split reads automatically.
Hi! Thanks for your review. I've tried limit the max_message_size/max_transfer_size on ath79-spi driver today. It does indeed reduce the size of a single read operation, but it cannot fix this issue. This problem seems to be caused by the capacitor taking some time to charge? So it requires some delay time? But strangely, even though I inserted same delay in ath79-spi spi-mem read function, it still couldn't work properly.
I decided not to touch the current patch. In the last attempt, I bricked this device, and recently I don't really want to teardown it to attach TTL.
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -20,6 +20,8 @@
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/limits.h>
+#include <linux/of.h>
#define DRV_NAME "ath79-spi"
@@ -41,6 +43,7 @@ struct ath79_spi {
struct spi_bitbang bitbang;
u32 ioc_base;
u32 reg_ctrl;
+ u32 max_message_size;
void __iomem *base;
struct clk *clk;
unsigned int rrw_delay;
@@ -105,6 +108,14 @@ static void ath79_spi_disable(struct ath79_spi *sp)
ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
}
+static size_t ath79_spi_max_message_size(struct spi_device *spi)
+{
+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+
+ WARN_ONCE("max_message_size %u\n", sp->max_message_size);
+ return sp->max_message_size; // ? sp->max_message_size : SIZE_MAX;
+}
+
static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned int nsecs,
u32 word, u8 bits, unsigned flags)
{
@@ -151,6 +162,11 @@ static int ath79_exec_mem_op(struct spi_mem *mem,
/* disable GPIO mode */
ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
+ if (sp->max_message_size) {
+ WARN_ONCE(1, "nbytes %u\n", op->data.nbytes);
+ usleep_range(10, 20);
+ }
+
memcpy_fromio(op->data.buf.in, sp->base + op->addr.val, op->data.nbytes);
/* enable GPIO mode */
@@ -188,6 +204,8 @@ static int ath79_spi_probe(struct platform_device *pdev)
master->flags = SPI_MASTER_GPIO_SS;
master->num_chipselect = 3;
master->mem_ops = &ath79_mem_ops;
+ master->max_transfer_size = ath79_spi_max_message_size;
+ master->max_message_size = ath79_spi_max_message_size;
sp->bitbang.master = master;
sp->bitbang.chipselect = ath79_spi_chipselect;
@@ -220,6 +238,12 @@ static int ath79_spi_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n",
sp->rrw_delay);
+ sp->max_message_size = 0;
+ if (!of_property_read_u32(pdev->dev.of_node, "max-message-size",
+ &sp->max_message_size))
+ dev_info(&pdev->dev, "set max spi message size to %u\n",
+ sp->max_message_size);
+
ath79_spi_enable(sp);
ret = spi_bitbang_start(&sp->bitbang);
if (ret)