aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-24 05:01:43 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-24 05:01:43 -0400
commit0305c8659ff9cebabf469d5cd0ab8dc384857e10 (patch)
tree1784b2bb078a58e50ca75dfccd1e9fc5f8b211b8
parent99988f7bbd16b861590dda4631c4db6cb17b5091 (diff)
parentd470a97c70a43ffafd6e728c913254b6d6fd1219 (diff)
Merge branch 'master' of git://git.infradead.org/~gleixner/mtd-nand-2.6.git
-rw-r--r--drivers/mtd/devices/doc2000.c66
-rw-r--r--drivers/mtd/devices/doc2001.c2
-rw-r--r--drivers/mtd/devices/doc2001plus.c2
-rw-r--r--drivers/mtd/inftlcore.c63
-rw-r--r--drivers/mtd/inftlmount.c12
-rw-r--r--drivers/mtd/mtdconcat.c136
-rw-r--r--drivers/mtd/mtdpart.c106
-rw-r--r--drivers/mtd/nand/Kconfig4
-rw-r--r--drivers/mtd/nand/ams-delta.c57
-rw-r--r--drivers/mtd/nand/au1550nd.c56
-rw-r--r--drivers/mtd/nand/autcpu12.c77
-rw-r--r--drivers/mtd/nand/cs553x_nand.c33
-rw-r--r--drivers/mtd/nand/diskonchip.c86
-rw-r--r--drivers/mtd/nand/edb7312.c42
-rw-r--r--drivers/mtd/nand/h1910.c40
-rw-r--r--drivers/mtd/nand/nand_base.c480
-rw-r--r--drivers/mtd/nand/nand_bbt.c104
-rw-r--r--drivers/mtd/nand/nandsim.c89
-rw-r--r--drivers/mtd/nand/ndfc.c23
-rw-r--r--drivers/mtd/nand/ppchameleonevb.c102
-rw-r--r--drivers/mtd/nand/rtc_from4.c34
-rw-r--r--drivers/mtd/nand/s3c2410.c64
-rw-r--r--drivers/mtd/nand/sharpsl.c41
-rw-r--r--drivers/mtd/nand/spia.c27
-rw-r--r--drivers/mtd/nand/toto.c65
-rw-r--r--drivers/mtd/nand/ts7250.c44
-rw-r--r--drivers/mtd/nftlcore.c15
-rw-r--r--drivers/mtd/nftlmount.c12
-rw-r--r--drivers/mtd/onenand/onenand_base.c217
-rw-r--r--fs/jffs2/wbuf.c28
-rw-r--r--include/linux/mtd/mtd.h11
-rw-r--r--include/linux/mtd/nand.h43
32 files changed, 666 insertions, 1515 deletions
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 423a34f4638c..d9ba1ee658f6 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -59,9 +59,6 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
59 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 59 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
60static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 60static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
61 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 61 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
62static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
63 unsigned long count, loff_t to, size_t *retlen,
64 u_char *eccbuf, struct nand_oobinfo *oobsel);
65static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 62static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
66 size_t *retlen, u_char *buf); 63 size_t *retlen, u_char *buf);
67static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 64static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
@@ -587,9 +584,6 @@ void DoC2k_init(struct mtd_info *mtd)
587 mtd->unpoint = NULL; 584 mtd->unpoint = NULL;
588 mtd->read = doc_read; 585 mtd->read = doc_read;
589 mtd->write = doc_write; 586 mtd->write = doc_write;
590 mtd->read_ecc = doc_read_ecc;
591 mtd->write_ecc = doc_write_ecc;
592 mtd->writev_ecc = doc_writev_ecc;
593 mtd->read_oob = doc_read_oob; 587 mtd->read_oob = doc_read_oob;
594 mtd->write_oob = doc_write_oob; 588 mtd->write_oob = doc_write_oob;
595 mtd->sync = NULL; 589 mtd->sync = NULL;
@@ -965,66 +959,6 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
965 return 0; 959 return 0;
966} 960}
967 961
968static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
969 unsigned long count, loff_t to, size_t *retlen,
970 u_char *eccbuf, struct nand_oobinfo *oobsel)
971{
972 static char static_buf[512];
973 static DEFINE_MUTEX(writev_buf_mutex);
974
975 size_t totretlen = 0;
976 size_t thisvecofs = 0;
977 int ret= 0;
978
979 mutex_lock(&writev_buf_mutex);
980
981 while(count) {
982 size_t thislen, thisretlen;
983 unsigned char *buf;
984
985 buf = vecs->iov_base + thisvecofs;
986 thislen = vecs->iov_len - thisvecofs;
987
988
989 if (thislen >= 512) {
990 thislen = thislen & ~(512-1);
991 thisvecofs += thislen;
992 } else {
993 /* Not enough to fill a page. Copy into buf */
994 memcpy(static_buf, buf, thislen);
995 buf = &static_buf[thislen];
996
997 while(count && thislen < 512) {
998 vecs++;
999 count--;
1000 thisvecofs = min((512-thislen), vecs->iov_len);
1001 memcpy(buf, vecs->iov_base, thisvecofs);
1002 thislen += thisvecofs;
1003 buf += thisvecofs;
1004 }
1005 buf = static_buf;
1006 }
1007 if (count && thisvecofs == vecs->iov_len) {
1008 thisvecofs = 0;
1009 vecs++;
1010 count--;
1011 }
1012 ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel);
1013
1014 totretlen += thisretlen;
1015
1016 if (ret || thisretlen != thislen)
1017 break;
1018
1019 to += thislen;
1020 }
1021
1022 mutex_unlock(&writev_buf_mutex);
1023 *retlen = totretlen;
1024 return ret;
1025}
1026
1027
1028static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 962static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1029 size_t * retlen, u_char * buf) 963 size_t * retlen, u_char * buf)
1030{ 964{
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index e6eaef28a2b0..579c0b570ae5 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -369,8 +369,6 @@ void DoCMil_init(struct mtd_info *mtd)
369 mtd->unpoint = NULL; 369 mtd->unpoint = NULL;
370 mtd->read = doc_read; 370 mtd->read = doc_read;
371 mtd->write = doc_write; 371 mtd->write = doc_write;
372 mtd->read_ecc = doc_read_ecc;
373 mtd->write_ecc = doc_write_ecc;
374 mtd->read_oob = doc_read_oob; 372 mtd->read_oob = doc_read_oob;
375 mtd->write_oob = doc_write_oob; 373 mtd->write_oob = doc_write_oob;
376 mtd->sync = NULL; 374 mtd->sync = NULL;
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index 8422c5e92d27..1ee0c0dcb53b 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -491,8 +491,6 @@ void DoCMilPlus_init(struct mtd_info *mtd)
491 mtd->unpoint = NULL; 491 mtd->unpoint = NULL;
492 mtd->read = doc_read; 492 mtd->read = doc_read;
493 mtd->write = doc_write; 493 mtd->write = doc_write;
494 mtd->read_ecc = doc_read_ecc;
495 mtd->write_ecc = doc_write_ecc;
496 mtd->read_oob = doc_read_oob; 494 mtd->read_oob = doc_read_oob;
497 mtd->write_oob = doc_write_oob; 495 mtd->write_oob = doc_write_oob;
498 mtd->sync = NULL; 496 mtd->sync = NULL;
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index a3b92479719d..ddd12993780d 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -36,6 +36,7 @@
36#include <linux/mtd/mtd.h> 36#include <linux/mtd/mtd.h>
37#include <linux/mtd/nftl.h> 37#include <linux/mtd/nftl.h>
38#include <linux/mtd/inftl.h> 38#include <linux/mtd/inftl.h>
39#include <linux/mtd/nand.h>
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/errno.h> 41#include <asm/errno.h>
41#include <asm/io.h> 42#include <asm/io.h>
@@ -79,14 +80,12 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
79 inftl->mbd.devnum = -1; 80 inftl->mbd.devnum = -1;
80 inftl->mbd.blksize = 512; 81 inftl->mbd.blksize = 512;
81 inftl->mbd.tr = tr; 82 inftl->mbd.tr = tr;
82 memcpy(&inftl->oobinfo, &mtd->oobinfo, sizeof(struct nand_oobinfo));
83 inftl->oobinfo.useecc = MTD_NANDECC_PLACEONLY;
84 83
85 if (INFTL_mount(inftl) < 0) { 84 if (INFTL_mount(inftl) < 0) {
86 printk(KERN_WARNING "INFTL: could not mount device\n"); 85 printk(KERN_WARNING "INFTL: could not mount device\n");
87 kfree(inftl); 86 kfree(inftl);
88 return; 87 return;
89 } 88 }
90 89
91 /* OK, it's a new one. Set up all the data structures. */ 90 /* OK, it's a new one. Set up all the data structures. */
92 91
@@ -221,7 +220,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
221 * Scan to find the Erase Unit which holds the actual data for each 220 * Scan to find the Erase Unit which holds the actual data for each
222 * 512-byte block within the Chain. 221 * 512-byte block within the Chain.
223 */ 222 */
224 silly = MAX_LOOPS; 223 silly = MAX_LOOPS;
225 while (thisEUN < inftl->nb_blocks) { 224 while (thisEUN < inftl->nb_blocks) {
226 for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) { 225 for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) {
227 if ((BlockMap[block] != 0xffff) || BlockDeleted[block]) 226 if ((BlockMap[block] != 0xffff) || BlockDeleted[block])
@@ -232,7 +231,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
232 (char *)&oob) < 0) 231 (char *)&oob) < 0)
233 status = SECTOR_IGNORE; 232 status = SECTOR_IGNORE;
234 else 233 else
235 status = oob.b.Status | oob.b.Status1; 234 status = oob.b.Status | oob.b.Status1;
236 235
237 switch(status) { 236 switch(status) {
238 case SECTOR_FREE: 237 case SECTOR_FREE:
@@ -282,29 +281,30 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
282 continue; 281 continue;
283 } 282 }
284 283
285 /* 284 /*
286 * Copy only in non free block (free blocks can only 285 * Copy only in non free block (free blocks can only
287 * happen in case of media errors or deleted blocks). 286 * happen in case of media errors or deleted blocks).
288 */ 287 */
289 if (BlockMap[block] == BLOCK_NIL) 288 if (BlockMap[block] == BLOCK_NIL)
290 continue; 289 continue;
291 290
292 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 291 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
293 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE, 292 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
294 &retlen, movebuf); 293 &retlen, movebuf);
295 if (ret < 0) { 294 if (ret < 0) {
296 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 295 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
297 BlockMap[block]) + (block * SECTORSIZE), 296 BlockMap[block]) + (block * SECTORSIZE),
298 SECTORSIZE, &retlen, movebuf); 297 SECTORSIZE, &retlen, movebuf);
299 if (ret != -EIO) 298 if (ret != -EIO)
300 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went " 299 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
301 "away on retry?\n"); 300 "away on retry?\n");
302 } 301 }
303 memset(&oob, 0xff, sizeof(struct inftl_oob)); 302 memset(&oob, 0xff, sizeof(struct inftl_oob));
304 oob.b.Status = oob.b.Status1 = SECTOR_USED; 303 oob.b.Status = oob.b.Status1 = SECTOR_USED;
305 MTD_WRITEECC(inftl->mbd.mtd, (inftl->EraseSize * targetEUN) + 304
306 (block * SECTORSIZE), SECTORSIZE, &retlen, 305 nand_write_raw(inftl->mbd.mtd, (inftl->EraseSize * targetEUN) +
307 movebuf, (char *)&oob, &inftl->oobinfo); 306 (block * SECTORSIZE), SECTORSIZE, &retlen,
307 movebuf, (char *)&oob);
308 } 308 }
309 309
310 /* 310 /*
@@ -329,17 +329,17 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
329 if (thisEUN == targetEUN) 329 if (thisEUN == targetEUN)
330 break; 330 break;
331 331
332 if (INFTL_formatblock(inftl, thisEUN) < 0) { 332 if (INFTL_formatblock(inftl, thisEUN) < 0) {
333 /* 333 /*
334 * Could not erase : mark block as reserved. 334 * Could not erase : mark block as reserved.
335 */ 335 */
336 inftl->PUtable[thisEUN] = BLOCK_RESERVED; 336 inftl->PUtable[thisEUN] = BLOCK_RESERVED;
337 } else { 337 } else {
338 /* Correctly erased : mark it as free */ 338 /* Correctly erased : mark it as free */
339 inftl->PUtable[thisEUN] = BLOCK_FREE; 339 inftl->PUtable[thisEUN] = BLOCK_FREE;
340 inftl->PUtable[prevEUN] = BLOCK_NIL; 340 inftl->PUtable[prevEUN] = BLOCK_NIL;
341 inftl->numfreeEUNs++; 341 inftl->numfreeEUNs++;
342 } 342 }
343 } 343 }
344 344
345 return targetEUN; 345 return targetEUN;
@@ -437,7 +437,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
437 MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) + 437 MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) +
438 blockofs, 8, &retlen, (char *)&bci); 438 blockofs, 8, &retlen, (char *)&bci);
439 439
440 status = bci.Status | bci.Status1; 440 status = bci.Status | bci.Status1;
441 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in " 441 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in "
442 "EUN %d is %x\n", block , writeEUN, status); 442 "EUN %d is %x\n", block , writeEUN, status);
443 443
@@ -670,12 +670,12 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
670 DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n", 670 DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n",
671 thisEUN, thisVUC); 671 thisEUN, thisVUC);
672 672
673 if (INFTL_formatblock(inftl, thisEUN) < 0) { 673 if (INFTL_formatblock(inftl, thisEUN) < 0) {
674 /* 674 /*
675 * Could not erase : mark block as reserved. 675 * Could not erase : mark block as reserved.
676 */ 676 */
677 inftl->PUtable[thisEUN] = BLOCK_RESERVED; 677 inftl->PUtable[thisEUN] = BLOCK_RESERVED;
678 } else { 678 } else {
679 /* Correctly erased : mark it as free */ 679 /* Correctly erased : mark it as free */
680 inftl->PUtable[thisEUN] = BLOCK_FREE; 680 inftl->PUtable[thisEUN] = BLOCK_FREE;
681 inftl->numfreeEUNs++; 681 inftl->numfreeEUNs++;
@@ -784,9 +784,10 @@ static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
784 784
785 memset(&oob, 0xff, sizeof(struct inftl_oob)); 785 memset(&oob, 0xff, sizeof(struct inftl_oob));
786 oob.b.Status = oob.b.Status1 = SECTOR_USED; 786 oob.b.Status = oob.b.Status1 = SECTOR_USED;
787 MTD_WRITEECC(inftl->mbd.mtd, (writeEUN * inftl->EraseSize) + 787
788 blockofs, SECTORSIZE, &retlen, (char *)buffer, 788 nand_write_raw(inftl->mbd.mtd, (writeEUN * inftl->EraseSize) +
789 (char *)&oob, &inftl->oobinfo); 789 blockofs, SECTORSIZE, &retlen, (char *)buffer,
790 (char *)&oob);
790 /* 791 /*
791 * need to write SECTOR_USED flags since they are not written 792 * need to write SECTOR_USED flags since they are not written
792 * in mtd_writeecc 793 * in mtd_writeecc
@@ -804,9 +805,9 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
804 struct INFTLrecord *inftl = (void *)mbd; 805 struct INFTLrecord *inftl = (void *)mbd;
805 unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)]; 806 unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)];
806 unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1); 807 unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
807 unsigned int status; 808 unsigned int status;
808 int silly = MAX_LOOPS; 809 int silly = MAX_LOOPS;
809 struct inftl_bci bci; 810 struct inftl_bci bci;
810 size_t retlen; 811 size_t retlen;
811 812
812 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=%p,block=%ld," 813 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=%p,block=%ld,"
@@ -850,7 +851,7 @@ foundit:
850 /* The requested block is not on the media, return all 0x00 */ 851 /* The requested block is not on the media, return all 0x00 */
851 memset(buffer, 0, SECTORSIZE); 852 memset(buffer, 0, SECTORSIZE);
852 } else { 853 } else {
853 size_t retlen; 854 size_t retlen;
854 loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs; 855 loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
855 if (MTD_READ(inftl->mbd.mtd, ptr, SECTORSIZE, &retlen, 856 if (MTD_READ(inftl->mbd.mtd, ptr, SECTORSIZE, &retlen,
856 buffer)) 857 buffer))
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index 43fdc9433882..f89a03795e76 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -350,21 +350,21 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
350 int len, int check_oob) 350 int len, int check_oob)
351{ 351{
352 u8 buf[SECTORSIZE + inftl->mbd.mtd->oobsize]; 352 u8 buf[SECTORSIZE + inftl->mbd.mtd->oobsize];
353 struct mtd_info *mtd = inftl->mbd.mtd;
353 size_t retlen; 354 size_t retlen;
354 int i; 355 int i;
355 356
356 DEBUG(MTD_DEBUG_LEVEL3, "INFTL: check_free_sectors(inftl=%p,"
357 "address=0x%x,len=%d,check_oob=%d)\n", inftl,
358 address, len, check_oob);
359
360 for (i = 0; i < len; i += SECTORSIZE) { 357 for (i = 0; i < len; i += SECTORSIZE) {
361 if (MTD_READECC(inftl->mbd.mtd, address, SECTORSIZE, &retlen, buf, &buf[SECTORSIZE], &inftl->oobinfo) < 0) 358 if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
362 return -1; 359 return -1;
363 if (memcmpb(buf, 0xff, SECTORSIZE) != 0) 360 if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
364 return -1; 361 return -1;
365 362
366 if (check_oob) { 363 if (check_oob) {
367 if (memcmpb(buf + SECTORSIZE, 0xff, inftl->mbd.mtd->oobsize) != 0) 364 if(mtd->read_oob(mtd, address, mtd->oobsize,
365 &retlen, &buf[SECTORSIZE]) < 0)
366 return -1;
367 if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0)
368 return -1; 368 return -1;
369 } 369 }
370 address += SECTORSIZE; 370 address += SECTORSIZE;
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index a5e8373349a5..6d52137988fa 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -143,119 +143,8 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
143} 143}
144 144
145static int 145static int
146concat_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, 146concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
147 size_t * retlen, u_char * buf, u_char * eccbuf, 147 unsigned long count, loff_t to, size_t * retlen)
148 struct nand_oobinfo *oobsel)
149{
150 struct mtd_concat *concat = CONCAT(mtd);
151 int err = -EINVAL;
152 int i;
153
154 *retlen = 0;
155
156 for (i = 0; i < concat->num_subdev; i++) {
157 struct mtd_info *subdev = concat->subdev[i];
158 size_t size, retsize;
159
160 if (from >= subdev->size) {
161 /* Not destined for this subdev */
162 size = 0;
163 from -= subdev->size;
164 continue;
165 }
166
167 if (from + len > subdev->size)
168 /* First part goes into this subdev */
169 size = subdev->size - from;
170 else
171 /* Entire transaction goes into this subdev */
172 size = len;
173
174 if (subdev->read_ecc)
175 err = subdev->read_ecc(subdev, from, size,
176 &retsize, buf, eccbuf, oobsel);
177 else
178 err = -EINVAL;
179
180 if (err)
181 break;
182
183 *retlen += retsize;
184 len -= size;
185 if (len == 0)
186 break;
187
188 err = -EINVAL;
189 buf += size;
190 if (eccbuf) {
191 eccbuf += subdev->oobsize;
192 /* in nand.c at least, eccbufs are
193 tagged with 2 (int)eccstatus'; we
194 must account for these */
195 eccbuf += 2 * (sizeof (int));
196 }
197 from = 0;
198 }
199 return err;
200}
201
202static int
203concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
204 size_t * retlen, const u_char * buf, u_char * eccbuf,
205 struct nand_oobinfo *oobsel)
206{
207 struct mtd_concat *concat = CONCAT(mtd);
208 int err = -EINVAL;
209 int i;
210
211 if (!(mtd->flags & MTD_WRITEABLE))
212 return -EROFS;
213
214 *retlen = 0;
215
216 for (i = 0; i < concat->num_subdev; i++) {
217 struct mtd_info *subdev = concat->subdev[i];
218 size_t size, retsize;
219
220 if (to >= subdev->size) {
221 size = 0;
222 to -= subdev->size;
223 continue;
224 }
225 if (to + len > subdev->size)
226 size = subdev->size - to;
227 else
228 size = len;
229
230 if (!(subdev->flags & MTD_WRITEABLE))
231 err = -EROFS;
232 else if (subdev->write_ecc)
233 err = subdev->write_ecc(subdev, to, size,
234 &retsize, buf, eccbuf, oobsel);
235 else
236 err = -EINVAL;
237
238 if (err)
239 break;
240
241 *retlen += retsize;
242 len -= size;
243 if (len == 0)
244 break;
245
246 err = -EINVAL;
247 buf += size;
248 if (eccbuf)
249 eccbuf += subdev->oobsize;
250 to = 0;
251 }
252 return err;
253}
254
255static int
256concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
257 unsigned long count, loff_t to, size_t * retlen,
258 u_char *eccbuf, struct nand_oobinfo *oobsel)
259{ 148{
260 struct mtd_concat *concat = CONCAT(mtd); 149 struct mtd_concat *concat = CONCAT(mtd);
261 struct kvec *vecs_copy; 150 struct kvec *vecs_copy;
@@ -315,10 +204,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
315 204
316 if (!(subdev->flags & MTD_WRITEABLE)) 205 if (!(subdev->flags & MTD_WRITEABLE))
317 err = -EROFS; 206 err = -EROFS;
318 else if (eccbuf)
319 err = subdev->writev_ecc(subdev, &vecs_copy[entry_low],
320 entry_high - entry_low + 1, to, &retsize,
321 eccbuf, oobsel);
322 else 207 else
323 err = subdev->writev(subdev, &vecs_copy[entry_low], 208 err = subdev->writev(subdev, &vecs_copy[entry_low],
324 entry_high - entry_low + 1, to, &retsize); 209 entry_high - entry_low + 1, to, &retsize);
@@ -333,8 +218,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
333 218
334 *retlen += retsize; 219 *retlen += retsize;
335 total_len -= wsize; 220 total_len -= wsize;
336 if (concat->mtd.type == MTD_NANDFLASH && eccbuf)
337 eccbuf += mtd->oobavail * (wsize / mtd->writesize);
338 221
339 if (total_len == 0) 222 if (total_len == 0)
340 break; 223 break;
@@ -348,13 +231,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
348} 231}
349 232
350static int 233static int
351concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
352 unsigned long count, loff_t to, size_t * retlen)
353{
354 return concat_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
355}
356
357static int
358concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 234concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
359 size_t * retlen, u_char * buf) 235 size_t * retlen, u_char * buf)
360{ 236{
@@ -837,14 +713,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
837 concat->mtd.oobsize = subdev[0]->oobsize; 713 concat->mtd.oobsize = subdev[0]->oobsize;
838 concat->mtd.ecctype = subdev[0]->ecctype; 714 concat->mtd.ecctype = subdev[0]->ecctype;
839 concat->mtd.eccsize = subdev[0]->eccsize; 715 concat->mtd.eccsize = subdev[0]->eccsize;
840 if (subdev[0]->read_ecc)
841 concat->mtd.read_ecc = concat_read_ecc;
842 if (subdev[0]->write_ecc)
843 concat->mtd.write_ecc = concat_write_ecc;
844 if (subdev[0]->writev) 716 if (subdev[0]->writev)
845 concat->mtd.writev = concat_writev; 717 concat->mtd.writev = concat_writev;
846 if (subdev[0]->writev_ecc)
847 concat->mtd.writev_ecc = concat_writev_ecc;
848 if (subdev[0]->read_oob) 718 if (subdev[0]->read_oob)
849 concat->mtd.read_oob = concat_read_oob; 719 concat->mtd.read_oob = concat_read_oob;
850 if (subdev[0]->write_oob) 720 if (subdev[0]->write_oob)
@@ -885,8 +755,6 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
885 concat->mtd.oobsize != subdev[i]->oobsize || 755 concat->mtd.oobsize != subdev[i]->oobsize ||
886 concat->mtd.ecctype != subdev[i]->ecctype || 756 concat->mtd.ecctype != subdev[i]->ecctype ||
887 concat->mtd.eccsize != subdev[i]->eccsize || 757 concat->mtd.eccsize != subdev[i]->eccsize ||
888 !concat->mtd.read_ecc != !subdev[i]->read_ecc ||
889 !concat->mtd.write_ecc != !subdev[i]->write_ecc ||
890 !concat->mtd.read_oob != !subdev[i]->read_oob || 758 !concat->mtd.read_oob != !subdev[i]->read_oob ||
891 !concat->mtd.write_oob != !subdev[i]->write_oob) { 759 !concat->mtd.write_oob != !subdev[i]->write_oob) {
892 kfree(concat); 760 kfree(concat);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 082662f90481..a93550ce7978 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -55,12 +55,8 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
55 len = 0; 55 len = 0;
56 else if (from + len > mtd->size) 56 else if (from + len > mtd->size)
57 len = mtd->size - from; 57 len = mtd->size - from;
58 if (part->master->read_ecc == NULL) 58 return part->master->read (part->master, from + part->offset,
59 return part->master->read (part->master, from + part->offset, 59 len, retlen, buf);
60 len, retlen, buf);
61 else
62 return part->master->read_ecc (part->master, from + part->offset,
63 len, retlen, buf, NULL, &mtd->oobinfo);
64} 60}
65 61
66static int part_point (struct mtd_info *mtd, loff_t from, size_t len, 62static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
@@ -74,6 +70,7 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
74 return part->master->point (part->master, from + part->offset, 70 return part->master->point (part->master, from + part->offset,
75 len, retlen, buf); 71 len, retlen, buf);
76} 72}
73
77static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) 74static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
78{ 75{
79 struct mtd_part *part = PART(mtd); 76 struct mtd_part *part = PART(mtd);
@@ -81,21 +78,6 @@ static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_
81 part->master->unpoint (part->master, addr, from + part->offset, len); 78 part->master->unpoint (part->master, addr, from + part->offset, len);
82} 79}
83 80
84
85static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
86 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
87{
88 struct mtd_part *part = PART(mtd);
89 if (oobsel == NULL)
90 oobsel = &mtd->oobinfo;
91 if (from >= mtd->size)
92 len = 0;
93 else if (from + len > mtd->size)
94 len = mtd->size - from;
95 return part->master->read_ecc (part->master, from + part->offset,
96 len, retlen, buf, eccbuf, oobsel);
97}
98
99static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len, 81static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
100 size_t *retlen, u_char *buf) 82 size_t *retlen, u_char *buf)
101{ 83{
@@ -148,30 +130,8 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
148 len = 0; 130 len = 0;
149 else if (to + len > mtd->size) 131 else if (to + len > mtd->size)
150 len = mtd->size - to; 132 len = mtd->size - to;
151 if (part->master->write_ecc == NULL) 133 return part->master->write (part->master, to + part->offset,
152 return part->master->write (part->master, to + part->offset, 134 len, retlen, buf);
153 len, retlen, buf);
154 else
155 return part->master->write_ecc (part->master, to + part->offset,
156 len, retlen, buf, NULL, &mtd->oobinfo);
157
158}
159
160static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
161 size_t *retlen, const u_char *buf,
162 u_char *eccbuf, struct nand_oobinfo *oobsel)
163{
164 struct mtd_part *part = PART(mtd);
165 if (!(mtd->flags & MTD_WRITEABLE))
166 return -EROFS;
167 if (oobsel == NULL)
168 oobsel = &mtd->oobinfo;
169 if (to >= mtd->size)
170 len = 0;
171 else if (to + len > mtd->size)
172 len = mtd->size - to;
173 return part->master->write_ecc (part->master, to + part->offset,
174 len, retlen, buf, eccbuf, oobsel);
175} 135}
176 136
177static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len, 137static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
@@ -208,52 +168,8 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
208 struct mtd_part *part = PART(mtd); 168 struct mtd_part *part = PART(mtd);
209 if (!(mtd->flags & MTD_WRITEABLE)) 169 if (!(mtd->flags & MTD_WRITEABLE))
210 return -EROFS; 170 return -EROFS;
211 if (part->master->writev_ecc == NULL) 171 return part->master->writev (part->master, vecs, count,
212 return part->master->writev (part->master, vecs, count,
213 to + part->offset, retlen); 172 to + part->offset, retlen);
214 else
215 return part->master->writev_ecc (part->master, vecs, count,
216 to + part->offset, retlen,
217 NULL, &mtd->oobinfo);
218}
219
220static int part_readv (struct mtd_info *mtd, struct kvec *vecs,
221 unsigned long count, loff_t from, size_t *retlen)
222{
223 struct mtd_part *part = PART(mtd);
224 if (part->master->readv_ecc == NULL)
225 return part->master->readv (part->master, vecs, count,
226 from + part->offset, retlen);
227 else
228 return part->master->readv_ecc (part->master, vecs, count,
229 from + part->offset, retlen,
230 NULL, &mtd->oobinfo);
231}
232
233static int part_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
234 unsigned long count, loff_t to, size_t *retlen,
235 u_char *eccbuf, struct nand_oobinfo *oobsel)
236{
237 struct mtd_part *part = PART(mtd);
238 if (!(mtd->flags & MTD_WRITEABLE))
239 return -EROFS;
240 if (oobsel == NULL)
241 oobsel = &mtd->oobinfo;
242 return part->master->writev_ecc (part->master, vecs, count,
243 to + part->offset, retlen,
244 eccbuf, oobsel);
245}
246
247static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs,
248 unsigned long count, loff_t from, size_t *retlen,
249 u_char *eccbuf, struct nand_oobinfo *oobsel)
250{
251 struct mtd_part *part = PART(mtd);
252 if (oobsel == NULL)
253 oobsel = &mtd->oobinfo;
254 return part->master->readv_ecc (part->master, vecs, count,
255 from + part->offset, retlen,
256 eccbuf, oobsel);
257} 173}
258 174
259static int part_erase (struct mtd_info *mtd, struct erase_info *instr) 175static int part_erase (struct mtd_info *mtd, struct erase_info *instr)
@@ -416,10 +332,6 @@ int add_mtd_partitions(struct mtd_info *master,
416 slave->mtd.unpoint = part_unpoint; 332 slave->mtd.unpoint = part_unpoint;
417 } 333 }
418 334
419 if (master->read_ecc)
420 slave->mtd.read_ecc = part_read_ecc;
421 if (master->write_ecc)
422 slave->mtd.write_ecc = part_write_ecc;
423 if (master->read_oob) 335 if (master->read_oob)
424 slave->mtd.read_oob = part_read_oob; 336 slave->mtd.read_oob = part_read_oob;
425 if (master->write_oob) 337 if (master->write_oob)
@@ -444,12 +356,6 @@ int add_mtd_partitions(struct mtd_info *master,
444 } 356 }
445 if (master->writev) 357 if (master->writev)
446 slave->mtd.writev = part_writev; 358 slave->mtd.writev = part_writev;
447 if (master->readv)
448 slave->mtd.readv = part_readv;
449 if (master->writev_ecc)
450 slave->mtd.writev_ecc = part_writev_ecc;
451 if (master->readv_ecc)
452 slave->mtd.readv_ecc = part_readv_ecc;
453 if (master->lock) 359 if (master->lock)
454 slave->mtd.lock = part_lock; 360 slave->mtd.lock = part_lock;
455 if (master->unlock) 361 if (master->unlock)
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index c2cb87fc4cb8..f24408d92688 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -65,7 +65,7 @@ config MTD_NAND_AMS_DELTA
65 65
66config MTD_NAND_TOTO 66config MTD_NAND_TOTO
67 tristate "NAND Flash device on TOTO board" 67 tristate "NAND Flash device on TOTO board"
68 depends on ARCH_OMAP && MTD_NAND 68 depends on ARCH_OMAP && MTD_NAND && BROKEN
69 help 69 help
70 Support for NAND flash on Texas Instruments Toto platform. 70 Support for NAND flash on Texas Instruments Toto platform.
71 71
@@ -96,7 +96,7 @@ config MTD_NAND_RTC_FROM4
96 96
97config MTD_NAND_PPCHAMELEONEVB 97config MTD_NAND_PPCHAMELEONEVB
98 tristate "NAND Flash device on PPChameleonEVB board" 98 tristate "NAND Flash device on PPChameleonEVB board"
99 depends on PPCHAMELEONEVB && MTD_NAND 99 depends on PPCHAMELEONEVB && MTD_NAND && BROKEN
100 help 100 help
101 This enables the NAND flash driver on the PPChameleon EVB Board. 101 This enables the NAND flash driver on the PPChameleon EVB Board.
102 102
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index aeaf2dece095..d7897dc6b3c8 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -34,13 +34,6 @@ static struct mtd_info *ams_delta_mtd = NULL;
34 34
35#define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP) 35#define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP)
36 36
37#define T_NAND_CTL_CLRALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, 0)
38#define T_NAND_CTL_SETALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, AMS_DELTA_LATCH2_NAND_ALE)
39#define T_NAND_CTL_CLRCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, 0)
40#define T_NAND_CTL_SETCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, AMS_DELTA_LATCH2_NAND_CLE)
41#define T_NAND_CTL_SETNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, 0)
42#define T_NAND_CTL_CLRNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, AMS_DELTA_LATCH2_NAND_NCE)
43
44/* 37/*
45 * Define partitions for flash devices 38 * Define partitions for flash devices
46 */ 39 */
@@ -66,25 +59,6 @@ static struct mtd_partition partition_info[] = {
66 .size = 3 * SZ_256K }, 59 .size = 3 * SZ_256K },
67}; 60};
68 61
69/*
70 * hardware specific access to control-lines
71*/
72
73static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd)
74{
75 switch (cmd) {
76
77 case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break;
78 case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break;
79
80 case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break;
81 case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break;
82
83 case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break;
84 case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break;
85 }
86}
87
88static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) 62static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte)
89{ 63{
90 struct nand_chip *this = mtd->priv; 64 struct nand_chip *this = mtd->priv;
@@ -141,6 +115,32 @@ static int ams_delta_verify_buf(struct mtd_info *mtd, const u_char *buf,
141 return 0; 115 return 0;
142} 116}
143 117
118/*
119 * Command control function
120 *
121 * ctrl:
122 * NAND_NCE: bit 0 -> bit 2
123 * NAND_CLE: bit 1 -> bit 7
124 * NAND_ALE: bit 2 -> bit 6
125 */
126static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd,
127 unsigned int ctrl)
128{
129
130 if (ctrl & NAND_CTRL_CHANGE) {
131 unsigned long bits;
132
133 bits = (~ctrl & NAND_NCE) << 2;
134 bits |= (ctrl & NAND_CLE) << 7;
135 bits |= (ctrl & NAND_ALE) << 6;
136
137 ams_delta_latch2_write(0xC2, bits);
138 }
139
140 if (cmd != NAND_CMD_NONE)
141 ams_delta_write_byte(mtd, cmd);
142}
143
144static int ams_delta_nand_ready(struct mtd_info *mtd) 144static int ams_delta_nand_ready(struct mtd_info *mtd)
145{ 145{
146 return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB); 146 return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB);
@@ -179,11 +179,10 @@ static int __init ams_delta_init(void)
179 this->IO_ADDR_R = (OMAP_MPUIO_BASE + OMAP_MPUIO_INPUT_LATCH); 179 this->IO_ADDR_R = (OMAP_MPUIO_BASE + OMAP_MPUIO_INPUT_LATCH);
180 this->IO_ADDR_W = (OMAP_MPUIO_BASE + OMAP_MPUIO_OUTPUT); 180 this->IO_ADDR_W = (OMAP_MPUIO_BASE + OMAP_MPUIO_OUTPUT);
181 this->read_byte = ams_delta_read_byte; 181 this->read_byte = ams_delta_read_byte;
182 this->write_byte = ams_delta_write_byte;
183 this->write_buf = ams_delta_write_buf; 182 this->write_buf = ams_delta_write_buf;
184 this->read_buf = ams_delta_read_buf; 183 this->read_buf = ams_delta_read_buf;
185 this->verify_buf = ams_delta_verify_buf; 184 this->verify_buf = ams_delta_verify_buf;
186 this->hwcontrol = ams_delta_hwcontrol; 185 this->cmd_ctrl = ams_delta_hwcontrol;
187 if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) { 186 if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) {
188 this->dev_ready = ams_delta_nand_ready; 187 this->dev_ready = ams_delta_nand_ready;
189 } else { 188 } else {
@@ -200,7 +199,7 @@ static int __init ams_delta_init(void)
200 AMS_DELTA_LATCH2_NAND_NCE | 199 AMS_DELTA_LATCH2_NAND_NCE |
201 AMS_DELTA_LATCH2_NAND_NWP); 200 AMS_DELTA_LATCH2_NAND_NWP);
202 201
203 /* Scan to find existance of the device */ 202 /* Scan to find existance of the device */
204 if (nand_scan(ams_delta_mtd, 1)) { 203 if (nand_scan(ams_delta_mtd, 1)) {
205 err = -ENXIO; 204 err = -ENXIO;
206 goto out_mtd; 205 goto out_mtd;
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 29dde7dcafa1..31228334da12 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -40,6 +40,7 @@
40static struct mtd_info *au1550_mtd = NULL; 40static struct mtd_info *au1550_mtd = NULL;
41static void __iomem *p_nand; 41static void __iomem *p_nand;
42static int nand_width = 1; /* default x8 */ 42static int nand_width = 1; /* default x8 */
43static void (*au1550_write_byte)(struct mtd_info *, u_char);
43 44
44/* 45/*
45 * Define partitions for flash device 46 * Define partitions for flash device
@@ -129,21 +130,6 @@ static u16 au_read_word(struct mtd_info *mtd)
129} 130}
130 131
131/** 132/**
132 * au_write_word - write one word to the chip
133 * @mtd: MTD device structure
134 * @word: data word to write
135 *
136 * write function for 16bit buswith without
137 * endianess conversion
138 */
139static void au_write_word(struct mtd_info *mtd, u16 word)
140{
141 struct nand_chip *this = mtd->priv;
142 writew(word, this->IO_ADDR_W);
143 au_sync();
144}
145
146/**
147 * au_write_buf - write buffer to chip 133 * au_write_buf - write buffer to chip
148 * @mtd: MTD device structure 134 * @mtd: MTD device structure
149 * @buf: data buffer 135 * @buf: data buffer
@@ -269,6 +255,18 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
269 return 0; 255 return 0;
270} 256}
271 257
258/* Select the chip by setting nCE to low */
259#define NAND_CTL_SETNCE 1
260/* Deselect the chip by setting nCE to high */
261#define NAND_CTL_CLRNCE 2
262/* Select the command latch by setting CLE to high */
263#define NAND_CTL_SETCLE 3
264/* Deselect the command latch by setting CLE to low */
265#define NAND_CTL_CLRCLE 4
266/* Select the address latch by setting ALE to high */
267#define NAND_CTL_SETALE 5
268/* Deselect the address latch by setting ALE to low */
269#define NAND_CTL_CLRALE 6
272 270
273static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) 271static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
274{ 272{
@@ -349,7 +347,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
349 ulong flags; 347 ulong flags;
350 348
351 /* Begin command latch cycle */ 349 /* Begin command latch cycle */
352 this->hwcontrol(mtd, NAND_CTL_SETCLE); 350 au1550_hwcontrol(mtd, NAND_CTL_SETCLE);
353 /* 351 /*
354 * Write out the command to the device. 352 * Write out the command to the device.
355 */ 353 */
@@ -367,25 +365,25 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
367 column -= 256; 365 column -= 256;
368 readcmd = NAND_CMD_READ1; 366 readcmd = NAND_CMD_READ1;
369 } 367 }
370 this->write_byte(mtd, readcmd); 368 au1550_write_byte(mtd, readcmd);
371 } 369 }
372 this->write_byte(mtd, command); 370 au1550_write_byte(mtd, command);
373 371
374 /* Set ALE and clear CLE to start address cycle */ 372 /* Set ALE and clear CLE to start address cycle */
375 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 373 au1550_hwcontrol(mtd, NAND_CTL_CLRCLE);
376 374
377 if (column != -1 || page_addr != -1) { 375 if (column != -1 || page_addr != -1) {
378 this->hwcontrol(mtd, NAND_CTL_SETALE); 376 au1550_hwcontrol(mtd, NAND_CTL_SETALE);
379 377
380 /* Serially input address */ 378 /* Serially input address */
381 if (column != -1) { 379 if (column != -1) {
382 /* Adjust columns for 16 bit buswidth */ 380 /* Adjust columns for 16 bit buswidth */
383 if (this->options & NAND_BUSWIDTH_16) 381 if (this->options & NAND_BUSWIDTH_16)
384 column >>= 1; 382 column >>= 1;
385 this->write_byte(mtd, column); 383 au1550_write_byte(mtd, column);
386 } 384 }
387 if (page_addr != -1) { 385 if (page_addr != -1) {
388 this->write_byte(mtd, (u8)(page_addr & 0xff)); 386 au1550_write_byte(mtd, (u8)(page_addr & 0xff));
389 387
390 if (command == NAND_CMD_READ0 || 388 if (command == NAND_CMD_READ0 ||
391 command == NAND_CMD_READ1 || 389 command == NAND_CMD_READ1 ||
@@ -400,17 +398,17 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
400 */ 398 */
401 ce_override = 1; 399 ce_override = 1;
402 local_irq_save(flags); 400 local_irq_save(flags);
403 this->hwcontrol(mtd, NAND_CTL_SETNCE); 401 au1550_hwcontrol(mtd, NAND_CTL_SETNCE);
404 } 402 }
405 403
406 this->write_byte(mtd, (u8)(page_addr >> 8)); 404 au1550_write_byte(mtd, (u8)(page_addr >> 8));
407 405
408 /* One more address cycle for devices > 32MiB */ 406 /* One more address cycle for devices > 32MiB */
409 if (this->chipsize > (32 << 20)) 407 if (this->chipsize > (32 << 20))
410 this->write_byte(mtd, (u8)((page_addr >> 16) & 0x0f)); 408 au1550_write_byte(mtd, (u8)((page_addr >> 16) & 0x0f));
411 } 409 }
412 /* Latch in address */ 410 /* Latch in address */
413 this->hwcontrol(mtd, NAND_CTL_CLRALE); 411 au1550_hwcontrol(mtd, NAND_CTL_CLRALE);
414 } 412 }
415 413
416 /* 414 /*
@@ -443,7 +441,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
443 udelay(1); 441 udelay(1);
444 442
445 /* Release -CE and re-enable interrupts. */ 443 /* Release -CE and re-enable interrupts. */
446 this->hwcontrol(mtd, NAND_CTL_CLRNCE); 444 au1550_hwcontrol(mtd, NAND_CTL_CLRNCE);
447 local_irq_restore(flags); 445 local_irq_restore(flags);
448 return; 446 return;
449 } 447 }
@@ -571,7 +569,6 @@ static int __init au1xxx_nand_init(void)
571 nand_width = au_readl(MEM_STCFG3) & (1 << 22); 569 nand_width = au_readl(MEM_STCFG3) & (1 << 22);
572 570
573 /* Set address of hardware control function */ 571 /* Set address of hardware control function */
574 this->hwcontrol = au1550_hwcontrol;
575 this->dev_ready = au1550_device_ready; 572 this->dev_ready = au1550_device_ready;
576 this->select_chip = au1550_select_chip; 573 this->select_chip = au1550_select_chip;
577 this->cmdfunc = au1550_command; 574 this->cmdfunc = au1550_command;
@@ -586,8 +583,7 @@ static int __init au1xxx_nand_init(void)
586 this->options |= NAND_BUSWIDTH_16; 583 this->options |= NAND_BUSWIDTH_16;
587 584
588 this->read_byte = (!nand_width) ? au_read_byte16 : au_read_byte; 585 this->read_byte = (!nand_width) ? au_read_byte16 : au_read_byte;
589 this->write_byte = (!nand_width) ? au_write_byte16 : au_write_byte; 586 au1550_write_byte = (!nand_width) ? au_write_byte16 : au_write_byte;
590 this->write_word = au_write_word;
591 this->read_word = au_read_word; 587 this->read_word = au_read_word;
592 this->write_buf = (!nand_width) ? au_write_buf16 : au_write_buf; 588 this->write_buf = (!nand_width) ? au_write_buf16 : au_write_buf;
593 this->read_buf = (!nand_width) ? au_read_buf16 : au_read_buf; 589 this->read_buf = (!nand_width) ? au_read_buf16 : au_read_buf;
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index dbb1b6267ade..fe94ae9ae1f2 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -4,7 +4,7 @@
4 * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de> 4 * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
5 * 5 *
6 * Derived from drivers/mtd/spia.c 6 * Derived from drivers/mtd/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 * 8 *
9 * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $ 9 * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
@@ -42,11 +42,6 @@
42 * MTD structure for AUTCPU12 board 42 * MTD structure for AUTCPU12 board
43 */ 43 */
44static struct mtd_info *autcpu12_mtd = NULL; 44static struct mtd_info *autcpu12_mtd = NULL;
45
46static int autcpu12_io_base = CS89712_VIRT_BASE;
47static int autcpu12_fio_pbase = AUTCPU12_PHYS_SMC;
48static int autcpu12_fio_ctrl = AUTCPU12_SMC_SELECT_OFFSET;
49static int autcpu12_pedr = AUTCPU12_SMC_PORT_OFFSET;
50static void __iomem *autcpu12_fio_base; 45static void __iomem *autcpu12_fio_base;
51 46
52/* 47/*
@@ -94,31 +89,42 @@ static struct mtd_partition partition_info128k[] = {
94#define NUM_PARTITIONS128K 2 89#define NUM_PARTITIONS128K 2
95/* 90/*
96 * hardware specific access to control-lines 91 * hardware specific access to control-lines
97*/ 92 *
98 93 * ALE bit 4 autcpu12_pedr
99static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) 94 * CLE bit 5 autcpu12_pedr
95 * NCE bit 0 fio_ctrl
96 *
97 */
98static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd,
99 unsigned int ctrl)
100{ 100{
101 switch (cmd) { 101 struct nand_chip *chip = mtd->priv;
102 102
103 case NAND_CTL_SETCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |= AUTCPU12_SMC_CLE; break; 103 if (ctrl & NAND_CTRL_CHANGE) {
104 case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_CLE; break; 104 void __iomem *addr
105 unsigned char bits;
105 106
106 case NAND_CTL_SETALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |= AUTCPU12_SMC_ALE; break; 107 addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET;
107 case NAND_CTL_CLRALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_ALE; break; 108 bits = (ctrl & NAND_CLE) << 4;
109 bits |= (ctrl & NAND_ALE) << 2;
110 writeb((readb(addr) & ~0x30) | bits, addr);
108 111
109 case NAND_CTL_SETNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x01; break; 112 addr = autcpu12_fio_base + AUTCPU12_SMC_SELECT_OFFSET;
110 case NAND_CTL_CLRNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x00; break; 113 writeb((readb(addr) & ~0x1) | (ctrl & NAND_NCE), addr);
111 } 114 }
115
116 if (cmd != NAND_CMD_NONE)
117 writeb(cmd, chip->IO_ADDR_W);
112} 118}
113 119
114/* 120/*
115* read device ready pin 121 * read device ready pin
116*/ 122 */
117int autcpu12_device_ready(struct mtd_info *mtd) 123int autcpu12_device_ready(struct mtd_info *mtd)
118{ 124{
125 void __iomem *addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET;
119 126
120 return ((*(volatile unsigned char *)(autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0; 127 return readb(addr) & AUTCPU12_SMC_RDY;
121
122} 128}
123 129
124/* 130/*
@@ -130,7 +136,8 @@ static int __init autcpu12_init(void)
130 int err = 0; 136 int err = 0;
131 137
132 /* Allocate memory for MTD device structure and private data */ 138 /* Allocate memory for MTD device structure and private data */
133 autcpu12_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); 139 autcpu12_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
140 GFP_KERNEL);
134 if (!autcpu12_mtd) { 141 if (!autcpu12_mtd) {
135 printk("Unable to allocate AUTCPU12 NAND MTD device structure.\n"); 142 printk("Unable to allocate AUTCPU12 NAND MTD device structure.\n");
136 err = -ENOMEM; 143 err = -ENOMEM;
@@ -138,7 +145,7 @@ static int __init autcpu12_init(void)
138 } 145 }
139 146
140 /* map physical adress */ 147 /* map physical adress */
141 autcpu12_fio_base = ioremap(autcpu12_fio_pbase, SZ_1K); 148 autcpu12_fio_base = ioremap(AUTCPU12_PHYS_SMC, SZ_1K);
142 if (!autcpu12_fio_base) { 149 if (!autcpu12_fio_base) {
143 printk("Ioremap autcpu12 SmartMedia Card failed\n"); 150 printk("Ioremap autcpu12 SmartMedia Card failed\n");
144 err = -EIO; 151 err = -EIO;
@@ -159,7 +166,7 @@ static int __init autcpu12_init(void)
159 /* Set address of NAND IO lines */ 166 /* Set address of NAND IO lines */
160 this->IO_ADDR_R = autcpu12_fio_base; 167 this->IO_ADDR_R = autcpu12_fio_base;
161 this->IO_ADDR_W = autcpu12_fio_base; 168 this->IO_ADDR_W = autcpu12_fio_base;
162 this->hwcontrol = autcpu12_hwcontrol; 169 this->cmd_ctrl = autcpu12_hwcontrol;
163 this->dev_ready = autcpu12_device_ready; 170 this->dev_ready = autcpu12_device_ready;
164 /* 20 us command delay time */ 171 /* 20 us command delay time */
165 this->chip_delay = 20; 172 this->chip_delay = 20;
@@ -179,10 +186,22 @@ static int __init autcpu12_init(void)
179 186
180 /* Register the partitions */ 187 /* Register the partitions */
181 switch (autcpu12_mtd->size) { 188 switch (autcpu12_mtd->size) {
182 case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; 189 case SZ_16M:
183 case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; 190 add_mtd_partitions(autcpu12_mtd, partition_info16k,
184 case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; 191 NUM_PARTITIONS16K);
185 case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; 192 break;
193 case SZ_32M:
194 add_mtd_partitions(autcpu12_mtd, partition_info32k,
195 NUM_PARTITIONS32K);
196 break;
197 case SZ_64M:
198 add_mtd_partitions(autcpu12_mtd, partition_info64k,
199 NUM_PARTITIONS64K);
200 break;
201 case SZ_128M:
202 add_mtd_partitions(autcpu12_mtd, partition_info128k,
203 NUM_PARTITIONS128K);
204 break;
186 default: 205 default:
187 printk("Unsupported SmartMedia device\n"); 206 printk("Unsupported SmartMedia device\n");
188 err = -ENXIO; 207 err = -ENXIO;
@@ -191,7 +210,7 @@ static int __init autcpu12_init(void)
191 goto out; 210 goto out;
192 211
193 out_ior: 212 out_ior:
194 iounmap((void *)autcpu12_fio_base); 213 iounmap(autcpu12_fio_base);
195 out_mtd: 214 out_mtd:
196 kfree(autcpu12_mtd); 215 kfree(autcpu12_mtd);
197 out: 216 out:
@@ -209,7 +228,7 @@ static void __exit autcpu12_cleanup(void)
209 nand_release(autcpu12_mtd); 228 nand_release(autcpu12_mtd);
210 229
211 /* unmap physical adress */ 230 /* unmap physical adress */
212 iounmap((void *)autcpu12_fio_base); 231 iounmap(autcpu12_fio_base);
213 232
214 /* Free the MTD device structure */ 233 /* Free the MTD device structure */
215 kfree(autcpu12_mtd); 234 kfree(autcpu12_mtd);
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c
index 064f3feadf53..1e0348ae325f 100644
--- a/drivers/mtd/nand/cs553x_nand.c
+++ b/drivers/mtd/nand/cs553x_nand.c
@@ -131,33 +131,17 @@ static void cs553x_write_byte(struct mtd_info *mtd, u_char byte)
131 writeb(byte, this->IO_ADDR_W + 0x801); 131 writeb(byte, this->IO_ADDR_W + 0x801);
132} 132}
133 133
134static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd) 134static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd,
135 unsigned int ctrl)
135{ 136{
136 struct nand_chip *this = mtd->priv; 137 struct nand_chip *this = mtd->priv;
137 void __iomem *mmio_base = this->IO_ADDR_R; 138 void __iomem *mmio_base = this->IO_ADDR_R;
138 unsigned char ctl; 139 if (ctrl & NAND_CTRL_CHANGE) {
139 140 unsigned char ctl = (ctrl & ~NAND_CTRL_CHANGE ) ^ 0x01;
140 switch (cmd) { 141 writeb(ctl, mmio_base + MM_NAND_CTL);
141 case NAND_CTL_SETCLE:
142 ctl = CS_NAND_CTL_CLE;
143 break;
144
145 case NAND_CTL_CLRCLE:
146 case NAND_CTL_CLRALE:
147 case NAND_CTL_SETNCE:
148 ctl = 0;
149 break;
150
151 case NAND_CTL_SETALE:
152 ctl = CS_NAND_CTL_ALE;
153 break;
154
155 default:
156 case NAND_CTL_CLRNCE:
157 ctl = CS_NAND_CTL_CE;
158 break;
159 } 142 }
160 writeb(ctl, mmio_base + MM_NAND_CTL); 143 if (cmd != NAND_CMD_NONE)
144 cs553x_write_byte(mtd, cmd);
161} 145}
162 146
163static int cs553x_device_ready(struct mtd_info *mtd) 147static int cs553x_device_ready(struct mtd_info *mtd)
@@ -233,10 +217,9 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
233 goto out_mtd; 217 goto out_mtd;
234 } 218 }
235 219
236 this->hwcontrol = cs553x_hwcontrol; 220 this->cmd_ctrl = cs553x_hwcontrol;
237 this->dev_ready = cs553x_device_ready; 221 this->dev_ready = cs553x_device_ready;
238 this->read_byte = cs553x_read_byte; 222 this->read_byte = cs553x_read_byte;
239 this->write_byte = cs553x_write_byte;
240 this->read_buf = cs553x_read_buf; 223 this->read_buf = cs553x_read_buf;
241 this->write_buf = cs553x_write_buf; 224 this->write_buf = cs553x_write_buf;
242 225
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index b771608ef84e..2ec9080e2b14 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -95,7 +95,8 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
95#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil) 95#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
96#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k) 96#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
97 97
98static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd); 98static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd,
99 unsigned int bitmask);
99static void doc200x_select_chip(struct mtd_info *mtd, int chip); 100static void doc200x_select_chip(struct mtd_info *mtd, int chip);
100 101
101static int debug = 0; 102static int debug = 0;
@@ -402,12 +403,10 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
402 uint16_t ret; 403 uint16_t ret;
403 404
404 doc200x_select_chip(mtd, nr); 405 doc200x_select_chip(mtd, nr);
405 doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); 406 doc200x_hwcontrol(mtd, NAND_CMD_READID,
406 this->write_byte(mtd, NAND_CMD_READID); 407 NAND_CTRL_CLE | NAND_CTRL_CHANGE);
407 doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); 408 doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
408 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 409 doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
409 this->write_byte(mtd, 0);
410 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
411 410
412 /* We cant' use dev_ready here, but at least we wait for the 411 /* We cant' use dev_ready here, but at least we wait for the
413 * command to complete 412 * command to complete
@@ -425,12 +424,11 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
425 } ident; 424 } ident;
426 void __iomem *docptr = doc->virtadr; 425 void __iomem *docptr = doc->virtadr;
427 426
428 doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); 427 doc200x_hwcontrol(mtd, NAND_CMD_READID,
429 doc2000_write_byte(mtd, NAND_CMD_READID); 428 NAND_CTRL_CLE | NAND_CTRL_CHANGE);
430 doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); 429 doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
431 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 430 doc200x_hwcontrol(mtd, NAND_CMD_NONE,
432 doc2000_write_byte(mtd, 0); 431 NAND_NCE | NAND_CTRL_CHANGE);
433 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
434 432
435 udelay(50); 433 udelay(50);
436 434
@@ -690,54 +688,41 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip)
690 chip -= (floor * doc->chips_per_floor); 688 chip -= (floor * doc->chips_per_floor);
691 689
692 /* 11.4.4 -- deassert CE before changing chip */ 690 /* 11.4.4 -- deassert CE before changing chip */
693 doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE); 691 doc200x_hwcontrol(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
694 692
695 WriteDOC(floor, docptr, FloorSelect); 693 WriteDOC(floor, docptr, FloorSelect);
696 WriteDOC(chip, docptr, CDSNDeviceSelect); 694 WriteDOC(chip, docptr, CDSNDeviceSelect);
697 695
698 doc200x_hwcontrol(mtd, NAND_CTL_SETNCE); 696 doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
699 697
700 doc->curchip = chip; 698 doc->curchip = chip;
701 doc->curfloor = floor; 699 doc->curfloor = floor;
702} 700}
703 701
704static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) 702#define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE)
703
704static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd,
705 unsigned int ctrl)
705{ 706{
706 struct nand_chip *this = mtd->priv; 707 struct nand_chip *this = mtd->priv;
707 struct doc_priv *doc = this->priv; 708 struct doc_priv *doc = this->priv;
708 void __iomem *docptr = doc->virtadr; 709 void __iomem *docptr = doc->virtadr;
709 710
710 switch (cmd) { 711 if (ctrl & NAND_CTRL_CHANGE) {
711 case NAND_CTL_SETNCE: 712 doc->CDSNControl &= ~CDSN_CTRL_MSK;
712 doc->CDSNControl |= CDSN_CTRL_CE; 713 doc->CDSNControl |= ctrl & CDSN_CTRL_MSK;
713 break; 714 if (debug)
714 case NAND_CTL_CLRNCE: 715 printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
715 doc->CDSNControl &= ~CDSN_CTRL_CE; 716 WriteDOC(doc->CDSNControl, docptr, CDSNControl);
716 break; 717 /* 11.4.3 -- 4 NOPs after CSDNControl write */
717 case NAND_CTL_SETCLE: 718 DoC_Delay(doc, 4);
718 doc->CDSNControl |= CDSN_CTRL_CLE; 719 }
719 break; 720 if (cmd != NAND_CMD_NONE) {
720 case NAND_CTL_CLRCLE: 721 if (DoC_is_2000(doc))
721 doc->CDSNControl &= ~CDSN_CTRL_CLE; 722 doc2000_write_byte(mtd, cmd);
722 break; 723 else
723 case NAND_CTL_SETALE: 724 doc2001_write_byte(mtd, cmd);
724 doc->CDSNControl |= CDSN_CTRL_ALE;
725 break;
726 case NAND_CTL_CLRALE:
727 doc->CDSNControl &= ~CDSN_CTRL_ALE;
728 break;
729 case NAND_CTL_SETWP:
730 doc->CDSNControl |= CDSN_CTRL_WP;
731 break;
732 case NAND_CTL_CLRWP:
733 doc->CDSNControl &= ~CDSN_CTRL_WP;
734 break;
735 } 725 }
736 if (debug)
737 printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
738 WriteDOC(doc->CDSNControl, docptr, CDSNControl);
739 /* 11.4.3 -- 4 NOPs after CSDNControl write */
740 DoC_Delay(doc, 4);
741} 726}
742 727
743static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) 728static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)
@@ -1454,7 +1439,6 @@ static inline int __init doc2000_init(struct mtd_info *mtd)
1454 struct nand_chip *this = mtd->priv; 1439 struct nand_chip *this = mtd->priv;
1455 struct doc_priv *doc = this->priv; 1440 struct doc_priv *doc = this->priv;
1456 1441
1457 this->write_byte = doc2000_write_byte;
1458 this->read_byte = doc2000_read_byte; 1442 this->read_byte = doc2000_read_byte;
1459 this->write_buf = doc2000_writebuf; 1443 this->write_buf = doc2000_writebuf;
1460 this->read_buf = doc2000_readbuf; 1444 this->read_buf = doc2000_readbuf;
@@ -1472,7 +1456,6 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
1472 struct nand_chip *this = mtd->priv; 1456 struct nand_chip *this = mtd->priv;
1473 struct doc_priv *doc = this->priv; 1457 struct doc_priv *doc = this->priv;
1474 1458
1475 this->write_byte = doc2001_write_byte;
1476 this->read_byte = doc2001_read_byte; 1459 this->read_byte = doc2001_read_byte;
1477 this->write_buf = doc2001_writebuf; 1460 this->write_buf = doc2001_writebuf;
1478 this->read_buf = doc2001_readbuf; 1461 this->read_buf = doc2001_readbuf;
@@ -1504,16 +1487,15 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)
1504 struct nand_chip *this = mtd->priv; 1487 struct nand_chip *this = mtd->priv;
1505 struct doc_priv *doc = this->priv; 1488 struct doc_priv *doc = this->priv;
1506 1489
1507 this->write_byte = NULL;
1508 this->read_byte = doc2001plus_read_byte; 1490 this->read_byte = doc2001plus_read_byte;
1509 this->write_buf = doc2001plus_writebuf; 1491 this->write_buf = doc2001plus_writebuf;
1510 this->read_buf = doc2001plus_readbuf; 1492 this->read_buf = doc2001plus_readbuf;
1511 this->verify_buf = doc2001plus_verifybuf; 1493 this->verify_buf = doc2001plus_verifybuf;
1512 this->scan_bbt = inftl_scan_bbt; 1494 this->scan_bbt = inftl_scan_bbt;
1513 this->hwcontrol = NULL; 1495 this->cmd_ctrl = NULL;
1514 this->select_chip = doc2001plus_select_chip; 1496 this->select_chip = doc2001plus_select_chip;
1515 this->cmdfunc = doc2001plus_command; 1497 this->cmdfunc = doc2001plus_command;
1516 this->enable_hwecc = doc2001plus_enable_hwecc; 1498 this->ecc.hwctl = doc2001plus_enable_hwecc;
1517 1499
1518 doc->chips_per_floor = 1; 1500 doc->chips_per_floor = 1;
1519 mtd->name = "DiskOnChip Millennium Plus"; 1501 mtd->name = "DiskOnChip Millennium Plus";
@@ -1670,7 +1652,7 @@ static int __init doc_probe(unsigned long physadr)
1670 1652
1671 nand->priv = doc; 1653 nand->priv = doc;
1672 nand->select_chip = doc200x_select_chip; 1654 nand->select_chip = doc200x_select_chip;
1673 nand->hwcontrol = doc200x_hwcontrol; 1655 nand->cmd_ctrl = doc200x_hwcontrol;
1674 nand->dev_ready = doc200x_dev_ready; 1656 nand->dev_ready = doc200x_dev_ready;
1675 nand->waitfunc = doc200x_wait; 1657 nand->waitfunc = doc200x_wait;
1676 nand->block_bad = doc200x_block_bad; 1658 nand->block_bad = doc200x_block_bad;
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 8e56570af91f..ba5a2174a408 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -73,32 +73,26 @@ static struct mtd_partition partition_info[] = {
73 73
74/* 74/*
75 * hardware specific access to control-lines 75 * hardware specific access to control-lines
76 *
77 * NAND_NCE: bit 0 -> bit 7
78 * NAND_CLE: bit 1 -> bit 4
79 * NAND_ALE: bit 2 -> bit 5
76 */ 80 */
77static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) 81static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
78{ 82{
79 switch (cmd) { 83 struct nand_chip *chip = mtd->priv;
80 84
81 case NAND_CTL_SETCLE: 85 if (ctrl & NAND_CTRL_CHANGE) {
82 clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr); 86 unsigned char bits;
83 break; 87
84 case NAND_CTL_CLRCLE: 88 bits = (ctrl & (NAND_CLE | NAND_ALE)) << 3;
85 clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr); 89 bits = (ctrl & NAND_NCE) << 7;
86 break; 90
87 91 clps_writeb((clps_readb(ep7312_pxdr) & 0xB0) | 0x10,
88 case NAND_CTL_SETALE: 92 ep7312_pxdr);
89 clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr);
90 break;
91 case NAND_CTL_CLRALE:
92 clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr);
93 break;
94
95 case NAND_CTL_SETNCE:
96 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr);
97 break;
98 case NAND_CTL_CLRNCE:
99 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) | 0x40, ep7312_pxdr);
100 break;
101 } 93 }
94 if (cmd != NAND_CMD_NONE)
95 writeb(cmd, chip->IO_ADDR_W);
102} 96}
103 97
104/* 98/*
@@ -159,7 +153,7 @@ static int __init ep7312_init(void)
159 /* insert callbacks */ 153 /* insert callbacks */
160 this->IO_ADDR_R = ep7312_fio_base; 154 this->IO_ADDR_R = ep7312_fio_base;
161 this->IO_ADDR_W = ep7312_fio_base; 155 this->IO_ADDR_W = ep7312_fio_base;
162 this->hwcontrol = ep7312_hwcontrol; 156 this->cmd_ctrl = ep7312_hwcontrol;
163 this->dev_ready = ep7312_device_ready; 157 this->dev_ready = ep7312_device_ready;
164 /* 15 us command delay time */ 158 /* 15 us command delay time */
165 this->chip_delay = 15; 159 this->chip_delay = 15;
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
index 06e91fa11b34..2d585d2d090c 100644
--- a/drivers/mtd/nand/h1910.c
+++ b/drivers/mtd/nand/h1910.c
@@ -56,36 +56,18 @@ static struct mtd_partition partition_info[] = {
56 56
57/* 57/*
58 * hardware specific access to control-lines 58 * hardware specific access to control-lines
59 *
60 * NAND_NCE: bit 0 - don't care
61 * NAND_CLE: bit 1 - address bit 2
62 * NAND_ALE: bit 2 - address bit 3
59 */ 63 */
60static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) 64static void h1910_hwcontrol(struct mtd_info *mtd, int cmd,
65 unsigned int ctrl)
61{ 66{
62 struct nand_chip *this = (struct nand_chip *)(mtd->priv); 67 struct nand_chip *chip = mtd->priv;
63 68
64 switch (cmd) { 69 if (cmd != NAND_CMD_NONE)
65 70 writeb(cmd, chip->IO_ADDR_W | ((ctrl & 0x6) << 1));
66 case NAND_CTL_SETCLE:
67 this->IO_ADDR_R |= (1 << 2);
68 this->IO_ADDR_W |= (1 << 2);
69 break;
70 case NAND_CTL_CLRCLE:
71 this->IO_ADDR_R &= ~(1 << 2);
72 this->IO_ADDR_W &= ~(1 << 2);
73 break;
74
75 case NAND_CTL_SETALE:
76 this->IO_ADDR_R |= (1 << 3);
77 this->IO_ADDR_W |= (1 << 3);
78 break;
79 case NAND_CTL_CLRALE:
80 this->IO_ADDR_R &= ~(1 << 3);
81 this->IO_ADDR_W &= ~(1 << 3);
82 break;
83
84 case NAND_CTL_SETNCE:
85 break;
86 case NAND_CTL_CLRNCE:
87 break;
88 }
89} 71}
90 72
91/* 73/*
@@ -145,7 +127,7 @@ static int __init h1910_init(void)
145 /* insert callbacks */ 127 /* insert callbacks */
146 this->IO_ADDR_R = nandaddr; 128 this->IO_ADDR_R = nandaddr;
147 this->IO_ADDR_W = nandaddr; 129 this->IO_ADDR_W = nandaddr;
148 this->hwcontrol = h1910_hwcontrol; 130 this->cmd_ctrl = h1910_hwcontrol;
149 this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */ 131 this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */
150 /* 15 us command delay time */ 132 /* 15 us command delay time */
151 this->chip_delay = 50; 133 this->chip_delay = 50;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 778535006c83..649c238837bb 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -139,23 +139,12 @@ static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
139 139
140static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, 140static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
141 size_t *retlen, uint8_t *buf); 141 size_t *retlen, uint8_t *buf);
142static int nand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
143 size_t *retlen, uint8_t *buf, uint8_t *eccbuf,
144 struct nand_oobinfo *oobsel);
145static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 142static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
146 size_t *retlen, uint8_t *buf); 143 size_t *retlen, uint8_t *buf);
147static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, 144static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
148 size_t *retlen, const uint8_t *buf); 145 size_t *retlen, const uint8_t *buf);
149static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
150 size_t *retlen, const uint8_t *buf, uint8_t *eccbuf,
151 struct nand_oobinfo *oobsel);
152static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, 146static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
153 size_t *retlen, const uint8_t *buf); 147 size_t *retlen, const uint8_t *buf);
154static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs,
155 unsigned long count, loff_t to, size_t *retlen);
156static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
157 unsigned long count, loff_t to, size_t *retlen,
158 uint8_t *eccbuf, struct nand_oobinfo *oobsel);
159static int nand_erase(struct mtd_info *mtd, struct erase_info *instr); 148static int nand_erase(struct mtd_info *mtd, struct erase_info *instr);
160static void nand_sync(struct mtd_info *mtd); 149static void nand_sync(struct mtd_info *mtd);
161 150
@@ -175,6 +164,12 @@ static int nand_verify_pages(struct mtd_info *mtd, struct nand_chip *this,
175static int nand_get_device(struct nand_chip *this, struct mtd_info *mtd, 164static int nand_get_device(struct nand_chip *this, struct mtd_info *mtd,
176 int new_state); 165 int new_state);
177 166
167/*
168 * For devices which display every fart in the system on a seperate LED. Is
169 * compiled away when LED support is disabled.
170 */
171DEFINE_LED_TRIGGER(nand_led_trigger);
172
178/** 173/**
179 * nand_release_device - [GENERIC] release chip 174 * nand_release_device - [GENERIC] release chip
180 * @mtd: MTD device structure 175 * @mtd: MTD device structure
@@ -209,19 +204,6 @@ static uint8_t nand_read_byte(struct mtd_info *mtd)
209} 204}
210 205
211/** 206/**
212 * nand_write_byte - [DEFAULT] write one byte to the chip
213 * @mtd: MTD device structure
214 * @byte: pointer to data byte to write
215 *
216 * Default write function for 8it buswith
217 */
218static void nand_write_byte(struct mtd_info *mtd, uint8_t byte)
219{
220 struct nand_chip *this = mtd->priv;
221 writeb(byte, this->IO_ADDR_W);
222}
223
224/**
225 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip 207 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
226 * @mtd: MTD device structure 208 * @mtd: MTD device structure
227 * 209 *
@@ -235,20 +217,6 @@ static uint8_t nand_read_byte16(struct mtd_info *mtd)
235} 217}
236 218
237/** 219/**
238 * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip
239 * @mtd: MTD device structure
240 * @byte: pointer to data byte to write
241 *
242 * Default write function for 16bit buswith with
243 * endianess conversion
244 */
245static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
246{
247 struct nand_chip *this = mtd->priv;
248 writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
249}
250
251/**
252 * nand_read_word - [DEFAULT] read one word from the chip 220 * nand_read_word - [DEFAULT] read one word from the chip
253 * @mtd: MTD device structure 221 * @mtd: MTD device structure
254 * 222 *
@@ -262,20 +230,6 @@ static u16 nand_read_word(struct mtd_info *mtd)
262} 230}
263 231
264/** 232/**
265 * nand_write_word - [DEFAULT] write one word to the chip
266 * @mtd: MTD device structure
267 * @word: data word to write
268 *
269 * Default write function for 16bit buswith without
270 * endianess conversion
271 */
272static void nand_write_word(struct mtd_info *mtd, u16 word)
273{
274 struct nand_chip *this = mtd->priv;
275 writew(word, this->IO_ADDR_W);
276}
277
278/**
279 * nand_select_chip - [DEFAULT] control CE line 233 * nand_select_chip - [DEFAULT] control CE line
280 * @mtd: MTD device structure 234 * @mtd: MTD device structure
281 * @chip: chipnumber to select, -1 for deselect 235 * @chip: chipnumber to select, -1 for deselect
@@ -287,10 +241,10 @@ static void nand_select_chip(struct mtd_info *mtd, int chip)
287 struct nand_chip *this = mtd->priv; 241 struct nand_chip *this = mtd->priv;
288 switch (chip) { 242 switch (chip) {
289 case -1: 243 case -1:
290 this->hwcontrol(mtd, NAND_CTL_CLRNCE); 244 this->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
291 break; 245 break;
292 case 0: 246 case 0:
293 this->hwcontrol(mtd, NAND_CTL_SETNCE); 247 this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
294 break; 248 break;
295 249
296 default: 250 default:
@@ -528,8 +482,6 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
528 return nand_isbad_bbt(mtd, ofs, allowbbt); 482 return nand_isbad_bbt(mtd, ofs, allowbbt);
529} 483}
530 484
531DEFINE_LED_TRIGGER(nand_led_trigger);
532
533/* 485/*
534 * Wait for the ready pin, after a command 486 * Wait for the ready pin, after a command
535 * The timeout is catched later. 487 * The timeout is catched later.
@@ -559,13 +511,12 @@ static void nand_wait_ready(struct mtd_info *mtd)
559 * Send command to NAND device. This function is used for small page 511 * Send command to NAND device. This function is used for small page
560 * devices (256/512 Bytes per page) 512 * devices (256/512 Bytes per page)
561 */ 513 */
562static void nand_command(struct mtd_info *mtd, unsigned command, int column, 514static void nand_command(struct mtd_info *mtd, unsigned int command,
563 int page_addr) 515 int column, int page_addr)
564{ 516{
565 register struct nand_chip *this = mtd->priv; 517 register struct nand_chip *this = mtd->priv;
518 int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
566 519
567 /* Begin command latch cycle */
568 this->hwcontrol(mtd, NAND_CTL_SETCLE);
569 /* 520 /*
570 * Write out the command to the device. 521 * Write out the command to the device.
571 */ 522 */
@@ -583,33 +534,32 @@ static void nand_command(struct mtd_info *mtd, unsigned command, int column,
583 column -= 256; 534 column -= 256;
584 readcmd = NAND_CMD_READ1; 535 readcmd = NAND_CMD_READ1;
585 } 536 }
586 this->write_byte(mtd, readcmd); 537 this->cmd_ctrl(mtd, readcmd, ctrl);
538 ctrl &= ~NAND_CTRL_CHANGE;
587 } 539 }
588 this->write_byte(mtd, command); 540 this->cmd_ctrl(mtd, command, ctrl);
589
590 /* Set ALE and clear CLE to start address cycle */
591 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
592
593 if (column != -1 || page_addr != -1) {
594 this->hwcontrol(mtd, NAND_CTL_SETALE);
595 541
596 /* Serially input address */ 542 /*
597 if (column != -1) { 543 * Address cycle, when necessary
598 /* Adjust columns for 16 bit buswidth */ 544 */
599 if (this->options & NAND_BUSWIDTH_16) 545 ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
600 column >>= 1; 546 /* Serially input address */
601 this->write_byte(mtd, column); 547 if (column != -1) {
602 } 548 /* Adjust columns for 16 bit buswidth */
603 if (page_addr != -1) { 549 if (this->options & NAND_BUSWIDTH_16)
604 this->write_byte(mtd, (uint8_t)(page_addr & 0xff)); 550 column >>= 1;
605 this->write_byte(mtd, (uint8_t)((page_addr >> 8) & 0xff)); 551 this->cmd_ctrl(mtd, column, ctrl);
606 /* One more address cycle for devices > 32MiB */ 552 ctrl &= ~NAND_CTRL_CHANGE;
607 if (this->chipsize > (32 << 20)) 553 }
608 this->write_byte(mtd, (uint8_t)((page_addr >> 16) & 0x0f)); 554 if (page_addr != -1) {
609 } 555 this->cmd_ctrl(mtd, page_addr, ctrl);
610 /* Latch in address */ 556 ctrl &= ~NAND_CTRL_CHANGE;
611 this->hwcontrol(mtd, NAND_CTL_CLRALE); 557 this->cmd_ctrl(mtd, page_addr >> 8, ctrl);
558 /* One more address cycle for devices > 32MiB */
559 if (this->chipsize > (32 << 20))
560 this->cmd_ctrl(mtd, page_addr >> 16, ctrl);
612 } 561 }
562 this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
613 563
614 /* 564 /*
615 * program and erase have their own busy handlers 565 * program and erase have their own busy handlers
@@ -622,15 +572,16 @@ static void nand_command(struct mtd_info *mtd, unsigned command, int column,
622 case NAND_CMD_ERASE2: 572 case NAND_CMD_ERASE2:
623 case NAND_CMD_SEQIN: 573 case NAND_CMD_SEQIN:
624 case NAND_CMD_STATUS: 574 case NAND_CMD_STATUS:
575 this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE);
625 return; 576 return;
626 577
627 case NAND_CMD_RESET: 578 case NAND_CMD_RESET:
628 if (this->dev_ready) 579 if (this->dev_ready)
629 break; 580 break;
630 udelay(this->chip_delay); 581 udelay(this->chip_delay);
631 this->hwcontrol(mtd, NAND_CTL_SETCLE); 582 this->cmd_ctrl(mtd, NAND_CMD_STATUS,
632 this->write_byte(mtd, NAND_CMD_STATUS); 583 NAND_CTRL_CLE | NAND_CTRL_CHANGE);
633 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 584 this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE);
634 while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ; 585 while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ;
635 return; 586 return;
636 587
@@ -659,12 +610,13 @@ static void nand_command(struct mtd_info *mtd, unsigned command, int column,
659 * @column: the column address for this command, -1 if none 610 * @column: the column address for this command, -1 if none
660 * @page_addr: the page address for this command, -1 if none 611 * @page_addr: the page address for this command, -1 if none
661 * 612 *
662 * Send command to NAND device. This is the version for the new large page devices 613 * Send command to NAND device. This is the version for the new large page
663 * We dont have the separate regions as we have in the small page devices. 614 * devices We dont have the separate regions as we have in the small page
664 * We must emulate NAND_CMD_READOOB to keep the code compatible. 615 * devices. We must emulate NAND_CMD_READOOB to keep the code compatible.
665 * 616 *
666 */ 617 */
667static void nand_command_lp(struct mtd_info *mtd, unsigned command, int column, int page_addr) 618static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
619 int column, int page_addr)
668{ 620{
669 register struct nand_chip *this = mtd->priv; 621 register struct nand_chip *this = mtd->priv;
670 622
@@ -674,34 +626,33 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned command, int column,
674 command = NAND_CMD_READ0; 626 command = NAND_CMD_READ0;
675 } 627 }
676 628
677 /* Begin command latch cycle */ 629 /* Command latch cycle */
678 this->hwcontrol(mtd, NAND_CTL_SETCLE); 630 this->cmd_ctrl(mtd, command & 0xff,
679 /* Write out the command to the device. */ 631 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
680 this->write_byte(mtd, (command & 0xff));
681 /* End command latch cycle */
682 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
683 632
684 if (column != -1 || page_addr != -1) { 633 if (column != -1 || page_addr != -1) {
685 this->hwcontrol(mtd, NAND_CTL_SETALE); 634 int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
686 635
687 /* Serially input address */ 636 /* Serially input address */
688 if (column != -1) { 637 if (column != -1) {
689 /* Adjust columns for 16 bit buswidth */ 638 /* Adjust columns for 16 bit buswidth */
690 if (this->options & NAND_BUSWIDTH_16) 639 if (this->options & NAND_BUSWIDTH_16)
691 column >>= 1; 640 column >>= 1;
692 this->write_byte(mtd, column & 0xff); 641 this->cmd_ctrl(mtd, column, ctrl);
693 this->write_byte(mtd, column >> 8); 642 ctrl &= ~NAND_CTRL_CHANGE;
643 this->cmd_ctrl(mtd, column >> 8, ctrl);
694 } 644 }
695 if (page_addr != -1) { 645 if (page_addr != -1) {
696 this->write_byte(mtd, (uint8_t)(page_addr & 0xff)); 646 this->cmd_ctrl(mtd, page_addr, ctrl);
697 this->write_byte(mtd, (uint8_t)((page_addr >> 8) & 0xff)); 647 this->cmd_ctrl(mtd, page_addr >> 8,
648 NAND_NCE | NAND_ALE);
698 /* One more address cycle for devices > 128MiB */ 649 /* One more address cycle for devices > 128MiB */
699 if (this->chipsize > (128 << 20)) 650 if (this->chipsize > (128 << 20))
700 this->write_byte(mtd, (uint8_t)((page_addr >> 16) & 0xff)); 651 this->cmd_ctrl(mtd, page_addr >> 16,
652 NAND_NCE | NAND_ALE);
701 } 653 }
702 /* Latch in address */
703 this->hwcontrol(mtd, NAND_CTL_CLRALE);
704 } 654 }
655 this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
705 656
706 /* 657 /*
707 * program and erase have their own busy handlers 658 * program and erase have their own busy handlers
@@ -733,20 +684,14 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned command, int column,
733 if (this->dev_ready) 684 if (this->dev_ready)
734 break; 685 break;
735 udelay(this->chip_delay); 686 udelay(this->chip_delay);
736 this->hwcontrol(mtd, NAND_CTL_SETCLE); 687 this->cmd_ctrl(mtd, NAND_CMD_STATUS, NAND_NCE | NAND_CLE);
737 this->write_byte(mtd, NAND_CMD_STATUS); 688 this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE);
738 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
739 while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ; 689 while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ;
740 return; 690 return;
741 691
742 case NAND_CMD_READ0: 692 case NAND_CMD_READ0:
743 /* Begin command latch cycle */ 693 this->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_NCE | NAND_CLE);
744 this->hwcontrol(mtd, NAND_CTL_SETCLE); 694 this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE);
745 /* Write out the start read command */
746 this->write_byte(mtd, NAND_CMD_READSTART);
747 /* End command latch cycle */
748 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
749 /* Fall through into ready check */
750 695
751 /* This applies to read commands */ 696 /* This applies to read commands */
752 default: 697 default:
@@ -1085,27 +1030,6 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retl
1085} 1030}
1086 1031
1087/** 1032/**
1088 * nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc
1089 * @mtd: MTD device structure
1090 * @from: offset to read from
1091 * @len: number of bytes to read
1092 * @retlen: pointer to variable to store the number of read bytes
1093 * @buf: the databuffer to put data
1094 * @oob_buf: filesystem supplied oob data buffer
1095 * @oobsel: oob selection structure
1096 *
1097 * This function simply calls nand_do_read_ecc with flags = 0xff
1098 */
1099static int nand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
1100 size_t *retlen, uint8_t *buf, uint8_t *oob_buf, struct nand_oobinfo *oobsel)
1101{
1102 /* use userspace supplied oobinfo, if zero */
1103 if (oobsel == NULL)
1104 oobsel = &mtd->oobinfo;
1105 return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff);
1106}
1107
1108/**
1109 * nand_do_read_ecc - [MTD Interface] Read data with ECC 1033 * nand_do_read_ecc - [MTD Interface] Read data with ECC
1110 * @mtd: MTD device structure 1034 * @mtd: MTD device structure
1111 * @from: offset to read from 1035 * @from: offset to read from
@@ -1529,6 +1453,56 @@ int nand_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, s
1529} 1453}
1530 1454
1531/** 1455/**
1456 * nand_write_raw - [GENERIC] Write raw data including oob
1457 * @mtd: MTD device structure
1458 * @buf: source buffer
1459 * @to: offset to write to
1460 * @len: number of bytes to write
1461 * @buf: source buffer
1462 * @oob: oob buffer
1463 *
1464 * Write raw data including oob
1465 */
1466int nand_write_raw(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
1467 uint8_t *buf, uint8_t *oob)
1468{
1469 struct nand_chip *this = mtd->priv;
1470 int page = (int)(to >> this->page_shift);
1471 int chip = (int)(to >> this->chip_shift);
1472 int ret;
1473
1474 *retlen = 0;
1475
1476 /* Do not allow writes past end of device */
1477 if ((to + len) > mtd->size) {
1478 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt write "
1479 "beyond end of device\n");
1480 return -EINVAL;
1481 }
1482
1483 /* Grab the lock and see if the device is available */
1484 nand_get_device(this, mtd, FL_WRITING);
1485
1486 this->select_chip(mtd, chip);
1487 this->data_poi = buf;
1488
1489 while (len != *retlen) {
1490 ret = nand_write_page(mtd, this, page, oob, &mtd->oobinfo, 0);
1491 if (ret)
1492 return ret;
1493 page++;
1494 *retlen += mtd->writesize;
1495 this->data_poi += mtd->writesize;
1496 oob += mtd->oobsize;
1497 }
1498
1499 /* Deselect and wake up anyone waiting on the device */
1500 nand_release_device(mtd);
1501 return 0;
1502}
1503EXPORT_SYMBOL_GPL(nand_write_raw);
1504
1505/**
1532 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer 1506 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
1533 * @mtd: MTD device structure 1507 * @mtd: MTD device structure
1534 * @fsbuf: buffer given by fs driver 1508 * @fsbuf: buffer given by fs driver
@@ -1590,57 +1564,39 @@ static uint8_t *nand_prepare_oobbuf(struct mtd_info *mtd, uint8_t *fsbuf, struct
1590#define NOTALIGNED(x) (x & (mtd->writesize-1)) != 0 1564#define NOTALIGNED(x) (x & (mtd->writesize-1)) != 0
1591 1565
1592/** 1566/**
1593 * nand_write - [MTD Interface] compability function for nand_write_ecc 1567 * nand_write - [MTD Interface] NAND write with ECC
1594 * @mtd: MTD device structure 1568 * @mtd: MTD device structure
1595 * @to: offset to write to 1569 * @to: offset to write to
1596 * @len: number of bytes to write 1570 * @len: number of bytes to write
1597 * @retlen: pointer to variable to store the number of written bytes 1571 * @retlen: pointer to variable to store the number of written bytes
1598 * @buf: the data to write 1572 * @buf: the data to write
1599 * 1573 *
1600 * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL
1601 *
1602*/
1603static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf)
1604{
1605 return (nand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL));
1606}
1607
1608/**
1609 * nand_write_ecc - [MTD Interface] NAND write with ECC
1610 * @mtd: MTD device structure
1611 * @to: offset to write to
1612 * @len: number of bytes to write
1613 * @retlen: pointer to variable to store the number of written bytes
1614 * @buf: the data to write
1615 * @eccbuf: filesystem supplied oob data buffer
1616 * @oobsel: oob selection structure
1617 *
1618 * NAND write with ECC 1574 * NAND write with ECC
1619 */ 1575 */
1620static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 1576static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
1621 size_t *retlen, const uint8_t *buf, uint8_t *eccbuf, 1577 size_t *retlen, const uint8_t *buf)
1622 struct nand_oobinfo *oobsel)
1623{ 1578{
1624 int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr; 1579 int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr;
1625 int autoplace = 0, numpages, totalpages; 1580 int autoplace = 0, numpages, totalpages;
1626 struct nand_chip *this = mtd->priv; 1581 struct nand_chip *this = mtd->priv;
1627 uint8_t *oobbuf, *bufstart; 1582 uint8_t *oobbuf, *bufstart, *eccbuf = NULL;
1628 int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); 1583 int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
1584 struct nand_oobinfo *oobsel = &mtd->oobinfo;
1629 1585
1630 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int)to, (int)len); 1586 DEBUG(MTD_DEBUG_LEVEL3, "nand_write: to = 0x%08x, len = %i\n", (unsigned int)to, (int)len);
1631 1587
1632 /* Initialize retlen, in case of early exit */ 1588 /* Initialize retlen, in case of early exit */
1633 *retlen = 0; 1589 *retlen = 0;
1634 1590
1635 /* Do not allow write past end of device */ 1591 /* Do not allow write past end of device */
1636 if ((to + len) > mtd->size) { 1592 if ((to + len) > mtd->size) {
1637 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n"); 1593 DEBUG(MTD_DEBUG_LEVEL0, "nand_write: Attempt to write past end of page\n");
1638 return -EINVAL; 1594 return -EINVAL;
1639 } 1595 }
1640 1596
1641 /* reject writes, which are not page aligned */ 1597 /* reject writes, which are not page aligned */
1642 if (NOTALIGNED(to) || NOTALIGNED(len)) { 1598 if (NOTALIGNED(to) || NOTALIGNED(len)) {
1643 printk(KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); 1599 printk(KERN_NOTICE "nand_write: Attempt to write not page aligned data\n");
1644 return -EINVAL; 1600 return -EINVAL;
1645 } 1601 }
1646 1602
@@ -1656,10 +1612,6 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
1656 if (nand_check_wp(mtd)) 1612 if (nand_check_wp(mtd))
1657 goto out; 1613 goto out;
1658 1614
1659 /* if oobsel is NULL, use chip defaults */
1660 if (oobsel == NULL)
1661 oobsel = &mtd->oobinfo;
1662
1663 /* Autoplace of oob data ? Use the default placement scheme */ 1615 /* Autoplace of oob data ? Use the default placement scheme */
1664 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { 1616 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
1665 oobsel = this->autooob; 1617 oobsel = this->autooob;
@@ -1694,7 +1646,7 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
1694 */ 1646 */
1695 ret = nand_write_page(mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0)); 1647 ret = nand_write_page(mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
1696 if (ret) { 1648 if (ret) {
1697 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret); 1649 DEBUG(MTD_DEBUG_LEVEL0, "nand_write: write_page failed %d\n", ret);
1698 goto out; 1650 goto out;
1699 } 1651 }
1700 /* Next oob page */ 1652 /* Next oob page */
@@ -1717,7 +1669,7 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
1717 ret = nand_verify_pages(mtd, this, startpage, page - startpage, 1669 ret = nand_verify_pages(mtd, this, startpage, page - startpage,
1718 oobbuf, oobsel, chipnr, (eccbuf != NULL)); 1670 oobbuf, oobsel, chipnr, (eccbuf != NULL));
1719 if (ret) { 1671 if (ret) {
1720 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); 1672 DEBUG(MTD_DEBUG_LEVEL0, "nand_write: verify_pages failed %d\n", ret);
1721 goto out; 1673 goto out;
1722 } 1674 }
1723 *retlen = written; 1675 *retlen = written;
@@ -1746,7 +1698,7 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
1746 if (!ret) 1698 if (!ret)
1747 *retlen = written; 1699 *retlen = written;
1748 else 1700 else
1749 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); 1701 DEBUG(MTD_DEBUG_LEVEL0, "nand_write: verify_pages failed %d\n", ret);
1750 1702
1751 out: 1703 out:
1752 /* Deselect and wake up anyone waiting on the device */ 1704 /* Deselect and wake up anyone waiting on the device */
@@ -1857,187 +1809,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *r
1857} 1809}
1858 1810
1859/** 1811/**
1860 * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc
1861 * @mtd: MTD device structure
1862 * @vecs: the iovectors to write
1863 * @count: number of vectors
1864 * @to: offset to write to
1865 * @retlen: pointer to variable to store the number of written bytes
1866 *
1867 * NAND write with kvec. This just calls the ecc function
1868 */
1869static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1870 loff_t to, size_t *retlen)
1871{
1872 return (nand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL));
1873}
1874
1875/**
1876 * nand_writev_ecc - [MTD Interface] write with iovec with ecc
1877 * @mtd: MTD device structure
1878 * @vecs: the iovectors to write
1879 * @count: number of vectors
1880 * @to: offset to write to
1881 * @retlen: pointer to variable to store the number of written bytes
1882 * @eccbuf: filesystem supplied oob data buffer
1883 * @oobsel: oob selection structure
1884 *
1885 * NAND write with iovec with ecc
1886 */
1887static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1888 loff_t to, size_t *retlen, uint8_t *eccbuf, struct nand_oobinfo *oobsel)
1889{
1890 int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
1891 int oob, numpages, autoplace = 0, startpage;
1892 struct nand_chip *this = mtd->priv;
1893 int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
1894 uint8_t *oobbuf, *bufstart;
1895
1896 /* Preset written len for early exit */
1897 *retlen = 0;
1898
1899 /* Calculate total length of data */
1900 total_len = 0;
1901 for (i = 0; i < count; i++)
1902 total_len += (int)vecs[i].iov_len;
1903
1904 DEBUG(MTD_DEBUG_LEVEL3, "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int)to, (unsigned int)total_len, count);
1905
1906 /* Do not allow write past end of page */
1907 if ((to + total_len) > mtd->size) {
1908 DEBUG(MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
1909 return -EINVAL;
1910 }
1911
1912 /* reject writes, which are not page aligned */
1913 if (NOTALIGNED(to) || NOTALIGNED(total_len)) {
1914 printk(KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
1915 return -EINVAL;
1916 }
1917
1918 /* Grab the lock and see if the device is available */
1919 nand_get_device(this, mtd, FL_WRITING);
1920
1921 /* Get the current chip-nr */
1922 chipnr = (int)(to >> this->chip_shift);
1923 /* Select the NAND device */
1924 this->select_chip(mtd, chipnr);
1925
1926 /* Check, if it is write protected */
1927 if (nand_check_wp(mtd))
1928 goto out;
1929
1930 /* if oobsel is NULL, use chip defaults */
1931 if (oobsel == NULL)
1932 oobsel = &mtd->oobinfo;
1933
1934 /* Autoplace of oob data ? Use the default placement scheme */
1935 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
1936 oobsel = this->autooob;
1937 autoplace = 1;
1938 }
1939 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1940 autoplace = 1;
1941
1942 /* Setup start page */
1943 page = (int)(to >> this->page_shift);
1944 /* Invalidate the page cache, if we write to the cached page */
1945 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
1946 this->pagebuf = -1;
1947
1948 startpage = page & this->pagemask;
1949
1950 /* Loop until all kvec' data has been written */
1951 len = 0;
1952 while (count) {
1953 /* If the given tuple is >= pagesize then
1954 * write it out from the iov
1955 */
1956 if ((vecs->iov_len - len) >= mtd->writesize) {
1957 /* Calc number of pages we can write
1958 * out of this iov in one go */
1959 numpages = (vecs->iov_len - len) >> this->page_shift;
1960 /* Do not cross block boundaries */
1961 numpages = min(ppblock - (startpage & (ppblock - 1)), numpages);
1962 oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages);
1963 bufstart = (uint8_t *) vecs->iov_base;
1964 bufstart += len;
1965 this->data_poi = bufstart;
1966 oob = 0;
1967 for (i = 1; i <= numpages; i++) {
1968 /* Write one page. If this is the last page to write
1969 * then use the real pageprogram command, else select
1970 * cached programming if supported by the chip.
1971 */
1972 ret = nand_write_page(mtd, this, page & this->pagemask,
1973 &oobbuf[oob], oobsel, i != numpages);
1974 if (ret)
1975 goto out;
1976 this->data_poi += mtd->writesize;
1977 len += mtd->writesize;
1978 oob += mtd->oobsize;
1979 page++;
1980 }
1981 /* Check, if we have to switch to the next tuple */
1982 if (len >= (int)vecs->iov_len) {
1983 vecs++;
1984 len = 0;
1985 count--;
1986 }
1987 } else {
1988 /* We must use the internal buffer, read data out of each
1989 * tuple until we have a full page to write
1990 */
1991 int cnt = 0;
1992 while (cnt < mtd->writesize) {
1993 if (vecs->iov_base != NULL && vecs->iov_len)
1994 this->data_buf[cnt++] = ((uint8_t *) vecs->iov_base)[len++];
1995 /* Check, if we have to switch to the next tuple */
1996 if (len >= (int)vecs->iov_len) {
1997 vecs++;
1998 len = 0;
1999 count--;
2000 }
2001 }
2002 this->pagebuf = page;
2003 this->data_poi = this->data_buf;
2004 bufstart = this->data_poi;
2005 numpages = 1;
2006 oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages);
2007 ret = nand_write_page(mtd, this, page & this->pagemask, oobbuf, oobsel, 0);
2008 if (ret)
2009 goto out;
2010 page++;
2011 }
2012
2013 this->data_poi = bufstart;
2014 ret = nand_verify_pages(mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
2015 if (ret)
2016 goto out;
2017
2018 written += mtd->writesize * numpages;
2019 /* All done ? */
2020 if (!count)
2021 break;
2022
2023 startpage = page & this->pagemask;
2024 /* Check, if we cross a chip boundary */
2025 if (!startpage) {
2026 chipnr++;
2027 this->select_chip(mtd, -1);
2028 this->select_chip(mtd, chipnr);
2029 }
2030 }
2031 ret = 0;
2032 out:
2033 /* Deselect and wake up anyone waiting on the device */
2034 nand_release_device(mtd);
2035
2036 *retlen = written;
2037 return ret;
2038}
2039
2040/**
2041 * single_erease_cmd - [GENERIC] NAND standard block erase command function 1812 * single_erease_cmd - [GENERIC] NAND standard block erase command function
2042 * @mtd: MTD device structure 1813 * @mtd: MTD device structure
2043 * @page: the page address of the block which will be erased 1814 * @page: the page address of the block which will be erased
@@ -2392,12 +2163,8 @@ static void nand_set_defaults(struct nand_chip *this, int busw)
2392 2163
2393 if (!this->select_chip) 2164 if (!this->select_chip)
2394 this->select_chip = nand_select_chip; 2165 this->select_chip = nand_select_chip;
2395 if (!this->write_byte)
2396 this->write_byte = busw ? nand_write_byte16 : nand_write_byte;
2397 if (!this->read_byte) 2166 if (!this->read_byte)
2398 this->read_byte = busw ? nand_read_byte16 : nand_read_byte; 2167 this->read_byte = busw ? nand_read_byte16 : nand_read_byte;
2399 if (!this->write_word)
2400 this->write_word = nand_write_word;
2401 if (!this->read_word) 2168 if (!this->read_word)
2402 this->read_word = nand_read_word; 2169 this->read_word = nand_read_word;
2403 if (!this->block_bad) 2170 if (!this->block_bad)
@@ -2713,13 +2480,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2713 mtd->unpoint = NULL; 2480 mtd->unpoint = NULL;
2714 mtd->read = nand_read; 2481 mtd->read = nand_read;
2715 mtd->write = nand_write; 2482 mtd->write = nand_write;
2716 mtd->read_ecc = nand_read_ecc;
2717 mtd->write_ecc = nand_write_ecc;
2718 mtd->read_oob = nand_read_oob; 2483 mtd->read_oob = nand_read_oob;
2719 mtd->write_oob = nand_write_oob; 2484 mtd->write_oob = nand_write_oob;
2720 mtd->readv = NULL;
2721 mtd->writev = nand_writev;
2722 mtd->writev_ecc = nand_writev_ecc;
2723 mtd->sync = nand_sync; 2485 mtd->sync = nand_sync;
2724 mtd->lock = NULL; 2486 mtd->lock = NULL;
2725 mtd->unlock = NULL; 2487 mtd->unlock = NULL;
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index fbccb2a25186..ecaaca18d1e0 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -156,7 +156,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
156 156
157 while (totlen) { 157 while (totlen) {
158 len = min(totlen, (size_t) (1 << this->bbt_erase_shift)); 158 len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
159 res = mtd->read_ecc(mtd, from, len, &retlen, buf, NULL, this->autooob); 159 res = mtd->read(mtd, from, len, &retlen, buf);
160 if (res < 0) { 160 if (res < 0) {
161 if (retlen != len) { 161 if (retlen != len) {
162 printk(KERN_INFO "nand_bbt: Error reading bad block table\n"); 162 printk(KERN_INFO "nand_bbt: Error reading bad block table\n");
@@ -471,17 +471,17 @@ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt
471 * 471 *
472*/ 472*/
473static int write_bbt(struct mtd_info *mtd, uint8_t *buf, 473static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
474 struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) 474 struct nand_bbt_descr *td, struct nand_bbt_descr *md,
475 int chipsel)
475{ 476{
476 struct nand_chip *this = mtd->priv; 477 struct nand_chip *this = mtd->priv;
477 struct nand_oobinfo oobinfo;
478 struct erase_info einfo; 478 struct erase_info einfo;
479 int i, j, res, chip = 0; 479 int i, j, res, chip = 0;
480 int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; 480 int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
481 int nrchips, bbtoffs, pageoffs; 481 int nrchips, bbtoffs, pageoffs, ooboffs;
482 uint8_t msk[4]; 482 uint8_t msk[4];
483 uint8_t rcode = td->reserved_block_code; 483 uint8_t rcode = td->reserved_block_code;
484 size_t retlen, len = 0; 484 size_t retlen, len = 0, ooblen;
485 loff_t to; 485 loff_t to;
486 486
487 if (!rcode) 487 if (!rcode)
@@ -526,12 +526,14 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
526 for (i = 0; i < td->maxblocks; i++) { 526 for (i = 0; i < td->maxblocks; i++) {
527 int block = startblock + dir * i; 527 int block = startblock + dir * i;
528 /* Check, if the block is bad */ 528 /* Check, if the block is bad */
529 switch ((this->bbt[block >> 2] >> (2 * (block & 0x03))) & 0x03) { 529 switch ((this->bbt[block >> 2] >>
530 (2 * (block & 0x03))) & 0x03) {
530 case 0x01: 531 case 0x01:
531 case 0x03: 532 case 0x03:
532 continue; 533 continue;
533 } 534 }
534 page = block << (this->bbt_erase_shift - this->page_shift); 535 page = block <<
536 (this->bbt_erase_shift - this->page_shift);
535 /* Check, if the block is used by the mirror table */ 537 /* Check, if the block is used by the mirror table */
536 if (!md || md->pages[chip] != page) 538 if (!md || md->pages[chip] != page)
537 goto write; 539 goto write;
@@ -542,11 +544,20 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
542 544
543 /* Set up shift count and masks for the flash table */ 545 /* Set up shift count and masks for the flash table */
544 bits = td->options & NAND_BBT_NRBITS_MSK; 546 bits = td->options & NAND_BBT_NRBITS_MSK;
547 msk[2] = ~rcode;
545 switch (bits) { 548 switch (bits) {
546 case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x01; break; 549 case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01;
547 case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x03; break; 550 msk[3] = 0x01;
548 case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; msk[2] = ~rcode; msk[3] = 0x0f; break; 551 break;
549 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; 552 case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01;
553 msk[3] = 0x03;
554 break;
555 case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C;
556 msk[3] = 0x0f;
557 break;
558 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F;
559 msk[3] = 0xff;
560 break;
550 default: return -EINVAL; 561 default: return -EINVAL;
551 } 562 }
552 563
@@ -554,49 +565,55 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
554 565
555 to = ((loff_t) page) << this->page_shift; 566 to = ((loff_t) page) << this->page_shift;
556 567
557 memcpy(&oobinfo, this->autooob, sizeof(oobinfo));
558 oobinfo.useecc = MTD_NANDECC_PLACEONLY;
559
560 /* Must we save the block contents ? */ 568 /* Must we save the block contents ? */
561 if (td->options & NAND_BBT_SAVECONTENT) { 569 if (td->options & NAND_BBT_SAVECONTENT) {
562 /* Make it block aligned */ 570 /* Make it block aligned */
563 to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1)); 571 to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
564 len = 1 << this->bbt_erase_shift; 572 len = 1 << this->bbt_erase_shift;
565 res = mtd->read_ecc(mtd, to, len, &retlen, buf, &buf[len], &oobinfo); 573 res = mtd->read(mtd, to, len, &retlen, buf);
566 if (res < 0) { 574 if (res < 0) {
567 if (retlen != len) { 575 if (retlen != len) {
568 printk(KERN_INFO 576 printk(KERN_INFO "nand_bbt: Error "
569 "nand_bbt: Error reading block for writing the bad block table\n"); 577 "reading block for writing "
578 "the bad block table\n");
570 return res; 579 return res;
571 } 580 }
572 printk(KERN_WARNING "nand_bbt: ECC error while reading block for writing bad block table\n"); 581 printk(KERN_WARNING "nand_bbt: ECC error "
582 "while reading block for writing "
583 "bad block table\n");
573 } 584 }
585 /* Read oob data */
586 ooblen = (len >> this->page_shift) * mtd->oobsize;
587 res = mtd->read_oob(mtd, to + mtd->writesize, ooblen,
588 &retlen, &buf[len]);
589 if (res < 0 || retlen != ooblen)
590 goto outerr;
591
574 /* Calc the byte offset in the buffer */ 592 /* Calc the byte offset in the buffer */
575 pageoffs = page - (int)(to >> this->page_shift); 593 pageoffs = page - (int)(to >> this->page_shift);
576 offs = pageoffs << this->page_shift; 594 offs = pageoffs << this->page_shift;
577 /* Preset the bbt area with 0xff */ 595 /* Preset the bbt area with 0xff */
578 memset(&buf[offs], 0xff, (size_t) (numblocks >> sft)); 596 memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
579 /* Preset the bbt's oob area with 0xff */ 597 ooboffs = len + (pageoffs * mtd->oobsize);
580 memset(&buf[len + pageoffs * mtd->oobsize], 0xff, 598
581 ((len >> this->page_shift) - pageoffs) * mtd->oobsize);
582 if (td->options & NAND_BBT_VERSION) {
583 buf[len + (pageoffs * mtd->oobsize) + td->veroffs] = td->version[chip];
584 }
585 } else { 599 } else {
586 /* Calc length */ 600 /* Calc length */
587 len = (size_t) (numblocks >> sft); 601 len = (size_t) (numblocks >> sft);
588 /* Make it page aligned ! */ 602 /* Make it page aligned ! */
589 len = (len + (mtd->writesize - 1)) & ~(mtd->writesize - 1); 603 len = (len + (mtd->writesize - 1)) &
604 ~(mtd->writesize - 1);
590 /* Preset the buffer with 0xff */ 605 /* Preset the buffer with 0xff */
591 memset(buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize); 606 memset(buf, 0xff, len +
607 (len >> this->page_shift)* mtd->oobsize);
592 offs = 0; 608 offs = 0;
609 ooboffs = len;
593 /* Pattern is located in oob area of first page */ 610 /* Pattern is located in oob area of first page */
594 memcpy(&buf[len + td->offs], td->pattern, td->len); 611 memcpy(&buf[ooboffs + td->offs], td->pattern, td->len);
595 if (td->options & NAND_BBT_VERSION) {
596 buf[len + td->veroffs] = td->version[chip];
597 }
598 } 612 }
599 613
614 if (td->options & NAND_BBT_VERSION)
615 buf[ooboffs + td->veroffs] = td->version[chip];
616
600 /* walk through the memory table */ 617 /* walk through the memory table */
601 for (i = 0; i < numblocks;) { 618 for (i = 0; i < numblocks;) {
602 uint8_t dat; 619 uint8_t dat;
@@ -604,7 +621,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
604 for (j = 0; j < 4; j++, i++) { 621 for (j = 0; j < 4; j++, i++) {
605 int sftcnt = (i << (3 - sft)) & sftmsk; 622 int sftcnt = (i << (3 - sft)) & sftmsk;
606 /* Do not store the reserved bbt blocks ! */ 623 /* Do not store the reserved bbt blocks ! */
607 buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt); 624 buf[offs + (i >> sft)] &=
625 ~(msk[dat & 0x03] << sftcnt);
608 dat >>= 2; 626 dat >>= 2;
609 } 627 }
610 } 628 }
@@ -614,23 +632,25 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
614 einfo.addr = (unsigned long)to; 632 einfo.addr = (unsigned long)to;
615 einfo.len = 1 << this->bbt_erase_shift; 633 einfo.len = 1 << this->bbt_erase_shift;
616 res = nand_erase_nand(mtd, &einfo, 1); 634 res = nand_erase_nand(mtd, &einfo, 1);
617 if (res < 0) { 635 if (res < 0)
618 printk(KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); 636 goto outerr;
619 return res;
620 }
621 637
622 res = mtd->write_ecc(mtd, to, len, &retlen, buf, &buf[len], &oobinfo); 638 res = nand_write_raw(mtd, to, len, &retlen, buf, &buf[len]);
623 if (res < 0) { 639 if (res < 0)
624 printk(KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); 640 goto outerr;
625 return res; 641
626 } 642 printk(KERN_DEBUG "Bad block table written to 0x%08x, version "
627 printk(KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", 643 "0x%02X\n", (unsigned int)to, td->version[chip]);
628 (unsigned int)to, td->version[chip]);
629 644
630 /* Mark it as used */ 645 /* Mark it as used */
631 td->pages[chip] = page; 646 td->pages[chip] = page;
632 } 647 }
633 return 0; 648 return 0;
649
650 outerr:
651 printk(KERN_WARNING
652 "nand_bbt: Error while writing bad block table %d\n", res);
653 return res;
634} 654}
635 655
636/** 656/**
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 22af9b29d2bf..ebd64abc8be8 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -1071,68 +1071,6 @@ switch_state(struct nandsim *ns)
1071 } 1071 }
1072} 1072}
1073 1073
1074static void
1075ns_hwcontrol(struct mtd_info *mtd, int cmd)
1076{
1077 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
1078
1079 switch (cmd) {
1080
1081 /* set CLE line high */
1082 case NAND_CTL_SETCLE:
1083 NS_DBG("ns_hwcontrol: start command latch cycles\n");
1084 ns->lines.cle = 1;
1085 break;
1086
1087 /* set CLE line low */
1088 case NAND_CTL_CLRCLE:
1089 NS_DBG("ns_hwcontrol: stop command latch cycles\n");
1090 ns->lines.cle = 0;
1091 break;
1092
1093 /* set ALE line high */
1094 case NAND_CTL_SETALE:
1095 NS_DBG("ns_hwcontrol: start address latch cycles\n");
1096 ns->lines.ale = 1;
1097 break;
1098
1099 /* set ALE line low */
1100 case NAND_CTL_CLRALE:
1101 NS_DBG("ns_hwcontrol: stop address latch cycles\n");
1102 ns->lines.ale = 0;
1103 break;
1104
1105 /* set WP line high */
1106 case NAND_CTL_SETWP:
1107 NS_DBG("ns_hwcontrol: enable write protection\n");
1108 ns->lines.wp = 1;
1109 break;
1110
1111 /* set WP line low */
1112 case NAND_CTL_CLRWP:
1113 NS_DBG("ns_hwcontrol: disable write protection\n");
1114 ns->lines.wp = 0;
1115 break;
1116
1117 /* set CE line low */
1118 case NAND_CTL_SETNCE:
1119 NS_DBG("ns_hwcontrol: enable chip\n");
1120 ns->lines.ce = 1;
1121 break;
1122
1123 /* set CE line high */
1124 case NAND_CTL_CLRNCE:
1125 NS_DBG("ns_hwcontrol: disable chip\n");
1126 ns->lines.ce = 0;
1127 break;
1128
1129 default:
1130 NS_ERR("hwcontrol: unknown command\n");
1131 }
1132
1133 return;
1134}
1135
1136static u_char 1074static u_char
1137ns_nand_read_byte(struct mtd_info *mtd) 1075ns_nand_read_byte(struct mtd_info *mtd)
1138{ 1076{
@@ -1359,6 +1297,18 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1359 return; 1297 return;
1360} 1298}
1361 1299
1300static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask)
1301{
1302 struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
1303
1304 ns->lines.cle = bitmask & NAND_CLE ? 1 : 0;
1305 ns->lines.ale = bitmask & NAND_ALE ? 1 : 0;
1306 ns->lines.ce = bitmask & NAND_NCE ? 1 : 0;
1307
1308 if (cmd != NAND_CMD_NONE)
1309 ns_nand_write_byte(mtd, cmd);
1310}
1311
1362static int 1312static int
1363ns_device_ready(struct mtd_info *mtd) 1313ns_device_ready(struct mtd_info *mtd)
1364{ 1314{
@@ -1377,17 +1327,6 @@ ns_nand_read_word(struct mtd_info *mtd)
1377} 1327}
1378 1328
1379static void 1329static void
1380ns_nand_write_word(struct mtd_info *mtd, uint16_t word)
1381{
1382 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
1383
1384 NS_DBG("write_word\n");
1385
1386 chip->write_byte(mtd, word & 0xFF);
1387 chip->write_byte(mtd, word >> 8);
1388}
1389
1390static void
1391ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 1330ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
1392{ 1331{
1393 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1332 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1514,14 +1453,12 @@ static int __init ns_init_module(void)
1514 /* 1453 /*
1515 * Register simulator's callbacks. 1454 * Register simulator's callbacks.
1516 */ 1455 */
1517 chip->hwcontrol = ns_hwcontrol; 1456 chip->cmd_ctrl = ns_hwcontrol;
1518 chip->read_byte = ns_nand_read_byte; 1457 chip->read_byte = ns_nand_read_byte;
1519 chip->dev_ready = ns_device_ready; 1458 chip->dev_ready = ns_device_ready;
1520 chip->write_byte = ns_nand_write_byte;
1521 chip->write_buf = ns_nand_write_buf; 1459 chip->write_buf = ns_nand_write_buf;
1522 chip->read_buf = ns_nand_read_buf; 1460 chip->read_buf = ns_nand_read_buf;
1523 chip->verify_buf = ns_nand_verify_buf; 1461 chip->verify_buf = ns_nand_verify_buf;
1524 chip->write_word = ns_nand_write_word;
1525 chip->read_word = ns_nand_read_word; 1462 chip->read_word = ns_nand_read_word;
1526 chip->ecc.mode = NAND_ECC_SOFT; 1463 chip->ecc.mode = NAND_ECC_SOFT;
1527 chip->options |= NAND_SKIP_BBTSCAN; 1464 chip->options |= NAND_SKIP_BBTSCAN;
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index e2dc81de106a..481541a683ca 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -60,22 +60,17 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip)
60 writel(ccr, ndfc->ndfcbase + NDFC_CCR); 60 writel(ccr, ndfc->ndfcbase + NDFC_CCR);
61} 61}
62 62
63static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd) 63static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
64{ 64{
65 struct ndfc_controller *ndfc = &ndfc_ctrl;
66 struct nand_chip *chip = mtd->priv; 65 struct nand_chip *chip = mtd->priv;
67 66
68 switch (cmd) { 67 if (cmd == NAND_CMD_NONE)
69 case NAND_CTL_SETCLE: 68 return;
70 chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_CMD; 69
71 break; 70 if (ctrl & NAND_CLE)
72 case NAND_CTL_SETALE: 71 writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_CMD);
73 chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_ALE; 72 else
74 break; 73 writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_ALE);
75 default:
76 chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA;
77 break;
78 }
79} 74}
80 75
81static int ndfc_ready(struct mtd_info *mtd) 76static int ndfc_ready(struct mtd_info *mtd)
@@ -158,7 +153,7 @@ static void ndfc_chip_init(struct ndfc_nand_mtd *mtd)
158 153
159 chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; 154 chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA;
160 chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA; 155 chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA;
161 chip->hwcontrol = ndfc_hwcontrol; 156 chip->cmd_ctrl = ndfc_hwcontrol;
162 chip->dev_ready = ndfc_ready; 157 chip->dev_ready = ndfc_ready;
163 chip->select_chip = ndfc_select_chip; 158 chip->select_chip = ndfc_select_chip;
164 chip->chip_delay = 50; 159 chip->chip_delay = 50;
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c
index 9fab0998524d..22fa65c12ab9 100644
--- a/drivers/mtd/nand/ppchameleonevb.c
+++ b/drivers/mtd/nand/ppchameleonevb.c
@@ -108,54 +108,68 @@ extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio
108/* 108/*
109 * hardware specific access to control-lines 109 * hardware specific access to control-lines
110 */ 110 */
111static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd) 111static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd,
112 unsigned int ctrl)
112{ 113{
113 switch (cmd) { 114 struct nand_chip *chip = mtd->priv;
114 115
115 case NAND_CTL_SETCLE: 116 if (ctrl & NAND_CTRL_CHANGE) {
116 MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR); 117#error Missing headerfiles. No way to fix this. -tglx
117 break; 118 switch (cmd) {
118 case NAND_CTL_CLRCLE: 119 case NAND_CTL_SETCLE:
119 MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR); 120 MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR);
120 break; 121 break;
121 case NAND_CTL_SETALE: 122 case NAND_CTL_CLRCLE:
122 MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR); 123 MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR);
123 break; 124 break;
124 case NAND_CTL_CLRALE: 125 case NAND_CTL_SETALE:
125 MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR); 126 MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR);
126 break; 127 break;
127 case NAND_CTL_SETNCE: 128 case NAND_CTL_CLRALE:
128 MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR); 129 MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR);
129 break; 130 break;
130 case NAND_CTL_CLRNCE: 131 case NAND_CTL_SETNCE:
131 MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR); 132 MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR);
132 break; 133 break;
134 case NAND_CTL_CLRNCE:
135 MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR);
136 break;
137 }
133 } 138 }
139 if (cmd != NAND_CMD_NONE)
140 writeb(cmd, chip->IO_ADDR_W);
134} 141}
135 142
136static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd) 143static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd,
144 unsigned int ctrl)
137{ 145{
138 switch (cmd) { 146 struct nand_chip *chip = mtd->priv;
139 147
140 case NAND_CTL_SETCLE: 148 if (ctrl & NAND_CTRL_CHANGE) {
141 MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR); 149#error Missing headerfiles. No way to fix this. -tglx
142 break; 150 switch (cmd) {
143 case NAND_CTL_CLRCLE: 151 case NAND_CTL_SETCLE:
144 MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR); 152 MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR);
145 break; 153 break;
146 case NAND_CTL_SETALE: 154 case NAND_CTL_CLRCLE:
147 MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR); 155 MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR);
148 break; 156 break;
149 case NAND_CTL_CLRALE: 157 case NAND_CTL_SETALE:
150 MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR); 158 MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR);
151 break; 159 break;
152 case NAND_CTL_SETNCE: 160 case NAND_CTL_CLRALE:
153 MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR); 161 MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR);
154 break; 162 break;
155 case NAND_CTL_CLRNCE: 163 case NAND_CTL_SETNCE:
156 MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR); 164 MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR);
157 break; 165 break;
166 case NAND_CTL_CLRNCE:
167 MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR);
168 break;
169 }
158 } 170 }
171 if (cmd != NAND_CMD_NONE)
172 writeb(cmd, chip->IO_ADDR_W);
159} 173}
160 174
161#ifdef USE_READY_BUSY_PIN 175#ifdef USE_READY_BUSY_PIN
@@ -251,7 +265,7 @@ static int __init ppchameleonevb_init(void)
251 /* insert callbacks */ 265 /* insert callbacks */
252 this->IO_ADDR_R = ppchameleon_fio_base; 266 this->IO_ADDR_R = ppchameleon_fio_base;
253 this->IO_ADDR_W = ppchameleon_fio_base; 267 this->IO_ADDR_W = ppchameleon_fio_base;
254 this->hwcontrol = ppchameleon_hwcontrol; 268 this->cmd_ctrl = ppchameleon_hwcontrol;
255#ifdef USE_READY_BUSY_PIN 269#ifdef USE_READY_BUSY_PIN
256 this->dev_ready = ppchameleon_device_ready; 270 this->dev_ready = ppchameleon_device_ready;
257#endif 271#endif
@@ -351,7 +365,7 @@ static int __init ppchameleonevb_init(void)
351 /* insert callbacks */ 365 /* insert callbacks */
352 this->IO_ADDR_R = ppchameleonevb_fio_base; 366 this->IO_ADDR_R = ppchameleonevb_fio_base;
353 this->IO_ADDR_W = ppchameleonevb_fio_base; 367 this->IO_ADDR_W = ppchameleonevb_fio_base;
354 this->hwcontrol = ppchameleonevb_hwcontrol; 368 this->cmd_ctrl = ppchameleonevb_hwcontrol;
355#ifdef USE_READY_BUSY_PIN 369#ifdef USE_READY_BUSY_PIN
356 this->dev_ready = ppchameleonevb_device_ready; 370 this->dev_ready = ppchameleonevb_device_ready;
357#endif 371#endif
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index f8e631c89a60..6c97bfaea19a 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -208,32 +208,18 @@ static uint8_t revbits[256] = {
208 * Address lines (A24-A22), so no action is required here. 208 * Address lines (A24-A22), so no action is required here.
209 * 209 *
210 */ 210 */
211static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) 211static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd,
212 unsigned int ctrl)
212{ 213{
213 struct nand_chip *this = (struct nand_chip *)(mtd->priv); 214 struct nand_chip *chip = (mtd->priv);
214 215
215 switch (cmd) { 216 if (cmd == NAND_CMD_NONE)
217 return;
216 218
217 case NAND_CTL_SETCLE: 219 if (ctrl & NAND_CLE)
218 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); 220 writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_CLE);
219 break; 221 else
220 case NAND_CTL_CLRCLE: 222 writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_ALE);
221 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE);
222 break;
223
224 case NAND_CTL_SETALE:
225 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE);
226 break;
227 case NAND_CTL_CLRALE:
228 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE);
229 break;
230
231 case NAND_CTL_SETNCE:
232 break;
233 case NAND_CTL_CLRNCE:
234 break;
235
236 }
237} 223}
238 224
239/* 225/*
@@ -559,7 +545,7 @@ static int __init rtc_from4_init(void)
559 this->IO_ADDR_R = rtc_from4_fio_base; 545 this->IO_ADDR_R = rtc_from4_fio_base;
560 this->IO_ADDR_W = rtc_from4_fio_base; 546 this->IO_ADDR_W = rtc_from4_fio_base;
561 /* Set address of hardware control function */ 547 /* Set address of hardware control function */
562 this->hwcontrol = rtc_from4_hwcontrol; 548 this->cmd_ctrl = rtc_from4_hwcontrol;
563 /* Set address of chip select function */ 549 /* Set address of chip select function */
564 this->select_chip = rtc_from4_nand_select_chip; 550 this->select_chip = rtc_from4_nand_select_chip;
565 /* command delay time (in us) */ 551 /* command delay time (in us) */
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 608340a25278..215227d1a65c 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -256,60 +256,36 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
256 * 256 *
257*/ 257*/
258 258
259static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd) 259static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd,
260 unsigend int ctrl)
260{ 261{
261 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 262 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
262 struct nand_chip *chip = mtd->priv; 263 struct nand_chip *chip = mtd->priv;
263 264
264 switch (cmd) { 265 if (cmd == NAND_CMD_NONE)
265 case NAND_CTL_SETNCE: 266 return;
266 case NAND_CTL_CLRNCE: 267
267 printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__); 268 if (cmd & NAND_CLE)
268 break; 269 writeb(cmd, info->regs + S3C2410_NFCMD);
269 270 else
270 case NAND_CTL_SETCLE: 271 writeb(cmd, info->regs + S3C2410_NFADDR);
271 chip->IO_ADDR_W = info->regs + S3C2410_NFCMD;
272 break;
273
274 case NAND_CTL_SETALE:
275 chip->IO_ADDR_W = info->regs + S3C2410_NFADDR;
276 break;
277
278 /* NAND_CTL_CLRCLE: */
279 /* NAND_CTL_CLRALE: */
280 default:
281 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
282 break;
283 }
284} 272}
285 273
286/* command and control functions */ 274/* command and control functions */
287 275
288static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd) 276static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd,
277 unsigend int ctrl)
289{ 278{
290 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 279 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
291 struct nand_chip *chip = mtd->priv; 280 struct nand_chip *chip = mtd->priv;
292 281
293 switch (cmd) { 282 if (cmd == NAND_CMD_NONE)
294 case NAND_CTL_SETNCE: 283 return;
295 case NAND_CTL_CLRNCE: 284
296 printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__); 285 if (cmd & NAND_CLE)
297 break; 286 writeb(cmd, info->regs + S3C2440_NFCMD);
298 287 else
299 case NAND_CTL_SETCLE: 288 writeb(cmd, info->regs + S3C2440_NFADDR);
300 chip->IO_ADDR_W = info->regs + S3C2440_NFCMD;
301 break;
302
303 case NAND_CTL_SETALE:
304 chip->IO_ADDR_W = info->regs + S3C2440_NFADDR;
305 break;
306
307 /* NAND_CTL_CLRCLE: */
308 /* NAND_CTL_CLRALE: */
309 default:
310 chip->IO_ADDR_W = info->regs + S3C2440_NFDATA;
311 break;
312 }
313} 289}
314 290
315/* s3c2410_nand_devready() 291/* s3c2410_nand_devready()
@@ -498,7 +474,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
498 474
499 chip->IO_ADDR_R = info->regs + S3C2410_NFDATA; 475 chip->IO_ADDR_R = info->regs + S3C2410_NFDATA;
500 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; 476 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
501 chip->hwcontrol = s3c2410_nand_hwcontrol; 477 chip->cmd_ctrl = s3c2410_nand_hwcontrol;
502 chip->dev_ready = s3c2410_nand_devready; 478 chip->dev_ready = s3c2410_nand_devready;
503 chip->write_buf = s3c2410_nand_write_buf; 479 chip->write_buf = s3c2410_nand_write_buf;
504 chip->read_buf = s3c2410_nand_read_buf; 480 chip->read_buf = s3c2410_nand_read_buf;
@@ -511,7 +487,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
511 if (info->is_s3c2440) { 487 if (info->is_s3c2440) {
512 chip->IO_ADDR_R = info->regs + S3C2440_NFDATA; 488 chip->IO_ADDR_R = info->regs + S3C2440_NFDATA;
513 chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; 489 chip->IO_ADDR_W = info->regs + S3C2440_NFDATA;
514 chip->hwcontrol = s3c2440_nand_hwcontrol; 490 chip->cmd_ctrl = s3c2440_nand_hwcontrol;
515 } 491 }
516 492
517 nmtd->info = info; 493 nmtd->info = info;
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 5554d0b97c8c..45a1da724bff 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -77,31 +77,26 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = {
77 77
78/* 78/*
79 * hardware specific access to control-lines 79 * hardware specific access to control-lines
80 * ctrl:
81 * NAND_CNE: bit 0 -> bit 0 & 4
82 * NAND_CLE: bit 1 -> bit 1
83 * NAND_ALE: bit 2 -> bit 2
84 *
80 */ 85 */
81static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd) 86static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd,
87 unsigned int ctrl)
82{ 88{
83 switch (cmd) { 89 struct nand_chip *chip = mtd->priv;
84 case NAND_CTL_SETCLE: 90
85 writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); 91 if (ctrl & NAND_CTRL_CHANGE) {
86 break; 92 unsigned char bits = ctrl & 0x07;
87 case NAND_CTL_CLRCLE: 93
88 writeb(readb(FLASHCTL) & ~FLCLE, FLASHCTL); 94 bits |= (ctrl & 0x01) << 4;
89 break; 95 writeb((readb(FLASHCTL) & 0x17) | bits, FLASHCTL);
90
91 case NAND_CTL_SETALE:
92 writeb(readb(FLASHCTL) | FLALE, FLASHCTL);
93 break;
94 case NAND_CTL_CLRALE:
95 writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
96 break;
97
98 case NAND_CTL_SETNCE:
99 writeb(readb(FLASHCTL) & ~(FLCE0 | FLCE1), FLASHCTL);
100 break;
101 case NAND_CTL_CLRNCE:
102 writeb(readb(FLASHCTL) | (FLCE0 | FLCE1), FLASHCTL);
103 break;
104 } 96 }
97
98 if (cmd != NAND_CMD_NONE)
99 writeb(cmd, chip->IO_ADDR_W);
105} 100}
106 101
107static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 102static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -196,7 +191,7 @@ static int __init sharpsl_nand_init(void)
196 this->IO_ADDR_R = FLASHIO; 191 this->IO_ADDR_R = FLASHIO;
197 this->IO_ADDR_W = FLASHIO; 192 this->IO_ADDR_W = FLASHIO;
198 /* Set address of hardware control function */ 193 /* Set address of hardware control function */
199 this->hwcontrol = sharpsl_nand_hwcontrol; 194 this->cmd_ctrl = sharpsl_nand_hwcontrol;
200 this->dev_ready = sharpsl_nand_dev_ready; 195 this->dev_ready = sharpsl_nand_dev_ready;
201 /* 15 us command delay time */ 196 /* 15 us command delay time */
202 this->chip_delay = 15; 197 this->chip_delay = 15;
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c
index 9737f1d67c3c..1f6d429b1583 100644
--- a/drivers/mtd/nand/spia.c
+++ b/drivers/mtd/nand/spia.c
@@ -82,20 +82,27 @@ static const struct mtd_partition partition_info[] = {
82 82
83/* 83/*
84 * hardware specific access to control-lines 84 * hardware specific access to control-lines
85*/ 85 *
86 * ctrl:
87 * NAND_CNE: bit 0 -> bit 2
88 * NAND_CLE: bit 1 -> bit 0
89 * NAND_ALE: bit 2 -> bit 1
90 */
86static void spia_hwcontrol(struct mtd_info *mtd, int cmd) 91static void spia_hwcontrol(struct mtd_info *mtd, int cmd)
87{ 92{
88 switch (cmd) { 93 struct nand_chip *chip = mtd->priv;
89 94
90 case NAND_CTL_SETCLE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |= 0x01; break; 95 if (ctrl & NAND_CTRL_CHANGE) {
91 case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x01; break; 96 void __iomem *addr = spia_io_base + spia_pedr;
97 unsigned char bits;
92 98
93 case NAND_CTL_SETALE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |= 0x02; break; 99 bits = (ctrl & NAND_CNE) << 2;
94 case NAND_CTL_CLRALE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x02; break; 100 bits |= (ctrl & NAND_CLE | NAND_ALE) >> 1;
95 101 writeb((readb(addr) & ~0x7) | bits, addr);
96 case NAND_CTL_SETNCE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x04; break;
97 case NAND_CTL_CLRNCE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |= 0x04; break;
98 } 102 }
103
104 if (cmd != NAND_CMD_NONE)
105 writeb(cmd, chip->IO_ADDR_W);
99} 106}
100 107
101/* 108/*
@@ -133,7 +140,7 @@ static int __init spia_init(void)
133 this->IO_ADDR_R = (void __iomem *)spia_fio_base; 140 this->IO_ADDR_R = (void __iomem *)spia_fio_base;
134 this->IO_ADDR_W = (void __iomem *)spia_fio_base; 141 this->IO_ADDR_W = (void __iomem *)spia_fio_base;
135 /* Set address of hardware control function */ 142 /* Set address of hardware control function */
136 this->hwcontrol = spia_hwcontrol; 143 this->cmd_ctrl = spia_hwcontrol;
137 /* 15 us command delay time */ 144 /* 15 us command delay time */
138 this->chip_delay = 15; 145 this->chip_delay = 15;
139 146
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c
index 50aa6a46911f..a9cf0190c27a 100644
--- a/drivers/mtd/nand/toto.c
+++ b/drivers/mtd/nand/toto.c
@@ -32,6 +32,8 @@
32#include <asm/arch-omap1510/hardware.h> 32#include <asm/arch-omap1510/hardware.h>
33#include <asm/arch/gpio.h> 33#include <asm/arch/gpio.h>
34 34
35#define CONFIG_NAND_WORKAROUND 1
36
35/* 37/*
36 * MTD structure for TOTO board 38 * MTD structure for TOTO board
37 */ 39 */
@@ -39,25 +41,6 @@ static struct mtd_info *toto_mtd = NULL;
39 41
40static unsigned long toto_io_base = OMAP_FLASH_1_BASE; 42static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
41 43
42#define CONFIG_NAND_WORKAROUND 1
43
44#define NAND_NCE 0x4000
45#define NAND_CLE 0x1000
46#define NAND_ALE 0x0002
47#define NAND_MASK (NAND_CLE | NAND_ALE | NAND_NCE)
48
49#define T_NAND_CTL_CLRALE(iob) gpiosetout(NAND_ALE, 0)
50#define T_NAND_CTL_SETALE(iob) gpiosetout(NAND_ALE, NAND_ALE)
51#ifdef CONFIG_NAND_WORKAROUND /* "some" dev boards busted, blue wired to rts2 :( */
52#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0); rts2setout(2, 2)
53#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE); rts2setout(2, 0)
54#else
55#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0)
56#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE)
57#endif
58#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
59#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
60
61/* 44/*
62 * Define partitions for flash devices 45 * Define partitions for flash devices
63 */ 46 */
@@ -91,25 +74,43 @@ static struct mtd_partition partition_info32M[] = {
91 74
92#define NUM_PARTITIONS32M 3 75#define NUM_PARTITIONS32M 3
93#define NUM_PARTITIONS64M 4 76#define NUM_PARTITIONS64M 4
77
94/* 78/*
95 * hardware specific access to control-lines 79 * hardware specific access to control-lines
96*/ 80 *
97 81 * ctrl:
98static void toto_hwcontrol(struct mtd_info *mtd, int cmd) 82 * NAND_NCE: bit 0 -> bit 14 (0x4000)
83 * NAND_CLE: bit 1 -> bit 12 (0x1000)
84 * NAND_ALE: bit 2 -> bit 1 (0x0002)
85 */
86static void toto_hwcontrol(struct mtd_info *mtd, int cmd,
87 unsigned int ctrl)
99{ 88{
89 struct nand_chip *chip = mtd->priv;
90
91 if (ctrl & NAND_CTRL_CHANGE) {
92 unsigned long bits;
100 93
101 udelay(1); /* hopefully enough time for tc make proceding write to clear */ 94 /* hopefully enough time for tc make proceding write to clear */
102 switch (cmd) { 95 udelay(1);
103 case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break;
104 case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break;
105 96
106 case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break; 97 bits = (~ctrl & NAND_NCE) << 14;
107 case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break; 98 bits |= (ctrl & NAND_CLE) << 12;
99 bits |= (ctrl & NAND_ALE) >> 1;
108 100
109 case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break; 101#warning Wild guess as gpiosetout() is nowhere defined in the kernel source - tglx
110 case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break; 102 gpiosetout(0x5002, bits);
103
104#ifdef CONFIG_NAND_WORKAROUND
105 /* "some" dev boards busted, blue wired to rts2 :( */
106 rts2setout(2, (ctrl & NAND_CLE) << 1);
107#endif
108 /* allow time to ensure gpio state to over take memory write */
109 udelay(1);
111 } 110 }
112 udelay(1); /* allow time to ensure gpio state to over take memory write */ 111
112 if (cmd != NAND_CMD_NONE)
113 writeb(cmd, chip->IO_ADDR_W);
113} 114}
114 115
115/* 116/*
@@ -142,7 +143,7 @@ static int __init toto_init(void)
142 /* Set address of NAND IO lines */ 143 /* Set address of NAND IO lines */
143 this->IO_ADDR_R = toto_io_base; 144 this->IO_ADDR_R = toto_io_base;
144 this->IO_ADDR_W = toto_io_base; 145 this->IO_ADDR_W = toto_io_base;
145 this->hwcontrol = toto_hwcontrol; 146 this->cmd_ctrl = toto_hwcontrol;
146 this->dev_ready = NULL; 147 this->dev_ready = NULL;
147 /* 25 us command delay time */ 148 /* 25 us command delay time */
148 this->chip_delay = 30; 149 this->chip_delay = 30;
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c
index 70bce1b0326c..a0b4b1edcb0d 100644
--- a/drivers/mtd/nand/ts7250.c
+++ b/drivers/mtd/nand/ts7250.c
@@ -83,31 +83,29 @@ static struct mtd_partition partition_info128[] = {
83 83
84/* 84/*
85 * hardware specific access to control-lines 85 * hardware specific access to control-lines
86 *
87 * ctrl:
88 * NAND_NCE: bit 0 -> bit 2
89 * NAND_CLE: bit 1 -> bit 1
90 * NAND_ALE: bit 2 -> bit 0
86 */ 91 */
87static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd) 92static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
88{ 93{
89 unsigned long ctrl = TS72XX_NAND_CONTROL_VIRT_BASE; 94 struct nand_chip *chip = mtd->priv;
90 95
91 switch (cmd) { 96 if (ctrl & NAND_CTRL_CHANGE) {
92 case NAND_CTL_SETCLE: 97 unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE;
93 __raw_writeb(__raw_readb(ctrl) | 0x2, ctrl); 98 unsigned char bits;
94 break; 99
95 case NAND_CTL_CLRCLE: 100 bits = (ctrl & NAND_CNE) << 2;
96 __raw_writeb(__raw_readb(ctrl) & ~0x2, ctrl); 101 bits |= ctrl & NAND_CLE;
97 break; 102 bits |= (ctrl & NAND_ALE) >> 2;
98 case NAND_CTL_SETALE: 103
99 __raw_writeb(__raw_readb(ctrl) | 0x1, ctrl); 104 __raw_writeb((__raw_readb(addr) & ~0x7) | bits, addr);
100 break;
101 case NAND_CTL_CLRALE:
102 __raw_writeb(__raw_readb(ctrl) & ~0x1, ctrl);
103 break;
104 case NAND_CTL_SETNCE:
105 __raw_writeb(__raw_readb(ctrl) | 0x4, ctrl);
106 break;
107 case NAND_CTL_CLRNCE:
108 __raw_writeb(__raw_readb(ctrl) & ~0x4, ctrl);
109 break;
110 } 105 }
106
107 if (cmd != NAND_CMD_NONE)
108 writeb(cmd, chip->IO_ADDR_W);
111} 109}
112 110
113/* 111/*
@@ -152,7 +150,7 @@ static int __init ts7250_init(void)
152 /* insert callbacks */ 150 /* insert callbacks */
153 this->IO_ADDR_R = (void *)TS72XX_NAND_DATA_VIRT_BASE; 151 this->IO_ADDR_R = (void *)TS72XX_NAND_DATA_VIRT_BASE;
154 this->IO_ADDR_W = (void *)TS72XX_NAND_DATA_VIRT_BASE; 152 this->IO_ADDR_W = (void *)TS72XX_NAND_DATA_VIRT_BASE;
155 this->hwcontrol = ts7250_hwcontrol; 153 this->cmd_ctrl = ts7250_hwcontrol;
156 this->dev_ready = ts7250_device_ready; 154 this->dev_ready = ts7250_device_ready;
157 this->chip_delay = 15; 155 this->chip_delay = 15;
158 this->ecc.mode = NAND_ECC_SOFT; 156 this->ecc.mode = NAND_ECC_SOFT;
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index d7cd5fa16ba4..dd03349946c2 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -70,8 +70,6 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
70 nftl->mbd.devnum = -1; 70 nftl->mbd.devnum = -1;
71 nftl->mbd.blksize = 512; 71 nftl->mbd.blksize = 512;
72 nftl->mbd.tr = tr; 72 nftl->mbd.tr = tr;
73 memcpy(&nftl->oobinfo, &mtd->oobinfo, sizeof(struct nand_oobinfo));
74 nftl->oobinfo.useecc = MTD_NANDECC_PLACEONLY;
75 73
76 if (NFTL_mount(nftl) < 0) { 74 if (NFTL_mount(nftl) < 0) {
77 printk(KERN_WARNING "NFTL: could not mount device\n"); 75 printk(KERN_WARNING "NFTL: could not mount device\n");
@@ -369,8 +367,11 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
369 } 367 }
370 memset(&oob, 0xff, sizeof(struct nftl_oob)); 368 memset(&oob, 0xff, sizeof(struct nftl_oob));
371 oob.b.Status = oob.b.Status1 = SECTOR_USED; 369 oob.b.Status = oob.b.Status1 = SECTOR_USED;
372 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512), 370
373 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo); 371 nand_write_raw(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) +
372 (block * 512), 512, &retlen, movebuf,
373 (char *)&oob);
374
374 } 375 }
375 376
376 /* add the header so that it is now a valid chain */ 377 /* add the header so that it is now a valid chain */
@@ -639,10 +640,10 @@ static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
639 640
640 memset(&oob, 0xff, sizeof(struct nftl_oob)); 641 memset(&oob, 0xff, sizeof(struct nftl_oob));
641 oob.b.Status = oob.b.Status1 = SECTOR_USED; 642 oob.b.Status = oob.b.Status1 = SECTOR_USED;
642 MTD_WRITEECC(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
643 512, &retlen, (char *)buffer, (char *)&oob, &nftl->oobinfo);
644 /* need to write SECTOR_USED flags since they are not written in mtd_writeecc */
645 643
644 nand_write_raw(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) +
645 blockofs, 512, &retlen, (char *)buffer,
646 (char *)&oob);
646 return 0; 647 return 0;
647} 648}
648#endif /* CONFIG_NFTL_RW */ 649#endif /* CONFIG_NFTL_RW */
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 3b104ebb219a..90e5e7e97fdc 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -268,18 +268,22 @@ static int memcmpb(void *a, int c, int n)
268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, 268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
269 int check_oob) 269 int check_oob)
270{ 270{
271 int i;
272 size_t retlen;
273 u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize]; 271 u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize];
272 struct mtd_info *mtd = nftl->mbd.mtd;
273 size_t retlen;
274 int i;
274 275
275 for (i = 0; i < len; i += SECTORSIZE) { 276 for (i = 0; i < len; i += SECTORSIZE) {
276 if (MTD_READECC(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf, &buf[SECTORSIZE], &nftl->oobinfo) < 0) 277 if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
277 return -1; 278 return -1;
278 if (memcmpb(buf, 0xff, SECTORSIZE) != 0) 279 if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
279 return -1; 280 return -1;
280 281
281 if (check_oob) { 282 if (check_oob) {
282 if (memcmpb(buf + SECTORSIZE, 0xff, nftl->mbd.mtd->oobsize) != 0) 283 if(mtd->read_oob(mtd, address, mtd->oobsize,
284 &retlen, &buf[SECTORSIZE]) < 0)
285 return -1;
286 if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0)
283 return -1; 287 return -1;
284 } 288 }
285 address += SECTORSIZE; 289 address += SECTORSIZE;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 4c2c61d54b3a..7a2419186ff4 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -597,31 +597,28 @@ static void onenand_release_device(struct mtd_info *mtd)
597} 597}
598 598
599/** 599/**
600 * onenand_read_ecc - [MTD Interface] Read data with ECC 600 * onenand_read - [MTD Interface] Read data from flash
601 * @param mtd MTD device structure 601 * @param mtd MTD device structure
602 * @param from offset to read from 602 * @param from offset to read from
603 * @param len number of bytes to read 603 * @param len number of bytes to read
604 * @param retlen pointer to variable to store the number of read bytes 604 * @param retlen pointer to variable to store the number of read bytes
605 * @param buf the databuffer to put data 605 * @param buf the databuffer to put data
606 * @param oob_buf filesystem supplied oob data buffer
607 * @param oobsel oob selection structure
608 * 606 *
609 * OneNAND read with ECC 607 * Read with ecc
610 */ 608*/
611static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, 609static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
612 size_t *retlen, u_char *buf, 610 size_t *retlen, u_char *buf)
613 u_char *oob_buf, struct nand_oobinfo *oobsel)
614{ 611{
615 struct onenand_chip *this = mtd->priv; 612 struct onenand_chip *this = mtd->priv;
616 int read = 0, column; 613 int read = 0, column;
617 int thislen; 614 int thislen;
618 int ret = 0; 615 int ret = 0;
619 616
620 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 617 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
621 618
622 /* Do not allow reads past end of device */ 619 /* Do not allow reads past end of device */
623 if ((from + len) > mtd->size) { 620 if ((from + len) > mtd->size) {
624 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: Attempt read beyond end of device\n"); 621 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: Attempt read beyond end of device\n");
625 *retlen = 0; 622 *retlen = 0;
626 return -EINVAL; 623 return -EINVAL;
627 } 624 }
@@ -654,7 +651,7 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
654 break; 651 break;
655 652
656 if (ret) { 653 if (ret) {
657 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: read failed = %d\n", ret); 654 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret);
658 goto out; 655 goto out;
659 } 656 }
660 657
@@ -676,22 +673,6 @@ out:
676} 673}
677 674
678/** 675/**
679 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
680 * @param mtd MTD device structure
681 * @param from offset to read from
682 * @param len number of bytes to read
683 * @param retlen pointer to variable to store the number of read bytes
684 * @param buf the databuffer to put data
685 *
686 * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
687*/
688static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
689 size_t *retlen, u_char *buf)
690{
691 return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
692}
693
694/**
695 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band 676 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
696 * @param mtd MTD device structure 677 * @param mtd MTD device structure
697 * @param from offset to read from 678 * @param from offset to read from
@@ -834,39 +815,36 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
834#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0) 815#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0)
835 816
836/** 817/**
837 * onenand_write_ecc - [MTD Interface] OneNAND write with ECC 818 * onenand_write - [MTD Interface] write buffer to FLASH
838 * @param mtd MTD device structure 819 * @param mtd MTD device structure
839 * @param to offset to write to 820 * @param to offset to write to
840 * @param len number of bytes to write 821 * @param len number of bytes to write
841 * @param retlen pointer to variable to store the number of written bytes 822 * @param retlen pointer to variable to store the number of written bytes
842 * @param buf the data to write 823 * @param buf the data to write
843 * @param eccbuf filesystem supplied oob data buffer
844 * @param oobsel oob selection structure
845 * 824 *
846 * OneNAND write with ECC 825 * Write with ECC
847 */ 826 */
848static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 827static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
849 size_t *retlen, const u_char *buf, 828 size_t *retlen, const u_char *buf)
850 u_char *eccbuf, struct nand_oobinfo *oobsel)
851{ 829{
852 struct onenand_chip *this = mtd->priv; 830 struct onenand_chip *this = mtd->priv;
853 int written = 0; 831 int written = 0;
854 int ret = 0; 832 int ret = 0;
855 833
856 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 834 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
857 835
858 /* Initialize retlen, in case of early exit */ 836 /* Initialize retlen, in case of early exit */
859 *retlen = 0; 837 *retlen = 0;
860 838
861 /* Do not allow writes past end of device */ 839 /* Do not allow writes past end of device */
862 if (unlikely((to + len) > mtd->size)) { 840 if (unlikely((to + len) > mtd->size)) {
863 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt write to past end of device\n"); 841 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt write to past end of device\n");
864 return -EINVAL; 842 return -EINVAL;
865 } 843 }
866 844
867 /* Reject writes, which are not page aligned */ 845 /* Reject writes, which are not page aligned */
868 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) { 846 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
869 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt to write not page aligned data\n"); 847 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt to write not page aligned data\n");
870 return -EINVAL; 848 return -EINVAL;
871 } 849 }
872 850
@@ -888,7 +866,7 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
888 866
889 ret = this->wait(mtd, FL_WRITING); 867 ret = this->wait(mtd, FL_WRITING);
890 if (ret) { 868 if (ret) {
891 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: write filaed %d\n", ret); 869 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);
892 goto out; 870 goto out;
893 } 871 }
894 872
@@ -897,7 +875,7 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
897 /* Only check verify write turn on */ 875 /* Only check verify write turn on */
898 ret = onenand_verify_page(mtd, (u_char *) buf, to); 876 ret = onenand_verify_page(mtd, (u_char *) buf, to);
899 if (ret) { 877 if (ret) {
900 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret); 878 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);
901 goto out; 879 goto out;
902 } 880 }
903 881
@@ -918,23 +896,6 @@ out:
918} 896}
919 897
920/** 898/**
921 * onenand_write - [MTD Interface] compability function for onenand_write_ecc
922 * @param mtd MTD device structure
923 * @param to offset to write to
924 * @param len number of bytes to write
925 * @param retlen pointer to variable to store the number of written bytes
926 * @param buf the data to write
927 *
928 * This function simply calls onenand_write_ecc
929 * with oob buffer and oobsel = NULL
930 */
931static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
932 size_t *retlen, const u_char *buf)
933{
934 return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
935}
936
937/**
938 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band 899 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
939 * @param mtd MTD device structure 900 * @param mtd MTD device structure
940 * @param to offset to write to 901 * @param to offset to write to
@@ -1014,144 +975,6 @@ out:
1014} 975}
1015 976
1016/** 977/**
1017 * onenand_writev_ecc - [MTD Interface] write with iovec with ecc
1018 * @param mtd MTD device structure
1019 * @param vecs the iovectors to write
1020 * @param count number of vectors
1021 * @param to offset to write to
1022 * @param retlen pointer to variable to store the number of written bytes
1023 * @param eccbuf filesystem supplied oob data buffer
1024 * @param oobsel oob selection structure
1025 *
1026 * OneNAND write with iovec with ecc
1027 */
1028static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
1029 unsigned long count, loff_t to, size_t *retlen,
1030 u_char *eccbuf, struct nand_oobinfo *oobsel)
1031{
1032 struct onenand_chip *this = mtd->priv;
1033 unsigned char *pbuf;
1034 size_t total_len, len;
1035 int i, written = 0;
1036 int ret = 0;
1037
1038 /* Preset written len for early exit */
1039 *retlen = 0;
1040
1041 /* Calculate total length of data */
1042 total_len = 0;
1043 for (i = 0; i < count; i++)
1044 total_len += vecs[i].iov_len;
1045
1046 DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
1047
1048 /* Do not allow write past end of the device */
1049 if (unlikely((to + total_len) > mtd->size)) {
1050 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
1051 return -EINVAL;
1052 }
1053
1054 /* Reject writes, which are not page aligned */
1055 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
1056 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
1057 return -EINVAL;
1058 }
1059
1060 /* Grab the lock and see if the device is available */
1061 onenand_get_device(mtd, FL_WRITING);
1062
1063 /* TODO handling oob */
1064
1065 /* Loop until all keve's data has been written */
1066 len = 0;
1067 while (count) {
1068 pbuf = this->page_buf;
1069 /*
1070 * If the given tuple is >= pagesize then
1071 * write it out from the iov
1072 */
1073 if ((vecs->iov_len - len) >= mtd->writesize) {
1074 pbuf = vecs->iov_base + len;
1075
1076 len += mtd->writesize;
1077
1078 /* Check, if we have to switch to the next tuple */
1079 if (len >= (int) vecs->iov_len) {
1080 vecs++;
1081 len = 0;
1082 count--;
1083 }
1084 } else {
1085 int cnt = 0, thislen;
1086 while (cnt < mtd->writesize) {
1087 thislen = min_t(int, mtd->writesize - cnt, vecs->iov_len - len);
1088 memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
1089 cnt += thislen;
1090 len += thislen;
1091
1092 /* Check, if we have to switch to the next tuple */
1093 if (len >= (int) vecs->iov_len) {
1094 vecs++;
1095 len = 0;
1096 count--;
1097 }
1098 }
1099 }
1100
1101 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);
1102
1103 this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->writesize);
1104 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1105
1106 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1107
1108 onenand_update_bufferram(mtd, to, 1);
1109
1110 ret = this->wait(mtd, FL_WRITING);
1111 if (ret) {
1112 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
1113 goto out;
1114 }
1115
1116
1117 /* Only check verify write turn on */
1118 ret = onenand_verify_page(mtd, (u_char *) pbuf, to);
1119 if (ret) {
1120 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
1121 goto out;
1122 }
1123
1124 written += mtd->writesize;
1125
1126 to += mtd->writesize;
1127 }
1128
1129out:
1130 /* Deselect and wakt up anyone waiting on the device */
1131 onenand_release_device(mtd);
1132
1133 *retlen = written;
1134
1135 return 0;
1136}
1137
1138/**
1139 * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
1140 * @param mtd MTD device structure
1141 * @param vecs the iovectors to write
1142 * @param count number of vectors
1143 * @param to offset to write to
1144 * @param retlen pointer to variable to store the number of written bytes
1145 *
1146 * OneNAND write with kvec. This just calls the ecc function
1147 */
1148static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
1149 unsigned long count, loff_t to, size_t *retlen)
1150{
1151 return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
1152}
1153
1154/**
1155 * onenand_block_checkbad - [GENERIC] Check if a block is marked bad 978 * onenand_block_checkbad - [GENERIC] Check if a block is marked bad
1156 * @param mtd MTD device structure 979 * @param mtd MTD device structure
1157 * @param ofs offset from device start 980 * @param ofs offset from device start
@@ -1950,8 +1773,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1950 mtd->unpoint = NULL; 1773 mtd->unpoint = NULL;
1951 mtd->read = onenand_read; 1774 mtd->read = onenand_read;
1952 mtd->write = onenand_write; 1775 mtd->write = onenand_write;
1953 mtd->read_ecc = onenand_read_ecc;
1954 mtd->write_ecc = onenand_write_ecc;
1955 mtd->read_oob = onenand_read_oob; 1776 mtd->read_oob = onenand_read_oob;
1956 mtd->write_oob = onenand_write_oob; 1777 mtd->write_oob = onenand_write_oob;
1957#ifdef CONFIG_MTD_ONENAND_OTP 1778#ifdef CONFIG_MTD_ONENAND_OTP
@@ -1962,10 +1783,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1962 mtd->write_user_prot_reg = onenand_write_user_prot_reg; 1783 mtd->write_user_prot_reg = onenand_write_user_prot_reg;
1963 mtd->lock_user_prot_reg = onenand_lock_user_prot_reg; 1784 mtd->lock_user_prot_reg = onenand_lock_user_prot_reg;
1964#endif 1785#endif
1965 mtd->readv = NULL;
1966 mtd->readv_ecc = NULL;
1967 mtd->writev = onenand_writev;
1968 mtd->writev_ecc = onenand_writev_ecc;
1969 mtd->sync = onenand_sync; 1786 mtd->sync = onenand_sync;
1970 mtd->lock = NULL; 1787 mtd->lock = NULL;
1971 mtd->unlock = onenand_unlock; 1788 mtd->unlock = onenand_unlock;
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 0d7abb260489..1871140e1e78 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -236,10 +236,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
236 } 236 }
237 237
238 /* Do the read... */ 238 /* Do the read... */
239 if (jffs2_cleanmarker_oob(c)) 239 ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
240 ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
241 else
242 ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
243 240
244 if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) { 241 if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) {
245 /* ECC recovered */ 242 /* ECC recovered */
@@ -293,16 +290,13 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
293 if (breakme++ == 20) { 290 if (breakme++ == 20) {
294 printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs); 291 printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs);
295 breakme = 0; 292 breakme = 0;
296 c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen, 293 c->mtd->write(c->mtd, ofs, towrite, &retlen,
297 brokenbuf, NULL, c->oobinfo); 294 brokenbuf);
298 ret = -EIO; 295 ret = -EIO;
299 } else 296 } else
300#endif 297#endif
301 if (jffs2_cleanmarker_oob(c)) 298 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen,
302 ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen, 299 rewrite_buf);
303 rewrite_buf, NULL, c->oobinfo);
304 else
305 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, rewrite_buf);
306 300
307 if (ret || retlen != towrite) { 301 if (ret || retlen != towrite) {
308 /* Argh. We tried. Really we did. */ 302 /* Argh. We tried. Really we did. */
@@ -455,15 +449,12 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
455 if (breakme++ == 20) { 449 if (breakme++ == 20) {
456 printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs); 450 printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs);
457 breakme = 0; 451 breakme = 0;
458 c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, 452 c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen,
459 &retlen, brokenbuf, NULL, c->oobinfo); 453 brokenbuf);
460 ret = -EIO; 454 ret = -EIO;
461 } else 455 } else
462#endif 456#endif
463 457
464 if (jffs2_cleanmarker_oob(c))
465 ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
466 else
467 ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf); 458 ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf);
468 459
469 if (ret || retlen != c->wbuf_pagesize) { 460 if (ret || retlen != c->wbuf_pagesize) {
@@ -792,10 +783,7 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
792 783
793 /* Read flash */ 784 /* Read flash */
794 down_read(&c->wbuf_sem); 785 down_read(&c->wbuf_sem);
795 if (jffs2_cleanmarker_oob(c)) 786 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
796 ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
797 else
798 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
799 787
800 if ( (ret == -EBADMSG) && (*retlen == len) ) { 788 if ( (ret == -EBADMSG) && (*retlen == len) ) {
801 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n", 789 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index d48c7492392b..b8ad634391db 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -115,9 +115,6 @@ struct mtd_info {
115 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 115 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
116 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 116 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
117 117
118 int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
119 int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
120
121 int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 118 int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
122 int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 119 int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
123 120
@@ -133,17 +130,11 @@ struct mtd_info {
133 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 130 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
134 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len); 131 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
135 132
136 /* kvec-based read/write methods. We need these especially for NAND flash, 133 /* kvec-based read/write methods.
137 with its limited number of write cycles per erase.
138 NB: The 'count' parameter is the number of _vectors_, each of 134 NB: The 'count' parameter is the number of _vectors_, each of
139 which contains an (ofs, len) tuple. 135 which contains an (ofs, len) tuple.
140 */ 136 */
141 int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen);
142 int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from,
143 size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
144 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); 137 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
145 int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to,
146 size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
147 138
148 /* Sync */ 139 /* Sync */
149 void (*sync) (struct mtd_info *mtd); 140 void (*sync) (struct mtd_info *mtd);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 460525841a27..2c0fb6380461 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -36,6 +36,9 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from,
36 size_t len, size_t ooblen); 36 size_t len, size_t ooblen);
37 37
38 38
39extern int nand_write_raw(struct mtd_info *mtd, loff_t to, size_t len,
40 size_t *retlen, uint8_t *buf, uint8_t *oob);
41
39/* The maximum number of NAND chips in an array */ 42/* The maximum number of NAND chips in an array */
40#define NAND_MAX_CHIPS 8 43#define NAND_MAX_CHIPS 8
41 44
@@ -47,23 +50,20 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from,
47 50
48/* 51/*
49 * Constants for hardware specific CLE/ALE/NCE function 52 * Constants for hardware specific CLE/ALE/NCE function
50*/ 53 *
54 * These are bits which can be or'ed to set/clear multiple
55 * bits in one go.
56 */
51/* Select the chip by setting nCE to low */ 57/* Select the chip by setting nCE to low */
52#define NAND_CTL_SETNCE 1 58#define NAND_NCE 0x01
53/* Deselect the chip by setting nCE to high */
54#define NAND_CTL_CLRNCE 2
55/* Select the command latch by setting CLE to high */ 59/* Select the command latch by setting CLE to high */
56#define NAND_CTL_SETCLE 3 60#define NAND_CLE 0x02
57/* Deselect the command latch by setting CLE to low */
58#define NAND_CTL_CLRCLE 4
59/* Select the address latch by setting ALE to high */ 61/* Select the address latch by setting ALE to high */
60#define NAND_CTL_SETALE 5 62#define NAND_ALE 0x04
61/* Deselect the address latch by setting ALE to low */ 63
62#define NAND_CTL_CLRALE 6 64#define NAND_CTRL_CLE (NAND_NCE | NAND_CLE)
63/* Set write protection by setting WP to high. Not used! */ 65#define NAND_CTRL_ALE (NAND_NCE | NAND_ALE)
64#define NAND_CTL_SETWP 7 66#define NAND_CTRL_CHANGE 0x80
65/* Clear write protection by setting WP to low. Not used! */
66#define NAND_CTL_CLRWP 8
67 67
68/* 68/*
69 * Standard NAND flash commands 69 * Standard NAND flash commands
@@ -103,6 +103,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from,
103#define NAND_CMD_STATUS_RESET 0x7f 103#define NAND_CMD_STATUS_RESET 0x7f
104#define NAND_CMD_STATUS_CLEAR 0xff 104#define NAND_CMD_STATUS_CLEAR 0xff
105 105
106#define NAND_CMD_NONE -1
107
106/* Status bits */ 108/* Status bits */
107#define NAND_STATUS_FAIL 0x01 109#define NAND_STATUS_FAIL 0x01
108#define NAND_STATUS_FAIL_N1 0x02 110#define NAND_STATUS_FAIL_N1 0x02
@@ -237,7 +239,7 @@ struct nand_ecc_ctrl {
237 int steps; 239 int steps;
238 int size; 240 int size;
239 int bytes; 241 int bytes;
240 int (*hwctl)(struct mtd_info *mtd, int mode); 242 void (*hwctl)(struct mtd_info *mtd, int mode);
241 int (*calculate)(struct mtd_info *mtd, 243 int (*calculate)(struct mtd_info *mtd,
242 const uint8_t *dat, 244 const uint8_t *dat,
243 uint8_t *ecc_code); 245 uint8_t *ecc_code);
@@ -251,16 +253,15 @@ struct nand_ecc_ctrl {
251 * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device 253 * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
252 * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device 254 * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
253 * @read_byte: [REPLACEABLE] read one byte from the chip 255 * @read_byte: [REPLACEABLE] read one byte from the chip
254 * @write_byte: [REPLACEABLE] write one byte to the chip
255 * @read_word: [REPLACEABLE] read one word from the chip 256 * @read_word: [REPLACEABLE] read one word from the chip
256 * @write_word: [REPLACEABLE] write one word to the chip
257 * @write_buf: [REPLACEABLE] write data from the buffer to the chip 257 * @write_buf: [REPLACEABLE] write data from the buffer to the chip
258 * @read_buf: [REPLACEABLE] read data from the chip into the buffer 258 * @read_buf: [REPLACEABLE] read data from the chip into the buffer
259 * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data 259 * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data
260 * @select_chip: [REPLACEABLE] select chip nr 260 * @select_chip: [REPLACEABLE] select chip nr
261 * @block_bad: [REPLACEABLE] check, if the block is bad 261 * @block_bad: [REPLACEABLE] check, if the block is bad
262 * @block_markbad: [REPLACEABLE] mark the block bad 262 * @block_markbad: [REPLACEABLE] mark the block bad
263 * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines 263 * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific funtion for controlling
264 * ALE/CLE/nCE. Also used to write command and address
264 * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line 265 * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line
265 * If set to NULL no access to ready/busy is available and the ready/busy information 266 * If set to NULL no access to ready/busy is available and the ready/busy information
266 * is read from the chip status register 267 * is read from the chip status register
@@ -304,17 +305,15 @@ struct nand_chip {
304 void __iomem *IO_ADDR_W; 305 void __iomem *IO_ADDR_W;
305 306
306 uint8_t (*read_byte)(struct mtd_info *mtd); 307 uint8_t (*read_byte)(struct mtd_info *mtd);
307 void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
308 u16 (*read_word)(struct mtd_info *mtd); 308 u16 (*read_word)(struct mtd_info *mtd);
309 void (*write_word)(struct mtd_info *mtd, u16 word);
310
311 void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); 309 void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
312 void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); 310 void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
313 int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); 311 int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
314 void (*select_chip)(struct mtd_info *mtd, int chip); 312 void (*select_chip)(struct mtd_info *mtd, int chip);
315 int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); 313 int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
316 int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); 314 int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
317 void (*hwcontrol)(struct mtd_info *mtd, int cmd); 315 void (*cmd_ctrl)(struct mtd_info *mtd, int dat,
316 unsigned int ctrl);
318 int (*dev_ready)(struct mtd_info *mtd); 317 int (*dev_ready)(struct mtd_info *mtd);
319 void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); 318 void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
320 int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); 319 int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);