diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 3e2edb8aaabd4cf1c8ff32f0f6575a039944e3ca..fa96a5201cc89cc6ee8ac7d85915a224b3e504c3 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -48,7 +48,7 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat)
 
 	last = off;
 
-	datbuf = malloc(nand->writesize + nand->oobsize);
+	datbuf = malloc(nand->writesize);
 	oobbuf = malloc(nand->oobsize);
 	if (!datbuf || !oobbuf) {
 		puts("No memory for page buffer\n");
@@ -59,7 +59,7 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat)
 	struct mtd_oob_ops ops;
 	memset(&ops, 0, sizeof(ops));
 	ops.datbuf = datbuf;
-	ops.oobbuf = oobbuf; /* must exist, but oob data will be appended to ops.datbuf */
+	ops.oobbuf = oobbuf;
 	ops.len = nand->writesize;
 	ops.ooblen = nand->oobsize;
 	ops.mode = MTD_OOB_RAW;
@@ -85,6 +85,7 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat)
 	}
 	puts("OOB:\n");
 	i = nand->oobsize >> 3;
+	p = oobbuf;
 	while (i--) {
 		printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
 		       p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 998fc73497caf4ca33e125ffafbb7b1d08b7d615..1d1b6286510b3c3c7b2d769f2243e929ab7411b2 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -39,7 +39,7 @@ COBJS-y += nand_bbt.o
 COBJS-y += nand_ids.o
 COBJS-y += nand_util.o
 endif
-COBJS-$(CONFIG_MTD_ECC_SOFT) += nand_ecc.o
+COBJS-y += nand_ecc.o
 COBJS-y += nand_base.o
 COBJS-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
 
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index b3f3c3c05a58bc23c2ae7b68fdd5ec00a6421027..5cac78b2968567a500a2db3155083f9661b189e9 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -1,6 +1,6 @@
 /* Integrated Flash Controller NAND Machine Driver
  *
- * Copyright (c) 2011 Freescale Semiconductor, Inc
+ * Copyright (c) 2012 Freescale Semiconductor, Inc
  *
  * Authors: Dipen Dudhat <Dipen.Dudhat@freescale.com>
  *
@@ -221,24 +221,11 @@ static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
 			  u32 *eccstat, unsigned int bufnum)
 {
 	u32 reg = eccstat[bufnum / 4];
-	int errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
-
-	if (errors == 15) { /* uncorrectable */
-		/* Blank pages fail hw ECC checks */
-		if (is_blank(mtd, ctrl, bufnum))
-			return 1;
-
-		/*
-		 * We disable ECCER reporting in hardware due to
-		 * erratum IFC-A002770 -- so report it now if we
-		 * see an uncorrectable error in ECCSTAT.
-		 */
-		ctrl->status |= IFC_NAND_EVTER_STAT_ECCER;
-	} else if (errors > 0) {
-		mtd->ecc_stats.corrected += errors;
-	}
+	int errors;
 
-	return 0;
+	errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
+
+	return errors;
 }
 
 /*
@@ -279,16 +266,33 @@ static int fsl_ifc_run_command(struct mtd_info *mtd)
 		printf("%s: Write Protect Error\n", __func__);
 
 	if (ctrl->eccread) {
-		int bufperpage = mtd->writesize / 512;
-		int bufnum = (ctrl->page & priv->bufnum_mask) * bufperpage;
-		int bufnum_end = bufnum + bufperpage - 1;
+		int errors;
+		int bufnum = ctrl->page & priv->bufnum_mask;
+		int sector = bufnum * chip->ecc.steps;
+		int sector_end = sector + chip->ecc.steps - 1;
 
-		for (i = bufnum / 4; i <= bufnum_end / 4; i++)
+		for (i = sector / 4; i <= sector_end / 4; i++)
 			eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]);
 
-		for (i = bufnum; i <= bufnum_end; i++) {
-			if (check_read_ecc(mtd, ctrl, eccstat, i))
+		for (i = sector; i <= sector_end; i++) {
+			errors = check_read_ecc(mtd, ctrl, eccstat, i);
+
+			if (errors == 15) {
+				/*
+				 * Uncorrectable error.
+				 * OK only if the whole page is blank.
+				 *
+				 * We disable ECCER reporting due to erratum
+				 * IFC-A002770 -- so report it now if we
+				 * see an uncorrectable error in ECCSTAT.
+				 */
+				if (!is_blank(mtd, ctrl, bufnum))
+					ctrl->status |=
+						IFC_NAND_EVTER_STAT_ECCER;
 				break;
+			}
+
+			mtd->ecc_stats.corrected += errors;
 		}
 
 		ctrl->eccread = 0;
@@ -448,21 +452,19 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 			out_be32(&ifc->ifc_nand.nand_fir1,
 				 (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT));
 
-			if (column >= mtd->writesize) {
-				/* OOB area --> READOOB */
-				column -= mtd->writesize;
-				nand_fcr0 |= NAND_CMD_READOOB <<
-						IFC_NAND_FCR0_CMD0_SHIFT;
-				ctrl->oob = 1;
-			} else if (column < 256) {
-				/* First 256 bytes --> READ0 */
-				nand_fcr0 |= NAND_CMD_READ0 << FCR_CMD0_SHIFT;
-			} else {
-				/* Second 256 bytes --> READ1 */
-				nand_fcr0 |= NAND_CMD_READ1 << FCR_CMD0_SHIFT;
-			}
+			if (column >= mtd->writesize)
+				nand_fcr0 |=
+				NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT;
+			else
+				nand_fcr0 |=
+				NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT;
 		}
 
+		if (column >= mtd->writesize) {
+			/* OOB area --> READOOB */
+			column -= mtd->writesize;
+			ctrl->oob = 1;
+		}
 		out_be32(&ifc->ifc_nand.nand_fcr0, nand_fcr0);
 		set_addr(mtd, column, page_addr, ctrl->oob);
 		return;
@@ -471,7 +473,8 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 	/* PAGEPROG reuses all of the setup from SEQIN and adds the length */
 	case NAND_CMD_PAGEPROG:
 		if (ctrl->oob)
-			out_be32(&ifc->ifc_nand.nand_fbcr, ctrl->index);
+			out_be32(&ifc->ifc_nand.nand_fbcr,
+					ctrl->index - ctrl->column);
 		else
 			out_be32(&ifc->ifc_nand.nand_fbcr, 0);
 
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 12b960fdb907ba44e3957b02a7b0e7a5f817dbf9..44f7b914578d1effda938c808d8696417a6812dc 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -479,6 +479,11 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
 {
 	struct nand_chip *chip = mtd->priv;
 
+	if (!(chip->options & NAND_BBT_SCANNED)) {
+		chip->options |= NAND_BBT_SCANNED;
+		chip->scan_bbt(mtd);
+	}
+
 	if (!chip->bbt)
 		return chip->block_bad(mtd, ofs, getchip);
 
@@ -3028,10 +3033,6 @@ int nand_scan_tail(struct mtd_info *mtd)
 		chip->ecc.mode = NAND_ECC_SOFT;
 
 	case NAND_ECC_SOFT:
-		if (!mtd_nand_has_ecc_soft()) {
-			printk(KERN_WARNING "CONFIG_MTD_ECC_SOFT not enabled\n");
-			return -EINVAL;
-		}
 		chip->ecc.calculate = nand_calculate_ecc;
 		chip->ecc.correct = nand_correct_data;
 		chip->ecc.read_page = nand_read_page_swecc;
@@ -3170,10 +3171,9 @@ int nand_scan_tail(struct mtd_info *mtd)
 
 	/* Check, if we should skip the bad block table scan */
 	if (chip->options & NAND_SKIP_BBTSCAN)
-		return 0;
+		chip->options |= NAND_BBT_SCANNED;
 
-	/* Build bad block table */
-	return chip->scan_bbt(mtd);
+	return 0;
 }
 
 /**
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 99668d552e22ac37e8af6c124ec2bfe25fdd6e25..da6fa184c3397d4dce226525e30f06f501da2f29 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -232,6 +232,8 @@ typedef enum {
 #define NAND_CREATE_EMPTY_BBT		0x01000000
 
 /* Options set by nand scan */
+/* bbt has already been read */
+#define NAND_BBT_SCANNED	0x40000000
 /* Nand scan has allocated controller struct */
 #define NAND_CONTROLLER_ALLOC	0x80000000
 
diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h
index 9715a53d86d4ec3716b167a646dd3732da556d13..090da505425d77d105acb6133d63dfaaa7c95b7b 100644
--- a/include/linux/mtd/nand_ecc.h
+++ b/include/linux/mtd/nand_ecc.h
@@ -15,10 +15,6 @@
 
 struct mtd_info;
 
-#if defined(CONFIG_MTD_ECC_SOFT)
-
-static inline int mtd_nand_has_ecc_soft(void) { return 1; }
-
 /*
  * Calculate 3 byte ECC code for 256 byte block
  */
@@ -29,25 +25,4 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
  */
 int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
 
-#else
-
-static inline int mtd_nand_has_ecc_soft(void) { return 0; }
-
-static inline int
-nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
-{
-	return -1;
-}
-
-static inline int
-nand_correct_data(struct mtd_info *mtd,
-			u_char *dat,
-			u_char *read_ecc,
-			u_char *calc_ecc)
-{
-	return -1;
-}
-
-#endif
-
 #endif /* __MTD_NAND_ECC_H__ */