aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/chips
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/mtd/chips
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/mtd/chips')
-rw-r--r--drivers/mtd/chips/Kconfig2
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c112
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c192
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c2
-rw-r--r--drivers/mtd/chips/cfi_probe.c2
-rw-r--r--drivers/mtd/chips/cfi_util.c11
-rw-r--r--drivers/mtd/chips/fwh_lock.h2
-rw-r--r--drivers/mtd/chips/jedec_probe.c37
8 files changed, 191 insertions, 169 deletions
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index 35c6a23b183b..b1e3c26edd6d 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -19,7 +19,7 @@ config MTD_JEDECPROBE
19 help 19 help
20 This option enables JEDEC-style probing of flash chips which are not 20 This option enables JEDEC-style probing of flash chips which are not
21 compatible with the Common Flash Interface, but will use the common 21 compatible with the Common Flash Interface, but will use the common
22 CFI-targetted flash drivers for any chips which are identified which 22 CFI-targeted flash drivers for any chips which are identified which
23 are in fact compatible in all but the probe method. This actually 23 are in fact compatible in all but the probe method. This actually
24 covers most AMD/Fujitsu-compatible chips and also non-CFI 24 covers most AMD/Fujitsu-compatible chips and also non-CFI
25 Intel chips. 25 Intel chips.
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 9e2b7e9e0ad9..e1e122f2f929 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -162,7 +162,7 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
162#endif 162#endif
163 163
164/* Atmel chips don't use the same PRI format as Intel chips */ 164/* Atmel chips don't use the same PRI format as Intel chips */
165static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) 165static void fixup_convert_atmel_pri(struct mtd_info *mtd)
166{ 166{
167 struct map_info *map = mtd->priv; 167 struct map_info *map = mtd->priv;
168 struct cfi_private *cfi = map->fldrv_priv; 168 struct cfi_private *cfi = map->fldrv_priv;
@@ -202,7 +202,7 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
202 cfi->cfiq->BufWriteTimeoutMax = 0; 202 cfi->cfiq->BufWriteTimeoutMax = 0;
203} 203}
204 204
205static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param) 205static void fixup_at49bv640dx_lock(struct mtd_info *mtd)
206{ 206{
207 struct map_info *map = mtd->priv; 207 struct map_info *map = mtd->priv;
208 struct cfi_private *cfi = map->fldrv_priv; 208 struct cfi_private *cfi = map->fldrv_priv;
@@ -214,7 +214,7 @@ static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param)
214 214
215#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE 215#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
216/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ 216/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
217static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) 217static void fixup_intel_strataflash(struct mtd_info *mtd)
218{ 218{
219 struct map_info *map = mtd->priv; 219 struct map_info *map = mtd->priv;
220 struct cfi_private *cfi = map->fldrv_priv; 220 struct cfi_private *cfi = map->fldrv_priv;
@@ -227,7 +227,7 @@ static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
227#endif 227#endif
228 228
229#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND 229#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
230static void fixup_no_write_suspend(struct mtd_info *mtd, void* param) 230static void fixup_no_write_suspend(struct mtd_info *mtd)
231{ 231{
232 struct map_info *map = mtd->priv; 232 struct map_info *map = mtd->priv;
233 struct cfi_private *cfi = map->fldrv_priv; 233 struct cfi_private *cfi = map->fldrv_priv;
@@ -240,7 +240,7 @@ static void fixup_no_write_suspend(struct mtd_info *mtd, void* param)
240} 240}
241#endif 241#endif
242 242
243static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param) 243static void fixup_st_m28w320ct(struct mtd_info *mtd)
244{ 244{
245 struct map_info *map = mtd->priv; 245 struct map_info *map = mtd->priv;
246 struct cfi_private *cfi = map->fldrv_priv; 246 struct cfi_private *cfi = map->fldrv_priv;
@@ -249,7 +249,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
249 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ 249 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */
250} 250}
251 251
252static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param) 252static void fixup_st_m28w320cb(struct mtd_info *mtd)
253{ 253{
254 struct map_info *map = mtd->priv; 254 struct map_info *map = mtd->priv;
255 struct cfi_private *cfi = map->fldrv_priv; 255 struct cfi_private *cfi = map->fldrv_priv;
@@ -259,7 +259,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param)
259 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; 259 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
260}; 260};
261 261
262static void fixup_use_point(struct mtd_info *mtd, void *param) 262static void fixup_use_point(struct mtd_info *mtd)
263{ 263{
264 struct map_info *map = mtd->priv; 264 struct map_info *map = mtd->priv;
265 if (!mtd->point && map_is_linear(map)) { 265 if (!mtd->point && map_is_linear(map)) {
@@ -268,7 +268,7 @@ static void fixup_use_point(struct mtd_info *mtd, void *param)
268 } 268 }
269} 269}
270 270
271static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) 271static void fixup_use_write_buffers(struct mtd_info *mtd)
272{ 272{
273 struct map_info *map = mtd->priv; 273 struct map_info *map = mtd->priv;
274 struct cfi_private *cfi = map->fldrv_priv; 274 struct cfi_private *cfi = map->fldrv_priv;
@@ -282,7 +282,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
282/* 282/*
283 * Some chips power-up with all sectors locked by default. 283 * Some chips power-up with all sectors locked by default.
284 */ 284 */
285static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param) 285static void fixup_unlock_powerup_lock(struct mtd_info *mtd)
286{ 286{
287 struct map_info *map = mtd->priv; 287 struct map_info *map = mtd->priv;
288 struct cfi_private *cfi = map->fldrv_priv; 288 struct cfi_private *cfi = map->fldrv_priv;
@@ -295,31 +295,31 @@ static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param)
295} 295}
296 296
297static struct cfi_fixup cfi_fixup_table[] = { 297static struct cfi_fixup cfi_fixup_table[] = {
298 { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, 298 { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri },
299 { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock, NULL }, 299 { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock },
300 { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock, NULL }, 300 { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock },
301#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE 301#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
302 { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, 302 { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash },
303#endif 303#endif
304#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND 304#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
305 { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, 305 { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend },
306#endif 306#endif
307#if !FORCE_WORD_WRITE 307#if !FORCE_WORD_WRITE
308 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL }, 308 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers },
309#endif 309#endif
310 { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL }, 310 { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct },
311 { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL }, 311 { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb },
312 { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, }, 312 { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock },
313 { 0, 0, NULL, NULL } 313 { 0, 0, NULL }
314}; 314};
315 315
316static struct cfi_fixup jedec_fixup_table[] = { 316static struct cfi_fixup jedec_fixup_table[] = {
317 { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, 317 { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock },
318 { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, 318 { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock },
319 { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, 319 { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock },
320 { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, 320 { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock },
321 { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, 321 { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock },
322 { 0, 0, NULL, NULL } 322 { 0, 0, NULL }
323}; 323};
324static struct cfi_fixup fixup_table[] = { 324static struct cfi_fixup fixup_table[] = {
325 /* The CFI vendor ids and the JEDEC vendor IDs appear 325 /* The CFI vendor ids and the JEDEC vendor IDs appear
@@ -327,8 +327,8 @@ static struct cfi_fixup fixup_table[] = {
327 * well. This table is to pick all cases where 327 * well. This table is to pick all cases where
328 * we know that is the case. 328 * we know that is the case.
329 */ 329 */
330 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point, NULL }, 330 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point },
331 { 0, 0, NULL, NULL } 331 { 0, 0, NULL }
332}; 332};
333 333
334static void cfi_fixup_major_minor(struct cfi_private *cfi, 334static void cfi_fixup_major_minor(struct cfi_private *cfi,
@@ -455,6 +455,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
455 mtd->flags = MTD_CAP_NORFLASH; 455 mtd->flags = MTD_CAP_NORFLASH;
456 mtd->name = map->name; 456 mtd->name = map->name;
457 mtd->writesize = 1; 457 mtd->writesize = 1;
458 mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
458 459
459 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; 460 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
460 461
@@ -811,12 +812,9 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
811 break; 812 break;
812 813
813 if (time_after(jiffies, timeo)) { 814 if (time_after(jiffies, timeo)) {
814 /* Urgh. Resume and pretend we weren't here. */ 815 /* Urgh. Resume and pretend we weren't here.
815 map_write(map, CMD(0xd0), adr); 816 * Make sure we're in 'read status' mode if it had finished */
816 /* Make sure we're in 'read status' mode if it had finished */ 817 put_chip(map, chip, adr);
817 map_write(map, CMD(0x70), adr);
818 chip->state = FL_ERASING;
819 chip->oldstate = FL_READY;
820 printk(KERN_ERR "%s: Chip not ready after erase " 818 printk(KERN_ERR "%s: Chip not ready after erase "
821 "suspended: status = 0x%lx\n", map->name, status.x[0]); 819 "suspended: status = 0x%lx\n", map->name, status.x[0]);
822 return -EIO; 820 return -EIO;
@@ -996,7 +994,6 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
996 994
997 switch(chip->oldstate) { 995 switch(chip->oldstate) {
998 case FL_ERASING: 996 case FL_ERASING:
999 chip->state = chip->oldstate;
1000 /* What if one interleaved chip has finished and the 997 /* What if one interleaved chip has finished and the
1001 other hasn't? The old code would leave the finished 998 other hasn't? The old code would leave the finished
1002 one in READY mode. That's bad, and caused -EROFS 999 one in READY mode. That's bad, and caused -EROFS
@@ -1229,10 +1226,32 @@ static int inval_cache_and_wait_for_operation(
1229 sleep_time = chip_op_time / 2; 1226 sleep_time = chip_op_time / 2;
1230 1227
1231 for (;;) { 1228 for (;;) {
1229 if (chip->state != chip_state) {
1230 /* Someone's suspended the operation: sleep */
1231 DECLARE_WAITQUEUE(wait, current);
1232 set_current_state(TASK_UNINTERRUPTIBLE);
1233 add_wait_queue(&chip->wq, &wait);
1234 mutex_unlock(&chip->mutex);
1235 schedule();
1236 remove_wait_queue(&chip->wq, &wait);
1237 mutex_lock(&chip->mutex);
1238 continue;
1239 }
1240
1232 status = map_read(map, cmd_adr); 1241 status = map_read(map, cmd_adr);
1233 if (map_word_andequal(map, status, status_OK, status_OK)) 1242 if (map_word_andequal(map, status, status_OK, status_OK))
1234 break; 1243 break;
1235 1244
1245 if (chip->erase_suspended && chip_state == FL_ERASING) {
1246 /* Erase suspend occurred while sleep: reset timeout */
1247 timeo = reset_timeo;
1248 chip->erase_suspended = 0;
1249 }
1250 if (chip->write_suspended && chip_state == FL_WRITING) {
1251 /* Write suspend occurred while sleep: reset timeout */
1252 timeo = reset_timeo;
1253 chip->write_suspended = 0;
1254 }
1236 if (!timeo) { 1255 if (!timeo) {
1237 map_write(map, CMD(0x70), cmd_adr); 1256 map_write(map, CMD(0x70), cmd_adr);
1238 chip->state = FL_STATUS; 1257 chip->state = FL_STATUS;
@@ -1256,27 +1275,6 @@ static int inval_cache_and_wait_for_operation(
1256 timeo--; 1275 timeo--;
1257 } 1276 }
1258 mutex_lock(&chip->mutex); 1277 mutex_lock(&chip->mutex);
1259
1260 while (chip->state != chip_state) {
1261 /* Someone's suspended the operation: sleep */
1262 DECLARE_WAITQUEUE(wait, current);
1263 set_current_state(TASK_UNINTERRUPTIBLE);
1264 add_wait_queue(&chip->wq, &wait);
1265 mutex_unlock(&chip->mutex);
1266 schedule();
1267 remove_wait_queue(&chip->wq, &wait);
1268 mutex_lock(&chip->mutex);
1269 }
1270 if (chip->erase_suspended && chip_state == FL_ERASING) {
1271 /* Erase suspend occured while sleep: reset timeout */
1272 timeo = reset_timeo;
1273 chip->erase_suspended = 0;
1274 }
1275 if (chip->write_suspended && chip_state == FL_WRITING) {
1276 /* Write suspend occured while sleep: reset timeout */
1277 timeo = reset_timeo;
1278 chip->write_suspended = 0;
1279 }
1280 } 1278 }
1281 1279
1282 /* Done and happy. */ 1280 /* Done and happy. */
@@ -1496,7 +1494,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1496 1494
1497 switch (mode) { 1495 switch (mode) {
1498 case FL_WRITING: 1496 case FL_WRITING:
1499 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41); 1497 write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0x40) : CMD(0x41);
1500 break; 1498 break;
1501 case FL_OTP_WRITE: 1499 case FL_OTP_WRITE:
1502 write_cmd = CMD(0xc0); 1500 write_cmd = CMD(0xc0);
@@ -1661,7 +1659,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1661 cmd_adr = adr & ~(wbufsize-1); 1659 cmd_adr = adr & ~(wbufsize-1);
1662 1660
1663 /* Let's determine this according to the interleave only once */ 1661 /* Let's determine this according to the interleave only once */
1664 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9); 1662 write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0xe8) : CMD(0xe9);
1665 1663
1666 mutex_lock(&chip->mutex); 1664 mutex_lock(&chip->mutex);
1667 ret = get_chip(map, chip, cmd_adr, FL_WRITING); 1665 ret = get_chip(map, chip, cmd_adr, FL_WRITING);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 3e6c47bdce53..23175edd5634 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -134,7 +134,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
134 134
135#ifdef AMD_BOOTLOC_BUG 135#ifdef AMD_BOOTLOC_BUG
136/* Wheee. Bring me the head of someone at AMD. */ 136/* Wheee. Bring me the head of someone at AMD. */
137static void fixup_amd_bootblock(struct mtd_info *mtd, void* param) 137static void fixup_amd_bootblock(struct mtd_info *mtd)
138{ 138{
139 struct map_info *map = mtd->priv; 139 struct map_info *map = mtd->priv;
140 struct cfi_private *cfi = map->fldrv_priv; 140 struct cfi_private *cfi = map->fldrv_priv;
@@ -186,7 +186,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd, void* param)
186} 186}
187#endif 187#endif
188 188
189static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) 189static void fixup_use_write_buffers(struct mtd_info *mtd)
190{ 190{
191 struct map_info *map = mtd->priv; 191 struct map_info *map = mtd->priv;
192 struct cfi_private *cfi = map->fldrv_priv; 192 struct cfi_private *cfi = map->fldrv_priv;
@@ -197,7 +197,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
197} 197}
198 198
199/* Atmel chips don't use the same PRI format as AMD chips */ 199/* Atmel chips don't use the same PRI format as AMD chips */
200static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) 200static void fixup_convert_atmel_pri(struct mtd_info *mtd)
201{ 201{
202 struct map_info *map = mtd->priv; 202 struct map_info *map = mtd->priv;
203 struct cfi_private *cfi = map->fldrv_priv; 203 struct cfi_private *cfi = map->fldrv_priv;
@@ -228,14 +228,14 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
228 cfi->cfiq->BufWriteTimeoutMax = 0; 228 cfi->cfiq->BufWriteTimeoutMax = 0;
229} 229}
230 230
231static void fixup_use_secsi(struct mtd_info *mtd, void *param) 231static void fixup_use_secsi(struct mtd_info *mtd)
232{ 232{
233 /* Setup for chips with a secsi area */ 233 /* Setup for chips with a secsi area */
234 mtd->read_user_prot_reg = cfi_amdstd_secsi_read; 234 mtd->read_user_prot_reg = cfi_amdstd_secsi_read;
235 mtd->read_fact_prot_reg = cfi_amdstd_secsi_read; 235 mtd->read_fact_prot_reg = cfi_amdstd_secsi_read;
236} 236}
237 237
238static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) 238static void fixup_use_erase_chip(struct mtd_info *mtd)
239{ 239{
240 struct map_info *map = mtd->priv; 240 struct map_info *map = mtd->priv;
241 struct cfi_private *cfi = map->fldrv_priv; 241 struct cfi_private *cfi = map->fldrv_priv;
@@ -250,7 +250,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
250 * Some Atmel chips (e.g. the AT49BV6416) power-up with all sectors 250 * Some Atmel chips (e.g. the AT49BV6416) power-up with all sectors
251 * locked by default. 251 * locked by default.
252 */ 252 */
253static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param) 253static void fixup_use_atmel_lock(struct mtd_info *mtd)
254{ 254{
255 mtd->lock = cfi_atmel_lock; 255 mtd->lock = cfi_atmel_lock;
256 mtd->unlock = cfi_atmel_unlock; 256 mtd->unlock = cfi_atmel_unlock;
@@ -263,7 +263,7 @@ static void fixup_old_sst_eraseregion(struct mtd_info *mtd)
263 struct cfi_private *cfi = map->fldrv_priv; 263 struct cfi_private *cfi = map->fldrv_priv;
264 264
265 /* 265 /*
266 * These flashes report two seperate eraseblock regions based on the 266 * These flashes report two separate eraseblock regions based on the
267 * sector_erase-size and block_erase-size, although they both operate on the 267 * sector_erase-size and block_erase-size, although they both operate on the
268 * same memory. This is not allowed according to CFI, so we just pick the 268 * same memory. This is not allowed according to CFI, so we just pick the
269 * sector_erase-size. 269 * sector_erase-size.
@@ -271,7 +271,7 @@ static void fixup_old_sst_eraseregion(struct mtd_info *mtd)
271 cfi->cfiq->NumEraseRegions = 1; 271 cfi->cfiq->NumEraseRegions = 1;
272} 272}
273 273
274static void fixup_sst39vf(struct mtd_info *mtd, void *param) 274static void fixup_sst39vf(struct mtd_info *mtd)
275{ 275{
276 struct map_info *map = mtd->priv; 276 struct map_info *map = mtd->priv;
277 struct cfi_private *cfi = map->fldrv_priv; 277 struct cfi_private *cfi = map->fldrv_priv;
@@ -282,7 +282,7 @@ static void fixup_sst39vf(struct mtd_info *mtd, void *param)
282 cfi->addr_unlock2 = 0x2AAA; 282 cfi->addr_unlock2 = 0x2AAA;
283} 283}
284 284
285static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) 285static void fixup_sst39vf_rev_b(struct mtd_info *mtd)
286{ 286{
287 struct map_info *map = mtd->priv; 287 struct map_info *map = mtd->priv;
288 struct cfi_private *cfi = map->fldrv_priv; 288 struct cfi_private *cfi = map->fldrv_priv;
@@ -291,9 +291,26 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param)
291 291
292 cfi->addr_unlock1 = 0x555; 292 cfi->addr_unlock1 = 0x555;
293 cfi->addr_unlock2 = 0x2AA; 293 cfi->addr_unlock2 = 0x2AA;
294
295 cfi->sector_erase_cmd = CMD(0x50);
296}
297
298static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd)
299{
300 struct map_info *map = mtd->priv;
301 struct cfi_private *cfi = map->fldrv_priv;
302
303 fixup_sst39vf_rev_b(mtd);
304
305 /*
306 * CFI reports 1024 sectors (0x03ff+1) of 64KBytes (0x0100*256) where
307 * it should report a size of 8KBytes (0x0020*256).
308 */
309 cfi->cfiq->EraseRegionInfo[0] = 0x002003ff;
310 pr_warning("%s: Bad 38VF640x CFI data; adjusting sector size from 64 to 8KiB\n", mtd->name);
294} 311}
295 312
296static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param) 313static void fixup_s29gl064n_sectors(struct mtd_info *mtd)
297{ 314{
298 struct map_info *map = mtd->priv; 315 struct map_info *map = mtd->priv;
299 struct cfi_private *cfi = map->fldrv_priv; 316 struct cfi_private *cfi = map->fldrv_priv;
@@ -304,7 +321,7 @@ static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param)
304 } 321 }
305} 322}
306 323
307static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param) 324static void fixup_s29gl032n_sectors(struct mtd_info *mtd)
308{ 325{
309 struct map_info *map = mtd->priv; 326 struct map_info *map = mtd->priv;
310 struct cfi_private *cfi = map->fldrv_priv; 327 struct cfi_private *cfi = map->fldrv_priv;
@@ -317,43 +334,48 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
317 334
318/* Used to fix CFI-Tables of chips without Extended Query Tables */ 335/* Used to fix CFI-Tables of chips without Extended Query Tables */
319static struct cfi_fixup cfi_nopri_fixup_table[] = { 336static struct cfi_fixup cfi_nopri_fixup_table[] = {
320 { CFI_MFR_SST, 0x234A, fixup_sst39vf, NULL, }, // SST39VF1602 337 { CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */
321 { CFI_MFR_SST, 0x234B, fixup_sst39vf, NULL, }, // SST39VF1601 338 { CFI_MFR_SST, 0x234b, fixup_sst39vf }, /* SST39VF1601 */
322 { CFI_MFR_SST, 0x235A, fixup_sst39vf, NULL, }, // SST39VF3202 339 { CFI_MFR_SST, 0x235a, fixup_sst39vf }, /* SST39VF3202 */
323 { CFI_MFR_SST, 0x235B, fixup_sst39vf, NULL, }, // SST39VF3201 340 { CFI_MFR_SST, 0x235b, fixup_sst39vf }, /* SST39VF3201 */
324 { CFI_MFR_SST, 0x235C, fixup_sst39vf_rev_b, NULL, }, // SST39VF3202B 341 { CFI_MFR_SST, 0x235c, fixup_sst39vf_rev_b }, /* SST39VF3202B */
325 { CFI_MFR_SST, 0x235D, fixup_sst39vf_rev_b, NULL, }, // SST39VF3201B 342 { CFI_MFR_SST, 0x235d, fixup_sst39vf_rev_b }, /* SST39VF3201B */
326 { CFI_MFR_SST, 0x236C, fixup_sst39vf_rev_b, NULL, }, // SST39VF6402B 343 { CFI_MFR_SST, 0x236c, fixup_sst39vf_rev_b }, /* SST39VF6402B */
327 { CFI_MFR_SST, 0x236D, fixup_sst39vf_rev_b, NULL, }, // SST39VF6401B 344 { CFI_MFR_SST, 0x236d, fixup_sst39vf_rev_b }, /* SST39VF6401B */
328 { 0, 0, NULL, NULL } 345 { 0, 0, NULL }
329}; 346};
330 347
331static struct cfi_fixup cfi_fixup_table[] = { 348static struct cfi_fixup cfi_fixup_table[] = {
332 { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, 349 { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri },
333#ifdef AMD_BOOTLOC_BUG 350#ifdef AMD_BOOTLOC_BUG
334 { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, 351 { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock },
335 { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock, NULL }, 352 { CFI_MFR_AMIC, CFI_ID_ANY, fixup_amd_bootblock },
353 { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock },
336#endif 354#endif
337 { CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, }, 355 { CFI_MFR_AMD, 0x0050, fixup_use_secsi },
338 { CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, }, 356 { CFI_MFR_AMD, 0x0053, fixup_use_secsi },
339 { CFI_MFR_AMD, 0x0055, fixup_use_secsi, NULL, }, 357 { CFI_MFR_AMD, 0x0055, fixup_use_secsi },
340 { CFI_MFR_AMD, 0x0056, fixup_use_secsi, NULL, }, 358 { CFI_MFR_AMD, 0x0056, fixup_use_secsi },
341 { CFI_MFR_AMD, 0x005C, fixup_use_secsi, NULL, }, 359 { CFI_MFR_AMD, 0x005C, fixup_use_secsi },
342 { CFI_MFR_AMD, 0x005F, fixup_use_secsi, NULL, }, 360 { CFI_MFR_AMD, 0x005F, fixup_use_secsi },
343 { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors, NULL, }, 361 { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors },
344 { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, 362 { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors },
345 { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, 363 { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors },
346 { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, 364 { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors },
365 { CFI_MFR_SST, 0x536a, fixup_sst38vf640x_sectorsize }, /* SST38VF6402 */
366 { CFI_MFR_SST, 0x536b, fixup_sst38vf640x_sectorsize }, /* SST38VF6401 */
367 { CFI_MFR_SST, 0x536c, fixup_sst38vf640x_sectorsize }, /* SST38VF6404 */
368 { CFI_MFR_SST, 0x536d, fixup_sst38vf640x_sectorsize }, /* SST38VF6403 */
347#if !FORCE_WORD_WRITE 369#if !FORCE_WORD_WRITE
348 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, 370 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers },
349#endif 371#endif
350 { 0, 0, NULL, NULL } 372 { 0, 0, NULL }
351}; 373};
352static struct cfi_fixup jedec_fixup_table[] = { 374static struct cfi_fixup jedec_fixup_table[] = {
353 { CFI_MFR_SST, SST49LF004B, fixup_use_fwh_lock, NULL, }, 375 { CFI_MFR_SST, SST49LF004B, fixup_use_fwh_lock },
354 { CFI_MFR_SST, SST49LF040B, fixup_use_fwh_lock, NULL, }, 376 { CFI_MFR_SST, SST49LF040B, fixup_use_fwh_lock },
355 { CFI_MFR_SST, SST49LF008A, fixup_use_fwh_lock, NULL, }, 377 { CFI_MFR_SST, SST49LF008A, fixup_use_fwh_lock },
356 { 0, 0, NULL, NULL } 378 { 0, 0, NULL }
357}; 379};
358 380
359static struct cfi_fixup fixup_table[] = { 381static struct cfi_fixup fixup_table[] = {
@@ -362,18 +384,37 @@ static struct cfi_fixup fixup_table[] = {
362 * well. This table is to pick all cases where 384 * well. This table is to pick all cases where
363 * we know that is the case. 385 * we know that is the case.
364 */ 386 */
365 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL }, 387 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip },
366 { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock, NULL }, 388 { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock },
367 { 0, 0, NULL, NULL } 389 { 0, 0, NULL }
368}; 390};
369 391
370 392
371static void cfi_fixup_major_minor(struct cfi_private *cfi, 393static void cfi_fixup_major_minor(struct cfi_private *cfi,
372 struct cfi_pri_amdstd *extp) 394 struct cfi_pri_amdstd *extp)
373{ 395{
374 if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e && 396 if (cfi->mfr == CFI_MFR_SAMSUNG) {
375 extp->MajorVersion == '0') 397 if ((extp->MajorVersion == '0' && extp->MinorVersion == '0') ||
398 (extp->MajorVersion == '3' && extp->MinorVersion == '3')) {
399 /*
400 * Samsung K8P2815UQB and K8D6x16UxM chips
401 * report major=0 / minor=0.
402 * K8D3x16UxC chips report major=3 / minor=3.
403 */
404 printk(KERN_NOTICE " Fixing Samsung's Amd/Fujitsu"
405 " Extended Query version to 1.%c\n",
406 extp->MinorVersion);
407 extp->MajorVersion = '1';
408 }
409 }
410
411 /*
412 * SST 38VF640x chips report major=0xFF / minor=0xFF.
413 */
414 if (cfi->mfr == CFI_MFR_SST && (cfi->id >> 4) == 0x0536) {
376 extp->MajorVersion = '1'; 415 extp->MajorVersion = '1';
416 extp->MinorVersion = '0';
417 }
377} 418}
378 419
379struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) 420struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
@@ -400,6 +441,10 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
400 mtd->flags = MTD_CAP_NORFLASH; 441 mtd->flags = MTD_CAP_NORFLASH;
401 mtd->name = map->name; 442 mtd->name = map->name;
402 mtd->writesize = 1; 443 mtd->writesize = 1;
444 mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
445
446 DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): write buffer size %d\n",
447 __func__, mtd->writebufsize);
403 448
404 mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot; 449 mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
405 450
@@ -417,13 +462,14 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
417 cfi_fixup_major_minor(cfi, extp); 462 cfi_fixup_major_minor(cfi, extp);
418 463
419 /* 464 /*
420 * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4 465 * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5
421 * see: http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_r20.pdf, page 19 466 * see: http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19
422 * http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_100_20011201.pdf 467 * http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf
423 * http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf 468 * http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf
469 * http://www.spansion.com/Support/Datasheets/S29GL_128S_01GS_00_02_e.pdf
424 */ 470 */
425 if (extp->MajorVersion != '1' || 471 if (extp->MajorVersion != '1' ||
426 (extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '4'))) { 472 (extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '5'))) {
427 printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query " 473 printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
428 "version %c.%c (%#02x/%#02x).\n", 474 "version %c.%c (%#02x/%#02x).\n",
429 extp->MajorVersion, extp->MinorVersion, 475 extp->MajorVersion, extp->MinorVersion,
@@ -545,15 +591,6 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
545 printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize); 591 printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
546 goto setup_err; 592 goto setup_err;
547 } 593 }
548#if 0
549 // debug
550 for (i=0; i<mtd->numeraseregions;i++){
551 printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
552 i,mtd->eraseregions[i].offset,
553 mtd->eraseregions[i].erasesize,
554 mtd->eraseregions[i].numblocks);
555 }
556#endif
557 594
558 __module_get(THIS_MODULE); 595 __module_get(THIS_MODULE);
559 register_reboot_notifier(&mtd->reboot_notifier); 596 register_reboot_notifier(&mtd->reboot_notifier);
@@ -575,8 +612,8 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
575 * 612 *
576 * Note that anything more complicated than checking if no bits are toggling 613 * Note that anything more complicated than checking if no bits are toggling
577 * (including checking DQ5 for an error status) is tricky to get working 614 * (including checking DQ5 for an error status) is tricky to get working
578 * correctly and is therefore not done (particulary with interleaved chips 615 * correctly and is therefore not done (particularly with interleaved chips
579 * as each chip must be checked independantly of the others). 616 * as each chip must be checked independently of the others).
580 */ 617 */
581static int __xipram chip_ready(struct map_info *map, unsigned long addr) 618static int __xipram chip_ready(struct map_info *map, unsigned long addr)
582{ 619{
@@ -599,8 +636,8 @@ static int __xipram chip_ready(struct map_info *map, unsigned long addr)
599 * 636 *
600 * Note that anything more complicated than checking if no bits are toggling 637 * Note that anything more complicated than checking if no bits are toggling
601 * (including checking DQ5 for an error status) is tricky to get working 638 * (including checking DQ5 for an error status) is tricky to get working
602 * correctly and is therefore not done (particulary with interleaved chips 639 * correctly and is therefore not done (particularly with interleaved chips
603 * as each chip must be checked independantly of the others). 640 * as each chip must be checked independently of the others).
604 * 641 *
605 */ 642 */
606static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word expected) 643static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word expected)
@@ -674,9 +711,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
674 * there was an error (so leave the erase 711 * there was an error (so leave the erase
675 * routine to recover from it) or we trying to 712 * routine to recover from it) or we trying to
676 * use the erase-in-progress sector. */ 713 * use the erase-in-progress sector. */
677 map_write(map, CMD(0x30), chip->in_progress_block_addr); 714 put_chip(map, chip, adr);
678 chip->state = FL_ERASING;
679 chip->oldstate = FL_READY;
680 printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); 715 printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
681 return -EIO; 716 return -EIO;
682 } 717 }
@@ -726,8 +761,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
726 761
727 switch(chip->oldstate) { 762 switch(chip->oldstate) {
728 case FL_ERASING: 763 case FL_ERASING:
729 chip->state = chip->oldstate; 764 map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr);
730 map_write(map, CMD(0x30), chip->in_progress_block_addr);
731 chip->oldstate = FL_READY; 765 chip->oldstate = FL_READY;
732 chip->state = FL_ERASING; 766 chip->state = FL_ERASING;
733 break; 767 break;
@@ -870,7 +904,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
870 local_irq_disable(); 904 local_irq_disable();
871 905
872 /* Resume the write or erase operation */ 906 /* Resume the write or erase operation */
873 map_write(map, CMD(0x30), adr); 907 map_write(map, cfi->sector_erase_cmd, adr);
874 chip->state = oldstate; 908 chip->state = oldstate;
875 start = xip_currtime(); 909 start = xip_currtime();
876 } else if (usec >= 1000000/HZ) { 910 } else if (usec >= 1000000/HZ) {
@@ -1025,9 +1059,6 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
1025 mutex_lock(&chip->mutex); 1059 mutex_lock(&chip->mutex);
1026 1060
1027 if (chip->state != FL_READY){ 1061 if (chip->state != FL_READY){
1028#if 0
1029 printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state);
1030#endif
1031 set_current_state(TASK_UNINTERRUPTIBLE); 1062 set_current_state(TASK_UNINTERRUPTIBLE);
1032 add_wait_queue(&chip->wq, &wait); 1063 add_wait_queue(&chip->wq, &wait);
1033 1064
@@ -1035,10 +1066,6 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
1035 1066
1036 schedule(); 1067 schedule();
1037 remove_wait_queue(&chip->wq, &wait); 1068 remove_wait_queue(&chip->wq, &wait);
1038#if 0
1039 if(signal_pending(current))
1040 return -EINTR;
1041#endif
1042 timeo = jiffies + HZ; 1069 timeo = jiffies + HZ;
1043 1070
1044 goto retry; 1071 goto retry;
@@ -1246,9 +1273,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1246 mutex_lock(&cfi->chips[chipnum].mutex); 1273 mutex_lock(&cfi->chips[chipnum].mutex);
1247 1274
1248 if (cfi->chips[chipnum].state != FL_READY) { 1275 if (cfi->chips[chipnum].state != FL_READY) {
1249#if 0
1250 printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
1251#endif
1252 set_current_state(TASK_UNINTERRUPTIBLE); 1276 set_current_state(TASK_UNINTERRUPTIBLE);
1253 add_wait_queue(&cfi->chips[chipnum].wq, &wait); 1277 add_wait_queue(&cfi->chips[chipnum].wq, &wait);
1254 1278
@@ -1256,10 +1280,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1256 1280
1257 schedule(); 1281 schedule();
1258 remove_wait_queue(&cfi->chips[chipnum].wq, &wait); 1282 remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
1259#if 0
1260 if(signal_pending(current))
1261 return -EINTR;
1262#endif
1263 goto retry; 1283 goto retry;
1264 } 1284 }
1265 1285
@@ -1324,9 +1344,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1324 mutex_lock(&cfi->chips[chipnum].mutex); 1344 mutex_lock(&cfi->chips[chipnum].mutex);
1325 1345
1326 if (cfi->chips[chipnum].state != FL_READY) { 1346 if (cfi->chips[chipnum].state != FL_READY) {
1327#if 0
1328 printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
1329#endif
1330 set_current_state(TASK_UNINTERRUPTIBLE); 1347 set_current_state(TASK_UNINTERRUPTIBLE);
1331 add_wait_queue(&cfi->chips[chipnum].wq, &wait); 1348 add_wait_queue(&cfi->chips[chipnum].wq, &wait);
1332 1349
@@ -1334,10 +1351,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1334 1351
1335 schedule(); 1352 schedule();
1336 remove_wait_queue(&cfi->chips[chipnum].wq, &wait); 1353 remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
1337#if 0
1338 if(signal_pending(current))
1339 return -EINTR;
1340#endif
1341 goto retry1; 1354 goto retry1;
1342 } 1355 }
1343 1356
@@ -1396,7 +1409,6 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1396 1409
1397 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1410 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
1398 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 1411 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
1399 //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
1400 1412
1401 /* Write Buffer Load */ 1413 /* Write Buffer Load */
1402 map_write(map, CMD(0x25), cmd_adr); 1414 map_write(map, CMD(0x25), cmd_adr);
@@ -1675,7 +1687,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1675 cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1687 cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
1676 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1688 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
1677 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 1689 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
1678 map_write(map, CMD(0x30), adr); 1690 map_write(map, cfi->sector_erase_cmd, adr);
1679 1691
1680 chip->state = FL_ERASING; 1692 chip->state = FL_ERASING;
1681 chip->erase_suspended = 0; 1693 chip->erase_suspended = 0;
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 314af1f5a370..179814a95f3a 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -238,6 +238,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
238 mtd->resume = cfi_staa_resume; 238 mtd->resume = cfi_staa_resume;
239 mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE; 239 mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE;
240 mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */ 240 mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
241 mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
241 map->fldrv = &cfi_staa_chipdrv; 242 map->fldrv = &cfi_staa_chipdrv;
242 __module_get(THIS_MODULE); 243 __module_get(THIS_MODULE);
243 mtd->name = map->name; 244 mtd->name = map->name;
@@ -295,6 +296,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
295 /* make sure we're in 'read status' mode */ 296 /* make sure we're in 'read status' mode */
296 map_write(map, CMD(0x70), cmd_addr); 297 map_write(map, CMD(0x70), cmd_addr);
297 chip->state = FL_ERASING; 298 chip->state = FL_ERASING;
299 wake_up(&chip->wq);
298 mutex_unlock(&chip->mutex); 300 mutex_unlock(&chip->mutex);
299 printk(KERN_ERR "Chip not ready after erase " 301 printk(KERN_ERR "Chip not ready after erase "
300 "suspended: status = 0x%lx\n", status.x[0]); 302 "suspended: status = 0x%lx\n", status.x[0]);
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
index 8f5b96aa87a0..d25535279404 100644
--- a/drivers/mtd/chips/cfi_probe.c
+++ b/drivers/mtd/chips/cfi_probe.c
@@ -177,6 +177,8 @@ static int __xipram cfi_chip_setup(struct map_info *map,
177 177
178 cfi->cfi_mode = CFI_MODE_CFI; 178 cfi->cfi_mode = CFI_MODE_CFI;
179 179
180 cfi->sector_erase_cmd = CMD(0x30);
181
180 /* Read the CFI info structure */ 182 /* Read the CFI info structure */
181 xip_disable_qry(base, map, cfi); 183 xip_disable_qry(base, map, cfi);
182 for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) 184 for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index e503b2ca894d..8e464054a631 100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Common Flash Interface support: 2 * Common Flash Interface support:
3 * Generic utility functions not dependant on command set 3 * Generic utility functions not dependent on command set
4 * 4 *
5 * Copyright (C) 2002 Red Hat 5 * Copyright (C) 2002 Red Hat
6 * Copyright (C) 2003 STMicroelectronics Limited 6 * Copyright (C) 2003 STMicroelectronics Limited
@@ -77,6 +77,13 @@ int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map,
77 cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL); 77 cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
78 if (cfi_qry_present(map, base, cfi)) 78 if (cfi_qry_present(map, base, cfi))
79 return 1; 79 return 1;
80 /* SST 39VF640xB */
81 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
82 cfi_send_gen_cmd(0xAA, 0x555, base, map, cfi, cfi->device_type, NULL);
83 cfi_send_gen_cmd(0x55, 0x2AA, base, map, cfi, cfi->device_type, NULL);
84 cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL);
85 if (cfi_qry_present(map, base, cfi))
86 return 1;
80 /* QRY not found */ 87 /* QRY not found */
81 return 0; 88 return 0;
82} 89}
@@ -149,7 +156,7 @@ void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup *fixups)
149 for (f=fixups; f->fixup; f++) { 156 for (f=fixups; f->fixup; f++) {
150 if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) && 157 if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) &&
151 ((f->id == CFI_ID_ANY) || (f->id == cfi->id))) { 158 ((f->id == CFI_ID_ANY) || (f->id == cfi->id))) {
152 f->fixup(mtd, f->param); 159 f->fixup(mtd);
153 } 160 }
154 } 161 }
155} 162}
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h
index d18064977192..5e3cc80128aa 100644
--- a/drivers/mtd/chips/fwh_lock.h
+++ b/drivers/mtd/chips/fwh_lock.h
@@ -98,7 +98,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len)
98 return ret; 98 return ret;
99} 99}
100 100
101static void fixup_use_fwh_lock(struct mtd_info *mtd, void *param) 101static void fixup_use_fwh_lock(struct mtd_info *mtd)
102{ 102{
103 printk(KERN_NOTICE "using fwh lock/unlock method\n"); 103 printk(KERN_NOTICE "using fwh lock/unlock method\n");
104 /* Setup for the chips with the fwh lock method */ 104 /* Setup for the chips with the fwh lock method */
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index d72a5fb2d041..ea832ea0e4aa 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -1935,14 +1935,14 @@ static void jedec_reset(u32 base, struct map_info *map, struct cfi_private *cfi)
1935} 1935}
1936 1936
1937 1937
1938static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) 1938static int cfi_jedec_setup(struct map_info *map, struct cfi_private *cfi, int index)
1939{ 1939{
1940 int i,num_erase_regions; 1940 int i,num_erase_regions;
1941 uint8_t uaddr; 1941 uint8_t uaddr;
1942 1942
1943 if (! (jedec_table[index].devtypes & p_cfi->device_type)) { 1943 if (!(jedec_table[index].devtypes & cfi->device_type)) {
1944 DEBUG(MTD_DEBUG_LEVEL1, "Rejecting potential %s with incompatible %d-bit device type\n", 1944 DEBUG(MTD_DEBUG_LEVEL1, "Rejecting potential %s with incompatible %d-bit device type\n",
1945 jedec_table[index].name, 4 * (1<<p_cfi->device_type)); 1945 jedec_table[index].name, 4 * (1<<cfi->device_type));
1946 return 0; 1946 return 0;
1947 } 1947 }
1948 1948
@@ -1950,27 +1950,28 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
1950 1950
1951 num_erase_regions = jedec_table[index].nr_regions; 1951 num_erase_regions = jedec_table[index].nr_regions;
1952 1952
1953 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); 1953 cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
1954 if (!p_cfi->cfiq) { 1954 if (!cfi->cfiq) {
1955 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); 1955 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
1956 return 0; 1956 return 0;
1957 } 1957 }
1958 1958
1959 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); 1959 memset(cfi->cfiq, 0, sizeof(struct cfi_ident));
1960 1960
1961 p_cfi->cfiq->P_ID = jedec_table[index].cmd_set; 1961 cfi->cfiq->P_ID = jedec_table[index].cmd_set;
1962 p_cfi->cfiq->NumEraseRegions = jedec_table[index].nr_regions; 1962 cfi->cfiq->NumEraseRegions = jedec_table[index].nr_regions;
1963 p_cfi->cfiq->DevSize = jedec_table[index].dev_size; 1963 cfi->cfiq->DevSize = jedec_table[index].dev_size;
1964 p_cfi->cfi_mode = CFI_MODE_JEDEC; 1964 cfi->cfi_mode = CFI_MODE_JEDEC;
1965 cfi->sector_erase_cmd = CMD(0x30);
1965 1966
1966 for (i=0; i<num_erase_regions; i++){ 1967 for (i=0; i<num_erase_regions; i++){
1967 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; 1968 cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
1968 } 1969 }
1969 p_cfi->cmdset_priv = NULL; 1970 cfi->cmdset_priv = NULL;
1970 1971
1971 /* This may be redundant for some cases, but it doesn't hurt */ 1972 /* This may be redundant for some cases, but it doesn't hurt */
1972 p_cfi->mfr = jedec_table[index].mfr_id; 1973 cfi->mfr = jedec_table[index].mfr_id;
1973 p_cfi->id = jedec_table[index].dev_id; 1974 cfi->id = jedec_table[index].dev_id;
1974 1975
1975 uaddr = jedec_table[index].uaddr; 1976 uaddr = jedec_table[index].uaddr;
1976 1977
@@ -1978,8 +1979,8 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
1978 our brains explode when we see the datasheets talking about address 1979 our brains explode when we see the datasheets talking about address
1979 lines numbered from A-1 to A18. The CFI table has unlock addresses 1980 lines numbered from A-1 to A18. The CFI table has unlock addresses
1980 in device-words according to the mode the device is connected in */ 1981 in device-words according to the mode the device is connected in */
1981 p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 / p_cfi->device_type; 1982 cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 / cfi->device_type;
1982 p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 / p_cfi->device_type; 1983 cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 / cfi->device_type;
1983 1984
1984 return 1; /* ok */ 1985 return 1; /* ok */
1985} 1986}
@@ -2074,7 +2075,7 @@ static inline int jedec_match( uint32_t base,
2074 } 2075 }
2075 2076
2076 /* 2077 /*
2077 * Make sure the ID's dissappear when the device is taken out of 2078 * Make sure the ID's disappear when the device is taken out of
2078 * ID mode. The only time this should fail when it should succeed 2079 * ID mode. The only time this should fail when it should succeed
2079 * is when the ID's are written as data to the same 2080 * is when the ID's are written as data to the same
2080 * addresses. For this rare and unfortunate case the chip 2081 * addresses. For this rare and unfortunate case the chip
@@ -2175,7 +2176,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2175 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", 2176 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
2176 __func__, cfi->mfr, cfi->id, 2177 __func__, cfi->mfr, cfi->id,
2177 cfi->addr_unlock1, cfi->addr_unlock2 ); 2178 cfi->addr_unlock1, cfi->addr_unlock2 );
2178 if (!cfi_jedec_setup(cfi, i)) 2179 if (!cfi_jedec_setup(map, cfi, i))
2179 return 0; 2180 return 0;
2180 goto ok_out; 2181 goto ok_out;
2181 } 2182 }