diff options
author | Koen Kooi <koen@openembedded.org> | 2006-02-28 11:50:40 +0000 |
---|---|---|
committer | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2006-02-28 11:50:40 +0000 |
commit | c1ec4c9321bf64981a9da192320bdd90a95a0cd3 (patch) | |
tree | 24adaeb14553acd2e7a9a7d56c33193a26d3e4a1 /packages/linux/ep93xx-kernel | |
parent | 17b807ebdf0f5c5d5dca74782b73ea9e22595a1f (diff) |
ep93xx kernel: update to derevo6
* usb host works(ish)
* serial on the glomation board requires an extra patch
Diffstat (limited to 'packages/linux/ep93xx-kernel')
-rw-r--r-- | packages/linux/ep93xx-kernel/derevo6.diff | 4434 |
1 files changed, 4434 insertions, 0 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; + |