diff --git a/board/atmel/at91cap9adk/nand.c b/board/atmel/at91cap9adk/nand.c
index 0432ef13d8..1dec5582f7 100644
--- a/board/atmel/at91cap9adk/nand.c
+++ b/board/atmel/at91cap9adk/nand.c
@@ -37,36 +37,35 @@
 #define	MASK_ALE	(1 << 21)	/* our ALE is AD21 */
 #define	MASK_CLE	(1 << 22)	/* our CLE is AD22 */
 
-static void at91cap9adk_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+static void at91cap9adk_nand_hwcontrol(struct mtd_info *mtd,
+				       int cmd, unsigned int ctrl)
 {
 	struct nand_chip *this = mtd->priv;
-	ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
 
-	IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
-	switch (cmd) {
-	case NAND_CTL_SETCLE:
-		IO_ADDR_W |= MASK_CLE;
-		break;
-	case NAND_CTL_SETALE:
-		IO_ADDR_W |= MASK_ALE;
-		break;
-	case NAND_CTL_CLRNCE:
-		at91_set_gpio_value(AT91_PIN_PD15, 1);
-		break;
-	case NAND_CTL_SETNCE:
-		at91_set_gpio_value(AT91_PIN_PD15, 0);
-		break;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
+		IO_ADDR_W &= ~(MASK_ALE | MASK_CLE);
+
+		if (ctrl & NAND_CLE)
+			IO_ADDR_W |= MASK_CLE;
+		if (ctrl & NAND_ALE)
+			IO_ADDR_W |= MASK_ALE;
+
+		at91_set_gpio_value(AT91_PIN_PD15, !(ctrl & NAND_NCE));
+		this->IO_ADDR_W = (void *) IO_ADDR_W;
 	}
-	this->IO_ADDR_W = (void *) IO_ADDR_W;
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
 }
 
 int board_nand_init(struct nand_chip *nand)
 {
-	nand->eccmode = NAND_ECC_SOFT;
+	nand->ecc.mode = NAND_ECC_SOFT;
 #ifdef CFG_NAND_DBW_16
 	nand->options = NAND_BUSWIDTH_16;
 #endif
-	nand->hwcontrol = at91cap9adk_nand_hwcontrol;
+	nand->cmd_ctrl = at91cap9adk_nand_hwcontrol;
 	nand->chip_delay = 20;
 
 	return 0;
diff --git a/board/atmel/at91sam9260ek/nand.c b/board/atmel/at91sam9260ek/nand.c
index 9738f0fd48..665e35c54b 100644
--- a/board/atmel/at91sam9260ek/nand.c
+++ b/board/atmel/at91sam9260ek/nand.c
@@ -37,27 +37,26 @@
 #define	MASK_ALE	(1 << 21)	/* our ALE is AD21 */
 #define	MASK_CLE	(1 << 22)	/* our CLE is AD22 */
 
-static void at91sam9260ek_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+static void at91sam9260ek_nand_hwcontrol(struct mtd_info *mtd,
+					 int cmd, unsigned int ctrl)
 {
 	struct nand_chip *this = mtd->priv;
-	ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
 
-	IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
-	switch (cmd) {
-	case NAND_CTL_SETCLE:
-		IO_ADDR_W |= MASK_CLE;
-		break;
-	case NAND_CTL_SETALE:
-		IO_ADDR_W |= MASK_ALE;
-		break;
-	case NAND_CTL_CLRNCE:
-		at91_set_gpio_value(AT91_PIN_PC14, 1);
-		break;
-	case NAND_CTL_SETNCE:
-		at91_set_gpio_value(AT91_PIN_PC14, 0);
-		break;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
+		IO_ADDR_W &= ~(MASK_ALE | MASK_CLE);
+
+		if (ctrl & NAND_CLE)
+			IO_ADDR_W |= MASK_CLE;
+		if (ctrl & NAND_ALE)
+			IO_ADDR_W |= MASK_ALE;
+
+		at91_set_gpio_value(AT91_PIN_PC14, !(ctrl & NAND_NCE));
+		this->IO_ADDR_W = (void *) IO_ADDR_W;
 	}
-	this->IO_ADDR_W = (void *) IO_ADDR_W;
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
 }
 
 static int at91sam9260ek_nand_ready(struct mtd_info *mtd)
@@ -67,11 +66,11 @@ static int at91sam9260ek_nand_ready(struct mtd_info *mtd)
 
 int board_nand_init(struct nand_chip *nand)
 {
-	nand->eccmode = NAND_ECC_SOFT;
+	nand->ecc.mode = NAND_ECC_SOFT;
 #ifdef CFG_NAND_DBW_16
 	nand->options = NAND_BUSWIDTH_16;
 #endif
-	nand->hwcontrol = at91sam9260ek_nand_hwcontrol;
+	nand->cmd_ctrl = at91sam9260ek_nand_hwcontrol;
 	nand->dev_ready = at91sam9260ek_nand_ready;
 	nand->chip_delay = 20;
 
diff --git a/board/atmel/at91sam9261ek/nand.c b/board/atmel/at91sam9261ek/nand.c
index 35b26dbefe..fccb9d78de 100644
--- a/board/atmel/at91sam9261ek/nand.c
+++ b/board/atmel/at91sam9261ek/nand.c
@@ -37,27 +37,26 @@
 #define	MASK_ALE	(1 << 22)	/* our ALE is AD22 */
 #define	MASK_CLE	(1 << 21)	/* our CLE is AD21 */
 
-static void at91sam9261ek_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+static void at91sam9261ek_nand_hwcontrol(struct mtd_info *mtd,
+					 int cmd, unsigned int ctrl)
 {
 	struct nand_chip *this = mtd->priv;
-	ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
 
-	IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
-	switch (cmd) {
-	case NAND_CTL_SETCLE:
-		IO_ADDR_W |= MASK_CLE;
-		break;
-	case NAND_CTL_SETALE:
-		IO_ADDR_W |= MASK_ALE;
-		break;
-	case NAND_CTL_CLRNCE:
-		at91_set_gpio_value(AT91_PIN_PC14, 1);
-		break;
-	case NAND_CTL_SETNCE:
-		at91_set_gpio_value(AT91_PIN_PC14, 0);
-		break;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
+		IO_ADDR_W &= ~(MASK_ALE | MASK_CLE);
+
+		if (ctrl & NAND_CLE)
+			IO_ADDR_W |= MASK_CLE;
+		if (ctrl & NAND_ALE)
+			IO_ADDR_W |= MASK_ALE;
+
+		at91_set_gpio_value(AT91_PIN_PC14, !(ctrl & NAND_NCE));
+		this->IO_ADDR_W = (void *) IO_ADDR_W;
 	}
-	this->IO_ADDR_W = (void *) IO_ADDR_W;
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
 }
 
 static int at91sam9261ek_nand_ready(struct mtd_info *mtd)
@@ -67,11 +66,11 @@ static int at91sam9261ek_nand_ready(struct mtd_info *mtd)
 
 int board_nand_init(struct nand_chip *nand)
 {
-	nand->eccmode = NAND_ECC_SOFT;
+	nand->ecc.mode = NAND_ECC_SOFT;
 #ifdef CFG_NAND_DBW_16
 	nand->options = NAND_BUSWIDTH_16;
 #endif
-	nand->hwcontrol = at91sam9261ek_nand_hwcontrol;
+	nand->cmd_ctrl = at91sam9261ek_nand_hwcontrol;
 	nand->dev_ready = at91sam9261ek_nand_ready;
 	nand->chip_delay = 20;
 
diff --git a/board/atmel/at91sam9263ek/nand.c b/board/atmel/at91sam9263ek/nand.c
index 5079972652..250ec7f394 100644
--- a/board/atmel/at91sam9263ek/nand.c
+++ b/board/atmel/at91sam9263ek/nand.c
@@ -37,27 +37,26 @@
 #define	MASK_ALE	(1 << 21)	/* our ALE is AD21 */
 #define	MASK_CLE	(1 << 22)	/* our CLE is AD22 */
 
-static void at91sam9263ek_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+static void at91sam9263ek_nand_hwcontrol(struct mtd_info *mtd,
+					 int cmd, unsigned int ctrl)
 {
 	struct nand_chip *this = mtd->priv;
-	ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
 
-	IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
-	switch (cmd) {
-	case NAND_CTL_SETCLE:
-		IO_ADDR_W |= MASK_CLE;
-		break;
-	case NAND_CTL_SETALE:
-		IO_ADDR_W |= MASK_ALE;
-		break;
-	case NAND_CTL_CLRNCE:
-		at91_set_gpio_value(AT91_PIN_PD15, 1);
-		break;
-	case NAND_CTL_SETNCE:
-		at91_set_gpio_value(AT91_PIN_PD15, 0);
-		break;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
+		IO_ADDR_W &= ~(MASK_ALE | MASK_CLE);
+
+		if (ctrl & NAND_CLE)
+			IO_ADDR_W |= MASK_CLE;
+		if (ctrl & NAND_ALE)
+			IO_ADDR_W |= MASK_ALE;
+
+		at91_set_gpio_value(AT91_PIN_PD15, !(ctrl & NAND_NCE));
+		this->IO_ADDR_W = (void *) IO_ADDR_W;
 	}
-	this->IO_ADDR_W = (void *) IO_ADDR_W;
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
 }
 
 static int at91sam9263ek_nand_ready(struct mtd_info *mtd)
@@ -67,11 +66,11 @@ static int at91sam9263ek_nand_ready(struct mtd_info *mtd)
 
 int board_nand_init(struct nand_chip *nand)
 {
-	nand->eccmode = NAND_ECC_SOFT;
+	nand->ecc.mode = NAND_ECC_SOFT;
 #ifdef CFG_NAND_DBW_16
 	nand->options = NAND_BUSWIDTH_16;
 #endif
-	nand->hwcontrol = at91sam9263ek_nand_hwcontrol;
+	nand->cmd_ctrl = at91sam9263ek_nand_hwcontrol;
 	nand->dev_ready = at91sam9263ek_nand_ready;
 	nand->chip_delay = 20;
 
diff --git a/board/atmel/at91sam9rlek/nand.c b/board/atmel/at91sam9rlek/nand.c
index 5af1a31175..eb342b842f 100644
--- a/board/atmel/at91sam9rlek/nand.c
+++ b/board/atmel/at91sam9rlek/nand.c
@@ -37,27 +37,26 @@
 #define	MASK_ALE	(1 << 21)	/* our ALE is AD21 */
 #define	MASK_CLE	(1 << 22)	/* our CLE is AD22 */
 
-static void at91sam9rlek_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+static void at91sam9rlek_nand_hwcontrol(struct mtd_info *mtd,
+					int cmd, unsigned int ctrl)
 {
 	struct nand_chip *this = mtd->priv;
-	ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
 
-	IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
-	switch (cmd) {
-	case NAND_CTL_SETCLE:
-		IO_ADDR_W |= MASK_CLE;
-		break;
-	case NAND_CTL_SETALE:
-		IO_ADDR_W |= MASK_ALE;
-		break;
-	case NAND_CTL_CLRNCE:
-		at91_set_gpio_value(AT91_PIN_PB6, 1);
-		break;
-	case NAND_CTL_SETNCE:
-		at91_set_gpio_value(AT91_PIN_PB6, 0);
-		break;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
+		IO_ADDR_W &= ~(MASK_ALE | MASK_CLE);
+
+		if (ctrl & NAND_CLE)
+			IO_ADDR_W |= MASK_CLE;
+		if (ctrl & NAND_ALE)
+			IO_ADDR_W |= MASK_ALE;
+
+		at91_set_gpio_value(AT91_PIN_PB6, !(ctrl & NAND_NCE));
+		this->IO_ADDR_W = (void *) IO_ADDR_W;
 	}
-	this->IO_ADDR_W = (void *) IO_ADDR_W;
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
 }
 
 static int at91sam9rlek_nand_ready(struct mtd_info *mtd)
@@ -67,11 +66,11 @@ static int at91sam9rlek_nand_ready(struct mtd_info *mtd)
 
 int board_nand_init(struct nand_chip *nand)
 {
-	nand->eccmode = NAND_ECC_SOFT;
+	nand->ecc.mode = NAND_ECC_SOFT;
 #ifdef CFG_NAND_DBW_16
 	nand->options = NAND_BUSWIDTH_16;
 #endif
-	nand->hwcontrol = at91sam9rlek_nand_hwcontrol;
+	nand->cmd_ctrl = at91sam9rlek_nand_hwcontrol;
 	nand->dev_ready = at91sam9rlek_nand_ready;
 	nand->chip_delay = 20;
 
diff --git a/board/freescale/m5373evb/nand.c b/board/freescale/m5373evb/nand.c
index 344a614895..404a9c386d 100644
--- a/board/freescale/m5373evb/nand.c
+++ b/board/freescale/m5373evb/nand.c
@@ -36,64 +36,39 @@ DECLARE_GLOBAL_DATA_PTR;
 #include <linux/mtd/mtd.h>
 
 #define SET_CLE		0x10
-#define CLR_CLE		~SET_CLE
 #define SET_ALE		0x08
-#define CLR_ALE		~SET_ALE
 
-static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd)
+static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl)
 {
 	struct nand_chip *this = mtdinfo->priv;
 	volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS;
 	u32 nand_baseaddr = (u32) this->IO_ADDR_W;
 
-	switch (cmd) {
-	case NAND_CTL_SETNCE:
-	case NAND_CTL_CLRNCE:
-		break;
-	case NAND_CTL_SETCLE:
-		nand_baseaddr |= SET_CLE;
-		break;
-	case NAND_CTL_CLRCLE:
-		nand_baseaddr &= CLR_CLE;
-		break;
-	case NAND_CTL_SETALE:
-		nand_baseaddr |= SET_ALE;
-		break;
-	case NAND_CTL_CLRALE:
-		nand_baseaddr |= CLR_ALE;
-		break;
-	case NAND_CTL_SETWP:
-		fbcs->csmr2 |= FBCS_CSMR_WP;
-		break;
-	case NAND_CTL_CLRWP:
-		fbcs->csmr2 &= ~FBCS_CSMR_WP;
-		break;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
+		IO_ADDR_W &= ~(SET_ALE | SE_CLE);
+
+		if (ctrl & NAND_CLE)
+			IO_ADDR_W |= SET_CLE;
+		if (ctrl & NAND_ALE)
+			IO_ADDR_W |= SET_ALE;
+
+		at91_set_gpio_value(AT91_PIN_PD15, !(ctrl & NAND_NCE));
+		this->IO_ADDR_W = (void *)IO_ADDR_W;
+
 	}
-	this->IO_ADDR_W = (void __iomem *)(nand_baseaddr);
-}
 
-static void nand_write_byte(struct mtd_info *mtdinfo, u_char byte)
-{
-	struct nand_chip *this = mtdinfo->priv;
-	*((volatile u8 *)(this->IO_ADDR_W)) = byte;
-}
-
-static u8 nand_read_byte(struct mtd_info *mtdinfo)
-{
-	struct nand_chip *this = mtdinfo->priv;
-	return (u8) (*((volatile u8 *)this->IO_ADDR_R));
-}
-
-static int nand_dev_ready(struct mtd_info *mtdinfo)
-{
-	return 1;
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
 }
 
 int board_nand_init(struct nand_chip *nand)
 {
 	volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO;
+	volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS;
 
 	*((volatile u16 *)CFG_LATCH_ADDR) |= 0x0004;
+	fbcs->csmr2 &= ~FBCS_CSMR_WP;
 
 	/* set up pin configuration */
 	gpio->par_timer &= ~GPIO_PAR_TIN3_TIN3;
@@ -103,11 +78,8 @@ int board_nand_init(struct nand_chip *nand)
 	gpio->podr_timer = 0;
 
 	nand->chip_delay = 50;
-	nand->eccmode = NAND_ECC_SOFT;
-	nand->hwcontrol = nand_hwcontrol;
-	nand->read_byte = nand_read_byte;
-	nand->write_byte = nand_write_byte;
-	nand->dev_ready = nand_dev_ready;
+	nand->ecc.mode = NAND_ECC_SOFT;
+	nand->cmd_ctrl = nand_hwcontrol;
 
 	return 0;
 }
diff --git a/board/quad100hd/nand.c b/board/quad100hd/nand.c
index a36b89dd79..766ee95bb3 100644
--- a/board/quad100hd/nand.c
+++ b/board/quad100hd/nand.c
@@ -25,35 +25,25 @@
 #include <config.h>
 #if defined(CONFIG_CMD_NAND)
 #include <asm/gpio.h>
+#include <asm/io.h>
 #include <nand.h>
 
 /*
  *	hardware specific access to control-lines
  */
-static void quad100hd_hwcontrol(struct mtd_info *mtd, int cmd)
+static void quad100hd_hwcontrol(struct mtd_info *mtd,
+				int cmd, unsigned int ctrl)
 {
-	switch(cmd) {
-	case NAND_CTL_SETCLE:
-		gpio_write_bit(CFG_NAND_CLE, 1);
-		break;
-	case NAND_CTL_CLRCLE:
-		gpio_write_bit(CFG_NAND_CLE, 0);
-		break;
+	struct nand_chip *this = mtd->priv;
 
-	case NAND_CTL_SETALE:
-		gpio_write_bit(CFG_NAND_ALE, 1);
-		break;
-	case NAND_CTL_CLRALE:
-		gpio_write_bit(CFG_NAND_ALE, 0);
-		break;
-
-	case NAND_CTL_SETNCE:
-		gpio_write_bit(CFG_NAND_CE, 0);
-		break;
-	case NAND_CTL_CLRNCE:
-		gpio_write_bit(CFG_NAND_CE, 1);
-		break;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		gpio_write_bit(CFG_NAND_CLE, !!(ctrl & NAND_CLE));
+		gpio_write_bit(CFG_NAND_ALE, !!(ctrl & NAND_ALE));
+		gpio_write_bit(CFG_NAND_CE, !(ctrl & NAND_NCE));
 	}
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
 }
 
 static int quad100hd_nand_ready(struct mtd_info *mtd)
@@ -67,9 +57,9 @@ static int quad100hd_nand_ready(struct mtd_info *mtd)
 int board_nand_init(struct nand_chip *nand)
 {
 	/* Set address of hardware control function */
-	nand->hwcontrol = quad100hd_hwcontrol;
+	nand->cmd_ctrl = quad100hd_hwcontrol;
 	nand->dev_ready = quad100hd_nand_ready;
-	nand->eccmode = NAND_ECC_SOFT;
+	nand->ecc.mode = NAND_ECC_SOFT;
 	/* 15 us command delay time */
 	nand->chip_delay =  20;
 
diff --git a/board/socrates/nand.c b/board/socrates/nand.c
index fc82ecbb73..6ec53f872d 100644
--- a/board/socrates/nand.c
+++ b/board/socrates/nand.c
@@ -31,22 +31,20 @@
 static int state;
 static void nand_write_byte(struct mtd_info *mtd, u_char byte);
 static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
-static void nand_write_word(struct mtd_info *mtd, u16 word);
 static u_char nand_read_byte(struct mtd_info *mtd);
 static u16 nand_read_word(struct mtd_info *mtd);
 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
 static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
 static int nand_device_ready(struct mtd_info *mtdinfo);
-static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd);
 
 #define FPGA_NAND_CMD_MASK		(0x7 << 28)
-#define FPGA_NAND_CMD_COMMAND	(0x0 << 28)
+#define FPGA_NAND_CMD_COMMAND		(0x0 << 28)
 #define FPGA_NAND_CMD_ADDR		(0x1 << 28)
 #define FPGA_NAND_CMD_READ		(0x2 << 28)
 #define FPGA_NAND_CMD_WRITE		(0x3 << 28)
 #define FPGA_NAND_BUSY			(0x1 << 15)
 #define FPGA_NAND_ENABLE		(0x1 << 31)
-#define FPGA_NAND_DATA_SHIFT	16
+#define FPGA_NAND_DATA_SHIFT		16
 
 /**
  * nand_write_byte -  write one byte to the chip
@@ -58,16 +56,6 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte)
 	nand_write_buf(mtd, (const uchar *)&byte, sizeof(byte));
 }
 
-/**
- * nand_write_word -  write one word to the chip
- * @mtd:	MTD device structure
- * @word:	data word to write
- */
-static void nand_write_word(struct mtd_info *mtd, u16 word)
-{
-	nand_write_buf(mtd, (const uchar *)&word, sizeof(word));
-}
-
 /**
  * nand_write_buf -  write buffer to chip
  * @mtd:	MTD device structure
@@ -78,18 +66,10 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
 	int i;
 	struct nand_chip *this = mtd->priv;
-	long val;
-
-	if ((state & FPGA_NAND_CMD_MASK) == FPGA_NAND_CMD_MASK) {
-		/* Write data */
-		val = (state & FPGA_NAND_ENABLE) | FPGA_NAND_CMD_WRITE;
-	} else {
-		/* Write address or command */
-		val = state;
-	}
 
 	for (i = 0; i < len; i++) {
-		out_be32(this->IO_ADDR_W, val | (buf[i] << FPGA_NAND_DATA_SHIFT));
+		out_be32(this->IO_ADDR_W,
+			 state | (buf[i] << FPGA_NAND_DATA_SHIFT));
 	}
 }
 
@@ -148,7 +128,7 @@ static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 
 	for (i = 0; i < len; i++) {
 		if (buf[i] != nand_read_byte(mtd));
-		return -EFAULT;
+			return -EFAULT;
 	}
 	return 0;
 }
@@ -171,42 +151,42 @@ static int nand_device_ready(struct mtd_info *mtdinfo)
  * @mtd:	MTD device structure
  * @cmd:	Command
  */
-static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd)
+static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl)
 {
+	if (ctrl & NAND_CTRL_CHANGE) {
+		state &= ~(FPGA_NAND_CMD_MASK | FPGA_NAND_ENABLE);
 
-	switch(cmd) {
-	case NAND_CTL_CLRALE:
-		state |= FPGA_NAND_CMD_MASK; /* use all 1s to mark */
-		break;
-	case NAND_CTL_CLRCLE:
-		state |= FPGA_NAND_CMD_MASK; /* use all 1s to mark */
-		break;
-	case NAND_CTL_SETCLE:
-		state = (state & ~FPGA_NAND_CMD_MASK) | FPGA_NAND_CMD_COMMAND;
-		break;
-	case NAND_CTL_SETALE:
-		state = (state & ~FPGA_NAND_CMD_MASK) | FPGA_NAND_CMD_ADDR;
-		break;
-	case NAND_CTL_SETNCE:
-		state |= FPGA_NAND_ENABLE;
-		break;
-	case NAND_CTL_CLRNCE:
-		state &= ~FPGA_NAND_ENABLE;
-		break;
-	default:
-		printf("%s: unknown cmd %#x\n", __FUNCTION__, cmd);
-		break;
+		switch (ctrl & (NAND_ALE | NAND_CLE)) {
+		case 0:
+			state |= FPGA_NAND_CMD_WRITE;
+			break;
+
+		case NAND_ALE:
+			state |= FPGA_NAND_CMD_ADDR;
+			break;
+
+		case NAND_CLE:
+			state |= FPGA_NAND_CMD_COMMAND;
+			break;
+
+		default:
+			printf("%s: unknown ctrl %#x\n", __FUNCTION__, ctrl);
+		}
+
+		if (ctrl & NAND_NCE)
+			state |= FPGA_NAND_ENABLE;
 	}
+
+	if (cmd != NAND_CMD_NONE)
+		nand_write_byte(mtdinfo, cmd);
 }
 
 int board_nand_init(struct nand_chip *nand)
 {
-	nand->hwcontrol = nand_hwcontrol;
-	nand->eccmode = NAND_ECC_SOFT;
+	nand->cmd_ctrl = nand_hwcontrol;
+	nand->ecc.mode = NAND_ECC_SOFT;
 	nand->dev_ready = nand_device_ready;
-	nand->write_byte = nand_write_byte;
 	nand->read_byte = nand_read_byte;
-	nand->write_word = nand_write_word;
 	nand->read_word = nand_read_word;
 	nand->write_buf = nand_write_buf;
 	nand->read_buf = nand_read_buf;
diff --git a/common/env_onenand.c b/common/env_onenand.c
index dbd0883fa8..d5c907c6f0 100644
--- a/common/env_onenand.c
+++ b/common/env_onenand.c
@@ -40,7 +40,7 @@ extern struct onenand_chip onenand_chip;
 /* References to names in env_common.c */
 extern uchar default_environment[];
 
-#define ONENAND_ENV_SIZE(mtd)	(mtd.oobblock - ENV_HEADER_SIZE)
+#define ONENAND_ENV_SIZE(mtd)	(mtd.writesize - ENV_HEADER_SIZE)
 
 char *env_name_spec = "OneNAND";
 
@@ -68,12 +68,12 @@ void env_relocate_spec(void)
 	env_addr = CFG_ENV_ADDR;
 
 	/* Check OneNAND exist */
-	if (onenand_mtd.oobblock)
+	if (onenand_mtd.writesize)
 		/* Ignore read fail */
-		onenand_read(&onenand_mtd, env_addr, onenand_mtd.oobblock,
+		onenand_read(&onenand_mtd, env_addr, onenand_mtd.writesize,
 			     &retlen, (u_char *) env_ptr);
 	else
-		onenand_mtd.oobblock = MAX_ONENAND_PAGESIZE;
+		onenand_mtd.writesize = MAX_ONENAND_PAGESIZE;
 
 	if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) !=
 	    env_ptr->crc)
@@ -109,7 +109,7 @@ int saveenv(void)
 	env_ptr->crc =
 	    crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd));
 
-	if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.oobblock, &retlen,
+	if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.writesize, &retlen,
 	     (u_char *) env_ptr)) {
 		printf("OneNAND: write failed at 0x%08x\n", instr.addr);
 		return 2;
diff --git a/cpu/arm920t/s3c24x0/nand.c b/cpu/arm920t/s3c24x0/nand.c
index 14882cb243..60174fb4d2 100644
--- a/cpu/arm920t/s3c24x0/nand.c
+++ b/cpu/arm920t/s3c24x0/nand.c
@@ -31,6 +31,7 @@
 
 #include <nand.h>
 #include <s3c2410.h>
+#include <asm/io.h>
 
 #define __REGb(x)	(*(volatile unsigned char *)(x))
 #define __REGi(x)	(*(volatile unsigned int *)(x))
@@ -54,34 +55,33 @@
 #define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
 #define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)
 
-static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd)
+#define S3C2410_ADDR_NALE 4
+#define S3C2410_ADDR_NCLE 8
+
+static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
 	struct nand_chip *chip = mtd->priv;
 
-	DEBUGN("hwcontrol(): 0x%02x: ", cmd);
+	DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
 
-	switch (cmd) {
-	case NAND_CTL_SETNCE:
-		NFCONF &= ~S3C2410_NFCONF_nFCE;
-		DEBUGN("NFCONF=0x%08x\n", NFCONF);
-		break;
-	case NAND_CTL_CLRNCE:
-		NFCONF |= S3C2410_NFCONF_nFCE;
-		DEBUGN("NFCONF=0x%08x\n", NFCONF);
-		break;
-	case NAND_CTL_SETALE:
-		chip->IO_ADDR_W = NF_BASE + 0x8;
-		DEBUGN("SETALE\n");
-		break;
-	case NAND_CTL_SETCLE:
-		chip->IO_ADDR_W = NF_BASE + 0x4;
-		DEBUGN("SETCLE\n");
-		break;
-	default:
-		chip->IO_ADDR_W = NF_BASE + 0xc;
-		break;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		ulong IO_ADDR_W = NF_BASE;
+
+		if (!(ctrl & NAND_CLE))
+			IO_ADDR_W |= S3C2410_ADDR_NCLE;
+		if (!(ctrl & NAND_ALE))
+			IO_ADDR_W |= S3C2410_ADDR_NALE;
+
+		chip->IO_ADDR_W = (void *)IO_ADDR_W;
+
+		if (ctrl & NAND_NCE)
+			NFCONF &= ~S3C2410_NFCONF_nFCE;
+		else
+			NFCONF |= S3C2410_NFCONF_nFCE;
 	}
-	return;
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, chip->IO_ADDR_W);
 }
 
 static int s3c2410_dev_ready(struct mtd_info *mtd)
@@ -93,7 +93,7 @@ static int s3c2410_dev_ready(struct mtd_info *mtd)
 #ifdef CONFIG_S3C2410_NAND_HWECC
 void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 {
-	DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd ,mode);
+	DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);
 	NFCONF |= S3C2410_NFCONF_INITECC;
 }
 
@@ -143,23 +143,23 @@ int board_nand_init(struct nand_chip *nand)
 	NFCONF = cfg;
 
 	/* initialize nand_chip data structure */
-	nand->IO_ADDR_R = nand->IO_ADDR_W = 0x4e00000c;
+	nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e00000c;
 
 	/* read_buf and write_buf are default */
 	/* read_byte and write_byte are default */
 
 	/* hwcontrol always must be implemented */
-	nand->hwcontrol = s3c2410_hwcontrol;
+	nand->cmd_ctrl = s3c2410_hwcontrol;
 
 	nand->dev_ready = s3c2410_dev_ready;
 
 #ifdef CONFIG_S3C2410_NAND_HWECC
-	nand->enable_hwecc = s3c2410_nand_enable_hwecc;
-	nand->calculate_ecc = s3c2410_nand_calculate_ecc;
-	nand->correct_data = s3c2410_nand_correct_data;
-	nand->eccmode = NAND_ECC_HW3_512;
+	nand->ecc.hwctl = s3c2410_nand_enable_hwecc;
+	nand->ecc.calculate = s3c2410_nand_calculate_ecc;
+	nand->ecc.correct = s3c2410_nand_correct_data;
+	nand->ecc.mode = NAND_ECC_HW3_512;
 #else
-	nand->eccmode = NAND_ECC_SOFT;
+	nand->ecc.mode = NAND_ECC_SOFT;
 #endif
 
 #ifdef CONFIG_S3C2410_NAND_BBT
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 7c9438be31..8f12fa26e0 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -328,7 +328,7 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
 
 	if (ONENAND_CURRENT_BUFFERRAM(this)) {
 		if (area == ONENAND_DATARAM)
-			return mtd->oobblock;
+			return mtd->writesize;
 		if (area == ONENAND_SPARERAM)
 			return mtd->oobsize;
 	}
@@ -478,6 +478,30 @@ static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
 	return 0;
 }
 
+/**
+ * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
+ * @param mtd           MTD data structure
+ * @param addr          start address to invalidate
+ * @param len           length to invalidate
+ *
+ * Invalidate BufferRAM information
+ */
+static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
+                                         unsigned int len)
+{
+	struct onenand_chip *this = mtd->priv;
+	int i;
+	loff_t end_addr = addr + len;
+
+	/* Invalidate BufferRAM */
+	for (i = 0; i < MAX_BUFFERRAM; i++) {
+		loff_t buf_addr = this->bufferram[i].block << this->erase_shift;
+
+		if (buf_addr >= addr && buf_addr < end_addr)
+			this->bufferram[i].valid = 0;
+	}
+}
+
 /**
  * onenand_get_device - [GENERIC] Get chip for selected access
  * @param mtd		MTD device structure
@@ -538,15 +562,15 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
 	onenand_get_device(mtd, FL_READING);
 
 	while (read < len) {
-		thislen = min_t(int, mtd->oobblock, len - read);
+		thislen = min_t(int, mtd->writesize, len - read);
 
-		column = from & (mtd->oobblock - 1);
-		if (column + thislen > mtd->oobblock)
-			thislen = mtd->oobblock - column;
+		column = from & (mtd->writesize - 1);
+		if (column + thislen > mtd->writesize)
+			thislen = mtd->writesize - column;
 
 		if (!onenand_check_bufferram(mtd, from)) {
 			this->command(mtd, ONENAND_CMD_READ, from,
-				      mtd->oobblock);
+				      mtd->writesize);
 			ret = this->wait(mtd, FL_READING);
 			/* First copy data and check return value for ECC handling */
 			onenand_update_bufferram(mtd, from, 1);
@@ -661,7 +685,7 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
 		/* Read more? */
 		if (read < len) {
 			/* Page size */
-			from += mtd->oobblock;
+			from += mtd->writesize;
 			column = 0;
 		}
 	}
@@ -688,7 +712,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
 	void __iomem *dataram0, *dataram1;
 	int ret = 0;
 
-	this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
+	this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
 
 	ret = this->wait(mtd, FL_READING);
 	if (ret)
@@ -698,9 +722,9 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
 
 	/* Check, if the two dataram areas are same */
 	dataram0 = this->base + ONENAND_DATARAM;
-	dataram1 = dataram0 + mtd->oobblock;
+	dataram1 = dataram0 + mtd->writesize;
 
-	if (memcmp(dataram0, dataram1, mtd->oobblock))
+	if (memcmp(dataram0, dataram1, mtd->writesize))
 		return -EBADMSG;
 
 	return 0;
@@ -709,7 +733,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
 #define onenand_verify_page(...)	(0)
 #endif
 
-#define NOTALIGNED(x)	((x & (mtd->oobblock - 1)) != 0)
+#define NOTALIGNED(x)	((x & (mtd->writesize - 1)) != 0)
 
 /**
  * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
@@ -757,15 +781,15 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 
 	/* Loop until all data write */
 	while (written < len) {
-		int thislen = min_t(int, mtd->oobblock, len - written);
+		int thislen = min_t(int, mtd->writesize, len - written);
 
-		this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
+		this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);
 
 		this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
 		this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
 				      mtd->oobsize);
 
-		this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
+		this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
 
 		onenand_update_bufferram(mtd, to, 1);
 
@@ -889,6 +913,25 @@ int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
 	return 0;
 }
 
+/**
+ * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
+ * @param mtd		MTD device structure
+ * @param ofs		offset from device start
+ * @param allowbbt	1, if its allowed to access the bbt area
+ *
+ * Check, if the block is bad, Either by reading the bad block table or
+ * calling of the scan function.
+ */
+static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
+{
+	struct onenand_chip *this = mtd->priv;
+	struct bbm_info *bbm = this->bbm;
+
+	/* Return info from the table */
+	return bbm->isbad_bbt(mtd, ofs, allowbbt);
+}
+
+
 /**
  * onenand_erase - [MTD Interface] erase block(s)
  * @param mtd		MTD device structure
@@ -947,6 +990,8 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 		this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
 
+		onenand_invalidate_bufferram(mtd, addr, block_size);
+
 		ret = this->wait(mtd, FL_ERASING);
 		/* Check, if it is write protected */
 		if (ret) {
@@ -1002,30 +1047,45 @@ void onenand_sync(struct mtd_info *mtd)
  * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
  * @param mtd		MTD device structure
  * @param ofs		offset relative to mtd start
+ *
+ * Check whether the block is bad
  */
 int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
-	/*
-	 * TODO
-	 * 1. Bad block table (BBT)
-	 *   -> using NAND BBT to support JFFS2
-	 * 2. Bad block management (BBM)
-	 *   -> bad block replace scheme
-	 *
-	 * Currently we do nothing
-	 */
-	return 0;
+	int ret;
+
+	/* Check for invalid offset */
+	if (ofs > mtd->size)
+		return -EINVAL;
+
+	onenand_get_device(mtd, FL_READING);
+	ret = onenand_block_isbad_nolock(mtd,ofs, 0);
+	onenand_release_device(mtd);
+	return ret;
 }
 
 /**
  * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
  * @param mtd		MTD device structure
  * @param ofs		offset relative to mtd start
+ *
+ * Mark the block as bad
  */
 int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
-	/* see above */
-	return 0;
+	struct onenand_chip *this = mtd->priv;
+	int ret;
+
+	ret = onenand_block_isbad(mtd, ofs);
+	if (ret) {
+		/* If it was bad already, return success and do nothing */
+		if (ret > 0)
+			return 0;
+		return ret;
+	}
+
+	ret = this->block_markbad(mtd, ofs);
+	return ret;
 }
 
 /**
@@ -1181,10 +1241,8 @@ static int onenand_probe(struct mtd_info *mtd)
 	/* Reset OneNAND to read default register values */
 	this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
 
-	{
-		int i;
-		for (i = 0; i < 10000; i++) ;
-	}
+	/* Wait reset */
+	this->wait(mtd, FL_RESETING);
 
 	/* Read manufacturer and device IDs from Register */
 	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
@@ -1209,16 +1267,16 @@ static int onenand_probe(struct mtd_info *mtd)
 
 	/* OneNAND page size & block size */
 	/* The data buffer size is equal to page size */
-	mtd->oobblock =
+	mtd->writesize =
 	    this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
-	mtd->oobsize = mtd->oobblock >> 5;
+	mtd->oobsize = mtd->writesize >> 5;
 	/* Pagers per block is always 64 in OneNAND */
-	mtd->erasesize = mtd->oobblock << 6;
+	mtd->erasesize = mtd->writesize << 6;
 
 	this->erase_shift = ffs(mtd->erasesize) - 1;
-	this->page_shift = ffs(mtd->oobblock) - 1;
+	this->page_shift = ffs(mtd->writesize) - 1;
 	this->ppb_shift = (this->erase_shift - this->page_shift);
-	this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
+	this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
 
 	/* REVIST: Multichip handling */
 
@@ -1237,11 +1295,10 @@ static int onenand_probe(struct mtd_info *mtd)
 		this->options |= ONENAND_CONT_LOCK;
 	}
 
+	mtd->flags = MTD_CAP_NANDFLASH;
 	mtd->erase = onenand_erase;
 	mtd->read = onenand_read;
 	mtd->write = onenand_write;
-	mtd->read_ecc = onenand_read_ecc;
-	mtd->write_ecc = onenand_write_ecc;
 	mtd->read_oob = onenand_read_oob;
 	mtd->write_oob = onenand_write_oob;
 	mtd->sync = onenand_sync;
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 0abaa1ab38..d13d2777e2 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -94,7 +94,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
 			/* No need to read pages fully,
 			 * just read required OOB bytes */
 			ret = onenand_read_oob(mtd,
-					     from + j * mtd->oobblock +
+					     from + j * mtd->writesize +
 					     bd->offs, readlen, &retlen,
 					     &buf[0]);
 
@@ -104,7 +104,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
 			}
 
 			if (check_short_pattern
-			    (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+			    (&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
 				bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
 				printk(KERN_WARNING
 				       "Bad eraseblock %d at 0x%08x\n", i >> 1,
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 8e0dc00f75..14815c219b 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -22,6 +22,22 @@
 #define MTD_ERASE_DONE          0x08
 #define MTD_ERASE_FAILED        0x10
 
+/*
+ * Enumeration for NAND/OneNAND flash chip state
+ */
+enum {
+	FL_READY,
+	FL_READING,
+	FL_WRITING,
+	FL_ERASING,
+	FL_SYNCING,
+	FL_CACHEDPRG,
+	FL_RESETING,
+	FL_UNLOCKING,
+	FL_LOCKING,
+	FL_PM_SUSPENDED,
+};
+
 /* If the erase fails, fail_addr might indicate exactly which block failed.  If
    fail_addr = 0xffffffff, the failure was not at the device level or was not
    specific to any particular block. */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 2993a89e1b..7ac72de95e 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -213,20 +213,6 @@ typedef enum {
 #define NAND_CI_CHIPNR_MSK	0x03
 #define NAND_CI_CELLTYPE_MSK	0x0C
 
-/*
- * nand_state_t - chip states
- * Enumeration for NAND flash chip state
- */
-typedef enum {
-	FL_READY,
-	FL_READING,
-	FL_WRITING,
-	FL_ERASING,
-	FL_SYNCING,
-	FL_CACHEDPRG,
-	FL_PM_SUSPENDED,
-} nand_state_t;
-
 /* Keep gcc happy */
 struct nand_chip;
 
@@ -416,7 +402,7 @@ struct nand_chip {
 	uint8_t		cellinfo;
 	int		badblockpos;
 
-	nand_state_t	state;
+	int 		state;
 
 	uint8_t		*oob_poi;
 	struct nand_hw_control  *controller;
diff --git a/include/linux/mtd/nand_legacy.h b/include/linux/mtd/nand_legacy.h
index 4494bc569d..99eafbbcdc 100644
--- a/include/linux/mtd/nand_legacy.h
+++ b/include/linux/mtd/nand_legacy.h
@@ -54,18 +54,6 @@
 #define NAND_CMD_ERASE2		0xd0
 #define NAND_CMD_RESET		0xff
 
-/*
- * Enumeration for NAND flash chip state
- */
-typedef enum {
-	FL_READY,
-	FL_READING,
-	FL_WRITING,
-	FL_ERASING,
-	FL_SYNCING
-} nand_state_t;
-
-
 /*
  * NAND Private Flash Chip Data
  *
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 4b0c2dfaaa..8a0fd0de97 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -17,6 +17,7 @@
 /* Note: The header order is impoertant */
 #include <onenand_uboot.h>
 
+#include <linux/mtd/compat.h>
 #include <linux/mtd/bbm.h>
 
 #define MAX_BUFFERRAM		2
@@ -27,20 +28,6 @@ extern int onenand_scan (struct mtd_info *mtd, int max_chips);
 /* Free resources held by the OneNAND device */
 extern void onenand_release (struct mtd_info *mtd);
 
-/**
- * onenand_state_t - chip states
- * Enumeration for OneNAND flash chip state
- */
-typedef enum {
-	FL_READY,
-	FL_READING,
-	FL_WRITING,
-	FL_ERASING,
-	FL_SYNCING,
-	FL_UNLOCKING,
-	FL_LOCKING,
-} onenand_state_t;
-
 /**
  * struct onenand_bufferram - OneNAND BufferRAM Data
  * @param block		block address in BufferRAM
@@ -103,10 +90,12 @@ struct onenand_chip {
 	unsigned short (*read_word) (void __iomem * addr);
 	void (*write_word) (unsigned short value, void __iomem * addr);
 	void (*mmcontrol) (struct mtd_info * mtd, int sync_read);
+	int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
+	int (*scan_bbt)(struct mtd_info *mtd);
 
 	spinlock_t chip_lock;
 	wait_queue_head_t wq;
-	onenand_state_t state;
+	int state;
 
 	struct nand_oobinfo *autooob;