mvebu: fix NAND flash issues (FS#67)
authorFelix Fietkau <nbd@nbd.name>
Sun, 31 Jul 2016 18:30:08 +0000 (20:30 +0200)
committerFelix Fietkau <nbd@nbd.name>
Sun, 31 Jul 2016 18:31:45 +0000 (20:31 +0200)
Remove the previous PIO delay patch and add a revert patch for a faulty
upstream commit, which seems to have introduced this issue in the first
place

Signed-off-by: Felix Fietkau <nbd@nbd.name>
target/linux/mvebu/patches-4.4/110-pxa3xxx_nand-handle-PIO-delays.patch [deleted file]
target/linux/mvebu/patches-4.4/110-pxa3xxx_revert_irq_thread.patch [new file with mode: 0644]

diff --git a/target/linux/mvebu/patches-4.4/110-pxa3xxx_nand-handle-PIO-delays.patch b/target/linux/mvebu/patches-4.4/110-pxa3xxx_nand-handle-PIO-delays.patch
deleted file mode 100644 (file)
index 7fa5697..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-Handle delays/excessive latency during flash command processing with PIO.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-
---- a/drivers/mtd/nand/pxa3xx_nand.c
-+++ b/drivers/mtd/nand/pxa3xx_nand.c
-@@ -227,6 +227,7 @@ struct pxa3xx_nand_info {
-       int                     use_dma;        /* use DMA ? */
-       int                     use_spare;      /* use spare ? */
-       int                     need_wait;
-+      int                     pio_progress;
-       /* Amount of real data per full chunk */
-       unsigned int            chunk_size;
-@@ -769,6 +770,7 @@ static irqreturn_t pxa3xx_nand_irq_threa
- {
-       struct pxa3xx_nand_info *info = data;
-+      info->pio_progress = 1;
-       handle_data_pio(info);
-       info->state = STATE_CMD_DONE;
-@@ -1175,8 +1177,13 @@ static void nand_cmdfunc(struct mtd_info
-               info->need_wait = 1;
-               pxa3xx_nand_start(info);
-+retry:
-+              info->pio_progress = 0;
-               if (!wait_for_completion_timeout(&info->cmd_complete,
-                   CHIP_DELAY_TIMEOUT)) {
-+                      if (info->pio_progress)
-+                          goto retry;
-+
-                       dev_err(&info->pdev->dev, "Wait time out!!!\n");
-                       /* Stop State Machine for next command cycle */
-                       pxa3xx_nand_stop(info);
diff --git a/target/linux/mvebu/patches-4.4/110-pxa3xxx_revert_irq_thread.patch b/target/linux/mvebu/patches-4.4/110-pxa3xxx_revert_irq_thread.patch
new file mode 100644 (file)
index 0000000..30da17d
--- /dev/null
@@ -0,0 +1,69 @@
+Revert "mtd: pxa3xx-nand: handle PIO in threaded interrupt"
+
+This reverts commit 24542257a3b987025d4b998ec2d15e556c98ad3f
+This upstream change has been causing spurious timeouts on accesses
+to the NAND flash if something else on the system is causing
+significant latency.
+
+Nothing guarantees that the thread will run in time, so the
+usual timeout is unreliable.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -765,24 +765,11 @@ static void start_data_dma(struct pxa3xx
+               __func__, direction, info->dma_cookie, info->sg.length);
+ }
+-static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data)
+-{
+-      struct pxa3xx_nand_info *info = data;
+-
+-      handle_data_pio(info);
+-
+-      info->state = STATE_CMD_DONE;
+-      nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ);
+-
+-      return IRQ_HANDLED;
+-}
+-
+ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
+ {
+       struct pxa3xx_nand_info *info = devid;
+       unsigned int status, is_completed = 0, is_ready = 0;
+       unsigned int ready, cmd_done;
+-      irqreturn_t ret = IRQ_HANDLED;
+       if (info->cs == 0) {
+               ready           = NDSR_FLASH_RDY;
+@@ -824,8 +811,7 @@ static irqreturn_t pxa3xx_nand_irq(int i
+               } else {
+                       info->state = (status & NDSR_RDDREQ) ?
+                                     STATE_PIO_READING : STATE_PIO_WRITING;
+-                      ret = IRQ_WAKE_THREAD;
+-                      goto NORMAL_IRQ_EXIT;
++                      handle_data_pio(info);
+               }
+       }
+       if (status & cmd_done) {
+@@ -870,7 +856,7 @@ static irqreturn_t pxa3xx_nand_irq(int i
+       if (is_ready)
+               complete(&info->dev_ready);
+ NORMAL_IRQ_EXIT:
+-      return ret;
++      return IRQ_HANDLED;
+ }
+ static inline int is_buf_blank(uint8_t *buf, size_t len)
+@@ -1849,9 +1835,7 @@ static int alloc_nand_resource(struct pl
+       /* initialize all interrupts to be disabled */
+       disable_int(info, NDSR_MASK);
+-      ret = request_threaded_irq(irq, pxa3xx_nand_irq,
+-                                 pxa3xx_nand_irq_thread, IRQF_ONESHOT,
+-                                 pdev->name, info);
++      ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to request IRQ\n");
+               goto fail_free_buf;