sharp.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

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. if(instr->callback)
  349. instr->callback(instr);
  350. return 0;
  351. }
  352. static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
  353. unsigned long adr)
  354. {
  355. int ret;
  356. int timeo;
  357. int status;
  358. DECLARE_WAITQUEUE(wait, current);
  359. map->write32(map,CMD_READ_STATUS,adr);
  360. status = map->read32(map,adr);
  361. timeo = jiffies + HZ;
  362. while(time_before(jiffies, timeo)){
  363. map->write32(map,CMD_READ_STATUS,adr);
  364. status = map->read32(map,adr);
  365. if((status & SR_READY)==SR_READY){
  366. ret = 0;
  367. goto out;
  368. }
  369. set_current_state(TASK_INTERRUPTIBLE);
  370. add_wait_queue(&chip->wq, &wait);
  371. //spin_unlock_bh(chip->mutex);
  372. schedule_timeout(1);
  373. schedule();
  374. remove_wait_queue(&chip->wq, &wait);
  375. //spin_lock_bh(chip->mutex);
  376. if (signal_pending(current)){
  377. ret = -EINTR;
  378. goto out;
  379. }
  380. }
  381. ret = -ETIME;
  382. out:
  383. return ret;
  384. }
  385. static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
  386. unsigned long adr)
  387. {
  388. int ret;
  389. //int timeo;
  390. int status;
  391. //int i;
  392. //printk("sharp_erase_oneblock()n");
  393. #ifdef AUTOUNLOCK
  394. /* This seems like a good place to do an unlock */
  395. sharp_unlock_oneblock(map,chip,adr);
  396. #endif
  397. map->write32(map,CMD_BLOCK_ERASE_1,adr);
  398. map->write32(map,CMD_BLOCK_ERASE_2,adr);
  399. chip->state = FL_ERASING;
  400. ret = sharp_do_wait_for_ready(map,chip,adr);
  401. if(ret<0)return ret;
  402. map->write32(map,CMD_READ_STATUS,adr);
  403. status = map->read32(map,adr);
  404. if(!(status&SR_ERRORS)){
  405. map->write32(map,CMD_RESET,adr);
  406. chip->state = FL_READY;
  407. //spin_unlock_bh(chip->mutex);
  408. return 0;
  409. }
  410. printk("sharp: error erasing block at addr=%08lx status=%08xn",adr,status);
  411. map->write32(map,CMD_CLEAR_STATUS,adr);
  412. //spin_unlock_bh(chip->mutex);
  413. return -EIO;
  414. }
  415. #ifdef AUTOUNLOCK
  416. static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
  417. unsigned long adr)
  418. {
  419. int i;
  420. int status;
  421. map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
  422. map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
  423. udelay(100);
  424. status = map->read32(map,adr);
  425. printk("status=%08xn",status);
  426. for(i=0;i<1000;i++){
  427. //map->write32(map,CMD_READ_STATUS,adr);
  428. status = map->read32(map,adr);
  429. if((status & SR_READY)==SR_READY)
  430. break;
  431. udelay(100);
  432. }
  433. if(i==1000){
  434. printk("sharp: timed out unlocking blockn");
  435. }
  436. if(!(status&SR_ERRORS)){
  437. map->write32(map,CMD_RESET,adr);
  438. chip->state = FL_READY;
  439. return;
  440. }
  441. printk("sharp: error unlocking block at addr=%08lx status=%08xn",adr,status);
  442. map->write32(map,CMD_CLEAR_STATUS,adr);
  443. }
  444. #endif
  445. static void sharp_sync(struct mtd_info *mtd)
  446. {
  447. //printk("sharp_sync()n");
  448. }
  449. static int sharp_suspend(struct mtd_info *mtd)
  450. {
  451. printk("sharp_suspend()n");
  452. return -EINVAL;
  453. }
  454. static void sharp_resume(struct mtd_info *mtd)
  455. {
  456. printk("sharp_resume()n");
  457. }
  458. static void sharp_destroy(struct mtd_info *mtd)
  459. {
  460. printk("sharp_destroy()n");
  461. }
  462. int __init sharp_probe_init(void)
  463. {
  464. printk("MTD Sharp chip driver <ds@lineo.com>n");
  465. register_mtd_chip_driver(&sharp_chipdrv);
  466. return 0;
  467. }
  468. static void __exit sharp_probe_exit(void)
  469. {
  470. unregister_mtd_chip_driver(&sharp_chipdrv);
  471. }
  472. module_init(sharp_probe_init);
  473. module_exit(sharp_probe_exit);
  474. MODULE_LICENSE("GPL");
  475. MODULE_AUTHOR("David Schleef <ds@schleef.org>");
  476. MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");