Merge branch 'master' of git://git.denx.de/u-boot-nand-flash
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 8b1e01a..886212a 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -426,7 +426,7 @@
 }
 
 /* Adjust a chip/partition size down for bad blocks so we don't
- * read/write/erase past the end of a chip/partition by accident.
+ * read/write past the end of a chip/partition by accident.
  */
 static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev)
 {
@@ -546,7 +546,6 @@
 		int scrub = !strncmp(cmd, "scrub", 5);
 		int spread = 0;
 		int args = 2;
-		int adjust_size = 0;
 		const char *scrub_warn =
 			"Warning: "
 			"scrub option will erase all factory set bad blocks!\n"
@@ -563,10 +562,8 @@
 				spread = 1;
 			} else if (!strcmp(&cmd[5], ".part")) {
 				args = 1;
-				adjust_size = 1;
 			} else if (!strcmp(&cmd[5], ".chip")) {
 				args = 0;
-				adjust_size = 1;
 			} else {
 				goto usage;
 			}
@@ -586,10 +583,6 @@
 				 &maxsize) != 0)
 			return 1;
 
-		/* size is unspecified */
-		if (adjust_size && !scrub)
-			adjust_size_for_badblocks(&size, off, dev);
-
 		nand = &nand_info[dev];
 
 		memset(&opts, 0, sizeof(opts));
diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c
index 7dc89b2..07dee89 100644
--- a/drivers/dfu/dfu_nand.c
+++ b/drivers/dfu/dfu_nand.c
@@ -63,12 +63,26 @@
 
 	nand = &nand_info[nand_curr_device];
 
-	if (op == DFU_OP_READ)
+	if (op == DFU_OP_READ) {
 		ret = nand_read_skip_bad(nand, start, &count, &actual,
 				lim, buf);
-	else
+	} else {
+		nand_erase_options_t opts;
+
+		memset(&opts, 0, sizeof(opts));
+		opts.offset = start;
+		opts.length = count;
+		opts.spread = 1;
+		opts.quiet = 1;
+		opts.lim = lim;
+		/* first erase */
+		ret = nand_erase_opts(nand, &opts);
+		if (ret)
+			return ret;
+		/* then write */
 		ret = nand_write_skip_bad(nand, start, &count, &actual,
 				lim, buf, 0);
+	}
 
 	if (ret != 0) {
 		printf("%s: nand_%s_skip_bad call failed at %llx!\n",
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index 7dd9953..09f01c8 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -487,7 +487,7 @@
 }
 
 static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
-			  int page, int sndcmd)
+			  int page)
 {
 	struct docg4_priv *doc = nand->priv;
 	void __iomem *docptr = CONFIG_SYS_NAND_BASE;
@@ -577,7 +577,7 @@
 		writew(p[i], nand->IO_ADDR_W);
 }
 
-static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
+static int write_page(struct mtd_info *mtd, struct nand_chip *nand,
 		       const uint8_t *buf, int use_ecc)
 {
 	void __iomem *docptr = CONFIG_SYS_NAND_BASE;
@@ -626,16 +626,18 @@
 	write_nop(docptr);
 	writew(0, docptr + DOC_DATAEND);
 	write_nop(docptr);
+
+	return 0;
 }
 
-static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
-				 const uint8_t *buf)
+static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+				 const uint8_t *buf, int oob_required)
 {
 	return write_page(mtd, nand, buf, 0);
 }
 
-static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
-			     const uint8_t *buf)
+static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
+			     const uint8_t *buf, int oob_required)
 {
 	return write_page(mtd, nand, buf, 1);
 }
@@ -706,13 +708,13 @@
 
 
 static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
-			       uint8_t *buf, int page)
+			       uint8_t *buf, int oob_required, int page)
 {
 	return read_page(mtd, nand, buf, page, 0);
 }
 
 static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand,
-			   uint8_t *buf, int page)
+			   uint8_t *buf, int oob_required, int page)
 {
 	return read_page(mtd, nand, buf, page, 1);
 }
@@ -779,7 +781,7 @@
 		return -ENOMEM;
 
 	read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
-	status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE);
+	status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);
 	if (status)
 		goto exit;
 
@@ -858,7 +860,7 @@
 
 	/* write first page of block */
 	write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
-	docg4_write_page(mtd, nand, buf);
+	docg4_write_page(mtd, nand, buf, 1);
 	ret = pageprog(mtd);
 	if (!ret)
 		mtd->ecc_stats.badblocks++;
@@ -959,8 +961,8 @@
 	nand->ecc.size = DOCG4_PAGE_SIZE;
 	nand->ecc.prepad = 8;
 	nand->ecc.bytes	= 8;
-	nand->options =
-		NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR;
+	nand->ecc.strength = DOCG4_T;
+	nand->options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE;
 	nand->controller = &nand->hwcontrol;
 
 	/* methods */
diff --git a/drivers/mtd/nand/docg4_spl.c b/drivers/mtd/nand/docg4_spl.c
index 95e856c..734cbeb 100644
--- a/drivers/mtd/nand/docg4_spl.c
+++ b/drivers/mtd/nand/docg4_spl.c
@@ -113,7 +113,6 @@
 	int g4_index = 0;
 	uint16_t flash_status;
 	uint16_t *buf;
-	uint16_t discard, magic_high, magic_low;
 
 	/* flash_offset must be aligned to the start of a block */
 	if (flash_offset & 0x3ffff)
@@ -154,9 +153,9 @@
 	 * The IPL on the palmtreo680 requires that this contain a 32 bit magic
 	 * number, or the load aborts.  We'll ignore it.
 	 */
-	discard = readw(docptr + 0x103c); /* hw quirk; 1st read discarded */
-	magic_low = readw(docptr + 0x103c);
-	magic_high = readw(docptr + DOCG4_MYSTERY_REG);
+	readw(docptr + 0x103c); /* hw quirk; 1st read discarded */
+	readw(docptr + 0x103c);	/* lower 16 bits of magic number */
+	readw(docptr + DOCG4_MYSTERY_REG); /* upper 16 bits of magic number */
 	writew(0, docptr + DOC_DATAEND);
 	write_nop(docptr);
 	write_nop(docptr);
@@ -183,15 +182,15 @@
 		write_nop(docptr);
 
 		/* read the 512 bytes of page data, 2 bytes at a time */
-		discard = readw(docptr + 0x103c);
+		readw(docptr + 0x103c); /* hw quirk */
 		for (i = 0; i < 256; i++)
 			*buf++ = readw(docptr + 0x103c);
 
 		/* read oob, but discard it */
 		for (i = 0; i < 7; i++)
-			discard = readw(docptr + 0x103c);
-		discard = readw(docptr + DOCG4_OOB_6_7);
-		discard = readw(docptr + DOCG4_OOB_6_7);
+			readw(docptr + 0x103c);
+		readw(docptr + DOCG4_OOB_6_7);
+		readw(docptr + DOCG4_OOB_6_7);
 
 		writew(0, docptr + DOC_DATAEND);
 		write_nop(docptr);
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
index a691fbc..9421e56 100644
--- a/drivers/mtd/nand/jz4740_nand.c
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -256,7 +256,7 @@
 	nand->ecc.strength	= 4;
 	nand->ecc.layout	= &qi_lb60_ecclayout_2gb;
 	nand->chip_delay	= 50;
-	nand->options		= NAND_USE_FLASH_BBT;
+	nand->bbt_options	|= NAND_BBT_USE_FLASH;
 
 	return 0;
 }
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index d81972c..1d22b52 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -120,6 +120,10 @@
 
 		WATCHDOG_RESET();
 
+		if (opts->lim && (erase.addr >= (opts->offset + opts->lim))) {
+			puts("Size of erase exceeds limit\n");
+			return -EFBIG;
+		}
 		if (!opts->scrub && bbtest) {
 			int ret = mtd_block_isbad(meminfo, erase.addr);
 			if (ret > 0) {
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c
index 43d8213..1187b9f 100644
--- a/drivers/mtd/nand/s3c2410_nand.c
+++ b/drivers/mtd/nand/s3c2410_nand.c
@@ -179,9 +179,7 @@
 #endif
 
 #ifdef CONFIG_S3C2410_NAND_BBT
-	nand->options = NAND_USE_FLASH_BBT;
-#else
-	nand->options = 0;
+	nand->bbt_options |= NAND_BBT_USE_FLASH;
 #endif
 
 	debug("end of nand_init\n");
diff --git a/include/nand.h b/include/nand.h
index 26190e4..228d871 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -125,6 +125,8 @@
 
 	/* Don't include skipped bad blocks in size to be erased */
 	int spread;
+	/* maximum size that actual may be in order to not exceed the buf */
+	loff_t lim;
 };
 
 typedef struct nand_erase_options nand_erase_options_t;