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 +#include + +#include +#include +#include +#include + +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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + + +/************************************************************************* + * 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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 */ + .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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 */ + .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 +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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 "); +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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 in