diff options
authorStefan Agner <>2015-09-01 10:03:33 -0700
committerStefan Agner <>2015-09-01 10:03:33 -0700
commitc303ef128309236cf5d62567a9f120451b3cce9a (patch)
parentf0a5b778a1676bed3d9760823bfeb2b18aee74f4 (diff)
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...
1 files 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");