diff options
Diffstat (limited to 'drivers/mtd/chips/sharp.c')
-rw-r--r-- | drivers/mtd/chips/sharp.c | 601 |
1 files changed, 0 insertions, 601 deletions
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c deleted file mode 100644 index c9cd3d21ccfa..000000000000 --- a/drivers/mtd/chips/sharp.c +++ /dev/null | |||
@@ -1,601 +0,0 @@ | |||
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.17 2005/11/29 14:28:28 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 | |||
67 | static struct mtd_info *sharp_probe(struct map_info *); | ||
68 | |||
69 | static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd); | ||
70 | |||
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); | ||
80 | |||
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 | ||
89 | |||
90 | |||
91 | struct sharp_info{ | ||
92 | struct flchip *chip; | ||
93 | int bogus; | ||
94 | int chipshift; | ||
95 | int numchips; | ||
96 | struct flchip chips[1]; | ||
97 | }; | ||
98 | |||
99 | static void sharp_destroy(struct mtd_info *mtd); | ||
100 | |||
101 | static struct mtd_chip_driver sharp_chipdrv = { | ||
102 | .probe = sharp_probe, | ||
103 | .destroy = sharp_destroy, | ||
104 | .name = "sharp", | ||
105 | .module = THIS_MODULE | ||
106 | }; | ||
107 | |||
108 | |||
109 | static struct mtd_info *sharp_probe(struct map_info *map) | ||
110 | { | ||
111 | struct mtd_info *mtd = NULL; | ||
112 | struct sharp_info *sharp = NULL; | ||
113 | int width; | ||
114 | |||
115 | mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); | ||
116 | if(!mtd) | ||
117 | return NULL; | ||
118 | |||
119 | sharp = kzalloc(sizeof(*sharp), GFP_KERNEL); | ||
120 | if(!sharp) { | ||
121 | kfree(mtd); | ||
122 | return NULL; | ||
123 | } | ||
124 | |||
125 | width = sharp_probe_map(map,mtd); | ||
126 | if(!width){ | ||
127 | kfree(mtd); | ||
128 | kfree(sharp); | ||
129 | return NULL; | ||
130 | } | ||
131 | |||
132 | mtd->priv = map; | ||
133 | mtd->type = MTD_NORFLASH; | ||
134 | mtd->erase = sharp_erase; | ||
135 | mtd->read = sharp_read; | ||
136 | mtd->write = sharp_write; | ||
137 | mtd->sync = sharp_sync; | ||
138 | mtd->suspend = sharp_suspend; | ||
139 | mtd->resume = sharp_resume; | ||
140 | mtd->flags = MTD_CAP_NORFLASH; | ||
141 | mtd->writesize = 1; | ||
142 | mtd->name = map->name; | ||
143 | |||
144 | sharp->chipshift = 23; | ||
145 | sharp->numchips = 1; | ||
146 | sharp->chips[0].start = 0; | ||
147 | sharp->chips[0].state = FL_READY; | ||
148 | sharp->chips[0].mutex = &sharp->chips[0]._spinlock; | ||
149 | sharp->chips[0].word_write_time = 0; | ||
150 | init_waitqueue_head(&sharp->chips[0].wq); | ||
151 | spin_lock_init(&sharp->chips[0]._spinlock); | ||
152 | |||
153 | map->fldrv = &sharp_chipdrv; | ||
154 | map->fldrv_priv = sharp; | ||
155 | |||
156 | __module_get(THIS_MODULE); | ||
157 | return mtd; | ||
158 | } | ||
159 | |||
160 | static inline void sharp_send_cmd(struct map_info *map, unsigned long cmd, unsigned long adr) | ||
161 | { | ||
162 | map_word map_cmd; | ||
163 | map_cmd.x[0] = cmd; | ||
164 | map_write(map, map_cmd, adr); | ||
165 | } | ||
166 | |||
167 | static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd) | ||
168 | { | ||
169 | map_word tmp, read0, read4; | ||
170 | unsigned long base = 0; | ||
171 | int width = 4; | ||
172 | |||
173 | tmp = map_read(map, base+0); | ||
174 | |||
175 | sharp_send_cmd(map, CMD_READ_ID, base+0); | ||
176 | |||
177 | read0 = map_read(map, base+0); | ||
178 | read4 = map_read(map, base+4); | ||
179 | if(read0.x[0] == 0x89898989){ | ||
180 | printk("Looks like sharp flash\n"); | ||
181 | switch(read4.x[0]){ | ||
182 | case 0xaaaaaaaa: | ||
183 | case 0xa0a0a0a0: | ||
184 | /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/ | ||
185 | /* a0 - LH28F016SCT-Z4 2Mx8, 32 64k blocks*/ | ||
186 | mtd->erasesize = 0x10000 * width; | ||
187 | mtd->size = 0x200000 * width; | ||
188 | return width; | ||
189 | case 0xa6a6a6a6: | ||
190 | /* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/ | ||
191 | /* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/ | ||
192 | mtd->erasesize = 0x10000 * width; | ||
193 | mtd->size = 0x100000 * width; | ||
194 | return width; | ||
195 | #if 0 | ||
196 | case 0x00000000: /* unknown */ | ||
197 | /* XX - LH28F004SCT 512kx8, 8 64k blocks*/ | ||
198 | mtd->erasesize = 0x10000 * width; | ||
199 | mtd->size = 0x80000 * width; | ||
200 | return width; | ||
201 | #endif | ||
202 | default: | ||
203 | printk("Sort-of looks like sharp flash, 0x%08lx 0x%08lx\n", | ||
204 | read0.x[0], read4.x[0]); | ||
205 | } | ||
206 | }else if((map_read(map, base+0).x[0] == CMD_READ_ID)){ | ||
207 | /* RAM, probably */ | ||
208 | printk("Looks like RAM\n"); | ||
209 | map_write(map, tmp, base+0); | ||
210 | }else{ | ||
211 | printk("Doesn't look like sharp flash, 0x%08lx 0x%08lx\n", | ||
212 | read0.x[0], read4.x[0]); | ||
213 | } | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | /* This function returns with the chip->mutex lock held. */ | ||
219 | static int sharp_wait(struct map_info *map, struct flchip *chip) | ||
220 | { | ||
221 | int i; | ||
222 | map_word status; | ||
223 | unsigned long timeo = jiffies + HZ; | ||
224 | DECLARE_WAITQUEUE(wait, current); | ||
225 | int adr = 0; | ||
226 | |||
227 | retry: | ||
228 | spin_lock_bh(chip->mutex); | ||
229 | |||
230 | switch(chip->state){ | ||
231 | case FL_READY: | ||
232 | sharp_send_cmd(map, CMD_READ_STATUS, adr); | ||
233 | chip->state = FL_STATUS; | ||
234 | case FL_STATUS: | ||
235 | for(i=0;i<100;i++){ | ||
236 | status = map_read(map, adr); | ||
237 | if((status.x[0] & SR_READY)==SR_READY) | ||
238 | break; | ||
239 | udelay(1); | ||
240 | } | ||
241 | break; | ||
242 | default: | ||
243 | printk("Waiting for chip\n"); | ||
244 | |||
245 | set_current_state(TASK_INTERRUPTIBLE); | ||
246 | add_wait_queue(&chip->wq, &wait); | ||
247 | |||
248 | spin_unlock_bh(chip->mutex); | ||
249 | |||
250 | schedule(); | ||
251 | remove_wait_queue(&chip->wq, &wait); | ||
252 | |||
253 | if(signal_pending(current)) | ||
254 | return -EINTR; | ||
255 | |||
256 | timeo = jiffies + HZ; | ||
257 | |||
258 | goto retry; | ||
259 | } | ||
260 | |||
261 | sharp_send_cmd(map, CMD_RESET, adr); | ||
262 | |||
263 | chip->state = FL_READY; | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static void sharp_release(struct flchip *chip) | ||
269 | { | ||
270 | wake_up(&chip->wq); | ||
271 | spin_unlock_bh(chip->mutex); | ||
272 | } | ||
273 | |||
274 | static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len, | ||
275 | size_t *retlen, u_char *buf) | ||
276 | { | ||
277 | struct map_info *map = mtd->priv; | ||
278 | struct sharp_info *sharp = map->fldrv_priv; | ||
279 | int chipnum; | ||
280 | int ret = 0; | ||
281 | int ofs = 0; | ||
282 | |||
283 | chipnum = (from >> sharp->chipshift); | ||
284 | ofs = from & ((1 << sharp->chipshift)-1); | ||
285 | |||
286 | *retlen = 0; | ||
287 | |||
288 | while(len){ | ||
289 | unsigned long thislen; | ||
290 | |||
291 | if(chipnum>=sharp->numchips) | ||
292 | break; | ||
293 | |||
294 | thislen = len; | ||
295 | if(ofs+thislen >= (1<<sharp->chipshift)) | ||
296 | thislen = (1<<sharp->chipshift) - ofs; | ||
297 | |||
298 | ret = sharp_wait(map,&sharp->chips[chipnum]); | ||
299 | if(ret<0) | ||
300 | break; | ||
301 | |||
302 | map_copy_from(map,buf,ofs,thislen); | ||
303 | |||
304 | sharp_release(&sharp->chips[chipnum]); | ||
305 | |||
306 | *retlen += thislen; | ||
307 | len -= thislen; | ||
308 | buf += thislen; | ||
309 | |||
310 | ofs = 0; | ||
311 | chipnum++; | ||
312 | } | ||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len, | ||
317 | size_t *retlen, const u_char *buf) | ||
318 | { | ||
319 | struct map_info *map = mtd->priv; | ||
320 | struct sharp_info *sharp = map->fldrv_priv; | ||
321 | int ret = 0; | ||
322 | int i,j; | ||
323 | int chipnum; | ||
324 | unsigned long ofs; | ||
325 | union { u32 l; unsigned char uc[4]; } tbuf; | ||
326 | |||
327 | *retlen = 0; | ||
328 | |||
329 | while(len){ | ||
330 | tbuf.l = 0xffffffff; | ||
331 | chipnum = to >> sharp->chipshift; | ||
332 | ofs = to & ((1<<sharp->chipshift)-1); | ||
333 | |||
334 | j=0; | ||
335 | for(i=ofs&3;i<4 && len;i++){ | ||
336 | tbuf.uc[i] = *buf; | ||
337 | buf++; | ||
338 | to++; | ||
339 | len--; | ||
340 | j++; | ||
341 | } | ||
342 | sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l); | ||
343 | if(ret<0) | ||
344 | return ret; | ||
345 | (*retlen)+=j; | ||
346 | } | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int sharp_write_oneword(struct map_info *map, struct flchip *chip, | ||
352 | unsigned long adr, __u32 datum) | ||
353 | { | ||
354 | int ret; | ||
355 | int timeo; | ||
356 | int try; | ||
357 | int i; | ||
358 | map_word data, status; | ||
359 | |||
360 | status.x[0] = 0; | ||
361 | ret = sharp_wait(map,chip); | ||
362 | |||
363 | for(try=0;try<10;try++){ | ||
364 | sharp_send_cmd(map, CMD_BYTE_WRITE, adr); | ||
365 | /* cpu_to_le32 -> hack to fix the writel be->le conversion */ | ||
366 | data.x[0] = cpu_to_le32(datum); | ||
367 | map_write(map, data, adr); | ||
368 | |||
369 | chip->state = FL_WRITING; | ||
370 | |||
371 | timeo = jiffies + (HZ/2); | ||
372 | |||
373 | sharp_send_cmd(map, CMD_READ_STATUS, adr); | ||
374 | for(i=0;i<100;i++){ | ||
375 | status = map_read(map, adr); | ||
376 | if((status.x[0] & SR_READY) == SR_READY) | ||
377 | break; | ||
378 | } | ||
379 | if(i==100){ | ||
380 | printk("sharp: timed out writing\n"); | ||
381 | } | ||
382 | |||
383 | if(!(status.x[0] & SR_ERRORS)) | ||
384 | break; | ||
385 | |||
386 | printk("sharp: error writing byte at addr=%08lx status=%08lx\n", adr, status.x[0]); | ||
387 | |||
388 | sharp_send_cmd(map, CMD_CLEAR_STATUS, adr); | ||
389 | } | ||
390 | sharp_send_cmd(map, CMD_RESET, adr); | ||
391 | chip->state = FL_READY; | ||
392 | |||
393 | wake_up(&chip->wq); | ||
394 | spin_unlock_bh(chip->mutex); | ||
395 | |||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr) | ||
400 | { | ||
401 | struct map_info *map = mtd->priv; | ||
402 | struct sharp_info *sharp = map->fldrv_priv; | ||
403 | unsigned long adr,len; | ||
404 | int chipnum, ret=0; | ||
405 | |||
406 | //printk("sharp_erase()\n"); | ||
407 | if(instr->addr & (mtd->erasesize - 1)) | ||
408 | return -EINVAL; | ||
409 | if(instr->len & (mtd->erasesize - 1)) | ||
410 | return -EINVAL; | ||
411 | if(instr->len + instr->addr > mtd->size) | ||
412 | return -EINVAL; | ||
413 | |||
414 | chipnum = instr->addr >> sharp->chipshift; | ||
415 | adr = instr->addr & ((1<<sharp->chipshift)-1); | ||
416 | len = instr->len; | ||
417 | |||
418 | while(len){ | ||
419 | ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr); | ||
420 | if(ret)return ret; | ||
421 | |||
422 | adr += mtd->erasesize; | ||
423 | len -= mtd->erasesize; | ||
424 | if(adr >> sharp->chipshift){ | ||
425 | adr = 0; | ||
426 | chipnum++; | ||
427 | if(chipnum>=sharp->numchips) | ||
428 | break; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | instr->state = MTD_ERASE_DONE; | ||
433 | mtd_erase_callback(instr); | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip, | ||
439 | unsigned long adr) | ||
440 | { | ||
441 | int ret; | ||
442 | unsigned long timeo; | ||
443 | map_word status; | ||
444 | DECLARE_WAITQUEUE(wait, current); | ||
445 | |||
446 | sharp_send_cmd(map, CMD_READ_STATUS, adr); | ||
447 | status = map_read(map, adr); | ||
448 | |||
449 | timeo = jiffies + HZ; | ||
450 | |||
451 | while(time_before(jiffies, timeo)){ | ||
452 | sharp_send_cmd(map, CMD_READ_STATUS, adr); | ||
453 | status = map_read(map, adr); | ||
454 | if((status.x[0] & SR_READY)==SR_READY){ | ||
455 | ret = 0; | ||
456 | goto out; | ||
457 | } | ||
458 | set_current_state(TASK_INTERRUPTIBLE); | ||
459 | add_wait_queue(&chip->wq, &wait); | ||
460 | |||
461 | //spin_unlock_bh(chip->mutex); | ||
462 | |||
463 | schedule_timeout(1); | ||
464 | schedule(); | ||
465 | remove_wait_queue(&chip->wq, &wait); | ||
466 | |||
467 | //spin_lock_bh(chip->mutex); | ||
468 | |||
469 | if (signal_pending(current)){ | ||
470 | ret = -EINTR; | ||
471 | goto out; | ||
472 | } | ||
473 | |||
474 | } | ||
475 | ret = -ETIME; | ||
476 | out: | ||
477 | return ret; | ||
478 | } | ||
479 | |||
480 | static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip, | ||
481 | unsigned long adr) | ||
482 | { | ||
483 | int ret; | ||
484 | //int timeo; | ||
485 | map_word status; | ||
486 | //int i; | ||
487 | |||
488 | //printk("sharp_erase_oneblock()\n"); | ||
489 | |||
490 | #ifdef AUTOUNLOCK | ||
491 | /* This seems like a good place to do an unlock */ | ||
492 | sharp_unlock_oneblock(map,chip,adr); | ||
493 | #endif | ||
494 | |||
495 | sharp_send_cmd(map, CMD_BLOCK_ERASE_1, adr); | ||
496 | sharp_send_cmd(map, CMD_BLOCK_ERASE_2, adr); | ||
497 | |||
498 | chip->state = FL_ERASING; | ||
499 | |||
500 | ret = sharp_do_wait_for_ready(map,chip,adr); | ||
501 | if(ret<0)return ret; | ||
502 | |||
503 | sharp_send_cmd(map, CMD_READ_STATUS, adr); | ||
504 | status = map_read(map, adr); | ||
505 | |||
506 | if(!(status.x[0] & SR_ERRORS)){ | ||
507 | sharp_send_cmd(map, CMD_RESET, adr); | ||
508 | chip->state = FL_READY; | ||
509 | //spin_unlock_bh(chip->mutex); | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | printk("sharp: error erasing block at addr=%08lx status=%08lx\n", adr, status.x[0]); | ||
514 | sharp_send_cmd(map, CMD_CLEAR_STATUS, adr); | ||
515 | |||
516 | //spin_unlock_bh(chip->mutex); | ||
517 | |||
518 | return -EIO; | ||
519 | } | ||
520 | |||
521 | #ifdef AUTOUNLOCK | ||
522 | static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip, | ||
523 | unsigned long adr) | ||
524 | { | ||
525 | int i; | ||
526 | map_word status; | ||
527 | |||
528 | sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_1, adr); | ||
529 | sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_2, adr); | ||
530 | |||
531 | udelay(100); | ||
532 | |||
533 | status = map_read(map, adr); | ||
534 | printk("status=%08lx\n", status.x[0]); | ||
535 | |||
536 | for(i=0;i<1000;i++){ | ||
537 | //sharp_send_cmd(map, CMD_READ_STATUS, adr); | ||
538 | status = map_read(map, adr); | ||
539 | if((status.x[0] & SR_READY) == SR_READY) | ||
540 | break; | ||
541 | udelay(100); | ||
542 | } | ||
543 | if(i==1000){ | ||
544 | printk("sharp: timed out unlocking block\n"); | ||
545 | } | ||
546 | |||
547 | if(!(status.x[0] & SR_ERRORS)){ | ||
548 | sharp_send_cmd(map, CMD_RESET, adr); | ||
549 | chip->state = FL_READY; | ||
550 | return; | ||
551 | } | ||
552 | |||
553 | printk("sharp: error unlocking block at addr=%08lx status=%08lx\n", adr, status.x[0]); | ||
554 | sharp_send_cmd(map, CMD_CLEAR_STATUS, adr); | ||
555 | } | ||
556 | #endif | ||
557 | |||
558 | static void sharp_sync(struct mtd_info *mtd) | ||
559 | { | ||
560 | //printk("sharp_sync()\n"); | ||
561 | } | ||
562 | |||
563 | static int sharp_suspend(struct mtd_info *mtd) | ||
564 | { | ||
565 | printk("sharp_suspend()\n"); | ||
566 | return -EINVAL; | ||
567 | } | ||
568 | |||
569 | static void sharp_resume(struct mtd_info *mtd) | ||
570 | { | ||
571 | printk("sharp_resume()\n"); | ||
572 | |||
573 | } | ||
574 | |||
575 | static void sharp_destroy(struct mtd_info *mtd) | ||
576 | { | ||
577 | printk("sharp_destroy()\n"); | ||
578 | |||
579 | } | ||
580 | |||
581 | static int __init sharp_probe_init(void) | ||
582 | { | ||
583 | printk("MTD Sharp chip driver <ds@lineo.com>\n"); | ||
584 | |||
585 | register_mtd_chip_driver(&sharp_chipdrv); | ||
586 | |||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static void __exit sharp_probe_exit(void) | ||
591 | { | ||
592 | unregister_mtd_chip_driver(&sharp_chipdrv); | ||
593 | } | ||
594 | |||
595 | module_init(sharp_probe_init); | ||
596 | module_exit(sharp_probe_exit); | ||
597 | |||
598 | |||
599 | MODULE_LICENSE("GPL"); | ||
600 | MODULE_AUTHOR("David Schleef <ds@schleef.org>"); | ||
601 | MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips"); | ||