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

This patch adds rudimentary platform support for the Freescale i.MX2 aka
"mxc" processor family. The code has been taken from the original patch
stack for 2.6.19, ported to top-of-tree and has been extensively cleaned
up according to kernel coding style.

Changes since last release:
 - clock handing moved into separate patch
 - broken DMA support removed (refer Sascha's and Pavel's discussion on ALKML)
 - ran checkpatch.pl on it

TODO:

 - get a sign from freescale for the patch

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

---

 arch/arm/Kconfig                            |    4 
 arch/arm/plat-mxc/Kconfig                   |    7 
 arch/arm/plat-mxc/Makefile                  |    2 
 arch/arm/plat-mxc/gpio.c                    |  468 ++++++++++++++++++++++++++++
 arch/arm/plat-mxc/irq.c                     |   25 -
 include/asm-arm/arch-mxc/common.h           |   29 +
 include/asm-arm/arch-mxc/dma.h              |   28 +
 include/asm-arm/arch-mxc/entry-macro-mx27.S |   46 ++
 include/asm-arm/arch-mxc/hardware.h         |   25 +
 include/asm-arm/arch-mxc/iim.h              |   76 ++++
 include/asm-arm/arch-mxc/io.h               |   29 +
 include/asm-arm/arch-mxc/irqs.h             |   41 +-
 include/asm-arm/arch-mxc/memory.h           |  117 ++++++-
 include/asm-arm/arch-mxc/mx27.h             |  347 ++++++++++++++++++++
 include/asm-arm/arch-mxc/mxc.h              |  115 ++++++
 include/asm-arm/arch-mxc/vmalloc.h          |   35 +-
 16 files changed, 1313 insertions(+), 81 deletions(-)

Index: arch/arm/plat-mxc/irq.c
===================================================================
--- arch/arm/plat-mxc/irq.c.orig
+++ arch/arm/plat-mxc/irq.c
@@ -1,11 +1,19 @@
 /*
- *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #include <linux/module.h>
@@ -17,7 +25,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
-#include <asm/arch/common.h>
 
 /* Disable interrupt number "irq" in the AVIC */
 static void mxc_mask_irq(unsigned int irq)
@@ -32,7 +39,7 @@ 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,
 };
Index: arch/arm/plat-mxc/gpio.c
===================================================================
--- /dev/null
+++ arch/arm/plat-mxc/gpio.c
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/*
+ * 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 enum iomux_pins
+ * @is_input: 1 (or non-zero) for input; 0 for output
+ */
+void mxc_set_gpio_direction(enum iomux_pins 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 enum iomux_pins
+ * @data: Value to be set (only 0 or 1 is valid)
+ */
+void mxc_set_gpio_dataout(enum iomux_pins 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 enum iomux_pins
+ */
+int mxc_get_gpio_datain(enum iomux_pins 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,
+				enum gpio_int_cfg 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 enum iomux_pins
+ *
+ * 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(enum iomux_pins 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);
+
+/**
+ * mxc_free_gpio - Release ownership for a GPIO pin
+ * @pin: A name defined by enum iomux_pins
+ */
+void mxc_free_gpio(enum iomux_pins 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);
+}
+EXPORT_SYMBOL(mxc_free_gpio);
+
+/*
+ * 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/Makefile
===================================================================
--- arch/arm/plat-mxc/Makefile.orig
+++ arch/arm/plat-mxc/Makefile
@@ -3,4 +3,4 @@
 #
 
 # Common support
-obj-y := irq.o
+obj-y := irq.o gpio.o
Index: arch/arm/plat-mxc/Kconfig
===================================================================
--- arch/arm/plat-mxc/Kconfig.orig
+++ arch/arm/plat-mxc/Kconfig
@@ -3,9 +3,14 @@ if ARCH_MXC
 menu "Freescale MXC Implementations"
 
 choice
-	prompt "MXC/iMX System Type"
+	prompt "MXC/iMX Base Type"
 	default ARCH_MX3
 
+config ARCH_MX2
+	bool "MX2-based"
+	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,76 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#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,46 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+	@ 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,347 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#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 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 >= 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
+
+/* silicon revisions specific to i.MX27 */
+#define CHIP_REV_1_0		0x00
+#define CHIP_REV_2_0		0x01
+
+#ifndef __ASSEMBLY__
+extern int cpu_is_mx27_rev(int);
+#endif
+
+#endif /* __ASM_ARCH_MXC_MX27_H__ */
Index: include/asm-arm/arch-mxc/common.h
===================================================================
--- include/asm-arm/arch-mxc/common.h.orig
+++ include/asm-arm/arch-mxc/common.h
@@ -1,20 +1,27 @@
 /*
  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #ifndef __ASM_ARCH_MXC_COMMON_H__
 #define __ASM_ARCH_MXC_COMMON_H__
 
-struct sys_timer;
-
-extern void mxc_map_io(void);
+extern void imx_map_io(void);
 extern void mxc_init_irq(void);
-extern struct sys_timer mxc_timer;
+extern struct sys_timer imx_timer;
+extern int mxc_clocks_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
@@ -1,17 +1,54 @@
 /*
  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #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,4 +63,70 @@
  */
 #define __bus_to_virt(a)	__phys_to_virt(a)
 
+#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
@@ -1,12 +1,12 @@
 /*
- *  Copyright (C) 2000 Russell King.
- *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2000 Russell King.
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
  *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -14,13 +14,30 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #ifndef __ASM_ARCH_MXC_VMALLOC_H__
 #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
@@ -1,27 +1,42 @@
 /*
- *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #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_EXPIO(irq)	((irq) - MXC_EXP_IO_BASE)
+#define MXC_IRQ_TO_GPIO(irq)	((irq) - MXC_GPIO_BASE)
+#define MXC_GPIO_TO_IRQ(x)	(MXC_GPIO_BASE + x)
 
-#define MXC_IRQ_TO_GPIO(irq)	((irq) - MXC_GPIO_INT_BASE)
-#define MXC_GPIO_TO_IRQ(x)	(MXC_GPIO_INT_BASE + x)
+/*
+ * FIXME: document me
+ */
+#define ARCH_TIMER_IRQ	INT_GPT
 
 /* Number of normal interrupts */
-#define NR_IRQS		MXC_MAX_INTS
+#ifndef MXC_MAX_BOARD_INTS
+# define MXC_MAX_BOARD_INTS 0
+#endif
+
+#define NR_IRQS	(MXC_MAX_INT_LINES + MXC_MAX_GPIO_LINES + MXC_MAX_BOARD_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
@@ -1,11 +1,19 @@
 /*
  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #ifndef __ASM_ARCH_MXC_H__
@@ -20,11 +28,99 @@
 # define cpu_is_mx31() (0)
 #endif
 
+#ifdef CONFIG_ARCH_MX2
+#endif
+
+/*
+ * 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)
+
+#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;
+};
+
+#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)
@@ -110,6 +206,7 @@
 #define GPTIR_IF1IE			GPTSR_IF1
 #define GPTIR_IF2IE			GPTSR_IF2
 #define GPTIR_ROVIE			GPTSR_ROV
+#endif /* CONFIG_ARCH_MX3 */
 
 /*
  *****************************************
@@ -149,4 +246,10 @@
 #define IIM_PROD_REV_SH		3
 #define IIM_PROD_REV_LEN	5
 
+/* 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 */
+
+#define MXC_MAX_GPIO_LINES      (GPIO_NUM_PIN * GPIO_PORT_NUM)
+
 #endif /*  __ASM_ARCH_MXC_H__ */
Index: include/asm-arm/arch-mxc/dma.h
===================================================================
--- include/asm-arm/arch-mxc/dma.h.orig
+++ include/asm-arm/arch-mxc/dma.h
@@ -1,14 +1,24 @@
 /*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
+ *  linux/include/asm-arm/arch-mxc/dma.h
+ *
+ *  Copyright (C) 1997,1998 Russell King
+ *
  * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef __ASM_ARCH_MXC_DMA_H__
-#define __ASM_ARCH_MXC_DMA_H__
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
 
-#endif
+#endif				/* _ASM_ARCH_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
@@ -1,11 +1,19 @@
 /*
- *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #ifndef __ASM_ARCH_MXC_IO_H__
@@ -18,5 +26,12 @@
 #define __io(a)			((void __iomem *)(a))
 
 #define __mem_pci(a)		(a)
+#define __mem_isa(a)		(a)
+
+/* 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: arch/arm/Kconfig
===================================================================
--- arch/arm/Kconfig.orig
+++ arch/arm/Kconfig
@@ -373,7 +373,9 @@ config ARCH_NS9XXX
 
 config ARCH_MXC
 	bool "Freescale MXC/iMX-based"
-	select ARCH_MTD_XIP
+	select GENERIC_GPIO
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 
Index: include/asm-arm/arch-mxc/hardware.h
===================================================================
--- include/asm-arm/arch-mxc/hardware.h.orig
+++ include/asm-arm/arch-mxc/hardware.h
@@ -1,11 +1,19 @@
 /*
- *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #ifndef __ASM_ARCH_MXC_HARDWARE_H__
@@ -17,6 +25,9 @@
 # include <asm/arch/mx31.h>
 #endif
 
+#ifdef CONFIG_ARCH_MX2
+#endif
+
 #include <asm/arch/mxc.h>
 
 /*
