diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index cfe288a..c528024 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -55,6 +55,12 @@ config MTD_NAND_TOTO
 	help
 	  Support for NAND flash on Texas Instruments Toto platform.
 
+config MTD_NAND_RB500
+	tristate "NAND Flash device on RB500 board"
+	depends on MTD_NAND
+	help
+	  Support for NAND flash on RB500 platform.
+
 config MTD_NAND_IDS
 	tristate
 
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 4174202..2be57c1 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_MTD_NAND_IDS)		+= nand_ids.
 
 obj-$(CONFIG_MTD_NAND_SPIA)		+= spia.o
 obj-$(CONFIG_MTD_NAND_TOTO)		+= toto.o
+obj-$(CONFIG_MTD_NAND_RB500)		+= rbmipsnand.o
 obj-$(CONFIG_MTD_NAND_AUTCPU12)		+= autcpu12.o
 obj-$(CONFIG_MTD_NAND_EDB7312)		+= edb7312.o
 obj-$(CONFIG_MTD_NAND_AU1550)		+= au1550nd.o
diff --git a/drivers/mtd/nand/rbmipsnand.c b/drivers/mtd/nand/rbmipsnand.c
new file mode 100644
index 0000000..6f7452a
--- /dev/null
+++ b/drivers/mtd/nand/rbmipsnand.c
@@ -0,0 +1,211 @@
+#include <linux/init.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bootinfo.h>
+//#include <asm/rb/rb100.h>
+
+#define IDT434_REG_BASE ((volatile void *) KSEG1ADDR(0x18000000))
+
+#define SMEM1(x) (*((volatile unsigned char *) (KSEG1ADDR(SMEM1_BASE) + x)))
+
+#define GPIOF 0x050000
+#define GPIOC 0x050004
+#define GPIOD 0x050008
+
+#define GPIO_RDY (1 << 0x08)
+#define GPIO_WPX (1 << 0x09)
+#define GPIO_ALE (1 << 0x0a)
+#define GPIO_CLE (1 << 0x0b)
+
+#define NAND_RW_REG	0x0	//data register
+#define NAND_SET_CEn	0x1	//CE# low
+#define NAND_CLR_CEn	0x2	//CE# high
+#define NAND_CLR_CLE	0x3	//CLE low
+#define NAND_SET_CLE	0x4	//CLE high
+#define NAND_CLR_ALE	0x5	//ALE low
+#define NAND_SET_ALE	0x6	//ALE high
+#define NAND_SET_SPn	0x7	//SP# low (use spare area)
+#define NAND_CLR_SPn	0x8	//SP# high (do not use spare area)
+#define NAND_SET_WPn	0x9	//WP# low
+#define NAND_CLR_WPn	0xA	//WP# high
+#define NAND_STS_REG	0xB	//Status register
+
+#define DEV2BASE 0x010020
+
+#define LO_WPX   (1 << 0)
+#define LO_ALE   (1 << 1)
+#define LO_CLE   (1 << 2)
+#define LO_CEX   (1 << 3)
+#define LO_FOFF  (1 << 5)
+#define LO_SPICS (1 << 6)
+#define LO_ULED  (1 << 7)
+
+#define MEM32(x) *((volatile unsigned *) (x))
+static void __iomem *p_nand;
+
+extern void changeLatchU5(unsigned char orMask, unsigned char nandMask);
+
+static int rb500_dev_ready(struct mtd_info *mtd) {
+    return MEM32(IDT434_REG_BASE + GPIOD) & GPIO_RDY;
+}
+/*
+static int rb100_dev_ready(struct mtd_info *mtd) {
+    return SMEM1(NAND_STS_REG) & 0x80;
+}
+*/
+static unsigned long iflags = 0;
+static int ioff = 0;
+/*
+static void rbmips_hwcontrol400(struct mtd_info *mtd, int cmd) {
+    switch (cmd) {
+    case NAND_CTL_SETCLE:
+	MEM32(IDT434_REG_BASE + GPIOD) |= GPIO_CLE;
+        break;
+    case NAND_CTL_CLRCLE:
+	MEM32(IDT434_REG_BASE + GPIOD) &= ~GPIO_CLE;
+        break;
+    case NAND_CTL_SETALE:
+	MEM32(IDT434_REG_BASE + GPIOD) |= GPIO_ALE;
+        break;
+    case NAND_CTL_CLRALE:
+	MEM32(IDT434_REG_BASE + GPIOD) &= ~GPIO_ALE;
+        break;
+    default:
+	break;
+    }
+}
+*/
+static void rbmips_hwcontrol500(struct mtd_info *mtd, int cmd) {
+    switch (cmd) {
+    case NAND_CTL_SETCLE:
+	changeLatchU5(LO_CLE, 0);
+        break;
+    case NAND_CTL_CLRCLE:
+	changeLatchU5(0, LO_CLE);
+        break;
+    case NAND_CTL_SETALE:
+	changeLatchU5(LO_ALE, 0);
+        break;
+    case NAND_CTL_CLRALE:
+	changeLatchU5(0, LO_ALE);
+        break;
+    default:
+        break;
+    }
+}
+/*
+static void rbmips_hwcontrol100(struct mtd_info *mtd, int cmd){
+    switch(cmd){
+    case NAND_CTL_SETCLE: 
+	SMEM1(NAND_SET_CLE) = 0x01; 
+	break;
+    case NAND_CTL_CLRCLE: 
+	SMEM1(NAND_CLR_CLE) = 0x01; 
+	break;
+    case NAND_CTL_SETALE: 
+	SMEM1(NAND_SET_ALE) = 0x01; 
+	break;
+    case NAND_CTL_CLRALE: 
+	SMEM1(NAND_CLR_ALE) = 0x01; 
+	break;
+    case NAND_CTL_SETNCE: 
+	SMEM1(NAND_SET_CEn) = 0x01; 
+	break;
+    case NAND_CTL_CLRNCE: 
+	SMEM1(NAND_CLR_CEn) = 0x01; 
+	break;
+    }
+}
+*/
+static struct mtd_partition partition_info[] = {
+    {
+        name: "RouterBoard NAND Boot",
+        offset: 0,
+	size: 4 * 1024 * 1024
+    },
+    {
+        name: "RouterBoard NAND Main",
+	offset: MTDPART_OFS_NXTBLK,
+	size: MTDPART_SIZ_FULL
+    }
+};
+
+static struct mtd_info rmtd;
+static struct nand_chip rnand;
+
+static unsigned init_ok = 0;
+
+unsigned get_rbnand_block_size(void) {
+	if (init_ok) return rmtd.oobblock; else return 0;
+}
+
+EXPORT_SYMBOL(get_rbnand_block_size);
+
+int __init rbmips_init(void) {
+	memset(&rmtd, 0, sizeof(rmtd));
+	memset(&rnand, 0, sizeof(rnand));
+/*
+	if (is_rb500()) {
+		if (is_rb400()) {
+			printk("RB400 nand\n");
+			MEM32(IDT434_REG_BASE + GPIOD) |= GPIO_WPX;
+			MEM32(IDT434_REG_BASE + GPIOD) &= ~GPIO_CLE;
+			MEM32(IDT434_REG_BASE + GPIOD) &= ~GPIO_ALE;
+			rnand.hwcontrol = rbmips_hwcontrol400;
+		} else {
+*/		
+			printk("RB500 nand\n");
+			changeLatchU5(LO_WPX | LO_FOFF | LO_CEX,
+				      LO_ULED | LO_ALE | LO_CLE);
+			rnand.hwcontrol = rbmips_hwcontrol500;
+//		}
+    
+		rnand.dev_ready = rb500_dev_ready;
+		rnand.IO_ADDR_W = (unsigned char *)
+			KSEG1ADDR(MEM32(IDT434_REG_BASE + DEV2BASE));
+		rnand.IO_ADDR_R = rnand.IO_ADDR_W;
+/*	} else if (is_rb100()) {
+		printk("RB100 nand\n");
+		MEM32(0xB2000064) = 0x100;
+		MEM32(0xB2000008) = 0x1;
+		SMEM1(NAND_SET_SPn) = 0x01; 
+		SMEM1(NAND_CLR_WPn) = 0x01; 
+		rnand.IO_ADDR_R = (unsigned char *)KSEG1ADDR(SMEM1_BASE);
+		rnand.IO_ADDR_W = rnand.IO_ADDR_R;
+		rnand.hwcontrol = rbmips_hwcontrol100;
+		rnand.dev_ready = rb100_dev_ready;
+	}
+*/
+	p_nand = (void __iomem *)ioremap(( void*)0x18a20000, 0x1000);
+	if (!p_nand) {
+		printk("RBnand Unable ioremap buffer");
+		return -ENXIO;
+	}
+	rnand.eccmode = NAND_ECC_SOFT;
+	rnand.chip_delay = 25;
+	rnand.options |= NAND_NO_AUTOINCR;
+	rmtd.priv = &rnand;
+
+	int *b = ( int *)KSEG1ADDR( 0x18010020);
+	printk( "dev2base 0x%08x mask 0x%08x c 0x%08x tc 0x%08x\n", b[ 0], b[ 1], b[ 2], b[ 3]);
+
+	if (nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1)
+	    && nand_scan(&rmtd, 1)  && nand_scan(&rmtd, 1)) {
+		printk("RBxxx nand device not found");
+		iounmap ((void *)p_nand);
+		return -ENXIO;
+	}
+
+	add_mtd_partitions(&rmtd, partition_info, 2);
+	init_ok = 1;
+	return 0;
+}
+
+module_init(rbmips_init);
+
+
+
+
+