diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 6e9e8cedd7239ea0d77ef7d78515ed4ead19a945..0dd24ebdf6ac2163f03a4b1b02040953edbc3072 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -108,6 +108,13 @@ config ARCH_EBSA110
 	  Ethernet interface, two PCMCIA sockets, two serial ports and a
 	  parallel port.
 
+config ARCH_EP93XX
+	bool "EP93xx-based"
+	select ARM_AMBA
+	select ARM_VIC
+	help
+	  This enables support for the Cirrus EP93xx series of CPUs.
+
 config ARCH_FOOTBRIDGE
 	bool "FootBridge"
 	select FOOTBRIDGE
@@ -250,6 +257,8 @@ endchoice
 
 source "arch/arm/mach-clps711x/Kconfig"
 
+source "arch/arm/mach-ep93xx/Kconfig"
+
 source "arch/arm/mach-footbridge/Kconfig"
 
 source "arch/arm/mach-integrator/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index fbfc14a56b965a9ed20f1bda358b6ebc37d43088..b5b1e4087516cf925de7d352f7a4fb898c22b371 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -105,6 +105,7 @@ endif
  machine-$(CONFIG_ARCH_AAEC2000)   := aaec2000
  machine-$(CONFIG_ARCH_REALVIEW)   := realview
  machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200
+ machine-$(CONFIG_ARCH_EP93XX)     := ep93xx
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..cec5a21ca4e341593e5a6b4470a7cc903c111f70
--- /dev/null
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -0,0 +1,21 @@
+if ARCH_EP93XX
+
+menu "Cirrus EP93xx Implementation Options"
+
+comment "EP93xx Platforms"
+
+config MACH_GESBC9312
+	bool "Support Glomation GESBC-9312-sx"
+	help
+	  Say 'Y' here if you want your kernel to support the Glomation
+	  GESBC-9312-sx board.
+
+config MACH_TS72XX
+	bool "Support Technologic Systems TS-72xx SBC"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Technologic Systems TS-72xx board.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5393af989e940c1efdc4af62dd5a63221ace68ff
--- /dev/null
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux kernel.
+#
+obj-y			:= core.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+obj-$(CONFIG_MACH_GESBC9312)	+= gesbc9312.o
+obj-$(CONFIG_MACH_TS72XX)	+= ts72xx.o
diff --git a/arch/arm/mach-ep93xx/Makefile.boot b/arch/arm/mach-ep93xx/Makefile.boot
new file mode 100644
index 0000000000000000000000000000000000000000..d5561ad15badcef26897b1f938355c05b5c6a592
--- /dev/null
+++ b/arch/arm/mach-ep93xx/Makefile.boot
@@ -0,0 +1,2 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
new file mode 100644
index 0000000000000000000000000000000000000000..f831f74dc8cc4d80ef8d22848c794875abd929c5
--- /dev/null
+++ b/arch/arm/mach-ep93xx/core.c
@@ -0,0 +1,173 @@
+/*
+ * arch/arm/mach-ep93xx/core.c
+ * Core routines for Cirrus EP93xx chips.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * Thanks go to Michael Burian and Ray Lehtiniemi for their key
+ * role in the ep93xx linux community.
+ *
+ * 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.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/delay.h>
+#include <linux/amba/bus.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware/vic.h>
+
+
+/*************************************************************************
+ * Static I/O mappings that are needed for all EP93xx platforms
+ *************************************************************************/
+static struct map_desc ep93xx_io_desc[] __initdata = {
+	{
+		.virtual	= EP93XX_AHB_VIRT_BASE,
+		.pfn		= __phys_to_pfn(EP93XX_AHB_PHYS_BASE),
+		.length		= EP93XX_AHB_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= EP93XX_APB_VIRT_BASE,
+		.pfn		= __phys_to_pfn(EP93XX_APB_PHYS_BASE),
+		.length		= EP93XX_APB_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init ep93xx_map_io(void)
+{
+	iotable_init(ep93xx_io_desc, ARRAY_SIZE(ep93xx_io_desc));
+}
+
+
+/*************************************************************************
+ * Timer handling for EP93xx
+ *************************************************************************
+ * The ep93xx has four internal timers.  Timers 1, 2 (both 16 bit) and
+ * 3 (32 bit) count down at 508 kHz, are self-reloading, and can generate
+ * an interrupt on underflow.  Timer 4 (40 bit) counts down at 983.04 kHz,
+ * is free-running, and can't generate interrupts.
+ *
+ * The 508 kHz timers are ideal for use for the timer interrupt, as the
+ * most common values of HZ divide 508 kHz nicely.  We pick one of the 16
+ * bit timers (timer 1) since we don't need more than 16 bits of reload
+ * value as long as HZ >= 8.
+ *
+ * The higher clock rate of timer 4 makes it a better choice than the
+ * other timers for use in gettimeoffset(), while the fact that it can't
+ * generate interrupts means we don't have to worry about not being able
+ * to use this timer for something else.  We also use timer 4 for keeping
+ * track of lost jiffies.
+ */
+static unsigned int last_jiffy_time;
+
+#define TIMER4_TICKS_PER_JIFFY		((CLOCK_TICK_RATE + (HZ/2)) / HZ)
+
+static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	write_seqlock(&xtime_lock);
+
+	__raw_writel(1, EP93XX_TIMER1_CLEAR);
+	while (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time
+						>= TIMER4_TICKS_PER_JIFFY) {
+		last_jiffy_time += TIMER4_TICKS_PER_JIFFY;
+		timer_tick(regs);
+	}
+
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction ep93xx_timer_irq = {
+	.name		= "ep93xx timer",
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= ep93xx_timer_interrupt,
+};
+
+static void __init ep93xx_timer_init(void)
+{
+	/* Enable periodic HZ timer.  */
+	__raw_writel(0x48, EP93XX_TIMER1_CONTROL);
+	__raw_writel((508000 / HZ) - 1, EP93XX_TIMER1_LOAD);
+	__raw_writel(0xc8, EP93XX_TIMER1_CONTROL);
+
+	/* Enable lost jiffy timer.  */
+	__raw_writel(0x100, EP93XX_TIMER4_VALUE_HIGH);
+
+	setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
+}
+
+static unsigned long ep93xx_gettimeoffset(void)
+{
+	int offset;
+
+	offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time;
+
+	/* Calculate (1000000 / 983040) * offset.  */
+	return offset + (53 * offset / 3072);
+}
+
+struct sys_timer ep93xx_timer = {
+	.init		= ep93xx_timer_init,
+	.offset		= ep93xx_gettimeoffset,
+};
+
+
+/*************************************************************************
+ * EP93xx IRQ handling
+ *************************************************************************/
+void __init ep93xx_init_irq(void)
+{
+	vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
+	vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
+}
+
+
+/*************************************************************************
+ * EP93xx peripheral handling
+ *************************************************************************/
+void __init ep93xx_init_devices(void)
+{
+	unsigned int v;
+
+	/*
+	 * Disallow access to MaverickCrunch initially.
+	 */
+	v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
+	v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
+	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+	__raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG);
+}
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
new file mode 100644
index 0000000000000000000000000000000000000000..d18fcb1a2f1b859d6bfea27da262f52d3c34e443
--- /dev/null
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-ep93xx/gesbc9312.c
+ * Glomation GESBC-9312-sx support.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * 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.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static void __init gesbc9312_init_machine(void)
+{
+	ep93xx_init_devices();
+	physmap_configure(0x60000000, 0x00800000, 4, NULL);
+}
+
+MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
+	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+	.phys_io	= EP93XX_APB_PHYS_BASE,
+	.io_pg_offst	= ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ep93xx_map_io,
+	.init_irq	= ep93xx_init_irq,
+	.timer		= &ep93xx_timer,
+	.init_machine	= gesbc9312_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
new file mode 100644
index 0000000000000000000000000000000000000000..777e75daa8a546dc2da62902d2a7f852ca10821d
--- /dev/null
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -0,0 +1,118 @@
+/*
+ * arch/arm/mach-ep93xx/ts72xx.c
+ * Technologic Systems TS72xx SBC support.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * 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.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+static struct map_desc ts72xx_io_desc[] __initdata = {
+	{
+		.virtual	= TS72XX_MODEL_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_MODEL_PHYS_BASE),
+		.length		= TS72XX_MODEL_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= TS72XX_OPTIONS_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_OPTIONS_PHYS_BASE),
+		.length		= TS72XX_OPTIONS_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= TS72XX_OPTIONS2_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
+		.length		= TS72XX_OPTIONS2_SIZE,
+		.type		= MT_DEVICE,
+	}
+};
+
+static struct map_desc ts72xx_nand_io_desc[] __initdata = {
+	{
+		.virtual	= TS72XX_NAND_DATA_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE),
+		.length		= TS72XX_NAND_DATA_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= TS72XX_NAND_CONTROL_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE),
+		.length		= TS72XX_NAND_CONTROL_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= TS72XX_NAND_BUSY_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE),
+		.length		= TS72XX_NAND_BUSY_SIZE,
+		.type		= MT_DEVICE,
+	}
+};
+
+static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = {
+	{
+		.virtual	= TS72XX_NAND_DATA_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_NAND2_DATA_PHYS_BASE),
+		.length		= TS72XX_NAND_DATA_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= TS72XX_NAND_CONTROL_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_NAND2_CONTROL_PHYS_BASE),
+		.length		= TS72XX_NAND_CONTROL_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= TS72XX_NAND_BUSY_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_NAND2_BUSY_PHYS_BASE),
+		.length		= TS72XX_NAND_BUSY_SIZE,
+		.type		= MT_DEVICE,
+	}
+};
+
+static void __init ts72xx_map_io(void)
+{
+	ep93xx_map_io();
+	iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc));
+
+	/*
+	 * The TS-7200 has NOR flash, the other models have NAND flash.
+	 */
+	if (!board_is_ts7200()) {
+		if (is_ts9420_installed()) {
+			iotable_init(ts72xx_alternate_nand_io_desc,
+				ARRAY_SIZE(ts72xx_alternate_nand_io_desc));
+		} else {
+			iotable_init(ts72xx_nand_io_desc,
+				ARRAY_SIZE(ts72xx_nand_io_desc));
+		}
+	}
+}
+
+static void __init ts72xx_init_machine(void)
+{
+	ep93xx_init_devices();
+	if (board_is_ts7200())
+		physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL);
+}
+
+MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
+	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+	.phys_io	= EP93XX_APB_PHYS_BASE,
+	.io_pg_offst	= ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ts72xx_map_io,
+	.init_irq	= ep93xx_init_irq,
+	.timer		= &ep93xx_timer,
+	.init_machine	= ts72xx_init_machine,
+MACHINE_END
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 3b79d0e234559666d52b8da4bf72cfe6028e7c9e..eaaec90db9728718da9114d10656d23dd5fc2797 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -62,7 +62,7 @@ config CPU_ARM720T
 # ARM920T
 config CPU_ARM920T
 	bool "Support ARM920T processor" if !ARCH_S3C2410
-	depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
+	depends on ARCH_EP93XX || ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
 	default y if ARCH_S3C2410 || ARCH_AT91RM9200
 	select CPU_32v4
 	select CPU_ABRT_EV4T
diff --git a/include/asm-arm/arch-ep93xx/debug-macro.S b/include/asm-arm/arch-ep93xx/debug-macro.S
new file mode 100644
index 0000000000000000000000000000000000000000..397565a0c6714578180658dc350515e1041de76b
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/debug-macro.S
@@ -0,0 +1,22 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/debug-macro.S
+ * Debugging macro include header
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * 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.
+ */
+#include <asm/arch/ep93xx-regs.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1				@ MMU enabled?
+		ldreq	\rx, =EP93XX_APB_PHYS_BASE	@ Physical base
+		ldrne	\rx, =EP93XX_APB_VIRT_BASE	@ virtual base
+		orr	\rx, \rx, #0x000c0000
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/include/asm-arm/arch-ep93xx/dma.h b/include/asm-arm/arch-ep93xx/dma.h
new file mode 100644
index 0000000000000000000000000000000000000000..898b3ab7fd46c944faa20c842ada51baa2ec8174
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/dma.h
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/dma.h
+ */
diff --git a/include/asm-arm/arch-ep93xx/entry-macro.S b/include/asm-arm/arch-ep93xx/entry-macro.S
new file mode 100644
index 0000000000000000000000000000000000000000..84140a28dfcf8bec343ef7a3341ac1671b9a8341
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/entry-macro.S
@@ -0,0 +1,53 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/entry-macro.S
+ * IRQ demultiplexing for EP93xx
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * 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.
+ */
+#include <asm/arch/ep93xx-regs.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =(EP93XX_AHB_VIRT_BASE)
+		orr	\base, \base, #0x000b0000
+		mov	\irqnr, #0
+		ldr	\irqstat, [\base]		@ lower 32 interrupts
+		cmp	\irqstat, #0
+		bne	1001f
+
+		eor	\base, \base, #0x00070000
+		ldr	\irqstat, [\base]		@ upper 32 interrupts
+		cmp	\irqstat, #0
+		beq	1002f
+		mov	\irqnr, #0x20
+
+1001:
+		movs	\tmp, \irqstat, lsl #16
+		movne	\irqstat, \tmp
+		addeq	\irqnr, \irqnr, #16
+
+		movs	\tmp, \irqstat, lsl #8
+		movne	\irqstat, \tmp
+		addeq	\irqnr, \irqnr, #8
+
+		movs	\tmp, \irqstat, lsl #4
+		movne	\irqstat, \tmp
+		addeq	\irqnr, \irqnr, #4
+
+		movs	\tmp, \irqstat, lsl #2
+		movne	\irqstat, \tmp
+		addeq	\irqnr, \irqnr, #2
+
+		movs	\tmp, \irqstat, lsl #1
+		addeq	\irqnr, \irqnr, #1
+		orrs	\base, \base, #1
+
+1002:
+		.endm
diff --git a/include/asm-arm/arch-ep93xx/ep93xx-regs.h b/include/asm-arm/arch-ep93xx/ep93xx-regs.h
new file mode 100644
index 0000000000000000000000000000000000000000..693f23886e855b18cb751ca2a12fa4dd6a47f35d
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/ep93xx-regs.h
@@ -0,0 +1,114 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/ep93xx-regs.h
+ */
+
+#ifndef __ASM_ARCH_EP93XX_REGS_H
+#define __ASM_ARCH_EP93XX_REGS_H
+
+/*
+ * EP93xx linux memory map:
+ *
+ * virt		phys		size
+ * fe800000			5M		per-platform mappings
+ * fed00000	80800000	2M		APB
+ * fef00000	80000000	1M		AHB
+ */
+
+#define EP93XX_AHB_PHYS_BASE		0x80000000
+#define EP93XX_AHB_VIRT_BASE		0xfef00000
+#define EP93XX_AHB_SIZE			0x00100000
+
+#define EP93XX_APB_PHYS_BASE		0x80800000
+#define EP93XX_APB_VIRT_BASE		0xfed00000
+#define EP93XX_APB_SIZE			0x00200000
+
+
+/* AHB peripherals */
+#define EP93XX_DMA_BASE			(EP93XX_AHB_VIRT_BASE + 0x00000000)
+
+#define EP93XX_ETHERNET_BASE		(EP93XX_AHB_VIRT_BASE + 0x00010000)
+
+#define EP93XX_USB_BASE			(EP93XX_AHB_VIRT_BASE + 0x00020000)
+#define EP93XX_USB_PHYS_BASE		(EP93XX_AHB_PHYS_BASE + 0x00020000)
+
+#define EP93XX_RASTER_BASE		(EP93XX_AHB_VIRT_BASE + 0x00030000)
+
+#define EP93XX_GRAPHICS_ACCEL_BASE	(EP93XX_AHB_VIRT_BASE + 0x00040000)
+
+#define EP93XX_SDRAM_CONTROLLER_BASE	(EP93XX_AHB_VIRT_BASE + 0x00060000)
+
+#define EP93XX_PCMCIA_CONTROLLER_BASE	(EP93XX_AHB_VIRT_BASE + 0x00080000)
+
+#define EP93XX_BOOT_ROM_BASE		(EP93XX_AHB_VIRT_BASE + 0x00090000)
+
+#define EP93XX_IDE_BASE			(EP93XX_AHB_VIRT_BASE + 0x000a0000)
+
+#define EP93XX_VIC1_BASE		(EP93XX_AHB_VIRT_BASE + 0x000b0000)
+
+#define EP93XX_VIC2_BASE		(EP93XX_AHB_VIRT_BASE + 0x000c0000)
+
+
+/* APB peripherals */
+#define EP93XX_TIMER_BASE		(EP93XX_APB_VIRT_BASE + 0x00010000)
+#define EP93XX_TIMER_REG(x)		(EP93XX_TIMER_BASE + (x))
+#define EP93XX_TIMER1_LOAD		EP93XX_TIMER_REG(0x00)
+#define EP93XX_TIMER1_VALUE		EP93XX_TIMER_REG(0x04)
+#define EP93XX_TIMER1_CONTROL		EP93XX_TIMER_REG(0x08)
+#define EP93XX_TIMER1_CLEAR		EP93XX_TIMER_REG(0x0c)
+#define EP93XX_TIMER2_LOAD		EP93XX_TIMER_REG(0x20)
+#define EP93XX_TIMER2_VALUE		EP93XX_TIMER_REG(0x24)
+#define EP93XX_TIMER2_CONTROL		EP93XX_TIMER_REG(0x28)
+#define EP93XX_TIMER2_CLEAR		EP93XX_TIMER_REG(0x2c)
+#define EP93XX_TIMER4_VALUE_LOW		EP93XX_TIMER_REG(0x60)
+#define EP93XX_TIMER4_VALUE_HIGH	EP93XX_TIMER_REG(0x64)
+#define EP93XX_TIMER3_LOAD		EP93XX_TIMER_REG(0x80)
+#define EP93XX_TIMER3_VALUE		EP93XX_TIMER_REG(0x84)
+#define EP93XX_TIMER3_CONTROL		EP93XX_TIMER_REG(0x88)
+#define EP93XX_TIMER3_CLEAR		EP93XX_TIMER_REG(0x8c)
+
+#define EP93XX_I2S_BASE			(EP93XX_APB_VIRT_BASE + 0x00020000)
+
+#define EP93XX_SECURITY_BASE		(EP93XX_APB_VIRT_BASE + 0x00030000)
+
+#define EP93XX_GPIO_BASE		(EP93XX_APB_VIRT_BASE + 0x00040000)
+
+#define EP93XX_AAC_BASE			(EP93XX_APB_VIRT_BASE + 0x00080000)
+
+#define EP93XX_SPI_BASE			(EP93XX_APB_VIRT_BASE + 0x000a0000)
+
+#define EP93XX_IRDA_BASE		(EP93XX_APB_VIRT_BASE + 0x000b0000)
+
+#define EP93XX_UART1_BASE		(EP93XX_APB_VIRT_BASE + 0x000c0000)
+#define EP93XX_UART1_PHYS_BASE		(EP93XX_APB_PHYS_BASE + 0x000c0000)
+
+#define EP93XX_UART2_BASE		(EP93XX_APB_VIRT_BASE + 0x000d0000)
+#define EP93XX_UART2_PHYS_BASE		(EP93XX_APB_PHYS_BASE + 0x000d0000)
+
+#define EP93XX_UART3_BASE		(EP93XX_APB_VIRT_BASE + 0x000e0000)
+#define EP93XX_UART3_PHYS_BASE		(EP93XX_APB_PHYS_BASE + 0x000e0000)
+
+#define EP93XX_KEY_MATRIX_BASE		(EP93XX_APB_VIRT_BASE + 0x000f0000)
+
+#define EP93XX_ADC_BASE			(EP93XX_APB_VIRT_BASE + 0x00100000)
+#define EP93XX_TOUCHSCREEN_BASE		(EP93XX_APB_VIRT_BASE + 0x00100000)
+
+#define EP93XX_PWM_BASE			(EP93XX_APB_VIRT_BASE + 0x00110000)
+
+#define EP93XX_RTC_BASE			(EP93XX_APB_VIRT_BASE + 0x00120000)
+
+#define EP93XX_SYSCON_BASE		(EP93XX_APB_VIRT_BASE + 0x00130000)
+#define EP93XX_SYSCON_REG(x)		(EP93XX_SYSCON_BASE + (x))
+#define EP93XX_SYSCON_POWER_STATE	EP93XX_SYSCON_REG(0x00)
+#define EP93XX_SYSCON_CLOCK_CONTROL	EP93XX_SYSCON_REG(0x04)
+#define EP93XX_SYSCON_CLOCK_UARTBAUD	0x20000000
+#define EP93XX_SYSCON_CLOCK_USH_EN	0x10000000
+#define EP93XX_SYSCON_HALT		EP93XX_SYSCON_REG(0x08)
+#define EP93XX_SYSCON_STANDBY		EP93XX_SYSCON_REG(0x0c)
+#define EP93XX_SYSCON_DEVICE_CONFIG	EP93XX_SYSCON_REG(0x80)
+#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE	0x00800000
+#define EP93XX_SYSCON_SWLOCK		EP93XX_SYSCON_REG(0xc0)
+
+#define EP93XX_WATCHDOG_BASE		(EP93XX_APB_VIRT_BASE + 0x00140000)
+
+
+#endif
diff --git a/include/asm-arm/arch-ep93xx/gesbc9312.h b/include/asm-arm/arch-ep93xx/gesbc9312.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d0b3023bff79215f160c3c064f46bfee35d7d4f
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/gesbc9312.h
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/gesbc9312.h
+ */
diff --git a/include/asm-arm/arch-ep93xx/hardware.h b/include/asm-arm/arch-ep93xx/hardware.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b69f454065d458830f72ecc26c40f05eb42e54b
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/hardware.h
@@ -0,0 +1,12 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/hardware.h
+ */
+
+#include "ep93xx-regs.h"
+
+#define pcibios_assign_all_busses()	0
+
+#include "platform.h"
+
+#include "gesbc9312.h"
+#include "ts72xx.h"
diff --git a/include/asm-arm/arch-ep93xx/io.h b/include/asm-arm/arch-ep93xx/io.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b4d25e290606a26d390f4df0cd04eb97ce8aecd
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/io.h
@@ -0,0 +1,8 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/io.h
+ */
+
+#define IO_SPACE_LIMIT		0xffffffff
+
+#define __io(p)			((void __iomem *)(p))
+#define __mem_pci(p)		(p)
diff --git a/include/asm-arm/arch-ep93xx/irqs.h b/include/asm-arm/arch-ep93xx/irqs.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c10fb964fafa43ac66b8d84b7cebeefeb7b040d
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/irqs.h
@@ -0,0 +1,78 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/irqs.h
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define IRQ_EP93XX_COMMRX		2
+#define IRQ_EP93XX_COMMTX		3
+#define IRQ_EP93XX_TIMER1		4
+#define IRQ_EP93XX_TIMER2		5
+#define IRQ_EP93XX_AACINTR		6
+#define IRQ_EP93XX_DMAM2P0		7
+#define IRQ_EP93XX_DMAM2P1		8
+#define IRQ_EP93XX_DMAM2P2		9
+#define IRQ_EP93XX_DMAM2P3		10
+#define IRQ_EP93XX_DMAM2P4		11
+#define IRQ_EP93XX_DMAM2P5		12
+#define IRQ_EP93XX_DMAM2P6		13
+#define IRQ_EP93XX_DMAM2P7		14
+#define IRQ_EP93XX_DMAM2P8		15
+#define IRQ_EP93XX_DMAM2P9		16
+#define IRQ_EP93XX_DMAM2M0		17
+#define IRQ_EP93XX_DMAM2M1		18
+#define IRQ_EP93XX_GPIO0MUX		20
+#define IRQ_EP93XX_GPIO1MUX		21
+#define IRQ_EP93XX_GPIO2MUX		22
+#define IRQ_EP93XX_GPIO3MUX		22
+#define IRQ_EP93XX_UART1RX		23
+#define IRQ_EP93XX_UART1TX		24
+#define IRQ_EP93XX_UART2RX		25
+#define IRQ_EP93XX_UART2TX		26
+#define IRQ_EP93XX_UART3RX		27
+#define IRQ_EP93XX_UART3TX		28
+#define IRQ_EP93XX_KEY			29
+#define IRQ_EP93XX_TOUCH		30
+#define EP93XX_VIC1_VALID_IRQ_MASK	0x7ffffffc
+
+#define IRQ_EP93XX_EXT0			32
+#define IRQ_EP93XX_EXT1			33
+#define IRQ_EP93XX_EXT2			34
+#define IRQ_EP93XX_64HZ			35
+#define IRQ_EP93XX_WATCHDOG		36
+#define IRQ_EP93XX_RTC			37
+#define IRQ_EP93XX_IRDA			38
+#define IRQ_EP93XX_ETHERNET		39
+#define IRQ_EP93XX_EXT3			40
+#define IRQ_EP93XX_PROG			41
+#define IRQ_EP93XX_1HZ			42
+#define IRQ_EP93XX_VSYNC		43
+#define IRQ_EP93XX_VIDEO_FIFO		44
+#define IRQ_EP93XX_SSP1RX		45
+#define IRQ_EP93XX_SSP1TX		46
+#define IRQ_EP93XX_GPIO4MUX		47
+#define IRQ_EP93XX_GPIO5MUX		48
+#define IRQ_EP93XX_GPIO6MUX		49
+#define IRQ_EP93XX_GPIO7MUX		50
+#define IRQ_EP93XX_TIMER3		51
+#define IRQ_EP93XX_UART1		52
+#define IRQ_EP93XX_SSP			53
+#define IRQ_EP93XX_UART2		54
+#define IRQ_EP93XX_UART3		55
+#define IRQ_EP93XX_USB			56
+#define IRQ_EP93XX_ETHERNET_PME		57
+#define IRQ_EP93XX_DSP			58
+#define IRQ_EP93XX_GPIO_AB		59
+#define IRQ_EP93XX_SAI			60
+#define EP93XX_VIC2_VALID_IRQ_MASK	0x1fffffff
+
+#define NR_EP93XX_IRQS			64
+
+#define EP93XX_BOARD_IRQ(x)		(NR_EP93XX_IRQS + (x))
+#define EP93XX_BOARD_IRQS		32
+
+#define NR_IRQS				(NR_EP93XX_IRQS + EP93XX_BOARD_IRQS)
+
+
+#endif
diff --git a/include/asm-arm/arch-ep93xx/memory.h b/include/asm-arm/arch-ep93xx/memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b1a5c7c83639b7101e7b77c9a2406bfe7854be2
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/memory.h
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET		UL(0x00000000)
+
+#define __bus_to_virt(x)	__phys_to_virt(x)
+#define __virt_to_bus(x)	__virt_to_phys(x)
+
+
+#endif
diff --git a/include/asm-arm/arch-ep93xx/platform.h b/include/asm-arm/arch-ep93xx/platform.h
new file mode 100644
index 0000000000000000000000000000000000000000..df9cbb6ef660965e7e94d1fba665c8d6eef380dd
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/platform.h
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/platform.h
+ */
+
+#ifndef __ASSEMBLY__
+
+void ep93xx_map_io(void);
+void ep93xx_init_irq(void);
+void ep93xx_init_time(unsigned long);
+void ep93xx_init_devices(void);
+extern struct sys_timer ep93xx_timer;
+
+
+#endif
diff --git a/include/asm-arm/arch-ep93xx/system.h b/include/asm-arm/arch-ep93xx/system.h
new file mode 100644
index 0000000000000000000000000000000000000000..79b718586746b23c4862c599ca222353804de0b8
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/system.h
@@ -0,0 +1,26 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/system.h
+ */
+
+#include <asm/hardware.h>
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	u32 devicecfg;
+
+	local_irq_disable();
+
+	devicecfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
+	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+	__raw_writel(devicecfg | 0x80000000, EP93XX_SYSCON_DEVICE_CONFIG);
+	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+	__raw_writel(devicecfg & ~0x80000000, EP93XX_SYSCON_DEVICE_CONFIG);
+
+	while (1)
+		;
+}
diff --git a/include/asm-arm/arch-ep93xx/timex.h b/include/asm-arm/arch-ep93xx/timex.h
new file mode 100644
index 0000000000000000000000000000000000000000..4140bddc97e20f6610bb3a8478d912c2bb2f1417
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/timex.h
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/timex.h
+ */
+
+#define CLOCK_TICK_RATE		983040
diff --git a/include/asm-arm/arch-ep93xx/ts72xx.h b/include/asm-arm/arch-ep93xx/ts72xx.h
new file mode 100644
index 0000000000000000000000000000000000000000..412215e77f444c7dc9c8a4861a96196280b127da
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/ts72xx.h
@@ -0,0 +1,90 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/ts72xx.h
+ */
+
+/*
+ * TS72xx memory map:
+ *
+ * virt		phys		size
+ * febff000	22000000	4K	model number register
+ * febfe000	22400000	4K	options register
+ * febfd000	22800000	4K	options register #2
+ * febfc000	[67]0000000	4K	NAND data register
+ * febfb000	[67]0400000	4K	NAND control register
+ * febfa000	[67]0800000	4K	NAND busy register
+ */
+
+#define TS72XX_MODEL_PHYS_BASE		0x22000000
+#define TS72XX_MODEL_VIRT_BASE		0xfebff000
+#define TS72XX_MODEL_SIZE		0x00001000
+
+#define TS72XX_MODEL_TS7200		0x00
+#define TS72XX_MODEL_TS7250		0x01
+#define TS72XX_MODEL_TS7260		0x02
+
+
+#define TS72XX_OPTIONS_PHYS_BASE	0x22400000
+#define TS72XX_OPTIONS_VIRT_BASE	0xfebfe000
+#define TS72XX_OPTIONS_SIZE		0x00001000
+
+#define TS72XX_OPTIONS_COM2_RS485	0x02
+#define TS72XX_OPTIONS_MAX197		0x01
+
+
+#define TS72XX_OPTIONS2_PHYS_BASE	0x22800000
+#define TS72XX_OPTIONS2_VIRT_BASE	0xfebfd000
+#define TS72XX_OPTIONS2_SIZE		0x00001000
+
+#define TS72XX_OPTIONS2_TS9420		0x04
+#define TS72XX_OPTIONS2_TS9420_BOOT	0x02
+
+
+#define TS72XX_NOR_PHYS_BASE		0x60000000
+#define TS72XX_NOR2_PHYS_BASE		0x62000000
+
+#define TS72XX_NAND1_DATA_PHYS_BASE	0x60000000
+#define TS72XX_NAND2_DATA_PHYS_BASE	0x70000000
+#define TS72XX_NAND_DATA_VIRT_BASE	0xfebfc000
+#define TS72XX_NAND_DATA_SIZE		0x00001000
+
+#define TS72XX_NAND1_CONTROL_PHYS_BASE	0x60400000
+#define TS72XX_NAND2_CONTROL_PHYS_BASE	0x70400000
+#define TS72XX_NAND_CONTROL_VIRT_BASE	0xfebfb000
+#define TS72XX_NAND_CONTROL_SIZE	0x00001000
+
+#define TS72XX_NAND1_BUSY_PHYS_BASE	0x60800000
+#define TS72XX_NAND2_BUSY_PHYS_BASE	0x70800000
+#define TS72XX_NAND_BUSY_VIRT_BASE	0xfebfa000
+#define TS72XX_NAND_BUSY_SIZE		0x00001000
+
+
+#ifndef __ASSEMBLY__
+#include <asm/io.h>
+
+static inline int board_is_ts7200(void)
+{
+	return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7200;
+}
+
+static inline int board_is_ts7250(void)
+{
+	return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7250;
+}
+
+static inline int board_is_ts7260(void)
+{
+	return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260;
+}
+
+static inline int is_max197_installed(void)
+{
+	return !!(__raw_readb(TS72XX_OPTIONS_VIRT_BASE) &
+					TS72XX_OPTIONS_MAX197);
+}
+
+static inline int is_ts9420_installed(void)
+{
+	return !!(__raw_readb(TS72XX_OPTIONS2_VIRT_BASE) &
+					TS72XX_OPTIONS2_TS9420);
+}
+#endif
diff --git a/include/asm-arm/arch-ep93xx/uncompress.h b/include/asm-arm/arch-ep93xx/uncompress.h
new file mode 100644
index 0000000000000000000000000000000000000000..4410d217077e04c743b7c6857fe2bef26bf49510
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/uncompress.h
@@ -0,0 +1,53 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/uncompress.h
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * 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.
+ */
+
+#include <asm/arch/ep93xx-regs.h>
+
+static unsigned char __raw_readb(unsigned int ptr)
+{
+	return *((volatile unsigned char *)ptr);
+}
+
+static void __raw_writeb(unsigned char value, unsigned int ptr)
+{
+	*((volatile unsigned char *)ptr) = value;
+}
+
+
+#define PHYS_UART1_DATA		0x808c0000
+#define PHYS_UART1_FLAG		0x808c0018
+#define UART1_FLAG_TXFF		0x20
+
+static __inline__ void putc(char c)
+{
+	int i;
+
+	for (i = 0; i < 1000; i++) {
+		/* Transmit fifo not full?  */
+		if (!(__raw_readb(PHYS_UART1_FLAG) & UART1_FLAG_TXFF))
+			break;
+	}
+
+	__raw_writeb(c, PHYS_UART1_DATA);
+}
+
+static void putstr(const char *s)
+{
+	while (*s) {
+		putc(*s);
+		if (*s == '\n')
+			putc('\r');
+		s++;
+	}
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-ep93xx/vmalloc.h b/include/asm-arm/arch-ep93xx/vmalloc.h
new file mode 100644
index 0000000000000000000000000000000000000000..205ea6b1cf5e82157627d97b0783041239d3299e
--- /dev/null
+++ b/include/asm-arm/arch-ep93xx/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/vmalloc.h
+ */
+
+#define VMALLOC_END	0xfe800000