diff options
author | Stefan Agner <stefan@agner.ch> | 2015-09-01 10:03:33 -0700 |
---|---|---|
committer | Stefan Agner <stefan@agner.ch> | 2015-09-01 10:03:33 -0700 |
commit | c303ef128309236cf5d62567a9f120451b3cce9a (patch) | |
tree | cecc771a64f060ce49d96dcd90fc62abbc0b1c86 /drivers/mtd/nand | |
parent | f0a5b778a1676bed3d9760823bfeb2b18aee74f4 (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...
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/vf610_nfc.c | 7 |
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); } |