diff options
Diffstat (limited to 'drivers/mtd/chips/cfi_cmdset_0020.c')
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0020.c | 183 |
1 files changed, 96 insertions, 87 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index c894f8801578..c4a19d2dc67f 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c | |||
@@ -4,8 +4,8 @@ | |||
4 | * | 4 | * |
5 | * (C) 2000 Red Hat. GPL'd | 5 | * (C) 2000 Red Hat. GPL'd |
6 | * | 6 | * |
7 | * $Id: cfi_cmdset_0020.c,v 1.19 2005/07/13 15:52:45 dwmw2 Exp $ | 7 | * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $ |
8 | * | 8 | * |
9 | * 10/10/2000 Nicolas Pitre <nico@cam.org> | 9 | * 10/10/2000 Nicolas Pitre <nico@cam.org> |
10 | * - completely revamped method functions so they are aware and | 10 | * - completely revamped method functions so they are aware and |
11 | * independent of the flash geometry (buswidth, interleave, etc.) | 11 | * independent of the flash geometry (buswidth, interleave, etc.) |
@@ -81,17 +81,17 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp) | |||
81 | printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); | 81 | printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); |
82 | printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); | 82 | printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); |
83 | for (i=9; i<32; i++) { | 83 | for (i=9; i<32; i++) { |
84 | if (extp->FeatureSupport & (1<<i)) | 84 | if (extp->FeatureSupport & (1<<i)) |
85 | printk(" - Unknown Bit %X: supported\n", i); | 85 | printk(" - Unknown Bit %X: supported\n", i); |
86 | } | 86 | } |
87 | 87 | ||
88 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); | 88 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); |
89 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); | 89 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); |
90 | for (i=1; i<8; i++) { | 90 | for (i=1; i<8; i++) { |
91 | if (extp->SuspendCmdSupport & (1<<i)) | 91 | if (extp->SuspendCmdSupport & (1<<i)) |
92 | printk(" - Unknown Bit %X: supported\n", i); | 92 | printk(" - Unknown Bit %X: supported\n", i); |
93 | } | 93 | } |
94 | 94 | ||
95 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); | 95 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); |
96 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); | 96 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); |
97 | printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); | 97 | printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); |
@@ -99,11 +99,11 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp) | |||
99 | if (extp->BlkStatusRegMask & (1<<i)) | 99 | if (extp->BlkStatusRegMask & (1<<i)) |
100 | printk(" - Unknown Bit %X Active: yes\n",i); | 100 | printk(" - Unknown Bit %X Active: yes\n",i); |
101 | } | 101 | } |
102 | 102 | ||
103 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", | 103 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", |
104 | extp->VccOptimal >> 8, extp->VccOptimal & 0xf); | 104 | extp->VccOptimal >> 8, extp->VccOptimal & 0xf); |
105 | if (extp->VppOptimal) | 105 | if (extp->VppOptimal) |
106 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", | 106 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", |
107 | extp->VppOptimal >> 8, extp->VppOptimal & 0xf); | 107 | extp->VppOptimal >> 8, extp->VppOptimal & 0xf); |
108 | } | 108 | } |
109 | #endif | 109 | #endif |
@@ -121,7 +121,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary) | |||
121 | int i; | 121 | int i; |
122 | 122 | ||
123 | if (cfi->cfi_mode) { | 123 | if (cfi->cfi_mode) { |
124 | /* | 124 | /* |
125 | * It's a real CFI chip, not one for which the probe | 125 | * It's a real CFI chip, not one for which the probe |
126 | * routine faked a CFI structure. So we read the feature | 126 | * routine faked a CFI structure. So we read the feature |
127 | * table from it. | 127 | * table from it. |
@@ -133,24 +133,33 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary) | |||
133 | if (!extp) | 133 | if (!extp) |
134 | return NULL; | 134 | return NULL; |
135 | 135 | ||
136 | if (extp->MajorVersion != '1' || | ||
137 | (extp->MinorVersion < '0' || extp->MinorVersion > '3')) { | ||
138 | printk(KERN_ERR " Unknown ST Microelectronics" | ||
139 | " Extended Query version %c.%c.\n", | ||
140 | extp->MajorVersion, extp->MinorVersion); | ||
141 | kfree(extp); | ||
142 | return NULL; | ||
143 | } | ||
144 | |||
136 | /* Do some byteswapping if necessary */ | 145 | /* Do some byteswapping if necessary */ |
137 | extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); | 146 | extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); |
138 | extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); | 147 | extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); |
139 | 148 | ||
140 | #ifdef DEBUG_CFI_FEATURES | 149 | #ifdef DEBUG_CFI_FEATURES |
141 | /* Tell the user about it in lots of lovely detail */ | 150 | /* Tell the user about it in lots of lovely detail */ |
142 | cfi_tell_features(extp); | 151 | cfi_tell_features(extp); |
143 | #endif | 152 | #endif |
144 | 153 | ||
145 | /* Install our own private info structure */ | 154 | /* Install our own private info structure */ |
146 | cfi->cmdset_priv = extp; | 155 | cfi->cmdset_priv = extp; |
147 | } | 156 | } |
148 | 157 | ||
149 | for (i=0; i< cfi->numchips; i++) { | 158 | for (i=0; i< cfi->numchips; i++) { |
150 | cfi->chips[i].word_write_time = 128; | 159 | cfi->chips[i].word_write_time = 128; |
151 | cfi->chips[i].buffer_write_time = 128; | 160 | cfi->chips[i].buffer_write_time = 128; |
152 | cfi->chips[i].erase_time = 1024; | 161 | cfi->chips[i].erase_time = 1024; |
153 | } | 162 | } |
154 | 163 | ||
155 | return cfi_staa_setup(map); | 164 | return cfi_staa_setup(map); |
156 | } | 165 | } |
@@ -178,15 +187,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) | |||
178 | mtd->size = devsize * cfi->numchips; | 187 | mtd->size = devsize * cfi->numchips; |
179 | 188 | ||
180 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; | 189 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; |
181 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) | 190 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) |
182 | * mtd->numeraseregions, GFP_KERNEL); | 191 | * mtd->numeraseregions, GFP_KERNEL); |
183 | if (!mtd->eraseregions) { | 192 | if (!mtd->eraseregions) { |
184 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); | 193 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); |
185 | kfree(cfi->cmdset_priv); | 194 | kfree(cfi->cmdset_priv); |
186 | kfree(mtd); | 195 | kfree(mtd); |
187 | return NULL; | 196 | return NULL; |
188 | } | 197 | } |
189 | 198 | ||
190 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { | 199 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { |
191 | unsigned long ernum, ersize; | 200 | unsigned long ernum, ersize; |
192 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; | 201 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; |
@@ -219,7 +228,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) | |||
219 | mtd->eraseregions[i].numblocks); | 228 | mtd->eraseregions[i].numblocks); |
220 | } | 229 | } |
221 | 230 | ||
222 | /* Also select the correct geometry setup too */ | 231 | /* Also select the correct geometry setup too */ |
223 | mtd->erase = cfi_staa_erase_varsize; | 232 | mtd->erase = cfi_staa_erase_varsize; |
224 | mtd->read = cfi_staa_read; | 233 | mtd->read = cfi_staa_read; |
225 | mtd->write = cfi_staa_write_buffers; | 234 | mtd->write = cfi_staa_write_buffers; |
@@ -250,8 +259,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
250 | 259 | ||
251 | adr += chip->start; | 260 | adr += chip->start; |
252 | 261 | ||
253 | /* Ensure cmd read/writes are aligned. */ | 262 | /* Ensure cmd read/writes are aligned. */ |
254 | cmd_addr = adr & ~(map_bankwidth(map)-1); | 263 | cmd_addr = adr & ~(map_bankwidth(map)-1); |
255 | 264 | ||
256 | /* Let's determine this according to the interleave only once */ | 265 | /* Let's determine this according to the interleave only once */ |
257 | status_OK = CMD(0x80); | 266 | status_OK = CMD(0x80); |
@@ -267,7 +276,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
267 | case FL_ERASING: | 276 | case FL_ERASING: |
268 | if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) | 277 | if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) |
269 | goto sleep; /* We don't support erase suspend */ | 278 | goto sleep; /* We don't support erase suspend */ |
270 | 279 | ||
271 | map_write (map, CMD(0xb0), cmd_addr); | 280 | map_write (map, CMD(0xb0), cmd_addr); |
272 | /* If the flash has finished erasing, then 'erase suspend' | 281 | /* If the flash has finished erasing, then 'erase suspend' |
273 | * appears to make some (28F320) flash devices switch to | 282 | * appears to make some (28F320) flash devices switch to |
@@ -282,7 +291,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
282 | status = map_read(map, cmd_addr); | 291 | status = map_read(map, cmd_addr); |
283 | if (map_word_andequal(map, status, status_OK, status_OK)) | 292 | if (map_word_andequal(map, status, status_OK, status_OK)) |
284 | break; | 293 | break; |
285 | 294 | ||
286 | if (time_after(jiffies, timeo)) { | 295 | if (time_after(jiffies, timeo)) { |
287 | /* Urgh */ | 296 | /* Urgh */ |
288 | map_write(map, CMD(0xd0), cmd_addr); | 297 | map_write(map, CMD(0xd0), cmd_addr); |
@@ -294,17 +303,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
294 | "suspended: status = 0x%lx\n", status.x[0]); | 303 | "suspended: status = 0x%lx\n", status.x[0]); |
295 | return -EIO; | 304 | return -EIO; |
296 | } | 305 | } |
297 | 306 | ||
298 | spin_unlock_bh(chip->mutex); | 307 | spin_unlock_bh(chip->mutex); |
299 | cfi_udelay(1); | 308 | cfi_udelay(1); |
300 | spin_lock_bh(chip->mutex); | 309 | spin_lock_bh(chip->mutex); |
301 | } | 310 | } |
302 | 311 | ||
303 | suspended = 1; | 312 | suspended = 1; |
304 | map_write(map, CMD(0xff), cmd_addr); | 313 | map_write(map, CMD(0xff), cmd_addr); |
305 | chip->state = FL_READY; | 314 | chip->state = FL_READY; |
306 | break; | 315 | break; |
307 | 316 | ||
308 | #if 0 | 317 | #if 0 |
309 | case FL_WRITING: | 318 | case FL_WRITING: |
310 | /* Not quite yet */ | 319 | /* Not quite yet */ |
@@ -325,7 +334,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
325 | chip->state = FL_READY; | 334 | chip->state = FL_READY; |
326 | break; | 335 | break; |
327 | } | 336 | } |
328 | 337 | ||
329 | /* Urgh. Chip not yet ready to talk to us. */ | 338 | /* Urgh. Chip not yet ready to talk to us. */ |
330 | if (time_after(jiffies, timeo)) { | 339 | if (time_after(jiffies, timeo)) { |
331 | spin_unlock_bh(chip->mutex); | 340 | spin_unlock_bh(chip->mutex); |
@@ -355,17 +364,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
355 | 364 | ||
356 | if (suspended) { | 365 | if (suspended) { |
357 | chip->state = chip->oldstate; | 366 | chip->state = chip->oldstate; |
358 | /* What if one interleaved chip has finished and the | 367 | /* What if one interleaved chip has finished and the |
359 | other hasn't? The old code would leave the finished | 368 | other hasn't? The old code would leave the finished |
360 | one in READY mode. That's bad, and caused -EROFS | 369 | one in READY mode. That's bad, and caused -EROFS |
361 | errors to be returned from do_erase_oneblock because | 370 | errors to be returned from do_erase_oneblock because |
362 | that's the only bit it checked for at the time. | 371 | that's the only bit it checked for at the time. |
363 | As the state machine appears to explicitly allow | 372 | As the state machine appears to explicitly allow |
364 | sending the 0x70 (Read Status) command to an erasing | 373 | sending the 0x70 (Read Status) command to an erasing |
365 | chip and expecting it to be ignored, that's what we | 374 | chip and expecting it to be ignored, that's what we |
366 | do. */ | 375 | do. */ |
367 | map_write(map, CMD(0xd0), cmd_addr); | 376 | map_write(map, CMD(0xd0), cmd_addr); |
368 | map_write(map, CMD(0x70), cmd_addr); | 377 | map_write(map, CMD(0x70), cmd_addr); |
369 | } | 378 | } |
370 | 379 | ||
371 | wake_up(&chip->wq); | 380 | wake_up(&chip->wq); |
@@ -405,14 +414,14 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t | |||
405 | *retlen += thislen; | 414 | *retlen += thislen; |
406 | len -= thislen; | 415 | len -= thislen; |
407 | buf += thislen; | 416 | buf += thislen; |
408 | 417 | ||
409 | ofs = 0; | 418 | ofs = 0; |
410 | chipnum++; | 419 | chipnum++; |
411 | } | 420 | } |
412 | return ret; | 421 | return ret; |
413 | } | 422 | } |
414 | 423 | ||
415 | static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | 424 | static inline int do_write_buffer(struct map_info *map, struct flchip *chip, |
416 | unsigned long adr, const u_char *buf, int len) | 425 | unsigned long adr, const u_char *buf, int len) |
417 | { | 426 | { |
418 | struct cfi_private *cfi = map->fldrv_priv; | 427 | struct cfi_private *cfi = map->fldrv_priv; |
@@ -420,7 +429,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
420 | unsigned long cmd_adr, timeo; | 429 | unsigned long cmd_adr, timeo; |
421 | DECLARE_WAITQUEUE(wait, current); | 430 | DECLARE_WAITQUEUE(wait, current); |
422 | int wbufsize, z; | 431 | int wbufsize, z; |
423 | 432 | ||
424 | /* M58LW064A requires bus alignment for buffer wriets -- saw */ | 433 | /* M58LW064A requires bus alignment for buffer wriets -- saw */ |
425 | if (adr & (map_bankwidth(map)-1)) | 434 | if (adr & (map_bankwidth(map)-1)) |
426 | return -EINVAL; | 435 | return -EINVAL; |
@@ -428,10 +437,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
428 | wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; | 437 | wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; |
429 | adr += chip->start; | 438 | adr += chip->start; |
430 | cmd_adr = adr & ~(wbufsize-1); | 439 | cmd_adr = adr & ~(wbufsize-1); |
431 | 440 | ||
432 | /* Let's determine this according to the interleave only once */ | 441 | /* Let's determine this according to the interleave only once */ |
433 | status_OK = CMD(0x80); | 442 | status_OK = CMD(0x80); |
434 | 443 | ||
435 | timeo = jiffies + HZ; | 444 | timeo = jiffies + HZ; |
436 | retry: | 445 | retry: |
437 | 446 | ||
@@ -439,7 +448,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
439 | printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state); | 448 | printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state); |
440 | #endif | 449 | #endif |
441 | spin_lock_bh(chip->mutex); | 450 | spin_lock_bh(chip->mutex); |
442 | 451 | ||
443 | /* Check that the chip's ready to talk to us. | 452 | /* Check that the chip's ready to talk to us. |
444 | * Later, we can actually think about interrupting it | 453 | * Later, we can actually think about interrupting it |
445 | * if it's in FL_ERASING state. | 454 | * if it's in FL_ERASING state. |
@@ -448,7 +457,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
448 | switch (chip->state) { | 457 | switch (chip->state) { |
449 | case FL_READY: | 458 | case FL_READY: |
450 | break; | 459 | break; |
451 | 460 | ||
452 | case FL_CFI_QUERY: | 461 | case FL_CFI_QUERY: |
453 | case FL_JEDEC_QUERY: | 462 | case FL_JEDEC_QUERY: |
454 | map_write(map, CMD(0x70), cmd_adr); | 463 | map_write(map, CMD(0x70), cmd_adr); |
@@ -513,7 +522,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
513 | 522 | ||
514 | /* Write length of data to come */ | 523 | /* Write length of data to come */ |
515 | map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); | 524 | map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); |
516 | 525 | ||
517 | /* Write data */ | 526 | /* Write data */ |
518 | for (z = 0; z < len; | 527 | for (z = 0; z < len; |
519 | z += map_bankwidth(map), buf += map_bankwidth(map)) { | 528 | z += map_bankwidth(map), buf += map_bankwidth(map)) { |
@@ -560,7 +569,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
560 | printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); | 569 | printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); |
561 | return -EIO; | 570 | return -EIO; |
562 | } | 571 | } |
563 | 572 | ||
564 | /* Latency issues. Drop the lock, wait a while and retry */ | 573 | /* Latency issues. Drop the lock, wait a while and retry */ |
565 | spin_unlock_bh(chip->mutex); | 574 | spin_unlock_bh(chip->mutex); |
566 | cfi_udelay(1); | 575 | cfi_udelay(1); |
@@ -572,9 +581,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
572 | if (!chip->buffer_write_time) | 581 | if (!chip->buffer_write_time) |
573 | chip->buffer_write_time++; | 582 | chip->buffer_write_time++; |
574 | } | 583 | } |
575 | if (z > 1) | 584 | if (z > 1) |
576 | chip->buffer_write_time++; | 585 | chip->buffer_write_time++; |
577 | 586 | ||
578 | /* Done and happy. */ | 587 | /* Done and happy. */ |
579 | DISABLE_VPP(map); | 588 | DISABLE_VPP(map); |
580 | chip->state = FL_STATUS; | 589 | chip->state = FL_STATUS; |
@@ -598,7 +607,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
598 | return 0; | 607 | return 0; |
599 | } | 608 | } |
600 | 609 | ||
601 | static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, | 610 | static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, |
602 | size_t len, size_t *retlen, const u_char *buf) | 611 | size_t len, size_t *retlen, const u_char *buf) |
603 | { | 612 | { |
604 | struct map_info *map = mtd->priv; | 613 | struct map_info *map = mtd->priv; |
@@ -620,7 +629,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, | |||
620 | printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); | 629 | printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); |
621 | printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); | 630 | printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); |
622 | #endif | 631 | #endif |
623 | 632 | ||
624 | /* Write buffer is worth it only if more than one word to write... */ | 633 | /* Write buffer is worth it only if more than one word to write... */ |
625 | while (len > 0) { | 634 | while (len > 0) { |
626 | /* We must not cross write block boundaries */ | 635 | /* We must not cross write block boundaries */ |
@@ -629,7 +638,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, | |||
629 | if (size > len) | 638 | if (size > len) |
630 | size = len; | 639 | size = len; |
631 | 640 | ||
632 | ret = do_write_buffer(map, &cfi->chips[chipnum], | 641 | ret = do_write_buffer(map, &cfi->chips[chipnum], |
633 | ofs, buf, size); | 642 | ofs, buf, size); |
634 | if (ret) | 643 | if (ret) |
635 | return ret; | 644 | return ret; |
@@ -640,13 +649,13 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, | |||
640 | len -= size; | 649 | len -= size; |
641 | 650 | ||
642 | if (ofs >> cfi->chipshift) { | 651 | if (ofs >> cfi->chipshift) { |
643 | chipnum ++; | 652 | chipnum ++; |
644 | ofs = 0; | 653 | ofs = 0; |
645 | if (chipnum == cfi->numchips) | 654 | if (chipnum == cfi->numchips) |
646 | return 0; | 655 | return 0; |
647 | } | 656 | } |
648 | } | 657 | } |
649 | 658 | ||
650 | return 0; | 659 | return 0; |
651 | } | 660 | } |
652 | 661 | ||
@@ -756,7 +765,7 @@ retry: | |||
756 | status = map_read(map, adr); | 765 | status = map_read(map, adr); |
757 | if (map_word_andequal(map, status, status_OK, status_OK)) | 766 | if (map_word_andequal(map, status, status_OK, status_OK)) |
758 | break; | 767 | break; |
759 | 768 | ||
760 | /* Urgh. Chip not yet ready to talk to us. */ | 769 | /* Urgh. Chip not yet ready to talk to us. */ |
761 | if (time_after(jiffies, timeo)) { | 770 | if (time_after(jiffies, timeo)) { |
762 | spin_unlock_bh(chip->mutex); | 771 | spin_unlock_bh(chip->mutex); |
@@ -789,7 +798,7 @@ retry: | |||
789 | map_write(map, CMD(0x20), adr); | 798 | map_write(map, CMD(0x20), adr); |
790 | map_write(map, CMD(0xD0), adr); | 799 | map_write(map, CMD(0xD0), adr); |
791 | chip->state = FL_ERASING; | 800 | chip->state = FL_ERASING; |
792 | 801 | ||
793 | spin_unlock_bh(chip->mutex); | 802 | spin_unlock_bh(chip->mutex); |
794 | msleep(1000); | 803 | msleep(1000); |
795 | spin_lock_bh(chip->mutex); | 804 | spin_lock_bh(chip->mutex); |
@@ -814,7 +823,7 @@ retry: | |||
814 | status = map_read(map, adr); | 823 | status = map_read(map, adr); |
815 | if (map_word_andequal(map, status, status_OK, status_OK)) | 824 | if (map_word_andequal(map, status, status_OK, status_OK)) |
816 | break; | 825 | break; |
817 | 826 | ||
818 | /* OK Still waiting */ | 827 | /* OK Still waiting */ |
819 | if (time_after(jiffies, timeo)) { | 828 | if (time_after(jiffies, timeo)) { |
820 | map_write(map, CMD(0x70), adr); | 829 | map_write(map, CMD(0x70), adr); |
@@ -824,13 +833,13 @@ retry: | |||
824 | spin_unlock_bh(chip->mutex); | 833 | spin_unlock_bh(chip->mutex); |
825 | return -EIO; | 834 | return -EIO; |
826 | } | 835 | } |
827 | 836 | ||
828 | /* Latency issues. Drop the lock, wait a while and retry */ | 837 | /* Latency issues. Drop the lock, wait a while and retry */ |
829 | spin_unlock_bh(chip->mutex); | 838 | spin_unlock_bh(chip->mutex); |
830 | cfi_udelay(1); | 839 | cfi_udelay(1); |
831 | spin_lock_bh(chip->mutex); | 840 | spin_lock_bh(chip->mutex); |
832 | } | 841 | } |
833 | 842 | ||
834 | DISABLE_VPP(map); | 843 | DISABLE_VPP(map); |
835 | ret = 0; | 844 | ret = 0; |
836 | 845 | ||
@@ -855,7 +864,7 @@ retry: | |||
855 | /* Reset the error bits */ | 864 | /* Reset the error bits */ |
856 | map_write(map, CMD(0x50), adr); | 865 | map_write(map, CMD(0x50), adr); |
857 | map_write(map, CMD(0x70), adr); | 866 | map_write(map, CMD(0x70), adr); |
858 | 867 | ||
859 | if ((chipstatus & 0x30) == 0x30) { | 868 | if ((chipstatus & 0x30) == 0x30) { |
860 | printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); | 869 | printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); |
861 | ret = -EIO; | 870 | ret = -EIO; |
@@ -904,17 +913,17 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
904 | 913 | ||
905 | i = 0; | 914 | i = 0; |
906 | 915 | ||
907 | /* Skip all erase regions which are ended before the start of | 916 | /* Skip all erase regions which are ended before the start of |
908 | the requested erase. Actually, to save on the calculations, | 917 | the requested erase. Actually, to save on the calculations, |
909 | we skip to the first erase region which starts after the | 918 | we skip to the first erase region which starts after the |
910 | start of the requested erase, and then go back one. | 919 | start of the requested erase, and then go back one. |
911 | */ | 920 | */ |
912 | 921 | ||
913 | while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) | 922 | while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) |
914 | i++; | 923 | i++; |
915 | i--; | 924 | i--; |
916 | 925 | ||
917 | /* OK, now i is pointing at the erase region in which this | 926 | /* OK, now i is pointing at the erase region in which this |
918 | erase request starts. Check the start of the requested | 927 | erase request starts. Check the start of the requested |
919 | erase range is aligned with the erase size which is in | 928 | erase range is aligned with the erase size which is in |
920 | effect here. | 929 | effect here. |
@@ -937,7 +946,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
937 | the address actually falls | 946 | the address actually falls |
938 | */ | 947 | */ |
939 | i--; | 948 | i--; |
940 | 949 | ||
941 | if ((instr->addr + instr->len) & (regions[i].erasesize-1)) | 950 | if ((instr->addr + instr->len) & (regions[i].erasesize-1)) |
942 | return -EINVAL; | 951 | return -EINVAL; |
943 | 952 | ||
@@ -949,7 +958,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
949 | 958 | ||
950 | while(len) { | 959 | while(len) { |
951 | ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); | 960 | ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); |
952 | 961 | ||
953 | if (ret) | 962 | if (ret) |
954 | return ret; | 963 | return ret; |
955 | 964 | ||
@@ -962,15 +971,15 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
962 | if (adr >> cfi->chipshift) { | 971 | if (adr >> cfi->chipshift) { |
963 | adr = 0; | 972 | adr = 0; |
964 | chipnum++; | 973 | chipnum++; |
965 | 974 | ||
966 | if (chipnum >= cfi->numchips) | 975 | if (chipnum >= cfi->numchips) |
967 | break; | 976 | break; |
968 | } | 977 | } |
969 | } | 978 | } |
970 | 979 | ||
971 | instr->state = MTD_ERASE_DONE; | 980 | instr->state = MTD_ERASE_DONE; |
972 | mtd_erase_callback(instr); | 981 | mtd_erase_callback(instr); |
973 | 982 | ||
974 | return 0; | 983 | return 0; |
975 | } | 984 | } |
976 | 985 | ||
@@ -996,7 +1005,7 @@ static void cfi_staa_sync (struct mtd_info *mtd) | |||
996 | case FL_JEDEC_QUERY: | 1005 | case FL_JEDEC_QUERY: |
997 | chip->oldstate = chip->state; | 1006 | chip->oldstate = chip->state; |
998 | chip->state = FL_SYNCING; | 1007 | chip->state = FL_SYNCING; |
999 | /* No need to wake_up() on this state change - | 1008 | /* No need to wake_up() on this state change - |
1000 | * as the whole point is that nobody can do anything | 1009 | * as the whole point is that nobody can do anything |
1001 | * with the chip now anyway. | 1010 | * with the chip now anyway. |
1002 | */ | 1011 | */ |
@@ -1007,11 +1016,11 @@ static void cfi_staa_sync (struct mtd_info *mtd) | |||
1007 | default: | 1016 | default: |
1008 | /* Not an idle state */ | 1017 | /* Not an idle state */ |
1009 | add_wait_queue(&chip->wq, &wait); | 1018 | add_wait_queue(&chip->wq, &wait); |
1010 | 1019 | ||
1011 | spin_unlock_bh(chip->mutex); | 1020 | spin_unlock_bh(chip->mutex); |
1012 | schedule(); | 1021 | schedule(); |
1013 | remove_wait_queue(&chip->wq, &wait); | 1022 | remove_wait_queue(&chip->wq, &wait); |
1014 | 1023 | ||
1015 | goto retry; | 1024 | goto retry; |
1016 | } | 1025 | } |
1017 | } | 1026 | } |
@@ -1022,7 +1031,7 @@ static void cfi_staa_sync (struct mtd_info *mtd) | |||
1022 | chip = &cfi->chips[i]; | 1031 | chip = &cfi->chips[i]; |
1023 | 1032 | ||
1024 | spin_lock_bh(chip->mutex); | 1033 | spin_lock_bh(chip->mutex); |
1025 | 1034 | ||
1026 | if (chip->state == FL_SYNCING) { | 1035 | if (chip->state == FL_SYNCING) { |
1027 | chip->state = chip->oldstate; | 1036 | chip->state = chip->oldstate; |
1028 | wake_up(&chip->wq); | 1037 | wake_up(&chip->wq); |
@@ -1057,9 +1066,9 @@ retry: | |||
1057 | 1066 | ||
1058 | case FL_STATUS: | 1067 | case FL_STATUS: |
1059 | status = map_read(map, adr); | 1068 | status = map_read(map, adr); |
1060 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1069 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1061 | break; | 1070 | break; |
1062 | 1071 | ||
1063 | /* Urgh. Chip not yet ready to talk to us. */ | 1072 | /* Urgh. Chip not yet ready to talk to us. */ |
1064 | if (time_after(jiffies, timeo)) { | 1073 | if (time_after(jiffies, timeo)) { |
1065 | spin_unlock_bh(chip->mutex); | 1074 | spin_unlock_bh(chip->mutex); |
@@ -1088,7 +1097,7 @@ retry: | |||
1088 | map_write(map, CMD(0x60), adr); | 1097 | map_write(map, CMD(0x60), adr); |
1089 | map_write(map, CMD(0x01), adr); | 1098 | map_write(map, CMD(0x01), adr); |
1090 | chip->state = FL_LOCKING; | 1099 | chip->state = FL_LOCKING; |
1091 | 1100 | ||
1092 | spin_unlock_bh(chip->mutex); | 1101 | spin_unlock_bh(chip->mutex); |
1093 | msleep(1000); | 1102 | msleep(1000); |
1094 | spin_lock_bh(chip->mutex); | 1103 | spin_lock_bh(chip->mutex); |
@@ -1102,7 +1111,7 @@ retry: | |||
1102 | status = map_read(map, adr); | 1111 | status = map_read(map, adr); |
1103 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1112 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1104 | break; | 1113 | break; |
1105 | 1114 | ||
1106 | /* OK Still waiting */ | 1115 | /* OK Still waiting */ |
1107 | if (time_after(jiffies, timeo)) { | 1116 | if (time_after(jiffies, timeo)) { |
1108 | map_write(map, CMD(0x70), adr); | 1117 | map_write(map, CMD(0x70), adr); |
@@ -1112,13 +1121,13 @@ retry: | |||
1112 | spin_unlock_bh(chip->mutex); | 1121 | spin_unlock_bh(chip->mutex); |
1113 | return -EIO; | 1122 | return -EIO; |
1114 | } | 1123 | } |
1115 | 1124 | ||
1116 | /* Latency issues. Drop the lock, wait a while and retry */ | 1125 | /* Latency issues. Drop the lock, wait a while and retry */ |
1117 | spin_unlock_bh(chip->mutex); | 1126 | spin_unlock_bh(chip->mutex); |
1118 | cfi_udelay(1); | 1127 | cfi_udelay(1); |
1119 | spin_lock_bh(chip->mutex); | 1128 | spin_lock_bh(chip->mutex); |
1120 | } | 1129 | } |
1121 | 1130 | ||
1122 | /* Done and happy. */ | 1131 | /* Done and happy. */ |
1123 | chip->state = FL_STATUS; | 1132 | chip->state = FL_STATUS; |
1124 | DISABLE_VPP(map); | 1133 | DISABLE_VPP(map); |
@@ -1162,8 +1171,8 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1162 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1171 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1163 | printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); | 1172 | printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); |
1164 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1173 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1165 | #endif | 1174 | #endif |
1166 | 1175 | ||
1167 | if (ret) | 1176 | if (ret) |
1168 | return ret; | 1177 | return ret; |
1169 | 1178 | ||
@@ -1173,7 +1182,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1173 | if (adr >> cfi->chipshift) { | 1182 | if (adr >> cfi->chipshift) { |
1174 | adr = 0; | 1183 | adr = 0; |
1175 | chipnum++; | 1184 | chipnum++; |
1176 | 1185 | ||
1177 | if (chipnum >= cfi->numchips) | 1186 | if (chipnum >= cfi->numchips) |
1178 | break; | 1187 | break; |
1179 | } | 1188 | } |
@@ -1208,7 +1217,7 @@ retry: | |||
1208 | status = map_read(map, adr); | 1217 | status = map_read(map, adr); |
1209 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1218 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1210 | break; | 1219 | break; |
1211 | 1220 | ||
1212 | /* Urgh. Chip not yet ready to talk to us. */ | 1221 | /* Urgh. Chip not yet ready to talk to us. */ |
1213 | if (time_after(jiffies, timeo)) { | 1222 | if (time_after(jiffies, timeo)) { |
1214 | spin_unlock_bh(chip->mutex); | 1223 | spin_unlock_bh(chip->mutex); |
@@ -1237,7 +1246,7 @@ retry: | |||
1237 | map_write(map, CMD(0x60), adr); | 1246 | map_write(map, CMD(0x60), adr); |
1238 | map_write(map, CMD(0xD0), adr); | 1247 | map_write(map, CMD(0xD0), adr); |
1239 | chip->state = FL_UNLOCKING; | 1248 | chip->state = FL_UNLOCKING; |
1240 | 1249 | ||
1241 | spin_unlock_bh(chip->mutex); | 1250 | spin_unlock_bh(chip->mutex); |
1242 | msleep(1000); | 1251 | msleep(1000); |
1243 | spin_lock_bh(chip->mutex); | 1252 | spin_lock_bh(chip->mutex); |
@@ -1251,7 +1260,7 @@ retry: | |||
1251 | status = map_read(map, adr); | 1260 | status = map_read(map, adr); |
1252 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1261 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1253 | break; | 1262 | break; |
1254 | 1263 | ||
1255 | /* OK Still waiting */ | 1264 | /* OK Still waiting */ |
1256 | if (time_after(jiffies, timeo)) { | 1265 | if (time_after(jiffies, timeo)) { |
1257 | map_write(map, CMD(0x70), adr); | 1266 | map_write(map, CMD(0x70), adr); |
@@ -1261,13 +1270,13 @@ retry: | |||
1261 | spin_unlock_bh(chip->mutex); | 1270 | spin_unlock_bh(chip->mutex); |
1262 | return -EIO; | 1271 | return -EIO; |
1263 | } | 1272 | } |
1264 | 1273 | ||
1265 | /* Latency issues. Drop the unlock, wait a while and retry */ | 1274 | /* Latency issues. Drop the unlock, wait a while and retry */ |
1266 | spin_unlock_bh(chip->mutex); | 1275 | spin_unlock_bh(chip->mutex); |
1267 | cfi_udelay(1); | 1276 | cfi_udelay(1); |
1268 | spin_lock_bh(chip->mutex); | 1277 | spin_lock_bh(chip->mutex); |
1269 | } | 1278 | } |
1270 | 1279 | ||
1271 | /* Done and happy. */ | 1280 | /* Done and happy. */ |
1272 | chip->state = FL_STATUS; | 1281 | chip->state = FL_STATUS; |
1273 | DISABLE_VPP(map); | 1282 | DISABLE_VPP(map); |
@@ -1292,7 +1301,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1292 | { | 1301 | { |
1293 | unsigned long temp_adr = adr; | 1302 | unsigned long temp_adr = adr; |
1294 | unsigned long temp_len = len; | 1303 | unsigned long temp_len = len; |
1295 | 1304 | ||
1296 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1305 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1297 | while (temp_len) { | 1306 | while (temp_len) { |
1298 | printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor))); | 1307 | printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor))); |
@@ -1310,7 +1319,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1310 | printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); | 1319 | printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); |
1311 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1320 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1312 | #endif | 1321 | #endif |
1313 | 1322 | ||
1314 | return ret; | 1323 | return ret; |
1315 | } | 1324 | } |
1316 | 1325 | ||
@@ -1334,7 +1343,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd) | |||
1334 | case FL_JEDEC_QUERY: | 1343 | case FL_JEDEC_QUERY: |
1335 | chip->oldstate = chip->state; | 1344 | chip->oldstate = chip->state; |
1336 | chip->state = FL_PM_SUSPENDED; | 1345 | chip->state = FL_PM_SUSPENDED; |
1337 | /* No need to wake_up() on this state change - | 1346 | /* No need to wake_up() on this state change - |
1338 | * as the whole point is that nobody can do anything | 1347 | * as the whole point is that nobody can do anything |
1339 | * with the chip now anyway. | 1348 | * with the chip now anyway. |
1340 | */ | 1349 | */ |
@@ -1353,9 +1362,9 @@ static int cfi_staa_suspend(struct mtd_info *mtd) | |||
1353 | if (ret) { | 1362 | if (ret) { |
1354 | for (i--; i >=0; i--) { | 1363 | for (i--; i >=0; i--) { |
1355 | chip = &cfi->chips[i]; | 1364 | chip = &cfi->chips[i]; |
1356 | 1365 | ||
1357 | spin_lock_bh(chip->mutex); | 1366 | spin_lock_bh(chip->mutex); |
1358 | 1367 | ||
1359 | if (chip->state == FL_PM_SUSPENDED) { | 1368 | if (chip->state == FL_PM_SUSPENDED) { |
1360 | /* No need to force it into a known state here, | 1369 | /* No need to force it into a known state here, |
1361 | because we're returning failure, and it didn't | 1370 | because we're returning failure, and it didn't |
@@ -1365,8 +1374,8 @@ static int cfi_staa_suspend(struct mtd_info *mtd) | |||
1365 | } | 1374 | } |
1366 | spin_unlock_bh(chip->mutex); | 1375 | spin_unlock_bh(chip->mutex); |
1367 | } | 1376 | } |
1368 | } | 1377 | } |
1369 | 1378 | ||
1370 | return ret; | 1379 | return ret; |
1371 | } | 1380 | } |
1372 | 1381 | ||
@@ -1378,11 +1387,11 @@ static void cfi_staa_resume(struct mtd_info *mtd) | |||
1378 | struct flchip *chip; | 1387 | struct flchip *chip; |
1379 | 1388 | ||
1380 | for (i=0; i<cfi->numchips; i++) { | 1389 | for (i=0; i<cfi->numchips; i++) { |
1381 | 1390 | ||
1382 | chip = &cfi->chips[i]; | 1391 | chip = &cfi->chips[i]; |
1383 | 1392 | ||
1384 | spin_lock_bh(chip->mutex); | 1393 | spin_lock_bh(chip->mutex); |
1385 | 1394 | ||
1386 | /* Go to known state. Chip may have been power cycled */ | 1395 | /* Go to known state. Chip may have been power cycled */ |
1387 | if (chip->state == FL_PM_SUSPENDED) { | 1396 | if (chip->state == FL_PM_SUSPENDED) { |
1388 | map_write(map, CMD(0xFF), 0); | 1397 | map_write(map, CMD(0xFF), 0); |