summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Nordgard-Hansen <hhansen@pvv.org>2012-11-23 23:11:03 +0100
committerHuang Shijie <b32955@freescale.com>2013-04-11 13:55:05 +0800
commitdc5e48a118558ba1964c6b69ffa307f15197dde3 (patch)
treebddd878ba68187e3504bcc89f2e9025ff2ea07ba
parent47287442d981a3d86c272226e4fe2222a78cf5d3 (diff)
mtd: fix recovery after failed write-buffer operation in cfi_cmdset_0002.c
When working on a problem with some flash chips that lock up during write-buffer operations, I think there may be a bug in the linux handling of chips using cfi_cmdset_0002.c. The datasheets I have found for a number of these chips all specify that when aborting a write-buffer command, it is not enough to use the standard reset. Rather a "write-to-buffer-reset command" is needed. This command is quite similar for all chips, the main variance seem to be if the final 0xF0 can go to any address or must go to addr_unlock1. The bug is then in the recovery handling when timing out at the end of do_write_buffer, where using the normal reset command is not sufficient. Without this change, if the write-buffer command fails then any following operations on the flash also fail. Signed-off-by: Harald Nordgard-Hansen <hhansen@pvv.org> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: Huang Shijie <b32955@freescale.com>
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 7e5564e9e759..a35416cbdbb4 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1549,8 +1549,20 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
UDELAY(map, chip, adr, 1);
}
- /* reset on all failures. */
- map_write( map, CMD(0xF0), chip->start );
+ /*
+ * Recovery from write-buffer programming failures requires
+ * the write-to-buffer-reset sequence. Since the last part
+ * of the sequence also works as a normal reset, we can run
+ * the same commands regardless of why we are here.
+ * See e.g.
+ * http://www.spansion.com/Support/Application%20Notes/MirrorBit_Write_Buffer_Prog_Page_Buffer_Read_AN.pdf
+ */
+ cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
+ cfi->device_type, NULL);
+ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi,
+ cfi->device_type, NULL);
+ cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, chip->start, map, cfi,
+ cfi->device_type, NULL);
xip_enable(map, chip, adr);
/* FIXME - should have reset delay before continuing */