diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index d94c759d3ea7d28923ee233cbe0435988eb5b74f..35df3778f8fdfd2a14af3e594e1f739dc32d9045 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -61,6 +61,11 @@
  *
  */
 
+static unsigned int reliable_mode = 0;
+module_param(reliable_mode, uint, 0);
+MODULE_PARM_DESC(reliable_mode, "Set the docg3 mode (0=normal MLC, 1=fast, "
+		 "2=reliable) : MLC normal operations are in normal mode");
+
 /**
  * struct docg3_oobinfo - DiskOnChip G3 OOB layout
  * @eccbytes: 8 bytes are used (1 for Hamming ECC, 7 for BCH ECC)
@@ -291,19 +296,41 @@ static void doc_write_data_area(struct docg3 *docg3, const void *buf, int len)
 }
 
 /**
- * doc_set_data_mode - Sets the flash to reliable data mode
+ * doc_set_data_mode - Sets the flash to normal or reliable data mode
  * @docg3: the device
  *
  * The reliable data mode is a bit slower than the fast mode, but less errors
  * occur.  Entering the reliable mode cannot be done without entering the fast
  * mode first.
+ *
+ * In reliable mode, pages 2*n and 2*n+1 are clones. Writing to page 0 of blocks
+ * (4,5) make the hardware write also to page 1 of blocks blocks(4,5). Reading
+ * from page 0 of blocks (4,5) or from page 1 of blocks (4,5) gives the same
+ * result, which is a logical and between bytes from page 0 and page 1 (which is
+ * consistent with the fact that writing to a page is _clearing_ bits of that
+ * page).
  */
 static void doc_set_reliable_mode(struct docg3 *docg3)
 {
-	doc_dbg("doc_set_reliable_mode()\n");
-	doc_flash_sequence(docg3, DOC_SEQ_SET_MODE);
-	doc_flash_command(docg3, DOC_CMD_FAST_MODE);
-	doc_flash_command(docg3, DOC_CMD_RELIABLE_MODE);
+	static char *strmode[] = { "normal", "fast", "reliable", "invalid" };
+
+	doc_dbg("doc_set_reliable_mode(%s)\n", strmode[docg3->reliable]);
+	switch (docg3->reliable) {
+	case 0:
+		break;
+	case 1:
+		doc_flash_sequence(docg3, DOC_SEQ_SET_FASTMODE);
+		doc_flash_command(docg3, DOC_CMD_FAST_MODE);
+		break;
+	case 2:
+		doc_flash_sequence(docg3, DOC_SEQ_SET_RELIABLEMODE);
+		doc_flash_command(docg3, DOC_CMD_FAST_MODE);
+		doc_flash_command(docg3, DOC_CMD_RELIABLE_MODE);
+		break;
+	default:
+		doc_err("doc_set_reliable_mode(): invalid mode\n");
+		break;
+	}
 	doc_delay(docg3, 2);
 }
 
@@ -778,18 +805,29 @@ static void doc_read_page_finish(struct docg3 *docg3)
  * @block1: second plane block index calculated
  * @page: page calculated
  * @ofs: offset in page
+ * @reliable: 0 if docg3 in normal mode, 1 if docg3 in fast mode, 2 if docg3 in
+ * reliable mode.
+ *
+ * The calculation is based on the reliable/normal mode. In normal mode, the 64
+ * pages of a block are available. In reliable mode, as pages 2*n and 2*n+1 are
+ * clones, only 32 pages per block are available.
  */
 static void calc_block_sector(loff_t from, int *block0, int *block1, int *page,
-			      int *ofs)
+			      int *ofs, int reliable)
 {
-	uint sector;
+	uint sector, pages_biblock;
+
+	pages_biblock = DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES;
+	if (reliable == 1 || reliable == 2)
+		pages_biblock /= 2;
 
 	sector = from / DOC_LAYOUT_PAGE_SIZE;
-	*block0 = sector / (DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES)
-		* DOC_LAYOUT_NBPLANES;
+	*block0 = sector / pages_biblock * DOC_LAYOUT_NBPLANES;
 	*block1 = *block0 + 1;
-	*page = sector % (DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES);
+	*page = sector % pages_biblock;
 	*page /= DOC_LAYOUT_NBPLANES;
+	if (reliable == 1 || reliable == 2)
+		*page *= 2;
 	if (sector % 2)
 		*ofs = DOC_LAYOUT_PAGE_OOB_SIZE;
 	else
@@ -836,7 +874,8 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
 		return -EINVAL;
 
 	ret = -EINVAL;
-	calc_block_sector(from + len, &block0, &block1, &page, &ofs);
+	calc_block_sector(from + len, &block0, &block1, &page, &ofs,
+			  docg3->reliable);
 	if (block1 > docg3->max_block)
 		goto err;
 
@@ -844,7 +883,8 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
 	ops->retlen = 0;
 	ret = 0;
 	while (!ret && (len > 0 || ooblen > 0)) {
-		calc_block_sector(from, &block0, &block1, &page, &ofs);
+		calc_block_sector(from, &block0, &block1, &page, &ofs,
+			docg3->reliable);
 		nbdata = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE);
 		nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE);
 		ret = doc_read_page_prepare(docg3, block0, block1, page, ofs);
@@ -983,7 +1023,8 @@ static int doc_block_isbad(struct mtd_info *mtd, loff_t from)
 	struct docg3 *docg3 = mtd->priv;
 	int block0, block1, page, ofs, is_good;
 
-	calc_block_sector(from, &block0, &block1, &page, &ofs);
+	calc_block_sector(from, &block0, &block1, &page, &ofs,
+		docg3->reliable);
 	doc_dbg("doc_block_isbad(from=%lld) => block=(%d,%d), page=%d, ofs=%d\n",
 		from, block0, block1, page, ofs);
 
@@ -1015,7 +1056,7 @@ static int doc_get_erase_count(struct docg3 *docg3, loff_t from)
 	doc_dbg("doc_get_erase_count(from=%lld, buf=%p)\n", from, buf);
 	if (from % DOC_LAYOUT_PAGE_SIZE)
 		return -EINVAL;
-	calc_block_sector(from, &block0, &block1, &page, &ofs);
+	calc_block_sector(from, &block0, &block1, &page, &ofs, docg3->reliable);
 	if (block1 > docg3->max_block)
 		return -EINVAL;
 
@@ -1156,14 +1197,15 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info)
 	doc_set_device_id(docg3, docg3->device_id);
 
 	info->state = MTD_ERASE_PENDING;
-	calc_block_sector(info->addr + info->len,
-			  &block0, &block1, &page, &ofs);
+	calc_block_sector(info->addr + info->len, &block0, &block1, &page,
+			  &ofs, docg3->reliable);
 	ret = -EINVAL;
 	if (block1 > docg3->max_block || page || ofs)
 		goto reset_err;
 
 	ret = 0;
-	calc_block_sector(info->addr, &block0, &block1, &page, &ofs);
+	calc_block_sector(info->addr, &block0, &block1, &page, &ofs,
+			  docg3->reliable);
 	doc_set_reliable_mode(docg3);
 	for (len = info->len; !ret && len > 0; len -= mtd->erasesize) {
 		info->state = MTD_ERASING;
@@ -1209,7 +1251,7 @@ static int doc_write_page(struct docg3 *docg3, loff_t to, const u_char *buf,
 	u8 syn[DOC_ECC_BCH_SIZE], hamming;
 
 	doc_dbg("doc_write_page(to=%lld)\n", to);
-	calc_block_sector(to, &block0, &block1, &page, &ofs);
+	calc_block_sector(to, &block0, &block1, &page, &ofs, docg3->reliable);
 
 	doc_set_device_id(docg3, docg3->device_id);
 	ret = doc_reset_seq(docg3);
@@ -1396,7 +1438,8 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
 		return -EINVAL;
 
 	ret = -EINVAL;
-	calc_block_sector(ofs + len, &block0, &block1, &page, &pofs);
+	calc_block_sector(ofs + len, &block0, &block1, &page, &pofs,
+			  docg3->reliable);
 	if (block1 > docg3->max_block)
 		goto err;
 
@@ -1638,6 +1681,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
 
 	cfg = doc_register_readb(docg3, DOC_CONFIGURATION);
 	docg3->if_cfg = (cfg & DOC_CONF_IF_CFG ? 1 : 0);
+	docg3->reliable = reliable_mode;
 
 	switch (chip_id) {
 	case DOC_CHIPID_G3:
@@ -1649,7 +1693,11 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
 	mtd->size = (docg3->max_block + 1) * DOC_LAYOUT_BLOCK_SIZE;
+	if (docg3->reliable == 2)
+		mtd->size /= 2;
 	mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES;
+	if (docg3->reliable == 2)
+		mtd->erasesize /= 2;
 	mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
 	mtd->oobsize = DOC_LAYOUT_OOB_SIZE;
 	mtd->owner = THIS_MODULE;
diff --git a/drivers/mtd/devices/docg3.h b/drivers/mtd/devices/docg3.h
index cd70b181f797950398656661d0ab6296194670f5..07182f9d484db9461c99074f9cbb1f746beac70a 100644
--- a/drivers/mtd/devices/docg3.h
+++ b/drivers/mtd/devices/docg3.h
@@ -135,7 +135,8 @@
  */
 #define DOC_SEQ_RESET			0x00
 #define DOC_SEQ_PAGE_SIZE_532		0x03
-#define DOC_SEQ_SET_MODE		0x09
+#define DOC_SEQ_SET_FASTMODE		0x05
+#define DOC_SEQ_SET_RELIABLEMODE	0x09
 #define DOC_SEQ_READ			0x12
 #define DOC_SEQ_SET_PLANE1		0x0e
 #define DOC_SEQ_SET_PLANE2		0x10
@@ -257,6 +258,11 @@
  * @base: mapped IO space
  * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
  * @if_cfg: if true, reads are on 16bits, else reads are on 8bits
+
+ * @reliable: if 0, docg3 in normal mode, if 1 docg3 in fast mode, if 2 in
+ *            reliable mode
+ *            Fast mode implies more errors than normal mode.
+ *            Reliable mode implies that page 2*n and 2*n+1 are clones.
  * @bbt: bad block table cache
  * @oob_write_ofs: offset of the MTD where this OOB should belong (ie. in next
  *                 page_write)
@@ -270,6 +276,7 @@ struct docg3 {
 	void __iomem *base;
 	unsigned int device_id:4;
 	unsigned int if_cfg:1;
+	unsigned int reliable:2;
 	int max_block;
 	u8 *bbt;
 	loff_t oob_write_ofs;