diff -urN -x CVS linux-2.6.24/arch/arm/configs/ks8695_defconfig linux-2.6/arch/arm/configs/ks8695_defconfig --- linux-2.6.24/arch/arm/configs/ks8695_defconfig 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6/arch/arm/configs/ks8695_defconfig 2008-03-04 21:53:53.000000000 +0200 @@ -1,39 +1,62 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc4 -# Thu May 25 15:42:51 2006 +# Linux kernel version: 2.6.24 +# Tue Mar 4 21:53:27 2008 # CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +# CONFIG_GENERIC_TIME is not set +# CONFIG_GENERIC_CLOCKEVENTS is not set CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=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_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -43,28 +66,30 @@ CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set -CONFIG_OBSOLETE_INTERMODULE=y - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# +CONFIG_BLOCK=y +# CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -82,56 +107,66 @@ # # System Type # +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set # 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 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_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_KS8695=y +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_PNX4008 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_DAVINCI 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 -# CONFIG_ARCH_AT91 is not set -CONFIG_ARCH_KS8695=y + +# +# Boot options +# + +# +# Power management +# # # Kendin/Micrel KS8695 Implementations # CONFIG_MACH_KS8695=y -# CONFIG_MACH_DSM320 is not set -# CONFIG_MACH_CM4002 is not set -# CONFIG_MACH_CM4008 is not set -# CONFIG_MACH_CM40xx is not set -# CONFIG_MACH_LITE300 is not set -# CONFIG_MACH_SE4200 is not set -# CONFIG_MACH_MANGA_KS8695 is not set # # Processor Type # CONFIG_CPU_32=y CONFIG_CPU_ARM922T=y -CONFIG_CPU_32v4=y +CONFIG_CPU_32v4T=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 +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y # # Processor Features @@ -140,16 +175,16 @@ # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_OUTER_CACHE is not set # # Bus support # CONFIG_PCI=y +CONFIG_PCI_SYSCALL=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y CONFIG_PCI_DEBUG=y - -# -# PCCARD (PCMCIA/CardBus) support -# CONFIG_PCCARD=y # CONFIG_PCMCIA_DEBUG is not set CONFIG_PCMCIA=y @@ -173,6 +208,7 @@ # # Kernel Features # +# CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set # CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 @@ -185,7 +221,13 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_LEDS is not set CONFIG_ALIGNMENT_TRAP=y # @@ -195,6 +237,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw" # CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set # # Floating point emulation @@ -219,7 +262,7 @@ # Power management options # # CONFIG_PM is not set -# CONFIG_APM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y # # Networking @@ -229,10 +272,13 @@ # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -251,28 +297,23 @@ # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO 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_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK 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 - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -283,13 +324,8 @@ # 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 # @@ -299,7 +335,17 @@ # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -308,19 +354,14 @@ # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set @@ -333,11 +374,14 @@ # User Modules And Translation Layers # CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=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 +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -363,7 +407,6 @@ # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access @@ -372,6 +415,7 @@ # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_ARM_INTEGRATOR is not set # CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_INTEL_VR_NOR is not set # CONFIG_MTD_PLATRAM is not set # @@ -389,29 +433,15 @@ # 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 +# UBI - Unsorted block images # +# CONFIG_MTD_UBI is not set # CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -423,13 +453,14 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set # CONFIG_IDE is not set # @@ -437,108 +468,56 @@ # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set # CONFIG_MD is not set - -# -# Fusion MPT device support -# # CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set - -# -# I2O device support -# # CONFIG_I2O is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# +# CONFIG_VETH is not set # CONFIG_ARCNET is not set - -# -# PHY device support -# # CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y # CONFIG_MII is not set CONFIG_ARM_KS8695_ETHER=y +# CONFIG_AX88796 is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set - -# -# Tulip family network device support -# # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set # CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# PCMCIA network device support +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_NET_PCMCIA is not set - -# -# Wan interfaces -# # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -548,16 +527,14 @@ # 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=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -567,7 +544,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set @@ -577,6 +553,7 @@ # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -592,6 +569,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -610,43 +588,21 @@ CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m # CONFIG_NVRAM is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set - -# # PCMCIA character devices # # CONFIG_SYNCLINK_CS is not set # CONFIG_CARDMAN_4000 is not set # CONFIG_CARDMAN_4040 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -654,49 +610,42 @@ # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# +# CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Misc devices -# - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set +# CONFIG_WATCHDOG is not set # -# LED drivers +# Sonics Silicon Backplane # +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # -# LED Triggers +# Multifunction device drivers # +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # -# Digital Video Broadcasting Devices +# Graphics support # -# CONFIG_DVB is not set +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Graphics support +# Display device support # -# CONFIG_FB is not set +# CONFIG_DISPLAY_SUPPORT is not set # # Console display driver support @@ -708,10 +657,11 @@ # Sound # # CONFIG_SOUND is not set - -# -# USB support -# +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HID_DEBUG=y +# CONFIG_HIDRAW is not set +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -725,15 +675,8 @@ # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set - -# -# Real Time Clock -# +# CONFIG_NEW_LEDS is not set CONFIG_RTC_LIB=y # CONFIG_RTC_CLASS is not set @@ -744,14 +687,17 @@ # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS 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_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -775,10 +721,11 @@ # Pseudo filesystems # CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -791,7 +738,6 @@ # 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=y # CONFIG_VXFS_FS is not set @@ -799,10 +745,7 @@ # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set @@ -810,46 +753,56 @@ # 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 is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# # CONFIG_NLS is not set - -# -# Profiling support -# +# CONFIG_DLM is not set +CONFIG_INSTRUMENTATION=y # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS 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_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y +# CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set CONFIG_DEBUG_USER=y # CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y @@ -860,21 +813,21 @@ # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# +# CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set # -# Hardware crypto devices -# - -# # Library routines # +CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff -urN -x CVS linux-2.6.24/arch/arm/mach-ks8695/Makefile linux-2.6/arch/arm/mach-ks8695/Makefile --- linux-2.6.24/arch/arm/mach-ks8695/Makefile 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6/arch/arm/mach-ks8695/Makefile 2007-12-31 15:04:45.000000000 +0200 @@ -9,7 +9,10 @@ obj- := # PCI support is optional -#obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_PCI) += pci.o + +# LEDs +obj-$(CONFIG_LEDS) += leds.o # Board-specific support obj-$(CONFIG_MACH_KS8695) += board-micrel.o diff -urN -x CVS linux-2.6.24/arch/arm/mach-ks8695/board-micrel.c linux-2.6/arch/arm/mach-ks8695/board-micrel.c --- linux-2.6.24/arch/arm/mach-ks8695/board-micrel.c 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6/arch/arm/mach-ks8695/board-micrel.c 2007-12-31 10:43:55.000000000 +0200 @@ -40,7 +40,7 @@ printk(KERN_INFO "Micrel KS8695 Development Board initializing\n"); #ifdef CONFIG_PCI -// ks8695_init_pci(&micrel_pci); + ks8695_init_pci(&micrel_pci); #endif /* Add devices */ diff -urN -x CVS linux-2.6.24/arch/arm/mach-ks8695/devices.c linux-2.6/arch/arm/mach-ks8695/devices.c --- linux-2.6.24/arch/arm/mach-ks8695/devices.c 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6/arch/arm/mach-ks8695/devices.c 2007-12-31 10:43:55.000000000 +0200 @@ -176,6 +176,27 @@ #endif +/* -------------------------------------------------------------------- + * LEDs + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_LEDS) +short ks8695_leds_cpu = -1; +short ks8695_leds_timer = -1; + +void __init ks8695_init_leds(u8 cpu_led, u8 timer_led) +{ + /* Enable GPIO to access the LEDs */ + gpio_direction_output(cpu_led, 1); + gpio_direction_output(timer_led, 1); + + ks8695_leds_cpu = cpu_led; + ks8695_leds_timer = timer_led; +} +#else +void __init ks8695_init_leds(u8 cpu_led, u8 timer_led) {} +#endif + /* -------------------------------------------------------------------- */ /* diff -urN -x CVS linux-2.6.24/arch/arm/mach-ks8695/gpio.c linux-2.6/arch/arm/mach-ks8695/gpio.c --- linux-2.6.24/arch/arm/mach-ks8695/gpio.c 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6/arch/arm/mach-ks8695/gpio.c 2007-12-31 14:49:20.000000000 +0200 @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -134,9 +136,9 @@ /* set line state */ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); if (state) - x |= (1 << pin); + x |= IOPD_(pin); else - x &= ~(1 << pin); + x &= ~IOPD_(pin); __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD); /* set pin as output */ @@ -166,9 +168,9 @@ /* set output line state */ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); if (state) - x |= (1 << pin); + x |= IOPD_(pin); else - x &= ~(1 << pin); + x &= ~IOPD_(pin); __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD); local_irq_restore(flags); @@ -187,7 +189,7 @@ return -EINVAL; x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); - return (x & (1 << pin)) != 0; + return (x & IOPD_(pin)) != 0; } EXPORT_SYMBOL(gpio_get_value); @@ -216,3 +218,84 @@ return (irq - KS8695_IRQ_EXTERN0); } EXPORT_SYMBOL(irq_to_gpio); + + +/* .... Debug interface ..................................................... */ + +#ifdef CONFIG_DEBUG_FS + +static int ks8695_gpio_show(struct seq_file *s, void *unused) +{ + unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN }; + unsigned int intmask[] = { IOPC_IOEINT0TM, IOPC_IOEINT1TM, IOPC_IOEINT2TM, IOPC_IOEINT3TM }; + unsigned long mode, ctrl, data; + int i; + + mode = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); + ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC); + data = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); + + seq_printf(s, "Pin\tI/O\tFunction\tState\n\n"); + + for (i = KS8695_GPIO_0; i <= KS8695_GPIO_15 ; i++) { + seq_printf(s, "%i:\t", i); + + seq_printf(s, "%s\t", (mode & IOPM_(i)) ? "Output" : "Input"); + + if (i <= KS8695_GPIO_3) { + if (ctrl & enable[i]) { + seq_printf(s, "EXT%i ", i); + + switch ((ctrl & intmask[i]) >> (4 * i)) { + case IOPC_TM_LOW: + seq_printf(s, "(Low)"); break; + case IOPC_TM_HIGH: + seq_printf(s, "(High)"); break; + case IOPC_TM_RISING: + seq_printf(s, "(Rising)"); break; + case IOPC_TM_FALLING: + seq_printf(s, "(Falling)"); break; + case IOPC_TM_EDGE: + seq_printf(s, "(Edges)"); break; + } + } + else + seq_printf(s, "GPIO\t"); + } + else if (i <= KS8695_GPIO_5) { + if (ctrl & enable[i]) + seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4); + else + seq_printf(s, "GPIO\t"); + } + else + seq_printf(s, "GPIO\t"); + + seq_printf(s, "\t"); + + seq_printf(s, "%i\n", (data & IOPD_(i)) ? 1 : 0); + } + return 0; +} + +static int ks8695_gpio_open(struct inode *inode, struct file *file) +{ + return single_open(file, ks8695_gpio_show, NULL); +} + +static const struct file_operations ks8695_gpio_operations = { + .open = ks8695_gpio_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init ks8695_gpio_debugfs_init(void) +{ + /* /sys/kernel/debug/ks8695_gpio */ + (void) debugfs_create_file("ks8695_gpio", S_IFREG | S_IRUGO, NULL, NULL, &ks8695_gpio_operations); + return 0; +} +postcore_initcall(ks8695_gpio_debugfs_init); + +#endif diff -urN -x CVS linux-2.6.24/arch/arm/mach-ks8695/leds.c linux-2.6/arch/arm/mach-ks8695/leds.c --- linux-2.6.24/arch/arm/mach-ks8695/leds.c 1970-01-01 02:00:00.000000000 +0200 +++ linux-2.6/arch/arm/mach-ks8695/leds.c 2007-12-31 15:18:25.000000000 +0200 @@ -0,0 +1,94 @@ +/* + * LED driver for KS8695-based boards. + * + * Copyright (C) Andrew Victor + * + * 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. + */ + +#include +#include +#include + +#include +#include +#include +#include + + +static inline void ks8695_led_on(unsigned int led) +{ + gpio_set_value(led, 0); +} + +static inline void ks8695_led_off(unsigned int led) +{ + gpio_set_value(led, 1); +} + +static inline void ks8695_led_toggle(unsigned int led) +{ + unsigned long is_off = gpio_get_value(led); + if (is_off) + ks8695_led_on(led); + else + ks8695_led_off(led); +} + + +/* + * Handle LED events. + */ +static void ks8695_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch(evt) { + case led_start: /* System startup */ + ks8695_led_on(ks8695_leds_cpu); + break; + + case led_stop: /* System stop / suspend */ + ks8695_led_off(ks8695_leds_cpu); + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: /* Every 50 timer ticks */ + ks8695_led_toggle(ks8695_leds_timer); + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: /* Entering idle state */ + ks8695_led_off(ks8695_leds_cpu); + break; + + case led_idle_end: /* Exit idle state */ + ks8695_led_on(ks8695_leds_cpu); + break; +#endif + + default: + break; + } + + local_irq_restore(flags); +} + + +static int __init leds_init(void) +{ + if ((ks8695_leds_timer == -1) || (ks8695_leds_cpu == -1)) + return -ENODEV; + + leds_event = ks8695_leds_event; + + leds_event(led_start); + return 0; +} + +__initcall(leds_init); diff -urN -x CVS linux-2.6.24/arch/arm/mach-ks8695/pci.c linux-2.6/arch/arm/mach-ks8695/pci.c --- linux-2.6.24/arch/arm/mach-ks8695/pci.c 1970-01-01 02:00:00.000000000 +0200 +++ linux-2.6/arch/arm/mach-ks8695/pci.c 2008-03-04 22:54:28.000000000 +0200 @@ -0,0 +1,324 @@ +/* + * arch/arm/mach-ks8695/pci.c + * + * Copyright (C) 2003, Micrel Semiconductors + * Copyright (C) 2006, Greg Ungerer + * Copyright (C) 2006, Ben Dooks + * + * 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 + +#include +#include +#include + +#include +#include + + +static int pci_dbg; +static int pci_cfg_dbg; + + +static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where) +{ + unsigned long pbca; + + pbca = PBCA_ENABLE | (where & ~3); + pbca |= PCI_SLOT(devfn) << 11 ; + pbca |= PCI_FUNC(devfn) << 8; + pbca |= bus_nr << 16; + + if (bus_nr == 0) { + /* use Type-0 transaction */ + __raw_writel(pbca, KS8695_PCI_VA + KS8695_PBCA); + } else { + /* use Type-1 transaction */ + __raw_writel(pbca | PBCA_TYPE1, KS8695_PCI_VA + KS8695_PBCA); + } +} + + +/* + * The KS8695 datasheet prohibits anything other than 32bit accesses + * to the IO registers, so all our configuration must be done with + * 32bit operations, and the correct bit masking and shifting. + */ + +static int ks8695_pci_readconfig(struct pci_bus *bus, + unsigned int devfn, int where, int size, u32 *value) +{ + ks8695_pci_setupconfig(bus->number, devfn, where); + + *value = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); + + switch (size) { + case 4: + break; + case 2: + *value = *value >> ((where & 2) * 8); + *value &= 0xffff; + break; + case 1: + *value = *value >> ((where & 3) * 8); + *value &= 0xff; + break; + } + + if (pci_cfg_dbg) { + printk("read: %d,%08x,%02x,%d: %08x (%08x)\n", + bus->number, devfn, where, size, *value, + __raw_readl(KS8695_PCI_VA + KS8695_PBCD)); + } + + return PCIBIOS_SUCCESSFUL; +} + +static int ks8695_pci_writeconfig(struct pci_bus *bus, + unsigned int devfn, int where, int size, u32 value) +{ + unsigned long tmp; + + if (pci_cfg_dbg) { + printk("write: %d,%08x,%02x,%d: %08x\n", + bus->number, devfn, where, size, value); + } + + ks8695_pci_setupconfig(bus->number, devfn, where); + + switch (size) { + case 4: + __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD); + break; + case 2: + tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); + tmp &= ~(0xffff << ((where & 2) * 8)); + tmp |= value << ((where & 2) * 8); + + __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD); + break; + case 1: + tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); + tmp &= ~(0xff << ((where & 3) * 8)); + tmp |= value << ((where & 3) * 8); + + __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static void ks8695_local_writeconfig(int where, u32 value) +{ + ks8695_pci_setupconfig(0, 0, where); + __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD); +} + +static struct pci_ops ks8695_pci_ops = { + .read = ks8695_pci_readconfig, + .write = ks8695_pci_writeconfig, +}; + +static struct pci_bus *ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &ks8695_pci_ops, sys); +} + +static struct resource pci_mem = { + .name = "PCI Memory space", + .start = KS8695_PCIMEM_PA, + .end = KS8695_PCIMEM_PA + (KS8695_PCIMEM_SIZE - 1), + .flags = IORESOURCE_MEM, +}; + +static struct resource pci_io = { + .name = "PCI IO space", + .start = KS8695_PCIIO_PA, + .end = KS8695_PCIIO_PA + (KS8695_PCIIO_SIZE - 1), + .flags = IORESOURCE_IO, +}; + +static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys) +{ + if (nr > 0) + return 0; + + request_resource(&iomem_resource, &pci_mem); + request_resource(&ioport_resource, &pci_io); + + sys->resource[0] = &pci_io; + sys->resource[1] = &pci_mem; + sys->resource[2] = NULL; + + /* Assign and enable processor bridge */ + ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA); + + /* Enable bus-master & Memory Space access */ + ks8695_local_writeconfig(PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + + /* Set cache-line size & latency. */ + ks8695_local_writeconfig(PCI_CACHE_LINE_SIZE, (32 << 8) | (L1_CACHE_BYTES / sizeof(u32))); + + /* Reserve PCI memory space for PCI-AHB resources */ + if (!request_mem_region(KS8695_PCIMEM_PA, SZ_64M, "PCI-AHB Bridge")) { + printk(KERN_ERR "Cannot allocate PCI-AHB Bridge memory.\n"); + return -EBUSY; + } + + return 1; +} + +static inline unsigned int size_mask(unsigned long size) +{ + return (~size) + 1; +} + +static int ks8695_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + unsigned long pc = instruction_pointer(regs); + unsigned long instr = *(unsigned long *)pc; + unsigned long cmdstat; + + cmdstat = __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS); + + printk(KERN_ERR "PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx [%s%s%s%s%s]\n", + addr, fsr, regs->ARM_pc, regs->ARM_lr, + cmdstat & (PCI_STATUS_SIG_TARGET_ABORT << 16) ? "GenTarget" : " ", + cmdstat & (PCI_STATUS_REC_TARGET_ABORT << 16) ? "RecvTarget" : " ", + cmdstat & (PCI_STATUS_REC_MASTER_ABORT << 16) ? "MasterAbort" : " ", + cmdstat & (PCI_STATUS_SIG_SYSTEM_ERROR << 16) ? "SysError" : " ", + cmdstat & (PCI_STATUS_DETECTED_PARITY << 16) ? "Parity" : " " + ); + + __raw_writel(cmdstat, KS8695_PCI_VA + KS8695_CRCFCS); + + /* + * If the instruction being executed was a read, + * make it look like it read all-ones. + */ + if ((instr & 0x0c100000) == 0x04100000) { + int reg = (instr >> 12) & 15; + unsigned long val; + + if (instr & 0x00400000) + val = 255; + else + val = -1; + + regs->uregs[reg] = val; + regs->ARM_pc += 4; + return 0; + } + + if ((instr & 0x0e100090) == 0x00100090) { + int reg = (instr >> 12) & 15; + + regs->uregs[reg] = -1; + regs->ARM_pc += 4; + return 0; + } + + return 1; +} + +static void __init ks8695_pci_preinit(void) +{ + /* stage 1 initialization, subid, subdevice = 0x0001 */ + __raw_writel(0x00010001, KS8695_PCI_VA + KS8695_CRCSID); + + /* stage 2 initialization */ + /* prefetch limits with 16 words, retry enable */ + __raw_writel(0x40000000, KS8695_PCI_VA + KS8695_PBCS); + + /* configure memory mapping */ + __raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBA); + __raw_writel(size_mask(KS8695_PCIMEM_SIZE), KS8695_PCI_VA + KS8695_PMBAM); + __raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBAT); + __raw_writel(0, KS8695_PCI_VA + KS8695_PMBAC); + + /* configure IO mapping */ + __raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBA); + __raw_writel(size_mask(KS8695_PCIIO_SIZE), KS8695_PCI_VA + KS8695_PIOBAM); + __raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBAT); + __raw_writel(0, KS8695_PCI_VA + KS8695_PIOBAC); + + /* hook in fault handlers */ + hook_fault_code(8, ks8695_pci_fault, SIGBUS, "external abort on non-linefetch"); + hook_fault_code(10, ks8695_pci_fault, SIGBUS, "external abort on non-linefetch"); +} + +static void ks8695_show_pciregs(void) +{ + if (!pci_dbg) + return; + + printk(KERN_INFO "PCI: CRCFID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFID)); + printk(KERN_INFO "PCI: CRCFCS = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS)); + printk(KERN_INFO "PCI: CRCFRV = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFRV)); + printk(KERN_INFO "PCI: CRCFLT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFLT)); + printk(KERN_INFO "PCI: CRCBMA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCBMA)); + printk(KERN_INFO "PCI: CRCSID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCSID)); + printk(KERN_INFO "PCI: CRCFIT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFIT)); + + printk(KERN_INFO "PCI: PBM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBM)); + printk(KERN_INFO "PCI: PBCS = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBCS)); + + printk(KERN_INFO "PCI: PMBA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBA)); + printk(KERN_INFO "PCI: PMBAC = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAC)); + printk(KERN_INFO "PCI: PMBAM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAM)); + printk(KERN_INFO "PCI: PMBAT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAT)); + + printk(KERN_INFO "PCI: PIOBA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBA)); + printk(KERN_INFO "PCI: PIOBAC = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAC)); + printk(KERN_INFO "PCI: PIOBAM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAM)); + printk(KERN_INFO "PCI: PIOBAT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAT)); +} + + +static struct hw_pci ks8695_pci __initdata = { + .nr_controllers = 1, + .preinit = ks8695_pci_preinit, + .setup = ks8695_pci_setup, + .scan = ks8695_pci_scan_bus, + .postinit = NULL, + .swizzle = pci_std_swizzle, + .map_irq = NULL, +}; + +void __init ks8695_init_pci(struct ks8695_pci_cfg *cfg) +{ + if (__raw_readl(KS8695_PCI_VA + KS8695_CRCFRV) & CFRV_GUEST) { + printk("PCI: KS8695 in guest mode, not initialising\n"); + return; + } + + printk(KERN_INFO "PCI: Initialising\n"); + ks8695_show_pciregs(); + + /* set Mode */ + __raw_writel(cfg->mode << 29, KS8695_PCI_VA + KS8695_PBM); + + ks8695_pci.map_irq = cfg->map_irq; /* board-specific map_irq method */ + + pci_common_init(&ks8695_pci); +} diff -urN -x CVS linux-2.6.24/drivers/net/arm/Kconfig linux-2.6/drivers/net/arm/Kconfig --- linux-2.6.24/drivers/net/arm/Kconfig 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6/drivers/net/arm/Kconfig 2008-03-04 21:52:40.000000000 +0200 @@ -47,3 +47,10 @@ 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. + +config ARM_KS8695_ETHER + tristate "KS8695 Ethernet support" + depends on NET_ETHERNET && ARM && ARCH_KS8695 + help + If you wish to compile a kernel for an KS8695-based board + and enable Ethernet support, then select this option. diff -urN -x CVS linux-2.6.24/drivers/net/arm/Makefile linux-2.6/drivers/net/arm/Makefile --- linux-2.6.24/drivers/net/arm/Makefile 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6/drivers/net/arm/Makefile 2008-03-04 21:51:41.000000000 +0200 @@ -9,3 +9,4 @@ obj-$(CONFIG_ARM_ETHER1) += ether1.o obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o +obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695_ether.o diff -urN -x CVS linux-2.6.24/drivers/net/arm/ks8695_ether.c linux-2.6/drivers/net/arm/ks8695_ether.c --- linux-2.6.24/drivers/net/arm/ks8695_ether.c 1970-01-01 02:00:00.000000000 +0200 +++ linux-2.6/drivers/net/arm/ks8695_ether.c 2008-03-04 22:46:48.000000000 +0200 @@ -0,0 +1,1010 @@ +/* + * Ethernet driver for the Kendin/Micrel KS8695. + * + * Copyright (C) 2006 Andrew Victor + * + * 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 "ks8695_ether.h" + + +#define DRV_NAME "ks8695_ether" +#define DRV_VERSION "0.01" + +/* ..................................................................... */ + +static inline unsigned long ks8695_read(struct net_device *dev, unsigned int reg) +{ + return __raw_readl(dev->base_addr + reg); +} + +static inline void ks8695_write(struct net_device *dev, unsigned int reg, unsigned long value) +{ + __raw_writel(value, dev->base_addr + reg); +} + + +/* ......................... ADDRESS MANAGEMENT ........................ */ + +#define KS8695_NR_ADDRESSES 16 + +/* + * Add the specified multicast addresses to the Additional Station + * Address registers. + */ +static void ks8695_set_mcast_address(struct net_device *dev, struct dev_mc_list *addr, int nr_addr) +{ + unsigned long low, high; + int i; + + /* Set multicast addresses in Additional Station Address registers */ + for (i = 0; i < nr_addr; i++, addr = addr->next) { + if (!addr) break; /* unexpected end of list */ + else if (i == KS8695_NR_ADDRESSES) break; /* too many addresses */ + + low = (addr->dmi_addr[2] << 24) | (addr->dmi_addr[3] << 16) | (addr->dmi_addr[4] << 8) | (addr->dmi_addr[5]); + high = (addr->dmi_addr[0] << 8) | (addr->dmi_addr[1]); + + ks8695_write(dev, KS8695_WMAAL_(i), low); + ks8695_write(dev, KS8695_WMAAH_(i), WMAAH_E | high); + } + + /* Clear the remaining Additional Station Addresses */ + for (; i < KS8695_NR_ADDRESSES; i++) { + ks8695_write(dev, KS8695_WMAAL_(i), 0); + ks8695_write(dev, KS8695_WMAAH_(i), 0); + } +} + +/* + * Enable/Disable promiscuous and multicast modes. + */ +static void ks8695eth_set_multi(struct net_device *dev) +{ + unsigned long ctrl; + + ctrl = ks8695_read(dev, KS8695_WMDRXC); + + if (dev->flags & IFF_PROMISC) /* enable promiscuous mode */ + ctrl |= WMDRXC_WMRA; + else if (dev->flags & ~IFF_PROMISC) /* disable promiscuous mode */ + ctrl &= ~WMDRXC_WMRA; + + if (dev->flags & IFF_ALLMULTI) /* enable all multicast mode */ + ctrl |= WMDRXC_WMRM; + else if (dev->mc_count > KS8695_NR_ADDRESSES) /* more specific multicast addresses than can be handled in hardware */ + ctrl |= WMDRXC_WMRM; + else if (dev->mc_count > 0) { /* enable specific multicasts */ + ctrl &= ~WMDRXC_WMRM; + ks8695_set_mcast_address(dev, dev->mc_list, dev->mc_count); + } + else if (dev->flags & ~IFF_ALLMULTI) { /* disable multicast mode */ + ctrl &= ~WMDRXC_WMRM; + ks8695_set_mcast_address(dev, NULL, 0); + } + + ks8695_write(dev, KS8695_WMDRXC, ctrl); +} + +/* + * Program the hardware MAC address from dev->dev_addr. + */ +static void update_mac_address(struct net_device *dev) +{ + unsigned long low, high; + + low = (dev->dev_addr[2] << 24) | (dev->dev_addr[3] << 16) | (dev->dev_addr[4] << 8) | (dev->dev_addr[5]); + high = (dev->dev_addr[0] << 8) | (dev->dev_addr[1]); + + ks8695_write(dev, KS8695_WMAL, low); + ks8695_write(dev, KS8695_WMAH, high); +} + +/* + * Store the new hardware address in dev->dev_addr, and update the MAC. + */ +static int ks8695eth_set_mac(struct net_device *dev, void* addr) +{ + struct sockaddr *address = addr; + DECLARE_MAC_BUF(mac); + + if (!is_valid_ether_addr(address->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, address->sa_data, dev->addr_len); + update_mac_address(dev); + + printk("%s: Setting MAC address to %s\n", dev->name, print_mac(mac, dev->dev_addr)); + + return 0; +} + +/* + * Retrieve the MAC address set by the bootloader. + */ +static void __init get_mac_address(struct net_device *dev) +{ + unsigned char addr[6]; + unsigned long low, high; + + low = ks8695_read(dev, KS8695_WMAL); + high = ks8695_read(dev, KS8695_WMAH); + + addr[0] = (high & 0xff00) >> 8; + addr[1] = (high & 0xff); + addr[2] = (low & 0xff000000) >> 24; + addr[3] = (low & 0xff0000) >> 16; + addr[4] = (low & 0xff00) >> 8; + addr[5] = (low & 0xff); + + if (is_valid_ether_addr(addr)) + memcpy(dev->dev_addr, &addr, 6); +} + + +/* ......................... ETHTOOL SUPPORT ........................... */ + +/* + * Get device-specific settings. + */ +static int ks8695eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + unsigned long ctrl; + + /* the defaults for all ports */ + cmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full + | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full + | SUPPORTED_TP | SUPPORTED_MII; + cmd->advertising = ADVERTISED_TP | ADVERTISED_MII; + cmd->port = PORT_MII; + cmd->transceiver = XCVR_INTERNAL; + + if (dev->base_addr == KS8695_HPNA_VA) { + cmd->phy_address = 0; + cmd->autoneg = AUTONEG_DISABLE; /* not supported for HPNA */ + + ctrl = __raw_readl(KS8695_MISC_VA + KS8695_HMC); + cmd->speed = (ctrl & HMC_HSS) ? SPEED_100 : SPEED_10; + cmd->duplex = (ctrl & HMC_HDS) ? DUPLEX_FULL : DUPLEX_HALF; + } + else if (dev->base_addr == KS8695_WAN_VA) { + cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause); + cmd->phy_address = 0; + + ctrl = __raw_readl(KS8695_MISC_VA + KS8695_WMC); + if ((ctrl & WMC_WAND) == 0) { /* auto-negotiation is enabled */ + cmd->advertising |= ADVERTISED_Autoneg; + if (ctrl & WMC_WANA100F) + cmd->advertising |= ADVERTISED_100baseT_Full; + if (ctrl & WMC_WANA100H) + cmd->advertising |= ADVERTISED_100baseT_Half; + if (ctrl & WMC_WANA10F) + cmd->advertising |= ADVERTISED_10baseT_Full; + if (ctrl & WMC_WANA10H) + cmd->advertising |= ADVERTISED_10baseT_Half; + if (ctrl & WMC_WANAP) + cmd->advertising |= ADVERTISED_Pause; + cmd->autoneg = AUTONEG_ENABLE; + + cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10; + cmd->duplex = (ctrl & WMC_WDS) ? DUPLEX_FULL : DUPLEX_HALF; + } + else { /* auto-negotiation is disabled */ + cmd->autoneg = AUTONEG_DISABLE; + + cmd->speed = (ctrl & WMC_WANF100) ? SPEED_100 : SPEED_10; + cmd->duplex = (ctrl & WMC_WANFF) ? DUPLEX_FULL : DUPLEX_HALF; + } + } + else if (dev->base_addr == KS8695_LAN_VA) { + // TODO: Implement for Switch ports + } + + return 0; +} + +/* + * Set device-specific settings. + */ +static int ks8695eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + unsigned long ctrl; + + if ((cmd->speed != SPEED_10) && (cmd->speed != SPEED_100)) + return -EINVAL; + if ((cmd->duplex != DUPLEX_HALF) && (cmd->duplex != DUPLEX_FULL)) + return -EINVAL; + if (cmd->port != PORT_MII) + return -EINVAL; + if (cmd->transceiver != XCVR_INTERNAL) + return -EINVAL; + if ((cmd->autoneg != AUTONEG_DISABLE) && (cmd->autoneg != AUTONEG_ENABLE)) + return -EINVAL; + + if (cmd->autoneg == AUTONEG_ENABLE) { + if ((cmd->advertising & (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full)) == 0) + return -EINVAL; + + if (dev->base_addr == KS8695_HPNA_VA) + return -EINVAL; /* HPNA does not support auto-negotiation. */ + else if (dev->base_addr == KS8695_WAN_VA) { + ctrl = __raw_readl(KS8695_MISC_VA + KS8695_WMC); + + ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H | WMC_WANA10F | WMC_WANA10H); + if (cmd->advertising & ADVERTISED_100baseT_Full) + ctrl |= WMC_WANA100F; + if (cmd->advertising & ADVERTISED_100baseT_Half) + ctrl |= WMC_WANA100H; + if (cmd->advertising & ADVERTISED_10baseT_Full) + ctrl |= WMC_WANA10F; + if (cmd->advertising & ADVERTISED_10baseT_Half) + ctrl |= WMC_WANA10H; + + ctrl |= WMC_WANR; /* force a re-negotiation */ + __raw_writel(ctrl, KS8695_MISC_VA + KS8695_WMC); + } + else if (dev->base_addr == KS8695_LAN_VA) { + // TODO: Implement for Switch ports + } + + } + else { + if (dev->base_addr == KS8695_HPNA_VA) { + ctrl = __raw_readl(KS8695_MISC_VA + KS8695_HMC); + + ctrl &= ~(HMC_HSS | HMC_HDS); + if (cmd->speed == SPEED_100) + ctrl |= HMC_HSS; + if (cmd->duplex == DUPLEX_FULL) + ctrl |= HMC_HDS; + + __raw_writel(ctrl, KS8695_MISC_VA + KS8695_HMC); + } + else if (dev->base_addr == KS8695_WAN_VA) { + ctrl = __raw_readl(KS8695_MISC_VA + KS8695_WMC); + + ctrl |= WMC_WAND; /* disable auto-negotiation */ + ctrl &= ~(WMC_WANF100 | WMC_WANFF); + if (cmd->speed == SPEED_100) + ctrl |= WMC_WANF100; + if (cmd->duplex == DUPLEX_FULL) + ctrl |= WMC_WANFF; + + __raw_writel(ctrl, KS8695_MISC_VA + KS8695_WMC); + } + else if (dev->base_addr == KS8695_LAN_VA) { + // TODO: Implement for Switch ports + } + } + + return 0; +} + +/* + * Restart the auto-negotiation. + */ +static int ks8695eth_nwayreset(struct net_device *dev) +{ + unsigned long ctrl; + + if (dev->base_addr == KS8695_HPNA_VA) /* HPNA has no auto-negotiation */ + return -EINVAL; + else if (dev->base_addr == KS8695_WAN_VA) { + ctrl = __raw_readl(KS8695_MISC_VA + KS8695_WMC); + + if ((ctrl & WMC_WAND) == 0) + __raw_writel(ctrl | WMC_WANR, KS8695_MISC_VA + KS8695_WMC); + else + return -EINVAL; /* auto-negitiation not enabled */ + } + else if (dev->base_addr == KS8695_LAN_VA) { + // TODO: Implement for Switch ports + } + + return 0; +} + +static void ks8695eth_get_pause(struct net_device *dev, struct ethtool_pauseparam *param) +{ + unsigned long ctrl; + + if (dev->base_addr == KS8695_HPNA_VA) + return; + else if (dev->base_addr == KS8695_WAN_VA) { + ctrl = __raw_readl(KS8695_MISC_VA + KS8695_WMC); /* advertise Pause */ + param->autoneg = (ctrl & WMC_WANAP); + + ctrl = ks8695_read(dev, KS8695_WMDRXC); /* current Tx Flow-control */ + param->rx_pause = (ctrl & WMDRXC_WMRFCE); + + ctrl = ks8695_read(dev, KS8695_WMDRXC); /* current Rx Flow-control */ + param->tx_pause = (ctrl & WMDTXC_WMTFCE); + } + else if (dev->base_addr == KS8695_LAN_VA) { + // TODO: Implement for Switch ports + } +} + +static int ks8695eth_set_pause(struct net_device *dev, struct ethtool_pauseparam *param) +{ + // TODO. + + return 0; +} + +static u32 ks8695eth_get_link(struct net_device *dev) +{ + unsigned long ctrl; + + if (dev->base_addr == KS8695_HPNA_VA) + return 1; /* HPNA always has link */ + else if (dev->base_addr == KS8695_WAN_VA) { + ctrl = __raw_readl(KS8695_MISC_VA + KS8695_WMC); + return (ctrl & WMC_WLS); + } + else if (dev->base_addr == KS8695_LAN_VA) { + // TODO: Implement for Switch ports + } + + return 0; +} + +/* + * Report driver information. + */ +static void ks8695eth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); + strlcpy(info->version, DRV_VERSION, sizeof(info->version)); + strlcpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info)); +} + +static struct ethtool_ops ks8695eth_ethtool_ops = { + .get_settings = ks8695eth_get_settings, + .set_settings = ks8695eth_set_settings, + .get_drvinfo = ks8695eth_get_drvinfo, + .nway_reset = ks8695eth_nwayreset, + .get_pauseparam = ks8695eth_get_pause, + .set_pauseparam = ks8695eth_set_pause, + .get_link = ks8695eth_get_link, +}; + + +/* ................................ MAC ................................ */ + +/* + * Setup the RX DMA descriptors, and enable and start the DMA receiver. + */ +static void ks8695eth_start_rx(struct net_device *dev) +{ + struct ks8695eth_priv *lp = (struct ks8695eth_priv *) dev->priv; + unsigned long ctrl; + int i; + + /* Setup the DMA descriptors */ + for (i = 0; i < MAX_RX_DESC; i++) { + lp->rxdma[i].length = MAX_RXBUF_SIZE; + lp->rxdma[i].addr = (unsigned long) lp->rxSkb[i].dma; + lp->rxdma[i].next = (unsigned long) lp->rxdma_phys + (sizeof(struct rx_descriptor) * (i+1)); + lp->rxdma[i].status = RDES_OWN; + } + + /* Create ring of DMA descriptors */ + lp->rxdma[MAX_RX_DESC-1].next = (unsigned long) lp->rxdma_phys; /* phys address of 1st descriptor */ + + /* Reset receive index (since hardware was reset) */ + lp->rx_idx = 0; + + /* Program address of 1st descriptor in KS8695 */ + ks8695_write(dev, KS8695_WRDLB, (unsigned long) lp->rxdma_phys); + + /* Enable and start the DMA Receiver */ + ctrl = ks8695_read(dev, KS8695_WMDRXC); + ks8695_write(dev, KS8695_WMDRXC, ctrl | WMDRXC_WMRE); + ks8695_write(dev, KS8695_WMDRSC, 0); +} + +/* + * Stop the DMA receiver. + */ +static void ks8695eth_stop_rx(struct net_device *dev) +{ + unsigned long ctrl; + + /* Disable receive DMA */ + ctrl = ks8695_read(dev, KS8695_WMDRXC); + ks8695_write(dev, KS8695_WMDRXC, ctrl & ~WMDRXC_WMRE); +} + +/* + * Setup the TX DMA descriptors, and enable DMA transmitter. + */ +static void ks8695eth_start_tx(struct net_device *dev) +{ + struct ks8695eth_priv *lp = (struct ks8695eth_priv *) dev->priv; + unsigned long ctrl; + int i; + + /* Setup the DMA descriptors */ + for (i = 0; i < MAX_TX_DESC; i++) { + lp->txdma[i].ownership = 0; + lp->txdma[i].status = 0; + lp->txdma[i].addr = 0; + lp->txdma[i].next = (unsigned long) lp->txdma_phys + (sizeof(struct tx_descriptor) * (i+1)); + } + + /* Create ring of DMA descriptors */ + lp->txdma[MAX_TX_DESC-1].next = (unsigned long) lp->txdma_phys; /* phys address of 1st desc */ + + /* Reset transmit indexes (since hardware was reset) */ + lp->tx_head = 0; + lp->tx_tail = 0; + + /* Program address of 1st descriptor in KS8695 */ + ks8695_write(dev, KS8695_WTDLB, (unsigned long) lp->txdma_phys); + + /* Enable the DMA transmitter (will be started on first packet) */ + ctrl = ks8695_read(dev, KS8695_WMDTXC); + ks8695_write(dev, KS8695_WMDTXC, ctrl | WMDTXC_WMTE); +} + +/* + * Stop the DMA transmitter. + */ +static void ks8695eth_stop_tx(struct net_device *dev) +{ + struct ks8695eth_priv *lp = (struct ks8695eth_priv *) dev->priv; + unsigned long ctrl; + int i; + + /* Disable transmit DMA */ + ctrl = ks8695_read(dev, KS8695_WMDTXC); + ks8695_write(dev, KS8695_WMDTXC, ctrl & ~WMDTXC_WMTE); + + /* Clear any pending skb's still on transmit queue */ + for (i = 0; i < MAX_TX_DESC; i++) { + lp->txdma[i].ownership = 0; + lp->txdma[i].status = 0; + lp->txdma[i].addr = 0; + + if (lp->txSkb[i].skb) { + dma_unmap_single(lp->dev, lp->txSkb[i].dma, lp->txSkb[i].length, DMA_TO_DEVICE); + dev_kfree_skb_irq(lp->txSkb[i].skb); + lp->txSkb[i].skb = NULL; + } + } +} + +/* + * Reset the MAC hardware. + */ +static void ks8695eth_hw_reset(struct net_device *dev) +{ + /* Perform hardware reset */ + ks8695_write(dev, KS8695_WMDTXC, WMDTXC_WMTRST); + while (ks8695_read(dev, KS8695_WMDTXC) & WMDTXC_WMTRST) { barrier(); } + + /* Initialize the hardware */ + ks8695_write(dev, KS8695_WMDRXC, WMDRXC_WMRU | WMDRXC_WMRB); /* RX: receive Unicast & Broadcast */ + ks8695_write(dev, KS8695_WMDTXC, WMDTXC_WMTEP | WMDTXC_WMTAC); /* TX: add Padding & CRC */ + + // TODO: Can set Rx/Tx PBL: (Micrel using 8) + // TODO: Enable hardware checksumming. + // TODO: Enable Rx/Tx flow-control +} + +/* + * Enable or Disable the IRQs associated with a network interface. + */ +static void ks8695eth_set_irq(struct net_device *dev, short enable) +{ + struct ks8695eth_priv *lp = (struct ks8695eth_priv *) dev->priv; + int i; + + for (i = 0; i < NR_IRQS; i++) { + if (lp->irqs & (1 << i)) { + if (enable) + enable_irq(i); + else + disable_irq(i); + } + } +} + +/* + * Open the ethernet interface. + */ +static int ks8695eth_open(struct net_device *dev) +{ + if (!is_valid_ether_addr(dev->dev_addr)) + return -EADDRNOTAVAIL; + + /* MUST reset hardware in _open() */ + ks8695eth_hw_reset(dev); + + /* Update the MAC address (incase user has changed it) */ + update_mac_address(dev); + + /* Start DMA */ + ks8695eth_start_tx(dev); + ks8695eth_start_rx(dev); + + /* Enable interrupts */ + ks8695eth_set_irq(dev, 1); + + netif_start_queue(dev); + return 0; +} + +/* + * Close the ethernet interface. + */ +static int ks8695eth_close(struct net_device *dev) +{ + /* Stop DMA */ + ks8695eth_stop_rx(dev); + ks8695eth_stop_tx(dev); + + /* Disable interrupts */ + ks8695eth_set_irq(dev, 0); + + netif_stop_queue(dev); + return 0; +} + +/* + * Return the current statistics. + */ +static struct net_device_stats *ks8695eth_stats(struct net_device *dev) +{ + struct ks8695eth_priv *adap = (struct ks8695eth_priv *) dev->priv; + + return &adap->stats; +} + +/* + * Queue a packet for transmission in next TX DMA descriptor. + */ +static int ks8695eth_xmit_frame(struct sk_buff *skb, struct net_device *dev) +{ + struct ks8695eth_priv *lp = (struct ks8695eth_priv *) dev->priv; + int i; + + /* Packets are added to head of array */ + i = lp->tx_head; + + /* Store packet information */ + lp->txSkb[i].skb = skb; + lp->txSkb[i].length = skb->len; + lp->txSkb[i].dma = dma_map_single(lp->dev, skb->data, skb->len, DMA_TO_DEVICE); + + spin_lock_irq(&lp->tx_lock); + + /* Set Tx descriptor information */ + lp->txdma[i].addr = lp->txSkb[i].dma; + lp->txdma[i].status = TDES_IC | TDES_FS | TDES_LS | (lp->txSkb[i].length & TDES_TBS); + lp->txdma[i].ownership = TDES_OWN; + + /* Start the DMA transmitter (if necessary) */ + ks8695_write(dev, KS8695_WMDTSC, 0); + + lp->tx_head = (lp->tx_head + 1) % MAX_TX_DESC; + if (lp->tx_head == lp->tx_tail) /* no more descriptors */ + netif_stop_queue(dev); + + spin_unlock_irq(&lp->tx_lock); + + dev->trans_start = jiffies; + return 0; +} + +/* ..................................................................... */ + +/* + * The link state of the WAN port has changed. + * (Called from interrupt context) + */ +static void ks8695eth_wan_link(struct net_device *dev) +{ + unsigned long ctrl; + + ctrl = __raw_readl(KS8695_MISC_VA + KS8695_WMC); + if (ctrl & WMC_WLS) { + netif_carrier_on(dev); + printk(KERN_INFO "%s: Link is now %s-%s\n", dev->name, + (ctrl & WMC_WSS) ? "100" : "10", + (ctrl & WMC_WDS) ? "FullDuplex" : "HalfDuplex"); + } + else { + netif_carrier_off(dev); + printk(KERN_INFO "%s: Link down.\n", dev->name); + } +} + +/* ..................................................................... */ + +/* + * A frame has been received. Exteract from buffer descriptor and deliver to + * upper layers. + * (Called from interrupt context) + */ +static void ks8695eth_rx_interrupt(struct net_device *dev) +{ + struct ks8695eth_priv *lp = (struct ks8695eth_priv *) dev->priv; + struct sk_buff *skb; + unsigned long flags; + unsigned int pktlen; + + while (!(lp->rxdma[lp->rx_idx].status & RDES_OWN)) { + flags = lp->rxdma[lp->rx_idx].status; + + if ((flags & (RDES_FS | RDES_LS)) != (RDES_FS | RDES_LS)) { + printk(KERN_ERR "%s: Spanning packet detected\n", dev->name); + goto rx_complete; + } + + /* handle errors */ + if (flags & (RDES_ES | RDES_RE)) { + lp->stats.rx_errors++; + + if (flags & RDES_TL) /* Frame too long */ + lp->stats.rx_length_errors++; + else if (flags & RDES_RF) /* Runt frame */ + lp->stats.rx_length_errors++; + else if (flags & RDES_CE) /* CRC error */ + lp->stats.rx_crc_errors++; + else if (flags & RDES_RE) /* MII error */ + lp->stats.rx_missed_errors++; + // TODO: If hardware checksumming, then check IP/TCP/UDP errors. + + goto rx_complete; + } + + pktlen = flags & RDES_FLEN; + pktlen = pktlen - 4; /* remove CRC */ + + // OLD CALL: consistent_sync(lp->rxSkb[lp->rx_idx].skb->data, MAX_RXBUF_SIZE, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(lp->dev, lp->rxSkb[lp->rx_idx].dma, MAX_RXBUF_SIZE, DMA_FROM_DEVICE); + + skb = dev_alloc_skb(pktlen+2); /* +2 to align IP header */ + if (!skb) { + lp->stats.rx_dropped++; + printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); + goto rx_complete; + } + + skb_reserve(skb, 2); /* align IP header */ + memcpy(skb_put(skb, pktlen), lp->rxSkb[lp->rx_idx].skb->data, pktlen); + + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + + /* update statistics */ + lp->stats.rx_packets++; + lp->stats.rx_bytes += pktlen; + if (flags & RDES_MF) + lp->stats.multicast++; + dev->last_rx = jiffies; + +rx_complete: + lp->rxdma[lp->rx_idx].status = RDES_OWN; /* reset ownership bit */ + + lp->rx_idx = (lp->rx_idx + 1) % MAX_RX_DESC; /* next descriptor */ + } + + /* restart DMA receiver incase it was suspended */ + ks8695_write(dev, KS8695_WMDRSC, 0); +} + +/* + * A packet has been transmitted. + * (Called from interrupt context) + */ +static void ks8695eth_tx_interrupt(struct net_device *dev) +{ + struct ks8695eth_priv *lp = (struct ks8695eth_priv *) dev->priv; + int i; + + /* Packets are removed from tail of array */ + i = lp->tx_tail; + + // TODO: Loop through multiple times? + + if (lp->txSkb[i].skb) { + /* update statistics */ + lp->stats.tx_packets++; + lp->stats.tx_bytes += lp->txSkb[i].length; + + /* free packet */ + dma_unmap_single(lp->dev, lp->txSkb[i].dma, lp->txSkb[i].length, DMA_TO_DEVICE); + dev_kfree_skb_irq(lp->txSkb[i].skb); + lp->txSkb[i].skb = NULL; + + /* Not necessary to clear descriptor since we still own it */ + } + + lp->tx_tail = (lp->tx_tail + 1) % MAX_TX_DESC; + + netif_wake_queue(dev); +} + +/* + * MAC interrupt handler + */ +static irqreturn_t ks8695eth_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = (struct net_device *) dev_id; + + switch (irq) { + case KS8695_IRQ_LAN_RX_STATUS: + case KS8695_IRQ_HPNA_RX_STATUS: + case KS8695_IRQ_WAN_RX_STATUS: + ks8695eth_rx_interrupt(dev); + return IRQ_HANDLED; + + case KS8695_IRQ_LAN_TX_STATUS: + case KS8695_IRQ_HPNA_TX_STATUS: + case KS8695_IRQ_WAN_TX_STATUS: + ks8695eth_tx_interrupt(dev); + return IRQ_HANDLED; + + case KS8695_IRQ_WAN_LINK: + ks8695eth_wan_link(dev); + return IRQ_HANDLED; + + default: + return IRQ_NONE; + } +} + + +/* ..................................................................... */ + +/* + * Initialize the WAN hardware to known defaults. + */ +static void __init ks8695eth_init_wan(void) +{ + unsigned long ctrl; + + /* Support auto-negotiation */ + ctrl = WMC_WANAP | WMC_WANA100F | WMC_WANA100H | WMC_WANA10F | WMC_WANA10H; + + /* LED0 = Activity , LED1 = Link */ + ctrl |= (WLED0S_ACTIVITY | WLED1S_LINK); + + /* Restart Auto-negotiation */ + ctrl |= WMC_WANR; + + __raw_writel(ctrl, KS8695_MISC_VA + KS8695_WMC); + + __raw_writel(0, KS8695_MISC_VA + KS8695_WPPM); + __raw_writel(0, KS8695_MISC_VA + KS8695_PPS); +} + +/* + * Initialize the LAN Switch hardware to known defaults. + */ +static void __init ks8695eth_init_switch(void) +{ + unsigned long ctrl; + + ctrl = 0x40819e00; /* default */ + + /* LED0 = Speed LED1 = Link/Activity */ + ctrl &= ~(SEC0_LLED1S | SEC0_LLED0S); + ctrl |= (LLED0S_LINK | LLED1S_LINK_ACTIVITY); + + /* Enable Switch */ + ctrl |= SEC0_ENABLE; + + __raw_writel(ctrl, KS8695_SWITCH_VA + KS8695_SEC0); + + __raw_writel(0x9400100, KS8695_SWITCH_VA + KS8695_SEC1); /* reset defaults */ +} + +static int ks8695eth_hook_irqs(struct platform_device *pdev, struct net_device *dev, unsigned long *irqset) +{ + struct resource *res; + int i = 0, ret; + + while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) { + set_irq_flags(res->start, IRQF_VALID | IRQF_NOAUTOEN); + + ret = request_irq(res->start, ks8695eth_interrupt, IRQF_DISABLED | IRQF_SHARED, res->name, dev); + if (ret) { + printk(KERN_ERR "%s: return_irq %u failed\n", dev->name, res->start); + return -EBUSY; + } + + *irqset |= (1 << res->start); + + // TODO: Can set different priorities for interrupts [0x BB AA FF]. + + i++; + } + + return 0; +} + +static int __init ks8695eth_probe(struct platform_device *pdev) +{ + struct net_device *dev; + struct ks8695eth_priv *lp; + struct resource *res; + int i = 0, ret, size; + DECLARE_MAC_BUF(mac); + + /* Create ethernet device */ + dev = alloc_etherdev(sizeof(struct ks8695eth_priv)); + if (!dev) + return -ENOMEM; + + /* Get I/O base address */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + free_netdev(dev); + return -ENODEV; + } + dev->base_addr = res->start; + + lp = (struct ks8695eth_priv *) dev->priv; + + /* Retreive MAC address before the MAC registers are reset */ + get_mac_address(dev); + + /* Reset the hardware */ + ks8695_write(dev, KS8695_WMDTXC, WMDTXC_WMTRST); + while (ks8695_read(dev, KS8695_WMDTXC) & WMDTXC_WMTRST) { barrier(); } + + /* Get IRQ's */ + dev->irq = platform_get_irq(pdev, 0); + ret = ks8695eth_hook_irqs(pdev, dev, &lp->irqs); + if (ret) { + // Cleanup. + } + + /* Allocate DMA-able memory for Tx descriptor */ + size = sizeof(struct tx_descriptor) * MAX_TX_DESC; + lp->txdma = dma_alloc_coherent(&pdev->dev, size, &lp->txdma_phys, GFP_KERNEL); + if (lp->txdma == NULL) { + // free IRQs + free_netdev(dev); + return -ENOMEM; + } + memset(lp->txdma, 0, size); + lp->tx_head = 0; + lp->tx_tail = 0; + + /* Allocate DMA-able memory for Rx descriptor */ + size = sizeof(struct rx_descriptor) * MAX_RX_DESC; + lp->rxdma = dma_alloc_coherent(&pdev->dev, size, &lp->rxdma_phys, GFP_KERNEL); + if (lp->rxdma == NULL) { + // free IRQs + // Free TX descriptor memory. + free_netdev(dev); + return -ENOMEM; + } + memset(lp->rxdma, 0, size); + lp->rx_idx = 0; + + /* Allocate DMA-able memory for Rx Data */ + for (i = 0; i < MAX_RX_DESC; i++) { + lp->rxSkb[i].skb = alloc_skb(MAX_RXBUF_SIZE, GFP_KERNEL); + if (lp->rxSkb[i].skb == NULL) { + // Cleanup + return -ENOMEM; + } + lp->rxSkb[i].length = MAX_RXBUF_SIZE; + lp->rxSkb[i].dma = dma_map_single(&pdev->dev, lp->rxSkb[i].skb->data, MAX_RXBUF_SIZE, DMA_FROM_DEVICE); + } + + spin_lock_init(&lp->tx_lock); + + platform_set_drvdata(pdev, dev); + + ether_setup(dev); + dev->open = ks8695eth_open; + dev->stop = ks8695eth_close; + dev->hard_start_xmit = ks8695eth_xmit_frame; + dev->get_stats = ks8695eth_stats; + dev->set_multicast_list = ks8695eth_set_multi; + dev->set_mac_address = ks8695eth_set_mac; + dev->ethtool_ops = &ks8695eth_ethtool_ops; + + SET_NETDEV_DEV(dev, &pdev->dev); + lp->dev = &pdev->dev; + + if (dev->base_addr == KS8695_WAN_VA) + ks8695eth_init_wan(); + else if (dev->base_addr == KS8695_LAN_VA) + ks8695eth_init_switch(); + + /* Register the network interface */ + ret = register_netdev(dev); + if (ret) { + // free IRQs + free_netdev(dev); +// dma_free_coherent(&pdev->dev, sizeof(struct ks8695_tx_dma), lp->txdma, lp->txdma_phys); +// dma_free_coherent(&pdev->dev, sizeof(struct ks8695_rx_dma), lp->rxdma, lp->rxdma_phys); + return ret; + } + + printk(KERN_INFO "%s: KS8695 ethernet (%s)\n", dev->name, print_mac(mac, dev->dev_addr)); + + return 0; +} + +static int __devexit ks8695eth_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); +// struct ks8695eth_priv *lp = (struct ks8695eth_priv *) dev->priv; + + unregister_netdev(dev); + + // Free IRQ +// dma_free_coherent(&pdev->dev, sizeof(struct ks8695_tx_dma), lp->txdma, lp->txdma_phys); +// dma_free_coherent(&pdev->dev, sizeof(struct ks8695_rx_dma), lp->rxdma, lp->rxdma_phys); + + platform_set_drvdata(pdev, NULL); + free_netdev(dev); + return 0; +} + +static struct platform_driver ks8695ether_driver = { + .probe = ks8695eth_probe, + .remove = __devexit_p(ks8695eth_remove), +// .suspend = +// .resume = + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + + +static int __init ks8695eth_init(void) +{ + return platform_driver_register(&ks8695ether_driver); +} + +static void __exit ks8695eth_exit(void) +{ + platform_driver_unregister(&ks8695ether_driver); +} + +module_init(ks8695eth_init); +module_exit(ks8695eth_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("KS8695 Ethernet driver"); +MODULE_AUTHOR("Andrew Victor"); diff -urN -x CVS linux-2.6.24/drivers/net/arm/ks8695_ether.h linux-2.6/drivers/net/arm/ks8695_ether.h --- linux-2.6.24/drivers/net/arm/ks8695_ether.h 1970-01-01 02:00:00.000000000 +0200 +++ linux-2.6/drivers/net/arm/ks8695_ether.h 2008-03-04 21:46:24.000000000 +0200 @@ -0,0 +1,93 @@ +/* + * Ethernet driver for the Micrel/Kendin KS8695 (Centaur) + * + * (C) 2006 Andrew Victor + * + */ + +#ifndef KS8695_ETHERNET +#define KS8695_ETHERNET + +/* .... Hardware Descriptors ................................................ */ + +struct rx_descriptor { + unsigned long status; + unsigned long length; + unsigned long addr; + unsigned long next; +}; + +#define RDES_OWN (1 << 31) /* Ownership */ +#define RDES_FS (1 << 30) /* First Descriptor */ +#define RDES_LS (1 << 29) /* Last Descriptor */ +#define RDES_IPE (1 << 28) /* IP Checksum error */ +#define RDES_TCPE (1 << 27) /* TCP Checksum error */ +#define RDES_UDPE (1 << 26) /* UDP Checksum error */ +#define RDES_ES (1 << 25) /* Error summary */ +#define RDES_MF (1 << 24) /* Multicast Frame */ +#define RDES_RE (1 << 19) /* MII Error reported */ +#define RDES_TL (1 << 18) /* Frame too Long */ +#define RDES_RF (1 << 17) /* Runt Frame */ +#define RDES_CE (1 << 16) /* CRC error */ +#define RDES_FT (1 << 15) /* Frame Type */ +#define RDES_FLEN (0x7ff) /* Frame Length */ + +#define RDES_RER (1 << 25) /* Receive End of Ring */ +#define RDES_RBS (0x7ff) /* Receive Buffer Size */ + + +struct tx_descriptor { + unsigned long ownership; + unsigned long status; + unsigned long addr; + unsigned long next; +}; + +#define TDES_OWN (1 << 31) /* Ownership */ + +#define TDES_IC (1 << 31) /* Interrupt on Completion */ +#define TDES_FS (1 << 30) /* First Segment */ +#define TDES_LS (1 << 29) /* Last Segment */ +#define TDES_IPCKG (1 << 28) /* IP Checksum generate */ +#define TDES_TCPCKG (1 << 27) /* TCP Checksum generate */ +#define TDES_UDPCKG (1 << 26) /* UDP Checksum generate */ +#define TDES_TER (1 << 25) /* Transmit End of Ring */ +#define TDES_TBS (0x7ff) /* Transmit Buffer Size */ + + +/* .... ..................................................................... */ + +#define MAX_RX_DESC 16 /* number of receive descriptors */ +#define MAX_TX_DESC 8 /* number of transmit descriptors */ +#define MAX_RXBUF_SIZE 0x600 /* 1518 rounded-up */ + +struct ks8695_buffer +{ + struct sk_buff *skb; + dma_addr_t dma; + unsigned long length; +}; + + +struct ks8695eth_priv +{ + struct device *dev; + struct net_device_stats stats; /* statistics */ + unsigned long irqs; /* IRQ bitset */ + + /* Transmit */ + struct tx_descriptor *txdma; /* Tx DMA descriptors */ + dma_addr_t txdma_phys; /* TX DMA descriptors (phys address) */ + unsigned int tx_head; /* descriptor index (add) */ + unsigned int tx_tail; /* descriptor index (remove) */ + spinlock_t tx_lock; + struct ks8695_buffer txSkb[MAX_TX_DESC]; /* packets being transmitted */ + + /* Receive */ + struct rx_descriptor *rxdma; /* Rx DMA descriptors */ + dma_addr_t rxdma_phys; /* Rx DMA descriptors (phys address) */ + unsigned int rx_idx; /* descriptor index */ + struct ks8695_buffer rxSkb[MAX_RX_DESC]; +}; + +#endif diff -urN -x CVS linux-2.6.24/include/asm-arm/arch-ks8695/devices.h linux-2.6/include/asm-arm/arch-ks8695/devices.h --- linux-2.6.24/include/asm-arm/arch-ks8695/devices.h 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6/include/asm-arm/arch-ks8695/devices.h 2007-12-31 10:44:34.000000000 +0200 @@ -18,6 +18,11 @@ extern void __init ks8695_add_device_lan(void); extern void __init ks8695_add_device_hpna(void); + /* LEDs */ +extern short ks8695_leds_cpu; +extern short ks8695_leds_timer; +extern void __init ks8695_init_leds(u8 cpu_led, u8 timer_led); + /* PCI */ #define KS8695_MODE_PCI 0 #define KS8695_MODE_MINIPCI 1 diff -urN -x CVS linux-2.6.24/include/asm-arm/arch-ks8695/regs-gpio.h linux-2.6/include/asm-arm/arch-ks8695/regs-gpio.h --- linux-2.6.24/include/asm-arm/arch-ks8695/regs-gpio.h 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6/include/asm-arm/arch-ks8695/regs-gpio.h 2007-12-31 10:44:34.000000000 +0200 @@ -49,5 +49,7 @@ #define IOPC_TM_FALLING (4) /* Falling Edge Detection */ #define IOPC_TM_EDGE (6) /* Both Edge Detection */ +/* Port Data Register */ +#define IOPD_(x) (1 << (x)) /* Signal Level of GPIO Pin x */ #endif