From patchwork Mon Jun 18 07:24:38 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [RFC, 1/2] mtd: cfi_cmdset_0002: Micron M29EW bugfix "Correcting Erase Suspend Hang Ups" Date: Sun, 17 Jun 2012 21:24:38 -0000 From: Gerlando Falauto X-Patchwork-Id: 165408 Message-Id: <1340004279-26496-2-git-send-email-gerlando.falauto@keymile.com> To: linux-mtd@lists.infradead.org Cc: Holger Brunck , Leo , Stefan Bigler , Gerlando Falauto >From TN-13-07: Patching the Linux Kernel and U-Boot for M29 Flash, page 20: Some revisions of the M29EW suffer from erase suspend hang ups. In particular, it can occur when the sequence Erase Confirm -> Suspend -> Program -> Resume causes a lockup due to internal timing issues. The consequence is that the erase cannot be resumed without inserting a dummy command after programming and prior to resuming. [...] The work-around is to issue a dummy write cycle that writes an F0 command code before the RESUME command. Signed-off-by: Stefan Bigler Signed-off-by: Gerlando Falauto Cc: Holger Brunck Cc: Leo --- drivers/mtd/chips/cfi_cmdset_0002.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 23175ed..72f6164 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -761,6 +761,11 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad switch(chip->oldstate) { case FL_ERASING: + /* before resume, insert a dummy 0xF0 cycle for Micron M29EW devices */ + if ( (cfi->mfr == 0x0089) && + (((cfi->device_type == CFI_DEVICETYPE_X8) && ((cfi->id & 0xff)== 0x7e)) + || ((cfi->device_type == CFI_DEVICETYPE_X16) && (cfi->id == 0x227e))) ) + map_write(map, CMD(0xF0), chip->in_progress_block_addr); map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr); chip->oldstate = FL_READY; chip->state = FL_ERASING; @@ -904,6 +909,12 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip, local_irq_disable(); /* Resume the write or erase operation */ + /* before resume, insert a dummy 0xF0 cycle for Micron M29EW devices */ + if ( (cfi->mfr == 0x0089) && + (((cfi->device_type == CFI_DEVICETYPE_X8) && ((cfi->id & 0xff)== 0x7e)) + || ((cfi->device_type == CFI_DEVICETYPE_X16) && (cfi->id == 0x227e))) ) + map_write(map, CMD(0xF0), adr); + map_write(map, cfi->sector_erase_cmd, adr); chip->state = oldstate; start = xip_currtime();