Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
[pandora-kernel.git] / drivers / mtd / chips / cfi_probe.c
index e63e674..b2acd32 100644 (file)
@@ -158,6 +158,7 @@ static int __xipram cfi_chip_setup(struct map_info *map,
        __u32 base = 0;
        int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
        int i;
+       int addr_unlock1 = 0x555, addr_unlock2 = 0x2AA;
 
        xip_enable(base, map, cfi);
 #ifdef DEBUG_CFI
@@ -181,29 +182,6 @@ static int __xipram cfi_chip_setup(struct map_info *map,
        for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
                ((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
 
-       /* Note we put the device back into Read Mode BEFORE going into Auto
-        * Select Mode, as some devices support nesting of modes, others
-        * don't. This way should always work.
-        * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
-        * so should be treated as nops or illegal (and so put the device
-        * back into Read Mode, which is a nop in this case).
-        */
-       cfi_send_gen_cmd(0xf0,     0, base, map, cfi, cfi->device_type, NULL);
-       cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
-       cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
-       cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
-       cfi->mfr = cfi_read_query16(map, base);
-       cfi->id = cfi_read_query16(map, base + ofs_factor);
-
-       /* Get AMD/Spansion extended JEDEC ID */
-       if (cfi->mfr == CFI_MFR_AMD && (cfi->id & 0xff) == 0x7e)
-               cfi->id = cfi_read_query(map, base + 0xe * ofs_factor) << 8 |
-                         cfi_read_query(map, base + 0xf * ofs_factor);
-
-       /* Put it back into Read Mode */
-       cfi_qry_mode_off(base, map, cfi);
-       xip_allowed(base, map);
-
        /* Do any necessary byteswapping */
        cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID);
 
@@ -228,6 +206,35 @@ static int __xipram cfi_chip_setup(struct map_info *map,
 #endif
        }
 
+       if (cfi->cfiq->P_ID == P_ID_SST_OLD) {
+               addr_unlock1 = 0x5555;
+               addr_unlock2 = 0x2AAA;
+       }
+
+       /*
+        * Note we put the device back into Read Mode BEFORE going into Auto
+        * Select Mode, as some devices support nesting of modes, others
+        * don't. This way should always work.
+        * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
+        * so should be treated as nops or illegal (and so put the device
+        * back into Read Mode, which is a nop in this case).
+        */
+       cfi_send_gen_cmd(0xf0,     0, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0xaa, addr_unlock1, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x55, addr_unlock2, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x90, addr_unlock1, base, map, cfi, cfi->device_type, NULL);
+       cfi->mfr = cfi_read_query16(map, base);
+       cfi->id = cfi_read_query16(map, base + ofs_factor);
+
+       /* Get AMD/Spansion extended JEDEC ID */
+       if (cfi->mfr == CFI_MFR_AMD && (cfi->id & 0xff) == 0x7e)
+               cfi->id = cfi_read_query(map, base + 0xe * ofs_factor) << 8 |
+                         cfi_read_query(map, base + 0xf * ofs_factor);
+
+       /* Put it back into Read Mode */
+       cfi_qry_mode_off(base, map, cfi);
+       xip_allowed(base, map);
+
        printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
               map->name, cfi->interleave, cfi->device_type*8, base,
               map->bankwidth*8);
@@ -269,6 +276,9 @@ static char *vendorname(__u16 vendor)
        case P_ID_SST_PAGE:
                return "SST Page Write";
 
+       case P_ID_SST_OLD:
+               return "SST 39VF160x/39VF320x";
+
        case P_ID_INTEL_PERFORMANCE:
                return "Intel Performance Code";