summaryrefslogtreecommitdiff
path: root/packages/linux
diff options
context:
space:
mode:
authorKoen Kooi <koen@openembedded.org>2006-02-28 11:50:40 +0000
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>2006-02-28 11:50:40 +0000
commitc1ec4c9321bf64981a9da192320bdd90a95a0cd3 (patch)
tree24adaeb14553acd2e7a9a7d56c33193a26d3e4a1 /packages/linux
parent17b807ebdf0f5c5d5dca74782b73ea9e22595a1f (diff)
ep93xx kernel: update to derevo6
* usb host works(ish) * serial on the glomation board requires an extra patch
Diffstat (limited to 'packages/linux')
-rw-r--r--packages/linux/ep93xx-kernel/derevo6.diff4434
-rw-r--r--packages/linux/ep93xx-kernel_2.6.15.bb4
2 files changed, 4436 insertions, 2 deletions
diff --git a/packages/linux/ep93xx-kernel/derevo6.diff b/packages/linux/ep93xx-kernel/derevo6.diff
new file mode 100644
index 0000000000..fc7f609056
--- /dev/null
+++ b/packages/linux/ep93xx-kernel/derevo6.diff
@@ -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;
+
diff --git a/packages/linux/ep93xx-kernel_2.6.15.bb b/packages/linux/ep93xx-kernel_2.6.15.bb
index b29011f5f4..46cb819d7d 100644
--- a/packages/linux/ep93xx-kernel_2.6.15.bb
+++ b/packages/linux/ep93xx-kernel_2.6.15.bb
@@ -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}"