Subject: [@num@/@total@] i.MX2 family: Adding basic platform support
From: Juergen Beisert <j.beisert@pengutronix.de>

This patch adds basic platform support for the mxc2 family of procesors.

TODO:
 - get a sign from freescale for the patch

Signed-off-by: Juergen Beisert <j.beisert@pengutronix.de>

---

 arch/arm/plat-mxc/Kconfig                   |    8
 arch/arm/plat-mxc/Makefile                  |    4
 arch/arm/plat-mxc/clock.c                   |  435 +++++++++
 arch/arm/plat-mxc/dma_mx2.c                 | 1251 ++++++++++++++++++++++++++++
 arch/arm/plat-mxc/gpio.c                    |  464 ++++++++++
 arch/arm/plat-mxc/irq.c                     |  172 +++
 include/asm-arm/arch-mxc/clock.h            |   69 +
 include/asm-arm/arch-mxc/common.h           |    5
 include/asm-arm/arch-mxc/dma.h              |  171 +++
 include/asm-arm/arch-mxc/entry-macro-mx27.S |   41
 include/asm-arm/arch-mxc/hardware.h         |   78 +
 include/asm-arm/arch-mxc/iim.h              |   71 +
 include/asm-arm/arch-mxc/io.h               |   12
 include/asm-arm/arch-mxc/irqs.h             |   20
 include/asm-arm/arch-mxc/memory.h           |   98 ++
 include/asm-arm/arch-mxc/mx27.h             |  338 +++++++
 include/asm-arm/arch-mxc/mx2_dma.h          |  216 ++++
 include/asm-arm/arch-mxc/mxc.h              |  193 ++--
 include/asm-arm/arch-mxc/vmalloc.h          |   20
 19 files changed, 3531 insertions(+), 135 deletions(-)

Index: arch/arm/plat-mxc/irq.c
===================================================================
--- arch/arm/plat-mxc/irq.c.orig
+++ arch/arm/plat-mxc/irq.c
@@ -17,7 +17,98 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
-#include <asm/arch/common.h>
+
+/*
+ *****************************************
+ * EDIO Registers                        *
+ *****************************************
+ */
+#ifdef EDIO_BASE_ADDR
+
+static const int mxc_edio_irq_map[] = {
+	INT_EXT_INT0,
+	INT_EXT_INT1,
+	INT_EXT_INT2,
+	INT_EXT_INT3,
+	INT_EXT_INT4,
+	INT_EXT_INT5,
+	INT_EXT_INT6,
+	INT_EXT_INT7,
+};
+
+static u32 edio_irq_type[MXC_MAX_EXT_LINES] = {
+	IRQT_LOW,
+	IRQT_LOW,
+	IRQT_LOW,
+	IRQT_LOW,
+	IRQT_LOW,
+	IRQT_LOW,
+	IRQT_LOW,
+	IRQT_LOW,
+};
+
+static int irq_to_edio(int irq)
+{
+	int i;
+	int edio = -1;
+
+	for (i = 0; i < MXC_MAX_EXT_LINES; i++) {
+		if (mxc_edio_irq_map[i] == irq) {
+			edio = i;
+			break;
+		}
+	}
+	return edio;
+}
+
+static void mxc_irq_set_edio_level(int irq, int trigger)
+{
+	int edio;
+	unsigned short rval;
+
+	edio = irq_to_edio(irq);
+	rval = __raw_readw(EDIO_EPPAR);
+	rval = (rval & (~(0x3 << (edio * 2)))) | (trigger << (edio * 2));
+	__raw_writew(rval, EDIO_EPPAR);
+}
+
+static void mxc_irq_set_edio_dir(int irq, int dir)
+{
+	int edio;
+	unsigned short rval;
+
+	edio = irq_to_edio(irq);
+
+	rval = __raw_readw(EDIO_EPDR);
+	rval &= ~(1 << edio);
+	rval |= (0 << edio);
+	__raw_writew(rval, (EDIO_EPDR));
+
+	/* set direction */
+	rval = __raw_readw(EDIO_EPDDR);
+
+	if (dir)
+		/* out */
+		rval |= (1 << edio);
+	else
+		/* in */
+		rval &= ~(1 << edio);
+
+	__raw_writew(rval, EDIO_EPDDR);
+
+}
+
+/*
+ * Allows tuning the IRQ type , trigger and priority
+ */
+static void mxc_irq_set_edio(int irq, int fiq, int priority, int trigger)
+{
+
+	mxc_irq_set_edio_dir(irq, 0);
+	/* set level */
+	mxc_irq_set_edio_level(irq, trigger);
+}
+#endif
 
 /* Disable interrupt number "irq" in the AVIC */
 static void mxc_mask_irq(unsigned int irq)
@@ -32,11 +123,78 @@ static void mxc_unmask_irq(unsigned int 
 }
 
 static struct irq_chip mxc_avic_chip = {
-	.mask_ack = mxc_mask_irq,
+	.ack = mxc_mask_irq,
+	.mask = mxc_mask_irq,
+	.unmask = mxc_unmask_irq,
+};
+
+#ifdef EDIO_BASE_ADDR
+static void mxc_ack_edio(u32 irq)
+{
+	u16 edio = (u16) irq_to_edio(irq);
+
+	if (edio_irq_type[edio] == IRQT_LOW) {
+		/* Mask interrupt for level sensitive */
+		mxc_mask_irq(irq);
+	} else if (edio_irq_type[edio] == IRQT_HIGH) {
+		/* clear edio interrupt */
+		__raw_writew((1 << edio), EDIO_EPFR);
+		/* dummy read for edio workaround */
+		__raw_readw(EDIO_EPFR);
+			/* Mask interrupt for level sensitive */
+		mxc_mask_irq(irq);
+	} else {
+		/* clear edio interrupt */
+		__raw_writew((1 << edio), EDIO_EPFR);
+		/* dummy read for edio workaround */
+		__raw_readw(EDIO_EPFR);
+	}
+}
+
+static int mxc_edio_set_type(u32 irq, u32 type)
+{
+	edio_irq_type[irq_to_edio(irq)] = type;
+
+	switch (type) {
+	case IRQT_RISING:
+		mxc_irq_set_edio_level(irq, 1);
+		set_irq_handler(irq, do_edge_IRQ);
+		break;
+	case IRQT_FALLING:
+		mxc_irq_set_edio_level(irq, 2);
+		set_irq_handler(irq, do_edge_IRQ);
+		break;
+	case IRQT_BOTHEDGE:
+		mxc_irq_set_edio_level(irq, 3);
+		set_irq_handler(irq, do_edge_IRQ);
+		break;
+	case IRQT_LOW:
+		mxc_irq_set_edio_level(irq, 0);
+		set_irq_handler(irq, do_level_IRQ);
+		break;
+	case IRQT_HIGH:
+		/* EDIO doesn't really support high-level interrupts,
+		 * so we're faking it
+		 */
+		mxc_irq_set_edio_level(irq, 1);
+		set_irq_handler(irq, do_level_IRQ);
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
+
+static struct irqchip mxc_edio_chip = {
+	.ack = mxc_ack_edio,
 	.mask = mxc_mask_irq,
 	.unmask = mxc_unmask_irq,
+	.set_type = mxc_edio_set_type,
 };
 
+#endif
+
 /*
  * This function initializes the AVIC hardware and disables all the
  * interrupts. It registers the interrupt enable and disable functions
@@ -61,7 +219,15 @@ void __init mxc_init_irq(void)
 	__raw_writel(0, AVIC_INTTYPEH);
 	__raw_writel(0, AVIC_INTTYPEL);
 	for (i = 0; i < MXC_MAX_INT_LINES; i++) {
-		set_irq_chip(i, &mxc_avic_chip);
+#ifdef EDIO_BASE_ADDR
+		if (irq_to_edio(i) != -1) {
+			mxc_irq_set_edio(i, 0, 0, 0);
+			set_irq_chip(i, &mxc_edio_chip);
+		} else
+#endif
+		{
+			set_irq_chip(i, &mxc_avic_chip);
+		}
 		set_irq_handler(i, handle_level_irq);
 		set_irq_flags(i, IRQF_VALID);
 	}
Index: arch/arm/plat-mxc/gpio.c
===================================================================
--- /dev/null
+++ arch/arm/plat-mxc/gpio.c
@@ -0,0 +1,464 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * Implementation based on omap gpio.c
+ *
+ * This file contains the GPIO implementation details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/irqs.h>
+#include <asm/mach/irq.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
+
+/* GPIO related defines */
+#if defined(CONFIG_ARCH_MX2)
+enum gpio_reg {
+	GPIO_DR = 0x1C,
+	GPIO_GDIR = 0x00,
+	GPIO_PSR = 0x24,
+	GPIO_ICR1 = 0x028,
+	GPIO_ICR2 = 0x2C,
+	GPIO_IMR = 0x30,
+	GPIO_ISR = 0x34,
+};
+#else
+enum gpio_reg {
+	GPIO_DR = 0x00,
+	GPIO_GDIR = 0x04,
+	GPIO_PSR = 0x08,
+	GPIO_ICR1 = 0x0C,
+	GPIO_ICR2 = 0x10,
+	GPIO_IMR = 0x14,
+	GPIO_ISR = 0x18,
+};
+#endif
+
+extern struct mxc_gpio_port mxc_gpio_ports[];
+
+struct gpio_port {
+	u32 num;		/* gpio port number */
+	u32 base;		/* gpio port base VA */
+	u16 irq;		/* irq number to the core */
+	u16 virtual_irq_start;	/* virtual irq start number */
+	u32 reserved_map;	/* keep track of which pins are in use */
+	u32 irq_is_level_map;	/* if a pin's irq is level sensitive. default is edge */
+	spinlock_t lock;	/* lock when operating on the port */
+};
+
+static struct gpio_port gpio_port[GPIO_PORT_NUM];
+
+/* Find the pointer to the gpio_port for a given pin. */
+static inline struct gpio_port *get_gpio_port(u32 gpio)
+{
+	return &gpio_port[GPIO_TO_PORT(gpio)];
+}
+
+/* Check if a gpio pin is within [0, MXC_MAX_GPIO_LINES -1] */
+static int check_gpio(u32 gpio)
+{
+	if (gpio >= MXC_MAX_GPIO_LINES) {
+		printk(KERN_ERR "mxc-gpio: invalid GPIO %d\n", gpio);
+		dump_stack();
+		return -1;
+	}
+	return 0;
+}
+
+/* Set a GPIO pin's direction */
+static void _set_gpio_direction(struct gpio_port *port, u32 index, int is_input)
+{
+	u32 reg = port->base + GPIO_GDIR;
+	u32 l;
+
+	l = __raw_readl(reg);
+	if (is_input)
+		l &= ~(1 << index);
+	else
+		l |= 1 << index;
+	__raw_writel(l, reg);
+}
+
+
+/**
+ * mxc_set_gpio_direction - Set a GPIO pin's direction
+ * @pin: A name defined by iomux_pin_name_t
+ * @is_input: 1 (or non-zero) for input; 0 for output
+ */
+void mxc_set_gpio_direction(iomux_pin_name_t pin, int is_input)
+{
+	struct gpio_port *port;
+	u32 gpio = IOMUX_TO_GPIO(pin);
+
+	if (check_gpio(gpio) < 0)
+		return;
+	port = get_gpio_port(gpio);
+	spin_lock(&port->lock);
+	_set_gpio_direction(port, GPIO_TO_INDEX(gpio), is_input);
+	spin_unlock(&port->lock);
+}
+EXPORT_SYMBOL(mxc_set_gpio_direction);
+
+/* Set a GPIO pin's data output */
+static void _set_gpio_dataout(struct gpio_port *port, u32 index, u32 data)
+{
+	u32 reg = port->base + GPIO_DR;
+	u32 l = 0;
+
+	l = (__raw_readl(reg) & (~(1 << index))) | (data << index);
+	__raw_writel(l, reg);
+}
+
+/**
+ * mxc_set_gpio_dataout - Set a GPIO pin's data output
+ * @pin: A name defined by iomux_pin_name_t
+ * @data: Value to be set (only 0 or 1 is valid)
+ */
+void mxc_set_gpio_dataout(iomux_pin_name_t pin, u32 data)
+{
+	struct gpio_port *port;
+	u32 gpio = IOMUX_TO_GPIO(pin);
+
+	if (check_gpio(gpio) < 0)
+		return;
+
+	port = get_gpio_port(gpio);
+	spin_lock(&port->lock);
+	_set_gpio_dataout(port, GPIO_TO_INDEX(gpio), (data == 0) ? 0 : 1);
+	spin_unlock(&port->lock);
+}
+EXPORT_SYMBOL(mxc_set_gpio_dataout);
+
+/**
+ * mxc_get_gpio_datain - Return the data value of a GPIO signal.
+ * @pin: A name defined by iomux_pin_name_t
+ */
+int mxc_get_gpio_datain(iomux_pin_name_t pin)
+{
+	struct gpio_port *port;
+	u32 gpio = IOMUX_TO_GPIO(pin);
+
+	if (check_gpio(gpio) < 0)
+		return -1;
+
+	port = get_gpio_port(gpio);
+
+	return (__raw_readl(port->base + GPIO_DR) >> GPIO_TO_INDEX(gpio)) & 1;
+}
+EXPORT_SYMBOL(mxc_get_gpio_datain);
+
+/* Clear a GPIO signal's interrupt status */
+static inline void _clear_gpio_irqstatus(struct gpio_port *port, u32 index)
+{
+	__raw_writel(1 << index, port->base + GPIO_ISR);
+}
+
+/* Set a GPIO pin's interrupt edge */
+static void _set_gpio_edge_ctrl(struct gpio_port *port, u32 index,
+				gpio_edge_t edge)
+{
+	u32 reg = port->base;
+	u32 l, sig;
+
+	reg += (index <= 15) ? GPIO_ICR1 : GPIO_ICR2;
+	sig = (index <= 15) ? index : (index - 16);
+	l = __raw_readl(reg);
+	l = (l & (~(0x3 << (sig * 2)))) | (edge << (sig * 2));
+	__raw_writel(l, reg);
+	_clear_gpio_irqstatus(port, index);
+}
+
+/* Enable/disable a GPIO signal's interrupt. */
+static inline void _set_gpio_irqenable(struct gpio_port *port, u32 index,
+				       bool enable)
+{
+	u32 reg = port->base + GPIO_IMR;
+	u32 mask = (!enable) ? 0 : 1;
+	u32 l;
+
+	l = __raw_readl(reg);
+	l = (l & (~(1 << index))) | (mask << index);
+	__raw_writel(l, reg);
+}
+
+static inline int _request_gpio(struct gpio_port *port, u32 index)
+{
+	spin_lock(&port->lock);
+	if (port->reserved_map & (1 << index)) {
+		printk(KERN_ERR
+		       "GPIO port %d (0-based), pin %d is already reserved!\n",
+		       port->num, index);
+		dump_stack();
+		spin_unlock(&port->lock);
+		return -1;
+	}
+	port->reserved_map |= (1 << index);
+	spin_unlock(&port->lock);
+	return 0;
+}
+
+/**
+ * mxc_request_gpio - Request ownership for a GPIO pin.
+ * @pin: A name defined by iomux_pin_name_t
+ *
+ * The caller has to check the return value of this function to
+ * make sure it returns 0 before make use of that pin.
+ */
+int mxc_request_gpio(iomux_pin_name_t pin)
+{
+	struct gpio_port *port;
+	u32 index, gpio = IOMUX_TO_GPIO(pin);
+
+	if (check_gpio(gpio) < 0)
+		return -EINVAL;
+
+	port = get_gpio_port(gpio);
+	index = GPIO_TO_INDEX(gpio);
+
+	return _request_gpio(port, index);
+}
+EXPORT_SYMBOL(mxc_request_gpio);
+EXPORT_SYMBOL(mxc_free_gpio);
+
+
+/**
+ * mxc_free_gpio - Release ownership for a GPIO pin
+ * @pin: A name defined by iomux_pin_name_t
+ */
+void mxc_free_gpio(iomux_pin_name_t pin)
+{
+	struct gpio_port *port;
+	u32 index, gpio = IOMUX_TO_GPIO(pin);
+
+	if (check_gpio(gpio) < 0)
+		return;
+
+	port = get_gpio_port(gpio);
+	index = GPIO_TO_INDEX(gpio);
+
+	spin_lock(&port->lock);
+	if ((!(port->reserved_map & (1 << index)))) {
+		printk(KERN_ERR "GPIO port %d, pin %d wasn't reserved!\n",
+		       port->num, index);
+		dump_stack();
+		spin_unlock(&port->lock);
+		return;
+	}
+	port->reserved_map &= ~(1 << index);
+	port->irq_is_level_map &= ~(1 << index);
+	_set_gpio_direction(port, index, 1);
+	_set_gpio_irqenable(port, index, 0);
+	_clear_gpio_irqstatus(port, index);
+	spin_unlock(&port->lock);
+}
+
+/*
+ * We need to unmask the GPIO port interrupt as soon as possible to
+ * avoid missing GPIO interrupts for other lines in the port.
+ * Then we need to mask-read-clear-unmask the triggered GPIO lines
+ * in the port to avoid missing nested interrupts for a GPIO line.
+ * If we wait to unmask individual GPIO lines in the port after the
+ * line's interrupt handler has been run, we may miss some nested
+ * interrupts.
+ */
+static void mxc_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	u32 isr_reg = 0, imr_reg = 0, imr_val;
+	u32 int_valid;
+	u32 gpio_irq;
+	struct gpio_port *port;
+
+	port = (struct gpio_port *)get_irq_data(irq);
+	isr_reg = port->base + GPIO_ISR;
+	imr_reg = port->base + GPIO_IMR;
+
+	imr_val = __raw_readl(imr_reg);
+	int_valid = __raw_readl(isr_reg) & imr_val;
+
+	if (unlikely(!int_valid)) {
+		printk(KERN_ERR "\nGPIO port: %d Spurious interrupt:0x%0x\n\n",
+		       port->num, int_valid);
+		BUG();		/* oops */
+	}
+
+	gpio_irq = port->virtual_irq_start;
+	for (; int_valid != 0; int_valid >>= 1, gpio_irq++) {
+		struct irq_desc *d;
+
+		if ((int_valid & 1) == 0)
+			continue;
+		d = irq_desc + gpio_irq;
+		if (unlikely(!(d->handle_irq))) {
+			printk(KERN_ERR "\nGPIO port: %d irq: %d unhandeled\n",
+			       port->num, gpio_irq);
+			BUG();	/* oops */
+		}
+		d->handle_irq(gpio_irq, d);
+	}
+}
+
+#ifdef MXC_MUX_GPIO_INTERRUPTS
+static void mxc_gpio_mux_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	int i;
+	u32 isr_reg = 0, imr_reg = 0, imr_val;
+	u32 int_valid;
+	struct gpio_port *port;
+
+	for (i = 0; i < GPIO_PORT_NUM; i++) {
+		port = &gpio_port[i];
+		isr_reg = port->base + GPIO_ISR;
+		imr_reg = port->base + GPIO_IMR;
+
+		imr_val = __raw_readl(imr_reg);
+		int_valid = __raw_readl(isr_reg) & imr_val;
+
+		if (int_valid) {
+			set_irq_data(irq, (void *)port);
+			mxc_gpio_irq_handler(irq, desc);
+		}
+	}
+}
+#endif
+
+/* Disable a gpio pin's interrupt by setting the bit in the imr. */
+static void gpio_mask_irq(u32 irq)
+{
+	u32 gpio = MXC_IRQ_TO_GPIO(irq);
+	struct gpio_port *port = get_gpio_port(gpio);
+
+	_set_gpio_irqenable(port, GPIO_TO_INDEX(gpio), 0);
+}
+
+/*
+ * Acknowledge a gpio pin's interrupt by clearing the bit in the isr.
+ * If the GPIO interrupt is level triggered, it also disables the interrupt.
+ */
+static void gpio_ack_irq(u32 irq)
+{
+	u32 gpio = MXC_IRQ_TO_GPIO(irq);
+	u32 index = GPIO_TO_INDEX(gpio);
+	struct gpio_port *port = get_gpio_port(gpio);
+
+	_clear_gpio_irqstatus(port, GPIO_TO_INDEX(gpio));
+	if (port->irq_is_level_map & (1 << index)) {
+		gpio_mask_irq(irq);
+	}
+}
+
+/* Enable a gpio pin's interrupt by clearing the bit in the imr. */
+static void gpio_unmask_irq(u32 irq)
+{
+	u32 gpio = MXC_IRQ_TO_GPIO(irq);
+	struct gpio_port *port = get_gpio_port(gpio);
+
+	_set_gpio_irqenable(port, GPIO_TO_INDEX(gpio), 1);
+}
+
+/* Enable a gpio pin's interrupt by clearing the bit in the imr. */
+static int gpio_set_irq_type(u32 irq, u32 type)
+{
+	u32 gpio = MXC_IRQ_TO_GPIO(irq);
+	struct gpio_port *port = get_gpio_port(gpio);
+
+	switch (type) {
+	case IRQT_RISING:
+		_set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio),
+				    GPIO_INT_RISE_EDGE);
+		set_irq_handler(irq, handle_edge_irq);
+		port->irq_is_level_map &= ~(1 << GPIO_TO_INDEX(gpio));
+		break;
+	case IRQT_FALLING:
+		_set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio),
+				    GPIO_INT_FALL_EDGE);
+		set_irq_handler(irq, handle_edge_irq);
+		port->irq_is_level_map &= ~(1 << GPIO_TO_INDEX(gpio));
+		break;
+	case IRQT_LOW:
+		_set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio),
+				    GPIO_INT_LOW_LEV);
+		set_irq_handler(irq, handle_level_irq);
+		port->irq_is_level_map |= 1 << GPIO_TO_INDEX(gpio);
+		break;
+	case IRQT_HIGH:
+		_set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio),
+				    GPIO_INT_HIGH_LEV);
+		set_irq_handler(irq, handle_level_irq);
+		port->irq_is_level_map |= 1 << GPIO_TO_INDEX(gpio);
+		break;
+	case IRQT_BOTHEDGE:
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+	.ack = gpio_ack_irq,
+	.mask = gpio_mask_irq,
+	.unmask = gpio_unmask_irq,
+	.set_type = gpio_set_irq_type,
+};
+
+static int __init mxc_gpio_init(void)
+{
+	int i;
+	struct gpio_port *port;
+
+	printk(KERN_INFO "MXC GPIO hardware\n");
+
+	for (i = 0; i < GPIO_PORT_NUM; i++) {
+		int j, gpio_count = GPIO_NUM_PIN;
+
+		port = &gpio_port[i];
+		port->base = mxc_gpio_ports[i].base;
+		port->num = mxc_gpio_ports[i].num;
+		port->irq = mxc_gpio_ports[i].irq;
+		port->virtual_irq_start = mxc_gpio_ports[i].virtual_irq_start;
+
+		port->reserved_map = 0;
+		spin_lock_init(&port->lock);
+
+		/* disable the interrupt and clear the status */
+		__raw_writel(0, port->base + GPIO_IMR);
+		__raw_writel(0xFFFFFFFF, port->base + GPIO_ISR);
+		for (j = port->virtual_irq_start;
+		     j < port->virtual_irq_start + gpio_count; j++) {
+			set_irq_chip(j, &gpio_irq_chip);
+			set_irq_handler(j, handle_edge_irq);
+			set_irq_flags(j, IRQF_VALID);
+		}
+#ifndef MXC_MUX_GPIO_INTERRUPTS
+		set_irq_chained_handler(port->irq, mxc_gpio_irq_handler);
+		set_irq_data(port->irq, port);
+#endif
+	}
+
+#ifdef MXC_MUX_GPIO_INTERRUPTS
+	set_irq_chained_handler(port->irq, mxc_gpio_mux_irq_handler);
+	set_irq_data(mxc_gpio_ports[0].irq, gpio_port);
+#endif
+
+	return 0;
+}
+
+postcore_initcall(mxc_gpio_init);
Index: arch/arm/plat-mxc/clock.c
===================================================================
--- /dev/null
+++ arch/arm/plat-mxc/clock.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*
+ *  Based on arch/arm/plat-omap/clock.c
+ *
+ *  Copyright (C) 2004 - 2005 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *  Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+
+#include <asm/io.h>
+#include <asm/semaphore.h>
+
+#include <asm/arch/clock.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clockfw_lock);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+/*
+ * Retrieve a clock by name.
+ *
+ * Note that we first try to use device id on the bus
+ * and clock name. If this fails, we try to use "<name>.<id>". If this fails,
+ * we try to use clock name only.
+ * The reference count to the clock's module owner ref count is incremented.
+ */
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	struct clk *p, *clk = ERR_PTR(-ENOENT);
+	int idno;
+	char *str;
+
+	if (id == NULL)
+		return clk;
+
+	if (dev == NULL || dev->bus != &platform_bus_type)
+		idno = -1;
+	else
+		idno = to_platform_device(dev)->id;
+
+	mutex_lock(&clocks_mutex);
+
+	list_for_each_entry(p, &clocks, node) {
+		if (p->id == idno &&
+		    strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+			clk = p;
+			goto found;
+		}
+	}
+
+	str = strrchr(id, '.');
+	if (str) {
+		str[0] = '\0';
+		str++;
+		idno = simple_strtol(str, NULL, 10);
+		list_for_each_entry(p, &clocks, node) {
+			if (p->id == idno &&
+			    strcmp(id, p->name) == 0 &&
+			    try_module_get(p->owner)) {
+				clk = p;
+				goto found;
+			}
+		}
+	}
+
+	list_for_each_entry(p, &clocks, node) {
+		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+			clk = p;
+			goto found;
+		}
+	}
+
+	printk(KERN_WARNING "clk: Unable to get requested clock: %s\n", id);
+
+found:
+	mutex_unlock(&clocks_mutex);
+
+	return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+static void __clk_disable(struct clk *clk)
+{
+	if (clk->usecount > 0 && !(--clk->usecount)) {
+		if (clk->disable != NULL) {
+			clk->disable(clk);
+		}
+		if (likely((u32) clk->parent))
+			__clk_disable(clk->parent);
+		if (unlikely((u32) clk->secondary))
+			__clk_disable(clk->secondary);
+	}
+}
+
+static int __clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (clk->usecount++ == 0) {
+		if (likely((u32) clk->parent)) {
+			ret = __clk_enable(clk->parent);
+
+			if (unlikely(ret != 0)) {
+				goto err1;
+			}
+		}
+
+		if (unlikely((u32) clk->secondary)) {
+			ret = __clk_enable(clk->secondary);
+
+			if (unlikely(ret != 0)) {
+				goto err2;
+			}
+		}
+
+		if (clk->enable) {
+			ret = clk->enable(clk);
+		}
+
+		if (unlikely(ret != 0)) {
+			goto err3;
+		}
+	}
+	return 0;
+
+err3:
+	if (clk->secondary)
+		__clk_disable(clk->secondary);
+err2:
+	if (clk->parent)
+		__clk_disable(clk->parent);
+err1:
+	clk->usecount--;
+	return ret;
+}
+
+/*
+ * Enable a clock.
+ * This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled.
+ */
+int clk_enable(struct clk *clk)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+
+	ret = __clk_enable(clk);
+
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/*
+ * Disable a clock.
+ * This function decrements the reference count on the clock and disables the
+ * clock when reference count is 0. The parent clock tree is recursively
+ * disabled.
+ */
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+
+	__clk_disable(clk);
+
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/*
+ * Get the reference count for the requested clock.
+ */
+int clk_get_usecount(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return 0;
+
+	return clk->usecount;
+}
+EXPORT_SYMBOL(clk_get_usecount);
+
+/*
+ * Retrieve the clock rate for a clock.
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return 0;
+
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/*
+ * Decrement the clock's module reference count.
+ */
+void clk_put(struct clk *clk)
+{
+	if (clk && !IS_ERR(clk))
+		module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+/*
+ * Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+		return 0;
+
+	return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Propagate rate to children */
+void propagate_rate(struct clk *tclk)
+{
+	struct clk *clkp;
+
+	if (tclk == NULL || IS_ERR(tclk))
+		return;
+
+	pr_debug("mxc clock: finding children of %s-%d\n", tclk->name,
+		 tclk->id);
+	list_for_each_entry(clkp, &clocks, node) {
+		if (likely(clkp->parent != tclk))
+			continue;
+		pr_debug("mxc clock: %s-%d: recalculating rate: old = %lu, ",
+			 clkp->name, clkp->id, clkp->rate);
+		if (likely((u32) clkp->recalc))
+			clkp->recalc(clkp);
+		else
+			clkp->rate = tclk->rate;
+		pr_debug("new = %lu\n", clkp->rate);
+		propagate_rate(clkp);
+	}
+}
+EXPORT_SYMBOL(propagate_rate);
+
+/*
+ * Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns.
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+		return ret;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+
+	ret = clk->set_rate(clk, rate);
+	if (likely(ret == 0))
+		propagate_rate(clk);
+
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/*
+ * Set the clock's parent to another clock source.
+ */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+	    IS_ERR(parent) || clk->set_parent == NULL)
+		return ret;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+	ret = clk->set_parent(clk, parent);
+	if (ret == 0) {
+		clk->parent = parent;
+		if (clk->recalc) {
+			clk->recalc(clk);
+		} else {
+			clk->rate = parent->rate;
+		}
+		propagate_rate(clk);
+	}
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/*
+ * Retrieve the clock's parent clock source.
+ */
+struct clk *clk_get_parent(struct clk *clk)
+{
+	struct clk *ret = NULL;
+
+	if (clk == NULL || IS_ERR(clk))
+		return ret;
+
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+/*
+ * Add a new clock to the clock tree.
+ */
+int clk_register(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
+	mutex_lock(&clocks_mutex);
+	list_add(&clk->node, &clocks);
+	mutex_unlock(&clocks_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+/*
+ * Remove a clock from the clock tree.
+ */
+void clk_unregister(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
+	mutex_lock(&clocks_mutex);
+	list_del(&clk->node);
+	mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+void mxc_dump_clocks(void)
+{
+	struct clk *clkp;
+	list_for_each_entry(clkp, &clocks, node) {
+		printk("name:\t%s-%d\n", clkp->name, clkp->id);
+		printk("count:\t%d\n", clkp->usecount);
+		printk("rate:\t%lu\n", clkp->rate);
+		if (clkp->parent)
+			printk("parent:\t%s-%d\n\n", clkp->parent->name,
+			       clkp->parent->id);
+		else
+			printk("parent:\tnone\n\n");
+	}
+}
+
+#ifdef CONFIG_PROC_FS
+static int mxc_clock_read_proc(char *page, char **start, off_t off,
+			       int count, int *eof, void *data)
+{
+	struct clk *clkp;
+	char *p = page;
+	int len;
+
+	list_for_each_entry(clkp, &clocks, node) {
+		p += sprintf(p, "%s-%d:\t\t%lu, %d",
+			     clkp->name, clkp->id, clkp->rate, clkp->usecount);
+		if (clkp->parent)
+			p += sprintf(p, ", %s-%d\n", clkp->parent->name,
+				     clkp->parent->id);
+		else
+			p += sprintf(p, "\n");
+	}
+
+	len = (p - page) - off;
+	if (len < 0)
+		len = 0;
+
+	*eof = (len <= count) ? 1 : 0;
+	*start = page + off;
+
+	return len;
+}
+
+static int __init mxc_setup_proc_entry(void)
+{
+	struct proc_dir_entry *res;
+
+	res = create_proc_read_entry("cpu/clocks", 0, NULL,
+				     mxc_clock_read_proc, NULL);
+	if (!res) {
+		printk(KERN_ERR "Failed to create proc/cpu/clocks\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+late_initcall(mxc_setup_proc_entry);
+#endif
Index: arch/arm/plat-mxc/Makefile
===================================================================
--- arch/arm/plat-mxc/Makefile.orig
+++ arch/arm/plat-mxc/Makefile
@@ -3,4 +3,6 @@
 #
 
 # Common support
-obj-y := irq.o
+obj-y := irq.o gpio.o clock.o
+
+obj-$(CONFIG_ARCH_MX2) += dma_mx2.o
Index: arch/arm/plat-mxc/dma_mx2.c
===================================================================
--- /dev/null
+++ arch/arm/plat-mxc/dma_mx2.c
@@ -0,0 +1,1251 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * This file contains functions for DMA API
+ *  Front-end to the DMA handling.  This handles the allocation/freeing
+ *  of DMA channels, and provides a unified interface to the machines
+ *  DMA facilities.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+
+#include <linux/proc_fs.h>
+#include <asm/io.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/dma.h>
+#include <asm/delay.h>
+
+#include <asm/atomic.h>
+
+/* commented temperily for mx27 compilation
+#define DMA_PM
+*/
+#ifdef DMA_PM
+#include <linux/pm.h>
+#include <asm/arch/apmc.h>
+struct apmc_user *dma_apmc_user;
+struct pm_dev *dma_pm;
+#define DMA_PMST_RESUME		0
+#define DMA_PMST_STANDBY		1
+#define DMA_PMST_SUSPEND		2
+static unsigned int dma_pm_status = DMA_PMST_RESUME;
+#endif
+
+/*
+ * This variable is used to controll the clock of DMA.
+ * It counts the number of actived channels
+ */
+static atomic_t g_dma_actived = ATOMIC_INIT(0);
+
+/*
+ * This variable point a proc file which contains the
+ * information of DMA channels
+ */
+static struct proc_dir_entry *g_proc_dir;
+
+/* The dma channels */
+static mxc_dma_channel_t g_dma_channels[MAX_DMA_CHANNELS];
+static mx2_dma_priv_t g_dma_privates[MXC_DMA_CHANNELS];
+static mx2_dma_bd_t g_dma_bd_table[MXC_DMA_CHANNELS][MAX_BD_SIZE];
+
+static DEFINE_SPINLOCK(dma_list_lock);
+
+static struct clk *dma_clk;
+
+/* flush buffer descriptor ring*/
+#define flush_dma_bd(private) \
+		{ \
+			atomic_set(&(private->bd_used), 0); \
+			private->bd_rd = private->bd_wr;\
+		}
+
+/* get next buffer discriptor */
+#define next_dma_bd(private) \
+		({ \
+			int bd_next = (private->bd_rd+1)%MAX_BD_SIZE; \
+			(bd_next ==  private->bd_wr) ? NULL: private->bd_ring+bd_next;\
+		})
+
+static inline int consume_dma_bd(mxc_dma_channel_t * dma, int error);
+
+/* allocate a dma channel */
+static inline int get_dma_channel(int idx)
+{
+	int i;
+	mxc_dma_channel_t *p;
+
+	if ((idx >= MAX_DMA_CHANNELS) && (idx != MXC_DMA_DYNAMIC_CHANNEL)) {
+		return -1;
+	}
+	if (idx != MXC_DMA_DYNAMIC_CHANNEL) {
+		p = g_dma_channels + idx;
+		BUG_ON(p->dynamic != 0);
+		if (xchg(&p->lock, 1) != 0) {
+			return -1;
+		}
+		return idx;
+	}
+
+	p = g_dma_channels;
+	for (i = 0; (i < MAX_DMA_CHANNELS); i++, p++) {
+		if (p->dynamic && (xchg(&p->lock, 1) == 0)) {
+			return i;
+		}
+	}
+	return -1;
+}
+
+/* release a dma channel. */
+static inline void put_dma_channel(int idx)
+{
+	mxc_dma_channel_t *p;
+
+	if ((idx < MAX_DMA_CHANNELS) && (idx >= 0)) {
+		p = g_dma_channels + idx;
+		(void)xchg(&p->lock, 0);
+	}
+}
+
+/* Get dma list for /proc/dma */
+static int mxc_get_dma_list(char *buf)
+{
+	mxc_dma_channel_t *dma;
+	char *p = buf;
+	int i;
+
+	for (i = 0, dma = g_dma_channels; i < MAX_DMA_CHANNELS; i++, dma++) {
+		if (dma->lock) {
+			p += sprintf(p, "dma channel %2d: %s\n", i,
+				     dma->dev_name ? dma->dev_name : "unknown");
+		} else {
+			p += sprintf(p, "dma channel %2d: unused\n", i);
+		}
+	}
+
+	return p - buf;
+}
+
+/* save the mask of dma interrupts*/
+#define save_dma_interrupt(flags) \
+		flags = __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DIMR)
+
+/* restore the mask of dma interrupts*/
+#define restore_dma_interrupt(flags) \
+		__raw_writel(flags, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DIMR)
+
+/* disable interrupt of dma channel*/
+static inline void mask_dma_interrupt(int channel)
+{
+	unsigned long reg;
+	save_dma_interrupt(reg);
+	reg |= 1 << channel;	/*mask interrupt; */
+	restore_dma_interrupt(reg);
+}
+
+/* enable interrupt of dma channel */
+static inline void unmask_dma_interrupt(int channel)
+{
+	unsigned long reg;
+	save_dma_interrupt(reg);
+	reg &= ~(1 << channel);	/*unmask interrupt; */
+	restore_dma_interrupt(reg);
+}
+
+/* get interrupt event of dma channel */
+static unsigned long inline __get_dma_interrupt(int channel)
+{
+	unsigned long mode;
+	mode = 0;
+	if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DISR) & (1 << channel))
+		mode |= DMA_DONE;
+
+	if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBTOSR) &
+	    (1 << channel))
+		mode |= DMA_BURST_TIMEOUT;
+	if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DSESR) & (1 << channel))
+		mode |= DMA_TRANSFER_ERROR;
+
+	if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBOSR) & (1 << channel))
+		mode |= DMA_BUFFER_OVERFLOW;
+	if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DRTOSR) &
+	    (1 << channel))
+		mode |= DMA_REQUEST_TIMEOUT;
+	return mode;
+}
+
+/* clean all event of dma interrupt and return the valid event. */
+static unsigned long inline __clear_dma_interrupt(int channel)
+{
+	unsigned long mode;
+	mode = __get_dma_interrupt(channel);
+	__raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DISR);
+	__raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBTOSR);
+	__raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DRTOSR);
+	__raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DSESR);
+	__raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBOSR);
+
+	return mode;
+}
+
+/* This function enables dma clocks without lock */
+static void inline __enable_dma_clk(void)
+{
+	unsigned long reg;
+	clk_enable(dma_clk);
+	reg = __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR);
+	reg |= 0x1;
+	__raw_writel(reg, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR);
+}
+
+/* This function disables dma clocks without lock */
+static void inline __disable_dma_clk(void)
+{
+	unsigned long reg;
+	reg = __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR);
+	reg &= ~0x1;
+	__raw_writel(reg, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR);
+	clk_disable(dma_clk);
+}
+
+/* This function enables dma clocks with lock */
+static void inline enable_dma_clk(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_list_lock, flags);
+	if (atomic_read(&g_dma_actived) == 0) {
+		__enable_dma_clk();
+	}
+	spin_unlock_irqrestore(&dma_list_lock, flags);
+	return;
+}
+
+/* This function disables dma clocks without locked */
+static void inline disable_dma_clk(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_list_lock, flags);
+	if (atomic_read(&g_dma_actived) == 0) {
+		__disable_dma_clk();
+	}
+	spin_unlock_irqrestore(&dma_list_lock, flags);
+	return;
+}
+
+/* select a buffer to transfer and setup dma channel for current transfer */
+static void setup_dmac(mxc_dma_channel_t * dma)
+{
+	mx2_dma_priv_t *priv = (mx2_dma_priv_t *) dma->private;
+	dma_regs_t *dma_base = (dma_regs_t *) (priv->dma_base);
+	mx2_dma_bd_t *p, *q;
+	unsigned long ctrl_val;
+
+	if (dma->active == 0) {
+		printk(KERN_ERR
+		       "dma channel %d is not enabled, when receiving this channel 's interrupt\n",
+		       dma->channel);
+		return;
+	}
+	if (atomic_read(&(priv->bd_used)) <= 0) {
+		printk(KERN_ERR "dma channel %d is empty\n", dma->channel);
+		dma->active = 0;
+		atomic_dec(&g_dma_actived);
+		return;
+	}
+	/* BUSY: transfering
+	 * PEND: Wait for set to DMAC.
+	 * s1: no transfering:
+	 *      set first(one BUSY). if there are more than one tranfer. set second &repeat is enabled(two BUSY).
+	 *
+	 * s2: transfering & just on transfer
+	 *      one BUSY. set the tranesfer and set repeat bit(two BUSY)
+	 * s3: transfering & repeat has set
+	 *     has two BUSY.
+	 */
+	p = priv->bd_ring + priv->bd_rd;
+	q = next_dma_bd(priv);
+	if (!(p->state & DMA_BD_ST_BUSY)) {
+		/*NOTICE:: This is first buffer or dma chain does not support chain-buffer. So CEN must clear & set again */
+		ctrl_val =
+		    __raw_readl(&(dma_base->Ctl)) &
+		    (~(DMA_CTL_ACRPT | DMA_CTL_RPT | DMA_CTL_CEN));
+		__raw_writel(ctrl_val, &(dma_base->Ctl));
+		if (p->mode != dma->mode) {
+			dma->mode = p->mode;	/* bi-dir channel do mode change */
+			if (dma->mode == MXC_DMA_MODE_READ) {
+				DMA_CTL_SET_SMOD(ctrl_val,
+						 priv->dma_info->sourceType);
+				DMA_CTL_SET_SSIZ(ctrl_val,
+						 priv->dma_info->sourcePort);
+				DMA_CTL_SET_DMOD(ctrl_val,
+						 priv->dma_info->destType);
+				DMA_CTL_SET_DSIZ(ctrl_val,
+						 priv->dma_info->destPort);
+			} else {
+				DMA_CTL_SET_SMOD(ctrl_val,
+						 priv->dma_info->destType);
+				DMA_CTL_SET_SSIZ(ctrl_val,
+						 priv->dma_info->destPort);
+				DMA_CTL_SET_DMOD(ctrl_val,
+						 priv->dma_info->sourceType);
+				DMA_CTL_SET_DSIZ(ctrl_val,
+						 priv->dma_info->sourcePort);
+			}
+		}
+		__raw_writel(p->src_addr, &(dma_base->SourceAddr));
+		__raw_writel(p->dst_addr, &(dma_base->DestAddr));
+		__raw_writel(p->count, &(dma_base->Count));
+		p->state |= DMA_BD_ST_BUSY;
+		p->state &= ~(DMA_BD_ST_PEND);
+		ctrl_val |= DMA_CTL_CEN;
+		__raw_writel(ctrl_val, &(dma_base->Ctl));
+		if (q && priv->dma_chaining) {	/*DO chain-buffer */
+			__raw_writel(q->src_addr, &(dma_base->SourceAddr));
+			__raw_writel(q->dst_addr, &(dma_base->DestAddr));
+			__raw_writel(q->count, &(dma_base->Count));
+			q->state |= DMA_BD_ST_BUSY;
+			q->state &= ~(DMA_BD_ST_PEND);
+			ctrl_val |= DMA_CTL_ACRPT | DMA_CTL_RPT | DMA_CTL_CEN;
+			__raw_writel(ctrl_val, &(dma_base->Ctl));
+		}
+	} else {		/* Just dma channel which supports dma buffer can run to there */
+		BUG_ON(!priv->dma_chaining);
+		if (q) {	/* p is tranfering, then q must be set into dma controller */
+			/*WARNING:: [1] dangerous area begin.
+			 *      If the p is completed during MCU run in this erea, the dma channel is crashed.
+			 */
+			__raw_writel(q->src_addr, &(dma_base->SourceAddr));
+			__raw_writel(q->dst_addr, &(dma_base->DestAddr));
+			__raw_writel(q->count, &(dma_base->Count));
+			/*WARNING:: [2] dangerous area end */
+			ctrl_val =
+			    __raw_readl(&(dma_base->Ctl)) | (DMA_CTL_ACRPT |
+							     DMA_CTL_RPT |
+							     DMA_CTL_CEN);
+			__raw_writel(ctrl_val, &(dma_base->Ctl));
+
+			/* WARNING:: This is workaround and it is dangerous:
+			 *      the judgement is not safety.
+			 */
+			if (!__get_dma_interrupt(dma->channel)) {
+				q->state |= DMA_BD_ST_BUSY;
+				q->state &= ~(DMA_BD_ST_PEND);
+			} else {
+				/*Waiting re-enable is in ISR */
+				printk(KERN_ERR
+				       "Warning:: The privous transfer is completed. Maybe the chain buffer is stopped.");
+			}
+		} else {	/* Last buffer is transfering: just clear RPT bit */
+			ctrl_val =
+			    __raw_readl(&(dma_base->Ctl)) &
+			    (~(DMA_CTL_ACRPT | DMA_CTL_RPT));
+			__raw_writel(ctrl_val, &(dma_base->Ctl));
+		}
+	}
+}
+
+/* interrupt handler of dma channel */
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+	mxc_dma_channel_t *dma = (mxc_dma_channel_t *) dev_id;
+	mx2_dma_priv_t *priv = (mx2_dma_priv_t *) (dma ? dma->private : NULL);
+	dma_regs_t *dma_base;
+	int state, error = MXC_DMA_DONE;
+
+	BUG_ON(priv == NULL);
+
+	dma_base = (dma_regs_t *) priv->dma_base;
+
+	state = __clear_dma_interrupt(dma->channel);
+
+	priv->trans_bytes += dma_base->transferd;
+	if (state != DMA_DONE) {
+		if (state & DMA_REQUEST_TIMEOUT) {
+			error = MXC_DMA_REQUEST_TIMEOUT;
+		} else {
+			error = MXC_DMA_TRANSFER_ERROR;
+		}
+	}
+	if (consume_dma_bd(dma, error)) {
+		disable_dma_clk();
+		if (dma->cb_fn) {
+			dma->cb_fn(dma->cb_args, error, priv->trans_bytes);
+		}
+		priv->trans_bytes = 0;
+	} else {
+		disable_dma_clk();
+	}
+	return IRQ_HANDLED;
+}
+
+/* Set DMA channel parameters */
+static int setup_dma_channel(mxc_dma_channel_t * dma, mx2_dma_info_t * dma_info)
+{
+	mx2_dma_priv_t *priv = (mx2_dma_priv_t *) (dma ? dma->private : NULL);
+	dma_regs_t *dma_base;
+	unsigned long reg;
+
+	if (!dma_info || !priv) {
+		return -1;
+	}
+
+	if (dma_info->sourceType > 3) {
+		return -1;
+	}
+	if (dma_info->destType > 3) {
+		return -1;
+	}
+	if (dma_info->destPort > 3) {
+		return -1;
+	}
+	if (dma_info->sourcePort > 3) {
+		return -1;
+	}
+	if (dma_info->M2D_Valid) {
+		/*add for second dma */
+		if (dma_info->W < dma_info->X) {
+			return -1;
+		}
+	}
+
+	priv->dma_chaining = dma_info->dma_chaining;
+	priv->ren = dma_info->ren;
+
+	if (dma_info->sourceType != DMA_TYPE_FIFO
+	    && dma_info->destType != DMA_TYPE_FIFO) {
+		if (dma_info->ren) {
+			printk(KERN_INFO
+			       "Warning:request enable just affect source or destination port is FIFO !\n");
+			priv->ren = 0;
+		}
+	}
+
+	if (dma_info->M2D_Valid) {
+		if (dma_info->msel) {
+			__raw_writel(dma_info->W,
+				     IO_ADDRESS(DMA_BASE_ADDR) + DMA_WSRB);
+			__raw_writel(dma_info->X,
+				     IO_ADDRESS(DMA_BASE_ADDR) + DMA_XSRB);
+			__raw_writel(dma_info->Y,
+				     IO_ADDRESS(DMA_BASE_ADDR) + DMA_YSRB);
+
+		} else {
+			__raw_writel(dma_info->W,
+				     IO_ADDRESS(DMA_BASE_ADDR) + DMA_WSRA);
+			__raw_writel(dma_info->X,
+				     IO_ADDRESS(DMA_BASE_ADDR) + DMA_XSRA);
+			__raw_writel(dma_info->Y,
+				     IO_ADDRESS(DMA_BASE_ADDR) + DMA_YSRA);
+		}
+	}
+
+	dma_base = (dma_regs_t *) (priv->dma_base);
+
+	__raw_writel(dma_info->burstLength, &(dma_base->BurstLength));
+	__raw_writel(dma_info->request, &(dma_base->RequestSource));
+
+	if (dma_info->ren) {
+		reg = dma_info->busuntils & 0x1FFFF;
+		if (dma_info->rto_en) {
+			reg |= 0xE000;
+		}
+		__raw_writel(reg, &(dma_base->BusUtilt));
+	} else {
+		__raw_writel(dma_info->busuntils, &(dma_base->BusUtilt));
+	}
+
+	reg = __raw_readl(&(dma_base->Ctl)) & (~(DMA_CTL_ACRPT | DMA_CTL_RPT));
+
+	if (dma_info->dir) {
+		reg |= DMA_CTL_MDIR;
+	} else {
+		reg &= ~DMA_CTL_MDIR;
+	}
+
+	if (priv->ren) {
+		reg |= DMA_CTL_REN;
+	} else {
+		reg &= ~DMA_CTL_REN;
+	}
+
+	if ((dma_info->M2D_Valid) && (dma_info->msel)) {
+		reg |= DMA_CTL_MSEL;
+	} else {
+		reg &= ~DMA_CTL_MSEL;
+	}
+
+	if (dma_info->mode) {
+		DMA_CTL_SET_SMOD(reg, dma_info->destType);
+		DMA_CTL_SET_SSIZ(reg, dma_info->destPort);
+		DMA_CTL_SET_DMOD(reg, dma_info->sourceType);
+		DMA_CTL_SET_DSIZ(reg, dma_info->sourcePort);
+	} else {
+		DMA_CTL_SET_SMOD(reg, dma_info->sourceType);
+		DMA_CTL_SET_SSIZ(reg, dma_info->sourcePort);
+		DMA_CTL_SET_DMOD(reg, dma_info->destType);
+		DMA_CTL_SET_DSIZ(reg, dma_info->destPort);
+	}
+
+	__raw_writel(reg, &(dma_base->Ctl));
+
+	__clear_dma_interrupt(dma->channel);
+	unmask_dma_interrupt(dma->channel);
+
+	disable_dma_clk();
+	return 0;
+}
+
+/* setup interrupt and setup dma channel by dma parameter  */
+static inline int __init_dma_channel(mxc_dma_channel_t * chan,
+				     mx2_dma_info_t * dma_info)
+{
+	mx2_dma_priv_t *dma_private = (mx2_dma_priv_t *) chan->private;
+	dma_regs_t *dma_base;
+	int ret;
+
+	mask_dma_interrupt(chan->channel);
+	ret =
+	    request_irq(dma_private->dma_irq, dma_irq_handler,
+			IRQF_DISABLED | IRQF_SHARED, chan->dev_name, (void *)chan);
+	if (ret) {
+		printk(KERN_ERR
+		       "%s: unable to request IRQ %d for DMA channel\n",
+		       chan->dev_name, dma_private->dma_irq);
+		return ret;
+	}
+
+	enable_dma_clk();
+
+	dma_base = (dma_regs_t *) (dma_private->dma_base);
+	__raw_writel(0, &(dma_base->Ctl));
+
+	ret = 0;
+	if ((ret = setup_dma_channel(chan, dma_info))) {
+		free_irq(dma_private->dma_irq, (void *)chan);
+	}
+	disable_dma_clk();
+	return 0;
+}
+
+/* initialize buffer descriptor ring.*/
+static inline void init_dma_bd(mx2_dma_priv_t * private)
+{
+	int i;
+	mx2_dma_bd_t *pbd;
+	private->bd_rd = private->bd_wr = 0;
+	atomic_set(&(private->bd_used), 0);
+	for (i = 0, pbd = private->bd_ring; i < MAX_BD_SIZE; i++, pbd++) {
+		pbd->state = 0;
+	}
+}
+
+/* add dma buffer into buffer descriptor ring */
+static inline int fill_dma_bd(mxc_dma_channel_t * dma,
+			      mxc_dma_requestbuf_t * buf, int num,
+			      mxc_dma_mode_t mode)
+{
+	int i, wr;
+	unsigned long flags, mask;
+	mx2_dma_priv_t *priv = dma->private;
+	mx2_dma_bd_t *p, *q;
+
+	if ((atomic_read(&(priv->bd_used)) + num) > MAX_BD_SIZE) {
+		return -EBUSY;
+	}
+
+	for (i = 0; i < num; i++) {
+		wr = priv->bd_wr;
+		p = priv->bd_ring + wr;
+		p->mode = mode;
+		p->count = buf[i].num_of_bytes;
+		p->src_addr = buf[i].src_addr;
+		p->dst_addr = buf[i].dst_addr;
+		if (i == num - 1) {
+			p->state = DMA_BD_ST_LAST | DMA_BD_ST_PEND;
+		} else {
+			p->state = DMA_BD_ST_PEND;
+		}
+		priv->bd_wr = (wr + 1) % MAX_BD_SIZE;
+		atomic_inc(&(priv->bd_used));
+
+		if (atomic_read(&(priv->bd_used)) != 2)
+			continue;
+		/* Disable interrupt of this channel */
+		local_irq_save(flags);
+		local_irq_disable();
+		save_dma_interrupt(mask);
+		mask_dma_interrupt(dma->channel);
+		local_irq_restore(flags);
+		/*TODO ::
+		 *  If channel is transfering and supports chain_buffer,
+		 *  when the new buffer is 2st buffer , repeat must be enabled
+		 */
+		if (priv->dma_chaining && dma->active) {
+			q = priv->bd_ring + priv->bd_rd;
+			if (q && (q->state & DMA_BD_ST_BUSY)) {
+				if (atomic_read(&(priv->bd_used)) == 2) {
+					setup_dmac(dma);
+				}
+			}
+		}
+		restore_dma_interrupt(mask);
+	}
+	return 0;
+}
+
+/* add sg-list into buffer descriptor ring */
+static inline int fill_dma_bd_by_sg(mxc_dma_channel_t * dma,
+				    struct scatterlist *sg, int num,
+				    int real_bytes, mxc_dma_mode_t mode)
+{
+	int i, wr, total_bytes = real_bytes;
+	unsigned long flags, mask;
+	mx2_dma_priv_t *priv = dma->private;
+	mx2_dma_bd_t *p, *q;
+	if ((atomic_read(&(priv->bd_used)) + num) > MAX_BD_SIZE) {
+		return -EBUSY;
+	}
+
+	for (i = 0; i < num && ((real_bytes <= 0) || (total_bytes > 0)); i++) {
+		wr = priv->bd_wr;
+		p = priv->bd_ring + wr;
+		p->mode = mode;
+		if (real_bytes > 0) {
+			if (sg[i].length >= total_bytes) {
+				p->count = total_bytes;
+			} else {
+				p->count = sg[i].length;
+			}
+			total_bytes -= p->count;
+		} else {
+			p->count = sg[i].length;
+		}
+		if (mode == MXC_DMA_MODE_READ) {
+			p->src_addr = priv->dma_info->per_address;
+			p->dst_addr = sg[i].dma_address;
+		} else {
+			p->dst_addr = priv->dma_info->per_address;
+			p->src_addr = sg[i].dma_address;
+		}
+		if ((i == num - 1) || ((real_bytes > 0) && (total_bytes == 0))) {
+			p->state = DMA_BD_ST_LAST | DMA_BD_ST_PEND;
+		} else {
+			p->state = DMA_BD_ST_PEND;
+		}
+		priv->bd_wr = (wr + 1) % MAX_BD_SIZE;
+		atomic_inc(&(priv->bd_used));
+
+		if (atomic_read(&(priv->bd_used)) != 2)
+			continue;
+		/* Disable interrupt of this channel */
+		local_irq_save(flags);
+		local_irq_disable();
+		save_dma_interrupt(mask);
+		mask_dma_interrupt(dma->channel);
+		local_irq_restore(flags);
+		/*TODO ::
+		 *  If channel is transfering and supports chain_buffer,
+		 *  when the new buffer is 2st buffer , repeat must be enabled
+		 */
+		if (priv->dma_chaining && dma->active) {
+			q = next_dma_bd(priv);
+			if (q && (q->state & DMA_BD_ST_BUSY)) {
+				if ((atomic_read(&(priv->bd_used))) == 2) {
+					setup_dmac(dma);
+				}
+			}
+		}
+		restore_dma_interrupt(mask);
+	}
+	return 0;
+}
+
+/* select next buffer descripter to transfer. */
+static inline int consume_dma_bd(mxc_dma_channel_t * dma, int error)
+{
+	mx2_dma_priv_t *priv = dma->private;
+	mx2_dma_bd_t *p;
+	int notify = 0;
+	if (priv == NULL) {
+		printk(KERN_ERR
+		       "request dma channel %d which is not initialize completed.!\n",
+		       dma->channel);
+		return 1;
+	}
+	if (error != MXC_DMA_DONE) {
+		for (p = priv->bd_ring + priv->bd_rd;
+		     atomic_read(&(priv->bd_used)) > 0;) {
+			priv->bd_rd = (priv->bd_rd + 1) % MAX_BD_SIZE;
+			atomic_dec(&(priv->bd_used));
+			if (p->state & DMA_BD_ST_LAST) {
+				p->state = 0;
+				break;
+			}
+			p->state = 0;
+		}
+		notify = 1;
+	} else {
+		p = priv->bd_ring + priv->bd_rd;
+		priv->bd_rd = (priv->bd_rd + 1) % MAX_BD_SIZE;
+		atomic_dec(&(priv->bd_used));
+		notify = (p->state & DMA_BD_ST_LAST) == DMA_BD_ST_LAST;
+	}
+	if (atomic_read(&(priv->bd_used)) <= 0) {
+		dma->active = 0;
+		atomic_dec(&g_dma_actived);
+	} else {
+		setup_dmac(dma);
+	}
+	return notify;
+}
+
+/**
+ * mxc_dma_request - Generally called by the driver at open time.
+ * @channel_id: A pre-defined id
+ * @dev_name: module name or device name
+ *
+ * The DMA driver would do any initialization steps that is required
+ * to get the channel ready for data transfer.
+ * The peripheral driver would specify the @channel_id associated with
+ * its peripheral. This would be used by the DMA driver to identify the
+ * peripheral requesting DMA and do the necessary setup on the channel
+ * associated with the particular peripheral.
+ * The DMA driver could use static or dynamic DMA channel allocation.
+ */
+int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name)
+{
+	mxc_dma_channel_t *dma;
+	mx2_dma_priv_t *dma_private = NULL;
+	mx2_dma_info_t *dma_info = mxc_dma_get_info(channel_id);
+	int index;
+	int ret;
+
+	if (dma_info == NULL) {
+		return -EINVAL;
+	}
+
+	if ((index = get_dma_channel(dma_info->dma_chan)) < 0) {
+		return -ENODEV;
+	}
+
+	dma = g_dma_channels + index;
+	dma_private = (mx2_dma_priv_t *) dma->private;
+	if (dma_private == NULL) {
+		printk(KERN_ERR
+		       "request dma channel %d which is not initialize completed.!\n",
+		       index);
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	dma->active = 0;
+	dma_private->dma_info = NULL;
+	dma->cb_fn = NULL;
+	dma->cb_args = NULL;
+	dma->dev_name = dev_name;
+	dma->mode = dma_info->mode ? MXC_DMA_MODE_WRITE : MXC_DMA_MODE_READ;
+	init_dma_bd(dma_private);
+
+	if (!(ret = __init_dma_channel(dma, dma_info))) {
+		dma_private->dma_info = dma_info;
+		return index;
+	}
+      exit:
+	put_dma_channel(index);
+	return ret;
+}
+EXPORT_SYMBOL(mxc_dma_request);
+
+/**
+ * mxc_dma_free - Generally called by the driver at close time.
+ * @channel_num: the channel number returned at request time
+ *
+ * The DMA driver would do any cleanup associated with this channel.
+ * @channel_num would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel associated with
+ * the particular peripheral
+ */
+int mxc_dma_free(int channel_num)
+{
+	mxc_dma_channel_t *dma;
+	mx2_dma_priv_t *dma_private;
+
+	if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+		return -EINVAL;
+	}
+
+	dma = g_dma_channels + channel_num;
+	dma_private = (mx2_dma_priv_t *) dma->private;
+	if (dma_private == NULL) {
+		printk(KERN_ERR
+		       "Free dma %d which is not completed initialization \n",
+		       channel_num);
+		return -EFAULT;
+	}
+	if (dma->lock) {
+		if (dma->active) {	/*Channel is busy */
+			mxc_dma_disable(channel_num);
+		}
+
+		dma_private = (mx2_dma_priv_t *) dma->private;
+
+		enable_dma_clk();
+		mask_dma_interrupt(channel_num);
+		disable_dma_clk();
+
+		free_irq(dma_private->dma_irq, (void *)dma);
+		put_dma_channel(channel_num);
+	}
+	return 0;
+}
+EXPORT_SYMBOL(mxc_dma_free);
+
+/**
+ * mxc_dma_config - Configure the buffers specified for DMA usage
+ * @channel_num: The channel number returned at request time
+ * @dma_buf: An array of physical addresses to the user defined buffers
+ * @num_buf: Nnumber of buffers in the array
+ * @mode: Specifies whether this is READ or WRITE operation
+ *
+ * This works on buffer sepecified by the user into dma channel. The
+ * caller must call mxc_dma_enable to start this transfer.
+ * @channel_num will be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel associated with the
+ * particular peripheral.
+ * The caller must guarantee the @dma_buf is available until the
+ * transfer is completed.
+ */
+int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf, int num_buf,
+		   mxc_dma_mode_t mode)
+{
+	mxc_dma_channel_t *dma;
+	mx2_dma_priv_t *dma_private;
+
+	if ((dma_buf == NULL) || (num_buf < 1)) {
+		return -EINVAL;
+	}
+
+	if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+		return -EINVAL;
+	}
+
+	dma = g_dma_channels + channel_num;
+	dma_private = (mx2_dma_priv_t *) dma->private;
+	if (dma_private == NULL) {
+		printk(KERN_ERR
+		       "config dma %d which is not completed initialization \n",
+		       channel_num);
+		return -EFAULT;
+	}
+
+	if (dma->lock == 0) {
+		return -ENODEV;
+	}
+
+	/*TODO: dma chainning can not support on bi-dir channel */
+	if (dma_private->dma_chaining && (dma->mode != mode)) {
+		return -EINVAL;
+	}
+
+	/*TODO: fill dma buffer into driver .
+	 * If driver is no enought buffer to save them , it will return -EBUSY
+	 */
+	if (fill_dma_bd(dma, dma_buf, num_buf, mode)) {
+		return -EBUSY;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mxc_dma_config);
+
+/**
+ * mxc_dma_sg_config - Configure the scatterlist for a DMA channel
+ * @channel_num: The channel number returned at request time
+ * @sg: A scatterlist of buffers
+ * @num_buf: Number of buffers in the array
+ * @num_of_bytes: Total number of bytes to transfer
+ * @mode: Specifies whether this is READ or WRITE operation
+ *
+ * This is a slight variation of mxc_dma_config(), it is provided for the
+ * convenience of drivers that have a scatterlist passed into them. It is
+ * the calling driver's responsibility to have the correct physical
+ * address filled in the "dma_address" field of the scatterlist.
+ * @channel_num will be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel associated with
+ * the particular peripheral
+ * The caller must guarantee the @sg is available until the transfer is
+ * completed.
+ * If @num_of_bytes is set to 0, this would imply to use the length field
+ * of the scatterlist for each DMA transfer. Else it would calculate
+ * the size for each DMA transfer.
+ */
+int mxc_dma_sg_config(int channel_num, struct scatterlist *sg,
+		      int num_buf, int num_of_bytes, mxc_dma_mode_t mode)
+{
+	mxc_dma_channel_t *dma;
+	mx2_dma_priv_t *dma_private;
+
+	if ((sg == NULL) || (num_buf < 1) || (num_of_bytes < 0)) {
+		return -EINVAL;
+	}
+
+	if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+		return -EINVAL;
+	}
+
+	dma = g_dma_channels + channel_num;
+	dma_private = (mx2_dma_priv_t *) dma->private;
+	if (dma_private == NULL) {
+		printk(KERN_ERR
+		       "config_sg dma %d which is not completed initialization \n",
+		       channel_num);
+		return -EFAULT;
+	}
+
+	if (dma->lock == 0) {
+		return -ENODEV;
+	}
+
+	/*TODO: dma chainning can not support on bi-dir channel */
+	if (dma_private->dma_chaining && (dma->mode != mode)) {
+		return -EINVAL;
+	}
+
+	/*TODO: fill dma buffer into driver .
+	 * If driver is no enought buffer to save them , it will return -EBUSY
+	 */
+	if (fill_dma_bd_by_sg(dma, sg, num_buf, num_of_bytes, mode)) {
+		return -EBUSY;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(mxc_dma_sg_config);
+
+/**
+ * mxc_dma_callback_set - setup users callback function
+ * @channel_num: The channel number returned at request time
+ * @callback: The callback function
+ * @arg: An argument that gets passed in to the callback function
+ *
+ * @callback gets called as a notification on transfer completion, user
+ * could specify NULL if he does not wish to be notified. @arg could
+ * be used by the user to do any driver specific operations.
+ */
+int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback,
+			 void *arg)
+{
+	mxc_dma_channel_t *dma;
+
+	if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+		return -EINVAL;
+	}
+	dma = g_dma_channels + channel_num;
+
+	if (!dma->lock) {
+		return -ENODEV;
+	}
+
+	if (dma->active) {
+		return -EBUSY;
+	}
+	dma->cb_fn = callback;
+	dma->cb_args = arg;
+	return 0;
+
+}
+EXPORT_SYMBOL(mxc_dma_callback_set);
+
+/**
+ * mxc_dma_disable - Stop the DMA channel and any ongoing transfers.
+ * @channel_num: The channel number returned at request time
+ *
+ * Subsequent use of mxc_dma_enable() will restart the channel and
+ * restart the transfer.
+ */
+int mxc_dma_disable(int channel_num)
+{
+	mxc_dma_channel_t *dma;
+	mx2_dma_priv_t *priv;
+	unsigned long ctrl_val;
+
+	if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+		return -EINVAL;
+	}
+
+	dma = g_dma_channels + channel_num;
+
+	if (dma->lock == 0) {
+		return -EINVAL;
+	}
+
+	if (!dma->active) {
+		return -EINVAL;
+	}
+
+	priv = (mx2_dma_priv_t *) dma->private;
+	if (priv == NULL) {
+		printk(KERN_ERR "disable a uncompleted dma channel %d\n",
+		       channel_num);
+		return -EFAULT;
+	}
+
+	dma->active = 0;
+	enable_dma_clk();
+
+	__clear_dma_interrupt(channel_num);
+	ctrl_val =
+	    __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_CCR(channel_num));
+	ctrl_val &= ~DMA_CTL_CEN;	/* clear CEN bit */
+	__raw_writel(ctrl_val,
+		     IO_ADDRESS(DMA_BASE_ADDR) + DMA_CCR(channel_num));
+	disable_dma_clk();
+	atomic_dec(&g_dma_actived);
+
+	/*TODO: Clear all request buffers */
+	flush_dma_bd(priv);
+	return 0;
+}
+EXPORT_SYMBOL(mxc_dma_disable);
+
+/**
+ * mxc_dma_enable - Start or restart DMA transfer.
+ * @channel_num: The channel number returned at request time
+ */
+int mxc_dma_enable(int channel_num)
+{
+	mxc_dma_channel_t *dma;
+	mx2_dma_priv_t *priv;
+
+	if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+		return -EINVAL;
+	}
+
+	dma = g_dma_channels + channel_num;
+
+	if (dma->lock == 0) {
+		return -EINVAL;
+	}
+
+	priv = (mx2_dma_priv_t *) dma->private;
+	if (priv == NULL) {
+		printk(KERN_ERR "enable a uncompleted dma channel %d\n",
+		       channel_num);
+		return -EFAULT;
+	}
+
+	if (dma->active) {
+		return 0;
+	}
+	dma->active = 1;
+	priv->trans_bytes = 0;
+
+	enable_dma_clk();
+
+	atomic_inc(&g_dma_actived);
+	__clear_dma_interrupt(channel_num);
+
+	setup_dmac(dma);
+	disable_dma_clk();
+	return 0;
+}
+EXPORT_SYMBOL(mxc_dma_enable);
+
+
+/**
+ * mxc_dump_dma_register - Dump DMA registers (debugging purposes)
+ * @channel: Requested channel NO.
+ */
+void mxc_dump_dma_register(int channel)
+{
+	mxc_dma_channel_t *dma = &g_dma_channels[channel];
+	mx2_dma_priv_t *priv = (mx2_dma_priv_t *) dma->private;
+	dma_regs_t *dma_base;
+
+	printk(KERN_INFO "======== Dump dma channel %d \n", channel);
+	if ((unsigned)channel >= MXC_DMA_CHANNELS) {
+		printk(KERN_INFO "Channel number is invalid \n");
+		return;
+	}
+	if (!dma->lock) {
+		printk(KERN_INFO "Channel is not allocated \n");
+		return;
+	}
+
+	printk(KERN_INFO "g_dma_actived = %d\n", atomic_read(&g_dma_actived));
+
+	enable_dma_clk();
+	dma_base = (dma_regs_t *) (priv->dma_base);
+	printk(KERN_INFO "DMA COMMON REGISTER\n");
+	printk(KERN_INFO "DMA CONTROL             DMA_DCR: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR));
+	printk(KERN_INFO "DMA Interrupt status    DMA_DISR: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DISR));
+	printk(KERN_INFO "DMA Interrupt Mask      DMA_DIMR: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DIMR));
+	printk(KERN_INFO "DMA Burst Time Out      DMA_DBTOSR: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBTOSR));
+	printk(KERN_INFO "DMA request Time Out    DMA_DRTOSR: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DRTOSR));
+	printk(KERN_INFO "DMA Transfer Error      DMA_DSESR: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DSESR));
+	printk(KERN_INFO "DMA DMA_Overflow        DMA_DBOSR: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBOSR));
+	printk(KERN_INFO "DMA Burst Time OutCtl   DMA_BurstTOCtl: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBTOCR));
+
+	printk(KERN_INFO "DMA 2D X size: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_XSRA));
+	printk(KERN_INFO "DMA 2D Y size: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_YSRA));
+	printk(KERN_INFO "DMA 2D Z size: %08x\n",
+	       __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_WSRA));
+
+	printk(KERN_INFO "DMA Chan %2d  Sourc     SourceAddr: %08x\n", channel,
+	       __raw_readl(&(dma_base->SourceAddr)));
+	printk(KERN_INFO "DMA Chan %2d  dest      DestAddr: %08x\n", channel,
+	       __raw_readl(&(dma_base->DestAddr)));
+	printk(KERN_INFO "DMA Chan %2d  count     Count: %08x\n", channel,
+	       __raw_readl(&(dma_base->Count)));
+	printk(KERN_INFO "DMA Chan %2d  Ctl       Ctl: %08x\n", channel,
+	       __raw_readl(&(dma_base->Ctl)));
+	printk(KERN_INFO "DMA Chan %2d  request   RequestSource: %08x\n",
+	       channel, __raw_readl(&(dma_base->RequestSource)));
+	printk(KERN_INFO "DMA Chan %2d  burstL    BurstLength: %08x\n", channel,
+	       __raw_readl(&(dma_base->BurstLength)));
+	printk(KERN_INFO "DMA Chan %2d  requestTO ReqTimeout: %08x\n", channel,
+	       __raw_readl(&(dma_base->ReqTimeout)));
+	printk(KERN_INFO "DMA Chan %2d  BusUtilt  BusUtilt: %08x\n", channel,
+	       __raw_readl(&(dma_base->BusUtilt)));
+
+	disable_dma_clk();
+}
+EXPORT_SYMBOL(mxc_dump_dma_register);
+
+#ifdef DMA_PM
+
+static int channel_in_use(void)
+{
+	int i;
+	for (i = 0; i < MXC_DMA_CHANNELS; i++) {
+		if (dma_chan[i].lock)
+			return 1;
+	}
+	return 0;
+}
+
+int mxc_dma_pm_standby(void)
+{
+	unsigned long reg;
+	if (dma_pm_status == DMA_PMST_STANDBY)
+		return 0;
+
+	if (!channel_in_use()) {
+		/*Disable DMA */
+		__disable_dma_clk();
+		dma_pm_status = DMA_PMST_STANDBY;
+		return 0;
+	}
+	return -1;
+}
+
+int mxc_dma_pm_resume(void)
+{
+	unsigned long reg;
+	if (dma_pm_status == DMA_PMST_RESUME)
+		return 0;
+
+	/*Enable HCLK_DMA and DMA(ipg clock) */
+	dma_pm_status = DMA_PMST_RESUME;
+	return 0;
+}
+
+int mxc_dma_pm_suspend(void)
+{
+	unsigned long reg;
+	if (dma_pm_status == DMA_PMST_SUSPEND)
+		return 0;
+
+	if (!channel_in_use()) {
+		/*Disable DMA */
+		__disable_dma_clk();
+		dma_pm_status = DMA_PMST_SUSPEND;
+		return 0;
+	}
+	return -1;
+}
+
+int mxc_dma_pm_handler(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+	int ret = 0;
+	switch (rqst) {
+		/*APM doesn't send PM_STANDBY and PM_STANDBY_RESUME request now. */
+	case PM_SUSPEND:
+		ret = dma_pm_suspend();
+		break;
+	case PM_RESUME:
+		ret = dma_pm_resume();
+		break;
+	}
+	return ret;
+}
+
+#endif				/*DMA_PM */
+
+int __init mxc_dma_init(void)
+{
+	int i;
+	mxc_dma_channel_t *dma = g_dma_channels;
+	mx2_dma_priv_t *private = g_dma_privates;
+
+	memset(dma, 0, sizeof(mxc_dma_channel_t) * MXC_DMA_CHANNELS);
+	for (i = 0; i < MXC_DMA_CHANNELS; i++, dma++, private++) {
+		dma->channel = i;
+		dma->private = private;
+		private->dma_base =
+		    (unsigned int)(IO_ADDRESS(DMA_BASE_ADDR + DMA_CH_BASE(i)));
+		private->dma_irq = i + MXC_DMA_INTR_0;	/*Dma channel interrupt number */
+		private->bd_ring = &g_dma_bd_table[i][0];
+	}
+
+	mxc_dma_load_info(g_dma_channels);
+
+	dma_clk = clk_get(NULL, "dma_clk");
+	clk_enable(dma_clk);
+
+	__raw_writel(0x2, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR);	/*reset DMA; */
+
+	disable_dma_clk();
+
+	/*use module init because create_proc after init_dma */
+	g_proc_dir = create_proc_entry("dma", 0, NULL);
+	g_proc_dir->read_proc = (read_proc_t *) mxc_get_dma_list;
+	g_proc_dir->data = NULL;
+
+#ifdef DMA_PM
+	/* Register the device with power management. */
+	dma_pm = pm_register(PM_DMA_DEV, PM_SYS_UNKNOWN, dma_pm_handler);
+#endif
+
+	return 0;
+}
+
+arch_initcall(mxc_dma_init);
+
Index: arch/arm/plat-mxc/Kconfig
===================================================================
--- arch/arm/plat-mxc/Kconfig.orig
+++ arch/arm/plat-mxc/Kconfig
@@ -1,10 +1,16 @@
 menu "Freescale MXC Implementations"
 
 choice
-	prompt "MXC/iMX System Type"
+	prompt "MXC/iMX Base Type"
 	depends on ARCH_MXC
 	default ARCH_MX3
 
+config ARCH_MX2
+	bool "MX2-based"
+	select GENERIC_TIME
+	help
+	  This enables support for systems based on the Freescale i.MX2 family
+
 config ARCH_MX3
 	bool "MX3-based"
 	help
Index: include/asm-arm/arch-mxc/iim.h
===================================================================
--- /dev/null
+++ include/asm-arm/arch-mxc/iim.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_IIM_H__
+#define __ASM_ARCH_MXC_IIM_H__
+
+/* Register offsets */
+#define MXC_IIMSTAT             0x0000
+#define MXC_IIMSTATM            0x0004
+#define MXC_IIMERR              0x0008
+#define MXC_IIMEMASK            0x000C
+#define MXC_IIMFCTL             0x0010
+#define MXC_IIMUA               0x0014
+#define MXC_IIMLA               0x0018
+#define MXC_IIMSDAT             0x001C
+#define MXC_IIMPREV             0x0020
+#define MXC_IIMSREV             0x0024
+#define MXC_IIMPRG_P            0x0028
+#define MXC_IIMSCS0             0x002C
+#define MXC_IIMSCS1             0x0030
+#define MXC_IIMSCS2             0x0034
+#define MXC_IIMSCS3             0x0038
+#define MXC_IIMFBAC0            0x0800
+#define MXC_IIMJAC              0x0804
+#define MXC_IIMHWV1             0x0808
+#define MXC_IIMHWV2             0x080C
+#define MXC_IIMHAB0             0x0810
+#define MXC_IIMHAB1             0x0814
+/* Definitions for i.MX27 TO2 */
+#define MXC_IIMMAC              0x0814
+#define MXC_IIMPREV_FUSE        0x0818
+#define MXC_IIMSREV_FUSE        0x081C
+#define MXC_IIMSJC_CHALL_0      0x0820
+#define MXC_IIMSJC_CHALL_7      0x083C
+#define MXC_IIMFB0UC17          0x0840
+#define MXC_IIMFB0UC255         0x0BFC
+#define MXC_IIMFBAC1            0x0C00
+/* Definitions for i.MX27 TO2 */
+#define MXC_IIMSUID             0x0C04
+#define MXC_IIMKEY0             0x0C04
+#define MXC_IIMKEY20            0x0C54
+#define MXC_IIMSJC_RESP_0       0x0C58
+#define MXC_IIMSJC_RESP_7       0x0C74
+#define MXC_IIMFB1UC30          0x0C78
+#define MXC_IIMFB1UC255         0x0FFC
+
+/* Bit definitions */
+
+#define MXC_IIMHWV1_WLOCK               (0x1 << 7)
+#define MXC_IIMHWV1_MCU_ENDIAN          (0x1 << 6)
+#define MXC_IIMHWV1_DSP_ENDIAN          (0x1 << 5)
+#define MXC_IIMHWV1_BOOT_INT            (0x1 << 4)
+#define MXC_IIMHWV1_SCC_DISABLE         (0x1 << 3)
+#define MXC_IIMHWV1_HANTRO_DISABLE      (0x1 << 2)
+#define MXC_IIMHWV1_MEMSTICK_DIS        (0x1 << 1)
+
+#define MXC_IIMHWV2_WLOCK               (0x1 << 7)
+#define MXC_IIMHWV2_BP_SDMA             (0x1 << 6)
+#define MXC_IIMHWV2_SCM_DCM             (0x1 << 5)
+
+#endif /* __ASM_ARCH_MXC_IIM_H__ */
Index: include/asm-arm/arch-mxc/entry-macro-mx27.S
===================================================================
--- /dev/null
+++ include/asm-arm/arch-mxc/entry-macro-mx27.S
@@ -0,0 +1,41 @@
+/*
+ *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+	@ this macro disables fast irq (not implemented)
+	.macro	disable_fiq
+	.endm
+
+	@ this macro checks which interrupt occured
+	@ and returns its number in irqnr
+	@ and returns if an interrupt occured in irqstat
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	@ Can't use IO_ADDRESS macro. Otherwise compilation error
+	ldr	\irqstat, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR)
+	@ Load offset & priority of the highest priority
+	@ interrupt pending.
+	ldr	\irqnr, [\irqstat, #0x40]	@ this is AVIC_NIVECSR
+	@ Shift off the priority leaving the offset or
+	@ "interrupt number"
+	mov	\irqnr, \irqnr, lsr #16
+	ldr	\irqstat, =1	@ dummy compare
+	ldr	\base, =0xFFFF	// invalid interrupt
+	cmp	\irqnr, \base
+	bne	1001f
+	ldr	\irqstat, =0
+	1001:
+	tst	\irqstat, #1	@ to make the condition code = TRUE
+	.endm
+
+	@ irq priority table (not used)
+	.macro	irq_prio_table
+	.endm
Index: include/asm-arm/arch-mxc/mx27.h
===================================================================
--- /dev/null
+++ include/asm-arm/arch-mxc/mx27.h
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_MX27_H__
+#define __ASM_ARCH_MXC_MX27_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+#include <asm/arch/mx27_pins.h>
+
+/*
+ * defines the OS clock tick rate
+ */
+#define CLOCK_TICK_RATE         13300000
+
+/*
+ * Register an interrupt handler for the SMN as well as the SCC.  In some
+ * implementations, the SMN is not connected at all, and in others, it is
+ * on the same interrupt line as the SCM. Comment this line out accordingly
+ */
+#define USE_SMN_INTERRUPT
+
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+#define MXC_UART_NR 6
+/*
+ * This option is used to set or clear the RXDMUXSEL bit in control reg 3.
+ * Certain platforms need this bit to be set in order to receive Irda data.
+ */
+#define MXC_UART_IR_RXDMUX      0x0004
+/*
+ * This option is used to set or clear the RXDMUXSEL bit in control reg 3.
+ * Certain platforms need this bit to be set in order to receive UART data.
+ */
+#define MXC_UART_RXDMUX         0x0004
+
+/*
+ * IRAM
+ */
+#define IRAM_BASE_ADDR          0xFFFF4C00	/* internal ram */
+
+/*
+ *  Register offests.
+ */
+#define AIPI_BASE_ADDR          0x10000000
+#define AIPI_BASE_ADDR_VIRT     0xD4000000
+#define AIPI_SIZE               SZ_1M
+
+#define DMA_BASE_ADDR           (AIPI_BASE_ADDR + 0x01000)
+#define WDOG_BASE_ADDR          (AIPI_BASE_ADDR + 0x02000)
+#define GPT1_BASE_ADDR          (AIPI_BASE_ADDR + 0x03000)
+#define GPT2_BASE_ADDR          (AIPI_BASE_ADDR + 0x04000)
+#define GPT3_BASE_ADDR          (AIPI_BASE_ADDR + 0x05000)
+#define PWM_BASE_ADDR           (AIPI_BASE_ADDR + 0x06000)
+#define RTC_BASE_ADDR           (AIPI_BASE_ADDR + 0x07000)
+#define KPP_BASE_ADDR           (AIPI_BASE_ADDR + 0x08000)
+#define OWIRE_BASE_ADDR         (AIPI_BASE_ADDR + 0x09000)
+#define UART1_BASE_ADDR         (AIPI_BASE_ADDR + 0x0A000)
+#define UART2_BASE_ADDR         (AIPI_BASE_ADDR + 0x0B000)
+#define UART3_BASE_ADDR         (AIPI_BASE_ADDR + 0x0C000)
+#define UART4_BASE_ADDR         (AIPI_BASE_ADDR + 0x0D000)
+#define CSPI1_BASE_ADDR         (AIPI_BASE_ADDR + 0x0E000)
+#define CSPI2_BASE_ADDR         (AIPI_BASE_ADDR + 0x0F000)
+#define SSI1_BASE_ADDR          (AIPI_BASE_ADDR + 0x10000)
+#define SSI2_BASE_ADDR          (AIPI_BASE_ADDR + 0x11000)
+#define I2C_BASE_ADDR           (AIPI_BASE_ADDR + 0x12000)
+#define SDHC1_BASE_ADDR         (AIPI_BASE_ADDR + 0x13000)
+#define SDHC2_BASE_ADDR         (AIPI_BASE_ADDR + 0x14000)
+#define GPIO_BASE_ADDR          (AIPI_BASE_ADDR + 0x15000)
+#define AUDMUX_BASE_ADDR        (AIPI_BASE_ADDR + 0x16000)
+
+#define CSPI3_BASE_ADDR         (AIPI_BASE_ADDR + 0x17000)
+#define MSHC_BASE_ADDR          (AIPI_BASE_ADDR + 0x18000)
+#define GPT5_BASE_ADDR          (AIPI_BASE_ADDR + 0x19000)
+#define GPT4_BASE_ADDR          (AIPI_BASE_ADDR + 0x1A000)
+#define UART5_BASE_ADDR         (AIPI_BASE_ADDR + 0x1B000)
+#define UART6_BASE_ADDR         (AIPI_BASE_ADDR + 0x1C000)
+#define I2C2_BASE_ADDR          (AIPI_BASE_ADDR + 0x1D000)
+#define SDHC3_BASE_ADDR         (AIPI_BASE_ADDR + 0x1E000)
+#define GPT6_BASE_ADDR          (AIPI_BASE_ADDR + 0x1F000)
+
+#define LCDC_BASE_ADDR          (AIPI_BASE_ADDR + 0x21000)
+#define SLCDC_BASE_ADDR         (AIPI_BASE_ADDR + 0x22000)
+#define VPU_BASE_ADDR           (AIPI_BASE_ADDR + 0x23000)
+#define USBOTG_BASE_ADDR        (AIPI_BASE_ADDR + 0x24000)
+/* for mx27*/
+#define OTG_BASE_ADDR           USBOTG_BASE_ADDR
+#define SAHARA_BASE_ADDR        (AIPI_BASE_ADDR + 0x25000)
+#define EMMA_BASE_ADDR          (AIPI_BASE_ADDR + 0x26400)
+#define CCM_BASE_ADDR           (AIPI_BASE_ADDR + 0x27000)
+#define SYSCTRL_BASE_ADDR       (AIPI_BASE_ADDR + 0x27800)
+#define IIM_BASE_ADDR           (AIPI_BASE_ADDR + 0x28000)
+
+#define RTIC_BASE_ADDR          (AIPI_BASE_ADDR + 0x2A000)
+#define FEC_BASE_ADDR           (AIPI_BASE_ADDR + 0x2B000)
+#define SCC_BASE_ADDR           (AIPI_BASE_ADDR + 0x2C000)
+#define ETB_BASE_ADDR           (AIPI_BASE_ADDR + 0x3B000)
+#define ETB_RAM_BASE_ADDR       (AIPI_BASE_ADDR + 0x3C000)
+
+#define JAM_BASE_ADDR           (AIPI_BASE_ADDR + 0x3E000)
+#define MAX_BASE_ADDR           (AIPI_BASE_ADDR + 0x3F000)
+
+/*
+ * ROMP and AVIC
+ */
+#define ROMP_BASE_ADDR          0x10041000
+
+#define AVIC_BASE_ADDR          0x10040000
+
+#define SAHB1_BASE_ADDR         0x80000000
+#define SAHB1_BASE_ADDR_VIRT    0xD4100000
+#define SAHB1_SIZE              SZ_1M
+
+#define CSI_BASE_ADDR           (SAHB1_BASE_ADDR + 0x0000)
+#define ATA_BASE_ADDR           (SAHB1_BASE_ADDR + 0x1000)
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define X_MEMC_BASE_ADDR        0xD8000000
+#define X_MEMC_BASE_ADDR_VIRT   0xD4200000
+#define X_MEMC_SIZE             SZ_1M
+
+#define NFC_BASE_ADDR           (X_MEMC_BASE_ADDR)
+#define SDRAMC_BASE_ADDR        (X_MEMC_BASE_ADDR + 0x1000)
+#define WEIM_BASE_ADDR          (X_MEMC_BASE_ADDR + 0x2000)
+#define M3IF_BASE_ADDR          (X_MEMC_BASE_ADDR + 0x3000)
+#define PCMCIA_CTL_BASE_ADDR    (X_MEMC_BASE_ADDR + 0x4000)
+
+/*
+ * Memory regions and CS
+ */
+#define SDRAM_BASE_ADDR         0xA0000000
+#define CSD1_BASE_ADDR          0xB0000000
+
+#define CS0_BASE_ADDR           0xC0000000
+#define CS1_BASE_ADDR           0xC8000000
+#define CS2_BASE_ADDR           0xD0000000
+#define CS3_BASE_ADDR           0xD2000000
+#define CS4_BASE_ADDR           0xD4000000
+#define CS4_BASE_ADDR_VIRT      0xEB000000
+#define CS4_SIZE                SZ_1M
+#define CS5_BASE_ADDR           0xD6000000
+#define PCMCIA_MEM_BASE_ADDR    0xDC000000
+
+/*
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x)   \
+        (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? AIPI_IO_ADDRESS(x):\
+        ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? SAHB1_IO_ADDRESS(x):\
+        ((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\
+        ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\
+        0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+
+#define AIPI_IO_ADDRESS(x)  \
+        (((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT)
+
+#define AVIC_IO_ADDRESS(x)      AIPI_IO_ADDRESS(x)
+
+#define SAHB1_IO_ADDRESS(x)  \
+        (((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT)
+
+#define CS4_IO_ADDRESS(x)  \
+        (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
+
+#define X_MEMC_IO_ADDRESS(x)  \
+        (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+#define PCMCIA_IO_ADDRESS(x) \
+        (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+/*
+ *  MX27 ADS Interrupt numbers
+ */
+#define INT_CCM                 63
+#define INT_IIM                 62
+#define INT_LCDC                61
+#define INT_SLCDC               60
+#define INT_SAHARA              59
+#define INT_SCC_SCM             58
+#define INT_SCC_SMN             57
+#define INT_USB3                56
+#define INT_USB2                55
+#define INT_USB1                54
+#define INT_VPU                53
+#define INT_EMMAPP              52
+#define INT_EMMAPRP             51
+#define INT_FEC                 50
+#define INT_UART5               49
+#define INT_UART6               48
+#define INT_DMACH15             47
+#define INT_DMACH14             46
+#define INT_DMACH13             45
+#define INT_DMACH12             44
+#define INT_DMACH11             43
+#define INT_DMACH10             42
+#define INT_DMACH9              41
+#define INT_DMACH8              40
+#define INT_DMACH7              39
+#define INT_DMACH6              38
+#define INT_DMACH5              37
+#define INT_DMACH4              36
+#define INT_DMACH3              35
+#define INT_DMACH2              34
+#define INT_DMACH1              33
+#define INT_DMACH0              32
+#define INT_CSI                 31
+#define INT_ATA                 30
+#define INT_NANDFC              29
+#define INT_PCMCIA              28
+#define INT_WDOG                27
+#define INT_GPT1                26
+#define INT_GPT2                25
+#define INT_GPT3                24
+#define INT_GPT                 INT_GPT1
+#define INT_PWM                 23
+#define INT_RTC                 22
+#define INT_KPP                 21
+#define INT_UART1               20
+#define INT_UART2               19
+#define INT_UART3               18
+#define INT_UART4               17
+#define INT_CSPI1               16
+#define INT_CSPI2               15
+#define INT_SSI1                14
+#define INT_SSI2                13
+#define INT_I2C                 12
+#define INT_SDHC1               11
+#define INT_SDHC2               10
+#define INT_SDHC3               9
+#define INT_GPIO                8
+#define INT_SDHC                7
+#define INT_CSPI3               6
+#define INT_RTIC                5
+#define INT_GPT4                4
+#define INT_GPT5                3
+#define INT_GPT6                2
+#define INT_I2C2                1
+
+#define MXC_MAX_INT_LINES       64
+#define MXC_MAX_EXT_LINES       0
+
+#define MXC_MUX_GPIO_INTERRUPTS 1
+#define MXC_GPIO_BASE           (MXC_MAX_INT_LINES)
+
+/*
+ * Number of GPIO port as defined in the IC Spec
+ */
+#define GPIO_PORT_NUM           6
+/*
+ * Number of GPIO pins per port
+ */
+#define GPIO_NUM_PIN            32
+
+#define DMA_REQ_NFC             37
+#define DMA_REQ_SDHC3           36
+#define DMA_REQ_UART6_RX        35
+#define DMA_REQ_UART6_TX        34
+#define DMA_REQ_UART5_RX        33
+#define DMA_REQ_UART5_TX        32
+#define DMA_REQ_CSI_RX          31
+#define DMA_REQ_CSI_STAT        30
+#define DMA_REQ_ATA_RCV         29
+#define DMA_REQ_ATA_TX          28
+#define DMA_REQ_UART1_TX        27
+#define DMA_REQ_UART1_RX        26
+#define DMA_REQ_UART2_TX        25
+#define DMA_REQ_UART2_RX        24
+#define DMA_REQ_UART3_TX        23
+#define DMA_REQ_UART3_RX        22
+#define DMA_REQ_UART4_TX        21
+#define DMA_REQ_UART4_RX        20
+#define DMA_REQ_CSPI1_TX        19
+#define DMA_REQ_CSPI1_RX        18
+#define DMA_REQ_CSPI2_TX        17
+#define DMA_REQ_CSPI2_RX        16
+#define DMA_REQ_SSI1_TX1        15
+#define DMA_REQ_SSI1_RX1        14
+#define DMA_REQ_SSI1_TX0        13
+#define DMA_REQ_SSI1_RX0        12
+#define DMA_REQ_SSI2_TX1        11
+#define DMA_REQ_SSI2_RX1        10
+#define DMA_REQ_SSI2_TX0        9
+#define DMA_REQ_SSI2_RX0        8
+#define DMA_REQ_SDHC1           7
+#define DMA_REQ_SDHC2           6
+#define DMA_REQ_MSHC            4
+#define DMA_REQ_EXT             3
+#define DMA_REQ_CSPI3_TX        2
+#define DMA_REQ_CSPI3_RX        1
+
+#define MXC_TIMER_GPT1          1
+#define MXC_TIMER_GPT2          2
+#define MXC_TIMER_GPT3          3
+#define MXC_TIMER_GPT4          4
+#define MXC_TIMER_GPT5          5
+#define MXC_TIMER_GPT6          6
+
+/*
+ * NFMS bit in FMCR register for pagesize of nandflash
+ */
+#define NFMS (*((volatile u32 *)IO_ADDRESS(SYSCTRL_BASE_ADDR+0x14)))
+
+#define NFMS_BIT 5
+
+/*
+ * GPT clock source mask and offset bit definition
+ */
+#define GPT_CTRL_MASK           0xFFFFFFF1
+#define GPT_CTRL_OFFSET	    	1
+
+#define SYSTEM_REV_MIN          CHIP_REV_0_0
+#define SYSTEM_REV_NUM          2
+
+#endif /* __ASM_ARCH_MXC_MX27_H__ */
Index: include/asm-arm/arch-mxc/mx2_dma.h
===================================================================
--- /dev/null
+++ include/asm-arm/arch-mxc/mx2_dma.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_MX2_H__
+#define __ASM_ARCH_MXC_MX2_H__
+
+#include <asm/hardware.h>
+#include <asm/dma.h>
+#include <stdarg.h>
+
+#define MXC_DMA_INTR_0		32
+
+#define DMA_DCR		0x000	/*  32bit dma control reg */
+#define DMA_DISR	0x004	/*  32bit dma interrupt status reg */
+#define DMA_DIMR	0x008	/*  32bit dma interrupt mask reg */
+#define DMA_DBTOSR	0x00c	/*  32bit dma burst timeout stat reg */
+#define DMA_DRTOSR	0x010	/*  32bit dma req timeout status reg */
+#define DMA_DSESR	0x014	/*  32bit dma transfer err status reg */
+#define DMA_DBOSR	0x018	/*  32bit dma buffer overflow stat reg */
+#define DMA_DBTOCR	0x01c	/*  32bit dma burst timeout ctrl reg */
+
+#define DMA_WSRA	0x040	/*  32bit dma W-size A reg */
+#define DMA_XSRA	0x044	/*  32bit dma X-size A reg */
+#define DMA_YSRA	0x048	/*  32bit dma Y-size A reg */
+#define DMA_WSRB	0x04C	/*  32bit dma W-size B reg */
+#define DMA_XSRB	0x050	/*  32bit dma X-size B reg */
+#define DMA_YSRB	0x054	/*  32bit dma Y-size B reg */
+
+#define DMA_CH_BASE(x)	(0x080+0x040*(x))
+
+#define DMA_SAR(x)	(DMA_CH_BASE(x)+0x000)
+#define DMA_DAR(x)	(DMA_CH_BASE(x)+0x004)
+#define DMA_CNTR(x)	(DMA_CH_BASE(x)+0x008)
+#define DMA_CCR(x)	(DMA_CH_BASE(x)+0x00C)	/* 32bit dma ch0 control reg */
+#define DMA_RSSR(x)	(DMA_CH_BASE(x)+0x010)	/* 32bit dma ch0 req source sel reg */
+#define DMA_BLR(x)	(DMA_CH_BASE(x)+0x014)	/* 32bit dma ch0 burst lenght reg */
+#define DMA_RTOR(x)	(DMA_CH_BASE(x)+0x018)	/* 32bit dma ch0 req time out reg */
+#define DMA_BUCR(x)	(DMA_CH_BASE(x)+0x018)	/* 32bit dma ch0 bus utilization reg */
+#define DMA_CCNR(x)	(DMA_CH_BASE(x)+0x01C)	/* 32bit dma ch0 */
+
+#define DMA_TCR		0x480	/* 32bit dma test control reg */
+#define DMA_TFIFOA	0x484	/* 32bit dma test fifo A reg */
+#define DMA_TDRR	0x488	/* 32bit dma test request reg */
+#define DMA_TDIPR	0x48c	/* 32bit dma test in progress reg */
+#define DMA_TFIFOB	0x490	/* 32bit dma test fifo B reg */
+
+/* This defines maximum DMA address */
+#define MAX_DMA_ADDRESS 0xffffffff
+
+#define MXC_DMA_CHANNELS 16
+#define MAX_DMA_CHANNELS MXC_DMA_CHANNELS
+
+#define MX_DMA_CHANNELS		MXC_DMA_CHANNELS
+
+#define DMA_MEM_SIZE_8	0x1
+#define DMA_MEM_SIZE_16	0x2
+#define DMA_MEM_SIZE_32	0x0
+
+#define DMA_TYPE_LINEAR	0x0
+#define DMA_TYPE_2D	0x01
+#define DMA_TYPE_FIFO	0x2
+#define DMA_TYPE_EBE	0x3
+
+#define DMA_DONE		0x1000
+#define DMA_BURST_TIMEOUT 	0x1
+#define DMA_REQUEST_TIMEOUT	0x2
+#define DMA_TRANSFER_ERROR	0x4
+#define DMA_BUFFER_OVERFLOW	0x8
+
+/* DMA control register*/
+typedef struct {
+	volatile u32 CEN:1;	/* Dma channel enable */
+	volatile u32 FRC:1;	/* Force a dma cycle bit */
+	volatile u32 RPT:1;	/* Repeat bit */
+	volatile u32 REN:1;	/* Request enable bit */
+	volatile u32 SSIZ:2;	/* Source port size, 2 bit in length */
+	volatile u32 DSIZ:2;	/* Dest port size, 2 bit in length */
+	volatile u32 MSEL:1;	/* 2D memory register set bit */
+	volatile u32 MDIR:1;	/* Transfer direction, inversed or normal */
+	volatile u32 SMOD:2;	/* Source mode, 2 bit in length */
+	volatile u32 DMOD:2;	/* Dest mode, 2 bit in length */
+	volatile u32 ACRPT:1;	/* Auto clear repeat bit */
+	volatile u32 Reserver:17;	/*  Reserved bits */
+
+} dma_regs_control;
+
+#define DMA_CTL_CEN 0x1
+#define DMA_CTL_FRC 0x2
+#define DMA_CTL_RPT 0x4
+#define DMA_CTL_REN 0x8
+
+#define DMA_CTL_MSEL 0x100
+#define DMA_CTL_MDIR 0x200
+#define DMA_CTL_ACRPT 0x4000
+
+#define DMA_CTL_GET_SSIZ(x) (((x)>>4)&0x3)
+#define DMA_CTL_GET_DSIZ(x) (((x)>>6)&0x3)
+#define DMA_CTL_GET_SMOD(x)  (((x)>>10)&0x3)
+#define DMA_CTL_GET_DMOD(x)  (((x)>>12)&0x3)
+
+#define DMA_CTL_SET_SSIZ(x,value) 	do{ \
+		(x)&=~(0x3<<4); \
+		(x)|=(value)<<4; 		\
+	}while(0)
+
+#define DMA_CTL_SET_DSIZ(x,value) 	do{ \
+		(x)&=~(0x3<<6); \
+		(x)|=(value)<<6; 		\
+	}while(0)
+
+#define DMA_CTL_SET_SMOD(x,value) 	do{ \
+		(x)&=~(0x3<<10); \
+		(x)|=(value)<<10; 		\
+	}while(0)
+
+#define DMA_CTL_SET_DMOD(x,value) 	do{ \
+		(x)&=~(0x3<<12); \
+		(x)|=(value)<<12; 		\
+	}while(0)
+
+typedef struct {
+	volatile u32 SourceAddr;
+	volatile u32 DestAddr;
+	volatile u32 Count;
+	volatile u32 Ctl;
+	volatile u32 RequestSource;
+	volatile u32 BurstLength;
+	union {
+		volatile u32 ReqTimeout;
+		volatile u32 BusUtilt;
+	};
+	volatile u32 transferd;
+} dma_regs_t;
+
+#ifndef TRANSFER_32BIT
+
+/* This defines DMA access data size */
+#define TRANSFER_8BIT       DMA_MEM_SIZE_8
+#define TRANSFER_16BIT      DMA_MEM_SIZE_16
+#define TRANSFER_32BIT      DMA_MEM_SIZE_32
+
+#endif
+
+/* This defines maximum device name length passed during mxc_request_dma(). */
+#define MAX_DEVNAME_LENGTH 32
+#define MAX_BD_SIZE	64
+
+/* dma channel parameters */
+typedef struct {
+	unsigned long dma_chan;	/* the dma channel information: dynamic or channel number */
+	u32 mode:1;		/* the initialized dma mode, 0 for dma read, 1 for dma write */
+	u32 rto_en:1;		/* enable request-timeout. It is valid when REN=1 */
+	u32 dir:1;		/* Transfer direction, 0 for increment, 1 for decrement */
+	u32 dma_chaining:1;	/* Autoclear bit for chainbuffer */
+	u32 ren:1;		/* enable transfer based request signal */
+	u32 M2D_Valid:1;	/* enable 2D address module. 0 for disable it. 1 for enabled it */
+	u32 msel:1;		/* 2D memory selection, 0 for set A, 1 for set B */
+	u32 burstLength;	/* Channel burst length */
+	u32 request;		/* Request source. */
+	u32 busuntils;		/* when REN=0, Bus utilization, otherwise it it request timeout */
+	u32 sourceType;		/* Source type, see DMA_TYPE_* */
+	u32 sourcePort;		/* Source port size, see DMA_MEM_SIZE_* */
+	u32 destType;		/* Destination type, see DMA_TYPE_* */
+	u32 destPort;		/* Destination port size, see DMA_MEM_SIZE_* */
+	__u32 per_address;	/* Peripheral source/destination physical address */
+	u32 W;			/* 2D Wide-size */
+	u32 X;			/* 2D X-size */
+	u32 Y;			/* 2D Y-size */
+} mx2_dma_info_t;
+
+/* dma buffer descriptor */
+typedef struct {
+	unsigned long state;	/* dma bd state */
+	int mode;		/* the dma mode of this bd */
+	unsigned long count;	/* the length of the dma transfer */
+	unsigned long src_addr;	/* the source address of the dma transfer */
+	unsigned long dst_addr;	/* the destination address of the dma transfer */
+} mx2_dma_bd_t;
+
+/* the states of dma buffer descriptor */
+#define DMA_BD_ST_BUSY	0x20000000	/* dma bd is transfering or has be configured into controller */
+#define DMA_BD_ST_PEND	0x10000000	/* dma bd is waiting to be configured into controller */
+#define DMA_BD_ST_LAST	0x08000000	/* dma bd is the last dma bd which is built in one dma transfer request
+					 * When completed this bd, the callback function must be called. */
+
+/* private information for MX2 */
+typedef struct mx2_dma_priv_s {
+	unsigned int dma_chaining:1;	/* 1: using headware dma chaining feature */
+	unsigned int ren:1;	/* 1: dma start besed on request signal */
+	unsigned long trans_bytes;	/* To store the transfered data bytes in this transfer */
+	mx2_dma_info_t *dma_info;	/* To store the pointer for dma parameter for reading and wirting */
+	int bd_rd;		/* the read index of bd ring */
+	int bd_wr;		/* the write index of bd ring */
+	atomic_t bd_used;	/* the valid bd number in bd ring */
+	mx2_dma_bd_t *bd_ring;	/* the pointer of bd ring */
+	unsigned long dma_base;	/* register base address of this channel */
+	int dma_irq;		/* irq number of this channel */
+} mx2_dma_priv_t;
+
+/* get the dma info by channel_id */
+extern mx2_dma_info_t *mxc_dma_get_info(mxc_dma_device_t channel_id);
+
+/*scan dma parameter list . And collect information about which channels are dynamic */
+extern void mxc_dma_load_info(mxc_dma_channel_t * dma);
+
+#endif /* __ASM_ARCH_MXC_MX2_H__ */
Index: include/asm-arm/arch-mxc/common.h
===================================================================
--- include/asm-arm/arch-mxc/common.h.orig
+++ include/asm-arm/arch-mxc/common.h
@@ -16,5 +16,8 @@ struct sys_timer;
 extern void mxc_map_io(void);
 extern void mxc_init_irq(void);
 extern struct sys_timer mxc_timer;
+extern int mxc_clocks_init(void);
+extern unsigned long board_get_ckih_rate(void);
+extern void mxc_cpu_common_init(void);
 
-#endif
+#endif /* __ASM_ARCH_MXC_COMMON_H__ */
Index: include/asm-arm/arch-mxc/memory.h
===================================================================
--- include/asm-arm/arch-mxc/memory.h.orig
+++ include/asm-arm/arch-mxc/memory.h
@@ -7,11 +7,38 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
 #ifndef __ASM_ARCH_MXC_MEMORY_H__
 #define __ASM_ARCH_MXC_MEMORY_H__
 
-#include <asm/hardware.h>
+#include <linux/version.h>
+#include <asm/memory.h>
+#include <asm/arch/hardware.h>
+
+#ifndef PAGE_SHIFT
+#include <asm/page.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define DMA_ZONE_SIZE   ((SZ_8M + CONSISTENT_DMA_SIZE) >> PAGE_SHIFT)
+
+static inline void __arch_adjust_zones(int node, unsigned long *zone_size,
+				       unsigned long *zhole_size)
+{
+	if (node != 0) return;
+	/* Only the first part of memory is usable for DMA */
+	zone_size[1] = zone_size[0] - DMA_ZONE_SIZE;
+	zhole_size[1] = zhole_size[0];
+	zone_size[0] = DMA_ZONE_SIZE;
+	zhole_size[0] = 0;
+}
+
+#define arch_adjust_zones(node, size, holes) \
+			  __arch_adjust_zones(node, size, holes)
+
+#define ISA_DMA_THRESHOLD   (PHYS_OFFSET + (DMA_ZONE_SIZE << PAGE_SHIFT) - 1)
+
+#endif
 
 /*
  * Virtual view <-> DMA view memory address translations
@@ -26,5 +53,70 @@
  */
 #define __bus_to_virt(a)	__phys_to_virt(a)
 
-#endif /* __ASM_ARCH_MXC_MEMORY_H__ */
+#ifdef CONFIG_DISCONTIGMEM
 
+/*
+ * The MXC's memory is physically contiguous, but to
+ * support and test Memory Type Based Allocation, we need
+ * to artificially create some memory banks. Our goal
+ * it to have a minimum of 4 nodes of the same size
+ * and to try to have a Node size be 16MiB when  possible.
+ */
+#if (SDRAM_MEM_SIZE == SZ_128M)
+#define        NODES_SHIFT	2	/* 4 Nodes */
+#define NODE_MAX_MEM_SHIFT	25	/* 32 MiB */
+#elif (SDRAM_MEM_SIZE == SZ_64M)
+#define        NODES_SHIFT	2	/* 4 Nodes */
+#define NODE_MAX_MEM_SHIFT	24	/* 16 MiB */
+#elif (SDRAM_MEM_SIZE == SZ_32M)
+#define        NODES_SHIFT	2	/* 4 Nodes */
+#define NODE_MAX_MEM_SHIFT	23	/* 8 MiB */
+#else
+#error "Please, #Define SDRAM_MEM_SIZE "
+#endif
+
+#define MXC_NUMNODES	(1 << NODES_SHIFT)
+#define NODE_MAX_MEM_SIZE	(1 << NODE_MAX_MEM_SHIFT)
+
+#define SET_NODE(mi, nid) { \
+	(mi)->bank[(nid)].start = PHYS_OFFSET + (nid) * NODE_MAX_MEM_SIZE; \
+	(mi)->bank[(nid)].size =  NODE_MAX_MEM_SIZE; \
+	(mi)->bank[(nid)].node = (nid); \
+	node_set_online(nid); \
+}
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(addr) \
+	(((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
+
+/*
+ * Given a page frame number, convert it to a node id.
+ */
+#define PFN_TO_NID(pfn) \
+	(((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT))
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and returns the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
+
+/*
+ * Given a page frame number, find the owning node of the memory
+ * and returns the mem_map of that node.
+ */
+#define PFN_TO_MAPBASE(pfn)    NODE_MEM_MAP(PFN_TO_NID(pfn))
+
+/*
+ * Given a kaddr, LOCAL_MAR_NR finds the owning node of the memory
+ * and returns the index corresponding to the appropriate page in the
+ * node's mem_map.
+ */
+#define LOCAL_MAP_NR(addr) \
+	(((unsigned long)(addr) & (NODE_MAX_MEM_SIZE - 1)) >> PAGE_SHIFT)
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* __ASM_ARCH_MXC_MEMORY_H__ */
Index: include/asm-arm/arch-mxc/vmalloc.h
===================================================================
--- include/asm-arm/arch-mxc/vmalloc.h.orig
+++ include/asm-arm/arch-mxc/vmalloc.h
@@ -21,9 +21,25 @@
 #define __ASM_ARCH_MXC_VMALLOC_H__
 
 /*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason.
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+
+/*
+ * vmalloc start address
+ */
+#define VMALLOC_START	  (((unsigned long)high_memory + \
+                           VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+
+/*
  * vmalloc ending address
  */
-#define VMALLOC_END       0xF4000000
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
 
 #endif /* __ASM_ARCH_MXC_VMALLOC_H__ */
-
Index: include/asm-arm/arch-mxc/irqs.h
===================================================================
--- include/asm-arm/arch-mxc/irqs.h.orig
+++ include/asm-arm/arch-mxc/irqs.h
@@ -7,26 +7,32 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
 #ifndef __ASM_ARCH_MXC_IRQS_H__
 #define __ASM_ARCH_MXC_IRQS_H__
 
-#include <asm/hardware.h>
+#include <asm/arch/hardware.h>
+
+#define MXC_IRQ_TO_EDIO(nr)     ((nr) - MXC_EXT_BASE)
+#define MXC_IRQ_IS_EDIO(nr)  	((nr) >= MXC_EXT_BASE)
 
 #define MXC_IRQ_TO_EXPIO(irq)	((irq) - MXC_EXP_IO_BASE)
 
-#define MXC_IRQ_TO_GPIO(irq)	((irq) - MXC_GPIO_INT_BASE)
-#define MXC_GPIO_TO_IRQ(x)	(MXC_GPIO_INT_BASE + x)
+#define MXC_IRQ_TO_GPIO(irq)	((irq) - MXC_GPIO_BASE)
+#define MXC_GPIO_TO_IRQ(x)	(MXC_GPIO_BASE + x)
+
+/*
+ * FIXME: document me
+ */
+#define ARCH_TIMER_IRQ	INT_GPT
 
 /*
  * Number of normal interrupts
  */
-#define NR_IRQS		MXC_MAX_INTS
+#define NR_IRQS         (MXC_MAX_INTS)
 
 /*
  * Number of fast interrupts
  */
-#define NR_FIQS		MXC_MAX_INTS
+#define NR_FIQS		(MXC_MAX_INTS)
 
 #endif /* __ASM_ARCH_MXC_IRQS_H__ */
-
Index: include/asm-arm/arch-mxc/mxc.h
===================================================================
--- include/asm-arm/arch-mxc/mxc.h.orig
+++ include/asm-arm/arch-mxc/mxc.h
@@ -7,7 +7,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
 #ifndef __ASM_ARCH_MXC_H__
 #define __ASM_ARCH_MXC_H__
 
@@ -15,11 +14,89 @@
 #error "Do not include directly."
 #endif
 
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+/*
+ * gpio port structure
+ */
+struct mxc_gpio_port {
+	u32 num;		/* gpio port number */
+	u32 base;		/* gpio port base VA */
+	u16 irq;		/* irq number to the core */
+	u16 virtual_irq_start;	/* virtual irq start number */
+};
+
+/*
+ * This structure is used to define the One wire platform data.
+ * It includes search rom accelerator.
+ */
+struct mxc_w1_config {
+	int search_rom_accelerator;
+};
+
+/*
+ * This structure is used to define the SPI master controller's platform
+ * data. It includes the SPI  bus number and the maximum number of
+ * slaves/chips it supports.
+ */
+struct mxc_spi_master {
+	unsigned int bus_num;	/* SPI Master's bus number. */
+	unsigned int maxchipselect;	/* * SPI Master's maximum number of chip selects. */
+	unsigned int spi_version;	/* CSPI Hardware Version. */
+};
+#endif
+
+#define IOMUX_TO_GPIO(pin) 	((((unsigned int)pin >> MUX_IO_P) * GPIO_NUM_PIN) + ((pin >> MUX_IO_I) & ((1 << (MUX_IO_P - MUX_IO_I)) -1)))
+#define IOMUX_TO_IRQ(pin)	(MXC_GPIO_BASE + IOMUX_TO_GPIO(pin))
+#define GPIO_TO_PORT(n)		(n / GPIO_NUM_PIN)
+#define GPIO_TO_INDEX(n)	(n % GPIO_NUM_PIN)
+
+/*
+ *****************************************
+ * EPIT  Register definitions            *
+ *****************************************
+ */
+#ifndef EPIT1_AP_BASE_ADDR
+#define EPIT1_AP_BASE_ADDR 	EPIT1_BASE_ADDR
+#endif
+
+#define MXC_EPIT_EPITCR		(IO_ADDRESS(EPIT1_AP_BASE_ADDR + 0x00))
+#define MXC_EPIT_EPITSR		(IO_ADDRESS(EPIT1_AP_BASE_ADDR + 0x04))
+#define MXC_EPIT_EPITLR		(IO_ADDRESS(EPIT1_AP_BASE_ADDR + 0x08))
+#define MXC_EPIT_EPITCMPR	(IO_ADDRESS(EPIT1_AP_BASE_ADDR + 0x0C))
+#define MXC_EPIT_EPITCNR	(IO_ADDRESS(EPIT1_AP_BASE_ADDR + 0x10))
+
 /*
  *****************************************
  * GPT  Register definitions             *
  *****************************************
  */
+#if defined(CONFIG_ARCH_MX2)
+#define GPT_BASE_ADDR(x)	(GPT ##x## _BASE_ADDR)
+#define MXC_GPT_TCTL(x)		(IO_ADDRESS(GPT_BASE_ADDR(x) + 0x00))
+#define MXC_GPT_TPRER(x)	(IO_ADDRESS(GPT_BASE_ADDR(x) + 0x04))
+#define MXC_GPT_TCMP(x)		(IO_ADDRESS(GPT_BASE_ADDR(x) + 0x08))
+#define MXC_GPT_TCR(x)		(IO_ADDRESS(GPT_BASE_ADDR(x) + 0x0C))
+#define MXC_GPT_TCN(x)		(IO_ADDRESS(GPT_BASE_ADDR(x) + 0x10))
+#define MXC_GPT_TSTAT(x)	(IO_ADDRESS(GPT_BASE_ADDR(x) + 0x14))
+#define MXC_GPT_GPTCNT		MXC_GPT_TCN(MXC_TIMER_GPT1)
+#define GPT_TSTAT_COMP		(1 << 0)
+#define GPT_TSTAT_CAPT		(1 << 1)
+#define GPT_TCTL_TEN		(1 << 0)
+#define GPT_TCTL_SRC_PER1	(1 << 1)
+#define GPT_TCTL_SRC_PER1_DIV4	(2 << 1)
+#define GPT_TCTL_SRC_TIN	(3 << 1)
+#define GPT_TCTL_SRC_32K	(4 << 1)
+#define GPT_TCTL_COMPEN		(1 << 4)
+#define GPT_TCTL_CAPTEN		(1 << 5)
+#define GPT_TCTL_FRR		(1 << 8)
+#define GPT_TCTL_OM		(1 << 9)
+#define GPT_TCTL_CC		(1 << 10)
+#define GPT_TCTL_SWR		(1 << 15)
+#endif /* CONFIG_ARCH_MX2 */
+
+#ifdef CONFIG_ARCH_MX3
 #define MXC_GPT_GPTCR		IO_ADDRESS(GPT1_BASE_ADDR + 0x00)
 #define MXC_GPT_GPTPR		IO_ADDRESS(GPT1_BASE_ADDR + 0x04)
 #define MXC_GPT_GPTSR		IO_ADDRESS(GPT1_BASE_ADDR + 0x08)
@@ -31,9 +108,7 @@
 #define MXC_GPT_GPTICR2		IO_ADDRESS(GPT1_BASE_ADDR + 0x20)
 #define MXC_GPT_GPTCNT		IO_ADDRESS(GPT1_BASE_ADDR + 0x24)
 
-/*!
- * GPT Control register bit definitions
- */
+/* GPT Control register bit definitions */
 #define GPTCR_FO3			(1 << 31)
 #define GPTCR_FO2			(1 << 30)
 #define GPTCR_FO1			(1 << 29)
@@ -107,6 +182,7 @@
 #define GPTIR_IF1IE			GPTSR_IF1
 #define GPTIR_IF2IE			GPTSR_IF2
 #define GPTIR_ROVIE			GPTSR_ROV
+#endif /* CONFIG_ARCH_MX3 */
 
 /*
  *****************************************
@@ -141,9 +217,25 @@
 #define AVIC_FIPNDH		(AVIC_BASE + 0x60)	/* fast int pending high */
 #define AVIC_FIPNDL		(AVIC_BASE + 0x64)	/* fast int pending low */
 
+/*
+ *****************************************
+ * EDIO Registers                        *
+ *****************************************
+ */
+#ifdef EDIO_BASE_ADDR
+#define EDIO_EPPAR		(IO_ADDRESS(EDIO_BASE_ADDR) + 0x00)
+#define EDIO_EPDDR		(IO_ADDRESS(EDIO_BASE_ADDR) + 0x02)
+#define EDIO_EPDR		(IO_ADDRESS(EDIO_BASE_ADDR) + 0x04)
+#define EDIO_EPFR		(IO_ADDRESS(EDIO_BASE_ADDR) + 0x06)
+#endif
+
 #define SYSTEM_PREV_REG		IO_ADDRESS(IIM_BASE_ADDR + 0x20)
 #define SYSTEM_SREV_REG		IO_ADDRESS(IIM_BASE_ADDR + 0x24)
 #define IIM_PROD_REV_SH		3
 #define IIM_PROD_REV_LEN	5
 
-#endif				/*  __ASM_ARCH_MXC_H__ */
+/* DMA driver defines */
+#define MXC_IDE_DMA_WATERMARK	32	/* DMA watermark level in bytes */
+#define MXC_IDE_DMA_BD_NR	(512/3/4)	/* Number of BDs per channel */
+
+#endif /*  __ASM_ARCH_MXC_H__ */
Index: include/asm-arm/arch-mxc/hardware.h
===================================================================
--- include/asm-arm/arch-mxc/hardware.h.orig
+++ include/asm-arm/arch-mxc/hardware.h
@@ -13,7 +13,67 @@
 
 #include <asm/sizes.h>
 
+/*
+ * defines PCIO_BASE (not used but needed for compilation)
+ */
+#define PCIO_BASE		0
+
+/*
+ * This macro is used to get certain bit field from a number
+ */
+#define MXC_GET_FIELD(val, len, sh)          ((val >> sh) & ((1 << len) - 1))
+
+/*
+ * This macro is used to set certain bit field inside a number
+ */
+#define MXC_SET_FIELD(val, len, sh, nval)    ((val & ~(((1 << len) - 1) << sh)) | nval << sh)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Processor specific defines
+ * ---------------------------------------------------------------------------
+ */
+#define CHIP_REV_1_0		0x10
+#define CHIP_REV_1_1		0x11
+#define CHIP_REV_1_2		0x12
+#define CHIP_REV_1_3		0x13
+#define CHIP_REV_2_0		0x20
+#define CHIP_REV_2_1		0x21
+#define CHIP_REV_2_2		0x22
+#define CHIP_REV_2_3		0x23
+#define CHIP_REV_3_0		0x30
+#define CHIP_REV_3_1		0x31
+#define CHIP_REV_3_2		0x32
+
+#ifdef CONFIG_ARCH_MX3
 #include <asm/arch/mx31.h>
+#define cpu_is_mx31()		(1)
+#else
+#define cpu_is_mx31()		(0)
+#endif
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+extern unsigned int system_rev;
+#define _is_rev(rev) ((system_rev == rev) ? 1 : ((system_rev < rev) ? -1 : 2))
+
+#define MXC_REV(type)				\
+static inline int type## _rev (int rev)		\
+{						\
+	return (type() ? _is_rev(rev) : 0);	\
+}
+
+/*
+ * Create inline functions to test for cpu revision
+ * Function name is cpu_is_<cpu name>_rev(rev)
+ *
+ * Returns:
+ *	 0 - not the cpu queried
+ *	 1 - cpu and revision match
+ *	 2 - cpu matches, but cpu revision is greater than queried rev
+ *	-1 - cpu matches, but cpu revision is less than queried rev
+ */
+MXC_REV(cpu_is_mx31);
+#endif
 
 #include <asm/arch/mxc.h>
 
@@ -24,24 +84,8 @@
  * Board specific defines
  * ---------------------------------------------------------------------------
  */
-#define MXC_EXP_IO_BASE         (MXC_GPIO_INT_BASE + MXC_MAX_GPIO_LINES)
-
+#ifdef CONFIG_MACH_MX31ADS
 #include <asm/arch/board-mx31ads.h>
-
-#ifndef MXC_MAX_EXP_IO_LINES
-#define MXC_MAX_EXP_IO_LINES 0
 #endif
 
-#define MXC_MAX_VIRTUAL_INTS	16
-#define MXC_VIRTUAL_INTS_BASE	(MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES)
-#define MXC_SDIO1_CARD_IRQ	MXC_VIRTUAL_INTS_BASE
-#define MXC_SDIO2_CARD_IRQ	(MXC_VIRTUAL_INTS_BASE + 1)
-#define MXC_SDIO3_CARD_IRQ	(MXC_VIRTUAL_INTS_BASE + 2)
-
-#define MXC_MAX_INTS            (MXC_MAX_INT_LINES + \
-                                MXC_MAX_GPIO_LINES + \
-                                MXC_MAX_EXP_IO_LINES + \
-                                MXC_MAX_VIRTUAL_INTS)
-
 #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
-
Index: include/asm-arm/arch-mxc/dma.h
===================================================================
--- include/asm-arm/arch-mxc/dma.h.orig
+++ include/asm-arm/arch-mxc/dma.h
@@ -11,11 +11,168 @@
 #ifndef __ASM_ARCH_MXC_DMA_H__
 #define __ASM_ARCH_MXC_DMA_H__
 
-/*!
- * @file dma.h
- * @brief This file contains Unified DMA API for all MXC platforms.
- * The API is platform independent.
- *
- * @ingroup SDMA
- */
+#define MXC_DMA_DYNAMIC_CHANNEL   255
+
+#define MXC_DMA_DONE		  0x0
+#define MXC_DMA_REQUEST_TIMEOUT   0x1
+#define MXC_DMA_TRANSFER_ERROR    0x2
+
+/* This defines the list of device ID's for DMA */
+typedef enum mxc_dma_device {
+	MXC_DMA_UART1_RX,
+	MXC_DMA_UART1_TX,
+	MXC_DMA_UART2_RX,
+	MXC_DMA_UART2_TX,
+	MXC_DMA_UART3_RX,
+	MXC_DMA_UART3_TX,
+	MXC_DMA_UART4_RX,
+	MXC_DMA_UART4_TX,
+	MXC_DMA_UART5_RX,
+	MXC_DMA_UART5_TX,
+	MXC_DMA_UART6_RX,
+	MXC_DMA_UART6_TX,
+	MXC_DMA_MMC1_WIDTH_1,
+	MXC_DMA_MMC1_WIDTH_4,
+	MXC_DMA_MMC2_WIDTH_1,
+	MXC_DMA_MMC2_WIDTH_4,
+	MXC_DMA_SSI1_8BIT_RX0,
+	MXC_DMA_SSI1_8BIT_TX0,
+	MXC_DMA_SSI1_16BIT_RX0,
+	MXC_DMA_SSI1_16BIT_TX0,
+	MXC_DMA_SSI1_24BIT_RX0,
+	MXC_DMA_SSI1_24BIT_TX0,
+	MXC_DMA_SSI1_8BIT_RX1,
+	MXC_DMA_SSI1_8BIT_TX1,
+	MXC_DMA_SSI1_16BIT_RX1,
+	MXC_DMA_SSI1_16BIT_TX1,
+	MXC_DMA_SSI1_24BIT_RX1,
+	MXC_DMA_SSI1_24BIT_TX1,
+	MXC_DMA_SSI2_8BIT_RX0,
+	MXC_DMA_SSI2_8BIT_TX0,
+	MXC_DMA_SSI2_16BIT_RX0,
+	MXC_DMA_SSI2_16BIT_TX0,
+	MXC_DMA_SSI2_24BIT_RX0,
+	MXC_DMA_SSI2_24BIT_TX0,
+	MXC_DMA_SSI2_8BIT_RX1,
+	MXC_DMA_SSI2_8BIT_TX1,
+	MXC_DMA_SSI2_16BIT_RX1,
+	MXC_DMA_SSI2_16BIT_TX1,
+	MXC_DMA_SSI2_24BIT_RX1,
+	MXC_DMA_SSI2_24BIT_TX1,
+	MXC_DMA_FIR_RX,
+	MXC_DMA_FIR_TX,
+	MXC_DMA_CSPI1_RX,
+	MXC_DMA_CSPI1_TX,
+	MXC_DMA_CSPI2_RX,
+	MXC_DMA_CSPI2_TX,
+	MXC_DMA_CSPI3_RX,
+	MXC_DMA_CSPI3_TX,
+	MXC_DMA_ATA_RX,
+	MXC_DMA_ATA_TX,
+	MXC_DMA_MEMORY,
+	MXC_DMA_DSP_PACKET_DATA0_RD,
+	MXC_DMA_DSP_PACKET_DATA0_WR,
+	MXC_DMA_DSP_PACKET_DATA1_RD,
+	MXC_DMA_DSP_PACKET_DATA1_WR,
+	MXC_DMA_DSP_LOG0_CHNL,
+	MXC_DMA_DSP_LOG1_CHNL,
+	MXC_DMA_DSP_LOG2_CHNL,
+	MXC_DMA_DSP_LOG3_CHNL,
+	MXC_DMA_CSI_RX,
+	MXC_DMA_TEST_RAM2D2RAM,
+	MXC_DMA_TEST_RAM2RAM2D,
+	MXC_DMA_TEST_RAM2D2RAM2D,
+	MXC_DMA_TEST_RAM2RAM,
+	MXC_DMA_TEST_HW_CHAINING,
+	MXC_DMA_TEST_SW_CHAINING
+} mxc_dma_device_t;
+
+/* This defines the prototype of callback funtion registered by the drivers */
+typedef void (*mxc_dma_callback_t) (void *arg, int error_status,
+				    unsigned int count);
+
+/* This defines the type of DMA transfer requested */
+typedef enum mxc_dma_mode {
+	MXC_DMA_MODE_READ,
+	MXC_DMA_MODE_WRITE,
+} mxc_dma_mode_t;
+
+/* This defines the DMA channel parameters */
+typedef struct mxc_dma_channel {
+	unsigned int active:1;	/* When there has a active tranfer, it is set to 1 */
+	unsigned int lock;	/* Defines the channel is allocated or not */
+	int curr_buf;		/* Current buffer */
+	mxc_dma_mode_t mode;	/* Read or Write */
+	unsigned int channel;	/* Channel info */
+	unsigned int dynamic:1;	/* Channel not statically allocated when 1 */
+	char *dev_name;		/* Device name */
+	void *private;		/* Private structure for platform */
+	mxc_dma_callback_t cb_fn;	/* The callback function */
+	void *cb_args;		/* The argument of callback function */
+} mxc_dma_channel_t;
+
+/* This structure contains the information about a dma transfer */
+typedef struct mxc_dma_requestbuf {
+	dma_addr_t src_addr;	/* source address */
+	dma_addr_t dst_addr;	/* destination address */
+	int num_of_bytes;	/* the length of this transfer : bytes */
+} mxc_dma_requestbuf_t;
+
+#if defined(CONFIG_ARCH_MX2)
+#include <asm/arch/mx2_dma.h>
+#else
+#include <asm/arch/sdma.h>
 #endif
+
+/*
+ * This function is generally called by the driver at open time.
+ * The DMA driver would do any initialization steps that is required
+ * to get the channel ready for data transfer.
+ */
+extern int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name);
+
+/*
+ * This function is generally called by the driver at close time. The DMA
+ * driver would do any cleanup associated with this channel.
+ */
+extern int mxc_dma_free(int channel_num);
+
+/*
+ * This function would just configure the buffers specified by the user into
+ * dma channel. The caller must call mxc_dma_enable to start this transfer.
+ */
+extern int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf,
+			  int num_buf, mxc_dma_mode_t mode);
+
+/*
+ * This function would just configure the scatterlist specified by the
+ * user into dma channel. This is a slight variation of mxc_dma_config(),
+ * it is provided for the convenience of drivers that have a scatterlist
+ * passed into them. It is the calling driver's responsibility to have the
+ * correct physical address filled in the "dma_address" field of the
+ * scatterlist.
+ */
+extern int mxc_dma_sg_config(int channel_num, struct scatterlist *sg,
+			     int num_buf, int num_of_bytes,
+			     mxc_dma_mode_t mode);
+
+/*
+ * This function is provided if the driver would like to set/change its
+ * callback function.
+ */
+extern int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback,
+				void *arg);
+
+/*
+ * This stops the DMA channel and any ongoing transfers. Subsequent use of
+ * mxc_dma_enable() will restart the channel and restart the transfer.
+ */
+extern int mxc_dma_disable(int channel_num);
+
+/*
+ * This starts DMA transfer. Or it restarts DMA on a stopped channel
+ * previously stopped with mxc_dma_disable().
+ */
+extern int mxc_dma_enable(int channel_num);
+
+#endif /* __ASM_ARCH_MXC_DMA_H__ */
Index: include/asm-arm/arch-mxc/io.h
===================================================================
--- include/asm-arm/arch-mxc/io.h.orig
+++ include/asm-arm/arch-mxc/io.h
@@ -14,12 +14,16 @@
 /* Allow IO space to be anywhere in the memory */
 #define IO_SPACE_LIMIT 0xffffffff
 
-/*
- * io address mapping macro
- */
+/* io address mapping macro */
 #define __io(a)			((void __iomem *)(a))
 
 #define __mem_pci(a)		(a)
+#define __mem_isa(a)		(a)
 
-#endif
+/* Validate the pci memory address for ioremap. */
+#define iomem_valid_addr(iomem,size)	(1)
+
+/* Convert PCI memory space to a CPU physical address */
+#define iomem_to_phys(iomem)	(iomem)
 
+#endif
Index: include/asm-arm/arch-mxc/clock.h
===================================================================
--- /dev/null
+++ include/asm-arm/arch-mxc/clock.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_CLOCK_H__
+#define __ASM_ARCH_MXC_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+struct module;
+
+struct clk {
+	struct list_head node;
+	struct module *owner;
+	const char *name;
+	int id;
+	/* Source clock this clk depends on */
+	struct clk *parent;
+	/* Secondary clock to enable/disable with this clock */
+	struct clk *secondary;
+	/* Current clock rate */
+	unsigned long rate;
+	/* Reference count of clock enable/disable */
+	__s8 usecount;
+	/* Register bit position for clock's enable/disable control. */
+	u8 enable_shift;
+	/* Register address for clock's enable/disable control. */
+	u32 enable_reg;
+	u32 flags;
+	/* Function ptr to recalculate the clock's rate based on parent
+	   clock's rate */
+	void (*recalc) (struct clk *);
+	/* Function ptr to set the clock to a new rate. The rate must match a
+	   supported rate returned from round_rate. Leave blank if clock is not
+	   programmable */
+	int (*set_rate) (struct clk *, unsigned long);
+	/* Function ptr to round the requested clock rate to the nearest
+	   supported rate that is less than or equal to the requested rate. */
+	unsigned long (*round_rate) (struct clk *, unsigned long);
+	/* Function ptr to enable the clock. Leave blank if clock can not
+	   be gated. */
+	int (*enable) (struct clk *);
+	/* Function ptr to disable the clock. Leave blank if clock can not
+	   be gated. */
+	void (*disable) (struct clk *);
+	/* Function ptr to set the parent clock of the clock. */
+	int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+/* Clock flags */
+#define RATE_PROPAGATES		(1 << 0)	/* Program children too */
+#define ALWAYS_ENABLED		(1 << 1)	/* Clock cannot be disabled */
+#define RATE_FIXED		(1 << 2)	/* Fixed clock rate */
+
+#endif				/* __ASSEMBLY__ */
+#endif				/* __ASM_ARCH_MXC_CLOCK_H__ */
