1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/device.h>
21#include <linux/interrupt.h>
22#include <linux/mutex.h>
23#include <linux/math64.h>
24#include <linux/sched.h>
25
26#include <linux/mtd/mtd.h>
27#include <linux/mtd/partitions.h>
28
29#include <linux/spi/spi.h>
30#include <linux/spi/flash.h>
31
32
33#define FLASH_PAGESIZE 256
34
35
36#define OPCODE_WREN 0x06
37#define OPCODE_RDSR 0x05
38#define OPCODE_WRSR 0x01
39#define OPCODE_NORM_READ 0x03
40#define OPCODE_FAST_READ 0x0b
41#define OPCODE_PP 0x02
42#define OPCODE_BE_4K 0x20
43#define OPCODE_BE_32K 0x52
44#define OPCODE_CHIP_ERASE 0xc7
45#define OPCODE_SE 0xd8
46#define OPCODE_RDID 0x9f
47
48
49#define OPCODE_BP 0x02
50#define OPCODE_WRDI 0x04
51#define OPCODE_AAI_WP 0xad
52
53
54#define SR_WIP 1
55#define SR_WEL 2
56
57#define SR_BP0 4
58#define SR_BP1 8
59#define SR_BP2 0x10
60#define SR_SRWD 0x80
61
62
63#define MAX_READY_WAIT_JIFFIES (40 * HZ)
64#define CMD_SIZE 4
65
66#ifdef CONFIG_M25PXX_USE_FAST_READ
67#define OPCODE_READ OPCODE_FAST_READ
68#define FAST_READ_DUMMY_BYTE 1
69#else
70#define OPCODE_READ OPCODE_NORM_READ
71#define FAST_READ_DUMMY_BYTE 0
72#endif
73
74
75
76struct m25p {
77 struct spi_device *spi;
78 struct mutex lock;
79 struct mtd_info mtd;
80 unsigned partitioned:1;
81 u8 erase_opcode;
82 u8 command[CMD_SIZE + FAST_READ_DUMMY_BYTE];
83};
84
85static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
86{
87 return container_of(mtd, struct m25p, mtd);
88}
89
90
91
92
93
94
95
96
97
98
99
100
101static int read_sr(struct m25p *flash)
102{
103 ssize_t retval;
104 u8 code = OPCODE_RDSR;
105 u8 val;
106
107 retval = spi_write_then_read(flash->spi, &code, 1, &val, 1);
108
109 if (retval < 0) {
110 dev_err(&flash->spi->dev, "error %d reading SR\n",
111 (int) retval);
112 return retval;
113 }
114
115 return val;
116}
117
118
119
120
121
122static int write_sr(struct m25p *flash, u8 val)
123{
124 flash->command[0] = OPCODE_WRSR;
125 flash->command[1] = val;
126
127 return spi_write(flash->spi, flash->command, 2);
128}
129
130
131
132
133
134static inline int write_enable(struct m25p *flash)
135{
136 u8 code = OPCODE_WREN;
137
138 return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
139}
140
141
142
143
144static inline int write_disable(struct m25p *flash)
145{
146 u8 code = OPCODE_WRDI;
147
148 return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
149}
150
151
152
153
154
155static int wait_till_ready(struct m25p *flash)
156{
157 unsigned long deadline;
158 int sr;
159
160 deadline = jiffies + MAX_READY_WAIT_JIFFIES;
161
162 do {
163 if ((sr = read_sr(flash)) < 0)
164 break;
165 else if (!(sr & SR_WIP))
166 return 0;
167
168 cond_resched();
169
170 } while (!time_after_eq(jiffies, deadline));
171
172 return 1;
173}
174
175
176
177
178
179
180static int erase_chip(struct m25p *flash)
181{
182 DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %lldKiB\n",
183 dev_name(&flash->spi->dev), __func__,
184 (long long)(flash->mtd.size >> 10));
185
186
187 if (wait_till_ready(flash))
188 return 1;
189
190
191 write_enable(flash);
192
193
194 flash->command[0] = OPCODE_CHIP_ERASE;
195
196 spi_write(flash->spi, flash->command, 1);
197
198 return 0;
199}
200
201
202
203
204
205
206
207static int erase_sector(struct m25p *flash, u32 offset)
208{
209 DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n",
210 dev_name(&flash->spi->dev), __func__,
211 flash->mtd.erasesize / 1024, offset);
212
213
214 if (wait_till_ready(flash))
215 return 1;
216
217
218 write_enable(flash);
219
220
221 flash->command[0] = flash->erase_opcode;
222 flash->command[1] = offset >> 16;
223 flash->command[2] = offset >> 8;
224 flash->command[3] = offset;
225
226 spi_write(flash->spi, flash->command, CMD_SIZE);
227
228 return 0;
229}
230
231
232
233
234
235
236
237
238
239
240
241static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
242{
243 struct m25p *flash = mtd_to_m25p(mtd);
244 u32 addr,len;
245 uint32_t rem;
246
247 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%llx, len %lld\n",
248 dev_name(&flash->spi->dev), __func__, "at",
249 (long long)instr->addr, (long long)instr->len);
250
251
252 if (instr->addr + instr->len > flash->mtd.size)
253 return -EINVAL;
254 div_u64_rem(instr->len, mtd->erasesize, &rem);
255 if (rem)
256 return -EINVAL;
257
258 addr = instr->addr;
259 len = instr->len;
260
261 mutex_lock(&flash->lock);
262
263
264 if (len == flash->mtd.size) {
265 if (erase_chip(flash)) {
266 instr->state = MTD_ERASE_FAILED;
267 mutex_unlock(&flash->lock);
268 return -EIO;
269 }
270
271
272
273
274
275
276
277 } else {
278 while (len) {
279 if (erase_sector(flash, addr)) {
280 instr->state = MTD_ERASE_FAILED;
281 mutex_unlock(&flash->lock);
282 return -EIO;
283 }
284
285 addr += mtd->erasesize;
286 len -= mtd->erasesize;
287 }
288 }
289
290 mutex_unlock(&flash->lock);
291
292 instr->state = MTD_ERASE_DONE;
293 mtd_erase_callback(instr);
294
295 return 0;
296}
297
298
299
300
301
302static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
303 size_t *retlen, u_char *buf)
304{
305 struct m25p *flash = mtd_to_m25p(mtd);
306 struct spi_transfer t[2];
307 struct spi_message m;
308
309 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
310 dev_name(&flash->spi->dev), __func__, "from",
311 (u32)from, len);
312
313
314 if (!len)
315 return 0;
316
317 if (from + len > flash->mtd.size)
318 return -EINVAL;
319
320 spi_message_init(&m);
321 memset(t, 0, (sizeof t));
322
323
324
325
326
327 t[0].tx_buf = flash->command;
328 t[0].len = CMD_SIZE + FAST_READ_DUMMY_BYTE;
329 spi_message_add_tail(&t[0], &m);
330
331 t[1].rx_buf = buf;
332 t[1].len = len;
333 spi_message_add_tail(&t[1], &m);
334
335
336 if (retlen)
337 *retlen = 0;
338
339 mutex_lock(&flash->lock);
340
341
342 if (wait_till_ready(flash)) {
343
344 mutex_unlock(&flash->lock);
345 return 1;
346 }
347
348
349
350
351
352
353
354 flash->command[0] = OPCODE_READ;
355 flash->command[1] = from >> 16;
356 flash->command[2] = from >> 8;
357 flash->command[3] = from;
358
359 spi_sync(flash->spi, &m);
360
361 *retlen = m.actual_length - CMD_SIZE - FAST_READ_DUMMY_BYTE;
362
363 mutex_unlock(&flash->lock);
364
365 return 0;
366}
367
368
369
370
371
372
373static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
374 size_t *retlen, const u_char *buf)
375{
376 struct m25p *flash = mtd_to_m25p(mtd);
377 u32 page_offset, page_size;
378 struct spi_transfer t[2];
379 struct spi_message m;
380
381 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
382 dev_name(&flash->spi->dev), __func__, "to",
383 (u32)to, len);
384
385 if (retlen)
386 *retlen = 0;
387
388
389 if (!len)
390 return(0);
391
392 if (to + len > flash->mtd.size)
393 return -EINVAL;
394
395 spi_message_init(&m);
396 memset(t, 0, (sizeof t));
397
398 t[0].tx_buf = flash->command;
399 t[0].len = CMD_SIZE;
400 spi_message_add_tail(&t[0], &m);
401
402 t[1].tx_buf = buf;
403 spi_message_add_tail(&t[1], &m);
404
405 mutex_lock(&flash->lock);
406
407
408 if (wait_till_ready(flash)) {
409 mutex_unlock(&flash->lock);
410 return 1;
411 }
412
413 write_enable(flash);
414
415
416 flash->command[0] = OPCODE_PP;
417 flash->command[1] = to >> 16;
418 flash->command[2] = to >> 8;
419 flash->command[3] = to;
420
421
422 page_offset = to % FLASH_PAGESIZE;
423
424
425 if (page_offset + len <= FLASH_PAGESIZE) {
426 t[1].len = len;
427
428 spi_sync(flash->spi, &m);
429
430 *retlen = m.actual_length - CMD_SIZE;
431 } else {
432 u32 i;
433
434
435 page_size = FLASH_PAGESIZE - page_offset;
436
437 t[1].len = page_size;
438 spi_sync(flash->spi, &m);
439
440 *retlen = m.actual_length - CMD_SIZE;
441
442
443 for (i = page_size; i < len; i += page_size) {
444 page_size = len - i;
445 if (page_size > FLASH_PAGESIZE)
446 page_size = FLASH_PAGESIZE;
447
448
449 flash->command[1] = (to + i) >> 16;
450 flash->command[2] = (to + i) >> 8;
451 flash->command[3] = (to + i);
452
453 t[1].tx_buf = buf + i;
454 t[1].len = page_size;
455
456 wait_till_ready(flash);
457
458 write_enable(flash);
459
460 spi_sync(flash->spi, &m);
461
462 if (retlen)
463 *retlen += m.actual_length - CMD_SIZE;
464 }
465 }
466
467 mutex_unlock(&flash->lock);
468
469 return 0;
470}
471
472static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
473 size_t *retlen, const u_char *buf)
474{
475 struct m25p *flash = mtd_to_m25p(mtd);
476 struct spi_transfer t[2];
477 struct spi_message m;
478 size_t actual;
479 int cmd_sz, ret;
480
481 if (retlen)
482 *retlen = 0;
483
484
485 if (!len)
486 return 0;
487
488 if (to + len > flash->mtd.size)
489 return -EINVAL;
490
491 spi_message_init(&m);
492 memset(t, 0, (sizeof t));
493
494 t[0].tx_buf = flash->command;
495 t[0].len = CMD_SIZE;
496 spi_message_add_tail(&t[0], &m);
497
498 t[1].tx_buf = buf;
499 spi_message_add_tail(&t[1], &m);
500
501 mutex_lock(&flash->lock);
502
503
504 ret = wait_till_ready(flash);
505 if (ret)
506 goto time_out;
507
508 write_enable(flash);
509
510 actual = to % 2;
511
512 if (actual) {
513 flash->command[0] = OPCODE_BP;
514 flash->command[1] = to >> 16;
515 flash->command[2] = to >> 8;
516 flash->command[3] = to;
517
518
519 t[1].len = 1;
520 spi_sync(flash->spi, &m);
521 ret = wait_till_ready(flash);
522 if (ret)
523 goto time_out;
524 *retlen += m.actual_length - CMD_SIZE;
525 }
526 to += actual;
527
528 flash->command[0] = OPCODE_AAI_WP;
529 flash->command[1] = to >> 16;
530 flash->command[2] = to >> 8;
531 flash->command[3] = to;
532
533
534 cmd_sz = CMD_SIZE;
535 for (; actual < len - 1; actual += 2) {
536 t[0].len = cmd_sz;
537
538 t[1].len = 2;
539 t[1].tx_buf = buf + actual;
540
541 spi_sync(flash->spi, &m);
542 ret = wait_till_ready(flash);
543 if (ret)
544 goto time_out;
545 *retlen += m.actual_length - cmd_sz;
546 cmd_sz = 1;
547 to += 2;
548 }
549 write_disable(flash);
550 ret = wait_till_ready(flash);
551 if (ret)
552 goto time_out;
553
554
555 if (actual != len) {
556 write_enable(flash);
557 flash->command[0] = OPCODE_BP;
558 flash->command[1] = to >> 16;
559 flash->command[2] = to >> 8;
560 flash->command[3] = to;
561 t[0].len = CMD_SIZE;
562 t[1].len = 1;
563 t[1].tx_buf = buf + actual;
564
565 spi_sync(flash->spi, &m);
566 ret = wait_till_ready(flash);
567 if (ret)
568 goto time_out;
569 *retlen += m.actual_length - CMD_SIZE;
570 write_disable(flash);
571 }
572
573time_out:
574 mutex_unlock(&flash->lock);
575 return ret;
576}
577
578
579
580
581
582
583
584struct flash_info {
585 char *name;
586
587
588
589
590
591 u32 jedec_id;
592 u16 ext_id;
593
594
595
596
597 unsigned sector_size;
598 u16 n_sectors;
599
600 u16 flags;
601#define SECT_4K 0x01
602};
603
604
605
606
607
608
609static struct flash_info __devinitdata m25p_data [] = {
610
611
612 { "at25fs010", 0x1f6601, 0, 32 * 1024, 4, SECT_4K, },
613 { "at25fs040", 0x1f6604, 0, 64 * 1024, 8, SECT_4K, },
614
615 { "at25df041a", 0x1f4401, 0, 64 * 1024, 8, SECT_4K, },
616 { "at25df641", 0x1f4800, 0, 64 * 1024, 128, SECT_4K, },
617
618 { "at26f004", 0x1f0400, 0, 64 * 1024, 8, SECT_4K, },
619 { "at26df081a", 0x1f4501, 0, 64 * 1024, 16, SECT_4K, },
620 { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
621 { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
622
623
624 { "mx25l3205d", 0xc22016, 0, 64 * 1024, 64, },
625 { "mx25l6405d", 0xc22017, 0, 64 * 1024, 128, },
626 { "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, },
627 { "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, },
628
629
630
631
632 { "s25sl004a", 0x010212, 0, 64 * 1024, 8, },
633 { "s25sl008a", 0x010213, 0, 64 * 1024, 16, },
634 { "s25sl016a", 0x010214, 0, 64 * 1024, 32, },
635 { "s25sl032a", 0x010215, 0, 64 * 1024, 64, },
636 { "s25sl064a", 0x010216, 0, 64 * 1024, 128, },
637 { "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, },
638 { "s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, },
639 { "s25fl129p0", 0x012018, 0x4d00, 256 * 1024, 64, },
640 { "s25fl129p1", 0x012018, 0x4d01, 64 * 1024, 256, },
641
642
643 { "sst25vf040b", 0xbf258d, 0, 64 * 1024, 8, SECT_4K, },
644 { "sst25vf080b", 0xbf258e, 0, 64 * 1024, 16, SECT_4K, },
645 { "sst25vf016b", 0xbf2541, 0, 64 * 1024, 32, SECT_4K, },
646 { "sst25vf032b", 0xbf254a, 0, 64 * 1024, 64, SECT_4K, },
647 { "sst25wf512", 0xbf2501, 0, 64 * 1024, 1, SECT_4K, },
648 { "sst25wf010", 0xbf2502, 0, 64 * 1024, 2, SECT_4K, },
649 { "sst25wf020", 0xbf2503, 0, 64 * 1024, 4, SECT_4K, },
650 { "sst25wf040", 0xbf2504, 0, 64 * 1024, 8, SECT_4K, },
651
652
653 { "m25p05", 0x202010, 0, 32 * 1024, 2, },
654 { "m25p10", 0x202011, 0, 32 * 1024, 4, },
655 { "m25p20", 0x202012, 0, 64 * 1024, 4, },
656 { "m25p40", 0x202013, 0, 64 * 1024, 8, },
657 { "m25p80", 0, 0, 64 * 1024, 16, },
658 { "m25p16", 0x202015, 0, 64 * 1024, 32, },
659 { "m25p32", 0x202016, 0, 64 * 1024, 64, },
660 { "m25p64", 0x202017, 0, 64 * 1024, 128, },
661 { "m25p128", 0x202018, 0, 256 * 1024, 64, },
662
663 { "m45pe10", 0x204011, 0, 64 * 1024, 2, },
664 { "m45pe80", 0x204014, 0, 64 * 1024, 16, },
665 { "m45pe16", 0x204015, 0, 64 * 1024, 32, },
666
667 { "m25pe80", 0x208014, 0, 64 * 1024, 16, },
668 { "m25pe16", 0x208015, 0, 64 * 1024, 32, SECT_4K, },
669
670
671 { "w25x10", 0xef3011, 0, 64 * 1024, 2, SECT_4K, },
672 { "w25x20", 0xef3012, 0, 64 * 1024, 4, SECT_4K, },
673 { "w25x40", 0xef3013, 0, 64 * 1024, 8, SECT_4K, },
674 { "w25x80", 0xef3014, 0, 64 * 1024, 16, SECT_4K, },
675 { "w25x16", 0xef3015, 0, 64 * 1024, 32, SECT_4K, },
676 { "w25x32", 0xef3016, 0, 64 * 1024, 64, SECT_4K, },
677 { "w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K, },
678};
679
680static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
681{
682 int tmp;
683 u8 code = OPCODE_RDID;
684 u8 id[5];
685 u32 jedec;
686 u16 ext_jedec;
687 struct flash_info *info;
688
689
690
691
692
693 tmp = spi_write_then_read(spi, &code, 1, id, 5);
694 if (tmp < 0) {
695 DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
696 dev_name(&spi->dev), tmp);
697 return NULL;
698 }
699 jedec = id[0];
700 jedec = jedec << 8;
701 jedec |= id[1];
702 jedec = jedec << 8;
703 jedec |= id[2];
704
705 ext_jedec = id[3] << 8 | id[4];
706
707 for (tmp = 0, info = m25p_data;
708 tmp < ARRAY_SIZE(m25p_data);
709 tmp++, info++) {
710 if (info->jedec_id == jedec) {
711 if (info->ext_id != 0 && info->ext_id != ext_jedec)
712 continue;
713 return info;
714 }
715 }
716 dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
717 return NULL;
718}
719
720
721
722
723
724
725
726static int __devinit m25p_probe(struct spi_device *spi)
727{
728 struct flash_platform_data *data;
729 struct m25p *flash;
730 struct flash_info *info;
731 unsigned i;
732
733
734
735
736
737
738 data = spi->dev.platform_data;
739 if (data && data->type) {
740 for (i = 0, info = m25p_data;
741 i < ARRAY_SIZE(m25p_data);
742 i++, info++) {
743 if (strcmp(data->type, info->name) == 0)
744 break;
745 }
746
747
748 if (i == ARRAY_SIZE(m25p_data)) {
749 DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n",
750 dev_name(&spi->dev), data->type);
751 info = NULL;
752
753
754 } else if (info->jedec_id) {
755 struct flash_info *chip = jedec_probe(spi);
756
757 if (!chip || chip != info) {
758 dev_warn(&spi->dev, "found %s, expected %s\n",
759 chip ? chip->name : "UNKNOWN",
760 info->name);
761 info = NULL;
762 }
763 }
764 } else
765 info = jedec_probe(spi);
766
767 if (!info)
768 return -ENODEV;
769
770 flash = kzalloc(sizeof *flash, GFP_KERNEL);
771 if (!flash)
772 return -ENOMEM;
773
774 flash->spi = spi;
775 mutex_init(&flash->lock);
776 dev_set_drvdata(&spi->dev, flash);
777
778
779
780
781
782
783 if (info->jedec_id >> 16 == 0x1f) {
784 write_enable(flash);
785 write_sr(flash, 0);
786 }
787
788 if (data && data->name)
789 flash->mtd.name = data->name;
790 else
791 flash->mtd.name = dev_name(&spi->dev);
792
793 flash->mtd.type = MTD_NORFLASH;
794 flash->mtd.writesize = 1;
795 flash->mtd.flags = MTD_CAP_NORFLASH;
796 flash->mtd.size = info->sector_size * info->n_sectors;
797 flash->mtd.erase = m25p80_erase;
798 flash->mtd.read = m25p80_read;
799
800
801 if (info->jedec_id >> 16 == 0xbf)
802 flash->mtd.write = sst_write;
803 else
804 flash->mtd.write = m25p80_write;
805
806
807 if (info->flags & SECT_4K) {
808 flash->erase_opcode = OPCODE_BE_4K;
809 flash->mtd.erasesize = 4096;
810 } else {
811 flash->erase_opcode = OPCODE_SE;
812 flash->mtd.erasesize = info->sector_size;
813 }
814
815 flash->mtd.dev.parent = &spi->dev;
816
817 dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
818 (long long)flash->mtd.size >> 10);
819
820 DEBUG(MTD_DEBUG_LEVEL2,
821 "mtd .name = %s, .size = 0x%llx (%lldMiB) "
822 ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
823 flash->mtd.name,
824 (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
825 flash->mtd.erasesize, flash->mtd.erasesize / 1024,
826 flash->mtd.numeraseregions);
827
828 if (flash->mtd.numeraseregions)
829 for (i = 0; i < flash->mtd.numeraseregions; i++)
830 DEBUG(MTD_DEBUG_LEVEL2,
831 "mtd.eraseregions[%d] = { .offset = 0x%llx, "
832 ".erasesize = 0x%.8x (%uKiB), "
833 ".numblocks = %d }\n",
834 i, (long long)flash->mtd.eraseregions[i].offset,
835 flash->mtd.eraseregions[i].erasesize,
836 flash->mtd.eraseregions[i].erasesize / 1024,
837 flash->mtd.eraseregions[i].numblocks);
838
839
840
841
842
843 if (mtd_has_partitions()) {
844 struct mtd_partition *parts = NULL;
845 int nr_parts = 0;
846
847 if (mtd_has_cmdlinepart()) {
848 static const char *part_probes[]
849 = { "cmdlinepart", NULL, };
850
851 nr_parts = parse_mtd_partitions(&flash->mtd,
852 part_probes, &parts, 0);
853 }
854
855 if (nr_parts <= 0 && data && data->parts) {
856 parts = data->parts;
857 nr_parts = data->nr_parts;
858 }
859
860 if (nr_parts > 0) {
861 for (i = 0; i < nr_parts; i++) {
862 DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
863 "{.name = %s, .offset = 0x%llx, "
864 ".size = 0x%llx (%lldKiB) }\n",
865 i, parts[i].name,
866 (long long)parts[i].offset,
867 (long long)parts[i].size,
868 (long long)(parts[i].size >> 10));
869 }
870 flash->partitioned = 1;
871 return add_mtd_partitions(&flash->mtd, parts, nr_parts);
872 }
873 } else if (data && data->nr_parts)
874 dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
875 data->nr_parts, data->name);
876
877 return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0;
878}
879
880
881static int __devexit m25p_remove(struct spi_device *spi)
882{
883 struct m25p *flash = dev_get_drvdata(&spi->dev);
884 int status;
885
886
887 if (mtd_has_partitions() && flash->partitioned)
888 status = del_mtd_partitions(&flash->mtd);
889 else
890 status = del_mtd_device(&flash->mtd);
891 if (status == 0)
892 kfree(flash);
893 return 0;
894}
895
896
897static struct spi_driver m25p80_driver = {
898 .driver = {
899 .name = "m25p80",
900 .bus = &spi_bus_type,
901 .owner = THIS_MODULE,
902 },
903 .probe = m25p_probe,
904 .remove = __devexit_p(m25p_remove),
905
906
907
908
909
910};
911
912
913static int __init m25p80_init(void)
914{
915 return spi_register_driver(&m25p80_driver);
916}
917
918
919static void __exit m25p80_exit(void)
920{
921 spi_unregister_driver(&m25p80_driver);
922}
923
924
925module_init(m25p80_init);
926module_exit(m25p80_exit);
927
928MODULE_LICENSE("GPL");
929MODULE_AUTHOR("Mike Lavender");
930MODULE_DESCRIPTION("MTD SPI driver for ST M25Pxx flash chips");
931