diff options
-rw-r--r-- | drivers/mtd/chips/sharp.c | 123 |
1 files changed, 66 insertions, 57 deletions
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c index 2d26bdef82d5..36f61a6a766e 100644 --- a/drivers/mtd/chips/sharp.c +++ b/drivers/mtd/chips/sharp.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2000,2001 David A. Schleef <ds@schleef.org> | 4 | * Copyright 2000,2001 David A. Schleef <ds@schleef.org> |
5 | * 2000,2001 Lineo, Inc. | 5 | * 2000,2001 Lineo, Inc. |
6 | * | 6 | * |
7 | * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $ | 7 | * $Id: sharp.c,v 1.17 2005/11/29 14:28:28 gleixner Exp $ |
8 | * | 8 | * |
9 | * Devices supported: | 9 | * Devices supported: |
10 | * LH28F016SCT Symmetrical block flash memory, 2Mx8 | 10 | * LH28F016SCT Symmetrical block flash memory, 2Mx8 |
@@ -160,22 +160,28 @@ struct mtd_info *sharp_probe(struct map_info *map) | |||
160 | return mtd; | 160 | return mtd; |
161 | } | 161 | } |
162 | 162 | ||
163 | static inline void sharp_send_cmd(struct map_info *map, unsigned long cmd, unsigned long adr) | ||
164 | { | ||
165 | map_word map_cmd; | ||
166 | map_cmd.x[0] = cmd; | ||
167 | map_write(map, map_cmd, adr); | ||
168 | } | ||
169 | |||
163 | static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd) | 170 | static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd) |
164 | { | 171 | { |
165 | unsigned long tmp; | 172 | map_word tmp, read0, read4; |
166 | unsigned long base = 0; | 173 | unsigned long base = 0; |
167 | u32 read0, read4; | ||
168 | int width = 4; | 174 | int width = 4; |
169 | 175 | ||
170 | tmp = map_read32(map, base+0); | 176 | tmp = map_read(map, base+0); |
171 | 177 | ||
172 | map_write32(map, CMD_READ_ID, base+0); | 178 | sharp_send_cmd(map, CMD_READ_ID, base+0); |
173 | 179 | ||
174 | read0=map_read32(map, base+0); | 180 | read0 = map_read(map, base+0); |
175 | read4=map_read32(map, base+4); | 181 | read4 = map_read(map, base+4); |
176 | if(read0 == 0x89898989){ | 182 | if(read0.x[0] == 0x89898989){ |
177 | printk("Looks like sharp flash\n"); | 183 | printk("Looks like sharp flash\n"); |
178 | switch(read4){ | 184 | switch(read4.x[0]){ |
179 | case 0xaaaaaaaa: | 185 | case 0xaaaaaaaa: |
180 | case 0xa0a0a0a0: | 186 | case 0xa0a0a0a0: |
181 | /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/ | 187 | /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/ |
@@ -197,16 +203,16 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd) | |||
197 | return width; | 203 | return width; |
198 | #endif | 204 | #endif |
199 | default: | 205 | default: |
200 | printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n", | 206 | printk("Sort-of looks like sharp flash, 0x%08lx 0x%08lx\n", |
201 | read0,read4); | 207 | read0.x[0], read4.x[0]); |
202 | } | 208 | } |
203 | }else if((map_read32(map, base+0) == CMD_READ_ID)){ | 209 | }else if((map_read(map, base+0).x[0] == CMD_READ_ID)){ |
204 | /* RAM, probably */ | 210 | /* RAM, probably */ |
205 | printk("Looks like RAM\n"); | 211 | printk("Looks like RAM\n"); |
206 | map_write32(map, tmp, base+0); | 212 | map_write(map, tmp, base+0); |
207 | }else{ | 213 | }else{ |
208 | printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n", | 214 | printk("Doesn't look like sharp flash, 0x%08lx 0x%08lx\n", |
209 | read0,read4); | 215 | read0.x[0], read4.x[0]); |
210 | } | 216 | } |
211 | 217 | ||
212 | return 0; | 218 | return 0; |
@@ -215,7 +221,8 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd) | |||
215 | /* This function returns with the chip->mutex lock held. */ | 221 | /* This function returns with the chip->mutex lock held. */ |
216 | static int sharp_wait(struct map_info *map, struct flchip *chip) | 222 | static int sharp_wait(struct map_info *map, struct flchip *chip) |
217 | { | 223 | { |
218 | int status, i; | 224 | int i; |
225 | map_word status; | ||
219 | unsigned long timeo = jiffies + HZ; | 226 | unsigned long timeo = jiffies + HZ; |
220 | DECLARE_WAITQUEUE(wait, current); | 227 | DECLARE_WAITQUEUE(wait, current); |
221 | int adr = 0; | 228 | int adr = 0; |
@@ -225,12 +232,12 @@ retry: | |||
225 | 232 | ||
226 | switch(chip->state){ | 233 | switch(chip->state){ |
227 | case FL_READY: | 234 | case FL_READY: |
228 | map_write32(map,CMD_READ_STATUS,adr); | 235 | sharp_send_cmd(map, CMD_READ_STATUS, adr); |
229 | chip->state = FL_STATUS; | 236 | chip->state = FL_STATUS; |
230 | case FL_STATUS: | 237 | case FL_STATUS: |
231 | for(i=0;i<100;i++){ | 238 | for(i=0;i<100;i++){ |
232 | status = map_read32(map,adr); | 239 | status = map_read(map, adr); |
233 | if((status & SR_READY)==SR_READY) | 240 | if((status.x[0] & SR_READY)==SR_READY) |
234 | break; | 241 | break; |
235 | udelay(1); | 242 | udelay(1); |
236 | } | 243 | } |
@@ -254,7 +261,7 @@ retry: | |||
254 | goto retry; | 261 | goto retry; |
255 | } | 262 | } |
256 | 263 | ||
257 | map_write32(map,CMD_RESET, adr); | 264 | sharp_send_cmd(map, CMD_RESET, adr); |
258 | 265 | ||
259 | chip->state = FL_READY; | 266 | chip->state = FL_READY; |
260 | 267 | ||
@@ -351,37 +358,39 @@ static int sharp_write_oneword(struct map_info *map, struct flchip *chip, | |||
351 | int timeo; | 358 | int timeo; |
352 | int try; | 359 | int try; |
353 | int i; | 360 | int i; |
354 | int status = 0; | 361 | map_word data, status; |
355 | 362 | ||
363 | status.x[0] = 0; | ||
356 | ret = sharp_wait(map,chip); | 364 | ret = sharp_wait(map,chip); |
357 | 365 | ||
358 | for(try=0;try<10;try++){ | 366 | for(try=0;try<10;try++){ |
359 | map_write32(map,CMD_BYTE_WRITE,adr); | 367 | sharp_send_cmd(map, CMD_BYTE_WRITE, adr); |
360 | /* cpu_to_le32 -> hack to fix the writel be->le conversion */ | 368 | /* cpu_to_le32 -> hack to fix the writel be->le conversion */ |
361 | map_write32(map,cpu_to_le32(datum),adr); | 369 | data.x[0] = cpu_to_le32(datum); |
370 | map_write(map, data, adr); | ||
362 | 371 | ||
363 | chip->state = FL_WRITING; | 372 | chip->state = FL_WRITING; |
364 | 373 | ||
365 | timeo = jiffies + (HZ/2); | 374 | timeo = jiffies + (HZ/2); |
366 | 375 | ||
367 | map_write32(map,CMD_READ_STATUS,adr); | 376 | sharp_send_cmd(map, CMD_READ_STATUS, adr); |
368 | for(i=0;i<100;i++){ | 377 | for(i=0;i<100;i++){ |
369 | status = map_read32(map,adr); | 378 | status = map_read(map, adr); |
370 | if((status & SR_READY)==SR_READY) | 379 | if((status.x[0] & SR_READY) == SR_READY) |
371 | break; | 380 | break; |
372 | } | 381 | } |
373 | if(i==100){ | 382 | if(i==100){ |
374 | printk("sharp: timed out writing\n"); | 383 | printk("sharp: timed out writing\n"); |
375 | } | 384 | } |
376 | 385 | ||
377 | if(!(status&SR_ERRORS)) | 386 | if(!(status.x[0] & SR_ERRORS)) |
378 | break; | 387 | break; |
379 | 388 | ||
380 | printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status); | 389 | printk("sharp: error writing byte at addr=%08lx status=%08lx\n", adr, status.x[0]); |
381 | 390 | ||
382 | map_write32(map,CMD_CLEAR_STATUS,adr); | 391 | sharp_send_cmd(map, CMD_CLEAR_STATUS, adr); |
383 | } | 392 | } |
384 | map_write32(map,CMD_RESET,adr); | 393 | sharp_send_cmd(map, CMD_RESET, adr); |
385 | chip->state = FL_READY; | 394 | chip->state = FL_READY; |
386 | 395 | ||
387 | wake_up(&chip->wq); | 396 | wake_up(&chip->wq); |
@@ -434,18 +443,18 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip, | |||
434 | { | 443 | { |
435 | int ret; | 444 | int ret; |
436 | unsigned long timeo; | 445 | unsigned long timeo; |
437 | int status; | 446 | map_word status; |
438 | DECLARE_WAITQUEUE(wait, current); | 447 | DECLARE_WAITQUEUE(wait, current); |
439 | 448 | ||
440 | map_write32(map,CMD_READ_STATUS,adr); | 449 | sharp_send_cmd(map, CMD_READ_STATUS, adr); |
441 | status = map_read32(map,adr); | 450 | status = map_read(map, adr); |
442 | 451 | ||
443 | timeo = jiffies + HZ; | 452 | timeo = jiffies + HZ; |
444 | 453 | ||
445 | while(time_before(jiffies, timeo)){ | 454 | while(time_before(jiffies, timeo)){ |
446 | map_write32(map,CMD_READ_STATUS,adr); | 455 | sharp_send_cmd(map, CMD_READ_STATUS, adr); |
447 | status = map_read32(map,adr); | 456 | status = map_read(map, adr); |
448 | if((status & SR_READY)==SR_READY){ | 457 | if((status.x[0] & SR_READY)==SR_READY){ |
449 | ret = 0; | 458 | ret = 0; |
450 | goto out; | 459 | goto out; |
451 | } | 460 | } |
@@ -476,7 +485,7 @@ static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
476 | { | 485 | { |
477 | int ret; | 486 | int ret; |
478 | //int timeo; | 487 | //int timeo; |
479 | int status; | 488 | map_word status; |
480 | //int i; | 489 | //int i; |
481 | 490 | ||
482 | //printk("sharp_erase_oneblock()\n"); | 491 | //printk("sharp_erase_oneblock()\n"); |
@@ -486,26 +495,26 @@ static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
486 | sharp_unlock_oneblock(map,chip,adr); | 495 | sharp_unlock_oneblock(map,chip,adr); |
487 | #endif | 496 | #endif |
488 | 497 | ||
489 | map_write32(map,CMD_BLOCK_ERASE_1,adr); | 498 | sharp_send_cmd(map, CMD_BLOCK_ERASE_1, adr); |
490 | map_write32(map,CMD_BLOCK_ERASE_2,adr); | 499 | sharp_send_cmd(map, CMD_BLOCK_ERASE_2, adr); |
491 | 500 | ||
492 | chip->state = FL_ERASING; | 501 | chip->state = FL_ERASING; |
493 | 502 | ||
494 | ret = sharp_do_wait_for_ready(map,chip,adr); | 503 | ret = sharp_do_wait_for_ready(map,chip,adr); |
495 | if(ret<0)return ret; | 504 | if(ret<0)return ret; |
496 | 505 | ||
497 | map_write32(map,CMD_READ_STATUS,adr); | 506 | sharp_send_cmd(map, CMD_READ_STATUS, adr); |
498 | status = map_read32(map,adr); | 507 | status = map_read(map, adr); |
499 | 508 | ||
500 | if(!(status&SR_ERRORS)){ | 509 | if(!(status.x[0] & SR_ERRORS)){ |
501 | map_write32(map,CMD_RESET,adr); | 510 | sharp_send_cmd(map, CMD_RESET, adr); |
502 | chip->state = FL_READY; | 511 | chip->state = FL_READY; |
503 | //spin_unlock_bh(chip->mutex); | 512 | //spin_unlock_bh(chip->mutex); |
504 | return 0; | 513 | return 0; |
505 | } | 514 | } |
506 | 515 | ||
507 | printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status); | 516 | printk("sharp: error erasing block at addr=%08lx status=%08lx\n", adr, status.x[0]); |
508 | map_write32(map,CMD_CLEAR_STATUS,adr); | 517 | sharp_send_cmd(map, CMD_CLEAR_STATUS, adr); |
509 | 518 | ||
510 | //spin_unlock_bh(chip->mutex); | 519 | //spin_unlock_bh(chip->mutex); |
511 | 520 | ||
@@ -517,20 +526,20 @@ static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip, | |||
517 | unsigned long adr) | 526 | unsigned long adr) |
518 | { | 527 | { |
519 | int i; | 528 | int i; |
520 | int status; | 529 | map_word status; |
521 | 530 | ||
522 | map_write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr); | 531 | sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_1, adr); |
523 | map_write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr); | 532 | sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_2, adr); |
524 | 533 | ||
525 | udelay(100); | 534 | udelay(100); |
526 | 535 | ||
527 | status = map_read32(map,adr); | 536 | status = map_read(map, adr); |
528 | printk("status=%08x\n",status); | 537 | printk("status=%08lx\n", status.x[0]); |
529 | 538 | ||
530 | for(i=0;i<1000;i++){ | 539 | for(i=0;i<1000;i++){ |
531 | //map_write32(map,CMD_READ_STATUS,adr); | 540 | //sharp_send_cmd(map, CMD_READ_STATUS, adr); |
532 | status = map_read32(map,adr); | 541 | status = map_read(map, adr); |
533 | if((status & SR_READY)==SR_READY) | 542 | if((status.x[0] & SR_READY) == SR_READY) |
534 | break; | 543 | break; |
535 | udelay(100); | 544 | udelay(100); |
536 | } | 545 | } |
@@ -538,14 +547,14 @@ static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip, | |||
538 | printk("sharp: timed out unlocking block\n"); | 547 | printk("sharp: timed out unlocking block\n"); |
539 | } | 548 | } |
540 | 549 | ||
541 | if(!(status&SR_ERRORS)){ | 550 | if(!(status.x[0] & SR_ERRORS)){ |
542 | map_write32(map,CMD_RESET,adr); | 551 | sharp_send_cmd(map, CMD_RESET, adr); |
543 | chip->state = FL_READY; | 552 | chip->state = FL_READY; |
544 | return; | 553 | return; |
545 | } | 554 | } |
546 | 555 | ||
547 | printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status); | 556 | printk("sharp: error unlocking block at addr=%08lx status=%08lx\n", adr, status.x[0]); |
548 | map_write32(map,CMD_CLEAR_STATUS,adr); | 557 | sharp_send_cmd(map, CMD_CLEAR_STATUS, adr); |
549 | } | 558 | } |
550 | #endif | 559 | #endif |
551 | 560 | ||