Index: drivers/mtd/nand/diskonchip.c
===================================================================
RCS file: /cvs/linux/kernel26/drivers/mtd/nand/diskonchip.c,v
retrieving revision 1.7
diff -u -r1.7 diskonchip.c
--- drivers/mtd/nand/diskonchip.c	8 Nov 2006 23:13:19 -0000	1.7
+++ drivers/mtd/nand/diskonchip.c	18 Nov 2006 00:19:23 -0000
@@ -61,6 +61,10 @@
 	0xff000000,
 #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
 	0xff000000,
+#elif defined(CONFIG_MACH_OMAP_H6300)
+        0x00000000,
+#elif defined(CONFIG_MACH_H4000)
+        0x00000000,
 #else
 #warning Unknown architecture for DiskOnChip. No default probe locations defined
 #endif
@@ -114,6 +118,9 @@
 static int show_firmware_partition = 0;
 module_param(show_firmware_partition, int, 0);
 
+static int floor = 0;
+module_param(floor, int, 0);
+
 #ifdef MTD_NAND_DISKONCHIP_BBTWRITE
 static int inftl_bbt_write = 1;
 #else
@@ -1483,6 +1490,146 @@
 	}
 }
 
+/************************************************************************/
+/***********************   MDoC+ 32MiB interface ************************/
+static void mdocplus32_select_chip(struct mtd_info *mtd, int chip)
+{
+    struct nand_chip *this = mtd->priv;
+    struct doc_priv *doc = this->priv;
+    void __iomem *docptr = doc->virtadr;
+
+    if (debug)
+        printk("select chip (%d)\n", chip);
+
+    if (chip == -1) {
+        /* Disable flash internally */
+        WriteDOC(0, docptr, Mplus_FlashSelect);
+        return;
+    }
+
+	/* Select teh device */
+	WriteDOC(doc->curfloor, docptr, Mplus_DeviceSelect);
+
+    /* Assert ChipEnable and deassert WriteProtect */
+    WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);
+    this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+}
+
+static void mdocplus32_readbuf(struct mtd_info *mtd,
+                u_char *buf, int len)
+{
+    struct nand_chip *this = mtd->priv;
+    struct doc_priv *doc = this->priv;
+    void __iomem *docptr = doc->virtadr;
+    int i;
+    uint16_t *buff  = (uint16_t *) buf;
+    int      size   = len >> 1;
+    int      loc    = DoC_Mil_CDSN_IO;
+
+    if (debug)printk("readbuf of %d bytes: ", len);
+    for (i=0; i < size; i++, loc += 2) {
+        buff[i] = ReadWDOC_(docptr ,loc);
+        if (debug && i < 8)
+            printk("%04x ", buff[i]);
+    }
+    if (debug) printk("\n");
+}
+
+static void mdocplus32_writebuf(struct mtd_info *mtd,
+                 const u_char *buf, int len)
+{
+    struct nand_chip *this = mtd->priv;
+    struct doc_priv *doc = this->priv;
+    void __iomem *docptr = doc->virtadr;
+    int i;
+    uint16_t *buff  = (uint16_t *) buf;
+    int      size   = len >> 1;
+    int      loc    = DoC_Mil_CDSN_IO;
+
+    if (debug)printk("writebuf of %d bytes: ", len);
+    for (i=0; i < size; i++, loc += 2) {
+        WriteWDOC_(buff[i], docptr ,loc);
+        if (debug && i < 8)
+            printk("%02x ", buf[i]);
+    }
+    if (debug) printk("\n");
+}
+
+static int mdocplus32_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+                         		uint8_t *buf)
+{
+	struct nand_chip *this = mtd->priv;
+    struct doc_priv *doc = this->priv;
+    void __iomem *docptr = doc->virtadr;
+    uint8_t *p = buf;
+    uint8_t *oob = chip->oob_poi;
+	int     stat;
+
+	ReadWDOC(docptr, Mplus_ReadPipeInit);
+	ReadWDOC(docptr, Mplus_ReadPipeInit);
+
+	chip->ecc.hwctl(mtd, NAND_ECC_READ);
+    chip->read_buf(mtd, p, 512);
+
+	chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
+    chip->read_buf(mtd, oob, 6);
+    stat = chip->ecc.correct(mtd, p, oob, NULL);
+
+	if (stat == -1)
+   		mtd->ecc_stats.failed++;
+  	else
+    	mtd->ecc_stats.corrected += stat;
+
+  	oob += 6;
+	chip->read_buf(mtd, oob, 4);
+	oob += 4;
+
+	p += 512;
+	chip->ecc.hwctl(mtd, NAND_ECC_READ);
+    chip->read_buf(mtd, p, 512);
+
+	chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
+    chip->read_buf(mtd, oob, 6);
+    stat = chip->ecc.correct(mtd, p, oob, NULL);
+
+    if (stat == -1)
+        mtd->ecc_stats.failed++;
+    else
+        mtd->ecc_stats.corrected += stat;
+	oob += 6;
+
+   	chip->read_buf(mtd, oob, 14);
+	oob += 14;
+	*((uint16_t *) oob) = ReadWDOC_(docptr,DoC_Mplus_LastDataRead);
+
+    return 0;
+}
+
+static inline int __init mdocplus32_init(struct mtd_info *mtd)
+{
+    struct nand_chip *this = mtd->priv;
+    struct doc_priv *doc = this->priv;
+
+    this->read_byte   	= doc2001plus_read_byte;
+    this->write_buf   	= mdocplus32_writebuf;
+    this->read_buf 	  	= mdocplus32_readbuf;
+    this->verify_buf  	= doc2001plus_verifybuf;
+    this->scan_bbt 	  	= inftl_scan_bbt;
+    this->cmd_ctrl 	  	= NULL;
+    this->select_chip 	= mdocplus32_select_chip;
+    this->cmdfunc 	  	= doc2001plus_command;
+    this->ecc.hwctl   	= doc2001plus_enable_hwecc;
+	this->ecc.read_page = mdocplus32_read_page;
+	this->options      |= (NAND_INTERLEAVE | NAND_BUSWIDTH_16);
+
+	doc->curfloor		 = floor;
+    doc->chips_per_floor = 1;
+    mtd->name = "DiskOnChip Millennium Plus";
+
+    return 1;
+}
+/*******************************************************************/
+
 static inline int __init doc2001plus_init(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
@@ -1569,6 +1716,9 @@
 		WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
 		mdelay(1);
 
+		/* Select the device */
+		WriteDOC(floor, virtadr, Mplus_DeviceSelect);
+
 		ChipID = ReadDOC(virtadr, ChipID);
 
 		switch (ChipID) {
@@ -1576,7 +1726,8 @@
 			reg = DoC_Mplus_Toggle;
 			break;
 		case DOC_ChipID_DocMilPlus32:
-			printk(KERN_ERR "DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n");
+			reg = DoC_Mplus_Toggle;
+            break;
 		default:
 			ret = -ENODEV;
 			goto notfound;
@@ -1680,6 +1831,8 @@
 		numchips = doc2000_init(mtd);
 	else if (ChipID == DOC_ChipID_DocMilPlus16)
 		numchips = doc2001plus_init(mtd);
+	else if (ChipID == DOC_ChipID_DocMilPlus32)
+		numchips = mdocplus32_init(mtd);
 	else
 		numchips = doc2001_init(mtd);
 
Index: drivers/mtd/nand/nand_base.c
===================================================================
RCS file: /cvs/linux/kernel26/drivers/mtd/nand/nand_base.c,v
retrieving revision 1.14
diff -u -r1.14 nand_base.c
--- drivers/mtd/nand/nand_base.c	8 Nov 2006 23:13:19 -0000	1.14
+++ drivers/mtd/nand/nand_base.c	18 Nov 2006 00:19:24 -0000
@@ -2167,6 +2167,10 @@
 {
 	struct nand_flash_dev *type = NULL;
 	int i, dev_id, maf_idx;
+	int interleave;
+
+	/* Check in interleave used */
+	interleave = (chip->options & NAND_INTERLEAVE) ? 1 : 0;
 
 	/* Select the device */
 	chip->select_chip(mtd, 0);
@@ -2217,10 +2221,10 @@
 		/*
 		 * Old devices have chip data hardcoded in the device id table
 		 */
-		mtd->erasesize = type->erasesize;
-		mtd->writesize = type->pagesize;
+		mtd->erasesize = type->erasesize << interleave;
+		mtd->writesize = type->pagesize << interleave;
 		mtd->oobsize = mtd->writesize / 32;
-		busw = type->options & NAND_BUSWIDTH_16;
+		busw = interleave ? NAND_BUSWIDTH_16 : type->options & NAND_BUSWIDTH_16;
 	}
 
 	/* Try to identify manufacturer */
Index: include/linux/mtd/doc2000.h
===================================================================
RCS file: /cvs/linux/kernel26/include/linux/mtd/doc2000.h,v
retrieving revision 1.5
diff -u -r1.5 doc2000.h
--- include/linux/mtd/doc2000.h	23 Aug 2006 18:43:36 -0000	1.5
+++ include/linux/mtd/doc2000.h	18 Nov 2006 00:19:24 -0000
@@ -73,6 +73,7 @@
 #define DoC_Mplus_Toggle		0x1046
 #define DoC_Mplus_DownloadStatus	0x1074
 #define DoC_Mplus_CtrlConfirm		0x1076
+#define DoC_Mplus_NprotectionStatus   0x1078
 #define DoC_Mplus_Power			0x1fff
 
 /* How to access the device?
@@ -80,7 +81,7 @@
  * On PPC, it's mmap'd and 16-bit wide.
  * Others use readb/writeb
  */
-#if defined(__arm__)
+#if 0 && defined(__arm__) && !defined(CONFIG_MACH_OMAP_H6300)
 #define ReadDOC_(adr, reg)      ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2))))
 #define WriteDOC_(d, adr, reg)  do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0)
 #define DOC_IOREMAP_LEN 0x8000
@@ -91,6 +92,8 @@
 #else
 #define ReadDOC_(adr, reg)      readb((void __iomem *)(adr) + (reg))
 #define WriteDOC_(d, adr, reg)  writeb(d, (void __iomem *)(adr) + (reg))
+#define ReadWDOC_(adr, reg)      readw((void __iomem *)(adr) + (reg))
+#define WriteWDOC_(d, adr, reg)  writew(d, (void __iomem *)(adr) + (reg))
 #define DOC_IOREMAP_LEN 0x2000
 
 #endif
@@ -103,6 +106,9 @@
 #define ReadDOC(adr, reg)      ReadDOC_(adr,DoC_##reg)
 #define WriteDOC(d, adr, reg)  WriteDOC_(d,adr,DoC_##reg)
 
+#define ReadWDOC(adr, reg)      ReadWDOC_(adr,DoC_##reg)
+#define WriteWDOC(d, adr, reg)  WriteWDOC_(d,adr,DoC_##reg)
+
 #define DOC_MODE_RESET 		0
 #define DOC_MODE_NORMAL 	1
 #define DOC_MODE_RESERVED1 	2
Index: include/linux/mtd/nand.h
===================================================================
RCS file: /cvs/linux/kernel26/include/linux/mtd/nand.h,v
retrieving revision 1.14
diff -u -r1.14 nand.h
--- include/linux/mtd/nand.h	8 Nov 2006 23:17:42 -0000	1.14
+++ include/linux/mtd/nand.h	18 Nov 2006 00:19:24 -0000
@@ -505,6 +505,13 @@
 /* Search good / bad pattern on the first and the second page */
 #define NAND_BBT_SCAN2NDPAGE	0x00004000
 
+/* Interleave architecture allows 16bits internal access
+ * instead of 8bit internal access to arrauy of daul NAND flash,
+ * which means array of two 8bit NAND flash will be seen as one
+ * large 16bit NAND flash.
+ */
+#define NAND_INTERLEAVE     0x00100000
+
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS	4
 
