diff mbox

[MTD] CHIPS: 0xFF intolerance for M29W128G

Message ID 62cbdcd90908260842l66275d12na133bdb7cc4ac14@mail.gmail.com
State New, archived
Headers show

Commit Message

massimo cirillo Aug. 26, 2009, 3:42 p.m. UTC
From: Massimo Cirillo <maxcir@gmail.com>

The M29W128G Numonyx flash devices are intolerant to any 0xFF command:
in the Cfi_util.c the function cfi_qry_mode_off() (that resets the device
after the autoselect mode) must have a 0xF0 command after the 0xFF command.
Intel-like devices are not influenced by a 0xF0 command.
This fix solves also the cause of the fixup_M29W128G_write_buffer() fix,
that can be commented out now.
The following patch applies to 2.6.30 kernel.

Signed-off-by: Massimo Cirillo <maxcir@gmail.com>
---
--

Comments

Jamie Lokier Aug. 26, 2009, 5:55 p.m. UTC | #1
massimo cirillo wrote:
> From: Massimo Cirillo <maxcir@gmail.com>
> 
> The M29W128G Numonyx flash devices are intolerant to any 0xFF command:
> in the Cfi_util.c the function cfi_qry_mode_off() (that resets the device
> after the autoselect mode) must have a 0xF0 command after the 0xFF command.
> Intel-like devices are not influenced by a 0xF0 command.
> This fix solves also the cause of the fixup_M29W128G_write_buffer() fix,
> that can be commented out now.
> The following patch applies to 2.6.30 kernel.

This change was discussed 1 year ago:

   http://lists.infradead.org/pipermail/linux-mtd/2008-August/022497.html

The conclusion was that 0xf0 after 0xff might not be safe for some
chips ("early revisions of L30"), but nobody could confirm which
chips, so Alexey Korolov suggested staying safe and using fixup
functions.

I'm inclined to think a per-manufacturer (ignoring chip-id) reset
function would be better than the attempt to poke several different
commands at a chip all mixed together in a careful order, knowing that
some commands break some chips but later commands fix them again.

-- Jamie
diff mbox

Patch

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c
b/drivers/mtd/chips/cfi_cmdset_0002.c
old mode 100644
new mode 100755
index 61ea833..5a65e92
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -308,7 +308,7 @@  static struct cfi_fixup cfi_fixup_table[] = {
 	{ CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
 	{ CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
 	{ CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
-	{ CFI_MFR_ST,  0x227E, fixup_M29W128G_write_buffer, NULL, },
+	/*{ CFI_MFR_ST,  0x227E, fixup_M29W128G_write_buffer, NULL, },*/
 #if !FORCE_WORD_WRITE
 	{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
 #endif
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
old mode 100644
new mode 100755
index 34d40e2..9c897f9
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -61,8 +61,8 @@  int __xipram cfi_qry_mode_on(uint32_t base,
 		return 1;
 	/* QRY not found probably we deal with some odd CFI chips */
 	/* Some revisions of some old Intel chips? */
-	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
 	if (cfi_qry_present(map, base, cfi))
 		return 1;
@@ -79,8 +79,11 @@  EXPORT_SYMBOL_GPL(cfi_qry_mode_on);
 void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map,
 			       struct cfi_private *cfi)
 {
-	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
+    /* Numonyx M29W128G requires two 0xF0 to exit succesfully from
+    autoselect mode. No consequences on Intel-like devices. */
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 }
 EXPORT_SYMBOL_GPL(cfi_qry_mode_off);