diff -urN linux-2.6.15.commit/arch/arm/common/Kconfig linux-2.6.15.snap/arch/arm/common/Kconfig
--- linux-2.6.15.commit/arch/arm/common/Kconfig	2006-02-12 10:22:18.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/common/Kconfig	2006-02-20 13:56:04.000000000 +0100
@@ -1,7 +1,10 @@
-config ICST525
+config ARM_GIC
 	bool
 
-config ARM_GIC
+config ARM_VIC
+	bool
+
+config ICST525
 	bool
 
 config ICST307
diff -urN linux-2.6.15.commit/arch/arm/common/Makefile linux-2.6.15.snap/arch/arm/common/Makefile
--- linux-2.6.15.commit/arch/arm/common/Makefile	2006-02-12 10:22:18.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/common/Makefile	2006-02-20 13:56:32.000000000 +0100
@@ -5,6 +5,7 @@
 obj-y				+= rtctime.o
 obj-$(CONFIG_ARM_AMBA)		+= amba.o
 obj-$(CONFIG_ARM_GIC)		+= gic.o
+obj-$(CONFIG_ARM_VIC)		+= vic.o
 obj-$(CONFIG_ICST525)		+= icst525.o
 obj-$(CONFIG_ICST307)		+= icst307.o
 obj-$(CONFIG_SA1111)		+= sa1111.o
diff -urN linux-2.6.15.commit/arch/arm/common/vic.c linux-2.6.15.snap/arch/arm/common/vic.c
--- linux-2.6.15.commit/arch/arm/common/vic.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/common/vic.c	2006-02-20 18:38:41.000000000 +0100
@@ -0,0 +1,91 @@
+/*
+ *  linux/arch/arm/common/vic.c
+ *
+ *  Copyright (C) 1999 - 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/list.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware/vic.h>
+
+static void vic_mask_irq(unsigned int irq)
+{
+	void __iomem *base = get_irq_chipdata(irq);
+	irq &= 31;
+	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void vic_unmask_irq(unsigned int irq)
+{
+	void __iomem *base = get_irq_chipdata(irq);
+	irq &= 31;
+	writel(1 << irq, base + VIC_INT_ENABLE);
+}
+
+static struct irqchip vic_chip = {
+	.ack	= vic_mask_irq,
+	.mask	= vic_mask_irq,
+	.unmask	= vic_unmask_irq,
+};
+
+void __init vic_init(void __iomem *base, unsigned int irq_start,
+		     u32 vic_sources)
+{
+	unsigned int i;
+
+	/* Disable all interrupts initially. */
+
+	writel(0, base + VIC_INT_SELECT);
+	writel(~0, base + VIC_INT_ENABLE_CLEAR);
+	writel(0, base + VIC_ITCR);
+	writel(~0, base + VIC_INT_SOFT_CLEAR);
+
+	/*
+	 * Make sure we clear all existing interrupts
+	 */
+	writel(0, base + VIC_VECT_ADDR);
+	for (i = 0; i < 19; i++) {
+		unsigned int value;
+
+		value = readl(base + VIC_VECT_ADDR);
+		writel(value, base + VIC_VECT_ADDR);
+	}
+
+	for (i = 0; i < 16; i++) {
+		void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
+//		writel(VIC_VECT_CNTL_ENABLE | i, reg);
+		writel(0, reg);
+	}
+
+	writel(32, base + VIC_DEF_VECT_ADDR);
+
+	for (i = 0; i < 32; i++) {
+		unsigned int irq = irq_start + i;
+
+		set_irq_chip(irq, &vic_chip);
+		set_irq_chipdata(irq, base);
+
+		if (vic_sources & (1 << i)) {
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+		}
+	}
+}
diff -urN linux-2.6.15.commit/arch/arm/configs/ep93xx_defconfig linux-2.6.15.snap/arch/arm/configs/ep93xx_defconfig
--- linux-2.6.15.commit/arch/arm/configs/ep93xx_defconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/configs/ep93xx_defconfig	2006-02-20 21:11:41.000000000 +0100
@@ -0,0 +1,850 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.15
+# Mon Feb 20 13:59:13 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+CONFIG_ARCH_EP93XX=y
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+
+#
+# Cirrus EP93xx Implementation Options
+#
+
+#
+# EP93xx Platforms
+#
+CONFIG_MACH_GESBC9312=y
+CONFIG_MACH_TS72XX=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+CONFIG_ARM_VIC=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAM0,115200 root=/dev/nfs ip=bootp"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_ROM=y
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_EP93XX_ETHERNET=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBA_PL010=y
+CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
+# CONFIG_SERIAL_AMBA_PL011 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
diff -urN linux-2.6.15.commit/arch/arm/Kconfig linux-2.6.15.snap/arch/arm/Kconfig
--- linux-2.6.15.commit/arch/arm/Kconfig	2006-02-12 10:22:17.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/Kconfig	2006-02-20 13:56:20.000000000 +0100
@@ -103,6 +103,13 @@
 	  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_CAMELOT
 	bool "Epxa10db"
 	help
@@ -219,6 +226,8 @@
 
 source "arch/arm/mach-clps711x/Kconfig"
 
+source "arch/arm/mach-ep93xx/Kconfig"
+
 source "arch/arm/mach-epxa10db/Kconfig"
 
 source "arch/arm/mach-footbridge/Kconfig"
diff -urN linux-2.6.15.commit/arch/arm/mach-ep93xx/core.c linux-2.6.15.snap/arch/arm/mach-ep93xx/core.c
--- linux-2.6.15.commit/arch/arm/mach-ep93xx/core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/mach-ep93xx/core.c	2006-02-28 01:41:25.000000000 +0100
@@ -0,0 +1,223 @@
+/*
+ * 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 <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/amba.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		((983040 + (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((CLOCK_TICK_RATE / 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
+ *************************************************************************/
+static struct amba_device uart1_device = {
+	.dev		= {
+		.bus_id = "apb:uart1",
+	},
+	.res		= {
+		.start	= EP93XX_UART1_BASE,
+		.end	= EP93XX_UART1_BASE + 0xfff,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= { IRQ_EP93XX_UART1, NO_IRQ },
+	.periphid	= 0x0041010,
+};
+
+static struct amba_device uart2_device = {
+	.dev		= {
+		.bus_id = "apb:uart2",
+	},
+	.res		= {
+		.start	= EP93XX_UART2_BASE,
+		.end	= EP93XX_UART2_BASE + 0xfff,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= { IRQ_EP93XX_UART2, NO_IRQ },
+	.periphid	= 0x0041010,
+};
+
+static struct resource ep93xx_ohci_resources[] = {
+	[0] = {
+		.start	= EP93XX_USB_BASE,
+		.end	= EP93XX_USB_BASE + 0xffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_EP93XX_USB,
+		.end	= IRQ_EP93XX_USB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ep93xx_ohci_device = {
+	.name		= "ep93xx-ohci",
+	.id		= -1,
+	.dev		= {
+		.dma_mask		= (void *)0xffffffff,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(ep93xx_ohci_resources),
+	.resource	= ep93xx_ohci_resources,
+};
+
+void __init ep93xx_init_devices(void)
+{
+#if 0
+	__raw_writel(__raw_readl(EP93XX_SYSCON_CLOCK_CONTROL) |
+					EP93XX_SYSCON_CLOCK_UARTBAUD,
+			EP93XX_SYSCON_CLOCK_CONTROL);
+#endif
+
+	amba_device_register(&uart1_device, &iomem_resource);
+	amba_device_register(&uart2_device, &iomem_resource);
+	platform_device_register(&ep93xx_ohci_device);
+}
diff -urN linux-2.6.15.commit/arch/arm/mach-ep93xx/gesbc9312.c linux-2.6.15.snap/arch/arm/mach-ep93xx/gesbc9312.c
--- linux-2.6.15.commit/arch/arm/mach-ep93xx/gesbc9312.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/mach-ep93xx/gesbc9312.c	2006-02-20 22:30:19.000000000 +0100
@@ -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, 0x02000000, 1, 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 -urN linux-2.6.15.commit/arch/arm/mach-ep93xx/Kconfig linux-2.6.15.snap/arch/arm/mach-ep93xx/Kconfig
--- linux-2.6.15.commit/arch/arm/mach-ep93xx/Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/mach-ep93xx/Kconfig	2006-02-19 18:09:49.000000000 +0100
@@ -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 TS-72xx
+	  board.
+
+endmenu
+
+endif
diff -urN linux-2.6.15.commit/arch/arm/mach-ep93xx/Makefile linux-2.6.15.snap/arch/arm/mach-ep93xx/Makefile
--- linux-2.6.15.commit/arch/arm/mach-ep93xx/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/mach-ep93xx/Makefile	2006-02-19 17:47:43.000000000 +0100
@@ -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 -urN linux-2.6.15.commit/arch/arm/mach-ep93xx/Makefile.boot linux-2.6.15.snap/arch/arm/mach-ep93xx/Makefile.boot
--- linux-2.6.15.commit/arch/arm/mach-ep93xx/Makefile.boot	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/mach-ep93xx/Makefile.boot	2006-02-19 22:04:54.000000000 +0100
@@ -0,0 +1,2 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
diff -urN linux-2.6.15.commit/arch/arm/mach-ep93xx/ts72xx.c linux-2.6.15.snap/arch/arm/mach-ep93xx/ts72xx.c
--- linux-2.6.15.commit/arch/arm/mach-ep93xx/ts72xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/mach-ep93xx/ts72xx.c	2006-02-22 17:01:43.000000000 +0100
@@ -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()) {
+		physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL);
+	} else {
+		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();
+}
+
+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 -urN linux-2.6.15.commit/arch/arm/Makefile linux-2.6.15.snap/arch/arm/Makefile
--- linux-2.6.15.commit/arch/arm/Makefile	2006-02-12 10:22:18.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/Makefile	2006-02-19 17:29:10.000000000 +0100
@@ -102,6 +102,7 @@
  machine-$(CONFIG_ARCH_H720X)	   := h720x
  machine-$(CONFIG_ARCH_AAEC2000)   := aaec2000
  machine-$(CONFIG_ARCH_REALVIEW)   := realview
+ machine-$(CONFIG_ARCH_EP93XX)	   := ep93xx
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
diff -urN linux-2.6.15.commit/arch/arm/mm/Kconfig linux-2.6.15.snap/arch/arm/mm/Kconfig
--- linux-2.6.15.commit/arch/arm/mm/Kconfig	2006-02-12 10:22:18.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/mm/Kconfig	2006-02-19 19:14:48.000000000 +0100
@@ -62,7 +62,7 @@
 # ARM920T
 config CPU_ARM920T
 	bool "Support ARM920T processor" if !ARCH_S3C2410
-	depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000
+	depends on ARCH_EP93XX || ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000
 	default y if ARCH_S3C2410
 	select CPU_32v4
 	select CPU_ABRT_EV4T
diff -urN linux-2.6.15.commit/arch/arm/tools/mach-types linux-2.6.15.snap/arch/arm/tools/mach-types
--- linux-2.6.15.commit/arch/arm/tools/mach-types	2006-02-12 10:22:18.000000000 +0100
+++ linux-2.6.15.snap/arch/arm/tools/mach-types	2006-02-19 19:49:29.000000000 +0100
@@ -910,3 +910,4 @@
 nadia2vb		MACH_NADIA2VB		NADIA2VB		897
 r1000			MACH_R1000		R1000			898
 hw90250			MACH_HW90250		HW90250			899
+gesbc9312		MACH_GESBC9312		GESBC9312		958
diff -urN linux-2.6.15.commit/drivers/mtd/maps/physmap.c linux-2.6.15.snap/drivers/mtd/maps/physmap.c
--- linux-2.6.15.commit/drivers/mtd/maps/physmap.c	2006-02-12 10:22:16.000000000 +0100
+++ linux-2.6.15.snap/drivers/mtd/maps/physmap.c	2006-02-20 21:14:23.000000000 +0100
@@ -51,6 +51,9 @@
 	static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };
 	const char **type;
 
+	if (!physmap_map.size)
+		return -EIO;
+
        	printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys);
 	physmap_map.virt = ioremap(physmap_map.phys, physmap_map.size);
 
diff -urN linux-2.6.15.commit/drivers/mtd/nand/Kconfig linux-2.6.15.snap/drivers/mtd/nand/Kconfig
--- linux-2.6.15.commit/drivers/mtd/nand/Kconfig	2006-02-12 10:22:16.000000000 +0100
+++ linux-2.6.15.snap/drivers/mtd/nand/Kconfig	2006-02-20 21:20:41.000000000 +0100
@@ -55,6 +55,12 @@
 	help
 	  Support for NAND flash on Texas Instruments Toto platform.
 
+config MTD_NAND_TS7250
+	tristate "NAND Flash device on TS-7250 board"
+	depends on MACH_TS72XX && MTD_NAND
+	help
+	  Support for NAND flash on Technologic Systems TS-7250 platform.
+
 config MTD_NAND_IDS
 	tristate
 
diff -urN linux-2.6.15.commit/drivers/mtd/nand/Makefile linux-2.6.15.snap/drivers/mtd/nand/Makefile
--- linux-2.6.15.commit/drivers/mtd/nand/Makefile	2006-02-12 10:22:16.000000000 +0100
+++ linux-2.6.15.snap/drivers/mtd/nand/Makefile	2006-02-20 21:19:38.000000000 +0100
@@ -17,6 +17,7 @@
 obj-$(CONFIG_MTD_NAND_H1900)		+= h1910.o
 obj-$(CONFIG_MTD_NAND_RTC_FROM4)	+= rtc_from4.o
 obj-$(CONFIG_MTD_NAND_SHARPSL)		+= sharpsl.o
+obj-$(CONFIG_MTD_NAND_TS7250)		+= ts7250.o
 obj-$(CONFIG_MTD_NAND_NANDSIM)		+= nandsim.o
 
 nand-objs = nand_base.o nand_bbt.o
diff -urN linux-2.6.15.commit/drivers/mtd/nand/ts7250.c linux-2.6.15.snap/drivers/mtd/nand/ts7250.c
--- linux-2.6.15.commit/drivers/mtd/nand/ts7250.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/drivers/mtd/nand/ts7250.c	2006-02-22 17:07:53.000000000 +0100
@@ -0,0 +1,212 @@
+/*
+ * drivers/mtd/nand/ts7250.c
+ *
+ * Copyright (C) 2004 Technologic Systems (support@embeddedARM.com)
+ *
+ * Derived from drivers/mtd/nand/edb7312.c
+ *   Copyright (C) 2004 Marius Gr�ger (mag@sysgo.de)
+ *
+ * Derived from drivers/mtd/nand/autcpu12.c
+ *   Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
+ *
+ * $Id: ts7250.c,v 1.4 2004/12/30 22:02:07 joff Exp $
+ *
+ * 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.
+ *
+ * Overview:
+ *   This is a device driver for the NAND flash device found on the
+ *   TS-7250 board which utilizes a Samsung 32 Mbyte part.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/sizes.h>
+
+/*
+ * MTD structure for TS7250 board
+ */
+static struct mtd_info *ts7250_mtd = NULL;
+
+
+/*
+ * Module stuff
+ */
+static void *ts7250_nandctrl = (void *)TS72XX_NAND_CONTROL_VIRT_BASE;
+static void *ts7250_nandbusy = (void *)TS72XX_NAND_BUSY_VIRT_BASE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+/*
+ * Define static partitions for flash device
+ */
+static struct mtd_partition partition_info32[] = {
+	{
+		.name		= "TS-BOOTROM",
+		.offset		= 0x00000000,
+		.size		= 0x00004000,
+	}, {
+		.name		= "Linux",
+		.offset		= 0x00004000,
+		.size		= 0x01d00000,
+	}, {
+		.name		= "RedBoot",
+		.offset		= 0x01d04000,
+		.size		= 0x002fc000,
+	},
+};
+
+/*
+ * Define static partitions for flash device
+ */
+static struct mtd_partition partition_info128[] = {
+	{
+		.name		= "TS-BOOTROM",
+		.offset		= 0x00000000,
+		.size		= 0x00004000,
+	}, {
+		.name		= "Linux",
+		.offset		= 0x00004000,
+		.size		= 0x07d00000,
+	}, {
+		.name		= "RedBoot",
+		.offset		= 0x07d04000,
+		.size		= 0x002fc000,
+	},
+};
+
+#define NUM_PARTITIONS 3
+
+extern int parse_cmdline_partitions(struct mtd_info *master,
+		struct mtd_partition **pparts, const char *mtd_id);
+#endif
+
+
+/*
+ *	hardware specific access to control-lines
+ */
+static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+	switch(cmd) {
+	case NAND_CTL_SETCLE:
+		writeb(readb(ts7250_nandctrl) | 0x2, ts7250_nandctrl);
+		break;
+	case NAND_CTL_CLRCLE:
+		writeb(readb(ts7250_nandctrl) & ~0x2, ts7250_nandctrl);
+		break;
+	case NAND_CTL_SETALE:
+		writeb(readb(ts7250_nandctrl) | 0x1, ts7250_nandctrl);
+		break;
+	case NAND_CTL_CLRALE:
+		writeb(readb(ts7250_nandctrl) & ~0x1, ts7250_nandctrl);
+		break;
+	case NAND_CTL_SETNCE:
+		writeb(readb(ts7250_nandctrl) | 0x4, ts7250_nandctrl);
+		break;
+	case NAND_CTL_CLRNCE:
+		writeb(readb(ts7250_nandctrl) & ~0x4, ts7250_nandctrl);
+		break;
+	}
+}
+
+/*
+ *	read device ready pin
+ */
+static int ts7250_device_ready(struct mtd_info *mtd)
+{
+	return readb(ts7250_nandbusy) & 0x20;
+}
+
+/*
+ * Main initialization routine
+ */
+static int __init ts7250_init (void)
+{
+	struct nand_chip *this;
+	const char *part_type = 0;
+	int mtd_parts_nb = 0;
+	struct mtd_partition *mtd_parts = 0;
+
+	if (board_is_ts7200())
+		return -ENXIO;
+
+	/* Allocate memory for MTD device structure and private data */
+	ts7250_mtd = kmalloc(sizeof(struct mtd_info) +
+				sizeof(struct nand_chip), GFP_KERNEL);
+	if (!ts7250_mtd) {
+		printk("Unable to allocate TS7250 NAND MTD device structure.\n");
+		return -ENOMEM;
+	}
+
+	/* Get pointer to private data */
+	this = (struct nand_chip *) (&ts7250_mtd[1]);
+
+	/* Initialize structures */
+	memset(ts7250_mtd, 0, sizeof(struct mtd_info));
+	memset(this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	ts7250_mtd->priv = this;
+
+	/* insert callbacks */
+	this->IO_ADDR_R = (void *)TS72XX_NAND_DATA_VIRT_BASE;
+	this->IO_ADDR_W = (void *)TS72XX_NAND_DATA_VIRT_BASE;
+	this->hwcontrol = ts7250_hwcontrol;
+	this->dev_ready = ts7250_device_ready;
+	this->chip_delay = 15;
+	this->eccmode = NAND_ECC_SOFT;
+
+	printk("Searching for NAND flash...\n");
+	/* Scan to find existence of the device */
+	if (nand_scan (ts7250_mtd, 1)) {
+		kfree (ts7250_mtd);
+		return -ENXIO;
+	}
+
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	mtd_parts_nb = parse_cmdline_partitions(ts7250_mtd, &mtd_parts,
+						"ts7250-nand");
+	if (mtd_parts_nb > 0)
+		part_type = "command line";
+	else
+		mtd_parts_nb = 0;
+#endif
+	if (mtd_parts_nb == 0) {
+		mtd_parts = partition_info32;
+		if (ts7250_mtd->size >= (128 * 0x100000))
+			mtd_parts = partition_info128;
+		mtd_parts_nb = NUM_PARTITIONS;
+		part_type = "static";
+	}
+
+	/* Register the partitions */
+	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+	add_mtd_partitions(ts7250_mtd, mtd_parts, mtd_parts_nb);
+
+	/* Return happy */
+	return 0;
+}
+module_init(ts7250_init);
+
+/*
+ * Clean up routine
+ */
+static void __exit ts7250_cleanup (void)
+{
+	/* Unregister the device */
+	del_mtd_device (ts7250_mtd);
+
+	/* Free the MTD device structure */
+	kfree (ts7250_mtd);
+}
+module_exit(ts7250_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jesse Off <joff@embeddedARM.com>");
+MODULE_DESCRIPTION("MTD map driver for Technologic Systems TS-7250 board");
diff -urN linux-2.6.15.commit/drivers/net/arm/ep93xx_eth_need_rewrite.c linux-2.6.15.snap/drivers/net/arm/ep93xx_eth_need_rewrite.c
--- linux-2.6.15.commit/drivers/net/arm/ep93xx_eth_need_rewrite.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/drivers/net/arm/ep93xx_eth_need_rewrite.c	2006-02-22 15:54:07.000000000 +0100
@@ -0,0 +1,1417 @@
+/*
+ * ep93xx_eth.c
+ *  Ethernet Device Driver for Cirrus Logic EP93xx.
+ *
+ * Copyright (C) 2003 by Cirrus Logic www.cirrus.com
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License.
+ *
+ *   This driver was written based on skeleton.c by Donald Becker and
+ * smc9194.c by Erik Stahlman.
+ *
+ * Getting a MAC address:
+ *
+ * Former versions of this driver got their MAC from I2C EEPROM or even used
+ * hardcoded ones. Unfortunately I had to remove the board dependant I2C stuff,
+ * and use a random generated MAC instead of the hardcoded one. Good news is
+ * the there is support for setting the MAC from userspace now. (see below)
+ *
+ * first consider some potential problems if you use this random generated MAC:
+ *
+ *    you can no longer count on it to be really unique
+ *    identifying a particular board over network will be difficult
+ *    DHCP servers can no longer use the MAC for assigning static IPs
+ *    DHCP servers with long leasetimes quickly run out of leases
+ *    ...
+ *
+ * So how can you set a valid MAC from userspace then?
+ *
+ * Let's say you've just bought your OUI from IEEE and it's "aa:bb:cc"
+ * Now you'd like to assign the MAC for your EP93xx board with serial #5
+ * MAC = OUI<<24 + serial number = aa:bb:cc:00:00:05
+ *
+ *   ifconfig eth0 hw ether aa:bb:cc:00:00:05            # first set the MAC
+ *   ifconfig eth0 192.168.1.1 netmask 255.255.255.0 up  # then set the IP
+ *
+ * Apart from hardcoding this lines in your startup scripts you could also use
+ * some userspace utility to read (and set) the MAC from eeprom, flash, ...
+ *
+ * History:
+ * 07/19/01 0.1  Sungwook Kim  initial release
+ * 10/16/01 0.2  Sungwook Kim  add workaround for ignorance of Tx request
+ *                              while sending frame
+ *                             add some error stuations handling
+ *
+ * 03/25/03 Melody Lee Modified for EP93xx
+ *
+ * 2004/2005  Michael Burian	porting to linux-2.6
+ * 2005-10-12 Michael Burian	fix problems when setting MAC with ifconfig
+ * 2005-10-30 Michael Burian	cleanups, ethtool support
+ */
+
+/* TODO: 
+ * 1. try if it's possible to use skbuff directly for RX/TX (avoid memcpy)
+ * 2. use kzalloc instead of kmalloc+memset
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/dma-mapping.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+#include <linux/random.h>
+#include <linux/ethtool.h>
+
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/arch/hardware.h>
+
+#include "ep93xx_eth_need_rewrite.h"
+
+#define DRV_NAME	"ep93xx_eth"
+#define DRV_VERSION	"2.8"
+#define DRV_DATE	"2005-11-08"
+
+static const char *version = DRV_NAME ": version " DRV_VERSION " " DRV_DATE \
+							" Cirrus Logic\n";
+
+/* total number of device instance, 0 means the 1st instance. */
+static int num_of_instance;
+static struct net_device * ep93xx_etherdev;
+
+/*
+ * A List of default device port configuration for auto probing.
+ * At this time, the CPU has only one Ethernet device,
+ * but better to support multiple device configuration.
+ * Keep in mind that the array must end in zero.
+ */
+
+/* We get the MAC_BASE from include/asm-arm/arch-ep93xx/regmap.h */
+static struct {
+	unsigned int base_addr;	/* base address, (0:end mark) */
+	int irq;		/* IRQ number, (0:auto detect) */
+} port_list[] __initdata = {
+	{ EP93XX_ETHERNET_BASE, IRQ_EP93XX_ETHERNET },
+	{ 0 /* end mark */ , 0 },
+};
+
+/*
+ * Some definitions belong to the operation of this driver.
+ * You should understand how it affect to driver before any modification.
+ */
+
+/* Interrupt Sources in Use */
+#define  DEF_INT_SRC  (IntEn_TxSQIE|IntEn_RxEOFIE|IntEn_RxEOBIE|IntEn_RxHDRIE)
+
+/*
+ * Length of Device Queue in number of entries
+ * (must be less than or equal to 255)
+ */
+
+/* length of Rx Descriptor Queue (4 or bigger) Must be power of 2. */
+#define  LQRXD  64
+#define  LQRXS   LQRXD		/* length of Rx Status Queue */
+
+/* length of Tx Descriptor Queue (4 or bigger) Must be power of 2. */
+#define  LQTXD  8
+#define  LQTXS   LQTXD		/* length of Tx Status Queue */
+
+/* Tx Queue fill-up level control */
+#define  LVL_TXSTOP    LQTXD - 2	/* level to ask the stack to stop Tx */
+#define  LVL_TXRESUME  2	/* level to ask the stack to resume Tx */
+
+/* Rx Buffer length in byte */
+#define  LRXB  (1518+2+16)	/* length of Rx buf, must be 4-byte aligned */
+#define  LTXB   LRXB
+
+#define EP93XX_DEF_MSG (NETIF_MSG_DRV		| \
+			NETIF_MSG_PROBE		| \
+			NETIF_MSG_LINK		| \
+			NETIF_MSG_RX_ERR	| \
+			NETIF_MSG_TX_ERR	| \
+			NETIF_MSG_HW)
+
+#define DBG(lvl,msg,args...) do { printk(lvl"%s:%d: %s(): " msg, __FILE__, \
+		__LINE__,  __FUNCTION__, ## args); } while (0)
+
+/*
+ * Custom Data Structures
+ */
+
+/*
+ * the information about the buffer passed to device.
+ * there are matching bufdsc informations
+ * for each Tx/Rx Descriptor Queue entry to trace
+ * the buffer within those queues.
+ */
+struct bufdsc {
+	/* virtual address representing the buffer passed to device */
+	void *vaddr;
+	/* free routine */
+	int (*free_rout) (void *buf);
+};
+
+/* device private information */
+struct ep93xx_priv {
+	/*  static device information */
+	int id;			/* device instance ID */
+	/* pointers to various queues (virtual address) */
+	struct rx_dsc *rdq;	/* Rx Descriptor Queue */
+	struct rx_sts *rsq;	/* Rx Status Queue */
+	struct tx_dsc *tdq;	/* Tx Descriptor Queue */
+	struct tx_sts *tsq;	/* Tx Status Queue */
+	unsigned char *rxbuf;	/* base of Rx Buffer pool */
+	unsigned char *txbuf;	/* base of Tx Buffer pool */
+	struct bufdsc *rxbd;	/* Rx Buffers info */
+	struct bufdsc *txbd;	/* Tx Buffers info */
+	/* physical addresses of the same queues */
+	dma_addr_t p_qbase;	/* base */
+	dma_addr_t p_rdq;	/* Rx Descriptor Queue */
+	dma_addr_t p_rsq;	/* Rx Status Queue */
+	dma_addr_t p_tdq;	/* Tx Descriptor Queue */
+	dma_addr_t p_tsq;	/* Tx Status Queue */
+	dma_addr_t p_rxbuf;	/* Rx Buffer pool */
+	dma_addr_t p_txbuf;	/* Tx Buffer pool */
+	/* MII Bus ID of Ethernet PHY */
+	struct mii_if_info mii;
+	/* lock for mii when using ioctls */
+	spinlock_t mii_lock;
+	/*  dynamic information, subject to clear when device open */
+	struct net_device_stats stats;	/* statistic data */
+	/* next processing index of device queues */
+	int idx_rdq;
+	int idx_rsq;
+	int idx_tdqhead;
+	int idx_tdqtail;
+	int idx_tsq;
+	void __iomem *base_addr;	/* base address */
+	u32 msg_enable;
+	int regs_len;
+};
+
+/*
+ * Internal Routines
+ */
+
+static inline unsigned int next_index(unsigned int idx_cur, unsigned int len)
+{
+	return (idx_cur + 1) % len;	/* next array index */
+}
+
+static inline u32 _rdl(struct net_device *dev, u32 reg)
+{
+	return readl(((struct ep93xx_priv *)(netdev_priv(dev)))->base_addr + reg);
+}
+
+static inline void _wrl(struct net_device *dev, u32 val, u32 reg)
+{
+	writel(val, ((struct ep93xx_priv *)(netdev_priv(dev)))->base_addr + reg);
+}
+
+static inline void _wrw(struct net_device *dev, u16 val, u32 reg)
+{
+	writew(val, ((struct ep93xx_priv *)(netdev_priv(dev)))->base_addr + reg);
+}
+
+static inline void _wrb(struct net_device *dev, u8 val, u32 reg)
+{
+	writeb(val, ((struct ep93xx_priv *)(netdev_priv(dev)))->base_addr + reg);
+}
+
+/**
+ * wait_on_reg()
+ */
+static int wait_on_reg(struct net_device *dev, int reg, unsigned long mask, unsigned long expect)
+{
+	int i, dt;
+
+	for (i = 0; i < 10000; i++) {
+		dt = _rdl(dev, reg);
+		dt = (dt ^ expect) & mask;
+		if (0 == dt)
+			break;
+	}
+	return dt;
+}
+
+/**
+ * mdio_write()
+ */
+static void mdio_write(struct net_device *dev, int idPhy, int reg, int dt)
+{
+	wait_on_reg(dev, REG_MIISts, MIISts_Busy, ~MIISts_Busy);
+	_wrl(dev, dt, REG_MIIData);
+	_wrl(dev, MIICmd_OP_WR | ((idPhy & 0x1f) << 5) | ((reg & 0x1f) << 0), REG_MIICmd);
+}
+
+/**
+ * mdio_read()
+ */
+static int mdio_read(struct net_device *dev, int idPhy, int reg)
+{
+	int dt;
+
+	wait_on_reg(dev, REG_MIISts, MIISts_Busy, ~MIISts_Busy);
+	_wrl(dev, MIICmd_OP_RD | ((idPhy & 0x1f) << 5) | ((reg & 0x1f) << 0), REG_MIICmd);
+
+	wait_on_reg(dev, REG_MIISts, MIISts_Busy, ~MIISts_Busy);
+	dt = _rdl(dev, REG_MIIData);
+
+	return dt & 0xffff;
+}
+
+/**
+ * phy_init()
+ */
+static void phy_init(struct net_device *dev)
+{
+
+	u32 oldval;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	oldval = _rdl(dev, REG_SelfCTL);
+
+#if 0
+	/* Set MDC clock to be divided by 8 and disable PreambleSuppress bit */
+	_wrl(dev, 0x0e00, REG_SelfCTL);
+#else
+	/* Set MDC clock to be divided by 32 and disable PreambleSuppress bit */
+	_wrl(dev, 0x6200, REG_SelfCTL);
+#endif
+
+	if (mii_link_ok(&(priv->mii)))
+		mii_check_media(&(priv->mii), netif_msg_link(priv), 1);
+
+	/* restore the old value */
+	_wrl(dev, oldval, REG_SelfCTL);
+}
+
+/**
+ * devQue_start()
+ *
+ * make descriptor queues active
+ * allocate queue entries if needed
+ * and set device registers up to make it operational
+ * assume device has been initialized
+ */
+static int devQue_start(struct net_device *dev)
+{
+	int err;
+	int i;
+	void *buf;
+	u32 phy_addr;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	/* turn off device bus mastering */
+	_wrl(dev, BMCtl_RxDis | BMCtl_TxDis | _rdl(dev, REG_BMCtl), REG_BMCtl);
+	err = wait_on_reg(dev, REG_BMSts, BMSts_TxAct, ~BMSts_TxAct);
+	err |= wait_on_reg(dev, REG_BMSts, BMSts_RxAct, ~BMSts_RxAct);
+	if (err && netif_msg_hw(priv))
+		DBG(KERN_ERR, "%s: BM does not stop\n", dev->name);
+
+	/* Tx Status Queue */
+	memset(priv->tsq, 0, sizeof(priv->tsq[0]) * LQTXS);
+	priv->idx_tsq = 0;
+	_wrl(dev, priv->p_tsq, REG_TxSBA);
+	_wrl(dev, priv->p_tsq, REG_TxSCA);
+	_wrw(dev, sizeof(priv->tsq[0]) * LQTXS, REG_TxSBL);
+	_wrw(dev, sizeof(priv->tsq[0]) * LQTXS, REG_TxSCL);
+
+	/* Tx Descriptor Queue */
+	memset(priv->tdq, 0, sizeof(priv->tdq[0]) * LQTXD);
+	priv->idx_tdqhead = priv->idx_tdqtail = 0;
+	_wrl(dev, priv->p_tdq, REG_TxDBA);
+	_wrl(dev, priv->p_tdq, REG_TxDCA);
+	_wrw(dev, sizeof(priv->tdq[0]) * LQTXD, REG_TxDBL);
+	_wrw(dev, sizeof(priv->tdq[0]) * LQTXD, REG_TxDCL);
+
+	/* Rx Status Queue */
+	memset(priv->rsq, 0, sizeof(priv->rsq[0]) * LQRXS);
+	priv->idx_rsq = 0;
+	_wrl(dev, priv->p_rsq, REG_RxSBA);
+	_wrl(dev, priv->p_rsq, REG_RxSCA);
+	_wrw(dev, sizeof(priv->rsq[0]) * LQRXS, REG_RxSBL);
+	_wrw(dev, sizeof(priv->rsq[0]) * LQRXS, REG_RxSCL);
+
+	/* Rx Descriptor Queue */
+	memset(priv->rdq, 0, sizeof(priv->rdq[0]) * LQRXD);
+	phy_addr = priv->p_rxbuf;
+	for (i = 0; i < LQRXD; i++) {
+		priv->rdq[i].bi = i;	/* index */
+		priv->rdq[i].ba = phy_addr;	/* physical address */
+		priv->rdq[i].bl = LRXB;	/* length */
+		phy_addr += LRXB;
+	}
+	priv->idx_rdq = 0;
+	_wrl(dev, priv->p_rdq, REG_RxDBA);
+	_wrl(dev, priv->p_rdq, REG_RxDCA);
+	_wrw(dev, sizeof(priv->rdq[0]) * LQRXD, REG_RxDBL);
+	_wrw(dev, sizeof(priv->rdq[0]) * LQRXD, REG_RxDCL);
+
+	/* init Rx Buffer Descriptors */
+	buf = priv->rxbuf;
+	for (i = 0; i < LQRXD; i++) {
+		priv->rxbd[i].vaddr = buf;
+		priv->rxbd[i].free_rout = NULL;
+		buf += LRXB;
+	}
+
+	/* init Tx Buffer Descriptors */
+	memset(priv->txbd, 0x0, sizeof(*priv->txbd) * LQTXD);
+
+	buf = priv->txbuf;
+	for (i = 0; i < LQTXD; i++) {
+		priv->txbd[i].vaddr = buf;
+		priv->txbd[i].free_rout = NULL;
+		buf += LTXB;
+	}
+
+	/* turn on device bus mastering */
+	_wrl(dev, BMCtl_TxEn | BMCtl_RxEn | _rdl(dev, REG_BMCtl), REG_BMCtl);
+	err = wait_on_reg(dev, REG_BMSts, BMSts_TxAct | BMSts_TxAct, BMSts_TxAct | BMSts_TxAct);
+	if (err && netif_msg_hw(priv))
+		DBG(KERN_ERR, "%s: BM does not start\n", dev->name);
+
+	/* Enqueue whole entries; this must be done after BM activation */
+	_wrl(dev, LQRXS, REG_RxSEQ);	/* Rx Status Queue */
+	_wrl(dev, LQRXD, REG_RxDEQ);	/* Rx Desc. queue */
+
+	return 0;
+}
+
+/**
+ * devQue_init()
+ * init device descriptor queues at system level
+ *  device access is not recommended at this point
+ *
+ */
+static int devQue_init(struct net_device *dev)
+{
+	void *buf;
+	void *tmp;
+	int size, size2;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	/* verify device Tx/Rx Descriptor/Status Queue data size */
+	if (8 != sizeof(struct rx_dsc)) {
+		if (netif_msg_probe(priv))
+			DBG(KERN_ERR, "sizeof rx_dsc != 8 bytes!\n");
+		return -ENOMEM;
+	} else if (8 != sizeof(struct rx_sts)) {
+		if (netif_msg_probe(priv))
+			DBG(KERN_ERR, "sizeof rx_sts != 8 bytes!\n");
+		return -ENOMEM;
+	} else if (8 != sizeof(struct tx_dsc)) {
+		if (netif_msg_probe(priv))
+			DBG(KERN_ERR, "sizeof tx_dsc != 8 bytes!\n");
+		return -ENOMEM;
+	} else if (4 != sizeof(struct tx_sts)) {
+		if (netif_msg_probe(priv))
+			DBG(KERN_ERR, "sizeof tx_sts != 4 bytes!\n");
+		return -ENOMEM;
+	}
+
+	/*
+	   allocate kernel memory for whole queues
+	   best if non-cached memory block due to DMA access by the device
+	   if CPU doesn't have bus snooping
+	 */
+	size = sizeof(struct rx_dsc) * (LQRXD + 1) +
+	    sizeof(struct rx_sts) * (LQRXS + 1) +
+	    sizeof(struct tx_dsc) * (LQTXD + 1) +
+	    sizeof(struct tx_sts) * (LQTXS + 1) + sizeof(unsigned long) * 4;
+
+	buf = tmp = dma_alloc_coherent(NULL, size, &priv->p_qbase, GFP_KERNEL | GFP_DMA);
+	if (!buf) {
+		if (netif_msg_probe(priv))
+			DBG(KERN_ERR, "no memory for queue\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * assign memory to each queue
+	 */
+	priv->rdq = buf;
+	buf = buf + sizeof(struct rx_dsc) * (LQRXD + 1);
+	priv->rsq = buf;
+	buf = buf + sizeof(struct rx_sts) * (LQRXS + 1);
+	priv->tdq = buf;
+	buf = buf + sizeof(struct tx_dsc) * (LQTXD + 1);
+	priv->tsq = buf;
+	buf = buf + sizeof(struct tx_sts) * (LQTXS + 1);
+
+	/*
+	 * store physical address of each queue
+	 */
+	priv->p_rdq = priv->p_qbase;
+	priv->p_rsq = priv->p_rdq + ((u32) priv->rsq - (u32) priv->rdq);
+	priv->p_tdq = priv->p_rdq + ((u32) priv->tdq - (u32) priv->rdq);
+	priv->p_tsq = priv->p_rdq + ((u32) priv->tsq - (u32) priv->rdq);
+
+	/*
+	 *  init queue entries
+	 */
+	memset(priv->rdq, 0, sizeof(struct rx_dsc) * LQRXD);
+	memset(priv->rsq, 0, sizeof(struct rx_sts) * LQRXS);
+	memset(priv->tdq, 0, sizeof(struct tx_dsc) * LQTXD);
+	memset(priv->tsq, 0, sizeof(struct tx_sts) * LQTXS);
+
+	/* Allocate Rx Buffer
+	   (We might need to copy from Rx buf to skbuff in whatever case,
+	   because device bus master requires 32bit aligned Rx buffer address
+	   but Linux network stack requires odd 16bit aligned Rx buf address) */
+	priv->rxbuf = dma_alloc_coherent(NULL, LRXB * LQRXD, &priv->p_rxbuf, GFP_KERNEL | GFP_DMA);
+
+	if (!priv->rxbuf) {
+		priv->rxbuf = NULL;
+		if (netif_msg_probe(priv))
+			DBG(KERN_ERR, "no memory for RxBuf\n");
+		goto err_free_qbase_1;
+	}
+
+	/* Allocate Tx Buffer */
+	priv->txbuf = dma_alloc_coherent(NULL, LTXB * LQTXD, &priv->p_txbuf, GFP_KERNEL | GFP_DMA);
+
+	if (!priv->txbuf) {
+		priv->txbuf = NULL;
+		if (netif_msg_probe(priv))
+			DBG(KERN_ERR, "no memory for TxBuf\n");
+		goto err_free_rxbuf_2;
+	}
+
+	/*
+	 * allocate kernel memory for buffer descriptors
+	 */
+	size2 = sizeof(struct bufdsc) * (LQRXD + LQTXD);
+	buf = kmalloc(size2, GFP_KERNEL);
+	if (!buf) {
+		if (netif_msg_probe(priv))
+			DBG(KERN_ERR, "no memory for buf desc\n");
+		goto err_free_txbuf_3;
+	}
+	memset(buf, 0x0, size2);	/* clear with 0 */
+	priv->rxbd = buf;
+	priv->txbd = buf + sizeof(struct bufdsc) * LQRXD;
+
+	return 0;
+
+err_free_txbuf_3:
+	dma_free_coherent(NULL, LTXB * LQTXD, priv->txbuf, priv->p_txbuf);
+err_free_rxbuf_2:
+	dma_free_coherent(NULL, LRXB * LQRXD, priv->rxbuf, priv->p_rxbuf);
+err_free_qbase_1:
+	dma_free_coherent(NULL, size, tmp, priv->p_qbase);
+	return -ENOMEM;
+}
+
+/**
+ * devQue_cleanup()
+ * Release queue, Tx buffers and Rx buffers memory
+ * Only call after unregister_netdev
+ */
+static void devQue_cleanup(struct net_device *dev)
+{
+	int size;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	/* descriptor queues size */
+	size = sizeof(struct rx_dsc) * (LQRXD + 1) +
+	    sizeof(struct rx_sts) * (LQRXS + 1) +
+	    sizeof(struct tx_dsc) * (LQTXD + 1) +
+	    sizeof(struct tx_sts) * (LQTXS + 1) + sizeof(unsigned long) * 4;
+
+	dma_free_coherent(NULL, size, priv->rdq, priv->p_qbase);
+	dma_free_coherent(NULL, LTXB * LQTXD, priv->txbuf, priv->p_txbuf);
+	dma_free_coherent(NULL, LRXB * LQRXD, priv->rxbuf, priv->p_rxbuf);
+	kfree(priv->rxbd);
+
+}
+
+/**
+ * set_multicast_tbl()
+ */
+static void set_multicast_tbl(struct net_device *dev, u8 *buf)
+{
+	int i;
+	unsigned char position;
+	struct dev_mc_list *cur_addr;
+
+	memset(buf, 0x00, 8);
+
+	cur_addr = dev->mc_list;
+	for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) {
+
+		if (!cur_addr)
+			break;
+		if (!(*cur_addr->dmi_addr & 1))
+			continue;	/* make sure multicast addr */
+		position = ether_crc_le(6, cur_addr->dmi_addr) >> 26;
+		buf[position >> 3] |= 1 << (position & 0x07);
+	}
+}
+
+/**
+ * ind_addr_wr()
+ */
+static int ind_addr_wr(struct net_device *dev, int afp, char *buf)
+{
+	u32 rxctl;
+	int i, len;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	afp &= 0x07;
+	if (4 == afp || 5 == afp) {
+		if (netif_msg_hw(priv))
+			DBG(KERN_ERR, "invalid afp value\n");
+		return -1;
+	}
+	len = (AFP_AFP_HASH == afp) ? 8 : 6;
+
+	rxctl = _rdl(dev, REG_RxCTL);	/* turn Rx off */
+	_wrl(dev, ~RxCTL_SRxON & rxctl, REG_RxCTL);
+	_wrl(dev, afp, REG_AFP);	/* load new address pattern */
+	for (i = 0; i < len; i++)
+		_wrb(dev, buf[i], REG_IndAD + i);
+	_wrl(dev, rxctl, REG_RxCTL);	/* turn Rx back */
+
+	return 0;
+}
+
+/**
+ * rx_ctl()
+ */
+static int rx_ctl(struct net_device *dev, int sw)
+{
+	unsigned long tmp = _rdl(dev, REG_RxCTL);
+
+	/*
+	 * Workaround for MAC lost 60-byte-long frames:
+	 * must enable Runt_CRC_Accept bit
+	 */
+	if (sw)
+		_wrl(dev, tmp | RxCTL_SRxON | RxCTL_RCRCA, REG_RxCTL);
+	else
+		_wrl(dev, tmp & ~RxCTL_SRxON, REG_RxCTL);
+
+	return 0;
+}
+
+/**
+ * chk_tx_lvl()
+ */
+static void chk_tx_lvl(struct net_device *dev)
+{
+	int filled;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	/* check Tx Descriptor Queue fill-up level */
+	filled = priv->idx_tdqhead - priv->idx_tdqtail;
+	if (filled < 0)
+		filled += LQTXD;
+
+	if (filled <= (LVL_TXRESUME + 1))
+		netif_wake_queue(dev);
+}
+
+/**
+ * cleanup_tx()
+ */
+static void cleanup_tx(struct net_device *dev)
+{
+	struct tx_sts *txsts;
+	int idxsts, bi;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	/*
+	 * process Tx Status Queue (no need to limit processing of TxStatus
+	 * Queue because each queue entry consist of 1 dword)
+	 */
+	while (priv->tsq[priv->idx_tsq].flags & TXSTS_TXFP) {
+		idxsts = priv->idx_tsq;
+		priv->idx_tsq = next_index(priv->idx_tsq, LQTXS);
+		txsts = &priv->tsq[idxsts];
+		if (!(txsts->flags & TXSTS_TXFP)) {	/* empty? */
+			if (netif_msg_tx_err(priv))
+				DBG(KERN_ERR, "QueTxSts is empty\n");
+			return;
+		}
+		txsts->flags &= ~TXSTS_TXFP;	/* mark processed */
+
+		bi = txsts->bi & TXSTS_BI;	/* buffer index */
+
+		/* statistics collection */
+		if (txsts->flags & TXSTS_TXWE) {	/* Sent without error */
+			priv->stats.tx_packets++;
+			priv->stats.tx_bytes += ((struct tx_dsc *)(priv->txbd[bi].vaddr))->bl_af & TXDSC_BL;
+		} else {	/* Tx failed due to error */
+			if (netif_msg_tx_err(priv))
+				DBG(KERN_ERR, "Tx failed QueTxSts");
+			priv->stats.tx_errors++;
+			if (txsts->flags & TXSTS_LCRS)
+				priv->stats.tx_carrier_errors++;
+			if (txsts->flags & TXSTS_TXU)
+				priv->stats.tx_fifo_errors++;
+			if (txsts->flags & TXSTS_ECOLL)
+				priv->stats.collisions++;
+		}
+
+		/* free Tx buffer */
+		if (priv->txbd[bi].free_rout) {
+			(*priv->txbd[bi].free_rout)(priv->txbd[bi].vaddr);
+			priv->txbd[bi].free_rout = NULL;
+		}
+
+		/* ahead Tx Descriptor Queue tail index */
+		priv->idx_tdqtail = next_index(priv->idx_tdqtail, LQTXD);
+	}
+}
+
+/**
+ * restart_tx()
+ */
+static int restart_tx(struct net_device *dev)
+{
+	int i;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	/* disable int */
+
+	/* turn off master INT control */
+	_wrl(dev, _rdl(dev, REG_GIntMsk) & ~GIntMsk_IntEn, REG_GIntMsk);
+
+	/* stop Tx and disable Tx DMA */
+	_wrl(dev, _rdl(dev, REG_TxCTL) & ~TxCTL_STxON, REG_TxCTL);
+	_wrl(dev, _rdl(dev, REG_BMCtl) | BMCtl_TxDis, REG_BMCtl);
+
+	/* reset Tx DMA */
+	_wrl(dev, BMCtl_TxChR | _rdl(dev, REG_BMCtl), REG_BMCtl);
+
+	/* release Tx buffers */
+	for (i = 0; i < LQTXD; i++) {
+		if (priv->txbd[i].free_rout) {
+			priv->txbd[i].free_rout(priv->txbd[i].vaddr);
+			priv->txbd[i].free_rout = NULL;
+		}
+		priv->stats.tx_dropped++;
+	}
+
+	/* init Tx Queues and flush cache */
+	memset(priv->tsq, 0, sizeof(priv->tsq[0]) * LQTXS);
+
+	/* init variables */
+	priv->idx_tsq = priv->idx_tdqhead = priv->idx_tdqtail = 0;
+
+	/* init registers */
+	wait_on_reg(dev, REG_BMSts, BMCtl_TxChR, ~BMCtl_TxChR);
+	_wrl(dev, priv->p_tsq, REG_TxSBA);
+	_wrl(dev, priv->p_tsq, REG_TxSCA);
+	_wrw(dev, sizeof(priv->tsq[0]) * LQTXS, REG_TxSBL);
+	_wrw(dev, sizeof(priv->tsq[0]) * LQTXS, REG_TxSCL);
+	_wrl(dev, priv->p_tdq, REG_TxDBA);
+	_wrl(dev, priv->p_tdq, REG_TxDCA);
+	_wrw(dev, sizeof(priv->tdq[0]) * LQTXD, REG_TxDBL);
+	_wrw(dev, sizeof(priv->tdq[0]) * LQTXD, REG_TxDCL);
+
+	/* start Tx and enable Tx DMA */
+	_wrl(dev, _rdl(dev, REG_TxCTL) | TxCTL_STxON, REG_TxCTL);
+	_wrl(dev, _rdl(dev, REG_BMCtl) | BMCtl_TxEn, REG_BMCtl);
+
+	/* enable int again */
+	_wrl(dev, _rdl(dev, REG_GIntMsk) | GIntMsk_IntEn, REG_GIntMsk);
+
+	return 0;
+}
+
+/**
+ * reset()
+ */
+static void reset(struct net_device *dev)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	/* soft reset command */
+	_wrb(dev, SelfCTL_RESET, REG_SelfCTL);
+	if (wait_on_reg(dev, REG_SelfCTL, SelfCTL_RESET, ~SelfCTL_RESET))
+		if (netif_msg_drv(priv))
+			DBG(KERN_WARNING, "Soft Reset does not self-clear\n");
+}
+
+/**
+ * eth_shutdown()- closes down the Ethernet module
+ *
+ * Make sure to:
+ *	1. disable all interrupt mask
+ *	2. disable Rx
+ *	3. disable Tx
+ *
+ *	TODO:
+ *   (1) maybe utilize power down mode.
+ *	Why not yet?  Because while the chip will go into power down mode,
+ *	the manual says that it will wake up in response to any I/O requests
+ *	in the register space.   Empirical results do not show this working.
+ */
+static int eth_shutdown(struct net_device *dev)
+{
+	reset(dev);
+	return 0;
+}
+
+/**
+ * eth_init() - Reset and initialize the device.
+ *
+ * Device should be initialized enough to function in polling mode.
+ * Tx and Rx must be disabled and no INT generation.
+ */
+static int eth_init(struct net_device *dev)
+{
+	/* reset device */
+	reset(dev);
+
+	/* init PHY */
+	phy_init(dev);
+
+	/* init MAC */
+
+	/*i Set MDC clock to be divided by 8 and enable PreambleSuppress bit */
+	_wrl(dev, 0x0f00, REG_SelfCTL);
+	/* mask Interrupt */
+	_wrl(dev, 0x00, REG_GIntMsk);
+	/* no Rx on at this point */
+	_wrl(dev, RxCTL_BA | RxCTL_IA0, REG_RxCTL);
+	_wrl(dev, 0x00, REG_TxCTL);
+	_wrl(dev, 0x00, REG_GT);
+	_wrl(dev, 0x00, REG_BMCtl);
+	/* Buffer Threshold */
+	_wrl(dev, (0x80 << 16) | (0x40 << 0), REG_RxBTH);
+	_wrl(dev, (0x80 << 16) | (0x40 << 0), REG_TxBTH);
+	/* Status Threshold */
+	_wrl(dev, (4 << 16) | (2 << 0), REG_RxSTH);
+	_wrl(dev, (4 << 16) | (2 << 0), REG_TxSTH);
+	/* Descriptor Threshold */
+	_wrl(dev, (4 << 16) | (2 << 0), REG_RxDTH);
+	_wrl(dev, (4 << 16) | (2 << 0), REG_TxDTH);
+	/* Max Frame Length & Tx Start Threshold */
+	_wrl(dev, ((1518 + 1) << 16) | (944 << 0), REG_MaxFL);
+
+	_rdl(dev, REG_TxCollCnt);	/* clear Tx Collision Count */
+	_rdl(dev, REG_RxMissCnt);	/* clear Rx Miss Counter */
+	_rdl(dev, REG_RxRntCnt);	/* clear Rx Runt Counter */
+
+	/* clear Pending INT */
+	_rdl(dev, REG_IntStsC);
+	/* Tx on */
+	_wrl(dev, TxCTL_STxON | _rdl(dev, REG_TxCTL), REG_TxCTL);
+
+	/* Set MAC address */
+	ind_addr_wr(dev, AFP_AFP_IA0, &dev->dev_addr[0]);
+
+	/* init queue */
+	devQue_start(dev);
+
+	return 0;
+}
+
+/**
+ * rx_isr() - Receive Interrupt Service Routine
+ */
+static void rx_isr(struct net_device *dev)
+{
+	struct rx_sts *rxsts;
+	/* index of Rx Status Queue Head from device (next put point) */
+	int idx_rsqhead;
+	int idxsts;
+	int cnt_sts_processed, cnt_desc_processed;
+	char *dest;
+	struct sk_buff *skb;
+	int len;
+	unsigned int dt;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	/* get Current Rx Status Queue pointer */
+	dt = _rdl(dev, REG_RxSCA);
+
+	/* convert to array index */
+	idx_rsqhead = (dt - priv->p_rsq) / sizeof(priv->rsq[0]);
+	if (!(0 <= idx_rsqhead && idx_rsqhead < LQRXS)) {
+		if (netif_msg_rx_err(priv))
+			DBG(KERN_ERR, " invalid REG_RxSCA\n");
+		return;
+	}
+
+	/* process Rx (limit to idx_rsqhead due to cache) */
+	cnt_sts_processed = cnt_desc_processed = 0;
+	while (idx_rsqhead != priv->idx_rsq) {
+		idxsts = priv->idx_rsq;
+		priv->idx_rsq = next_index(priv->idx_rsq, LQRXS);
+		rxsts = &priv->rsq[idxsts];
+		if (!(rxsts->w1 & RXSTS_RFP)) {	/* empty? */
+			if (netif_msg_rx_err(priv))
+				DBG(KERN_ERR, "QueRxSts empty\n");
+			return;
+		}
+		rxsts->w1 &= ~RXSTS_RFP;	/* mark processed */
+
+		cnt_sts_processed++;
+
+		if (!(rxsts->w1 & RXSTS_EOB))	/* buffer has no data */
+			continue;
+
+		if ((rxsts->bi & RXSTS_BI) != priv->idx_rdq) {
+			if (netif_msg_rx_err(priv))
+				DBG(KERN_ERR, "unmatching idx_rdq\n");
+			continue;
+		}
+		priv->idx_rdq = next_index(priv->idx_rdq, LQRXD);
+		cnt_desc_processed++;
+
+		/* received a frame with error */
+		if (!((rxsts->w1 & RXSTS_EOF) && (rxsts->w1 & RXSTS_RWE))) {
+			if (netif_msg_rx_err(priv))
+				DBG(KERN_WARNING, "Rx error RxSts\n");
+			priv->stats.rx_errors++;
+			if (rxsts->w1 & RXSTS_OE)
+				priv->stats.rx_fifo_errors++;
+			if (rxsts->w1 & RXSTS_FE)
+				priv->stats.rx_frame_errors++;
+			if ((rxsts->w1 & RXSTS_RUNT) || (rxsts->w1 & RXSTS_EDATA))
+				priv->stats.rx_length_errors++;
+			if (rxsts->w1 & RXSTS_CRCE)
+				priv->stats.rx_crc_errors++;
+			continue;
+		}
+
+		len = rxsts->fl;
+
+		/* alloc buffer for protocal stack */
+		skb = dev_alloc_skb(len + 5);
+		if (NULL == skb) {
+			if (netif_msg_rx_err(priv))
+				DBG(KERN_ERR, "Low Memory, Rx dropped\n");
+			priv->stats.rx_dropped++;
+			continue;
+		}
+
+		/* odd 16 bit alignment to make protocal stack happy */
+		skb_reserve(skb, 2);
+		skb->dev = dev;
+		dest = skb_put(skb, len);
+		memcpy(dest, priv->rxbd[(rxsts->bi & RXSTS_BI)].vaddr, len);
+		skb->protocol = eth_type_trans(skb, dev);
+		/* pass Rx packet to system */
+		netif_rx(skb);
+		dev->last_rx = jiffies;
+		priv->stats.rx_packets++;
+		priv->stats.rx_bytes += len;
+		if (RXSTS_AM == (rxsts->w1 & RXSTS_AM))
+			priv->stats.multicast++;
+	}
+
+	/* enqueue */
+	_wrl(dev, cnt_sts_processed, REG_RxSEQ);
+	_wrl(dev, cnt_desc_processed, REG_RxDEQ);
+}
+
+/**
+ * tx_isr() - Transmit Interrupt Service Routine
+ */
+static int tx_isr(struct net_device *dev)
+{
+	cleanup_tx(dev);
+	chk_tx_lvl(dev);	/* resume Tx if it was stopped */
+	return 0;
+}
+
+/**
+ * ep93xx_isr()
+ */
+static irqreturn_t ep93xx_isr(int irq, void *dev_id, struct pt_regs *pRegs)
+{
+	struct net_device *dev = dev_id;
+	int lpCnt;
+	u32 intS;
+
+	lpCnt = 0;
+	do {
+		/* get INT status and then clear */
+		intS = _rdl(dev, REG_IntStsC);
+
+		if (!intS)
+			break;	/* no INT */
+		if (IntSts_RxSQ & intS)
+			rx_isr(dev);	/* Rx INT */
+		if (IntSts_TxSQ & intS)
+			tx_isr(dev);	/* Tx INT */
+	} while (lpCnt++ < 64);	/* limit loop to serve other interrupts too */
+	return IRQ_HANDLED;
+}
+
+/* Exposed Driver Routines to the Outside World */
+
+/**
+ * ep93xx_get_stats()
+ */
+static struct net_device_stats *ep93xx_get_stats(struct net_device *dev)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	return &priv->stats;
+}
+
+/**
+ * ep93xx_set_multicast_list()
+ */
+static void ep93xx_set_multicast_list(struct net_device *dev)
+{
+	u8 tbl[8 + 1];
+
+	if (IFF_PROMISC & dev->flags) {
+		_wrl(dev, RxCTL_PA | _rdl(dev, REG_RxCTL), REG_RxCTL);
+
+	} else if (IFF_ALLMULTI & dev->flags) {	/* receive all multicast addr */
+		_wrl(dev, RxCTL_MA | (~RxCTL_PA & _rdl(dev, REG_RxCTL)), REG_RxCTL);
+		memset(tbl, 0xff, 8);
+		ind_addr_wr(dev, AFP_AFP_HASH, &tbl[0]);
+
+	} else if (dev->mc_count) {	/* set H/W multicasting filter */
+		_wrl(dev, RxCTL_MA | (~RxCTL_PA & _rdl(dev, REG_RxCTL)), REG_RxCTL);
+		set_multicast_tbl(dev, &tbl[0]);
+		ind_addr_wr(dev, AFP_AFP_HASH, &tbl[0]);
+
+	} else {		/* no multicasting */
+		_wrl(dev, ~(RxCTL_PA | RxCTL_MA) & _rdl(dev, REG_RxCTL), REG_RxCTL);
+	}
+}
+
+/**
+ * ep93xx_tx_timeout()
+ */
+static void ep93xx_tx_timeout(struct net_device *dev)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	/* If we get here, some higher level has decided we are broken.
+	   There should really be a "kick me" function call instead. */
+	if (netif_msg_tx_err(priv))
+		DBG(KERN_WARNING, "transmit timed out\n");
+
+	phy_init(dev);
+
+	/* kick Tx engine */
+	restart_tx(dev);
+
+	/* ask the Network Stack to resume Tx if there is room available */
+	chk_tx_lvl(dev);
+}
+
+/**
+ * ep93xx_start_xmit()
+ */
+static int ep93xx_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+/* @swk check H/W defect of Tx Underrun Error caused by certain frame length */
+	struct tx_dsc *txdsc;
+	int idx_tdqhd;
+	int filled;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	idx_tdqhd = priv->idx_tdqhead;
+	txdsc = &priv->tdq[idx_tdqhd];
+
+	/* check Tx Descriptor Queue fill-up level */
+	filled = idx_tdqhd - priv->idx_tdqtail;
+	if (filled < 0)
+		filled += LQTXD;
+	filled += 1;
+
+	/* check Queue level */
+	if (LVL_TXSTOP <= filled) {
+		netif_stop_queue(dev);	/* no more Tx allowed */
+		if (netif_msg_tx_err(priv))
+			DBG(KERN_INFO, "%s: Tx STOP requested\n", dev->name);
+		if (LVL_TXSTOP < filled) {
+			/* this situation can not be happen */
+			if (netif_msg_tx_err(priv))
+				DBG(KERN_ERR, "%s: Tx Request while stopped\n", dev->name);
+			return NETDEV_TX_BUSY;
+		}
+	}
+
+	/* fill up Tx Descriptor Queue entry */
+	if (skb->len < ETH_ZLEN) {
+		txdsc->bl_af = ETH_ZLEN & TXDSC_BL;	/* also clears AF! */
+		skb = skb_padto(skb, ETH_ZLEN);
+		if (skb == NULL)
+			return NETDEV_TX_OK;
+	} else {
+		txdsc->bl_af = skb->len & TXDSC_BL;	/* also clears AF! */
+	}
+	txdsc->ba = priv->p_txbuf + (idx_tdqhd * LTXB);
+	txdsc->bi_eof = (idx_tdqhd & TXDSC_BI) | TXDSC_EOF;
+
+	dev->trans_start = jiffies;
+
+	/* copy data to Tx buffer */
+	memcpy(priv->txbd[idx_tdqhd].vaddr, skb->data, skb->len);
+	priv->txbd[idx_tdqhd].free_rout = NULL;
+
+	/* Free the data buffer passed by upper layer */
+	dev_kfree_skb_any(skb);
+
+	/* ahead Tx Desc Queue */
+	priv->idx_tdqhead = next_index(priv->idx_tdqhead, LQTXD);
+	wmb();
+
+	/* Enqueue a Tx Descriptor to the device */
+	_wrl(dev, 1, REG_TxDEQ);
+
+	if (netif_msg_tx_queued(priv))
+		DBG(KERN_DEBUG, "%s: Tx packet queued\n", dev->name);
+
+	return NETDEV_TX_OK;
+}
+
+/**
+ * ep93xx_close()
+ *
+ * this makes the board clean up everything that it can
+ * and not talk to the outside world.   Caused by
+ *. an 'ifconfig ethX down'
+ */
+static int ep93xx_close(struct net_device *dev)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	free_irq(dev->irq, dev);
+
+	netif_stop_queue(dev);
+	eth_shutdown(dev);
+
+	if (netif_msg_ifdown(priv))
+		DBG(KERN_INFO, "%s: ep93xx_close()\n", dev->name);
+
+	return 0;
+}
+
+/**
+ * ep93xx_open() - Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc ..
+ */
+static int ep93xx_open(struct net_device *dev)
+{
+	int status;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	/* clear dynamic device info */
+	memset(&priv->stats, 0, sizeof(priv->stats));
+	priv->idx_rdq = 0;
+	priv->idx_rsq = 0;
+	priv->idx_tdqhead = 0;
+	priv->idx_tdqtail = 0;
+	priv->idx_tsq = 0;
+
+	/* reset/init device */
+	status = eth_init(dev);
+	if (status != 0) {
+		return -EAGAIN;
+	}
+
+	/* turn on INT, turn on Rx */
+	status = request_irq(dev->irq, &ep93xx_isr, 0, DRV_NAME, dev);
+	if (status) {
+		if (netif_msg_ifup(priv))
+			DBG(KERN_ERR, "%s: unable to get IRQ\n", dev->name);
+		return status;
+	}
+
+	/* Enable interrupt driven operation. Also turn on Rx but no Tx. */
+	/* setup Interrupt sources */
+	_wrl(dev, DEF_INT_SRC, REG_IntEn);
+	/* turn on INT */
+	_wrl(dev, GIntMsk_IntEn, REG_GIntMsk);
+	/* turn on Rx */
+	rx_ctl(dev, 1);
+
+	/* link to upper layer */
+	netif_start_queue(dev);
+
+	if (netif_msg_ifup(priv))
+		DBG(KERN_INFO, "%s: irq=%d\n", dev->name, dev->irq);
+
+	return 0;
+}
+
+static int ep93xx_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	int rc;
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	spin_lock_irq(&priv->mii_lock);
+	rc = generic_mii_ioctl(&priv->mii, if_mii(rq), cmd, NULL);
+	spin_unlock_irq(&priv->mii_lock);
+
+	return rc;
+}
+
+/*
+ * Ethtool support
+ */
+
+static void ep93xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+}
+
+static int ep93xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	spin_lock_irq(&priv->mii_lock);
+	mii_ethtool_gset(&priv->mii, cmd);
+	spin_unlock_irq(&priv->mii_lock);
+	return 0;
+}
+
+static int ep93xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	int rc;
+	spin_lock_irq(&priv->mii_lock);
+	rc = mii_ethtool_sset(&priv->mii, cmd);
+	spin_unlock_irq(&priv->mii_lock);
+	return rc;
+}
+
+static int ep93xx_nway_reset(struct net_device *dev)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	return mii_nway_restart(&priv->mii);
+}
+
+static u32 ep93xx_get_link(struct net_device *dev)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	return mii_link_ok(&priv->mii);
+}
+
+static u32 ep93xx_get_msglevel(struct net_device *dev)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	return priv->msg_enable;
+}
+
+static void ep93xx_set_msglevel(struct net_device *dev, u32 datum)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	priv->msg_enable = datum;
+}
+
+static void ep93xx_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	spin_lock_irq(&priv->mii_lock);
+	memcpy_fromio(regbuf, priv->base_addr, regs->len);
+	spin_unlock_irq(&priv->mii_lock);
+}
+
+static int ep93xx_get_regs_len(struct net_device *dev)
+{
+	struct ep93xx_priv *priv = netdev_priv(dev);
+	return priv->regs_len;
+}
+
+static struct ethtool_ops ep93xx_ethtool_ops = {
+	.get_drvinfo		= ep93xx_get_drvinfo,
+	.get_settings		= ep93xx_get_settings,
+	.set_settings		= ep93xx_set_settings,
+	.get_regs		= ep93xx_get_regs,
+	.get_regs_len		= ep93xx_get_regs_len,
+	.nway_reset		= ep93xx_nway_reset,
+	.get_link		= ep93xx_get_link,
+	.get_msglevel		= ep93xx_get_msglevel,
+	.set_msglevel		= ep93xx_set_msglevel,
+};
+
+/**
+ *  driver_init() - Logical driver initialization for an individual device
+ *
+ *      Minimum device H/W access at this point
+ *
+ *  Task:
+ *        Initialize the structure if needed
+ *        print out my vanity message if not done so already
+ *        print out what type of hardware is detected
+ *        print out the ethernet address
+ *        find the IRQ
+ *        set up my private data
+ *        configure the dev structure with my subroutines
+ *        actually GRAB the irq.
+ *        GRAB the region
+ *
+ */
+static int __init driver_init(struct net_device *dev, u32 baseA, int irq)
+{
+	int i;
+	struct resource *res;
+	struct sockaddr sa;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	if (0 == num_of_instance)
+		printk("%s", version);
+
+	/* skip probing for a second one, we _know_ that it does not exist */
+	if (1 == num_of_instance)
+		return -ENODEV;
+
+	memset(dev->priv, 0x00, sizeof(struct ep93xx_priv));
+
+	/* device instance ID */
+	priv->id = num_of_instance;
+
+	/* mii stuff */
+	spin_lock_init(&priv->mii_lock);
+	priv->mii.dev = dev;
+	priv->mii.mdio_read = mdio_read;
+	priv->mii.mdio_write = mdio_write;
+	priv->mii.phy_id_mask = 0x1f;
+	priv->mii.reg_num_mask = 0x1f;
+	priv->msg_enable = EP93XX_DEF_MSG;
+	priv->regs_len = DEV_REG_SPACE;
+
+	priv->base_addr = (void *)(baseA);
+
+	dev->irq = irq;
+
+	res = request_mem_region(baseA, DEV_REG_SPACE, DRV_NAME);
+	if (res == NULL) {
+		if (netif_msg_probe(priv))
+			DBG(KERN_ERR, "request_mem_region failed!\n");
+		goto err_free_priv_1;
+	}
+
+	dev->open = &ep93xx_open;
+	dev->stop = &ep93xx_close;
+	dev->do_ioctl = &ep93xx_ioctl;
+	dev->hard_start_xmit = &ep93xx_start_xmit;
+	dev->tx_timeout = &ep93xx_tx_timeout;
+	dev->watchdog_timeo = HZ * 5;
+	dev->get_stats = &ep93xx_get_stats;
+	dev->set_multicast_list = &ep93xx_set_multicast_list;
+	dev->ethtool_ops = &ep93xx_ethtool_ops;
+
+	ether_setup(dev);
+
+	if (devQue_init(dev))
+		goto err_free_bd_memregion_irq_2;
+
+	reset(dev);
+
+	/*
+	 * use a random MAC for now -
+	 * don't forget to set a valid MAC later on with ifconfig
+	 */
+	sa.sa_family = AF_INET;
+//	random_ether_addr(sa.sa_data);
+	memcpy(sa.sa_data, "\x00\xd0\x69\x40\x2b\x13", 6);
+	dev->set_mac_address(dev, &sa);
+
+	if (netif_msg_probe(priv)) {
+		printk(KERN_INFO DRV_NAME ": #%d at 0x%p IRQ:%d\n", priv->id, priv->base_addr, dev->irq);
+		printk(KERN_INFO DRV_NAME ": using random number");
+		for (i = 0; i < 6; i++)
+			printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
+
+		printk(" as MAC, don't forget to assign a valid MAC later!\n");
+	}
+	num_of_instance++;
+	return 0;
+
+err_free_bd_memregion_irq_2:
+	kfree(priv->rxbd);
+	disable_irq(dev->irq);
+	free_irq(dev->irq, dev);
+	release_mem_region((u32)priv->base_addr, DEV_REG_SPACE);
+err_free_priv_1:
+	kfree(dev->priv);
+	return -EAGAIN;
+}
+
+/**
+ * ep93xx_probe - probe for ep93xx device
+ *
+ * Probe for the one (and only) ethernet device found on
+ * EP93xx SOC CPU.
+ */
+static int __init ep93xx_probe(void)
+{
+	int err;
+	struct ep93xx_priv *priv;
+	struct net_device *dev = alloc_etherdev(sizeof(struct ep93xx_priv));
+
+	if (!dev)
+		return -ENODEV;
+
+	priv = netdev_priv(dev);
+
+	SET_MODULE_OWNER(dev);
+
+	sprintf(dev->name, "eth0");
+
+	priv->base_addr = (void *)(port_list[0].base_addr);
+
+	dev->irq = port_list[0].irq;
+
+	err = driver_init(dev, (u32)priv->base_addr, dev->irq);
+	if (err)
+		goto err_free_netdev;
+
+	err = register_netdev(dev);
+	if (err)
+		goto err_free_memregion_irq_1;
+
+	ep93xx_etherdev = dev;
+	disable_irq(dev->irq);
+	return 0;
+
+err_free_memregion_irq_1:
+	kfree(priv->rxbd);
+	disable_irq(dev->irq);
+	free_irq(dev->irq, dev);
+	release_mem_region((u32)priv->base_addr, DEV_REG_SPACE);
+err_free_netdev:
+	free_netdev(dev);
+	return err;
+}
+
+static void __exit ep93xx_exit(void)
+{
+	struct net_device *dev = ep93xx_etherdev;
+	struct ep93xx_priv *priv = netdev_priv(dev);
+
+	if (dev) {
+		unregister_netdev(dev);
+		devQue_cleanup(dev);
+		free_irq(dev->irq, dev);
+		release_mem_region((u32)priv->base_addr, DEV_REG_SPACE);
+		free_netdev(dev);
+	}
+}
+
+module_init(ep93xx_probe);
+module_exit(ep93xx_exit);
+MODULE_LICENSE("GPL");
diff -urN linux-2.6.15.commit/drivers/net/arm/ep93xx_eth_need_rewrite.h linux-2.6.15.snap/drivers/net/arm/ep93xx_eth_need_rewrite.h
--- linux-2.6.15.commit/drivers/net/arm/ep93xx_eth_need_rewrite.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/drivers/net/arm/ep93xx_eth_need_rewrite.h	2006-02-20 00:09:48.000000000 +0100
@@ -0,0 +1,355 @@
+/*
+ * ep93xx_eth.h
+ * : header file of Ethernet Device Driver for Cirrus Logic EP93xx.
+ *
+ * Copyright (C) 2003 by Cirrus Logic www.cirrus.com
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License.
+ *
+ * This file contains device related information like register info
+ * and register access method macros for the Ethernet device
+ * embedded within Cirrus Logic's EP93xx SOC chip.
+ *
+ * Information contained in this file was obtained from
+ * the EP9312 Manual Revision 0.12 and 0.14 from Cirrus Logic.
+ *
+ * History
+ * 05/18/01  Sungwook Kim  Initial release
+ * 03/25/2003  Melody Modified for EP92xx
+ */
+
+#ifndef _EP93xx_ETH_H_
+#define _EP93xx_ETH_H_
+
+/*
+ * Definition of the registers.
+ * For details, refer to the datasheet  .
+ *
+ * Basically, most registers are 32 bits width register.
+ * But some are 16 bits and some are 6 or 8 bytes long.
+ */
+
+#define  REG_RxCTL  0x0000	/*offset to Receiver Control Reg */
+#define  RxCTL_PauseA  (1<<20)
+#define  RxCTL_RxFCE1  (1<<19)
+#define  RxCTL_RxFCE0  (1<<18)
+#define  RxCTL_BCRC    (1<<17)
+#define  RxCTL_SRxON   (1<<16)
+#define  RxCTL_RCRCA   (1<<13)
+#define  RxCTL_RA      (1<<12)
+#define  RxCTL_PA      (1<<11)
+#define  RxCTL_BA      (1<<10)
+#define  RxCTL_MA      (1<<9)
+#define  RxCTL_IAHA    (1<<8)
+#define  RxCTL_IA3     (1<<3)
+#define  RxCTL_IA2     (1<<2)
+#define  RxCTL_IA1     (1<<1)
+#define  RxCTL_IA0     (1<<0)
+
+#define  REG_TxCTL  0x0004	/*offset to Transmit Control Reg */
+#define  TxCTL_DefDis  (1<<7)
+#define  TxCTL_MBE     (1<<6)
+#define  TxCTL_ICRC    (1<<5)
+#define  TxCTL_TxPD    (1<<5)
+#define  TxCTL_OColl   (1<<3)
+#define  TxCTL_SP      (1<<2)
+#define  TxCTL_PB      (1<<1)
+#define  TxCTL_STxON   (1<<0)
+
+#define  REG_TestCTL   0x0008	/*Test Control Reg, R/W */
+#define  TestCTL_MACF  (1<<7)
+#define  TestCTL_MFDX  (1<<6)
+#define  TestCTL_DB    (1<<5)
+#define  TestCTL_MIIF  (1<<4)
+
+#define  REG_MIICmd  0x0010	/*offset to MII Command Reg, R/W */
+#define  MIICmd_OP     (0x03<<14)
+#define  MIICmd_OP_RD  (2<<14)
+#define  MIICmd_OP_WR  (1<<14)
+#define  MIICmd_PHYAD  (0x1f<<5)
+#define  MIICmd_REGAD  (0x1f<<0)
+
+#define  REG_MIIData  0x0014	/*offset to MII Data Reg, R/W */
+#define  MIIData_MIIData  (0xffff<<0)
+
+#define  REG_MIISts  0x0018	/*offset to MII Status Reg, R */
+#define  MIISts_Busy  (1<<0)
+
+#define  REG_SelfCTL  0x0020	/*offset to Self Control Reg */
+#define  SelfCTL_RWP    (1<<7)	/*Remote Wake Pin */
+#define  SelfCTL_GPO0   (1<<5)
+#define  SelfCTL_PUWE   (1<<4)
+#define  SelfCTL_PDWE   (1<<3)
+#define  SelfCTL_MIIL   (1<<2)
+#define  SelfCTL_RESET  (1<<0)
+
+#define  REG_IntEn   0x0024	/*Interrupt Enable Reg, R/W */
+#define  IntEn_RWIE    (1<<30)
+#define  IntEn_RxMIE   (1<<29)
+#define  IntEn_RxBIE   (1<<28)
+#define  IntEn_RxSQIE  (1<<27)
+#define  IntEn_TxLEIE  (1<<26)
+#define  IntEn_ECIE    (1<<25)
+#define  IntEn_TxUHIE  (1<<24)
+#define  IntEn_MOIE    (1<<18)
+#define  IntEn_TxCOIE  (1<<17)
+#define  IntEn_RxROIE  (1<<16)
+#define  IntEn_MIIIE   (1<<12)
+#define  IntEn_PHYSIE  (1<<11)
+#define  IntEn_TIE     (1<<10)
+#define  IntEn_SWIE    (1<<8)
+#define  IntEn_TxSQIE   (1<<3)
+#define  IntEn_RxEOFIE  (1<<2)
+#define  IntEn_RxEOBIE  (1<<1)
+#define  IntEn_RxHDRIE  (1<<0)
+
+#define  REG_IntStsP  0x0028	/*offset to Interrupt Status Preserve Reg, R/W */
+#define  REG_IntStsC  0x002c	/*offset to Interrupt Status Clear Reg, R */
+#define  IntSts_RWI    (1<<30)
+#define  IntSts_RxMI   (1<<29)
+#define  IntSts_RxBI   (1<<28)
+#define  IntSts_RxSQI  (1<<27)
+#define  IntSts_TxLEI  (1<<26)
+#define  IntSts_ECI    (1<<25)
+#define  IntSts_TxUHI  (1<<24)
+#define  IntSts_MOI    (1<<18)
+#define  IntSts_TxCOI  (1<<17)
+#define  IntSts_RxROI  (1<<16)
+#define  IntSts_MIII   (1<<12)
+#define  IntSts_PHYSI  (1<<11)
+#define  IntSts_TI     (1<<10)
+#define  IntSts_AHBE   (1<<9)
+#define  IntSts_SWI    (1<<8)
+#define  IntSts_OTHER  (1<<4)
+#define  IntSts_TxSQ   (1<<3)
+#define  IntSts_RxSQ   (1<<2)
+
+#define  REG_GT  0x0040		/*offset to General Timer Reg */
+#define  GT_GTC  (0xffff<<16)
+#define  GT_GTP  (0xffff<<0)
+
+#define  REG_FCT  0x0044	/*offset to Flow Control Timer Reg */
+#define  FCT_FCT  (0x00ffffff<<0)
+
+#define  REG_FCF  0x0048	/*offset to Flow Control Format Reg */
+#define  FCF_MACCT  (0xffff<<16)
+#define  FCF_TPT    (0xffff<<0)
+
+#define  REG_AFP  0x004c	/*offset to Address Filter Pointer Reg */
+#define  AFP_AFP  (0x07<<0)	/*Address Filter Pointer
+				   (bank control for REG_IndAD) */
+#define  AFP_AFP_IA0   0	/*Primary Individual Address (MAC Addr) */
+#define  AFP_AFP_IA1   1	/*Individual Address 1 */
+#define  AFP_AFP_IA2   2	/*Individual Address 2 */
+#define  AFP_AFP_IA3   3	/*Individual Address 3 */
+#define  AFP_AFP_DTxP  6	/*Destination Address of Tx Pause Frame */
+#define  AFP_AFP_HASH  7	/*Hash Table */
+
+#define  REG_IndAD      0x0050	/*offset to Individual Address Reg,
+				   n bytes, R/W */
+
+#define  REG_GIntSts    0x0060	/*offset to Global Interrupt
+				   Status Reg (writing 1 will clear) */
+#define  REG_GIntROS    0x0068	/*offset to Global Interrupt
+				   Status Read Only Reg */
+#define  GIntSts_INT  (1<<15)	/*Global Interrupt Request Status */
+
+#define  REG_GIntMsk    0x0064	/*offset to Global Interrupt Mask Reg */
+#define  GIntMsk_IntEn  (1<<15)	/*Global Interrupt Enable */
+
+#define  REG_GIntFrc    0x006c	/*offset to Global Interrupt Force Reg */
+#define  GIntFrc_INT  (1<<15)	/*Force to set GIntSts */
+
+#define  REG_TxCollCnt  0x0070	/*Transmit Collision Count Reg, R */
+#define  REG_RxMissCnt  0x0074	/*Receive Miss Count Reg, R */
+#define  REG_RxRntCnt   0x0078	/*Receive Runt Count Reg, R */
+
+#define  REG_BMCtl  0x0080	/*offset to Bus Master Control Reg, R/W */
+#define  BMCtl_MT     (1<<13)
+#define  BMCtl_TT     (1<<12)
+#define  BMCtl_UnH    (1<<11)
+#define  BMCtl_TxChR  (1<<10)
+#define  BMCtl_TxDis  (1<<9)
+#define  BMCtl_TxEn   (1<<8)
+#define  BMCtl_EH2    (1<<6)
+#define  BMCtl_EH1    (1<<5)
+#define  BMCtl_EEOB   (1<<4)
+#define  BMCtl_RxChR  (1<<2)
+#define  BMCtl_RxDis  (1<<1)
+#define  BMCtl_RxEn   (1<<0)
+
+#define  REG_BMSts  0x0084	/*offset to Bus Master Status Reg, R */
+#define  BMSts_TxAct  (1<<7)
+#define  BMSts_TP     (1<<4)
+#define  BMSts_RxAct  (1<<3)
+#define  BMSts_QID    (0x07<<0)
+#define  BMSts_QID_RxDt   (0<<0)
+#define  BMSts_QID_TxDt   (1<<0)
+#define  BMSts_QID_RxSts  (2<<0)
+#define  BMSts_QID_TxSts  (3<<0)
+#define  BMSts_QID_RxDesc (4<<0)
+#define  BMSts_QID_TxDesc (5<<0)
+
+#define  REG_RBCA   0x0088	/*offset to Receive Buffer
+				   Current Address Reg, R */
+#define  REG_TBCA   0x008c	/*offset to Transmit Buffer
+				   Current Address Reg, R */
+
+#define  REG_RxDBA  0x0090	/*offset to Receive Descriptor Queue
+				   Base Address Reg, R/W */
+#define  REG_RxDBL  0x0094	/*offset to Receive Descriptor Queue
+				   Base Length Reg, R/W, 16bits */
+#define  REG_RxDCL  0x0096	/*offset to Receive Descriptor Queue
+				   Current Length Reg, R/W, 16bits */
+#define  REG_RxDCA  0x0098	/*offset to Receive Descriptor Queue
+				   Current Address Reg, R/W */
+
+#define  REG_RxDEQ  0x009c	/*offset to Receive Descriptor
+				   Enqueue Reg, R/W */
+#define  RxDEQ_RDV  (0xffff<<16)	/*R 16bit; Receive Descriptor Value */
+#define  RxDEQ_RDI  (0xff<<0)	/*W 8bit; Receive Descriptor Increment */
+
+#define  REG_RxSBA  0x00a0	/*offset to Receive Status Queue
+				   Base Address Reg, R/W */
+#define  REG_RxSBL  0x00a4	/*offset to Receive Status Queue
+				   Base Length Reg, R/W, 16bits */
+#define  REG_RxSCL  0x00a6	/*offset to Receive Status Queue
+				   Current Length Reg, R/W, 16bits */
+#define  REG_RxSCA  0x00a8	/*offset to Receive Status Queue
+				   Current Address Reg, R/W */
+
+#define  REG_RxSEQ  0x00ac	/*offset to Receive Status Queue
+				   Current Address Reg, R/W */
+#define  RxSEQ_RSV  (0xffff<<16)
+#define  RxSEQ_RSI  (0xff<<0)
+
+#define  REG_TxDBA  0x00b0	/*offset to Transmit Descriptor Queue
+				   Base Address Reg, R/W */
+#define  REG_TxDBL  0x00b4	/*offset to Transmit Descriptor Queue
+				   Base Length Reg, R/W, 16bits */
+#define  REG_TxDCL  0x00b6	/*offset to Transmit Descriptor Queue
+				   Current Length Reg, R/W, 16bits */
+#define  REG_TxDCA  0x00b8	/*offset to Transmit Descriptor Queue
+				   Current Address Reg, R/W */
+
+#define  REG_TxDEQ  0x00bc	/*offset to Transmit Descriptor Queue
+				   Current Address Reg, R/W */
+#define  TxDEQ_TDV  (0xffff<<16)
+#define  TxDEQ_TDI  (0xff<<0)
+
+#define  REG_TxSBA  0x00c0	/*offset to Transmit Status Queue
+				   Base Address Reg, R/W */
+#define  REG_TxSBL  0x00c4	/*offset to Transmit Status Queue
+				   Base Length Reg, R/W, 16bits */
+#define  REG_TxSCL  0x00c6	/*offset to Transmit Status Queue
+				   Current Length Reg, R/W, 16bits */
+#define  REG_TxSCA  0x00c8	/*offset to Transmit Status Queue
+				   Current Address Reg, R/W */
+
+#define  REG_RxBTH  0x00d0	/*offset to Receive Buffer
+				   Threshold Reg, R/W */
+#define  RxBTH_RDHT  (0x03ff<<16)
+#define  RxBTH_RDST  (0x03ff<<0)
+
+#define  REG_TxBTH  0x00d4	/*offset to Transmit Buffer
+				   Threshold Reg, R/W */
+#define  TxBTH_TDHT  (0x03ff<<16)
+#define  TxBTH_TDST  (0x03ff<<0)
+
+#define  REG_RxSTH  0x00d8	/*offset to Receive Status
+				   Threshold Reg, R/W */
+#define  RxSTH_RSHT  (0x003f<<16)
+#define  RxSTH_RSST  (0x003f<<0)
+
+#define  REG_TxSTH  0x00dc	/*offset to Transmit Status
+				   Threshold Reg, R/W */
+#define  TxSTH_TSHT  (0x003f<<16)
+#define  TxSTH_TSST  (0x003f<<0)
+
+#define  REG_RxDTH  0x00e0	/*offset to Receive Descriptor
+				   Threshold Reg, R/W */
+#define  RxDTH_RDHT  (0x003f<<16)
+#define  RxDTH_RDST  (0x003f<<0)
+
+#define  REG_TxDTH  0x00e4	/*offset to Transmit Descriptor
+				   Threshold Reg, R/W */
+#define  TxDTH_TDHT  (0x003f<<16)
+#define  TxDTH_TDST  (0x003f<<0)
+
+#define  REG_MaxFL  0x00e8	/*offset to Max Frame Length Reg, R/W */
+#define  MaxFL_MFL  (0x07ff<<16)
+#define  MaxFL_TST  (0x07ff<<0)
+
+#define  REG_RxHL  0x00ec	/*offset to Receive Header Length Reg, R/W */
+#define  RxHL_RHL2  (0x07ff<<16)
+#define  RxHL_RHL1  (0x03ff<<0)
+
+#define  REG_MACCFG0  0x0100	/*offset to Test Reg #0, R/W */
+#define  MACCFG0_DbgSel  (1<<7)
+#define  MACCFG0_LCKEN   (1<<6)
+#define  MACCFG0_LRATE   (1<<5)
+#define  MACCFG0_RXERR   (1<<4)
+#define  MACCFG0_BIT33   (1<<2)
+#define  MACCFG0_PMEEN   (1<<1)
+#define  MACCFG0_PMEST   (1<<0)
+
+#define  REG_MACCFG1  0x0104	/*offset to Test Reg #1, R/W */
+#define  REG_MACCFG2  0x0108	/*offset to Test Reg #2, R */
+#define  REG_MACCFG3  0x010c	/*offset to Test Reg #3, R */
+
+/*---------------------------------------------------------------
+ * Definition of Descriptor/Status Queue Entry
+ *-------------------------------------------------------------*/
+struct rx_dsc {
+	__be32 ba;
+	__be16 bl;
+	__be16 bi;		/* let nsof flag be part of bi */
+};
+
+#define RXSTS_RFP 	0x80000000
+#define RXSTS_RWE	0x40000000
+#define RXSTS_EOF	0x20000000
+#define RXSTS_EOB	0x10000000
+#define RXSTS_AM	0x00C00000
+#define RXSTS_OE	0x00100000
+#define RXSTS_FE	0x00080000
+#define RXSTS_RUNT	0x00040000
+#define RXSTS_EDATA	0x00020000
+#define RXSTS_CRCE	0x00010000
+
+#define RXSTS_BI	0x7FFF
+struct rx_sts {			/* Receive Status Queue Entry */
+	__be32	w1;		
+	__be16	fl;		
+	__be16	bi;		/* bi and rfp2 */
+};
+
+#define TXDSC_BL	0x0FFF
+#define TXDSC_AF	0x8000
+#define TXDSC_BI	0x7FFF
+#define TXDSC_EOF	0x8000
+struct tx_dsc {                 /* Transmit Descriptor Queue Entry */
+	__be32	ba;	/*b31-0: physical Buffer Address */
+	__be16	bl_af;	/* Buffer Length, Abort Frame */
+	__be16	bi_eof;	/* Buffer Index, End Of Frame */
+};
+
+#define TXSTS_BI	0x7fff
+#define TXSTS_TXFP	0x80
+#define TXSTS_TXWE	0x40
+#define TXSTS_LCRS	0x10
+#define TXSTS_TXU	0x02
+#define TXSTS_ECOLL	0x01
+
+struct tx_sts {
+	__be16	bi;
+	u8	ncoll;
+	u8	flags;
+};
+
+/*
+ *  Size of device registers occupied in memory/IO address map
+ */
+#define  DEV_REG_SPACE  0x00010000
+
+#endif				/* _EP93xx_ETH_H_ */
diff -urN linux-2.6.15.commit/drivers/net/arm/Kconfig linux-2.6.15.snap/drivers/net/arm/Kconfig
--- linux-2.6.15.commit/drivers/net/arm/Kconfig	2006-02-12 10:22:16.000000000 +0100
+++ linux-2.6.15.snap/drivers/net/arm/Kconfig	2006-02-20 00:10:36.000000000 +0100
@@ -44,3 +44,12 @@
 	  will generate a suitable hw address based on the board serial
 	  number (MTD support is required for this). Otherwise you will
 	  need to set a suitable hw address using ifconfig.
+
+config EP93XX_ETHERNET
+	tristate "EP93xx Ethernet support"
+	depends on NET_ETHERNET && ARM && ARCH_EP93XX
+	select CRC32
+	select MII
+	help
+	  This is a driver for the ethernet hardware included in EP93xx CPUs.
+	  Say Y if you are building a kernel for EP93xx based devices.
diff -urN linux-2.6.15.commit/drivers/net/arm/Makefile linux-2.6.15.snap/drivers/net/arm/Makefile
--- linux-2.6.15.commit/drivers/net/arm/Makefile	2006-02-12 10:22:16.000000000 +0100
+++ linux-2.6.15.snap/drivers/net/arm/Makefile	2006-02-20 00:12:09.000000000 +0100
@@ -8,3 +8,4 @@
 obj-$(CONFIG_ARM_ETHERH)	+= etherh.o
 obj-$(CONFIG_ARM_ETHER3)	+= ether3.o
 obj-$(CONFIG_ARM_ETHER1)	+= ether1.o
+obj-$(CONFIG_EP93XX_ETHERNET)	+= ep93xx_eth_need_rewrite.o
diff -urN linux-2.6.15.commit/drivers/serial/amba-pl010.c linux-2.6.15.snap/drivers/serial/amba-pl010.c
--- linux-2.6.15.commit/drivers/serial/amba-pl010.c	2006-02-12 10:22:16.000000000 +0100
+++ linux-2.6.15.snap/drivers/serial/amba-pl010.c	2006-02-20 00:08:56.000000000 +0100
@@ -93,8 +93,8 @@
  *  UART0  7    6
  *  UART1  5    4
  */
-#define SC_CTRLC	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
-#define SC_CTRLS	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+//#define SC_CTRLC	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
+//#define SC_CTRLS	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
 
 /*
  * We wrap our port structure around the generic uart_port.
@@ -339,8 +339,8 @@
 	else
 		ctrls |= uap->dtr_mask;
 
-	__raw_writel(ctrls, SC_CTRLS);
-	__raw_writel(ctrlc, SC_CTRLC);
+//	__raw_writel(ctrls, SC_CTRLS);
+//	__raw_writel(ctrlc, SC_CTRLC);
 }
 
 static void pl010_break_ctl(struct uart_port *port, int break_state)
@@ -568,11 +568,12 @@
 static struct uart_amba_port amba_ports[UART_NR] = {
 	{
 		.port	= {
-			.membase	= (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),
-			.mapbase	= INTEGRATOR_UART0_BASE,
+			.membase	= (void *)(EP93XX_APB_VIRT_BASE + 0x000c0000),
+			.mapbase	= EP93XX_APB_PHYS_BASE + 0x000c0000,
 			.iotype		= SERIAL_IO_MEM,
-			.irq		= IRQ_UARTINT0,
-			.uartclk	= 14745600,
+			.irq		= IRQ_EP93XX_UART1,
+//			.uartclk	= 14745600,
+			.uartclk	= 7372800,
 			.fifosize	= 16,
 			.ops		= &amba_pl010_pops,
 			.flags		= ASYNC_BOOT_AUTOCONF,
@@ -583,11 +584,12 @@
 	},
 	{
 		.port	= {
-			.membase	= (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE),
-			.mapbase	= INTEGRATOR_UART1_BASE,
+			.membase	= (void *)(EP93XX_APB_VIRT_BASE + 0x000d0000),
+			.mapbase	= EP93XX_APB_PHYS_BASE + 0x000d0000,
 			.iotype		= SERIAL_IO_MEM,
-			.irq		= IRQ_UARTINT1,
-			.uartclk	= 14745600,
+			.irq		= IRQ_EP93XX_UART2,
+//			.uartclk	= 14745600,
+			.uartclk	= 7372800,
 			.fifosize	= 16,
 			.ops		= &amba_pl010_pops,
 			.flags		= ASYNC_BOOT_AUTOCONF,
diff -urN linux-2.6.15.commit/drivers/usb/host/ohci-ep93xx.c linux-2.6.15.snap/drivers/usb/host/ohci-ep93xx.c
--- linux-2.6.15.commit/drivers/usb/host/ohci-ep93xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/drivers/usb/host/ohci-ep93xx.c	2006-02-28 02:18:54.000000000 +0100
@@ -0,0 +1,170 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ * (C) Copyright 2002 Hewlett-Packard Company
+ *
+ * Bus Glue for ep93xx.
+ *
+ * Written by Christopher Hoover <ch@hpl.hp.com>
+ * Based on fragments of previous driver by Russell King et al.
+ *
+ * Modified for LH7A404 from ohci-sa1111.c
+ *  by Durgesh Pattamatta <pattamattad@sharpsec.com>
+ *
+ * Modified for pxa27x from ohci-lh7a404.c
+ *  by Nick Bane <nick@cecomputing.co.uk> 26-8-2004
+ *
+ * Modified for ep93xx from ohci-pxa27x.c
+ *  by Lennert Buytenhek <buytenh@wantstofly.org> 28-2-2006
+ *  Based on an earlier driver by Ray Lehtiniemi
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include <linux/device.h>
+#include <linux/signal.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+
+static void ep93xx_start_hc(struct platform_device *dev)
+{
+	unsigned int pwrcnt;
+
+	pwrcnt = __raw_readl(EP93XX_SYSCON_CLOCK_CONTROL);
+	pwrcnt |= EP93XX_SYSCON_CLOCK_USH_EN;
+	__raw_writel(pwrcnt, EP93XX_SYSCON_CLOCK_CONTROL);
+}
+
+static void ep93xx_stop_hc(struct platform_device *dev)
+{
+	unsigned int pwrcnt;
+
+	pwrcnt = __raw_readl(EP93XX_SYSCON_CLOCK_CONTROL);
+	pwrcnt &= ~EP93XX_SYSCON_CLOCK_USH_EN;
+	__raw_writel(pwrcnt, EP93XX_SYSCON_CLOCK_CONTROL);
+}
+
+int usb_hcd_ep93xx_probe(const struct hc_driver *driver,
+			 struct platform_device *dev)
+{
+	int retval;
+	struct usb_hcd *hcd;
+
+	hcd = usb_create_hcd(driver, &dev->dev, "ep93xx");
+	if (hcd == NULL)
+		return -ENOMEM;
+
+	hcd->rsrc_start = dev->resource[0].start;
+	hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		usb_put_hcd(hcd);
+		retval = -EBUSY;
+		goto err1;
+	}
+
+	hcd->regs = (void __iomem *)dev->resource[0].start;
+
+	ep93xx_start_hc(dev);
+
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
+	if (retval == 0)
+		return retval;
+
+	ep93xx_stop_hc(dev);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+	usb_put_hcd(hcd);
+
+	return retval;
+}
+
+void usb_hcd_ep93xx_remove(struct usb_hcd *hcd, struct platform_device *dev)
+{
+	usb_remove_hcd(hcd);
+	ep93xx_stop_hc(dev);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+}
+
+static int __devinit ohci_ep93xx_start(struct usb_hcd *hcd)
+{
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	int ret;
+
+	if ((ret = ohci_init(ohci)) < 0)
+		return ret;
+
+	if ((ret = ohci_run(ohci)) < 0) {
+		err("can't start %s", hcd->self.bus_name);
+		ohci_stop(hcd);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct hc_driver ohci_ep93xx_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "EP93xx OHCI",
+	.hcd_priv_size		= sizeof(struct ohci_hcd),
+	.irq			= ohci_irq,
+	.flags			= HCD_USB11,
+	.start			= ohci_ep93xx_start,
+	.stop			= ohci_stop,
+	.urb_enqueue		= ohci_urb_enqueue,
+	.urb_dequeue		= ohci_urb_dequeue,
+	.endpoint_disable	= ohci_endpoint_disable,
+	.get_frame_number	= ohci_get_frame,
+	.hub_status_data	= ohci_hub_status_data,
+	.hub_control		= ohci_hub_control,
+};
+
+extern int usb_disabled(void);
+
+static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = -ENODEV;
+	if (!usb_disabled())
+		ret = usb_hcd_ep93xx_probe(&ohci_ep93xx_hc_driver, pdev);
+
+	return ret;
+		return -ENODEV;
+}
+
+static int ohci_hcd_ep93xx_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_hcd_ep93xx_remove(hcd, pdev);
+
+	return 0;
+}
+
+static struct platform_driver ohci_hcd_ep93xx_driver = {
+	.probe		= ohci_hcd_ep93xx_drv_probe,
+	.remove		= ohci_hcd_ep93xx_drv_remove,
+	.driver		= {
+		.name	= "ep93xx-ohci",
+	},
+};
+
+static int __init ohci_hcd_ep93xx_init(void)
+{
+	return platform_driver_register(&ohci_hcd_ep93xx_driver);
+}
+
+static void __exit ohci_hcd_ep93xx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_ep93xx_driver);
+}
+
+module_init(ohci_hcd_ep93xx_init);
+module_exit(ohci_hcd_ep93xx_cleanup);
diff -urN linux-2.6.15.commit/drivers/usb/host/ohci-hcd.c linux-2.6.15.snap/drivers/usb/host/ohci-hcd.c
--- linux-2.6.15.commit/drivers/usb/host/ohci-hcd.c	2006-02-12 10:22:16.000000000 +0100
+++ linux-2.6.15.snap/drivers/usb/host/ohci-hcd.c	2006-02-28 01:30:21.000000000 +0100
@@ -909,6 +909,10 @@
 #include "ohci-pxa27x.c"
 #endif
 
+#ifdef CONFIG_ARCH_EP93XX
+#include "ohci-ep93xx.c"
+#endif
+
 #ifdef CONFIG_SOC_AU1X00
 #include "ohci-au1xxx.c"
 #endif
@@ -923,6 +927,7 @@
       || defined(CONFIG_ARCH_OMAP) \
       || defined (CONFIG_ARCH_LH7A404) \
       || defined (CONFIG_PXA27x) \
+      || defined (CONFIG_ARCH_EP93XX) \
       || defined (CONFIG_SOC_AU1X00) \
       || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
 	)
diff -urN linux-2.6.15.commit/drivers/usb/Kconfig linux-2.6.15.snap/drivers/usb/Kconfig
--- linux-2.6.15.commit/drivers/usb/Kconfig	2006-02-12 10:22:16.000000000 +0100
+++ linux-2.6.15.snap/drivers/usb/Kconfig	2006-02-20 22:56:03.000000000 +0100
@@ -22,6 +22,7 @@
 	default y if ARCH_LH7A404
 	default y if ARCH_S3C2410
 	default y if PXA27x
+	default y if ARCH_EP93XX
 	# PPC:
 	default y if STB03xxx
 	default y if PPC_MPC52xx
diff -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/debug-macro.S linux-2.6.15.snap/include/asm-arm/arch-ep93xx/debug-macro.S
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/debug-macro.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/debug-macro.S	2006-02-19 18:59:06.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+		.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
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x18]
+		tst	\rd, #0x08
+		bne	1001b
+		.endm
+
+		.macro	waituart,rd,rx
+		nop
+		nop
+		nop
+		.endm
diff -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/dma.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/dma.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/dma.h	2006-02-19 19:28:06.000000000 +0100
@@ -0,0 +1,6 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/dma.h
+ */
+
+#define MAX_DMA_ADDRESS		0xffffffff
+#define MAX_DMA_CHANNELS	0
diff -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/entry-macro.S linux-2.6.15.snap/include/asm-arm/arch-ep93xx/entry-macro.S
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/entry-macro.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/entry-macro.S	2006-02-20 19:04:14.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+		.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
Binary files linux-2.6.15.commit/include/asm-arm/arch-ep93xx/.entry-macro.S.swp and linux-2.6.15.snap/include/asm-arm/arch-ep93xx/.entry-macro.S.swp differ
diff -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/ep93xx-regs.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/ep93xx-regs.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/ep93xx-regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/ep93xx-regs.h	2006-02-28 01:32:57.000000000 +0100
@@ -0,0 +1,118 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/ep93xx-regs.h
+ */
+
+#ifndef __ARCH_EP93XX_REGS_H
+#define __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_RASTER_BASE		(EP93XX_AHB_VIRT_BASE + 0x00030000)
+
+#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_VIC1_REG(x)		(EP93XX_VIC1_BASE + (x))
+#define EP93XX_VIC1_IRQ_STATUS		EP93XX_VIC1_REG(0x0000)
+#define EP93XX_VIC1_SELECT		EP93XX_VIC1_REG(0x000c)
+#define EP93XX_VIC1_ENABLE		EP93XX_VIC1_REG(0x0010)
+#define EP93XX_VIC1_ENABLE_CLEAR	EP93XX_VIC1_REG(0x0014)
+#define EP93XX_VIC1_VECT_CNTRL		EP93XX_VIC1_REG(0x0200)
+
+#define EP93XX_VIC2_BASE		(EP93XX_AHB_VIRT_BASE + 0x000c0000)
+#define EP93XX_VIC2_REG(x)		(EP93XX_VIC2_BASE + (x))
+#define EP93XX_VIC2_IRQ_STATUS		EP93XX_VIC2_REG(0x0000)
+#define EP93XX_VIC2_SELECT		EP93XX_VIC2_REG(0x000c)
+#define EP93XX_VIC2_ENABLE		EP93XX_VIC2_REG(0x0010)
+#define EP93XX_VIC2_ENABLE_CLEAR	EP93XX_VIC2_REG(0x0014)
+#define EP93XX_VIC2_VECT_CNTRL		EP93XX_VIC2_REG(0x0200)
+
+
+/* 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_UART2_BASE		(EP93XX_APB_VIRT_BASE + 0x000d0000)
+
+#define EP93XX_UART3_BASE		(EP93XX_APB_VIRT_BASE + 0x000e0000)
+
+#define EP93XX_KEY_MATRIX_BASE		(EP93XX_APB_VIRT_BASE + 0x000f0000)
+
+#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_SWLOCK		EP93XX_SYSCON_REG(0xc0)
+
+#define EP93XX_WATCHDOG_BASE		(EP93XX_APB_VIRT_BASE + 0x00140000)
+
+
+#endif
diff -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/gesbc9312.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/gesbc9312.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/gesbc9312.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/gesbc9312.h	2006-02-19 19:30:10.000000000 +0100
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/gesbc9312.h
+ */
diff -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/hardware.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/hardware.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/hardware.h	2006-02-19 20:15:12.000000000 +0100
@@ -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 -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/io.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/io.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/io.h	2006-02-19 20:03:57.000000000 +0100
@@ -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 -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/irqs.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/irqs.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/irqs.h	2006-02-19 21:29:37.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/irqs.h
+ */
+
+#ifndef _IRQS_H
+#define _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			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 -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/memory.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/memory.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/memory.h	2006-02-22 02:05:51.000000000 +0100
@@ -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 -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/param.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/param.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/param.h	2006-02-22 02:05:20.000000000 +0100
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/param.h
+ */
diff -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/platform.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/platform.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/platform.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/platform.h	2006-02-20 14:26:36.000000000 +0100
@@ -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 -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/system.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/system.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/system.h	2006-02-20 21:28:04.000000000 +0100
@@ -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 -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/timex.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/timex.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/timex.h	2006-02-19 19:16:38.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/timex.h
+ */
+
+#define CLOCK_TICK_RATE	508000
diff -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/ts72xx.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/ts72xx.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/ts72xx.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/ts72xx.h	2006-02-22 17:01:02.000000000 +0100
@@ -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 -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/uncompress.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/uncompress.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/uncompress.h	2006-02-22 02:20:49.000000000 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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>
+
+#define PHYS_UART1_DATA		((unsigned long *)0x808c0000)
+#define PHYS_UART1_FLAG		((unsigned long *)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 (!(*PHYS_UART1_FLAG & UART1_FLAG_TXFF))
+			break;
+	}
+
+	*PHYS_UART1_DATA = c;
+}
+
+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 -urN linux-2.6.15.commit/include/asm-arm/arch-ep93xx/vmalloc.h linux-2.6.15.snap/include/asm-arm/arch-ep93xx/vmalloc.h
--- linux-2.6.15.commit/include/asm-arm/arch-ep93xx/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/arch-ep93xx/vmalloc.h	2006-02-19 22:05:22.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/vmalloc.h
+ */
+
+#define VMALLOC_END	0xfe800000
diff -urN linux-2.6.15.commit/include/asm-arm/hardware/vic.h linux-2.6.15.snap/include/asm-arm/hardware/vic.h
--- linux-2.6.15.commit/include/asm-arm/hardware/vic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/hardware/vic.h	2006-02-20 13:57:02.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ *  linux/include/asm-arm/hardware/vic.h
+ *
+ *  Copyright (c) ARM Limited 2003.  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.
+ *
+ * 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_ARM_HARDWARE_VIC_H
+#define __ASM_ARM_HARDWARE_VIC_H
+
+#define VIC_IRQ_STATUS			0x00
+#define VIC_FIQ_STATUS			0x04
+#define VIC_RAW_STATUS			0x08
+#define VIC_INT_SELECT			0x0c	/* 1 = FIQ, 0 = IRQ */
+#define VIC_INT_ENABLE			0x10	/* 1 = enable, 0 = disable */
+#define VIC_INT_ENABLE_CLEAR		0x14
+#define VIC_INT_SOFT			0x18
+#define VIC_INT_SOFT_CLEAR		0x1c
+#define VIC_PROTECT			0x20
+#define VIC_VECT_ADDR			0x30
+#define VIC_DEF_VECT_ADDR		0x34
+
+#define VIC_VECT_ADDR0			0x100	/* 0 to 15 */
+#define VIC_VECT_CNTL0			0x200	/* 0 to 15 */
+#define VIC_ITCR			0x300	/* VIC test control register */
+
+#define VIC_VECT_CNTL_ENABLE		(1 << 5)
+
+#ifndef __ASSEMBLY__
+void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources);
+#endif
+
+#endif
diff -urN linux-2.6.15.commit/include/asm-arm/mach/irq.h linux-2.6.15.snap/include/asm-arm/mach/irq.h
--- linux-2.6.15.commit/include/asm-arm/mach/irq.h	2006-02-12 10:22:19.000000000 +0100
+++ linux-2.6.15.snap/include/asm-arm/mach/irq.h	2006-02-20 13:57:02.000000000 +0100
@@ -61,7 +61,7 @@
 	struct irqchip	*chip;
 	struct irqaction *action;
 	struct list_head pend;
-	void		*chipdata;
+	void __iomem	*chipdata;
 	void		*data;
 	unsigned int	disable_depth;