aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-30 20:31:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-30 20:31:56 -0400
commit623ff7739e7c00fa3d55dbfd42a492a68298fd7a (patch)
tree0b7461753a1b13b27ea2958a7d48c6efb47bba54 /drivers/mtd/devices
parentc39e8ede284f469971589f2e04af78216e1a771d (diff)
parent7b0e67f604e1829e5292e1ad7743eb18dc42ea7c (diff)
Merge tag 'for-linus-3.4' of git://git.infradead.org/mtd-2.6
Pull MTD changes from David Woodhouse: - Artem's cleanup of the MTD API continues apace. - Fixes and improvements for ST FSMC and SuperH FLCTL NAND, amongst others. - More work on DiskOnChip G3, new driver for DiskOnChip G4. - Clean up debug/warning printks in JFFS2 to use pr_<level>. Fix up various trivial conflicts, largely due to changes in calling conventions for things like dmaengine_prep_slave_sg() (new inline wrapper to hide new parameter, clashing with rewrite of previously last parameter that used to be an 'append' flag, and is now a bitmap of 'unsigned long flags'). (Also some header file fallout - like so many merges this merge window - and silly conflicts with sparse fixes) * tag 'for-linus-3.4' of git://git.infradead.org/mtd-2.6: (120 commits) mtd: docg3 add protection against concurrency mtd: docg3 refactor cascade floors structure mtd: docg3 increase write/erase timeout mtd: docg3 fix inbound calculations mtd: nand: gpmi: fix function annotations mtd: phram: fix section mismatch for phram_setup mtd: unify initialization of erase_info->fail_addr mtd: support ONFI multi lun NAND mtd: sm_ftl: fix typo in major number. mtd: add device-tree support to spear_smi mtd: spear_smi: Remove default partition information from driver mtd: Add device-tree support to fsmc_nand mtd: fix section mismatch for doc_probe_device mtd: nand/fsmc: Remove sparse warnings and errors mtd: nand/fsmc: Add DMA support mtd: nand/fsmc: Access the NAND device word by word whenever possible mtd: nand/fsmc: Use dev_err to report error scenario mtd: nand/fsmc: Use devm routines mtd: nand/fsmc: Modify fsmc driver to accept nand timing parameters via platform mtd: fsmc_nand: add pm callbacks to support hibernation ...
Diffstat (limited to 'drivers/mtd/devices')
-rw-r--r--drivers/mtd/devices/Kconfig7
-rw-r--r--drivers/mtd/devices/Makefile1
-rw-r--r--drivers/mtd/devices/block2mtd.c28
-rw-r--r--drivers/mtd/devices/doc2000.c25
-rw-r--r--drivers/mtd/devices/doc2001.c22
-rw-r--r--drivers/mtd/devices/doc2001plus.c22
-rw-r--r--drivers/mtd/devices/docg3.c201
-rw-r--r--drivers/mtd/devices/docg3.h20
-rw-r--r--drivers/mtd/devices/lart.c17
-rw-r--r--drivers/mtd/devices/m25p80.c56
-rw-r--r--drivers/mtd/devices/ms02-nv.c12
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c50
-rw-r--r--drivers/mtd/devices/mtdram.c35
-rw-r--r--drivers/mtd/devices/phram.c76
-rw-r--r--drivers/mtd/devices/pmc551.c99
-rw-r--r--drivers/mtd/devices/slram.c41
-rw-r--r--drivers/mtd/devices/spear_smi.c1147
-rw-r--r--drivers/mtd/devices/sst25l.c46
18 files changed, 1444 insertions, 461 deletions
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 8d3dac40d7e6..4cdb2af7bf44 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -103,6 +103,13 @@ config M25PXX_USE_FAST_READ
103 help 103 help
104 This option enables FAST_READ access supported by ST M25Pxx. 104 This option enables FAST_READ access supported by ST M25Pxx.
105 105
106config MTD_SPEAR_SMI
107 tristate "SPEAR MTD NOR Support through SMI controller"
108 depends on PLAT_SPEAR
109 default y
110 help
111 This enable SNOR support on SPEAR platforms using SMI controller
112
106config MTD_SST25L 113config MTD_SST25L
107 tristate "Support SST25L (non JEDEC) SPI Flash chips" 114 tristate "Support SST25L (non JEDEC) SPI Flash chips"
108 depends on SPI_MASTER 115 depends on SPI_MASTER
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 56c7cd462f11..a4dd1d822b6c 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_LART) += lart.o
17obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o 17obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
18obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o 18obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
19obj-$(CONFIG_MTD_M25P80) += m25p80.o 19obj-$(CONFIG_MTD_M25P80) += m25p80.o
20obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
20obj-$(CONFIG_MTD_SST25L) += sst25l.o 21obj-$(CONFIG_MTD_SST25L) += sst25l.o
21 22
22CFLAGS_docg3.o += -I$(src) \ No newline at end of file 23CFLAGS_docg3.o += -I$(src) \ No newline at end of file
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index e7e46d1e7463..a4a80b742e65 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -104,14 +104,6 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
104 int offset = from & (PAGE_SIZE-1); 104 int offset = from & (PAGE_SIZE-1);
105 int cpylen; 105 int cpylen;
106 106
107 if (from > mtd->size)
108 return -EINVAL;
109 if (from + len > mtd->size)
110 len = mtd->size - from;
111
112 if (retlen)
113 *retlen = 0;
114
115 while (len) { 107 while (len) {
116 if ((offset + len) > PAGE_SIZE) 108 if ((offset + len) > PAGE_SIZE)
117 cpylen = PAGE_SIZE - offset; // multiple pages 109 cpylen = PAGE_SIZE - offset; // multiple pages
@@ -148,8 +140,6 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
148 int offset = to & ~PAGE_MASK; // page offset 140 int offset = to & ~PAGE_MASK; // page offset
149 int cpylen; 141 int cpylen;
150 142
151 if (retlen)
152 *retlen = 0;
153 while (len) { 143 while (len) {
154 if ((offset+len) > PAGE_SIZE) 144 if ((offset+len) > PAGE_SIZE)
155 cpylen = PAGE_SIZE - offset; // multiple pages 145 cpylen = PAGE_SIZE - offset; // multiple pages
@@ -188,13 +178,6 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
188 struct block2mtd_dev *dev = mtd->priv; 178 struct block2mtd_dev *dev = mtd->priv;
189 int err; 179 int err;
190 180
191 if (!len)
192 return 0;
193 if (to >= mtd->size)
194 return -ENOSPC;
195 if (to + len > mtd->size)
196 len = mtd->size - to;
197
198 mutex_lock(&dev->write_mutex); 181 mutex_lock(&dev->write_mutex);
199 err = _block2mtd_write(dev, buf, to, len, retlen); 182 err = _block2mtd_write(dev, buf, to, len, retlen);
200 mutex_unlock(&dev->write_mutex); 183 mutex_unlock(&dev->write_mutex);
@@ -283,13 +266,14 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
283 dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; 266 dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
284 dev->mtd.erasesize = erase_size; 267 dev->mtd.erasesize = erase_size;
285 dev->mtd.writesize = 1; 268 dev->mtd.writesize = 1;
269 dev->mtd.writebufsize = PAGE_SIZE;
286 dev->mtd.type = MTD_RAM; 270 dev->mtd.type = MTD_RAM;
287 dev->mtd.flags = MTD_CAP_RAM; 271 dev->mtd.flags = MTD_CAP_RAM;
288 dev->mtd.erase = block2mtd_erase; 272 dev->mtd._erase = block2mtd_erase;
289 dev->mtd.write = block2mtd_write; 273 dev->mtd._write = block2mtd_write;
290 dev->mtd.writev = mtd_writev; 274 dev->mtd._writev = mtd_writev;
291 dev->mtd.sync = block2mtd_sync; 275 dev->mtd._sync = block2mtd_sync;
292 dev->mtd.read = block2mtd_read; 276 dev->mtd._read = block2mtd_read;
293 dev->mtd.priv = dev; 277 dev->mtd.priv = dev;
294 dev->mtd.owner = THIS_MODULE; 278 dev->mtd.owner = THIS_MODULE;
295 279
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index b1cdf6479019..a4eb8b5b85ec 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -562,14 +562,15 @@ void DoC2k_init(struct mtd_info *mtd)
562 562
563 mtd->type = MTD_NANDFLASH; 563 mtd->type = MTD_NANDFLASH;
564 mtd->flags = MTD_CAP_NANDFLASH; 564 mtd->flags = MTD_CAP_NANDFLASH;
565 mtd->writesize = 512; 565 mtd->writebufsize = mtd->writesize = 512;
566 mtd->oobsize = 16; 566 mtd->oobsize = 16;
567 mtd->ecc_strength = 2;
567 mtd->owner = THIS_MODULE; 568 mtd->owner = THIS_MODULE;
568 mtd->erase = doc_erase; 569 mtd->_erase = doc_erase;
569 mtd->read = doc_read; 570 mtd->_read = doc_read;
570 mtd->write = doc_write; 571 mtd->_write = doc_write;
571 mtd->read_oob = doc_read_oob; 572 mtd->_read_oob = doc_read_oob;
572 mtd->write_oob = doc_write_oob; 573 mtd->_write_oob = doc_write_oob;
573 this->curfloor = -1; 574 this->curfloor = -1;
574 this->curchip = -1; 575 this->curchip = -1;
575 mutex_init(&this->lock); 576 mutex_init(&this->lock);
@@ -602,13 +603,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
602 int i, len256 = 0, ret=0; 603 int i, len256 = 0, ret=0;
603 size_t left = len; 604 size_t left = len;
604 605
605 /* Don't allow read past end of device */
606 if (from >= this->totlen)
607 return -EINVAL;
608
609 mutex_lock(&this->lock); 606 mutex_lock(&this->lock);
610
611 *retlen = 0;
612 while (left) { 607 while (left) {
613 len = left; 608 len = left;
614 609
@@ -748,13 +743,7 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
748 size_t left = len; 743 size_t left = len;
749 int status; 744 int status;
750 745
751 /* Don't allow write past end of device */
752 if (to >= this->totlen)
753 return -EINVAL;
754
755 mutex_lock(&this->lock); 746 mutex_lock(&this->lock);
756
757 *retlen = 0;
758 while (left) { 747 while (left) {
759 len = left; 748 len = left;
760 749
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 7543b98f46c4..f6927955dab0 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -346,14 +346,15 @@ void DoCMil_init(struct mtd_info *mtd)
346 346
347 /* FIXME: erase size is not always 8KiB */ 347 /* FIXME: erase size is not always 8KiB */
348 mtd->erasesize = 0x2000; 348 mtd->erasesize = 0x2000;
349 mtd->writesize = 512; 349 mtd->writebufsize = mtd->writesize = 512;
350 mtd->oobsize = 16; 350 mtd->oobsize = 16;
351 mtd->ecc_strength = 2;
351 mtd->owner = THIS_MODULE; 352 mtd->owner = THIS_MODULE;
352 mtd->erase = doc_erase; 353 mtd->_erase = doc_erase;
353 mtd->read = doc_read; 354 mtd->_read = doc_read;
354 mtd->write = doc_write; 355 mtd->_write = doc_write;
355 mtd->read_oob = doc_read_oob; 356 mtd->_read_oob = doc_read_oob;
356 mtd->write_oob = doc_write_oob; 357 mtd->_write_oob = doc_write_oob;
357 this->curfloor = -1; 358 this->curfloor = -1;
358 this->curchip = -1; 359 this->curchip = -1;
359 360
@@ -383,10 +384,6 @@ static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
383 void __iomem *docptr = this->virtadr; 384 void __iomem *docptr = this->virtadr;
384 struct Nand *mychip = &this->chips[from >> (this->chipshift)]; 385 struct Nand *mychip = &this->chips[from >> (this->chipshift)];
385 386
386 /* Don't allow read past end of device */
387 if (from >= this->totlen)
388 return -EINVAL;
389
390 /* Don't allow a single read to cross a 512-byte block boundary */ 387 /* Don't allow a single read to cross a 512-byte block boundary */
391 if (from + len > ((from | 0x1ff) + 1)) 388 if (from + len > ((from | 0x1ff) + 1))
392 len = ((from | 0x1ff) + 1) - from; 389 len = ((from | 0x1ff) + 1) - from;
@@ -494,10 +491,6 @@ static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
494 void __iomem *docptr = this->virtadr; 491 void __iomem *docptr = this->virtadr;
495 struct Nand *mychip = &this->chips[to >> (this->chipshift)]; 492 struct Nand *mychip = &this->chips[to >> (this->chipshift)];
496 493
497 /* Don't allow write past end of device */
498 if (to >= this->totlen)
499 return -EINVAL;
500
501#if 0 494#if 0
502 /* Don't allow a single write to cross a 512-byte block boundary */ 495 /* Don't allow a single write to cross a 512-byte block boundary */
503 if (to + len > ( (to | 0x1ff) + 1)) 496 if (to + len > ( (to | 0x1ff) + 1))
@@ -599,7 +592,6 @@ static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
599 printk("Error programming flash\n"); 592 printk("Error programming flash\n");
600 /* Error in programming 593 /* Error in programming
601 FIXME: implement Bad Block Replacement (in nftl.c ??) */ 594 FIXME: implement Bad Block Replacement (in nftl.c ??) */
602 *retlen = 0;
603 ret = -EIO; 595 ret = -EIO;
604 } 596 }
605 dummy = ReadDOC(docptr, LastDataRead); 597 dummy = ReadDOC(docptr, LastDataRead);
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index 177510d0e7ee..04eb2e4aa50f 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -467,14 +467,15 @@ void DoCMilPlus_init(struct mtd_info *mtd)
467 467
468 mtd->type = MTD_NANDFLASH; 468 mtd->type = MTD_NANDFLASH;
469 mtd->flags = MTD_CAP_NANDFLASH; 469 mtd->flags = MTD_CAP_NANDFLASH;
470 mtd->writesize = 512; 470 mtd->writebufsize = mtd->writesize = 512;
471 mtd->oobsize = 16; 471 mtd->oobsize = 16;
472 mtd->ecc_strength = 2;
472 mtd->owner = THIS_MODULE; 473 mtd->owner = THIS_MODULE;
473 mtd->erase = doc_erase; 474 mtd->_erase = doc_erase;
474 mtd->read = doc_read; 475 mtd->_read = doc_read;
475 mtd->write = doc_write; 476 mtd->_write = doc_write;
476 mtd->read_oob = doc_read_oob; 477 mtd->_read_oob = doc_read_oob;
477 mtd->write_oob = doc_write_oob; 478 mtd->_write_oob = doc_write_oob;
478 this->curfloor = -1; 479 this->curfloor = -1;
479 this->curchip = -1; 480 this->curchip = -1;
480 481
@@ -581,10 +582,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
581 void __iomem * docptr = this->virtadr; 582 void __iomem * docptr = this->virtadr;
582 struct Nand *mychip = &this->chips[from >> (this->chipshift)]; 583 struct Nand *mychip = &this->chips[from >> (this->chipshift)];
583 584
584 /* Don't allow read past end of device */
585 if (from >= this->totlen)
586 return -EINVAL;
587
588 /* Don't allow a single read to cross a 512-byte block boundary */ 585 /* Don't allow a single read to cross a 512-byte block boundary */
589 if (from + len > ((from | 0x1ff) + 1)) 586 if (from + len > ((from | 0x1ff) + 1))
590 len = ((from | 0x1ff) + 1) - from; 587 len = ((from | 0x1ff) + 1) - from;
@@ -700,10 +697,6 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
700 void __iomem * docptr = this->virtadr; 697 void __iomem * docptr = this->virtadr;
701 struct Nand *mychip = &this->chips[to >> (this->chipshift)]; 698 struct Nand *mychip = &this->chips[to >> (this->chipshift)];
702 699
703 /* Don't allow write past end of device */
704 if (to >= this->totlen)
705 return -EINVAL;
706
707 /* Don't allow writes which aren't exactly one block (512 bytes) */ 700 /* Don't allow writes which aren't exactly one block (512 bytes) */
708 if ((to & 0x1ff) || (len != 0x200)) 701 if ((to & 0x1ff) || (len != 0x200))
709 return -EINVAL; 702 return -EINVAL;
@@ -800,7 +793,6 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
800 printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to); 793 printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to);
801 /* Error in programming 794 /* Error in programming
802 FIXME: implement Bad Block Replacement (in nftl.c ??) */ 795 FIXME: implement Bad Block Replacement (in nftl.c ??) */
803 *retlen = 0;
804 ret = -EIO; 796 ret = -EIO;
805 } 797 }
806 dummy = ReadDOC(docptr, Mplus_LastDataRead); 798 dummy = ReadDOC(docptr, Mplus_LastDataRead);
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index ad11ef0a81f4..8272c02668d6 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -80,14 +80,9 @@ static struct nand_ecclayout docg3_oobinfo = {
80 .oobavail = 8, 80 .oobavail = 8,
81}; 81};
82 82
83/**
84 * struct docg3_bch - BCH engine
85 */
86static struct bch_control *docg3_bch;
87
88static inline u8 doc_readb(struct docg3 *docg3, u16 reg) 83static inline u8 doc_readb(struct docg3 *docg3, u16 reg)
89{ 84{
90 u8 val = readb(docg3->base + reg); 85 u8 val = readb(docg3->cascade->base + reg);
91 86
92 trace_docg3_io(0, 8, reg, (int)val); 87 trace_docg3_io(0, 8, reg, (int)val);
93 return val; 88 return val;
@@ -95,7 +90,7 @@ static inline u8 doc_readb(struct docg3 *docg3, u16 reg)
95 90
96static inline u16 doc_readw(struct docg3 *docg3, u16 reg) 91static inline u16 doc_readw(struct docg3 *docg3, u16 reg)
97{ 92{
98 u16 val = readw(docg3->base + reg); 93 u16 val = readw(docg3->cascade->base + reg);
99 94
100 trace_docg3_io(0, 16, reg, (int)val); 95 trace_docg3_io(0, 16, reg, (int)val);
101 return val; 96 return val;
@@ -103,13 +98,13 @@ static inline u16 doc_readw(struct docg3 *docg3, u16 reg)
103 98
104static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg) 99static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg)
105{ 100{
106 writeb(val, docg3->base + reg); 101 writeb(val, docg3->cascade->base + reg);
107 trace_docg3_io(1, 8, reg, val); 102 trace_docg3_io(1, 8, reg, val);
108} 103}
109 104
110static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg) 105static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg)
111{ 106{
112 writew(val, docg3->base + reg); 107 writew(val, docg3->cascade->base + reg);
113 trace_docg3_io(1, 16, reg, val); 108 trace_docg3_io(1, 16, reg, val);
114} 109}
115 110
@@ -643,7 +638,8 @@ static int doc_ecc_bch_fix_data(struct docg3 *docg3, void *buf, u8 *hwecc)
643 638
644 for (i = 0; i < DOC_ECC_BCH_SIZE; i++) 639 for (i = 0; i < DOC_ECC_BCH_SIZE; i++)
645 ecc[i] = bitrev8(hwecc[i]); 640 ecc[i] = bitrev8(hwecc[i]);
646 numerrs = decode_bch(docg3_bch, NULL, DOC_ECC_BCH_COVERED_BYTES, 641 numerrs = decode_bch(docg3->cascade->bch, NULL,
642 DOC_ECC_BCH_COVERED_BYTES,
647 NULL, ecc, NULL, errorpos); 643 NULL, ecc, NULL, errorpos);
648 BUG_ON(numerrs == -EINVAL); 644 BUG_ON(numerrs == -EINVAL);
649 if (numerrs < 0) 645 if (numerrs < 0)
@@ -734,7 +730,7 @@ err:
734 * doc_read_page_getbytes - Reads bytes from a prepared page 730 * doc_read_page_getbytes - Reads bytes from a prepared page
735 * @docg3: the device 731 * @docg3: the device
736 * @len: the number of bytes to be read (must be a multiple of 4) 732 * @len: the number of bytes to be read (must be a multiple of 4)
737 * @buf: the buffer to be filled in 733 * @buf: the buffer to be filled in (or NULL is forget bytes)
738 * @first: 1 if first time read, DOC_READADDRESS should be set 734 * @first: 1 if first time read, DOC_READADDRESS should be set
739 * 735 *
740 */ 736 */
@@ -849,7 +845,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
849 struct mtd_oob_ops *ops) 845 struct mtd_oob_ops *ops)
850{ 846{
851 struct docg3 *docg3 = mtd->priv; 847 struct docg3 *docg3 = mtd->priv;
852 int block0, block1, page, ret, ofs = 0; 848 int block0, block1, page, ret, skip, ofs = 0;
853 u8 *oobbuf = ops->oobbuf; 849 u8 *oobbuf = ops->oobbuf;
854 u8 *buf = ops->datbuf; 850 u8 *buf = ops->datbuf;
855 size_t len, ooblen, nbdata, nboob; 851 size_t len, ooblen, nbdata, nboob;
@@ -869,34 +865,36 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
869 865
870 doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n", 866 doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n",
871 from, ops->mode, buf, len, oobbuf, ooblen); 867 from, ops->mode, buf, len, oobbuf, ooblen);
872 if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % DOC_LAYOUT_OOB_SIZE) || 868 if (ooblen % DOC_LAYOUT_OOB_SIZE)
873 (from % DOC_LAYOUT_PAGE_SIZE))
874 return -EINVAL; 869 return -EINVAL;
875 870
876 ret = -EINVAL; 871 if (from + len > mtd->size)
877 calc_block_sector(from + len, &block0, &block1, &page, &ofs, 872 return -EINVAL;
878 docg3->reliable);
879 if (block1 > docg3->max_block)
880 goto err;
881 873
882 ops->oobretlen = 0; 874 ops->oobretlen = 0;
883 ops->retlen = 0; 875 ops->retlen = 0;
884 ret = 0; 876 ret = 0;
877 skip = from % DOC_LAYOUT_PAGE_SIZE;
878 mutex_lock(&docg3->cascade->lock);
885 while (!ret && (len > 0 || ooblen > 0)) { 879 while (!ret && (len > 0 || ooblen > 0)) {
886 calc_block_sector(from, &block0, &block1, &page, &ofs, 880 calc_block_sector(from - skip, &block0, &block1, &page, &ofs,
887 docg3->reliable); 881 docg3->reliable);
888 nbdata = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE); 882 nbdata = min_t(size_t, len, DOC_LAYOUT_PAGE_SIZE - skip);
889 nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE); 883 nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE);
890 ret = doc_read_page_prepare(docg3, block0, block1, page, ofs); 884 ret = doc_read_page_prepare(docg3, block0, block1, page, ofs);
891 if (ret < 0) 885 if (ret < 0)
892 goto err; 886 goto out;
893 ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); 887 ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES);
894 if (ret < 0) 888 if (ret < 0)
895 goto err_in_read; 889 goto err_in_read;
896 ret = doc_read_page_getbytes(docg3, nbdata, buf, 1); 890 ret = doc_read_page_getbytes(docg3, skip, NULL, 1);
891 if (ret < skip)
892 goto err_in_read;
893 ret = doc_read_page_getbytes(docg3, nbdata, buf, 0);
897 if (ret < nbdata) 894 if (ret < nbdata)
898 goto err_in_read; 895 goto err_in_read;
899 doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE - nbdata, 896 doc_read_page_getbytes(docg3,
897 DOC_LAYOUT_PAGE_SIZE - nbdata - skip,
900 NULL, 0); 898 NULL, 0);
901 ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0); 899 ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0);
902 if (ret < nboob) 900 if (ret < nboob)
@@ -950,13 +948,15 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
950 len -= nbdata; 948 len -= nbdata;
951 ooblen -= nboob; 949 ooblen -= nboob;
952 from += DOC_LAYOUT_PAGE_SIZE; 950 from += DOC_LAYOUT_PAGE_SIZE;
951 skip = 0;
953 } 952 }
954 953
954out:
955 mutex_unlock(&docg3->cascade->lock);
955 return ret; 956 return ret;
956err_in_read: 957err_in_read:
957 doc_read_page_finish(docg3); 958 doc_read_page_finish(docg3);
958err: 959 goto out;
959 return ret;
960} 960}
961 961
962/** 962/**
@@ -1114,10 +1114,10 @@ static int doc_get_op_status(struct docg3 *docg3)
1114 */ 1114 */
1115static int doc_write_erase_wait_status(struct docg3 *docg3) 1115static int doc_write_erase_wait_status(struct docg3 *docg3)
1116{ 1116{
1117 int status, ret = 0; 1117 int i, status, ret = 0;
1118 1118
1119 if (!doc_is_ready(docg3)) 1119 for (i = 0; !doc_is_ready(docg3) && i < 5; i++)
1120 usleep_range(3000, 3000); 1120 msleep(20);
1121 if (!doc_is_ready(docg3)) { 1121 if (!doc_is_ready(docg3)) {
1122 doc_dbg("Timeout reached and the chip is still not ready\n"); 1122 doc_dbg("Timeout reached and the chip is still not ready\n");
1123 ret = -EAGAIN; 1123 ret = -EAGAIN;
@@ -1196,18 +1196,19 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info)
1196 int block0, block1, page, ret, ofs = 0; 1196 int block0, block1, page, ret, ofs = 0;
1197 1197
1198 doc_dbg("doc_erase(from=%lld, len=%lld\n", info->addr, info->len); 1198 doc_dbg("doc_erase(from=%lld, len=%lld\n", info->addr, info->len);
1199 doc_set_device_id(docg3, docg3->device_id);
1200 1199
1201 info->state = MTD_ERASE_PENDING; 1200 info->state = MTD_ERASE_PENDING;
1202 calc_block_sector(info->addr + info->len, &block0, &block1, &page, 1201 calc_block_sector(info->addr + info->len, &block0, &block1, &page,
1203 &ofs, docg3->reliable); 1202 &ofs, docg3->reliable);
1204 ret = -EINVAL; 1203 ret = -EINVAL;
1205 if (block1 > docg3->max_block || page || ofs) 1204 if (info->addr + info->len > mtd->size || page || ofs)
1206 goto reset_err; 1205 goto reset_err;
1207 1206
1208 ret = 0; 1207 ret = 0;
1209 calc_block_sector(info->addr, &block0, &block1, &page, &ofs, 1208 calc_block_sector(info->addr, &block0, &block1, &page, &ofs,
1210 docg3->reliable); 1209 docg3->reliable);
1210 mutex_lock(&docg3->cascade->lock);
1211 doc_set_device_id(docg3, docg3->device_id);
1211 doc_set_reliable_mode(docg3); 1212 doc_set_reliable_mode(docg3);
1212 for (len = info->len; !ret && len > 0; len -= mtd->erasesize) { 1213 for (len = info->len; !ret && len > 0; len -= mtd->erasesize) {
1213 info->state = MTD_ERASING; 1214 info->state = MTD_ERASING;
@@ -1215,6 +1216,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info)
1215 block0 += 2; 1216 block0 += 2;
1216 block1 += 2; 1217 block1 += 2;
1217 } 1218 }
1219 mutex_unlock(&docg3->cascade->lock);
1218 1220
1219 if (ret) 1221 if (ret)
1220 goto reset_err; 1222 goto reset_err;
@@ -1401,7 +1403,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
1401 struct mtd_oob_ops *ops) 1403 struct mtd_oob_ops *ops)
1402{ 1404{
1403 struct docg3 *docg3 = mtd->priv; 1405 struct docg3 *docg3 = mtd->priv;
1404 int block0, block1, page, ret, pofs = 0, autoecc, oobdelta; 1406 int ret, autoecc, oobdelta;
1405 u8 *oobbuf = ops->oobbuf; 1407 u8 *oobbuf = ops->oobbuf;
1406 u8 *buf = ops->datbuf; 1408 u8 *buf = ops->datbuf;
1407 size_t len, ooblen; 1409 size_t len, ooblen;
@@ -1438,12 +1440,8 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
1438 if (len && ooblen && 1440 if (len && ooblen &&
1439 (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta)) 1441 (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta))
1440 return -EINVAL; 1442 return -EINVAL;
1441 1443 if (ofs + len > mtd->size)
1442 ret = -EINVAL; 1444 return -EINVAL;
1443 calc_block_sector(ofs + len, &block0, &block1, &page, &pofs,
1444 docg3->reliable);
1445 if (block1 > docg3->max_block)
1446 goto err;
1447 1445
1448 ops->oobretlen = 0; 1446 ops->oobretlen = 0;
1449 ops->retlen = 0; 1447 ops->retlen = 0;
@@ -1457,6 +1455,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
1457 if (autoecc < 0) 1455 if (autoecc < 0)
1458 return autoecc; 1456 return autoecc;
1459 1457
1458 mutex_lock(&docg3->cascade->lock);
1460 while (!ret && len > 0) { 1459 while (!ret && len > 0) {
1461 memset(oob, 0, sizeof(oob)); 1460 memset(oob, 0, sizeof(oob));
1462 if (ofs == docg3->oob_write_ofs) 1461 if (ofs == docg3->oob_write_ofs)
@@ -1477,8 +1476,9 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
1477 } 1476 }
1478 ops->retlen += DOC_LAYOUT_PAGE_SIZE; 1477 ops->retlen += DOC_LAYOUT_PAGE_SIZE;
1479 } 1478 }
1480err: 1479
1481 doc_set_device_id(docg3, 0); 1480 doc_set_device_id(docg3, 0);
1481 mutex_unlock(&docg3->cascade->lock);
1482 return ret; 1482 return ret;
1483} 1483}
1484 1484
@@ -1535,9 +1535,11 @@ static ssize_t dps0_is_key_locked(struct device *dev,
1535 struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); 1535 struct docg3 *docg3 = sysfs_dev2docg3(dev, attr);
1536 int dps0; 1536 int dps0;
1537 1537
1538 mutex_lock(&docg3->cascade->lock);
1538 doc_set_device_id(docg3, docg3->device_id); 1539 doc_set_device_id(docg3, docg3->device_id);
1539 dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); 1540 dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS);
1540 doc_set_device_id(docg3, 0); 1541 doc_set_device_id(docg3, 0);
1542 mutex_unlock(&docg3->cascade->lock);
1541 1543
1542 return sprintf(buf, "%d\n", !(dps0 & DOC_DPS_KEY_OK)); 1544 return sprintf(buf, "%d\n", !(dps0 & DOC_DPS_KEY_OK));
1543} 1545}
@@ -1548,9 +1550,11 @@ static ssize_t dps1_is_key_locked(struct device *dev,
1548 struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); 1550 struct docg3 *docg3 = sysfs_dev2docg3(dev, attr);
1549 int dps1; 1551 int dps1;
1550 1552
1553 mutex_lock(&docg3->cascade->lock);
1551 doc_set_device_id(docg3, docg3->device_id); 1554 doc_set_device_id(docg3, docg3->device_id);
1552 dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); 1555 dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS);
1553 doc_set_device_id(docg3, 0); 1556 doc_set_device_id(docg3, 0);
1557 mutex_unlock(&docg3->cascade->lock);
1554 1558
1555 return sprintf(buf, "%d\n", !(dps1 & DOC_DPS_KEY_OK)); 1559 return sprintf(buf, "%d\n", !(dps1 & DOC_DPS_KEY_OK));
1556} 1560}
@@ -1565,10 +1569,12 @@ static ssize_t dps0_insert_key(struct device *dev,
1565 if (count != DOC_LAYOUT_DPS_KEY_LENGTH) 1569 if (count != DOC_LAYOUT_DPS_KEY_LENGTH)
1566 return -EINVAL; 1570 return -EINVAL;
1567 1571
1572 mutex_lock(&docg3->cascade->lock);
1568 doc_set_device_id(docg3, docg3->device_id); 1573 doc_set_device_id(docg3, docg3->device_id);
1569 for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) 1574 for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++)
1570 doc_writeb(docg3, buf[i], DOC_DPS0_KEY); 1575 doc_writeb(docg3, buf[i], DOC_DPS0_KEY);
1571 doc_set_device_id(docg3, 0); 1576 doc_set_device_id(docg3, 0);
1577 mutex_unlock(&docg3->cascade->lock);
1572 return count; 1578 return count;
1573} 1579}
1574 1580
@@ -1582,10 +1588,12 @@ static ssize_t dps1_insert_key(struct device *dev,
1582 if (count != DOC_LAYOUT_DPS_KEY_LENGTH) 1588 if (count != DOC_LAYOUT_DPS_KEY_LENGTH)
1583 return -EINVAL; 1589 return -EINVAL;
1584 1590
1591 mutex_lock(&docg3->cascade->lock);
1585 doc_set_device_id(docg3, docg3->device_id); 1592 doc_set_device_id(docg3, docg3->device_id);
1586 for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) 1593 for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++)
1587 doc_writeb(docg3, buf[i], DOC_DPS1_KEY); 1594 doc_writeb(docg3, buf[i], DOC_DPS1_KEY);
1588 doc_set_device_id(docg3, 0); 1595 doc_set_device_id(docg3, 0);
1596 mutex_unlock(&docg3->cascade->lock);
1589 return count; 1597 return count;
1590} 1598}
1591 1599
@@ -1601,13 +1609,13 @@ static struct device_attribute doc_sys_attrs[DOC_MAX_NBFLOORS][4] = {
1601}; 1609};
1602 1610
1603static int doc_register_sysfs(struct platform_device *pdev, 1611static int doc_register_sysfs(struct platform_device *pdev,
1604 struct mtd_info **floors) 1612 struct docg3_cascade *cascade)
1605{ 1613{
1606 int ret = 0, floor, i = 0; 1614 int ret = 0, floor, i = 0;
1607 struct device *dev = &pdev->dev; 1615 struct device *dev = &pdev->dev;
1608 1616
1609 for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS && floors[floor]; 1617 for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS &&
1610 floor++) 1618 cascade->floors[floor]; floor++)
1611 for (i = 0; !ret && i < 4; i++) 1619 for (i = 0; !ret && i < 4; i++)
1612 ret = device_create_file(dev, &doc_sys_attrs[floor][i]); 1620 ret = device_create_file(dev, &doc_sys_attrs[floor][i]);
1613 if (!ret) 1621 if (!ret)
@@ -1621,12 +1629,12 @@ static int doc_register_sysfs(struct platform_device *pdev,
1621} 1629}
1622 1630
1623static void doc_unregister_sysfs(struct platform_device *pdev, 1631static void doc_unregister_sysfs(struct platform_device *pdev,
1624 struct mtd_info **floors) 1632 struct docg3_cascade *cascade)
1625{ 1633{
1626 struct device *dev = &pdev->dev; 1634 struct device *dev = &pdev->dev;
1627 int floor, i; 1635 int floor, i;
1628 1636
1629 for (floor = 0; floor < DOC_MAX_NBFLOORS && floors[floor]; 1637 for (floor = 0; floor < DOC_MAX_NBFLOORS && cascade->floors[floor];
1630 floor++) 1638 floor++)
1631 for (i = 0; i < 4; i++) 1639 for (i = 0; i < 4; i++)
1632 device_remove_file(dev, &doc_sys_attrs[floor][i]); 1640 device_remove_file(dev, &doc_sys_attrs[floor][i]);
@@ -1640,7 +1648,11 @@ static int dbg_flashctrl_show(struct seq_file *s, void *p)
1640 struct docg3 *docg3 = (struct docg3 *)s->private; 1648 struct docg3 *docg3 = (struct docg3 *)s->private;
1641 1649
1642 int pos = 0; 1650 int pos = 0;
1643 u8 fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); 1651 u8 fctrl;
1652
1653 mutex_lock(&docg3->cascade->lock);
1654 fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
1655 mutex_unlock(&docg3->cascade->lock);
1644 1656
1645 pos += seq_printf(s, 1657 pos += seq_printf(s,
1646 "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n", 1658 "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n",
@@ -1658,9 +1670,12 @@ static int dbg_asicmode_show(struct seq_file *s, void *p)
1658{ 1670{
1659 struct docg3 *docg3 = (struct docg3 *)s->private; 1671 struct docg3 *docg3 = (struct docg3 *)s->private;
1660 1672
1661 int pos = 0; 1673 int pos = 0, pctrl, mode;
1662 int pctrl = doc_register_readb(docg3, DOC_ASICMODE); 1674
1663 int mode = pctrl & 0x03; 1675 mutex_lock(&docg3->cascade->lock);
1676 pctrl = doc_register_readb(docg3, DOC_ASICMODE);
1677 mode = pctrl & 0x03;
1678 mutex_unlock(&docg3->cascade->lock);
1664 1679
1665 pos += seq_printf(s, 1680 pos += seq_printf(s,
1666 "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (", 1681 "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (",
@@ -1692,7 +1707,11 @@ static int dbg_device_id_show(struct seq_file *s, void *p)
1692{ 1707{
1693 struct docg3 *docg3 = (struct docg3 *)s->private; 1708 struct docg3 *docg3 = (struct docg3 *)s->private;
1694 int pos = 0; 1709 int pos = 0;
1695 int id = doc_register_readb(docg3, DOC_DEVICESELECT); 1710 int id;
1711
1712 mutex_lock(&docg3->cascade->lock);
1713 id = doc_register_readb(docg3, DOC_DEVICESELECT);
1714 mutex_unlock(&docg3->cascade->lock);
1696 1715
1697 pos += seq_printf(s, "DeviceId = %d\n", id); 1716 pos += seq_printf(s, "DeviceId = %d\n", id);
1698 return pos; 1717 return pos;
@@ -1705,6 +1724,7 @@ static int dbg_protection_show(struct seq_file *s, void *p)
1705 int pos = 0; 1724 int pos = 0;
1706 int protect, dps0, dps0_low, dps0_high, dps1, dps1_low, dps1_high; 1725 int protect, dps0, dps0_low, dps0_high, dps1, dps1_low, dps1_high;
1707 1726
1727 mutex_lock(&docg3->cascade->lock);
1708 protect = doc_register_readb(docg3, DOC_PROTECTION); 1728 protect = doc_register_readb(docg3, DOC_PROTECTION);
1709 dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); 1729 dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS);
1710 dps0_low = doc_register_readw(docg3, DOC_DPS0_ADDRLOW); 1730 dps0_low = doc_register_readw(docg3, DOC_DPS0_ADDRLOW);
@@ -1712,6 +1732,7 @@ static int dbg_protection_show(struct seq_file *s, void *p)
1712 dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); 1732 dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS);
1713 dps1_low = doc_register_readw(docg3, DOC_DPS1_ADDRLOW); 1733 dps1_low = doc_register_readw(docg3, DOC_DPS1_ADDRLOW);
1714 dps1_high = doc_register_readw(docg3, DOC_DPS1_ADDRHIGH); 1734 dps1_high = doc_register_readw(docg3, DOC_DPS1_ADDRHIGH);
1735 mutex_unlock(&docg3->cascade->lock);
1715 1736
1716 pos += seq_printf(s, "Protection = 0x%02x (", 1737 pos += seq_printf(s, "Protection = 0x%02x (",
1717 protect); 1738 protect);
@@ -1804,7 +1825,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
1804 1825
1805 switch (chip_id) { 1826 switch (chip_id) {
1806 case DOC_CHIPID_G3: 1827 case DOC_CHIPID_G3:
1807 mtd->name = kasprintf(GFP_KERNEL, "DiskOnChip G3 floor %d", 1828 mtd->name = kasprintf(GFP_KERNEL, "docg3.%d",
1808 docg3->device_id); 1829 docg3->device_id);
1809 docg3->max_block = 2047; 1830 docg3->max_block = 2047;
1810 break; 1831 break;
@@ -1817,16 +1838,17 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
1817 mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES; 1838 mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES;
1818 if (docg3->reliable == 2) 1839 if (docg3->reliable == 2)
1819 mtd->erasesize /= 2; 1840 mtd->erasesize /= 2;
1820 mtd->writesize = DOC_LAYOUT_PAGE_SIZE; 1841 mtd->writebufsize = mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
1821 mtd->oobsize = DOC_LAYOUT_OOB_SIZE; 1842 mtd->oobsize = DOC_LAYOUT_OOB_SIZE;
1822 mtd->owner = THIS_MODULE; 1843 mtd->owner = THIS_MODULE;
1823 mtd->erase = doc_erase; 1844 mtd->_erase = doc_erase;
1824 mtd->read = doc_read; 1845 mtd->_read = doc_read;
1825 mtd->write = doc_write; 1846 mtd->_write = doc_write;
1826 mtd->read_oob = doc_read_oob; 1847 mtd->_read_oob = doc_read_oob;
1827 mtd->write_oob = doc_write_oob; 1848 mtd->_write_oob = doc_write_oob;
1828 mtd->block_isbad = doc_block_isbad; 1849 mtd->_block_isbad = doc_block_isbad;
1829 mtd->ecclayout = &docg3_oobinfo; 1850 mtd->ecclayout = &docg3_oobinfo;
1851 mtd->ecc_strength = DOC_ECC_BCH_T;
1830} 1852}
1831 1853
1832/** 1854/**
@@ -1834,6 +1856,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
1834 * @base: the io space where the device is probed 1856 * @base: the io space where the device is probed
1835 * @floor: the floor of the probed device 1857 * @floor: the floor of the probed device
1836 * @dev: the device 1858 * @dev: the device
1859 * @cascade: the cascade of chips this devices will belong to
1837 * 1860 *
1838 * Checks whether a device at the specified IO range, and floor is available. 1861 * Checks whether a device at the specified IO range, and floor is available.
1839 * 1862 *
@@ -1841,8 +1864,8 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
1841 * if a memory allocation failed. If floor 0 is checked, a reset of the ASIC is 1864 * if a memory allocation failed. If floor 0 is checked, a reset of the ASIC is
1842 * launched. 1865 * launched.
1843 */ 1866 */
1844static struct mtd_info *doc_probe_device(void __iomem *base, int floor, 1867static struct mtd_info * __init
1845 struct device *dev) 1868doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev)
1846{ 1869{
1847 int ret, bbt_nbpages; 1870 int ret, bbt_nbpages;
1848 u16 chip_id, chip_id_inv; 1871 u16 chip_id, chip_id_inv;
@@ -1865,7 +1888,7 @@ static struct mtd_info *doc_probe_device(void __iomem *base, int floor,
1865 1888
1866 docg3->dev = dev; 1889 docg3->dev = dev;
1867 docg3->device_id = floor; 1890 docg3->device_id = floor;
1868 docg3->base = base; 1891 docg3->cascade = cascade;
1869 doc_set_device_id(docg3, docg3->device_id); 1892 doc_set_device_id(docg3, docg3->device_id);
1870 if (!floor) 1893 if (!floor)
1871 doc_set_asic_mode(docg3, DOC_ASICMODE_RESET); 1894 doc_set_asic_mode(docg3, DOC_ASICMODE_RESET);
@@ -1882,7 +1905,7 @@ static struct mtd_info *doc_probe_device(void __iomem *base, int floor,
1882 switch (chip_id) { 1905 switch (chip_id) {
1883 case DOC_CHIPID_G3: 1906 case DOC_CHIPID_G3:
1884 doc_info("Found a G3 DiskOnChip at addr %p, floor %d\n", 1907 doc_info("Found a G3 DiskOnChip at addr %p, floor %d\n",
1885 base, floor); 1908 docg3->cascade->base, floor);
1886 break; 1909 break;
1887 default: 1910 default:
1888 doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id); 1911 doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id);
@@ -1927,10 +1950,12 @@ static void doc_release_device(struct mtd_info *mtd)
1927static int docg3_resume(struct platform_device *pdev) 1950static int docg3_resume(struct platform_device *pdev)
1928{ 1951{
1929 int i; 1952 int i;
1953 struct docg3_cascade *cascade;
1930 struct mtd_info **docg3_floors, *mtd; 1954 struct mtd_info **docg3_floors, *mtd;
1931 struct docg3 *docg3; 1955 struct docg3 *docg3;
1932 1956
1933 docg3_floors = platform_get_drvdata(pdev); 1957 cascade = platform_get_drvdata(pdev);
1958 docg3_floors = cascade->floors;
1934 mtd = docg3_floors[0]; 1959 mtd = docg3_floors[0];
1935 docg3 = mtd->priv; 1960 docg3 = mtd->priv;
1936 1961
@@ -1952,11 +1977,13 @@ static int docg3_resume(struct platform_device *pdev)
1952static int docg3_suspend(struct platform_device *pdev, pm_message_t state) 1977static int docg3_suspend(struct platform_device *pdev, pm_message_t state)
1953{ 1978{
1954 int floor, i; 1979 int floor, i;
1980 struct docg3_cascade *cascade;
1955 struct mtd_info **docg3_floors, *mtd; 1981 struct mtd_info **docg3_floors, *mtd;
1956 struct docg3 *docg3; 1982 struct docg3 *docg3;
1957 u8 ctrl, pwr_down; 1983 u8 ctrl, pwr_down;
1958 1984
1959 docg3_floors = platform_get_drvdata(pdev); 1985 cascade = platform_get_drvdata(pdev);
1986 docg3_floors = cascade->floors;
1960 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { 1987 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) {
1961 mtd = docg3_floors[floor]; 1988 mtd = docg3_floors[floor];
1962 if (!mtd) 1989 if (!mtd)
@@ -2006,7 +2033,7 @@ static int __init docg3_probe(struct platform_device *pdev)
2006 struct resource *ress; 2033 struct resource *ress;
2007 void __iomem *base; 2034 void __iomem *base;
2008 int ret, floor, found = 0; 2035 int ret, floor, found = 0;
2009 struct mtd_info **docg3_floors; 2036 struct docg3_cascade *cascade;
2010 2037
2011 ret = -ENXIO; 2038 ret = -ENXIO;
2012 ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2039 ress = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2017,17 +2044,19 @@ static int __init docg3_probe(struct platform_device *pdev)
2017 base = ioremap(ress->start, DOC_IOSPACE_SIZE); 2044 base = ioremap(ress->start, DOC_IOSPACE_SIZE);
2018 2045
2019 ret = -ENOMEM; 2046 ret = -ENOMEM;
2020 docg3_floors = kzalloc(sizeof(*docg3_floors) * DOC_MAX_NBFLOORS, 2047 cascade = kzalloc(sizeof(*cascade) * DOC_MAX_NBFLOORS,
2021 GFP_KERNEL); 2048 GFP_KERNEL);
2022 if (!docg3_floors) 2049 if (!cascade)
2023 goto nomem1; 2050 goto nomem1;
2024 docg3_bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, 2051 cascade->base = base;
2052 mutex_init(&cascade->lock);
2053 cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T,
2025 DOC_ECC_BCH_PRIMPOLY); 2054 DOC_ECC_BCH_PRIMPOLY);
2026 if (!docg3_bch) 2055 if (!cascade->bch)
2027 goto nomem2; 2056 goto nomem2;
2028 2057
2029 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { 2058 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) {
2030 mtd = doc_probe_device(base, floor, dev); 2059 mtd = doc_probe_device(cascade, floor, dev);
2031 if (IS_ERR(mtd)) { 2060 if (IS_ERR(mtd)) {
2032 ret = PTR_ERR(mtd); 2061 ret = PTR_ERR(mtd);
2033 goto err_probe; 2062 goto err_probe;
@@ -2038,7 +2067,7 @@ static int __init docg3_probe(struct platform_device *pdev)
2038 else 2067 else
2039 continue; 2068 continue;
2040 } 2069 }
2041 docg3_floors[floor] = mtd; 2070 cascade->floors[floor] = mtd;
2042 ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 2071 ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL,
2043 0); 2072 0);
2044 if (ret) 2073 if (ret)
@@ -2046,26 +2075,26 @@ static int __init docg3_probe(struct platform_device *pdev)
2046 found++; 2075 found++;
2047 } 2076 }
2048 2077
2049 ret = doc_register_sysfs(pdev, docg3_floors); 2078 ret = doc_register_sysfs(pdev, cascade);
2050 if (ret) 2079 if (ret)
2051 goto err_probe; 2080 goto err_probe;
2052 if (!found) 2081 if (!found)
2053 goto notfound; 2082 goto notfound;
2054 2083
2055 platform_set_drvdata(pdev, docg3_floors); 2084 platform_set_drvdata(pdev, cascade);
2056 doc_dbg_register(docg3_floors[0]->priv); 2085 doc_dbg_register(cascade->floors[0]->priv);
2057 return 0; 2086 return 0;
2058 2087
2059notfound: 2088notfound:
2060 ret = -ENODEV; 2089 ret = -ENODEV;
2061 dev_info(dev, "No supported DiskOnChip found\n"); 2090 dev_info(dev, "No supported DiskOnChip found\n");
2062err_probe: 2091err_probe:
2063 free_bch(docg3_bch); 2092 kfree(cascade->bch);
2064 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) 2093 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
2065 if (docg3_floors[floor]) 2094 if (cascade->floors[floor])
2066 doc_release_device(docg3_floors[floor]); 2095 doc_release_device(cascade->floors[floor]);
2067nomem2: 2096nomem2:
2068 kfree(docg3_floors); 2097 kfree(cascade);
2069nomem1: 2098nomem1:
2070 iounmap(base); 2099 iounmap(base);
2071noress: 2100noress:
@@ -2080,19 +2109,19 @@ noress:
2080 */ 2109 */
2081static int __exit docg3_release(struct platform_device *pdev) 2110static int __exit docg3_release(struct platform_device *pdev)
2082{ 2111{
2083 struct mtd_info **docg3_floors = platform_get_drvdata(pdev); 2112 struct docg3_cascade *cascade = platform_get_drvdata(pdev);
2084 struct docg3 *docg3 = docg3_floors[0]->priv; 2113 struct docg3 *docg3 = cascade->floors[0]->priv;
2085 void __iomem *base = docg3->base; 2114 void __iomem *base = cascade->base;
2086 int floor; 2115 int floor;
2087 2116
2088 doc_unregister_sysfs(pdev, docg3_floors); 2117 doc_unregister_sysfs(pdev, cascade);
2089 doc_dbg_unregister(docg3); 2118 doc_dbg_unregister(docg3);
2090 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) 2119 for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
2091 if (docg3_floors[floor]) 2120 if (cascade->floors[floor])
2092 doc_release_device(docg3_floors[floor]); 2121 doc_release_device(cascade->floors[floor]);
2093 2122
2094 kfree(docg3_floors); 2123 free_bch(docg3->cascade->bch);
2095 free_bch(docg3_bch); 2124 kfree(cascade);
2096 iounmap(base); 2125 iounmap(base);
2097 return 0; 2126 return 0;
2098} 2127}
diff --git a/drivers/mtd/devices/docg3.h b/drivers/mtd/devices/docg3.h
index db0da436b493..19fb93f96a3a 100644
--- a/drivers/mtd/devices/docg3.h
+++ b/drivers/mtd/devices/docg3.h
@@ -22,6 +22,8 @@
22#ifndef _MTD_DOCG3_H 22#ifndef _MTD_DOCG3_H
23#define _MTD_DOCG3_H 23#define _MTD_DOCG3_H
24 24
25#include <linux/mtd/mtd.h>
26
25/* 27/*
26 * Flash memory areas : 28 * Flash memory areas :
27 * - 0x0000 .. 0x07ff : IPL 29 * - 0x0000 .. 0x07ff : IPL
@@ -267,9 +269,23 @@
267#define DOC_LAYOUT_DPS_KEY_LENGTH 8 269#define DOC_LAYOUT_DPS_KEY_LENGTH 8
268 270
269/** 271/**
272 * struct docg3_cascade - Cascade of 1 to 4 docg3 chips
273 * @floors: floors (ie. one physical docg3 chip is one floor)
274 * @base: IO space to access all chips in the cascade
275 * @bch: the BCH correcting control structure
276 * @lock: lock to protect docg3 IO space from concurrent accesses
277 */
278struct docg3_cascade {
279 struct mtd_info *floors[DOC_MAX_NBFLOORS];
280 void __iomem *base;
281 struct bch_control *bch;
282 struct mutex lock;
283};
284
285/**
270 * struct docg3 - DiskOnChip driver private data 286 * struct docg3 - DiskOnChip driver private data
271 * @dev: the device currently under control 287 * @dev: the device currently under control
272 * @base: mapped IO space 288 * @cascade: the cascade this device belongs to
273 * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3) 289 * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
274 * @if_cfg: if true, reads are on 16bits, else reads are on 8bits 290 * @if_cfg: if true, reads are on 16bits, else reads are on 8bits
275 291
@@ -287,7 +303,7 @@
287 */ 303 */
288struct docg3 { 304struct docg3 {
289 struct device *dev; 305 struct device *dev;
290 void __iomem *base; 306 struct docg3_cascade *cascade;
291 unsigned int device_id:4; 307 unsigned int device_id:4;
292 unsigned int if_cfg:1; 308 unsigned int if_cfg:1;
293 unsigned int reliable:2; 309 unsigned int reliable:2;
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index 3a11ea628e58..82bd00af5cc3 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -367,9 +367,6 @@ static int flash_erase (struct mtd_info *mtd,struct erase_info *instr)
367 printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n", __func__, instr->addr, instr->len); 367 printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n", __func__, instr->addr, instr->len);
368#endif 368#endif
369 369
370 /* sanity checks */
371 if (instr->addr + instr->len > mtd->size) return (-EINVAL);
372
373 /* 370 /*
374 * check that both start and end of the requested erase are 371 * check that both start and end of the requested erase are
375 * aligned with the erasesize at the appropriate addresses. 372 * aligned with the erasesize at the appropriate addresses.
@@ -440,10 +437,6 @@ static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retle
440 printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n", __func__, (__u32)from, len); 437 printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n", __func__, (__u32)from, len);
441#endif 438#endif
442 439
443 /* sanity checks */
444 if (!len) return (0);
445 if (from + len > mtd->size) return (-EINVAL);
446
447 /* we always read len bytes */ 440 /* we always read len bytes */
448 *retlen = len; 441 *retlen = len;
449 442
@@ -522,11 +515,8 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen
522 printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n", __func__, (__u32)to, len); 515 printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n", __func__, (__u32)to, len);
523#endif 516#endif
524 517
525 *retlen = 0;
526
527 /* sanity checks */ 518 /* sanity checks */
528 if (!len) return (0); 519 if (!len) return (0);
529 if (to + len > mtd->size) return (-EINVAL);
530 520
531 /* first, we write a 0xFF.... padded byte until we reach a dword boundary */ 521 /* first, we write a 0xFF.... padded byte until we reach a dword boundary */
532 if (to & (BUSWIDTH - 1)) 522 if (to & (BUSWIDTH - 1))
@@ -630,14 +620,15 @@ static int __init lart_flash_init (void)
630 mtd.name = module_name; 620 mtd.name = module_name;
631 mtd.type = MTD_NORFLASH; 621 mtd.type = MTD_NORFLASH;
632 mtd.writesize = 1; 622 mtd.writesize = 1;
623 mtd.writebufsize = 4;
633 mtd.flags = MTD_CAP_NORFLASH; 624 mtd.flags = MTD_CAP_NORFLASH;
634 mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; 625 mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN;
635 mtd.erasesize = FLASH_BLOCKSIZE_MAIN; 626 mtd.erasesize = FLASH_BLOCKSIZE_MAIN;
636 mtd.numeraseregions = ARRAY_SIZE(erase_regions); 627 mtd.numeraseregions = ARRAY_SIZE(erase_regions);
637 mtd.eraseregions = erase_regions; 628 mtd.eraseregions = erase_regions;
638 mtd.erase = flash_erase; 629 mtd._erase = flash_erase;
639 mtd.read = flash_read; 630 mtd._read = flash_read;
640 mtd.write = flash_write; 631 mtd._write = flash_write;
641 mtd.owner = THIS_MODULE; 632 mtd.owner = THIS_MODULE;
642 633
643#ifdef LART_DEBUG 634#ifdef LART_DEBUG
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 7c60dddbefc0..1924d247c1cb 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -288,9 +288,6 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
288 __func__, (long long)instr->addr, 288 __func__, (long long)instr->addr,
289 (long long)instr->len); 289 (long long)instr->len);
290 290
291 /* sanity checks */
292 if (instr->addr + instr->len > flash->mtd.size)
293 return -EINVAL;
294 div_u64_rem(instr->len, mtd->erasesize, &rem); 291 div_u64_rem(instr->len, mtd->erasesize, &rem);
295 if (rem) 292 if (rem)
296 return -EINVAL; 293 return -EINVAL;
@@ -349,13 +346,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
349 pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), 346 pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
350 __func__, (u32)from, len); 347 __func__, (u32)from, len);
351 348
352 /* sanity checks */
353 if (!len)
354 return 0;
355
356 if (from + len > flash->mtd.size)
357 return -EINVAL;
358
359 spi_message_init(&m); 349 spi_message_init(&m);
360 memset(t, 0, (sizeof t)); 350 memset(t, 0, (sizeof t));
361 351
@@ -371,9 +361,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
371 t[1].len = len; 361 t[1].len = len;
372 spi_message_add_tail(&t[1], &m); 362 spi_message_add_tail(&t[1], &m);
373 363
374 /* Byte count starts at zero. */
375 *retlen = 0;
376
377 mutex_lock(&flash->lock); 364 mutex_lock(&flash->lock);
378 365
379 /* Wait till previous write/erase is done. */ 366 /* Wait till previous write/erase is done. */
@@ -417,15 +404,6 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
417 pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), 404 pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
418 __func__, (u32)to, len); 405 __func__, (u32)to, len);
419 406
420 *retlen = 0;
421
422 /* sanity checks */
423 if (!len)
424 return(0);
425
426 if (to + len > flash->mtd.size)
427 return -EINVAL;
428
429 spi_message_init(&m); 407 spi_message_init(&m);
430 memset(t, 0, (sizeof t)); 408 memset(t, 0, (sizeof t));
431 409
@@ -509,15 +487,6 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
509 pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), 487 pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
510 __func__, (u32)to, len); 488 __func__, (u32)to, len);
511 489
512 *retlen = 0;
513
514 /* sanity checks */
515 if (!len)
516 return 0;
517
518 if (to + len > flash->mtd.size)
519 return -EINVAL;
520
521 spi_message_init(&m); 490 spi_message_init(&m);
522 memset(t, 0, (sizeof t)); 491 memset(t, 0, (sizeof t));
523 492
@@ -908,14 +877,14 @@ static int __devinit m25p_probe(struct spi_device *spi)
908 flash->mtd.writesize = 1; 877 flash->mtd.writesize = 1;
909 flash->mtd.flags = MTD_CAP_NORFLASH; 878 flash->mtd.flags = MTD_CAP_NORFLASH;
910 flash->mtd.size = info->sector_size * info->n_sectors; 879 flash->mtd.size = info->sector_size * info->n_sectors;
911 flash->mtd.erase = m25p80_erase; 880 flash->mtd._erase = m25p80_erase;
912 flash->mtd.read = m25p80_read; 881 flash->mtd._read = m25p80_read;
913 882
914 /* sst flash chips use AAI word program */ 883 /* sst flash chips use AAI word program */
915 if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) 884 if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST)
916 flash->mtd.write = sst_write; 885 flash->mtd._write = sst_write;
917 else 886 else
918 flash->mtd.write = m25p80_write; 887 flash->mtd._write = m25p80_write;
919 888
920 /* prefer "small sector" erase if possible */ 889 /* prefer "small sector" erase if possible */
921 if (info->flags & SECT_4K) { 890 if (info->flags & SECT_4K) {
@@ -932,6 +901,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
932 ppdata.of_node = spi->dev.of_node; 901 ppdata.of_node = spi->dev.of_node;
933 flash->mtd.dev.parent = &spi->dev; 902 flash->mtd.dev.parent = &spi->dev;
934 flash->page_size = info->page_size; 903 flash->page_size = info->page_size;
904 flash->mtd.writebufsize = flash->page_size;
935 905
936 if (info->addr_width) 906 if (info->addr_width)
937 flash->addr_width = info->addr_width; 907 flash->addr_width = info->addr_width;
@@ -1004,21 +974,7 @@ static struct spi_driver m25p80_driver = {
1004 */ 974 */
1005}; 975};
1006 976
1007 977module_spi_driver(m25p80_driver);
1008static int __init m25p80_init(void)
1009{
1010 return spi_register_driver(&m25p80_driver);
1011}
1012
1013
1014static void __exit m25p80_exit(void)
1015{
1016 spi_unregister_driver(&m25p80_driver);
1017}
1018
1019
1020module_init(m25p80_init);
1021module_exit(m25p80_exit);
1022 978
1023MODULE_LICENSE("GPL"); 979MODULE_LICENSE("GPL");
1024MODULE_AUTHOR("Mike Lavender"); 980MODULE_AUTHOR("Mike Lavender");
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index 8423fb6d4f26..182849d39c61 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -59,12 +59,8 @@ static int ms02nv_read(struct mtd_info *mtd, loff_t from,
59{ 59{
60 struct ms02nv_private *mp = mtd->priv; 60 struct ms02nv_private *mp = mtd->priv;
61 61
62 if (from + len > mtd->size)
63 return -EINVAL;
64
65 memcpy(buf, mp->uaddr + from, len); 62 memcpy(buf, mp->uaddr + from, len);
66 *retlen = len; 63 *retlen = len;
67
68 return 0; 64 return 0;
69} 65}
70 66
@@ -73,12 +69,8 @@ static int ms02nv_write(struct mtd_info *mtd, loff_t to,
73{ 69{
74 struct ms02nv_private *mp = mtd->priv; 70 struct ms02nv_private *mp = mtd->priv;
75 71
76 if (to + len > mtd->size)
77 return -EINVAL;
78
79 memcpy(mp->uaddr + to, buf, len); 72 memcpy(mp->uaddr + to, buf, len);
80 *retlen = len; 73 *retlen = len;
81
82 return 0; 74 return 0;
83} 75}
84 76
@@ -215,8 +207,8 @@ static int __init ms02nv_init_one(ulong addr)
215 mtd->size = fixsize; 207 mtd->size = fixsize;
216 mtd->name = (char *)ms02nv_name; 208 mtd->name = (char *)ms02nv_name;
217 mtd->owner = THIS_MODULE; 209 mtd->owner = THIS_MODULE;
218 mtd->read = ms02nv_read; 210 mtd->_read = ms02nv_read;
219 mtd->write = ms02nv_write; 211 mtd->_write = ms02nv_write;
220 mtd->writesize = 1; 212 mtd->writesize = 1;
221 213
222 ret = -EIO; 214 ret = -EIO;
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 236057ead0d2..928fb0e6d73a 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -164,9 +164,6 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
164 dev_name(&spi->dev), (long long)instr->addr, 164 dev_name(&spi->dev), (long long)instr->addr,
165 (long long)instr->len); 165 (long long)instr->len);
166 166
167 /* Sanity checks */
168 if (instr->addr + instr->len > mtd->size)
169 return -EINVAL;
170 div_u64_rem(instr->len, priv->page_size, &rem); 167 div_u64_rem(instr->len, priv->page_size, &rem);
171 if (rem) 168 if (rem)
172 return -EINVAL; 169 return -EINVAL;
@@ -252,14 +249,6 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
252 pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev), 249 pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev),
253 (unsigned)from, (unsigned)(from + len)); 250 (unsigned)from, (unsigned)(from + len));
254 251
255 *retlen = 0;
256
257 /* Sanity checks */
258 if (!len)
259 return 0;
260 if (from + len > mtd->size)
261 return -EINVAL;
262
263 /* Calculate flash page/byte address */ 252 /* Calculate flash page/byte address */
264 addr = (((unsigned)from / priv->page_size) << priv->page_offset) 253 addr = (((unsigned)from / priv->page_size) << priv->page_offset)
265 + ((unsigned)from % priv->page_size); 254 + ((unsigned)from % priv->page_size);
@@ -328,14 +317,6 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
328 pr_debug("%s: write 0x%x..0x%x\n", 317 pr_debug("%s: write 0x%x..0x%x\n",
329 dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len)); 318 dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len));
330 319
331 *retlen = 0;
332
333 /* Sanity checks */
334 if (!len)
335 return 0;
336 if ((to + len) > mtd->size)
337 return -EINVAL;
338
339 spi_message_init(&msg); 320 spi_message_init(&msg);
340 321
341 x[0].tx_buf = command = priv->command; 322 x[0].tx_buf = command = priv->command;
@@ -490,8 +471,6 @@ static ssize_t otp_read(struct spi_device *spi, unsigned base,
490 471
491 if ((off + len) > 64) 472 if ((off + len) > 64)
492 len = 64 - off; 473 len = 64 - off;
493 if (len == 0)
494 return len;
495 474
496 spi_message_init(&m); 475 spi_message_init(&m);
497 476
@@ -611,16 +590,16 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
611 590
612static char *otp_setup(struct mtd_info *device, char revision) 591static char *otp_setup(struct mtd_info *device, char revision)
613{ 592{
614 device->get_fact_prot_info = dataflash_get_otp_info; 593 device->_get_fact_prot_info = dataflash_get_otp_info;
615 device->read_fact_prot_reg = dataflash_read_fact_otp; 594 device->_read_fact_prot_reg = dataflash_read_fact_otp;
616 device->get_user_prot_info = dataflash_get_otp_info; 595 device->_get_user_prot_info = dataflash_get_otp_info;
617 device->read_user_prot_reg = dataflash_read_user_otp; 596 device->_read_user_prot_reg = dataflash_read_user_otp;
618 597
619 /* rev c parts (at45db321c and at45db1281 only!) use a 598 /* rev c parts (at45db321c and at45db1281 only!) use a
620 * different write procedure; not (yet?) implemented. 599 * different write procedure; not (yet?) implemented.
621 */ 600 */
622 if (revision > 'c') 601 if (revision > 'c')
623 device->write_user_prot_reg = dataflash_write_user_otp; 602 device->_write_user_prot_reg = dataflash_write_user_otp;
624 603
625 return ", OTP"; 604 return ", OTP";
626} 605}
@@ -672,9 +651,9 @@ add_dataflash_otp(struct spi_device *spi, char *name,
672 device->owner = THIS_MODULE; 651 device->owner = THIS_MODULE;
673 device->type = MTD_DATAFLASH; 652 device->type = MTD_DATAFLASH;
674 device->flags = MTD_WRITEABLE; 653 device->flags = MTD_WRITEABLE;
675 device->erase = dataflash_erase; 654 device->_erase = dataflash_erase;
676 device->read = dataflash_read; 655 device->_read = dataflash_read;
677 device->write = dataflash_write; 656 device->_write = dataflash_write;
678 device->priv = priv; 657 device->priv = priv;
679 658
680 device->dev.parent = &spi->dev; 659 device->dev.parent = &spi->dev;
@@ -946,18 +925,7 @@ static struct spi_driver dataflash_driver = {
946 /* FIXME: investigate suspend and resume... */ 925 /* FIXME: investigate suspend and resume... */
947}; 926};
948 927
949static int __init dataflash_init(void) 928module_spi_driver(dataflash_driver);
950{
951 return spi_register_driver(&dataflash_driver);
952}
953module_init(dataflash_init);
954
955static void __exit dataflash_exit(void)
956{
957 spi_unregister_driver(&dataflash_driver);
958}
959module_exit(dataflash_exit);
960
961 929
962MODULE_LICENSE("GPL"); 930MODULE_LICENSE("GPL");
963MODULE_AUTHOR("Andrew Victor, David Brownell"); 931MODULE_AUTHOR("Andrew Victor, David Brownell");
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index 2562689ba6b4..ec59d65897fb 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -34,34 +34,23 @@ static struct mtd_info *mtd_info;
34 34
35static int ram_erase(struct mtd_info *mtd, struct erase_info *instr) 35static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
36{ 36{
37 if (instr->addr + instr->len > mtd->size)
38 return -EINVAL;
39
40 memset((char *)mtd->priv + instr->addr, 0xff, instr->len); 37 memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
41
42 instr->state = MTD_ERASE_DONE; 38 instr->state = MTD_ERASE_DONE;
43 mtd_erase_callback(instr); 39 mtd_erase_callback(instr);
44
45 return 0; 40 return 0;
46} 41}
47 42
48static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, 43static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
49 size_t *retlen, void **virt, resource_size_t *phys) 44 size_t *retlen, void **virt, resource_size_t *phys)
50{ 45{
51 if (from + len > mtd->size)
52 return -EINVAL;
53
54 /* can we return a physical address with this driver? */
55 if (phys)
56 return -EINVAL;
57
58 *virt = mtd->priv + from; 46 *virt = mtd->priv + from;
59 *retlen = len; 47 *retlen = len;
60 return 0; 48 return 0;
61} 49}
62 50
63static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 51static int ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
64{ 52{
53 return 0;
65} 54}
66 55
67/* 56/*
@@ -80,11 +69,7 @@ static unsigned long ram_get_unmapped_area(struct mtd_info *mtd,
80static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, 69static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
81 size_t *retlen, u_char *buf) 70 size_t *retlen, u_char *buf)
82{ 71{
83 if (from + len > mtd->size)
84 return -EINVAL;
85
86 memcpy(buf, mtd->priv + from, len); 72 memcpy(buf, mtd->priv + from, len);
87
88 *retlen = len; 73 *retlen = len;
89 return 0; 74 return 0;
90} 75}
@@ -92,11 +77,7 @@ static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
92static int ram_write(struct mtd_info *mtd, loff_t to, size_t len, 77static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
93 size_t *retlen, const u_char *buf) 78 size_t *retlen, const u_char *buf)
94{ 79{
95 if (to + len > mtd->size)
96 return -EINVAL;
97
98 memcpy((char *)mtd->priv + to, buf, len); 80 memcpy((char *)mtd->priv + to, buf, len);
99
100 *retlen = len; 81 *retlen = len;
101 return 0; 82 return 0;
102} 83}
@@ -126,12 +107,12 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
126 mtd->priv = mapped_address; 107 mtd->priv = mapped_address;
127 108
128 mtd->owner = THIS_MODULE; 109 mtd->owner = THIS_MODULE;
129 mtd->erase = ram_erase; 110 mtd->_erase = ram_erase;
130 mtd->point = ram_point; 111 mtd->_point = ram_point;
131 mtd->unpoint = ram_unpoint; 112 mtd->_unpoint = ram_unpoint;
132 mtd->get_unmapped_area = ram_get_unmapped_area; 113 mtd->_get_unmapped_area = ram_get_unmapped_area;
133 mtd->read = ram_read; 114 mtd->_read = ram_read;
134 mtd->write = ram_write; 115 mtd->_write = ram_write;
135 116
136 if (mtd_device_register(mtd, NULL, 0)) 117 if (mtd_device_register(mtd, NULL, 0))
137 return -EIO; 118 return -EIO;
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 23423bd00b06..67823de68db6 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -33,45 +33,33 @@ struct phram_mtd_list {
33 33
34static LIST_HEAD(phram_list); 34static LIST_HEAD(phram_list);
35 35
36
37static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) 36static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
38{ 37{
39 u_char *start = mtd->priv; 38 u_char *start = mtd->priv;
40 39
41 if (instr->addr + instr->len > mtd->size)
42 return -EINVAL;
43
44 memset(start + instr->addr, 0xff, instr->len); 40 memset(start + instr->addr, 0xff, instr->len);
45 41
46 /* This'll catch a few races. Free the thing before returning :) 42 /*
43 * This'll catch a few races. Free the thing before returning :)
47 * I don't feel at all ashamed. This kind of thing is possible anyway 44 * I don't feel at all ashamed. This kind of thing is possible anyway
48 * with flash, but unlikely. 45 * with flash, but unlikely.
49 */ 46 */
50
51 instr->state = MTD_ERASE_DONE; 47 instr->state = MTD_ERASE_DONE;
52
53 mtd_erase_callback(instr); 48 mtd_erase_callback(instr);
54
55 return 0; 49 return 0;
56} 50}
57 51
58static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, 52static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
59 size_t *retlen, void **virt, resource_size_t *phys) 53 size_t *retlen, void **virt, resource_size_t *phys)
60{ 54{
61 if (from + len > mtd->size)
62 return -EINVAL;
63
64 /* can we return a physical address with this driver? */
65 if (phys)
66 return -EINVAL;
67
68 *virt = mtd->priv + from; 55 *virt = mtd->priv + from;
69 *retlen = len; 56 *retlen = len;
70 return 0; 57 return 0;
71} 58}
72 59
73static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 60static int phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
74{ 61{
62 return 0;
75} 63}
76 64
77static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, 65static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
@@ -79,14 +67,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
79{ 67{
80 u_char *start = mtd->priv; 68 u_char *start = mtd->priv;
81 69
82 if (from >= mtd->size)
83 return -EINVAL;
84
85 if (len > mtd->size - from)
86 len = mtd->size - from;
87
88 memcpy(buf, start + from, len); 70 memcpy(buf, start + from, len);
89
90 *retlen = len; 71 *retlen = len;
91 return 0; 72 return 0;
92} 73}
@@ -96,20 +77,11 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
96{ 77{
97 u_char *start = mtd->priv; 78 u_char *start = mtd->priv;
98 79
99 if (to >= mtd->size)
100 return -EINVAL;
101
102 if (len > mtd->size - to)
103 len = mtd->size - to;
104
105 memcpy(start + to, buf, len); 80 memcpy(start + to, buf, len);
106
107 *retlen = len; 81 *retlen = len;
108 return 0; 82 return 0;
109} 83}
110 84
111
112
113static void unregister_devices(void) 85static void unregister_devices(void)
114{ 86{
115 struct phram_mtd_list *this, *safe; 87 struct phram_mtd_list *this, *safe;
@@ -142,11 +114,11 @@ static int register_device(char *name, unsigned long start, unsigned long len)
142 new->mtd.name = name; 114 new->mtd.name = name;
143 new->mtd.size = len; 115 new->mtd.size = len;
144 new->mtd.flags = MTD_CAP_RAM; 116 new->mtd.flags = MTD_CAP_RAM;
145 new->mtd.erase = phram_erase; 117 new->mtd._erase = phram_erase;
146 new->mtd.point = phram_point; 118 new->mtd._point = phram_point;
147 new->mtd.unpoint = phram_unpoint; 119 new->mtd._unpoint = phram_unpoint;
148 new->mtd.read = phram_read; 120 new->mtd._read = phram_read;
149 new->mtd.write = phram_write; 121 new->mtd._write = phram_write;
150 new->mtd.owner = THIS_MODULE; 122 new->mtd.owner = THIS_MODULE;
151 new->mtd.type = MTD_RAM; 123 new->mtd.type = MTD_RAM;
152 new->mtd.erasesize = PAGE_SIZE; 124 new->mtd.erasesize = PAGE_SIZE;
@@ -233,7 +205,17 @@ static inline void kill_final_newline(char *str)
233 return 1; \ 205 return 1; \
234} while (0) 206} while (0)
235 207
236static int phram_setup(const char *val, struct kernel_param *kp) 208/*
209 * This shall contain the module parameter if any. It is of the form:
210 * - phram=<device>,<address>,<size> for module case
211 * - phram.phram=<device>,<address>,<size> for built-in case
212 * We leave 64 bytes for the device name, 12 for the address and 12 for the
213 * size.
214 * Example: phram.phram=rootfs,0xa0000000,512Mi
215 */
216static __initdata char phram_paramline[64+12+12];
217
218static int __init phram_setup(const char *val)
237{ 219{
238 char buf[64+12+12], *str = buf; 220 char buf[64+12+12], *str = buf;
239 char *token[3]; 221 char *token[3];
@@ -282,12 +264,28 @@ static int phram_setup(const char *val, struct kernel_param *kp)
282 return ret; 264 return ret;
283} 265}
284 266
285module_param_call(phram, phram_setup, NULL, NULL, 000); 267static int __init phram_param_call(const char *val, struct kernel_param *kp)
268{
269 /*
270 * This function is always called before 'init_phram()', whether
271 * built-in or module.
272 */
273 if (strlen(val) >= sizeof(phram_paramline))
274 return -ENOSPC;
275 strcpy(phram_paramline, val);
276
277 return 0;
278}
279
280module_param_call(phram, phram_param_call, NULL, NULL, 000);
286MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\""); 281MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\"");
287 282
288 283
289static int __init init_phram(void) 284static int __init init_phram(void)
290{ 285{
286 if (phram_paramline[0])
287 return phram_setup(phram_paramline);
288
291 return 0; 289 return 0;
292} 290}
293 291
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index 5d53c5760a6c..0c51b988e1f8 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -94,12 +94,48 @@
94#include <linux/ioctl.h> 94#include <linux/ioctl.h>
95#include <asm/io.h> 95#include <asm/io.h>
96#include <linux/pci.h> 96#include <linux/pci.h>
97
98#include <linux/mtd/mtd.h> 97#include <linux/mtd/mtd.h>
99#include <linux/mtd/pmc551.h> 98
99#define PMC551_VERSION \
100 "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n"
101
102#define PCI_VENDOR_ID_V3_SEMI 0x11b0
103#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200
104
105#define PMC551_PCI_MEM_MAP0 0x50
106#define PMC551_PCI_MEM_MAP1 0x54
107#define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000
108#define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0
109#define PMC551_PCI_MEM_MAP_REG_EN 0x00000002
110#define PMC551_PCI_MEM_MAP_ENABLE 0x00000001
111
112#define PMC551_SDRAM_MA 0x60
113#define PMC551_SDRAM_CMD 0x62
114#define PMC551_DRAM_CFG 0x64
115#define PMC551_SYS_CTRL_REG 0x78
116
117#define PMC551_DRAM_BLK0 0x68
118#define PMC551_DRAM_BLK1 0x6c
119#define PMC551_DRAM_BLK2 0x70
120#define PMC551_DRAM_BLK3 0x74
121#define PMC551_DRAM_BLK_GET_SIZE(x) (524288 << ((x >> 4) & 0x0f))
122#define PMC551_DRAM_BLK_SET_COL_MUX(x, v) (((x) & ~0x00007000) | (((v) & 0x7) << 12))
123#define PMC551_DRAM_BLK_SET_ROW_MUX(x, v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8))
124
125struct mypriv {
126 struct pci_dev *dev;
127 u_char *start;
128 u32 base_map0;
129 u32 curr_map0;
130 u32 asize;
131 struct mtd_info *nextpmc551;
132};
100 133
101static struct mtd_info *pmc551list; 134static struct mtd_info *pmc551list;
102 135
136static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
137 size_t *retlen, void **virt, resource_size_t *phys);
138
103static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) 139static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
104{ 140{
105 struct mypriv *priv = mtd->priv; 141 struct mypriv *priv = mtd->priv;
@@ -115,16 +151,6 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
115#endif 151#endif
116 152
117 end = instr->addr + instr->len - 1; 153 end = instr->addr + instr->len - 1;
118
119 /* Is it past the end? */
120 if (end > mtd->size) {
121#ifdef CONFIG_MTD_PMC551_DEBUG
122 printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n",
123 (long)end, (long)mtd->size);
124#endif
125 return -EINVAL;
126 }
127
128 eoff_hi = end & ~(priv->asize - 1); 154 eoff_hi = end & ~(priv->asize - 1);
129 soff_hi = instr->addr & ~(priv->asize - 1); 155 soff_hi = instr->addr & ~(priv->asize - 1);
130 eoff_lo = end & (priv->asize - 1); 156 eoff_lo = end & (priv->asize - 1);
@@ -178,18 +204,6 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
178 printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len); 204 printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len);
179#endif 205#endif
180 206
181 if (from + len > mtd->size) {
182#ifdef CONFIG_MTD_PMC551_DEBUG
183 printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n",
184 (long)from + len, (long)mtd->size);
185#endif
186 return -EINVAL;
187 }
188
189 /* can we return a physical address with this driver? */
190 if (phys)
191 return -EINVAL;
192
193 soff_hi = from & ~(priv->asize - 1); 207 soff_hi = from & ~(priv->asize - 1);
194 soff_lo = from & (priv->asize - 1); 208 soff_lo = from & (priv->asize - 1);
195 209
@@ -205,11 +219,12 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
205 return 0; 219 return 0;
206} 220}
207 221
208static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 222static int pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
209{ 223{
210#ifdef CONFIG_MTD_PMC551_DEBUG 224#ifdef CONFIG_MTD_PMC551_DEBUG
211 printk(KERN_DEBUG "pmc551_unpoint()\n"); 225 printk(KERN_DEBUG "pmc551_unpoint()\n");
212#endif 226#endif
227 return 0;
213} 228}
214 229
215static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, 230static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
@@ -228,16 +243,6 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
228#endif 243#endif
229 244
230 end = from + len - 1; 245 end = from + len - 1;
231
232 /* Is it past the end? */
233 if (end > mtd->size) {
234#ifdef CONFIG_MTD_PMC551_DEBUG
235 printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n",
236 (long)end, (long)mtd->size);
237#endif
238 return -EINVAL;
239 }
240
241 soff_hi = from & ~(priv->asize - 1); 246 soff_hi = from & ~(priv->asize - 1);
242 eoff_hi = end & ~(priv->asize - 1); 247 eoff_hi = end & ~(priv->asize - 1);
243 soff_lo = from & (priv->asize - 1); 248 soff_lo = from & (priv->asize - 1);
@@ -295,16 +300,6 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
295#endif 300#endif
296 301
297 end = to + len - 1; 302 end = to + len - 1;
298 /* Is it past the end? or did the u32 wrap? */
299 if (end > mtd->size) {
300#ifdef CONFIG_MTD_PMC551_DEBUG
301 printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, "
302 "size: %ld, to: %ld)\n", (long)end, (long)mtd->size,
303 (long)to);
304#endif
305 return -EINVAL;
306 }
307
308 soff_hi = to & ~(priv->asize - 1); 303 soff_hi = to & ~(priv->asize - 1);
309 eoff_hi = end & ~(priv->asize - 1); 304 eoff_hi = end & ~(priv->asize - 1);
310 soff_lo = to & (priv->asize - 1); 305 soff_lo = to & (priv->asize - 1);
@@ -358,7 +353,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
358 * mechanism 353 * mechanism
359 * returns the size of the memory region found. 354 * returns the size of the memory region found.
360 */ 355 */
361static u32 fixup_pmc551(struct pci_dev *dev) 356static int fixup_pmc551(struct pci_dev *dev)
362{ 357{
363#ifdef CONFIG_MTD_PMC551_BUGFIX 358#ifdef CONFIG_MTD_PMC551_BUGFIX
364 u32 dram_data; 359 u32 dram_data;
@@ -668,7 +663,7 @@ static int __init init_pmc551(void)
668 struct mypriv *priv; 663 struct mypriv *priv;
669 int found = 0; 664 int found = 0;
670 struct mtd_info *mtd; 665 struct mtd_info *mtd;
671 u32 length = 0; 666 int length = 0;
672 667
673 if (msize) { 668 if (msize) {
674 msize = (1 << (ffs(msize) - 1)) << 20; 669 msize = (1 << (ffs(msize) - 1)) << 20;
@@ -786,11 +781,11 @@ static int __init init_pmc551(void)
786 781
787 mtd->size = msize; 782 mtd->size = msize;
788 mtd->flags = MTD_CAP_RAM; 783 mtd->flags = MTD_CAP_RAM;
789 mtd->erase = pmc551_erase; 784 mtd->_erase = pmc551_erase;
790 mtd->read = pmc551_read; 785 mtd->_read = pmc551_read;
791 mtd->write = pmc551_write; 786 mtd->_write = pmc551_write;
792 mtd->point = pmc551_point; 787 mtd->_point = pmc551_point;
793 mtd->unpoint = pmc551_unpoint; 788 mtd->_unpoint = pmc551_unpoint;
794 mtd->type = MTD_RAM; 789 mtd->type = MTD_RAM;
795 mtd->name = "PMC551 RAM board"; 790 mtd->name = "PMC551 RAM board";
796 mtd->erasesize = 0x10000; 791 mtd->erasesize = 0x10000;
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 288594163c22..8f52fc858e48 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -75,7 +75,7 @@ static slram_mtd_list_t *slram_mtdlist = NULL;
75static int slram_erase(struct mtd_info *, struct erase_info *); 75static int slram_erase(struct mtd_info *, struct erase_info *);
76static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **, 76static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **,
77 resource_size_t *); 77 resource_size_t *);
78static void slram_unpoint(struct mtd_info *, loff_t, size_t); 78static int slram_unpoint(struct mtd_info *, loff_t, size_t);
79static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); 79static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
80static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 80static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
81 81
@@ -83,21 +83,13 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
83{ 83{
84 slram_priv_t *priv = mtd->priv; 84 slram_priv_t *priv = mtd->priv;
85 85
86 if (instr->addr + instr->len > mtd->size) {
87 return(-EINVAL);
88 }
89
90 memset(priv->start + instr->addr, 0xff, instr->len); 86 memset(priv->start + instr->addr, 0xff, instr->len);
91
92 /* This'll catch a few races. Free the thing before returning :) 87 /* This'll catch a few races. Free the thing before returning :)
93 * I don't feel at all ashamed. This kind of thing is possible anyway 88 * I don't feel at all ashamed. This kind of thing is possible anyway
94 * with flash, but unlikely. 89 * with flash, but unlikely.
95 */ 90 */
96
97 instr->state = MTD_ERASE_DONE; 91 instr->state = MTD_ERASE_DONE;
98
99 mtd_erase_callback(instr); 92 mtd_erase_callback(instr);
100
101 return(0); 93 return(0);
102} 94}
103 95
@@ -106,20 +98,14 @@ static int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
106{ 98{
107 slram_priv_t *priv = mtd->priv; 99 slram_priv_t *priv = mtd->priv;
108 100
109 /* can we return a physical address with this driver? */
110 if (phys)
111 return -EINVAL;
112
113 if (from + len > mtd->size)
114 return -EINVAL;
115
116 *virt = priv->start + from; 101 *virt = priv->start + from;
117 *retlen = len; 102 *retlen = len;
118 return(0); 103 return(0);
119} 104}
120 105
121static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 106static int slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
122{ 107{
108 return 0;
123} 109}
124 110
125static int slram_read(struct mtd_info *mtd, loff_t from, size_t len, 111static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
@@ -127,14 +113,7 @@ static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
127{ 113{
128 slram_priv_t *priv = mtd->priv; 114 slram_priv_t *priv = mtd->priv;
129 115
130 if (from > mtd->size)
131 return -EINVAL;
132
133 if (from + len > mtd->size)
134 len = mtd->size - from;
135
136 memcpy(buf, priv->start + from, len); 116 memcpy(buf, priv->start + from, len);
137
138 *retlen = len; 117 *retlen = len;
139 return(0); 118 return(0);
140} 119}
@@ -144,11 +123,7 @@ static int slram_write(struct mtd_info *mtd, loff_t to, size_t len,
144{ 123{
145 slram_priv_t *priv = mtd->priv; 124 slram_priv_t *priv = mtd->priv;
146 125
147 if (to + len > mtd->size)
148 return -EINVAL;
149
150 memcpy(priv->start + to, buf, len); 126 memcpy(priv->start + to, buf, len);
151
152 *retlen = len; 127 *retlen = len;
153 return(0); 128 return(0);
154} 129}
@@ -199,11 +174,11 @@ static int register_device(char *name, unsigned long start, unsigned long length
199 (*curmtd)->mtdinfo->name = name; 174 (*curmtd)->mtdinfo->name = name;
200 (*curmtd)->mtdinfo->size = length; 175 (*curmtd)->mtdinfo->size = length;
201 (*curmtd)->mtdinfo->flags = MTD_CAP_RAM; 176 (*curmtd)->mtdinfo->flags = MTD_CAP_RAM;
202 (*curmtd)->mtdinfo->erase = slram_erase; 177 (*curmtd)->mtdinfo->_erase = slram_erase;
203 (*curmtd)->mtdinfo->point = slram_point; 178 (*curmtd)->mtdinfo->_point = slram_point;
204 (*curmtd)->mtdinfo->unpoint = slram_unpoint; 179 (*curmtd)->mtdinfo->_unpoint = slram_unpoint;
205 (*curmtd)->mtdinfo->read = slram_read; 180 (*curmtd)->mtdinfo->_read = slram_read;
206 (*curmtd)->mtdinfo->write = slram_write; 181 (*curmtd)->mtdinfo->_write = slram_write;
207 (*curmtd)->mtdinfo->owner = THIS_MODULE; 182 (*curmtd)->mtdinfo->owner = THIS_MODULE;
208 (*curmtd)->mtdinfo->type = MTD_RAM; 183 (*curmtd)->mtdinfo->type = MTD_RAM;
209 (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; 184 (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ;
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
new file mode 100644
index 000000000000..797d43cd3550
--- /dev/null
+++ b/drivers/mtd/devices/spear_smi.c
@@ -0,0 +1,1147 @@
1/*
2 * SMI (Serial Memory Controller) device driver for Serial NOR Flash on
3 * SPEAr platform
4 * The serial nor interface is largely based on drivers/mtd/m25p80.c,
5 * however the SPI interface has been replaced by SMI.
6 *
7 * Copyright © 2010 STMicroelectronics.
8 * Ashish Priyadarshi
9 * Shiraz Hashim <shiraz.hashim@st.com>
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 */
15
16#include <linux/clk.h>
17#include <linux/delay.h>
18#include <linux/device.h>
19#include <linux/err.h>
20#include <linux/errno.h>
21#include <linux/interrupt.h>
22#include <linux/io.h>
23#include <linux/ioport.h>
24#include <linux/jiffies.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/param.h>
28#include <linux/platform_device.h>
29#include <linux/mtd/mtd.h>
30#include <linux/mtd/partitions.h>
31#include <linux/mtd/spear_smi.h>
32#include <linux/mutex.h>
33#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/wait.h>
36#include <linux/of.h>
37#include <linux/of_address.h>
38
39/* SMI clock rate */
40#define SMI_MAX_CLOCK_FREQ 50000000 /* 50 MHz */
41
42/* MAX time out to safely come out of a erase or write busy conditions */
43#define SMI_PROBE_TIMEOUT (HZ / 10)
44#define SMI_MAX_TIME_OUT (3 * HZ)
45
46/* timeout for command completion */
47#define SMI_CMD_TIMEOUT (HZ / 10)
48
49/* registers of smi */
50#define SMI_CR1 0x0 /* SMI control register 1 */
51#define SMI_CR2 0x4 /* SMI control register 2 */
52#define SMI_SR 0x8 /* SMI status register */
53#define SMI_TR 0xC /* SMI transmit register */
54#define SMI_RR 0x10 /* SMI receive register */
55
56/* defines for control_reg 1 */
57#define BANK_EN (0xF << 0) /* enables all banks */
58#define DSEL_TIME (0x6 << 4) /* Deselect time 6 + 1 SMI_CK periods */
59#define SW_MODE (0x1 << 28) /* enables SW Mode */
60#define WB_MODE (0x1 << 29) /* Write Burst Mode */
61#define FAST_MODE (0x1 << 15) /* Fast Mode */
62#define HOLD1 (0x1 << 16) /* Clock Hold period selection */
63
64/* defines for control_reg 2 */
65#define SEND (0x1 << 7) /* Send data */
66#define TFIE (0x1 << 8) /* Transmission Flag Interrupt Enable */
67#define WCIE (0x1 << 9) /* Write Complete Interrupt Enable */
68#define RD_STATUS_REG (0x1 << 10) /* reads status reg */
69#define WE (0x1 << 11) /* Write Enable */
70
71#define TX_LEN_SHIFT 0
72#define RX_LEN_SHIFT 4
73#define BANK_SHIFT 12
74
75/* defines for status register */
76#define SR_WIP 0x1 /* Write in progress */
77#define SR_WEL 0x2 /* Write enable latch */
78#define SR_BP0 0x4 /* Block protect 0 */
79#define SR_BP1 0x8 /* Block protect 1 */
80#define SR_BP2 0x10 /* Block protect 2 */
81#define SR_SRWD 0x80 /* SR write protect */
82#define TFF 0x100 /* Transfer Finished Flag */
83#define WCF 0x200 /* Transfer Finished Flag */
84#define ERF1 0x400 /* Forbidden Write Request */
85#define ERF2 0x800 /* Forbidden Access */
86
87#define WM_SHIFT 12
88
89/* flash opcodes */
90#define OPCODE_RDID 0x9f /* Read JEDEC ID */
91
92/* Flash Device Ids maintenance section */
93
94/* data structure to maintain flash ids from different vendors */
95struct flash_device {
96 char *name;
97 u8 erase_cmd;
98 u32 device_id;
99 u32 pagesize;
100 unsigned long sectorsize;
101 unsigned long size_in_bytes;
102};
103
104#define FLASH_ID(n, es, id, psize, ssize, size) \
105{ \
106 .name = n, \
107 .erase_cmd = es, \
108 .device_id = id, \
109 .pagesize = psize, \
110 .sectorsize = ssize, \
111 .size_in_bytes = size \
112}
113
114static struct flash_device flash_devices[] = {
115 FLASH_ID("st m25p16" , 0xd8, 0x00152020, 0x100, 0x10000, 0x200000),
116 FLASH_ID("st m25p32" , 0xd8, 0x00162020, 0x100, 0x10000, 0x400000),
117 FLASH_ID("st m25p64" , 0xd8, 0x00172020, 0x100, 0x10000, 0x800000),
118 FLASH_ID("st m25p128" , 0xd8, 0x00182020, 0x100, 0x40000, 0x1000000),
119 FLASH_ID("st m25p05" , 0xd8, 0x00102020, 0x80 , 0x8000 , 0x10000),
120 FLASH_ID("st m25p10" , 0xd8, 0x00112020, 0x80 , 0x8000 , 0x20000),
121 FLASH_ID("st m25p20" , 0xd8, 0x00122020, 0x100, 0x10000, 0x40000),
122 FLASH_ID("st m25p40" , 0xd8, 0x00132020, 0x100, 0x10000, 0x80000),
123 FLASH_ID("st m25p80" , 0xd8, 0x00142020, 0x100, 0x10000, 0x100000),
124 FLASH_ID("st m45pe10" , 0xd8, 0x00114020, 0x100, 0x10000, 0x20000),
125 FLASH_ID("st m45pe20" , 0xd8, 0x00124020, 0x100, 0x10000, 0x40000),
126 FLASH_ID("st m45pe40" , 0xd8, 0x00134020, 0x100, 0x10000, 0x80000),
127 FLASH_ID("st m45pe80" , 0xd8, 0x00144020, 0x100, 0x10000, 0x100000),
128 FLASH_ID("sp s25fl004" , 0xd8, 0x00120201, 0x100, 0x10000, 0x80000),
129 FLASH_ID("sp s25fl008" , 0xd8, 0x00130201, 0x100, 0x10000, 0x100000),
130 FLASH_ID("sp s25fl016" , 0xd8, 0x00140201, 0x100, 0x10000, 0x200000),
131 FLASH_ID("sp s25fl032" , 0xd8, 0x00150201, 0x100, 0x10000, 0x400000),
132 FLASH_ID("sp s25fl064" , 0xd8, 0x00160201, 0x100, 0x10000, 0x800000),
133 FLASH_ID("atmel 25f512" , 0x52, 0x0065001F, 0x80 , 0x8000 , 0x10000),
134 FLASH_ID("atmel 25f1024" , 0x52, 0x0060001F, 0x100, 0x8000 , 0x20000),
135 FLASH_ID("atmel 25f2048" , 0x52, 0x0063001F, 0x100, 0x10000, 0x40000),
136 FLASH_ID("atmel 25f4096" , 0x52, 0x0064001F, 0x100, 0x10000, 0x80000),
137 FLASH_ID("atmel 25fs040" , 0xd7, 0x0004661F, 0x100, 0x10000, 0x80000),
138 FLASH_ID("mac 25l512" , 0xd8, 0x001020C2, 0x010, 0x10000, 0x10000),
139 FLASH_ID("mac 25l1005" , 0xd8, 0x001120C2, 0x010, 0x10000, 0x20000),
140 FLASH_ID("mac 25l2005" , 0xd8, 0x001220C2, 0x010, 0x10000, 0x40000),
141 FLASH_ID("mac 25l4005" , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
142 FLASH_ID("mac 25l4005a" , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
143 FLASH_ID("mac 25l8005" , 0xd8, 0x001420C2, 0x010, 0x10000, 0x100000),
144 FLASH_ID("mac 25l1605" , 0xd8, 0x001520C2, 0x100, 0x10000, 0x200000),
145 FLASH_ID("mac 25l1605a" , 0xd8, 0x001520C2, 0x010, 0x10000, 0x200000),
146 FLASH_ID("mac 25l3205" , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
147 FLASH_ID("mac 25l3205a" , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
148 FLASH_ID("mac 25l6405" , 0xd8, 0x001720C2, 0x100, 0x10000, 0x800000),
149};
150
151/* Define spear specific structures */
152
153struct spear_snor_flash;
154
155/**
156 * struct spear_smi - Structure for SMI Device
157 *
158 * @clk: functional clock
159 * @status: current status register of SMI.
160 * @clk_rate: functional clock rate of SMI (default: SMI_MAX_CLOCK_FREQ)
161 * @lock: lock to prevent parallel access of SMI.
162 * @io_base: base address for registers of SMI.
163 * @pdev: platform device
164 * @cmd_complete: queue to wait for command completion of NOR-flash.
165 * @num_flashes: number of flashes actually present on board.
166 * @flash: separate structure for each Serial NOR-flash attached to SMI.
167 */
168struct spear_smi {
169 struct clk *clk;
170 u32 status;
171 unsigned long clk_rate;
172 struct mutex lock;
173 void __iomem *io_base;
174 struct platform_device *pdev;
175 wait_queue_head_t cmd_complete;
176 u32 num_flashes;
177 struct spear_snor_flash *flash[MAX_NUM_FLASH_CHIP];
178};
179
180/**
181 * struct spear_snor_flash - Structure for Serial NOR Flash
182 *
183 * @bank: Bank number(0, 1, 2, 3) for each NOR-flash.
184 * @dev_id: Device ID of NOR-flash.
185 * @lock: lock to manage flash read, write and erase operations
186 * @mtd: MTD info for each NOR-flash.
187 * @num_parts: Total number of partition in each bank of NOR-flash.
188 * @parts: Partition info for each bank of NOR-flash.
189 * @page_size: Page size of NOR-flash.
190 * @base_addr: Base address of NOR-flash.
191 * @erase_cmd: erase command may vary on different flash types
192 * @fast_mode: flash supports read in fast mode
193 */
194struct spear_snor_flash {
195 u32 bank;
196 u32 dev_id;
197 struct mutex lock;
198 struct mtd_info mtd;
199 u32 num_parts;
200 struct mtd_partition *parts;
201 u32 page_size;
202 void __iomem *base_addr;
203 u8 erase_cmd;
204 u8 fast_mode;
205};
206
207static inline struct spear_snor_flash *get_flash_data(struct mtd_info *mtd)
208{
209 return container_of(mtd, struct spear_snor_flash, mtd);
210}
211
212/**
213 * spear_smi_read_sr - Read status register of flash through SMI
214 * @dev: structure of SMI information.
215 * @bank: bank to which flash is connected
216 *
217 * This routine will return the status register of the flash chip present at the
218 * given bank.
219 */
220static int spear_smi_read_sr(struct spear_smi *dev, u32 bank)
221{
222 int ret;
223 u32 ctrlreg1;
224
225 mutex_lock(&dev->lock);
226 dev->status = 0; /* Will be set in interrupt handler */
227
228 ctrlreg1 = readl(dev->io_base + SMI_CR1);
229 /* program smi in hw mode */
230 writel(ctrlreg1 & ~(SW_MODE | WB_MODE), dev->io_base + SMI_CR1);
231
232 /* performing a rsr instruction in hw mode */
233 writel((bank << BANK_SHIFT) | RD_STATUS_REG | TFIE,
234 dev->io_base + SMI_CR2);
235
236 /* wait for tff */
237 ret = wait_event_interruptible_timeout(dev->cmd_complete,
238 dev->status & TFF, SMI_CMD_TIMEOUT);
239
240 /* copy dev->status (lower 16 bits) in order to release lock */
241 if (ret > 0)
242 ret = dev->status & 0xffff;
243 else
244 ret = -EIO;
245
246 /* restore the ctrl regs state */
247 writel(ctrlreg1, dev->io_base + SMI_CR1);
248 writel(0, dev->io_base + SMI_CR2);
249 mutex_unlock(&dev->lock);
250
251 return ret;
252}
253
254/**
255 * spear_smi_wait_till_ready - wait till flash is ready
256 * @dev: structure of SMI information.
257 * @bank: flash corresponding to this bank
258 * @timeout: timeout for busy wait condition
259 *
260 * This routine checks for WIP (write in progress) bit in Status register
261 * If successful the routine returns 0 else -EBUSY
262 */
263static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank,
264 unsigned long timeout)
265{
266 unsigned long finish;
267 int status;
268
269 finish = jiffies + timeout;
270 do {
271 status = spear_smi_read_sr(dev, bank);
272 if (status < 0)
273 continue; /* try till timeout */
274 else if (!(status & SR_WIP))
275 return 0;
276
277 cond_resched();
278 } while (!time_after_eq(jiffies, finish));
279
280 dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n");
281 return status;
282}
283
284/**
285 * spear_smi_int_handler - SMI Interrupt Handler.
286 * @irq: irq number
287 * @dev_id: structure of SMI device, embedded in dev_id.
288 *
289 * The handler clears all interrupt conditions and records the status in
290 * dev->status which is used by the driver later.
291 */
292static irqreturn_t spear_smi_int_handler(int irq, void *dev_id)
293{
294 u32 status = 0;
295 struct spear_smi *dev = dev_id;
296
297 status = readl(dev->io_base + SMI_SR);
298
299 if (unlikely(!status))
300 return IRQ_NONE;
301
302 /* clear all interrupt conditions */
303 writel(0, dev->io_base + SMI_SR);
304
305 /* copy the status register in dev->status */
306 dev->status |= status;
307
308 /* send the completion */
309 wake_up_interruptible(&dev->cmd_complete);
310
311 return IRQ_HANDLED;
312}
313
314/**
315 * spear_smi_hw_init - initializes the smi controller.
316 * @dev: structure of smi device
317 *
318 * this routine initializes the smi controller wit the default values
319 */
320static void spear_smi_hw_init(struct spear_smi *dev)
321{
322 unsigned long rate = 0;
323 u32 prescale = 0;
324 u32 val;
325
326 rate = clk_get_rate(dev->clk);
327
328 /* functional clock of smi */
329 prescale = DIV_ROUND_UP(rate, dev->clk_rate);
330
331 /*
332 * setting the standard values, fast mode, prescaler for
333 * SMI_MAX_CLOCK_FREQ (50MHz) operation and bank enable
334 */
335 val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8);
336
337 mutex_lock(&dev->lock);
338 writel(val, dev->io_base + SMI_CR1);
339 mutex_unlock(&dev->lock);
340}
341
342/**
343 * get_flash_index - match chip id from a flash list.
344 * @flash_id: a valid nor flash chip id obtained from board.
345 *
346 * try to validate the chip id by matching from a list, if not found then simply
347 * returns negative. In case of success returns index in to the flash devices
348 * array.
349 */
350static int get_flash_index(u32 flash_id)
351{
352 int index;
353
354 /* Matches chip-id to entire list of 'serial-nor flash' ids */
355 for (index = 0; index < ARRAY_SIZE(flash_devices); index++) {
356 if (flash_devices[index].device_id == flash_id)
357 return index;
358 }
359
360 /* Memory chip is not listed and not supported */
361 return -ENODEV;
362}
363
364/**
365 * spear_smi_write_enable - Enable the flash to do write operation
366 * @dev: structure of SMI device
367 * @bank: enable write for flash connected to this bank
368 *
369 * Set write enable latch with Write Enable command.
370 * Returns 0 on success.
371 */
372static int spear_smi_write_enable(struct spear_smi *dev, u32 bank)
373{
374 int ret;
375 u32 ctrlreg1;
376
377 mutex_lock(&dev->lock);
378 dev->status = 0; /* Will be set in interrupt handler */
379
380 ctrlreg1 = readl(dev->io_base + SMI_CR1);
381 /* program smi in h/w mode */
382 writel(ctrlreg1 & ~SW_MODE, dev->io_base + SMI_CR1);
383
384 /* give the flash, write enable command */
385 writel((bank << BANK_SHIFT) | WE | TFIE, dev->io_base + SMI_CR2);
386
387 ret = wait_event_interruptible_timeout(dev->cmd_complete,
388 dev->status & TFF, SMI_CMD_TIMEOUT);
389
390 /* restore the ctrl regs state */
391 writel(ctrlreg1, dev->io_base + SMI_CR1);
392 writel(0, dev->io_base + SMI_CR2);
393
394 if (ret <= 0) {
395 ret = -EIO;
396 dev_err(&dev->pdev->dev,
397 "smi controller failed on write enable\n");
398 } else {
399 /* check whether write mode status is set for required bank */
400 if (dev->status & (1 << (bank + WM_SHIFT)))
401 ret = 0;
402 else {
403 dev_err(&dev->pdev->dev, "couldn't enable write\n");
404 ret = -EIO;
405 }
406 }
407
408 mutex_unlock(&dev->lock);
409 return ret;
410}
411
412static inline u32
413get_sector_erase_cmd(struct spear_snor_flash *flash, u32 offset)
414{
415 u32 cmd;
416 u8 *x = (u8 *)&cmd;
417
418 x[0] = flash->erase_cmd;
419 x[1] = offset >> 16;
420 x[2] = offset >> 8;
421 x[3] = offset;
422
423 return cmd;
424}
425
426/**
427 * spear_smi_erase_sector - erase one sector of flash
428 * @dev: structure of SMI information
429 * @command: erase command to be send
430 * @bank: bank to which this command needs to be send
431 * @bytes: size of command
432 *
433 * Erase one sector of flash memory at offset ``offset'' which is any
434 * address within the sector which should be erased.
435 * Returns 0 if successful, non-zero otherwise.
436 */
437static int spear_smi_erase_sector(struct spear_smi *dev,
438 u32 bank, u32 command, u32 bytes)
439{
440 u32 ctrlreg1 = 0;
441 int ret;
442
443 ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
444 if (ret)
445 return ret;
446
447 ret = spear_smi_write_enable(dev, bank);
448 if (ret)
449 return ret;
450
451 mutex_lock(&dev->lock);
452
453 ctrlreg1 = readl(dev->io_base + SMI_CR1);
454 writel((ctrlreg1 | SW_MODE) & ~WB_MODE, dev->io_base + SMI_CR1);
455
456 /* send command in sw mode */
457 writel(command, dev->io_base + SMI_TR);
458
459 writel((bank << BANK_SHIFT) | SEND | TFIE | (bytes << TX_LEN_SHIFT),
460 dev->io_base + SMI_CR2);
461
462 ret = wait_event_interruptible_timeout(dev->cmd_complete,
463 dev->status & TFF, SMI_CMD_TIMEOUT);
464
465 if (ret <= 0) {
466 ret = -EIO;
467 dev_err(&dev->pdev->dev, "sector erase failed\n");
468 } else
469 ret = 0; /* success */
470
471 /* restore ctrl regs */
472 writel(ctrlreg1, dev->io_base + SMI_CR1);
473 writel(0, dev->io_base + SMI_CR2);
474
475 mutex_unlock(&dev->lock);
476 return ret;
477}
478
479/**
480 * spear_mtd_erase - perform flash erase operation as requested by user
481 * @mtd: Provides the memory characteristics
482 * @e_info: Provides the erase information
483 *
484 * Erase an address range on the flash chip. The address range may extend
485 * one or more erase sectors. Return an error is there is a problem erasing.
486 */
487static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info)
488{
489 struct spear_snor_flash *flash = get_flash_data(mtd);
490 struct spear_smi *dev = mtd->priv;
491 u32 addr, command, bank;
492 int len, ret;
493
494 if (!flash || !dev)
495 return -ENODEV;
496
497 bank = flash->bank;
498 if (bank > dev->num_flashes - 1) {
499 dev_err(&dev->pdev->dev, "Invalid Bank Num");
500 return -EINVAL;
501 }
502
503 addr = e_info->addr;
504 len = e_info->len;
505
506 mutex_lock(&flash->lock);
507
508 /* now erase sectors in loop */
509 while (len) {
510 command = get_sector_erase_cmd(flash, addr);
511 /* preparing the command for flash */
512 ret = spear_smi_erase_sector(dev, bank, command, 4);
513 if (ret) {
514 e_info->state = MTD_ERASE_FAILED;
515 mutex_unlock(&flash->lock);
516 return ret;
517 }
518 addr += mtd->erasesize;
519 len -= mtd->erasesize;
520 }
521
522 mutex_unlock(&flash->lock);
523 e_info->state = MTD_ERASE_DONE;
524 mtd_erase_callback(e_info);
525
526 return 0;
527}
528
529/**
530 * spear_mtd_read - performs flash read operation as requested by the user
531 * @mtd: MTD information of the memory bank
532 * @from: Address from which to start read
533 * @len: Number of bytes to be read
534 * @retlen: Fills the Number of bytes actually read
535 * @buf: Fills this after reading
536 *
537 * Read an address range from the flash chip. The address range
538 * may be any size provided it is within the physical boundaries.
539 * Returns 0 on success, non zero otherwise
540 */
541static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
542 size_t *retlen, u8 *buf)
543{
544 struct spear_snor_flash *flash = get_flash_data(mtd);
545 struct spear_smi *dev = mtd->priv;
546 void *src;
547 u32 ctrlreg1, val;
548 int ret;
549
550 if (!flash || !dev)
551 return -ENODEV;
552
553 if (flash->bank > dev->num_flashes - 1) {
554 dev_err(&dev->pdev->dev, "Invalid Bank Num");
555 return -EINVAL;
556 }
557
558 /* select address as per bank number */
559 src = flash->base_addr + from;
560
561 mutex_lock(&flash->lock);
562
563 /* wait till previous write/erase is done. */
564 ret = spear_smi_wait_till_ready(dev, flash->bank, SMI_MAX_TIME_OUT);
565 if (ret) {
566 mutex_unlock(&flash->lock);
567 return ret;
568 }
569
570 mutex_lock(&dev->lock);
571 /* put smi in hw mode not wbt mode */
572 ctrlreg1 = val = readl(dev->io_base + SMI_CR1);
573 val &= ~(SW_MODE | WB_MODE);
574 if (flash->fast_mode)
575 val |= FAST_MODE;
576
577 writel(val, dev->io_base + SMI_CR1);
578
579 memcpy_fromio(buf, (u8 *)src, len);
580
581 /* restore ctrl reg1 */
582 writel(ctrlreg1, dev->io_base + SMI_CR1);
583 mutex_unlock(&dev->lock);
584
585 *retlen = len;
586 mutex_unlock(&flash->lock);
587
588 return 0;
589}
590
591static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank,
592 void *dest, const void *src, size_t len)
593{
594 int ret;
595 u32 ctrlreg1;
596
597 /* wait until finished previous write command. */
598 ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
599 if (ret)
600 return ret;
601
602 /* put smi in write enable */
603 ret = spear_smi_write_enable(dev, bank);
604 if (ret)
605 return ret;
606
607 /* put smi in hw, write burst mode */
608 mutex_lock(&dev->lock);
609
610 ctrlreg1 = readl(dev->io_base + SMI_CR1);
611 writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1);
612
613 memcpy_toio(dest, src, len);
614
615 writel(ctrlreg1, dev->io_base + SMI_CR1);
616
617 mutex_unlock(&dev->lock);
618 return 0;
619}
620
621/**
622 * spear_mtd_write - performs write operation as requested by the user.
623 * @mtd: MTD information of the memory bank.
624 * @to: Address to write.
625 * @len: Number of bytes to be written.
626 * @retlen: Number of bytes actually wrote.
627 * @buf: Buffer from which the data to be taken.
628 *
629 * Write an address range to the flash chip. Data must be written in
630 * flash_page_size chunks. The address range may be any size provided
631 * it is within the physical boundaries.
632 * Returns 0 on success, non zero otherwise
633 */
634static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
635 size_t *retlen, const u8 *buf)
636{
637 struct spear_snor_flash *flash = get_flash_data(mtd);
638 struct spear_smi *dev = mtd->priv;
639 void *dest;
640 u32 page_offset, page_size;
641 int ret;
642
643 if (!flash || !dev)
644 return -ENODEV;
645
646 if (flash->bank > dev->num_flashes - 1) {
647 dev_err(&dev->pdev->dev, "Invalid Bank Num");
648 return -EINVAL;
649 }
650
651 /* select address as per bank number */
652 dest = flash->base_addr + to;
653 mutex_lock(&flash->lock);
654
655 page_offset = (u32)to % flash->page_size;
656
657 /* do if all the bytes fit onto one page */
658 if (page_offset + len <= flash->page_size) {
659 ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, len);
660 if (!ret)
661 *retlen += len;
662 } else {
663 u32 i;
664
665 /* the size of data remaining on the first page */
666 page_size = flash->page_size - page_offset;
667
668 ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf,
669 page_size);
670 if (ret)
671 goto err_write;
672 else
673 *retlen += page_size;
674
675 /* write everything in pagesize chunks */
676 for (i = page_size; i < len; i += page_size) {
677 page_size = len - i;
678 if (page_size > flash->page_size)
679 page_size = flash->page_size;
680
681 ret = spear_smi_cpy_toio(dev, flash->bank, dest + i,
682 buf + i, page_size);
683 if (ret)
684 break;
685 else
686 *retlen += page_size;
687 }
688 }
689
690err_write:
691 mutex_unlock(&flash->lock);
692
693 return ret;
694}
695
696/**
697 * spear_smi_probe_flash - Detects the NOR Flash chip.
698 * @dev: structure of SMI information.
699 * @bank: bank on which flash must be probed
700 *
701 * This routine will check whether there exists a flash chip on a given memory
702 * bank ID.
703 * Return index of the probed flash in flash devices structure
704 */
705static int spear_smi_probe_flash(struct spear_smi *dev, u32 bank)
706{
707 int ret;
708 u32 val = 0;
709
710 ret = spear_smi_wait_till_ready(dev, bank, SMI_PROBE_TIMEOUT);
711 if (ret)
712 return ret;
713
714 mutex_lock(&dev->lock);
715
716 dev->status = 0; /* Will be set in interrupt handler */
717 /* put smi in sw mode */
718 val = readl(dev->io_base + SMI_CR1);
719 writel(val | SW_MODE, dev->io_base + SMI_CR1);
720
721 /* send readid command in sw mode */
722 writel(OPCODE_RDID, dev->io_base + SMI_TR);
723
724 val = (bank << BANK_SHIFT) | SEND | (1 << TX_LEN_SHIFT) |
725 (3 << RX_LEN_SHIFT) | TFIE;
726 writel(val, dev->io_base + SMI_CR2);
727
728 /* wait for TFF */
729 ret = wait_event_interruptible_timeout(dev->cmd_complete,
730 dev->status & TFF, SMI_CMD_TIMEOUT);
731 if (ret <= 0) {
732 ret = -ENODEV;
733 goto err_probe;
734 }
735
736 /* get memory chip id */
737 val = readl(dev->io_base + SMI_RR);
738 val &= 0x00ffffff;
739 ret = get_flash_index(val);
740
741err_probe:
742 /* clear sw mode */
743 val = readl(dev->io_base + SMI_CR1);
744 writel(val & ~SW_MODE, dev->io_base + SMI_CR1);
745
746 mutex_unlock(&dev->lock);
747 return ret;
748}
749
750
751#ifdef CONFIG_OF
752static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev,
753 struct device_node *np)
754{
755 struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev);
756 struct device_node *pp = NULL;
757 const __be32 *addr;
758 u32 val;
759 int len;
760 int i = 0;
761
762 if (!np)
763 return -ENODEV;
764
765 of_property_read_u32(np, "clock-rate", &val);
766 pdata->clk_rate = val;
767
768 pdata->board_flash_info = devm_kzalloc(&pdev->dev,
769 sizeof(*pdata->board_flash_info),
770 GFP_KERNEL);
771
772 /* Fill structs for each subnode (flash device) */
773 while ((pp = of_get_next_child(np, pp))) {
774 struct spear_smi_flash_info *flash_info;
775
776 flash_info = &pdata->board_flash_info[i];
777 pdata->np[i] = pp;
778
779 /* Read base-addr and size from DT */
780 addr = of_get_property(pp, "reg", &len);
781 pdata->board_flash_info->mem_base = be32_to_cpup(&addr[0]);
782 pdata->board_flash_info->size = be32_to_cpup(&addr[1]);
783
784 if (of_get_property(pp, "st,smi-fast-mode", NULL))
785 pdata->board_flash_info->fast_mode = 1;
786
787 i++;
788 }
789
790 pdata->num_flashes = i;
791
792 return 0;
793}
794#else
795static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev,
796 struct device_node *np)
797{
798 return -ENOSYS;
799}
800#endif
801
802static int spear_smi_setup_banks(struct platform_device *pdev,
803 u32 bank, struct device_node *np)
804{
805 struct spear_smi *dev = platform_get_drvdata(pdev);
806 struct mtd_part_parser_data ppdata = {};
807 struct spear_smi_flash_info *flash_info;
808 struct spear_smi_plat_data *pdata;
809 struct spear_snor_flash *flash;
810 struct mtd_partition *parts = NULL;
811 int count = 0;
812 int flash_index;
813 int ret = 0;
814
815 pdata = dev_get_platdata(&pdev->dev);
816 if (bank > pdata->num_flashes - 1)
817 return -EINVAL;
818
819 flash_info = &pdata->board_flash_info[bank];
820 if (!flash_info)
821 return -ENODEV;
822
823 flash = kzalloc(sizeof(*flash), GFP_ATOMIC);
824 if (!flash)
825 return -ENOMEM;
826 flash->bank = bank;
827 flash->fast_mode = flash_info->fast_mode ? 1 : 0;
828 mutex_init(&flash->lock);
829
830 /* verify whether nor flash is really present on board */
831 flash_index = spear_smi_probe_flash(dev, bank);
832 if (flash_index < 0) {
833 dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank);
834 ret = flash_index;
835 goto err_probe;
836 }
837 /* map the memory for nor flash chip */
838 flash->base_addr = ioremap(flash_info->mem_base, flash_info->size);
839 if (!flash->base_addr) {
840 ret = -EIO;
841 goto err_probe;
842 }
843
844 dev->flash[bank] = flash;
845 flash->mtd.priv = dev;
846
847 if (flash_info->name)
848 flash->mtd.name = flash_info->name;
849 else
850 flash->mtd.name = flash_devices[flash_index].name;
851
852 flash->mtd.type = MTD_NORFLASH;
853 flash->mtd.writesize = 1;
854 flash->mtd.flags = MTD_CAP_NORFLASH;
855 flash->mtd.size = flash_info->size;
856 flash->mtd.erasesize = flash_devices[flash_index].sectorsize;
857 flash->page_size = flash_devices[flash_index].pagesize;
858 flash->mtd.writebufsize = flash->page_size;
859 flash->erase_cmd = flash_devices[flash_index].erase_cmd;
860 flash->mtd._erase = spear_mtd_erase;
861 flash->mtd._read = spear_mtd_read;
862 flash->mtd._write = spear_mtd_write;
863 flash->dev_id = flash_devices[flash_index].device_id;
864
865 dev_info(&dev->pdev->dev, "mtd .name=%s .size=%llx(%lluM)\n",
866 flash->mtd.name, flash->mtd.size,
867 flash->mtd.size / (1024 * 1024));
868
869 dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n",
870 flash->mtd.erasesize, flash->mtd.erasesize / 1024);
871
872#ifndef CONFIG_OF
873 if (flash_info->partitions) {
874 parts = flash_info->partitions;
875 count = flash_info->nr_partitions;
876 }
877#endif
878 ppdata.of_node = np;
879
880 ret = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, parts,
881 count);
882 if (ret) {
883 dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret);
884 goto err_map;
885 }
886
887 return 0;
888
889err_map:
890 iounmap(flash->base_addr);
891
892err_probe:
893 kfree(flash);
894 return ret;
895}
896
897/**
898 * spear_smi_probe - Entry routine
899 * @pdev: platform device structure
900 *
901 * This is the first routine which gets invoked during booting and does all
902 * initialization/allocation work. The routine looks for available memory banks,
903 * and do proper init for any found one.
904 * Returns 0 on success, non zero otherwise
905 */
906static int __devinit spear_smi_probe(struct platform_device *pdev)
907{
908 struct device_node *np = pdev->dev.of_node;
909 struct spear_smi_plat_data *pdata = NULL;
910 struct spear_smi *dev;
911 struct resource *smi_base;
912 int irq, ret = 0;
913 int i;
914
915 if (np) {
916 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
917 if (!pdata) {
918 pr_err("%s: ERROR: no memory", __func__);
919 ret = -ENOMEM;
920 goto err;
921 }
922 pdev->dev.platform_data = pdata;
923 ret = spear_smi_probe_config_dt(pdev, np);
924 if (ret) {
925 ret = -ENODEV;
926 dev_err(&pdev->dev, "no platform data\n");
927 goto err;
928 }
929 } else {
930 pdata = dev_get_platdata(&pdev->dev);
931 if (pdata < 0) {
932 ret = -ENODEV;
933 dev_err(&pdev->dev, "no platform data\n");
934 goto err;
935 }
936 }
937
938 smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
939 if (!smi_base) {
940 ret = -ENODEV;
941 dev_err(&pdev->dev, "invalid smi base address\n");
942 goto err;
943 }
944
945 irq = platform_get_irq(pdev, 0);
946 if (irq < 0) {
947 ret = -ENODEV;
948 dev_err(&pdev->dev, "invalid smi irq\n");
949 goto err;
950 }
951
952 dev = kzalloc(sizeof(*dev), GFP_ATOMIC);
953 if (!dev) {
954 ret = -ENOMEM;
955 dev_err(&pdev->dev, "mem alloc fail\n");
956 goto err;
957 }
958
959 smi_base = request_mem_region(smi_base->start, resource_size(smi_base),
960 pdev->name);
961 if (!smi_base) {
962 ret = -EBUSY;
963 dev_err(&pdev->dev, "request mem region fail\n");
964 goto err_mem;
965 }
966
967 dev->io_base = ioremap(smi_base->start, resource_size(smi_base));
968 if (!dev->io_base) {
969 ret = -EIO;
970 dev_err(&pdev->dev, "ioremap fail\n");
971 goto err_ioremap;
972 }
973
974 dev->pdev = pdev;
975 dev->clk_rate = pdata->clk_rate;
976
977 if (dev->clk_rate < 0 || dev->clk_rate > SMI_MAX_CLOCK_FREQ)
978 dev->clk_rate = SMI_MAX_CLOCK_FREQ;
979
980 dev->num_flashes = pdata->num_flashes;
981
982 if (dev->num_flashes > MAX_NUM_FLASH_CHIP) {
983 dev_err(&pdev->dev, "exceeding max number of flashes\n");
984 dev->num_flashes = MAX_NUM_FLASH_CHIP;
985 }
986
987 dev->clk = clk_get(&pdev->dev, NULL);
988 if (IS_ERR(dev->clk)) {
989 ret = PTR_ERR(dev->clk);
990 goto err_clk;
991 }
992
993 ret = clk_enable(dev->clk);
994 if (ret)
995 goto err_clk_enable;
996
997 ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev);
998 if (ret) {
999 dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n");
1000 goto err_irq;
1001 }
1002
1003 mutex_init(&dev->lock);
1004 init_waitqueue_head(&dev->cmd_complete);
1005 spear_smi_hw_init(dev);
1006 platform_set_drvdata(pdev, dev);
1007
1008 /* loop for each serial nor-flash which is connected to smi */
1009 for (i = 0; i < dev->num_flashes; i++) {
1010 ret = spear_smi_setup_banks(pdev, i, pdata->np[i]);
1011 if (ret) {
1012 dev_err(&dev->pdev->dev, "bank setup failed\n");
1013 goto err_bank_setup;
1014 }
1015 }
1016
1017 return 0;
1018
1019err_bank_setup:
1020 free_irq(irq, dev);
1021 platform_set_drvdata(pdev, NULL);
1022err_irq:
1023 clk_disable(dev->clk);
1024err_clk_enable:
1025 clk_put(dev->clk);
1026err_clk:
1027 iounmap(dev->io_base);
1028err_ioremap:
1029 release_mem_region(smi_base->start, resource_size(smi_base));
1030err_mem:
1031 kfree(dev);
1032err:
1033 return ret;
1034}
1035
1036/**
1037 * spear_smi_remove - Exit routine
1038 * @pdev: platform device structure
1039 *
1040 * free all allocations and delete the partitions.
1041 */
1042static int __devexit spear_smi_remove(struct platform_device *pdev)
1043{
1044 struct spear_smi *dev;
1045 struct spear_smi_plat_data *pdata;
1046 struct spear_snor_flash *flash;
1047 struct resource *smi_base;
1048 int ret;
1049 int i, irq;
1050
1051 dev = platform_get_drvdata(pdev);
1052 if (!dev) {
1053 dev_err(&pdev->dev, "dev is null\n");
1054 return -ENODEV;
1055 }
1056
1057 pdata = dev_get_platdata(&pdev->dev);
1058
1059 /* clean up for all nor flash */
1060 for (i = 0; i < dev->num_flashes; i++) {
1061 flash = dev->flash[i];
1062 if (!flash)
1063 continue;
1064
1065 /* clean up mtd stuff */
1066 ret = mtd_device_unregister(&flash->mtd);
1067 if (ret)
1068 dev_err(&pdev->dev, "error removing mtd\n");
1069
1070 iounmap(flash->base_addr);
1071 kfree(flash);
1072 }
1073
1074 irq = platform_get_irq(pdev, 0);
1075 free_irq(irq, dev);
1076
1077 clk_disable(dev->clk);
1078 clk_put(dev->clk);
1079 iounmap(dev->io_base);
1080 kfree(dev);
1081
1082 smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1083 release_mem_region(smi_base->start, resource_size(smi_base));
1084 platform_set_drvdata(pdev, NULL);
1085
1086 return 0;
1087}
1088
1089int spear_smi_suspend(struct platform_device *pdev, pm_message_t state)
1090{
1091 struct spear_smi *dev = platform_get_drvdata(pdev);
1092
1093 if (dev && dev->clk)
1094 clk_disable(dev->clk);
1095
1096 return 0;
1097}
1098
1099int spear_smi_resume(struct platform_device *pdev)
1100{
1101 struct spear_smi *dev = platform_get_drvdata(pdev);
1102 int ret = -EPERM;
1103
1104 if (dev && dev->clk)
1105 ret = clk_enable(dev->clk);
1106
1107 if (!ret)
1108 spear_smi_hw_init(dev);
1109 return ret;
1110}
1111
1112#ifdef CONFIG_OF
1113static const struct of_device_id spear_smi_id_table[] = {
1114 { .compatible = "st,spear600-smi" },
1115 {}
1116};
1117MODULE_DEVICE_TABLE(of, spear_smi_id_table);
1118#endif
1119
1120static struct platform_driver spear_smi_driver = {
1121 .driver = {
1122 .name = "smi",
1123 .bus = &platform_bus_type,
1124 .owner = THIS_MODULE,
1125 .of_match_table = of_match_ptr(spear_smi_id_table),
1126 },
1127 .probe = spear_smi_probe,
1128 .remove = __devexit_p(spear_smi_remove),
1129 .suspend = spear_smi_suspend,
1130 .resume = spear_smi_resume,
1131};
1132
1133static int spear_smi_init(void)
1134{
1135 return platform_driver_register(&spear_smi_driver);
1136}
1137module_init(spear_smi_init);
1138
1139static void spear_smi_exit(void)
1140{
1141 platform_driver_unregister(&spear_smi_driver);
1142}
1143module_exit(spear_smi_exit);
1144
1145MODULE_LICENSE("GPL");
1146MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>");
1147MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips");
diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c
index 5fc198350b94..ab8a2f4c8d60 100644
--- a/drivers/mtd/devices/sst25l.c
+++ b/drivers/mtd/devices/sst25l.c
@@ -175,9 +175,6 @@ static int sst25l_erase(struct mtd_info *mtd, struct erase_info *instr)
175 int err; 175 int err;
176 176
177 /* Sanity checks */ 177 /* Sanity checks */
178 if (instr->addr + instr->len > flash->mtd.size)
179 return -EINVAL;
180
181 if ((uint32_t)instr->len % mtd->erasesize) 178 if ((uint32_t)instr->len % mtd->erasesize)
182 return -EINVAL; 179 return -EINVAL;
183 180
@@ -223,16 +220,6 @@ static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len,
223 unsigned char command[4]; 220 unsigned char command[4];
224 int ret; 221 int ret;
225 222
226 /* Sanity checking */
227 if (len == 0)
228 return 0;
229
230 if (from + len > flash->mtd.size)
231 return -EINVAL;
232
233 if (retlen)
234 *retlen = 0;
235
236 spi_message_init(&message); 223 spi_message_init(&message);
237 memset(&transfer, 0, sizeof(transfer)); 224 memset(&transfer, 0, sizeof(transfer));
238 225
@@ -274,13 +261,6 @@ static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len,
274 int i, j, ret, bytes, copied = 0; 261 int i, j, ret, bytes, copied = 0;
275 unsigned char command[5]; 262 unsigned char command[5];
276 263
277 /* Sanity checks */
278 if (!len)
279 return 0;
280
281 if (to + len > flash->mtd.size)
282 return -EINVAL;
283
284 if ((uint32_t)to % mtd->writesize) 264 if ((uint32_t)to % mtd->writesize)
285 return -EINVAL; 265 return -EINVAL;
286 266
@@ -402,10 +382,11 @@ static int __devinit sst25l_probe(struct spi_device *spi)
402 flash->mtd.flags = MTD_CAP_NORFLASH; 382 flash->mtd.flags = MTD_CAP_NORFLASH;
403 flash->mtd.erasesize = flash_info->erase_size; 383 flash->mtd.erasesize = flash_info->erase_size;
404 flash->mtd.writesize = flash_info->page_size; 384 flash->mtd.writesize = flash_info->page_size;
385 flash->mtd.writebufsize = flash_info->page_size;
405 flash->mtd.size = flash_info->page_size * flash_info->nr_pages; 386 flash->mtd.size = flash_info->page_size * flash_info->nr_pages;
406 flash->mtd.erase = sst25l_erase; 387 flash->mtd._erase = sst25l_erase;
407 flash->mtd.read = sst25l_read; 388 flash->mtd._read = sst25l_read;
408 flash->mtd.write = sst25l_write; 389 flash->mtd._write = sst25l_write;
409 390
410 dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name, 391 dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name,
411 (long long)flash->mtd.size >> 10); 392 (long long)flash->mtd.size >> 10);
@@ -418,9 +399,9 @@ static int __devinit sst25l_probe(struct spi_device *spi)
418 flash->mtd.numeraseregions); 399 flash->mtd.numeraseregions);
419 400
420 401
421 ret = mtd_device_parse_register(&flash->mtd, NULL, 0, 402 ret = mtd_device_parse_register(&flash->mtd, NULL, NULL,
422 data ? data->parts : NULL, 403 data ? data->parts : NULL,
423 data ? data->nr_parts : 0); 404 data ? data->nr_parts : 0);
424 if (ret) { 405 if (ret) {
425 kfree(flash); 406 kfree(flash);
426 dev_set_drvdata(&spi->dev, NULL); 407 dev_set_drvdata(&spi->dev, NULL);
@@ -450,18 +431,7 @@ static struct spi_driver sst25l_driver = {
450 .remove = __devexit_p(sst25l_remove), 431 .remove = __devexit_p(sst25l_remove),
451}; 432};
452 433
453static int __init sst25l_init(void) 434module_spi_driver(sst25l_driver);
454{
455 return spi_register_driver(&sst25l_driver);
456}
457
458static void __exit sst25l_exit(void)
459{
460 spi_unregister_driver(&sst25l_driver);
461}
462
463module_init(sst25l_init);
464module_exit(sst25l_exit);
465 435
466MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips"); 436MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips");
467MODULE_AUTHOR("Andre Renaud <andre@bluewatersys.com>, " 437MODULE_AUTHOR("Andre Renaud <andre@bluewatersys.com>, "