Index: linux-2.6.21/drivers/mtd/maps/Kconfig
===================================================================
--- linux-2.6.21.orig/drivers/mtd/maps/Kconfig	2007-04-26 00:08:32.000000000 -0300
+++ linux-2.6.21/drivers/mtd/maps/Kconfig	2007-04-26 20:49:33.000000000 -0300
@@ -595,6 +595,28 @@
 	help
 	  This enables access to the flash chip on the Sharp SL Series of PDAs.
 
+config MTD_EZX
+	tristate "Map driver for Motorola EZX Platform"
+	depends on MTD && PXA_EZX
+
+if MTD_EZX
+
+choice
+	prompt "Select partition mapping for EZX platform"
+
+config MTD_EZX_A780
+	bool "A780/E680 Original Mapping"
+
+config MTD_EZX_A780_ALTERNATE
+	bool "A780/E680 Alternate Mapping for BLOB2"
+
+config MTD_EZX_E2
+	bool "E2 Original Mapping"
+
+endchoice
+
+endif
+
 config MTD_PLATRAM
 	tristate "Map driver for platform device RAM (mtd-ram)"
 	depends on MTD
Index: linux-2.6.21/drivers/mtd/maps/Makefile
===================================================================
--- linux-2.6.21.orig/drivers/mtd/maps/Makefile	2007-04-26 00:08:32.000000000 -0300
+++ linux-2.6.21/drivers/mtd/maps/Makefile	2007-04-26 20:30:30.000000000 -0300
@@ -72,3 +72,4 @@
 obj-$(CONFIG_MTD_OMAP_NOR)	+= omap_nor.o
 obj-$(CONFIG_MTD_MTX1)		+= mtx-1_flash.o
 obj-$(CONFIG_MTD_TQM834x)	+= tqm834x.o
+obj-$(CONFIG_MTD_EZX)		+= ezx-flash.o
Index: linux-2.6.21/drivers/mtd/maps/ezx-flash.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.21/drivers/mtd/maps/ezx-flash.c	2007-04-26 20:30:30.000000000 -0300
@@ -0,0 +1,227 @@
+/*
+ * $Id:  $
+ *
+ * Map driver for the PXA27x
+ *
+ * Author:	Harald Welte
+ * Copyright:	(C) 2001 MontaVista Software Inc.
+ *
+ * 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.
+ *
+ * Mar 3, 2007 - (Daniel Ribeiro) Alternate partition table
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/mainstone.h>
+
+#define WINDOW_ADDR		0x0
+#define WINDOW_SIZE		(32*1024*1024)
+#define WINDOW_CACHE_ADDR	0x0
+#define WINDOW_CACHE_SIZE	0x1a00000
+
+static void pxa27x_map_inval_cache(struct map_info *map, unsigned long from,
+				   ssize_t len)
+{
+#if 0
+	unsigned long endaddress, i, j;
+	endaddress = from + len -1;
+	from &= ~(32-1);
+	endaddress &= ~(32-1);
+	for (i = from; i <= endaddress; i += 32)
+		asm("mcr	p15, 0, %0, c7, c6, 1"::"r"(i));
+
+	asm(	"mrc p15, 0, %0, c2, c0, 0\n"
+		"mov %0, %0\n"
+		"sub pc, pc #4"
+		:"=r"(j));
+#else
+	consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE);
+#endif
+}
+
+
+struct map_info pxa27x_map = {
+	.name		= "PXA27x flash",
+	.size		= WINDOW_SIZE,
+	.phys		= WINDOW_ADDR,
+	.inval_cache	= &pxa27x_map_inval_cache,
+};
+
+#if defined CONFIG_MTD_EZX_A780_ALTERNATE
+static struct mtd_partition pxa27x_partitions[] = {
+	{
+		.name		= "Bootloader (RO)",
+		.size		= 0x00020000,
+		.offset		= 0,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "Bootloader 2",
+		.size		= 0x00020000,
+		.offset		= 0x00020000,
+	} , {
+		.name		= "Kernel 1",
+		.size		= 0x000e0000, // 896KB
+		.offset		= 0x00040000,
+	} , {
+		.name		= "rootfs",
+		.size		= 0x01760000,
+		.offset		= 0x00120000,
+	} , {
+		.name		= "Kernel 2",
+		.size		= 0x00180000, // 1.5MB
+		.offset		= 0x01880000,
+	} , {
+		.name		= "VFM_Filesystem",
+		.size		= 0x005a0000,
+		.offset		= 0x01a00000,
+	} , {
+		.name		= "setup",
+		.size		= 0x00020000,
+		.offset		= 0x01fa0000,
+	} , {
+		.name		= "Logo",
+		.size		= 0x00020000,
+		.offset		= 0x01fc0000,
+	},
+};
+#elif defined CONFIG_MTD_EZX_A780
+static struct mtd_partition pxa27x_partitions[] = {
+	{
+		.name		= "Bootloader",
+		.size		= 0x00020000,
+		.offset		= 0,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "Kernel",
+		.size		= 0x000e0000,
+		.offset		= 0x00020000,
+	} , {
+		.name		= "rootfs",
+		.size		= 0x018e0000,
+		.offset		= 0x00120000,
+	} , {
+		.name		= "VFM_Filesystem",
+		.size		= 0x00580000,
+		.offset		= 0x01a00000,
+	} , {
+		.name		= "setup",
+		.size		= 0x00020000,
+		.offset		= 0x01fa0000,
+	} , {
+		.name		= "Logo",
+		.size		= 0x00020000,
+		.offset		= 0x01fc0000,
+	},
+};
+#else
+#error "please define partition for this PXA27x implementation"
+#endif
+
+
+static struct mtd_info *mymtd;
+static struct mtd_partition *parsed_parts;
+
+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
+
+static int __init init_pxa27x(void)
+{
+	struct mtd_partition *parts;
+	int nb_parts = 0;
+	int parsed_nr_parts = 0;
+	char *part_type = "static";
+
+	pxa27x_map.bankwidth = (BOOT_DEF & 1) ? 2 : 4;
+
+	printk("Probing PXA27x flash at physical address 0x%08x (%d-bit bankwidth)\n",
+		WINDOW_ADDR, pxa27x_map.bankwidth * 8);
+	pxa27x_map.virt = ioremap(pxa27x_map.phys, pxa27x_map.size);
+
+	if (!pxa27x_map.virt) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+
+	mymtd = do_map_probe("cfi_probe", &pxa27x_map);
+	if (!mymtd) {
+		iounmap((void *)pxa27x_map.virt);
+		return -ENXIO;
+	}
+	mymtd->owner = THIS_MODULE;
+
+#if 0
+	/* ioremap the first flash chip as cacheable */
+	pxa27x_map.cached = ioremap_cached(pxa27x_map.phys, pxa27x_map.size);
+	if (!pxa27x_map.cached) {
+		printk("Failed to do cacheable-ioremap\n");
+		iounmap((void *)pxa27x_map.virt);
+		return -EIO;
+	}
+#endif
+	simple_map_init(&pxa27x_map);
+
+	if (parsed_nr_parts == 0) {
+		int ret = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0);
+
+		if (ret > 0) {
+			part_type = "RedBoot";
+			parsed_nr_parts = ret;
+		}
+	}
+
+	if (parsed_nr_parts > 0) {
+		parts = parsed_parts;
+		nb_parts = parsed_nr_parts;
+	} else {
+		parts = pxa27x_partitions;
+		nb_parts = ARRAY_SIZE(pxa27x_partitions);
+	}
+
+	if (nb_parts) {
+		printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+		add_mtd_partitions(mymtd, parts, nb_parts);
+	} else {
+		add_mtd_device(mymtd);
+	}
+#if 0
+	if (ret = ezx_partition_init())
+#endif
+	return 0;
+}
+
+static void __exit cleanup_pxa27x(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+		if (parsed_parts)
+			kfree(parsed_parts);
+	}
+	if (pxa27x_map.virt)
+		iounmap((void *)pxa27x_map.virt);
+	if (pxa27x_map.cached)
+		iounmap((void *)pxa27x_map.cached);
+	return;
+}
+
+module_init(init_pxa27x);
+module_exit(cleanup_pxa27x);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("MTD map driver for Motorola EZX platform");