public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] mtd: nand: pxa3xx-nand: fix random command timeouts
@ 2015-08-12 16:22 Robert Jarzmik
  2015-08-16 15:29 ` Ezequiel Garcia
  0 siblings, 1 reply; 7+ messages in thread
From: Robert Jarzmik @ 2015-08-12 16:22 UTC (permalink / raw)
  To: Ezequiel Garcia, David Woodhouse, Brian Norris
  Cc: linux-mtd, linux-kernel, Robert Jarzmik

When 2 commands are submitted in a row, and the second is very quick,
the completion of the second command might never come. This happens
especially if the second command is quick, such as a status read after
an erase.

The issue is that in the interrupt handler, the status bits are cleared
after the new command is issued. There is a small temporal window where
this happens :
 - the previous command has set the command done bit
 - the ready for a command bit is set
 - the handler submits the next command
   - just then, the command completes, and the command done bit is still
     set
 - the handler clears the "previous" command done bit
 - the handler exits

In this flow, the "command done" of the next command will never trigger
a new interrupt to finish the status command, as it was cleared for both
commands.

Fix this by clearing the status bit before submitting a new command.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/mtd/nand/pxa3xx_nand.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index b0737aec7caf..718097414b9c 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -687,8 +687,10 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 		is_ready = 1;
 	}
 
+	/* clear NDSR to let the controller exit the IRQ */
+	nand_writel(info, NDSR, status);
+
 	if (status & NDSR_WRCMDREQ) {
-		nand_writel(info, NDSR, NDSR_WRCMDREQ);
 		status &= ~NDSR_WRCMDREQ;
 		info->state = STATE_CMD_HANDLE;
 
@@ -709,8 +711,6 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 			nand_writel(info, NDCB0, info->ndcb3);
 	}
 
-	/* clear NDSR to let the controller exit the IRQ */
-	nand_writel(info, NDSR, status);
 	if (is_completed)
 		complete(&info->cmd_complete);
 	if (is_ready)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-08-19  6:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-12 16:22 [PATCH] mtd: nand: pxa3xx-nand: fix random command timeouts Robert Jarzmik
2015-08-16 15:29 ` Ezequiel Garcia
2015-08-16 22:18   ` Robert Jarzmik
2015-08-17 19:09     ` Ezequiel Garcia
2015-08-17 19:15       ` Robert Jarzmik
2015-08-19  0:46         ` Brian Norris
2015-08-19  6:22           ` Robert Jarzmik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox