ep93xx kernel: update to derevo6
authorKoen Kooi <koen@openembedded.org>
Tue, 28 Feb 2006 11:50:40 +0000 (11:50 +0000)
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>
Tue, 28 Feb 2006 11:50:40 +0000 (11:50 +0000)
* usb host works(ish)
* serial on the glomation board requires an extra patch

packages/linux/ep93xx-kernel/derevo6.diff [new file with mode: 0644]
packages/linux/ep93xx-kernel_2.6.15.bb

diff --git a/packages/linux/ep93xx-kernel/derevo6.diff b/packages/linux/ep93xx-kernel/derevo6.diff
new file mode 100644 (file)
index 0000000..fc7f609
--- /dev/null
@@ -0,0 +1,4434 @@
+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;
index b29011f..46cb819 100644 (file)
@@ -1,10 +1,10 @@
 DESCRIPTION = "Linux Kernel for Cirrus Logic ep39xx compatible machines"
 SECTION = "kernel"
 LICENSE = "GPL"
-PR = "r5"
+PR = "r6"
 
 SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \
-                  http://wantstofly.org/~buytenh/ep93xx/derevo4.diff;patch=1 \
+                  file://derevo6.diff;patch=1 \
                   "
 
 S = "${WORKDIR}/linux-${PV}"