summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Agner <stefan@agner.ch>2015-09-01 10:03:33 -0700
committerStefan Agner <stefan@agner.ch>2015-09-01 10:03:33 -0700
commitc303ef128309236cf5d62567a9f120451b3cce9a (patch)
treececc771a64f060ce49d96dcd90fc62abbc0b1c86
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...
-rw-r--r--drivers/mtd/nand/vf610_nfc.c7
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");
+
vf610_nfc_clear_status(nfc);
}