Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 33bc227e4e48ddadcf2eacb381c19df338f0a6c8 595 lines 13 kB view raw
1/* 2 * MTD chip driver for pre-CFI Sharp flash chips 3 * 4 * Copyright 2000,2001 David A. Schleef <ds@schleef.org> 5 * 2000,2001 Lineo, Inc. 6 * 7 * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $ 8 * 9 * Devices supported: 10 * LH28F016SCT Symmetrical block flash memory, 2Mx8 11 * LH28F008SCT Symmetrical block flash memory, 1Mx8 12 * 13 * Documentation: 14 * http://www.sharpmeg.com/datasheets/memic/flashcmp/ 15 * http://www.sharpmeg.com/datasheets/memic/flashcmp/01symf/16m/016sctl9.pdf 16 * 016sctl9.pdf 17 * 18 * Limitations: 19 * This driver only supports 4x1 arrangement of chips. 20 * Not tested on anything but PowerPC. 21 */ 22 23#include <linux/kernel.h> 24#include <linux/module.h> 25#include <linux/types.h> 26#include <linux/sched.h> 27#include <linux/errno.h> 28#include <linux/interrupt.h> 29#include <linux/mtd/map.h> 30#include <linux/mtd/mtd.h> 31#include <linux/mtd/cfi.h> 32#include <linux/delay.h> 33#include <linux/init.h> 34#include <linux/slab.h> 35 36#define CMD_RESET 0xffffffff 37#define CMD_READ_ID 0x90909090 38#define CMD_READ_STATUS 0x70707070 39#define CMD_CLEAR_STATUS 0x50505050 40#define CMD_BLOCK_ERASE_1 0x20202020 41#define CMD_BLOCK_ERASE_2 0xd0d0d0d0 42#define CMD_BYTE_WRITE 0x40404040 43#define CMD_SUSPEND 0xb0b0b0b0 44#define CMD_RESUME 0xd0d0d0d0 45#define CMD_SET_BLOCK_LOCK_1 0x60606060 46#define CMD_SET_BLOCK_LOCK_2 0x01010101 47#define CMD_SET_MASTER_LOCK_1 0x60606060 48#define CMD_SET_MASTER_LOCK_2 0xf1f1f1f1 49#define CMD_CLEAR_BLOCK_LOCKS_1 0x60606060 50#define CMD_CLEAR_BLOCK_LOCKS_2 0xd0d0d0d0 51 52#define SR_READY 0x80808080 // 1 = ready 53#define SR_ERASE_SUSPEND 0x40404040 // 1 = block erase suspended 54#define SR_ERROR_ERASE 0x20202020 // 1 = error in block erase or clear lock bits 55#define SR_ERROR_WRITE 0x10101010 // 1 = error in byte write or set lock bit 56#define SR_VPP 0x08080808 // 1 = Vpp is low 57#define SR_WRITE_SUSPEND 0x04040404 // 1 = byte write suspended 58#define SR_PROTECT 0x02020202 // 1 = lock bit set 59#define SR_RESERVED 0x01010101 60 61#define SR_ERRORS (SR_ERROR_ERASE|SR_ERROR_WRITE|SR_VPP|SR_PROTECT) 62 63/* Configuration options */ 64 65#undef AUTOUNLOCK /* automatically unlocks blocks before erasing */ 66 67struct mtd_info *sharp_probe(struct map_info *); 68 69static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd); 70 71static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len, 72 size_t *retlen, u_char *buf); 73static int sharp_write(struct mtd_info *mtd, loff_t from, size_t len, 74 size_t *retlen, const u_char *buf); 75static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr); 76static void sharp_sync(struct mtd_info *mtd); 77static int sharp_suspend(struct mtd_info *mtd); 78static void sharp_resume(struct mtd_info *mtd); 79static void sharp_destroy(struct mtd_info *mtd); 80 81static int sharp_write_oneword(struct map_info *map, struct flchip *chip, 82 unsigned long adr, __u32 datum); 83static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip, 84 unsigned long adr); 85#ifdef AUTOUNLOCK 86static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip, 87 unsigned long adr); 88#endif 89 90 91struct sharp_info{ 92 struct flchip *chip; 93 int bogus; 94 int chipshift; 95 int numchips; 96 struct flchip chips[1]; 97}; 98 99struct mtd_info *sharp_probe(struct map_info *map); 100static void sharp_destroy(struct mtd_info *mtd); 101 102static struct mtd_chip_driver sharp_chipdrv = { 103 .probe = sharp_probe, 104 .destroy = sharp_destroy, 105 .name = "sharp", 106 .module = THIS_MODULE 107}; 108 109 110struct mtd_info *sharp_probe(struct map_info *map) 111{ 112 struct mtd_info *mtd = NULL; 113 struct sharp_info *sharp = NULL; 114 int width; 115 116 mtd = kmalloc(sizeof(*mtd), GFP_KERNEL); 117 if(!mtd) 118 return NULL; 119 120 sharp = kmalloc(sizeof(*sharp), GFP_KERNEL); 121 if(!sharp) { 122 kfree(mtd); 123 return NULL; 124 } 125 126 memset(mtd, 0, sizeof(*mtd)); 127 128 width = sharp_probe_map(map,mtd); 129 if(!width){ 130 kfree(mtd); 131 kfree(sharp); 132 return NULL; 133 } 134 135 mtd->priv = map; 136 mtd->type = MTD_NORFLASH; 137 mtd->erase = sharp_erase; 138 mtd->read = sharp_read; 139 mtd->write = sharp_write; 140 mtd->sync = sharp_sync; 141 mtd->suspend = sharp_suspend; 142 mtd->resume = sharp_resume; 143 mtd->flags = MTD_CAP_NORFLASH; 144 mtd->name = map->name; 145 146 memset(sharp, 0, sizeof(*sharp)); 147 sharp->chipshift = 23; 148 sharp->numchips = 1; 149 sharp->chips[0].start = 0; 150 sharp->chips[0].state = FL_READY; 151 sharp->chips[0].mutex = &sharp->chips[0]._spinlock; 152 sharp->chips[0].word_write_time = 0; 153 init_waitqueue_head(&sharp->chips[0].wq); 154 spin_lock_init(&sharp->chips[0]._spinlock); 155 156 map->fldrv = &sharp_chipdrv; 157 map->fldrv_priv = sharp; 158 159 __module_get(THIS_MODULE); 160 return mtd; 161} 162 163static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd) 164{ 165 unsigned long tmp; 166 unsigned long base = 0; 167 u32 read0, read4; 168 int width = 4; 169 170 tmp = map_read32(map, base+0); 171 172 map_write32(map, CMD_READ_ID, base+0); 173 174 read0=map_read32(map, base+0); 175 read4=map_read32(map, base+4); 176 if(read0 == 0x89898989){ 177 printk("Looks like sharp flash\n"); 178 switch(read4){ 179 case 0xaaaaaaaa: 180 case 0xa0a0a0a0: 181 /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/ 182 /* a0 - LH28F016SCT-Z4 2Mx8, 32 64k blocks*/ 183 mtd->erasesize = 0x10000 * width; 184 mtd->size = 0x200000 * width; 185 return width; 186 case 0xa6a6a6a6: 187 /* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/ 188 /* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/ 189 mtd->erasesize = 0x10000 * width; 190 mtd->size = 0x100000 * width; 191 return width; 192#if 0 193 case 0x00000000: /* unknown */ 194 /* XX - LH28F004SCT 512kx8, 8 64k blocks*/ 195 mtd->erasesize = 0x10000 * width; 196 mtd->size = 0x80000 * width; 197 return width; 198#endif 199 default: 200 printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n", 201 read0,read4); 202 } 203 }else if((map_read32(map, base+0) == CMD_READ_ID)){ 204 /* RAM, probably */ 205 printk("Looks like RAM\n"); 206 map_write32(map, tmp, base+0); 207 }else{ 208 printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n", 209 read0,read4); 210 } 211 212 return 0; 213} 214 215/* This function returns with the chip->mutex lock held. */ 216static int sharp_wait(struct map_info *map, struct flchip *chip) 217{ 218 int status, i; 219 unsigned long timeo = jiffies + HZ; 220 DECLARE_WAITQUEUE(wait, current); 221 int adr = 0; 222 223retry: 224 spin_lock_bh(chip->mutex); 225 226 switch(chip->state){ 227 case FL_READY: 228 map_write32(map,CMD_READ_STATUS,adr); 229 chip->state = FL_STATUS; 230 case FL_STATUS: 231 for(i=0;i<100;i++){ 232 status = map_read32(map,adr); 233 if((status & SR_READY)==SR_READY) 234 break; 235 udelay(1); 236 } 237 break; 238 default: 239 printk("Waiting for chip\n"); 240 241 set_current_state(TASK_INTERRUPTIBLE); 242 add_wait_queue(&chip->wq, &wait); 243 244 spin_unlock_bh(chip->mutex); 245 246 schedule(); 247 remove_wait_queue(&chip->wq, &wait); 248 249 if(signal_pending(current)) 250 return -EINTR; 251 252 timeo = jiffies + HZ; 253 254 goto retry; 255 } 256 257 map_write32(map,CMD_RESET, adr); 258 259 chip->state = FL_READY; 260 261 return 0; 262} 263 264static void sharp_release(struct flchip *chip) 265{ 266 wake_up(&chip->wq); 267 spin_unlock_bh(chip->mutex); 268} 269 270static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len, 271 size_t *retlen, u_char *buf) 272{ 273 struct map_info *map = mtd->priv; 274 struct sharp_info *sharp = map->fldrv_priv; 275 int chipnum; 276 int ret = 0; 277 int ofs = 0; 278 279 chipnum = (from >> sharp->chipshift); 280 ofs = from & ((1 << sharp->chipshift)-1); 281 282 *retlen = 0; 283 284 while(len){ 285 unsigned long thislen; 286 287 if(chipnum>=sharp->numchips) 288 break; 289 290 thislen = len; 291 if(ofs+thislen >= (1<<sharp->chipshift)) 292 thislen = (1<<sharp->chipshift) - ofs; 293 294 ret = sharp_wait(map,&sharp->chips[chipnum]); 295 if(ret<0) 296 break; 297 298 map_copy_from(map,buf,ofs,thislen); 299 300 sharp_release(&sharp->chips[chipnum]); 301 302 *retlen += thislen; 303 len -= thislen; 304 buf += thislen; 305 306 ofs = 0; 307 chipnum++; 308 } 309 return ret; 310} 311 312static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len, 313 size_t *retlen, const u_char *buf) 314{ 315 struct map_info *map = mtd->priv; 316 struct sharp_info *sharp = map->fldrv_priv; 317 int ret = 0; 318 int i,j; 319 int chipnum; 320 unsigned long ofs; 321 union { u32 l; unsigned char uc[4]; } tbuf; 322 323 *retlen = 0; 324 325 while(len){ 326 tbuf.l = 0xffffffff; 327 chipnum = to >> sharp->chipshift; 328 ofs = to & ((1<<sharp->chipshift)-1); 329 330 j=0; 331 for(i=ofs&3;i<4 && len;i++){ 332 tbuf.uc[i] = *buf; 333 buf++; 334 to++; 335 len--; 336 j++; 337 } 338 sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l); 339 if(ret<0) 340 return ret; 341 (*retlen)+=j; 342 } 343 344 return 0; 345} 346 347static int sharp_write_oneword(struct map_info *map, struct flchip *chip, 348 unsigned long adr, __u32 datum) 349{ 350 int ret; 351 int timeo; 352 int try; 353 int i; 354 int status = 0; 355 356 ret = sharp_wait(map,chip); 357 358 for(try=0;try<10;try++){ 359 map_write32(map,CMD_BYTE_WRITE,adr); 360 /* cpu_to_le32 -> hack to fix the writel be->le conversion */ 361 map_write32(map,cpu_to_le32(datum),adr); 362 363 chip->state = FL_WRITING; 364 365 timeo = jiffies + (HZ/2); 366 367 map_write32(map,CMD_READ_STATUS,adr); 368 for(i=0;i<100;i++){ 369 status = map_read32(map,adr); 370 if((status & SR_READY)==SR_READY) 371 break; 372 } 373 if(i==100){ 374 printk("sharp: timed out writing\n"); 375 } 376 377 if(!(status&SR_ERRORS)) 378 break; 379 380 printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status); 381 382 map_write32(map,CMD_CLEAR_STATUS,adr); 383 } 384 map_write32(map,CMD_RESET,adr); 385 chip->state = FL_READY; 386 387 wake_up(&chip->wq); 388 spin_unlock_bh(chip->mutex); 389 390 return 0; 391} 392 393static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr) 394{ 395 struct map_info *map = mtd->priv; 396 struct sharp_info *sharp = map->fldrv_priv; 397 unsigned long adr,len; 398 int chipnum, ret=0; 399 400//printk("sharp_erase()\n"); 401 if(instr->addr & (mtd->erasesize - 1)) 402 return -EINVAL; 403 if(instr->len & (mtd->erasesize - 1)) 404 return -EINVAL; 405 if(instr->len + instr->addr > mtd->size) 406 return -EINVAL; 407 408 chipnum = instr->addr >> sharp->chipshift; 409 adr = instr->addr & ((1<<sharp->chipshift)-1); 410 len = instr->len; 411 412 while(len){ 413 ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr); 414 if(ret)return ret; 415 416 adr += mtd->erasesize; 417 len -= mtd->erasesize; 418 if(adr >> sharp->chipshift){ 419 adr = 0; 420 chipnum++; 421 if(chipnum>=sharp->numchips) 422 break; 423 } 424 } 425 426 instr->state = MTD_ERASE_DONE; 427 mtd_erase_callback(instr); 428 429 return 0; 430} 431 432static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip, 433 unsigned long adr) 434{ 435 int ret; 436 unsigned long timeo; 437 int status; 438 DECLARE_WAITQUEUE(wait, current); 439 440 map_write32(map,CMD_READ_STATUS,adr); 441 status = map_read32(map,adr); 442 443 timeo = jiffies + HZ; 444 445 while(time_before(jiffies, timeo)){ 446 map_write32(map,CMD_READ_STATUS,adr); 447 status = map_read32(map,adr); 448 if((status & SR_READY)==SR_READY){ 449 ret = 0; 450 goto out; 451 } 452 set_current_state(TASK_INTERRUPTIBLE); 453 add_wait_queue(&chip->wq, &wait); 454 455 //spin_unlock_bh(chip->mutex); 456 457 schedule_timeout(1); 458 schedule(); 459 remove_wait_queue(&chip->wq, &wait); 460 461 //spin_lock_bh(chip->mutex); 462 463 if (signal_pending(current)){ 464 ret = -EINTR; 465 goto out; 466 } 467 468 } 469 ret = -ETIME; 470out: 471 return ret; 472} 473 474static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip, 475 unsigned long adr) 476{ 477 int ret; 478 //int timeo; 479 int status; 480 //int i; 481 482//printk("sharp_erase_oneblock()\n"); 483 484#ifdef AUTOUNLOCK 485 /* This seems like a good place to do an unlock */ 486 sharp_unlock_oneblock(map,chip,adr); 487#endif 488 489 map_write32(map,CMD_BLOCK_ERASE_1,adr); 490 map_write32(map,CMD_BLOCK_ERASE_2,adr); 491 492 chip->state = FL_ERASING; 493 494 ret = sharp_do_wait_for_ready(map,chip,adr); 495 if(ret<0)return ret; 496 497 map_write32(map,CMD_READ_STATUS,adr); 498 status = map_read32(map,adr); 499 500 if(!(status&SR_ERRORS)){ 501 map_write32(map,CMD_RESET,adr); 502 chip->state = FL_READY; 503 //spin_unlock_bh(chip->mutex); 504 return 0; 505 } 506 507 printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status); 508 map_write32(map,CMD_CLEAR_STATUS,adr); 509 510 //spin_unlock_bh(chip->mutex); 511 512 return -EIO; 513} 514 515#ifdef AUTOUNLOCK 516static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip, 517 unsigned long adr) 518{ 519 int i; 520 int status; 521 522 map_write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr); 523 map_write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr); 524 525 udelay(100); 526 527 status = map_read32(map,adr); 528 printk("status=%08x\n",status); 529 530 for(i=0;i<1000;i++){ 531 //map_write32(map,CMD_READ_STATUS,adr); 532 status = map_read32(map,adr); 533 if((status & SR_READY)==SR_READY) 534 break; 535 udelay(100); 536 } 537 if(i==1000){ 538 printk("sharp: timed out unlocking block\n"); 539 } 540 541 if(!(status&SR_ERRORS)){ 542 map_write32(map,CMD_RESET,adr); 543 chip->state = FL_READY; 544 return; 545 } 546 547 printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status); 548 map_write32(map,CMD_CLEAR_STATUS,adr); 549} 550#endif 551 552static void sharp_sync(struct mtd_info *mtd) 553{ 554 //printk("sharp_sync()\n"); 555} 556 557static int sharp_suspend(struct mtd_info *mtd) 558{ 559 printk("sharp_suspend()\n"); 560 return -EINVAL; 561} 562 563static void sharp_resume(struct mtd_info *mtd) 564{ 565 printk("sharp_resume()\n"); 566 567} 568 569static void sharp_destroy(struct mtd_info *mtd) 570{ 571 printk("sharp_destroy()\n"); 572 573} 574 575int __init sharp_probe_init(void) 576{ 577 printk("MTD Sharp chip driver <ds@lineo.com>\n"); 578 579 register_mtd_chip_driver(&sharp_chipdrv); 580 581 return 0; 582} 583 584static void __exit sharp_probe_exit(void) 585{ 586 unregister_mtd_chip_driver(&sharp_chipdrv); 587} 588 589module_init(sharp_probe_init); 590module_exit(sharp_probe_exit); 591 592 593MODULE_LICENSE("GPL"); 594MODULE_AUTHOR("David Schleef <ds@schleef.org>"); 595MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");