From c303ef128309236cf5d62567a9f120451b3cce9a Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 1 Sep 2015 10:03:33 -0700 Subject: mtd: nand: vf610_nfc: unconditionally wait for interrupt Always wait for idle interrupt. This avoids a race condition: The interrupt may fire between setting and checking the idle bit. So the IRQ handler will increment the completion struct (cmd_done), but won't be doing the corresponding decrement via wait_for_completion(). The subsequent wait_for_completion() will immediately succeed, the upper layers then read out the old page buffer (again). This explains the pattern observed in various tests which showed data of the same page twice instead of two consecutive pages... --- drivers/mtd/nand/vf610_nfc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 14f51c88c0f9..b56b8540917a 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -264,10 +264,9 @@ static void vf610_nfc_done(struct vf610_nfc *nfc) vf610_nfc_set(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT); vf610_nfc_set(nfc, NFC_FLASH_CMD2, START_BIT); - if (!(vf610_nfc_read(nfc, NFC_IRQ_STATUS) & IDLE_IRQ_BIT)) { - if (!wait_for_completion_timeout(&nfc->cmd_done, timeout)) - dev_warn(nfc->dev, "Timeout while waiting for BUSY.\n"); - } + if (!wait_for_completion_timeout(&nfc->cmd_done, timeout)) + dev_warn(nfc->dev, "Timeout while waiting for BUSY.\n"); + vf610_nfc_clear_status(nfc); } -- cgit v1.2.3