[UDP]: saddr_cmp function should take const socket pointers
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / mtd / chips / sharp.c
blob967abbecdff9bb450aab9852e28c5ee84d39dcc7
1 /*
2 * MTD chip driver for pre-CFI Sharp flash chips
4 * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
5 * 2000,2001 Lineo, Inc.
7 * $Id: sharp.c,v 1.17 2005/11/29 14:28:28 gleixner Exp $
9 * Devices supported:
10 * LH28F016SCT Symmetrical block flash memory, 2Mx8
11 * LH28F008SCT Symmetrical block flash memory, 1Mx8
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
18 * Limitations:
19 * This driver only supports 4x1 arrangement of chips.
20 * Not tested on anything but PowerPC.
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>
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
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
61 #define SR_ERRORS (SR_ERROR_ERASE|SR_ERROR_WRITE|SR_VPP|SR_PROTECT)
63 /* Configuration options */
65 #undef AUTOUNLOCK /* automatically unlocks blocks before erasing */
67 static struct mtd_info *sharp_probe(struct map_info *);
69 static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);
71 static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
72 size_t *retlen, u_char *buf);
73 static int sharp_write(struct mtd_info *mtd, loff_t from, size_t len,
74 size_t *retlen, const u_char *buf);
75 static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr);
76 static void sharp_sync(struct mtd_info *mtd);
77 static int sharp_suspend(struct mtd_info *mtd);
78 static void sharp_resume(struct mtd_info *mtd);
79 static void sharp_destroy(struct mtd_info *mtd);
81 static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
82 unsigned long adr, __u32 datum);
83 static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
84 unsigned long adr);
85 #ifdef AUTOUNLOCK
86 static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
87 unsigned long adr);
88 #endif
91 struct sharp_info{
92 struct flchip *chip;
93 int bogus;
94 int chipshift;
95 int numchips;
96 struct flchip chips[1];
99 static void sharp_destroy(struct mtd_info *mtd);
101 static struct mtd_chip_driver sharp_chipdrv = {
102 .probe = sharp_probe,
103 .destroy = sharp_destroy,
104 .name = "sharp",
105 .module = THIS_MODULE
109 static struct mtd_info *sharp_probe(struct map_info *map)
111 struct mtd_info *mtd = NULL;
112 struct sharp_info *sharp = NULL;
113 int width;
115 mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
116 if(!mtd)
117 return NULL;
119 sharp = kmalloc(sizeof(*sharp), GFP_KERNEL);
120 if(!sharp) {
121 kfree(mtd);
122 return NULL;
125 memset(mtd, 0, sizeof(*mtd));
127 width = sharp_probe_map(map,mtd);
128 if(!width){
129 kfree(mtd);
130 kfree(sharp);
131 return NULL;
134 mtd->priv = map;
135 mtd->type = MTD_NORFLASH;
136 mtd->erase = sharp_erase;
137 mtd->read = sharp_read;
138 mtd->write = sharp_write;
139 mtd->sync = sharp_sync;
140 mtd->suspend = sharp_suspend;
141 mtd->resume = sharp_resume;
142 mtd->flags = MTD_CAP_NORFLASH;
143 mtd->writesize = 1;
144 mtd->name = map->name;
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);
156 map->fldrv = &sharp_chipdrv;
157 map->fldrv_priv = sharp;
159 __module_get(THIS_MODULE);
160 return mtd;
163 static inline void sharp_send_cmd(struct map_info *map, unsigned long cmd, unsigned long adr)
165 map_word map_cmd;
166 map_cmd.x[0] = cmd;
167 map_write(map, map_cmd, adr);
170 static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
172 map_word tmp, read0, read4;
173 unsigned long base = 0;
174 int width = 4;
176 tmp = map_read(map, base+0);
178 sharp_send_cmd(map, CMD_READ_ID, base+0);
180 read0 = map_read(map, base+0);
181 read4 = map_read(map, base+4);
182 if(read0.x[0] == 0x89898989){
183 printk("Looks like sharp flash\n");
184 switch(read4.x[0]){
185 case 0xaaaaaaaa:
186 case 0xa0a0a0a0:
187 /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
188 /* a0 - LH28F016SCT-Z4 2Mx8, 32 64k blocks*/
189 mtd->erasesize = 0x10000 * width;
190 mtd->size = 0x200000 * width;
191 return width;
192 case 0xa6a6a6a6:
193 /* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/
194 /* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/
195 mtd->erasesize = 0x10000 * width;
196 mtd->size = 0x100000 * width;
197 return width;
198 #if 0
199 case 0x00000000: /* unknown */
200 /* XX - LH28F004SCT 512kx8, 8 64k blocks*/
201 mtd->erasesize = 0x10000 * width;
202 mtd->size = 0x80000 * width;
203 return width;
204 #endif
205 default:
206 printk("Sort-of looks like sharp flash, 0x%08lx 0x%08lx\n",
207 read0.x[0], read4.x[0]);
209 }else if((map_read(map, base+0).x[0] == CMD_READ_ID)){
210 /* RAM, probably */
211 printk("Looks like RAM\n");
212 map_write(map, tmp, base+0);
213 }else{
214 printk("Doesn't look like sharp flash, 0x%08lx 0x%08lx\n",
215 read0.x[0], read4.x[0]);
218 return 0;
221 /* This function returns with the chip->mutex lock held. */
222 static int sharp_wait(struct map_info *map, struct flchip *chip)
224 int i;
225 map_word status;
226 unsigned long timeo = jiffies + HZ;
227 DECLARE_WAITQUEUE(wait, current);
228 int adr = 0;
230 retry:
231 spin_lock_bh(chip->mutex);
233 switch(chip->state){
234 case FL_READY:
235 sharp_send_cmd(map, CMD_READ_STATUS, adr);
236 chip->state = FL_STATUS;
237 case FL_STATUS:
238 for(i=0;i<100;i++){
239 status = map_read(map, adr);
240 if((status.x[0] & SR_READY)==SR_READY)
241 break;
242 udelay(1);
244 break;
245 default:
246 printk("Waiting for chip\n");
248 set_current_state(TASK_INTERRUPTIBLE);
249 add_wait_queue(&chip->wq, &wait);
251 spin_unlock_bh(chip->mutex);
253 schedule();
254 remove_wait_queue(&chip->wq, &wait);
256 if(signal_pending(current))
257 return -EINTR;
259 timeo = jiffies + HZ;
261 goto retry;
264 sharp_send_cmd(map, CMD_RESET, adr);
266 chip->state = FL_READY;
268 return 0;
271 static void sharp_release(struct flchip *chip)
273 wake_up(&chip->wq);
274 spin_unlock_bh(chip->mutex);
277 static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
278 size_t *retlen, u_char *buf)
280 struct map_info *map = mtd->priv;
281 struct sharp_info *sharp = map->fldrv_priv;
282 int chipnum;
283 int ret = 0;
284 int ofs = 0;
286 chipnum = (from >> sharp->chipshift);
287 ofs = from & ((1 << sharp->chipshift)-1);
289 *retlen = 0;
291 while(len){
292 unsigned long thislen;
294 if(chipnum>=sharp->numchips)
295 break;
297 thislen = len;
298 if(ofs+thislen >= (1<<sharp->chipshift))
299 thislen = (1<<sharp->chipshift) - ofs;
301 ret = sharp_wait(map,&sharp->chips[chipnum]);
302 if(ret<0)
303 break;
305 map_copy_from(map,buf,ofs,thislen);
307 sharp_release(&sharp->chips[chipnum]);
309 *retlen += thislen;
310 len -= thislen;
311 buf += thislen;
313 ofs = 0;
314 chipnum++;
316 return ret;
319 static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len,
320 size_t *retlen, const u_char *buf)
322 struct map_info *map = mtd->priv;
323 struct sharp_info *sharp = map->fldrv_priv;
324 int ret = 0;
325 int i,j;
326 int chipnum;
327 unsigned long ofs;
328 union { u32 l; unsigned char uc[4]; } tbuf;
330 *retlen = 0;
332 while(len){
333 tbuf.l = 0xffffffff;
334 chipnum = to >> sharp->chipshift;
335 ofs = to & ((1<<sharp->chipshift)-1);
337 j=0;
338 for(i=ofs&3;i<4 && len;i++){
339 tbuf.uc[i] = *buf;
340 buf++;
341 to++;
342 len--;
343 j++;
345 sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l);
346 if(ret<0)
347 return ret;
348 (*retlen)+=j;
351 return 0;
354 static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
355 unsigned long adr, __u32 datum)
357 int ret;
358 int timeo;
359 int try;
360 int i;
361 map_word data, status;
363 status.x[0] = 0;
364 ret = sharp_wait(map,chip);
366 for(try=0;try<10;try++){
367 sharp_send_cmd(map, CMD_BYTE_WRITE, adr);
368 /* cpu_to_le32 -> hack to fix the writel be->le conversion */
369 data.x[0] = cpu_to_le32(datum);
370 map_write(map, data, adr);
372 chip->state = FL_WRITING;
374 timeo = jiffies + (HZ/2);
376 sharp_send_cmd(map, CMD_READ_STATUS, adr);
377 for(i=0;i<100;i++){
378 status = map_read(map, adr);
379 if((status.x[0] & SR_READY) == SR_READY)
380 break;
382 if(i==100){
383 printk("sharp: timed out writing\n");
386 if(!(status.x[0] & SR_ERRORS))
387 break;
389 printk("sharp: error writing byte at addr=%08lx status=%08lx\n", adr, status.x[0]);
391 sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
393 sharp_send_cmd(map, CMD_RESET, adr);
394 chip->state = FL_READY;
396 wake_up(&chip->wq);
397 spin_unlock_bh(chip->mutex);
399 return 0;
402 static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
404 struct map_info *map = mtd->priv;
405 struct sharp_info *sharp = map->fldrv_priv;
406 unsigned long adr,len;
407 int chipnum, ret=0;
409 //printk("sharp_erase()\n");
410 if(instr->addr & (mtd->erasesize - 1))
411 return -EINVAL;
412 if(instr->len & (mtd->erasesize - 1))
413 return -EINVAL;
414 if(instr->len + instr->addr > mtd->size)
415 return -EINVAL;
417 chipnum = instr->addr >> sharp->chipshift;
418 adr = instr->addr & ((1<<sharp->chipshift)-1);
419 len = instr->len;
421 while(len){
422 ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr);
423 if(ret)return ret;
425 adr += mtd->erasesize;
426 len -= mtd->erasesize;
427 if(adr >> sharp->chipshift){
428 adr = 0;
429 chipnum++;
430 if(chipnum>=sharp->numchips)
431 break;
435 instr->state = MTD_ERASE_DONE;
436 mtd_erase_callback(instr);
438 return 0;
441 static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
442 unsigned long adr)
444 int ret;
445 unsigned long timeo;
446 map_word status;
447 DECLARE_WAITQUEUE(wait, current);
449 sharp_send_cmd(map, CMD_READ_STATUS, adr);
450 status = map_read(map, adr);
452 timeo = jiffies + HZ;
454 while(time_before(jiffies, timeo)){
455 sharp_send_cmd(map, CMD_READ_STATUS, adr);
456 status = map_read(map, adr);
457 if((status.x[0] & SR_READY)==SR_READY){
458 ret = 0;
459 goto out;
461 set_current_state(TASK_INTERRUPTIBLE);
462 add_wait_queue(&chip->wq, &wait);
464 //spin_unlock_bh(chip->mutex);
466 schedule_timeout(1);
467 schedule();
468 remove_wait_queue(&chip->wq, &wait);
470 //spin_lock_bh(chip->mutex);
472 if (signal_pending(current)){
473 ret = -EINTR;
474 goto out;
478 ret = -ETIME;
479 out:
480 return ret;
483 static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
484 unsigned long adr)
486 int ret;
487 //int timeo;
488 map_word status;
489 //int i;
491 //printk("sharp_erase_oneblock()\n");
493 #ifdef AUTOUNLOCK
494 /* This seems like a good place to do an unlock */
495 sharp_unlock_oneblock(map,chip,adr);
496 #endif
498 sharp_send_cmd(map, CMD_BLOCK_ERASE_1, adr);
499 sharp_send_cmd(map, CMD_BLOCK_ERASE_2, adr);
501 chip->state = FL_ERASING;
503 ret = sharp_do_wait_for_ready(map,chip,adr);
504 if(ret<0)return ret;
506 sharp_send_cmd(map, CMD_READ_STATUS, adr);
507 status = map_read(map, adr);
509 if(!(status.x[0] & SR_ERRORS)){
510 sharp_send_cmd(map, CMD_RESET, adr);
511 chip->state = FL_READY;
512 //spin_unlock_bh(chip->mutex);
513 return 0;
516 printk("sharp: error erasing block at addr=%08lx status=%08lx\n", adr, status.x[0]);
517 sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
519 //spin_unlock_bh(chip->mutex);
521 return -EIO;
524 #ifdef AUTOUNLOCK
525 static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
526 unsigned long adr)
528 int i;
529 map_word status;
531 sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_1, adr);
532 sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_2, adr);
534 udelay(100);
536 status = map_read(map, adr);
537 printk("status=%08lx\n", status.x[0]);
539 for(i=0;i<1000;i++){
540 //sharp_send_cmd(map, CMD_READ_STATUS, adr);
541 status = map_read(map, adr);
542 if((status.x[0] & SR_READY) == SR_READY)
543 break;
544 udelay(100);
546 if(i==1000){
547 printk("sharp: timed out unlocking block\n");
550 if(!(status.x[0] & SR_ERRORS)){
551 sharp_send_cmd(map, CMD_RESET, adr);
552 chip->state = FL_READY;
553 return;
556 printk("sharp: error unlocking block at addr=%08lx status=%08lx\n", adr, status.x[0]);
557 sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
559 #endif
561 static void sharp_sync(struct mtd_info *mtd)
563 //printk("sharp_sync()\n");
566 static int sharp_suspend(struct mtd_info *mtd)
568 printk("sharp_suspend()\n");
569 return -EINVAL;
572 static void sharp_resume(struct mtd_info *mtd)
574 printk("sharp_resume()\n");
578 static void sharp_destroy(struct mtd_info *mtd)
580 printk("sharp_destroy()\n");
584 static int __init sharp_probe_init(void)
586 printk("MTD Sharp chip driver <ds@lineo.com>\n");
588 register_mtd_chip_driver(&sharp_chipdrv);
590 return 0;
593 static void __exit sharp_probe_exit(void)
595 unregister_mtd_chip_driver(&sharp_chipdrv);
598 module_init(sharp_probe_init);
599 module_exit(sharp_probe_exit);
602 MODULE_LICENSE("GPL");
603 MODULE_AUTHOR("David Schleef <ds@schleef.org>");
604 MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");