diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 4883139..acf0c25 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -37,6 +37,17 @@ config MTD_NAND_ECC_BCH
 	  ECC codes. They are used with NAND devices requiring more than 1 bit
 	  of error correction.
 
+config MTD_NAND_BENAND
+	bool "Support BENAND (embedded ECC NAND)"
+	default n
+	help
+	  This enables support for BENAND, which is an SLC NAND flash
+	  solution with embedded error correction code (ECC).
+	  currently supports only 128bytes OOB type.
+	  In the read sequence, "status read command" is executed to check
+	  the ECC status after read data.
+	  The write sequence is the same as raw write.
+
 config MTD_SM_COMMON
 	tristate
 	default n
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 2cbd091..f58dee8 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -5,6 +5,7 @@
 obj-$(CONFIG_MTD_NAND)			+= nand.o
 obj-$(CONFIG_MTD_NAND_ECC)		+= nand_ecc.o
 obj-$(CONFIG_MTD_NAND_BCH)		+= nand_bch.o
+obj-$(CONFIG_MTD_NAND_BENAND)		+= nand_benand.o
 obj-$(CONFIG_MTD_NAND_IDS)		+= nand_ids.o
 obj-$(CONFIG_MTD_SM_COMMON) 		+= sm_common.o
 
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1a03b7f..9cbef8c 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -43,6 +43,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/nand_bch.h>
+#include <linux/mtd/nand_benand.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/leds.h>
@@ -3076,6 +3077,11 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 		extid >>= 2;
 		/* Get buswidth information */
 		*busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+
+		/* check BENAND (embedded ECC) */
+		if (id_data[0] == NAND_MFR_TOSHIBA &&
+		    (id_data[4] & NAND_ECCENGINE))
+			nand_benand_setupecc(mtd, &(chip->ecc.mode));
 	}
 }
 
@@ -3530,6 +3536,25 @@ int nand_scan_tail(struct mtd_info *mtd)
 			chip->ecc.bytes * 8 / fls(8 * chip->ecc.size);
 		break;
 
+	case NAND_ECC_BENAND:
+		if (!IS_ENABLED(CONFIG_MTD_NAND_BENAND)) {
+			pr_warn("CONFIG_MTD_BENAND not enabled\n");
+			BUG();
+		}
+
+		chip->ecc.read_page = nand_read_page_benand;
+		chip->ecc.write_page = nand_write_page_raw;
+		chip->ecc.read_page_raw = nand_read_page_raw;
+		chip->ecc.write_page_raw = nand_write_page_raw;
+		chip->ecc.read_oob = nand_read_oob_std;
+		chip->ecc.write_oob = nand_write_oob_std;
+
+		if (nand_benand_init(mtd)) {
+			pr_warn("BENAND initialization failed!\n");
+			BUG();
+		}
+		break;
+
 	case NAND_ECC_NONE:
 		pr_warn("NAND_ECC_NONE selected by board driver. "
 			   "This is not recommended!\n");
diff --git a/drivers/mtd/nand/nand_benand.c b/drivers/mtd/nand/nand_benand.c
new file mode 100644
index 0000000..fe8008d
--- /dev/null
+++ b/drivers/mtd/nand/nand_benand.c
@@ -0,0 +1,113 @@
+/*
+ * This file provides functions for BENAND, which is an SLC NAND flash
+ * solution with embedded error correction code (ECC).
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2013
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_benand.h>
+
+static struct nand_ecclayout benand_oob_128 = {
+	.oobfree = {
+		{.offset = 2, .length = 3},
+		{.offset = 18, .length = 3},
+		{.offset = 34, .length = 3},
+		{.offset = 50, .length = 3},
+		{.offset = 66, .length = 3},
+		{.offset = 82, .length = 3},
+		{.offset = 98, .length = 3},
+		{.offset = 114, .length = 3},
+	}
+};
+
+/**
+ * nand_read_page_raw - [Intern] read raw page data with benand.
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
+ *
+ * Not for syndrome calculating ECC controllers, which use a special oob layout.
+ */
+
+int nand_read_page_benand(struct mtd_info *mtd, struct nand_chip *chip,
+			  uint8_t *buf, int oob_required, int page)
+{
+	u8 status;
+	unsigned int max_bitflips = 0;
+
+	chip->ecc.read_page_raw(mtd, chip, buf, oob_required, page);
+
+	/* Check Read Status */
+
+	chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+	status = chip->read_byte(mtd);
+
+	if (status & NAND_STATUS_FAIL)
+		/* uncorrectable error */
+		mtd->ecc_stats.failed++;
+	else if (status & NAND_CHIP_READ_STATUS) {
+		/* correctable error
+		   How many bits have been corrected is unknown.
+		   therefore bitflips is set to ecc.strength. */
+		mtd->ecc_stats.corrected += chip->ecc.strength;
+		max_bitflips = chip->ecc.strength;
+	}
+
+	return max_bitflips;
+}
+EXPORT_SYMBOL(nand_read_page_benand);
+
+void nand_benand_setupecc(struct mtd_info *mtd, nand_ecc_modes_t *mode)
+{
+	/* support only 128bytes OOB type */
+	if (mtd->oobsize == 128)
+		*mode = NAND_ECC_BENAND;
+}
+
+int nand_benand_init(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	chip->ecc.size = mtd->writesize;
+
+	if (mtd->oobsize == 128) {
+		chip->ecc.layout = &benand_oob_128;
+		chip->ecc.bytes = 72;      /* 9B * (4096B/512B) */
+		chip->ecc.strength = 32;   /* 4b * (4096B/512B) */
+	} else {
+		pr_warn("%d unsupported oobsize in benand_init\n",
+			mtd->oobsize);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(nand_benand_init);
+
+MODULE_AUTHOR("TOSHIBA Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("BENAND (embedded ECC NAND) support");
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 24e9159..b01c4bf 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -129,6 +129,7 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 /* Status bits */
 #define NAND_STATUS_FAIL	0x01
 #define NAND_STATUS_FAIL_N1	0x02
+#define NAND_CHIP_READ_STATUS   0x08  /* for BENAND */
 #define NAND_STATUS_TRUE_READY	0x20
 #define NAND_STATUS_READY	0x40
 #define NAND_STATUS_WP		0x80
@@ -143,6 +144,7 @@ typedef enum {
 	NAND_ECC_HW_SYNDROME,
 	NAND_ECC_HW_OOB_FIRST,
 	NAND_ECC_SOFT_BCH,
+	NAND_ECC_BENAND,
 } nand_ecc_modes_t;
 
 /*
@@ -575,6 +577,11 @@ struct nand_chip {
 #define NAND_MFR_MACRONIX	0xc2
 #define NAND_MFR_EON		0x92
 
+/*
+ * 5th ID Data
+ */
+#define NAND_ECCENGINE		(1<<7)  /* ECC engine on chip */
+
 /**
  * struct nand_flash_dev - NAND Flash Device ID Structure
  * @name:	Identify the device type
diff --git a/include/linux/mtd/nand_benand.h b/include/linux/mtd/nand_benand.h
new file mode 100644
index 0000000..a047b6f
--- /dev/null
+++ b/include/linux/mtd/nand_benand.h
@@ -0,0 +1,43 @@
+/*
+ * (C) Copyright TOSHIBA CORPORATION 2013
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file is the header for the NAND BENAND implementation.
+ */
+
+#ifndef __MTD_NAND_BENAND_H__
+#define __MTD_NAND_BENAND_H__
+
+#if defined(CONFIG_MTD_NAND_BENAND)
+
+void nand_benand_setupecc(struct mtd_info *mtd, nand_ecc_modes_t *mode);
+
+int nand_read_page_benand(struct mtd_info *mtd, struct nand_chip *chip,
+			  uint8_t *buf, int oob_required, int page);
+
+int nand_benand_init(struct mtd_info *mtd);
+
+#else /* !CONFIG_MTD_NAND_BENAND */
+
+static inline void nand_benand_setupecc(struct mtd_info *mtd,
+					nand_ecc_modes_t *mode) {}
+
+static inline int nand_read_page_benand(struct mtd_info *mtd,
+					struct nand_chip *chip,
+					uint8_t *buf, int oob_required,
+					int page)
+{
+	return -1;
+}
+
+static inline int nand_benand_init(struct mtd_info *mtd)
+{
+	return -1;
+}
+
+#endif /* CONFIG_MTD_NAND_BENAND */
+#endif /* __MTD_NAND_BENAND_H__ */
