diff options
Diffstat (limited to 'drivers/mtd/chips/sharp.c')
| -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 | ||
