sharp.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:13k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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.7 2002/02/13 15:49:07 dwmw2 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. #include <linux/kernel.h>
  23. #include <linux/module.h>
  24. #include <linux/version.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/cfi.h>
  31. #include <linux/delay.h>
  32. #define CMD_RESET 0xffffffff
  33. #define CMD_READ_ID 0x90909090
  34. #define CMD_READ_STATUS 0x70707070
  35. #define CMD_CLEAR_STATUS 0x50505050
  36. #define CMD_BLOCK_ERASE_1 0x20202020
  37. #define CMD_BLOCK_ERASE_2 0xd0d0d0d0
  38. #define CMD_BYTE_WRITE 0x40404040
  39. #define CMD_SUSPEND 0xb0b0b0b0
  40. #define CMD_RESUME 0xd0d0d0d0
  41. #define CMD_SET_BLOCK_LOCK_1 0x60606060
  42. #define CMD_SET_BLOCK_LOCK_2 0x01010101
  43. #define CMD_SET_MASTER_LOCK_1 0x60606060
  44. #define CMD_SET_MASTER_LOCK_2 0xf1f1f1f1
  45. #define CMD_CLEAR_BLOCK_LOCKS_1 0x60606060
  46. #define CMD_CLEAR_BLOCK_LOCKS_2 0xd0d0d0d0
  47. #define SR_READY 0x80808080 // 1 = ready
  48. #define SR_ERASE_SUSPEND 0x40404040 // 1 = block erase suspended
  49. #define SR_ERROR_ERASE 0x20202020 // 1 = error in block erase or clear lock bits
  50. #define SR_ERROR_WRITE 0x10101010 // 1 = error in byte write or set lock bit
  51. #define SR_VPP 0x08080808 // 1 = Vpp is low
  52. #define SR_WRITE_SUSPEND 0x04040404 // 1 = byte write suspended
  53. #define SR_PROTECT 0x02020202 // 1 = lock bit set
  54. #define SR_RESERVED 0x01010101
  55. #define SR_ERRORS (SR_ERROR_ERASE|SR_ERROR_WRITE|SR_VPP|SR_PROTECT)
  56. /* Configuration options */
  57. #undef AUTOUNLOCK  /* automatically unlocks blocks before erasing */
  58. struct mtd_info *sharp_probe(struct map_info *);
  59. static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);
  60. static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
  61. size_t *retlen, u_char *buf);
  62. static int sharp_write(struct mtd_info *mtd, loff_t from, size_t len,
  63. size_t *retlen, const u_char *buf);
  64. static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr);
  65. static void sharp_sync(struct mtd_info *mtd);
  66. static int sharp_suspend(struct mtd_info *mtd);
  67. static void sharp_resume(struct mtd_info *mtd);
  68. static void sharp_destroy(struct mtd_info *mtd);
  69. static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
  70. unsigned long adr, __u32 datum);
  71. static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
  72. unsigned long adr);
  73. #ifdef AUTOUNLOCK
  74. static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
  75. unsigned long adr);
  76. #endif
  77. struct sharp_info{
  78. struct flchip *chip;
  79. int bogus;
  80. int chipshift;
  81. int numchips;
  82. struct flchip chips[1];
  83. };
  84. struct mtd_info *sharp_probe(struct map_info *map);
  85. static void sharp_destroy(struct mtd_info *mtd);
  86. static struct mtd_chip_driver sharp_chipdrv = {
  87. probe: sharp_probe,
  88. destroy: sharp_destroy,
  89. name: "sharp",
  90. module: THIS_MODULE
  91. };
  92. struct mtd_info *sharp_probe(struct map_info *map)
  93. {
  94. struct mtd_info *mtd = NULL;
  95. struct sharp_info *sharp = NULL;
  96. int width;
  97. mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
  98. if(!mtd)
  99. return NULL;
  100. sharp = kmalloc(sizeof(*sharp), GFP_KERNEL);
  101. if(!sharp)
  102. return NULL;
  103. memset(mtd, 0, sizeof(*mtd));
  104. width = sharp_probe_map(map,mtd);
  105. if(!width){
  106. kfree(mtd);
  107. kfree(sharp);
  108. return NULL;
  109. }
  110. mtd->priv = map;
  111. mtd->type = MTD_NORFLASH;
  112. mtd->erase = sharp_erase;
  113. mtd->read = sharp_read;
  114. mtd->write = sharp_write;
  115. mtd->sync = sharp_sync;
  116. mtd->suspend = sharp_suspend;
  117. mtd->resume = sharp_resume;
  118. mtd->flags = MTD_CAP_NORFLASH;
  119. mtd->name = map->name;
  120. memset(sharp, 0, sizeof(*sharp));
  121. sharp->chipshift = 23;
  122. sharp->numchips = 1;
  123. sharp->chips[0].start = 0;
  124. sharp->chips[0].state = FL_READY;
  125. sharp->chips[0].mutex = &sharp->chips[0]._spinlock;
  126. sharp->chips[0].word_write_time = 0;
  127. init_waitqueue_head(&sharp->chips[0].wq);
  128. spin_lock_init(&sharp->chips[0]._spinlock);
  129. map->fldrv = &sharp_chipdrv;
  130. map->fldrv_priv = sharp;
  131. MOD_INC_USE_COUNT;
  132. return mtd;
  133. }
  134. static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
  135. {
  136. unsigned long tmp;
  137. unsigned long base = 0;
  138. u32 read0, read4;
  139. int width = 4;
  140. tmp = map->read32(map, base+0);
  141. map->write32(map, CMD_READ_ID, base+0);
  142. read0=map->read32(map, base+0);
  143. read4=map->read32(map, base+4);
  144. if(read0 == 0x89898989){
  145. printk("Looks like sharp flashn");
  146. switch(read4){
  147. case 0xaaaaaaaa:
  148. case 0xa0a0a0a0:
  149. /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
  150. /* a0 - LH28F016SCT-Z4  2Mx8, 32 64k blocks*/
  151. mtd->erasesize = 0x10000 * width;
  152. mtd->size = 0x200000 * width;
  153. return width;
  154. case 0xa6a6a6a6:
  155. /* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/
  156. /* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/
  157. mtd->erasesize = 0x10000 * width;
  158. mtd->size = 0x100000 * width;
  159. return width;
  160. #if 0
  161. case 0x00000000: /* unknown */
  162. /* XX - LH28F004SCT 512kx8, 8 64k blocks*/
  163. mtd->erasesize = 0x10000 * width;
  164. mtd->size = 0x80000 * width;
  165. return width;
  166. #endif
  167. default:
  168. printk("Sort-of looks like sharp flash, 0x%08x 0x%08xn",
  169. read0,read4);
  170. }
  171. }else if((map->read32(map, base+0) == CMD_READ_ID)){
  172. /* RAM, probably */
  173. printk("Looks like RAMn");
  174. map->write32(map, tmp, base+0);
  175. }else{
  176. printk("Doesn't look like sharp flash, 0x%08x 0x%08xn",
  177. read0,read4);
  178. }
  179. return 0;
  180. }
  181. /* This function returns with the chip->mutex lock held. */
  182. static int sharp_wait(struct map_info *map, struct flchip *chip)
  183. {
  184. __u16 status;
  185. unsigned long timeo = jiffies + HZ;
  186. DECLARE_WAITQUEUE(wait, current);
  187. int adr = 0;
  188. retry:
  189. spin_lock_bh(chip->mutex);
  190. switch(chip->state){
  191. case FL_READY:
  192. map->write32(map,CMD_READ_STATUS,adr);
  193. chip->state = FL_STATUS;
  194. case FL_STATUS:
  195. status = map->read32(map,adr);
  196. //printk("status=%08xn",status);
  197. udelay(100);
  198. if((status & SR_READY)!=SR_READY){
  199. //printk(".status=%08xn",status);
  200. udelay(100);
  201. }
  202. break;
  203. default:
  204. printk("Waiting for chipn");
  205. set_current_state(TASK_INTERRUPTIBLE);
  206. add_wait_queue(&chip->wq, &wait);
  207. spin_unlock_bh(chip->mutex);
  208. schedule();
  209. remove_wait_queue(&chip->wq, &wait);
  210. if(signal_pending(current))
  211. return -EINTR;
  212. timeo = jiffies + HZ;
  213. goto retry;
  214. }
  215. map->write32(map,CMD_RESET, adr);
  216. chip->state = FL_READY;
  217. return 0;
  218. }
  219. static void sharp_release(struct flchip *chip)
  220. {
  221. wake_up(&chip->wq);
  222. spin_unlock_bh(chip->mutex);
  223. }
  224. static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
  225. size_t *retlen, u_char *buf)
  226. {
  227. struct map_info *map = mtd->priv;
  228. struct sharp_info *sharp = map->fldrv_priv;
  229. int chipnum;
  230. int ret = 0;
  231. int ofs = 0;
  232. chipnum = (from >> sharp->chipshift);
  233. ofs = from & ((1 << sharp->chipshift)-1);
  234. *retlen = 0;
  235. while(len){
  236. unsigned long thislen;
  237. if(chipnum>=sharp->numchips)
  238. break;
  239. thislen = len;
  240. if(ofs+thislen >= (1<<sharp->chipshift))
  241. thislen = (1<<sharp->chipshift) - ofs;
  242. ret = sharp_wait(map,&sharp->chips[chipnum]);
  243. if(ret<0)
  244. break;
  245. map->copy_from(map,buf,ofs,thislen);
  246. sharp_release(&sharp->chips[chipnum]);
  247. *retlen += thislen;
  248. len -= thislen;
  249. buf += thislen;
  250. ofs = 0;
  251. chipnum++;
  252. }
  253. return ret;
  254. }
  255. static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len,
  256. size_t *retlen, const u_char *buf)
  257. {
  258. struct map_info *map = mtd->priv;
  259. struct sharp_info *sharp = map->fldrv_priv;
  260. int ret = 0;
  261. int i,j;
  262. int chipnum;
  263. unsigned long ofs;
  264. union { u32 l; unsigned char uc[4]; } tbuf;
  265. *retlen = 0;
  266. while(len){
  267. tbuf.l = 0xffffffff;
  268. chipnum = to >> sharp->chipshift;
  269. ofs = to & ((1<<sharp->chipshift)-1);
  270. j=0;
  271. for(i=ofs&3;i<4 && len;i++){
  272. tbuf.uc[i] = *buf;
  273. buf++;
  274. to++;
  275. len--;
  276. j++;
  277. }
  278. sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l);
  279. if(ret<0)
  280. return ret;
  281. (*retlen)+=j;
  282. }
  283. return 0;
  284. }
  285. static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
  286. unsigned long adr, __u32 datum)
  287. {
  288. int ret;
  289. int timeo;
  290. int try;
  291. int i;
  292. int status = 0;
  293. ret = sharp_wait(map,chip);
  294. for(try=0;try<10;try++){
  295. map->write32(map,CMD_BYTE_WRITE,adr);
  296. /* cpu_to_le32 -> hack to fix the writel be->le conversion */
  297. map->write32(map,cpu_to_le32(datum),adr);
  298. chip->state = FL_WRITING;
  299. timeo = jiffies + (HZ/2);
  300. map->write32(map,CMD_READ_STATUS,adr);
  301. for(i=0;i<100;i++){
  302. status = map->read32(map,adr);
  303. if((status & SR_READY)==SR_READY)
  304. break;
  305. }
  306. if(i==100){
  307. printk("sharp: timed out writingn");
  308. }
  309. if(!(status&SR_ERRORS))
  310. break;
  311. printk("sharp: error writing byte at addr=%08lx status=%08xn",adr,status);
  312. map->write32(map,CMD_CLEAR_STATUS,adr);
  313. }
  314. map->write32(map,CMD_RESET,adr);
  315. chip->state = FL_READY;
  316. wake_up(&chip->wq);
  317. spin_unlock_bh(chip->mutex);
  318. return 0;
  319. }
  320. static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
  321. {
  322. struct map_info *map = mtd->priv;
  323. struct sharp_info *sharp = map->fldrv_priv;
  324. unsigned long adr,len;
  325. int chipnum, ret=0;
  326. //printk("sharp_erase()n");
  327. if(instr->addr & (mtd->erasesize - 1))
  328. return -EINVAL;
  329. if(instr->len & (mtd->erasesize - 1))
  330. return -EINVAL;
  331. if(instr->len + instr->addr > mtd->size)
  332. return -EINVAL;
  333. chipnum = instr->addr >> sharp->chipshift;
  334. adr = instr->addr & ((1<<sharp->chipshift)-1);
  335. len = instr->len;
  336. while(len){
  337. ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr);
  338. if(ret)return ret;
  339. adr += mtd->erasesize;
  340. len -= mtd->erasesize;
  341. if(adr >> sharp->chipshift){
  342. adr = 0;
  343. chipnum++;
  344. if(chipnum>=sharp->numchips)
  345. break;
  346. }
  347. }
  348. instr->state = MTD_ERASE_DONE;
  349. if(instr->callback)
  350. instr->callback(instr);
  351. return 0;
  352. }
  353. static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
  354. unsigned long adr)
  355. {
  356. int ret;
  357. int timeo;
  358. int status;
  359. DECLARE_WAITQUEUE(wait, current);
  360. map->write32(map,CMD_READ_STATUS,adr);
  361. status = map->read32(map,adr);
  362. timeo = jiffies + HZ;
  363. while(time_before(jiffies, timeo)){
  364. map->write32(map,CMD_READ_STATUS,adr);
  365. status = map->read32(map,adr);
  366. if((status & SR_READY)==SR_READY){
  367. ret = 0;
  368. goto out;
  369. }
  370. set_current_state(TASK_INTERRUPTIBLE);
  371. add_wait_queue(&chip->wq, &wait);
  372. //spin_unlock_bh(chip->mutex);
  373. schedule_timeout(1);
  374. schedule();
  375. remove_wait_queue(&chip->wq, &wait);
  376. //spin_lock_bh(chip->mutex);
  377. if (signal_pending(current)){
  378. ret = -EINTR;
  379. goto out;
  380. }
  381. }
  382. ret = -ETIME;
  383. out:
  384. return ret;
  385. }
  386. static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
  387. unsigned long adr)
  388. {
  389. int ret;
  390. //int timeo;
  391. int status;
  392. //int i;
  393. //printk("sharp_erase_oneblock()n");
  394. #ifdef AUTOUNLOCK
  395. /* This seems like a good place to do an unlock */
  396. sharp_unlock_oneblock(map,chip,adr);
  397. #endif
  398. map->write32(map,CMD_BLOCK_ERASE_1,adr);
  399. map->write32(map,CMD_BLOCK_ERASE_2,adr);
  400. chip->state = FL_ERASING;
  401. ret = sharp_do_wait_for_ready(map,chip,adr);
  402. if(ret<0)return ret;
  403. map->write32(map,CMD_READ_STATUS,adr);
  404. status = map->read32(map,adr);
  405. if(!(status&SR_ERRORS)){
  406. map->write32(map,CMD_RESET,adr);
  407. chip->state = FL_READY;
  408. //spin_unlock_bh(chip->mutex);
  409. return 0;
  410. }
  411. printk("sharp: error erasing block at addr=%08lx status=%08xn",adr,status);
  412. map->write32(map,CMD_CLEAR_STATUS,adr);
  413. //spin_unlock_bh(chip->mutex);
  414. return -EIO;
  415. }
  416. #ifdef AUTOUNLOCK
  417. static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
  418. unsigned long adr)
  419. {
  420. int i;
  421. int status;
  422. map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
  423. map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
  424. udelay(100);
  425. status = map->read32(map,adr);
  426. printk("status=%08xn",status);
  427. for(i=0;i<1000;i++){
  428. //map->write32(map,CMD_READ_STATUS,adr);
  429. status = map->read32(map,adr);
  430. if((status & SR_READY)==SR_READY)
  431. break;
  432. udelay(100);
  433. }
  434. if(i==1000){
  435. printk("sharp: timed out unlocking blockn");
  436. }
  437. if(!(status&SR_ERRORS)){
  438. map->write32(map,CMD_RESET,adr);
  439. chip->state = FL_READY;
  440. return;
  441. }
  442. printk("sharp: error unlocking block at addr=%08lx status=%08xn",adr,status);
  443. map->write32(map,CMD_CLEAR_STATUS,adr);
  444. }
  445. #endif
  446. static void sharp_sync(struct mtd_info *mtd)
  447. {
  448. //printk("sharp_sync()n");
  449. }
  450. static int sharp_suspend(struct mtd_info *mtd)
  451. {
  452. printk("sharp_suspend()n");
  453. return -EINVAL;
  454. }
  455. static void sharp_resume(struct mtd_info *mtd)
  456. {
  457. printk("sharp_resume()n");
  458. }
  459. static void sharp_destroy(struct mtd_info *mtd)
  460. {
  461. printk("sharp_destroy()n");
  462. }
  463. int __init sharp_probe_init(void)
  464. {
  465. printk("MTD Sharp chip driver <ds@lineo.com>n");
  466. register_mtd_chip_driver(&sharp_chipdrv);
  467. return 0;
  468. }
  469. static void __exit sharp_probe_exit(void)
  470. {
  471. unregister_mtd_chip_driver(&sharp_chipdrv);
  472. }
  473. module_init(sharp_probe_init);
  474. module_exit(sharp_probe_exit);
  475. MODULE_LICENSE("GPL");
  476. MODULE_AUTHOR("David Schleef <ds@schleef.org>");
  477. MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");