From fb69129560edbf2fa298af0b74bcd0e6a838170e Mon Sep 17 00:00:00 2001 From: Ash Charles Date: Mon, 18 Oct 2010 11:05:33 +0000 Subject: linux-gumstix-2.6.15 & gumstix_2.6.5-gnalm1: removed outdated recipes * removed two old recipes in the linux kernel with pre-2.6.20 kernel as suggested by Marcin's RFC of 20 Oct 2010. Signed-off-by: Ash Charles Signed-off-by: Khem Raj --- recipes/linux/gumstix-2.6.5-gnalm1-gum0/defconfig | 777 - .../linux-2.6.5-gnalm1.patch | 20991 ------------------- recipes/linux/gumstix_2.6.5-gnalm1-gum0.bb | 30 - .../add_input_randomness_export.patch | 13 - .../linux/linux-gumstix-2.6.15/arch-config.patch | 55 - recipes/linux/linux-gumstix-2.6.15/audio.patch | 454 - .../linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch | 1415 -- .../linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch | 117 - .../linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch | 403 - .../linux/linux-gumstix-2.6.15/board-init.patch | 98 - .../linux-gumstix-2.6.15/bugfix-i2c-include.patch | 12 - .../linux-gumstix-2.6.15/bugfix-mmc-clock.patch | 14 - .../linux-gumstix-2.6.15/bugfix-mtd-onenand.patch | 22 - .../linux-gumstix-2.6.15/bugfix-pxa-audio.patch | 25 - .../linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch | 64 - .../bugfix-pxa-serial-mctrl.patch | 12 - .../linux/linux-gumstix-2.6.15/bugfix-rndis.patch | 14 - .../bugfix-serial-interrupt.patch | 25 - .../bugfix-serial-register-status.patch | 70 - .../linux/linux-gumstix-2.6.15/compact-flash.patch | 171 - .../cpufreq-better-freqs.patch | 53 - .../cpufreq-ondemand-by-default.patch | 42 - .../linux/linux-gumstix-2.6.15/defconfig-gumstix | 995 - recipes/linux/linux-gumstix-2.6.15/defconfig.patch | 766 - .../disable-uncompress-message.patch | 32 - .../linux-gumstix-2.6.15/ethernet-config.patch | 26 - recipes/linux/linux-gumstix-2.6.15/flash.patch | 171 - .../linux/linux-gumstix-2.6.15/gumstix-mmc.patch | 91 - recipes/linux/linux-gumstix-2.6.15/header.patch | 87 - .../linux-gumstix-2.6.15/i2c-gpl-module-fix.patch | 43 - .../kconfig-arch-cleanup.patch | 72 - .../linux/linux-gumstix-2.6.15/kernel-osx.patch | 50 - .../kobject_get_path_export.patch | 13 - .../linux-gumstix-2.6.15/mach-types-fix.patch | 13 - .../linux/linux-gumstix-2.6.15/mmc-version4.patch | 12 - .../modular-init-bluetooth.patch | 106 - .../linux-gumstix-2.6.15/modular-init-smc91x.patch | 171 - .../modular-init-usb-gadget.patch | 105 - recipes/linux/linux-gumstix-2.6.15/proc-gpio.patch | 401 - .../pxa255-gpio-count-bugfix.patch | 13 - .../linux/linux-gumstix-2.6.15/pxa2xx_udc.patch | 57 - .../rmk-2022-2-rtctime-sa110-pxa255-driver.patch | 329 - .../linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch | 34 - .../linux-gumstix-2.6.15/serial-ether-addr.patch | 46 - .../linux-gumstix-2.6.15/smc-ether-addr.patch | 53 - .../linux-gumstix-2.6.15/ucb1400-ac97-audio.patch | 84 - .../linux-gumstix-2.6.15/ucb1400-touchscreen.patch | 704 - recipes/linux/linux-gumstix_2.6.15.bb | 110 - 48 files changed, 29461 deletions(-) delete mode 100644 recipes/linux/gumstix-2.6.5-gnalm1-gum0/defconfig delete mode 100644 recipes/linux/gumstix-2.6.5-gnalm1-gum0/linux-2.6.5-gnalm1.patch delete mode 100644 recipes/linux/gumstix_2.6.5-gnalm1-gum0.bb delete mode 100644 recipes/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/arch-config.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/audio.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/board-init.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bugfix-i2c-include.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bugfix-mmc-clock.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bugfix-mtd-onenand.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-audio.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-serial-mctrl.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bugfix-rndis.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bugfix-serial-interrupt.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/bugfix-serial-register-status.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/compact-flash.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/cpufreq-better-freqs.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/cpufreq-ondemand-by-default.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/defconfig-gumstix delete mode 100644 recipes/linux/linux-gumstix-2.6.15/defconfig.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/disable-uncompress-message.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/ethernet-config.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/flash.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/gumstix-mmc.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/header.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/i2c-gpl-module-fix.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/kconfig-arch-cleanup.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/kernel-osx.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/kobject_get_path_export.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/mach-types-fix.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/mmc-version4.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/modular-init-bluetooth.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/modular-init-smc91x.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/modular-init-usb-gadget.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/proc-gpio.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/pxa255-gpio-count-bugfix.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/pxa2xx_udc.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/rmk-2022-2-rtctime-sa110-pxa255-driver.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/serial-ether-addr.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/smc-ether-addr.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/ucb1400-ac97-audio.patch delete mode 100644 recipes/linux/linux-gumstix-2.6.15/ucb1400-touchscreen.patch delete mode 100644 recipes/linux/linux-gumstix_2.6.15.bb (limited to 'recipes/linux') diff --git a/recipes/linux/gumstix-2.6.5-gnalm1-gum0/defconfig b/recipes/linux/gumstix-2.6.5-gnalm1-gum0/defconfig deleted file mode 100644 index 64020e2cbe..0000000000 --- a/recipes/linux/gumstix-2.6.5-gnalm1-gum0/defconfig +++ /dev/null @@ -1,777 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_STANDALONE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_HOTPLUG is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# System Type -# -# CONFIG_ARCH_ADIFCC is not set -# CONFIG_ARCH_ANAKIN is not set -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -CONFIG_ARCH_PXA=y -# CONFIG_ARCH_EBSA110 is not set -# 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_L7200 is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_SHARK is not set - -# -# CLPS711X/EP721X Implementations -# - -# -# Epxa10db -# - -# -# Footbridge Implementations -# - -# -# IOP3xx Implementation Options -# -# CONFIG_ARCH_IOP310 is not set -# CONFIG_ARCH_IOP321 is not set - -# -# IOP3xx Chipset Features -# - -# -# Intel PXA250/210 Implementations -# -CONFIG_ARCH_GUMSTIK=y -# CONFIG_ARCH_LUBBOCK is not set -# CONFIG_ARCH_PXA_IDP is not set - -# -# SA11x0 Implementations -# - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_XSCALE=y -CONFIG_CPU_32v5=y -CONFIG_CPU_ABRT_EV5T=y -CONFIG_CPU_TLB_V4WBI=y -CONFIG_CPU_MINICACHE=y - -# -# Processor Features -# -# CONFIG_ARM_THUMB is not set -CONFIG_XSCALE_PMU=y - -# -# General setup -# -# CONFIG_ZBOOT_ROM is not set -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CPU_FREQ=y - -# -# At least one math emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -CONFIG_FPE_FASTFPE=y -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -# CONFIG_BINFMT_MISC is not set - -# -# Generic Driver Options -# -CONFIG_PM=y -# CONFIG_PREEMPT is not set -# CONFIG_APM is not set -# CONFIG_ARTHUR is not set -CONFIG_CMDLINE="root=/dev/ram0 console=tty0,115200n8" -CONFIG_ALIGNMENT_TRAP=y - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CONCAT=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -# 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 - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -# 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 -# -CONFIG_MTD_COMPLEX_MAPPINGS=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x00180000 -CONFIG_MTD_PHYSMAP_LEN=0x00280000 -CONFIG_MTD_PHYSMAP_BUSWIDTH=2 -CONFIG_MTD_GUMSTIK=y -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_MTDRAM is not set -CONFIG_MTD_BLKMTD=y - -# -# 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 - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -CONFIG_BLK_DEV_NBD=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=36000 -CONFIG_BLK_DEV_INITRD=y - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_IPV6 is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -CONFIG_IPV6_SCTP__=y -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q 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 -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPPOE is not set -CONFIG_SLIP=y -# CONFIG_SLIP_COMPRESSED is not set -# CONFIG_SLIP_SMART is not set -# CONFIG_SLIP_MODE_SLIP6 is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# Bluetooth support -# -CONFIG_BT=y -CONFIG_BT_L2CAP=y -CONFIG_BT_SCO=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -# CONFIG_BT_BNEP_MC_FILTER is not set -# CONFIG_BT_BNEP_PROTO_FILTER is not set - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_H4=y -# CONFIG_BT_HCIUART_BCSP is not set -# CONFIG_BT_HCIVHCI is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_SCSI is not set - -# -# Fusion MPT device support -# - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -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_TSLIBDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -# CONFIG_SERIO is not set -# CONFIG_SERIO_I8042 is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_QIC02_TAPE 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_GEN_RTC is not set -CONFIG_SA1100_RTC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER 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_ALGOPXA=y - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_ISA is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -CONFIG_I2C_PXA2XX=y -# CONFIG_SCx200_ACB is not set - -# -# Hardware Sensors Chip support -# -# CONFIG_I2C_SENSOR is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM75 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_LM90 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set - -# -# Other I2C Chip support -# -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# MMC/SD Card support -# -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_BLOCK=y -CONFIG_MMC_PXA=y - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -# CONFIG_EXT2_FS_POSIX_ACL is not set -# CONFIG_EXT2_FS_SECURITY is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_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=y -CONFIG_VFAT_FS=y -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS_XATTR=y -# CONFIG_DEVPTS_FS_SECURITY is not set -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# 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=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_FS_NAND is not set -CONFIG_CRAMFS=y -# 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 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -# CONFIG_EXPORTFS is not set -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 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_INTERMEZZO_FS is not set -# CONFIG_AFS_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=y -# CONFIG_LDM_DEBUG is not set -# CONFIG_NEC98_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 is not set -# 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_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 - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# -# CONFIG_MCP is not set - -# -# Console Switches -# -# CONFIG_SWITCHES is not set - -# -# USB support -# - -# -# USB Gadget Support -# -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_NET2280 is not set -CONFIG_USB_GADGET_PXA2XX=y -CONFIG_USB_PXA2XX=y -CONFIG_USB_PXA2XX_SMALL=y -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_SA1100 is not set -# CONFIG_USB_GADGET_DUALSPEED is not set -# CONFIG_USB_ZERO is not set -CONFIG_USB_ETH=y -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FILE_STORAGE is not set -# CONFIG_USB_G_SERIAL is not set - -# -# Kernel hacking -# -CONFIG_FRAME_POINTER=y -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_KERNEL is not set - -# -# Security options -# -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_CRC32=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/recipes/linux/gumstix-2.6.5-gnalm1-gum0/linux-2.6.5-gnalm1.patch b/recipes/linux/gumstix-2.6.5-gnalm1-gum0/linux-2.6.5-gnalm1.patch deleted file mode 100644 index 4da2b88285..0000000000 --- a/recipes/linux/gumstix-2.6.5-gnalm1-gum0/linux-2.6.5-gnalm1.patch +++ /dev/null @@ -1,20991 +0,0 @@ ---- linux-2.6.5/kernel/printk.c~heh 2004-04-03 22:38:24.000000000 -0500 -+++ linux-2.6.5/kernel/printk.c 2004-04-30 20:57:36.000000000 -0400 -@@ -832,3 +832,25 @@ - printk_ratelimit_burst); - } - EXPORT_SYMBOL(printk_ratelimit); -+ -+#include -+ -+static void -+show_msg_info(int key, struct pt_regs *regs, struct tty_struct *tty) -+{ -+ call_console_drivers(log_end - logged_chars, log_end); -+} -+ -+static struct sysrq_key_op msg_info_op = { -+ .handler = show_msg_info, -+ .help_msg = "Dumpmsgs", -+ .action_msg = "Kernel Messages", -+}; -+ -+static int __init dbg_init(void) -+{ -+ register_sysrq_key('d', &msg_info_op); -+ return 0; -+} -+ -+__initcall(dbg_init); ---- linux-2.6.5/kernel/resource.c~heh 2004-04-03 22:37:36.000000000 -0500 -+++ linux-2.6.5/kernel/resource.c 2004-04-30 20:57:36.000000000 -0400 -@@ -179,6 +179,8 @@ - { - struct resource *tmp, **p; - -+ BUG_ON(old->child); -+ - p = &old->parent->child; - for (;;) { - tmp = *p; -@@ -409,6 +411,47 @@ - EXPORT_SYMBOL(adjust_resource); - - /* -+ * Given an existing resource, change its start and size to match the -+ * arguments. Returns -EBUSY if it can't fit. Existing children of -+ * the resource are assumed to be immutable. -+ */ -+int reallocate_resource(struct resource *res, unsigned long start, unsigned long size) -+{ -+ struct resource *tmp, *parent = res->parent; -+ unsigned long end = start + size - 1; -+ int result = -EBUSY; -+ -+ write_lock(&resource_lock); -+ -+ if ((start < parent->start) || (end > parent->end)) -+ goto out; -+ -+ for (tmp = res->child; tmp; tmp = tmp->sibling) { -+ if ((tmp->start < start) || (tmp->end > end)) -+ goto out; -+ } -+ -+ if (res->sibling && (res->sibling->start <= end)) -+ goto out; -+ -+ tmp = parent->child; -+ if (tmp != res) { -+ while (tmp->sibling != res) -+ tmp = tmp->sibling; -+ if (start <= tmp->end) -+ goto out; -+ } -+ -+ res->start = start; -+ res->end = end; -+ result = 0; -+ -+ out: -+ write_unlock(&resource_lock); -+ return result; -+} -+ -+/* - * This is compatibility stuff for IO resources. - * - * Note how this, unlike the above, knows about ---- linux-2.6.5/include/asm-arm/mach/irq.h~heh 2004-04-03 22:36:54.000000000 -0500 -+++ linux-2.6.5/include/asm-arm/mach/irq.h 2004-04-30 20:57:36.000000000 -0400 -@@ -14,6 +14,19 @@ - struct pt_regs; - struct seq_file; - -+/* -+ * Architectures are expected to define NR_IRQ_DEVICES and -+ * NR_IRQ_DEVICE_SHIFT if they wish to use dynamic IRQs. -+ */ -+#ifndef NR_IRQ_DEVICES -+#define NR_IRQ_DEVICES 1 -+#endif -+#define NR_IRQ_PER_DEVICE (1 << (NR_IRQ_DEVICE_SHIFT - 1)) -+ -+#define IRQ_DEVICE(i) ((i) >> NR_IRQ_DEVICE_SHIFT) -+#define IRQ_INDEX(i) ((i) & (NR_IRQ_PER_GROUP - 1)) -+#define TO_IRQ(g,i) (((g) << NR_IRQ_DEVICE_SHIFT) + (i)) -+ - typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *); - typedef void (*irq_control_t)(unsigned int); - ---- linux-2.6.5/include/asm-arm/arch-pxa/uncompress.h~heh 2004-04-03 22:36:17.000000000 -0500 -+++ linux-2.6.5/include/asm-arm/arch-pxa/uncompress.h 2004-04-30 20:57:36.000000000 -0400 -@@ -12,6 +12,7 @@ - #define FFUART ((volatile unsigned long *)0x40100000) - #define BTUART ((volatile unsigned long *)0x40200000) - #define STUART ((volatile unsigned long *)0x40700000) -+#define HWUART ((volatile unsigned long *)0x41600000) - - #define UART FFUART - ---- linux-2.6.5/include/asm-arm/arch-pxa/dma.h~heh 2004-04-03 22:38:18.000000000 -0500 -+++ linux-2.6.5/include/asm-arm/arch-pxa/dma.h 2004-04-30 20:57:36.000000000 -0400 -@@ -22,11 +22,11 @@ - * Note: this structure must always be aligned to a 16-byte boundary. - */ - --typedef struct { -- volatile u32 ddadr; /* Points to the next descriptor + flags */ -- volatile u32 dsadr; /* DSADR value for the current transfer */ -- volatile u32 dtadr; /* DTADR value for the current transfer */ -- volatile u32 dcmd; /* DCMD value for the current transfer */ -+typedef struct pxa_dma_desc { -+ u32 ddadr; /* Points to the next descriptor + flags */ -+ u32 dsadr; /* DSADR value for the current transfer */ -+ u32 dtadr; /* DTADR value for the current transfer */ -+ u32 dcmd; /* DCMD value for the current transfer */ - } pxa_dma_desc; - - /* ---- linux-2.6.5/include/asm-arm/arch-pxa/serial.h~heh 2004-04-03 22:37:06.000000000 -0500 -+++ linux-2.6.5/include/asm-arm/arch-pxa/serial.h 2004-04-30 20:57:36.000000000 -0400 -@@ -43,6 +43,15 @@ - io_type: SERIAL_IO_MEM, \ - irq: IRQ_BTUART, \ - flags: STD_COM_FLAGS, \ -+ }, { \ -+ type: PORT_PXA, \ -+ xmit_fifo_size: 64, \ -+ baud_base: BAUD_BASE, \ -+ iomem_base: &HWUART, \ -+ iomem_reg_shift: 2, \ -+ io_type: SERIAL_IO_MEM, \ -+ irq: IRQ_HWUART, \ -+ flags: STD_COM_FLAGS, \ - } - - #define EXTRA_SERIAL_PORT_DEFNS ---- linux-2.6.5/include/asm-arm/arch-pxa/pxa-regs.h~heh 2004-04-03 22:37:36.000000000 -0500 -+++ linux-2.6.5/include/asm-arm/arch-pxa/pxa-regs.h 2004-04-30 20:57:36.000000000 -0400 -@@ -124,26 +124,26 @@ - #define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */ - #define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */ - #define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */ --#define DRCMR15 __REG(0x4000013c) /* Reserved */ --#define DRCMR16 __REG(0x40000140) /* Reserved */ -+#define DRCMR15 __REG(0x4000013c) /* Request to Channel Map Register for NSSP receive Request */ -+#define DRCMR16 __REG(0x40000140) /* Request to Channel Map Register for NSSP transmit Request */ - #define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */ - #define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */ - #define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */ - #define DRCMR20 __REG(0x40000150) /* Request to Channel Map Register for STUART transmit Request */ - #define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC receive Request */ - #define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC transmit Request */ --#define DRCMR23 __REG(0x4000015c) /* Reserved */ --#define DRCMR24 __REG(0x40000160) /* Reserved */ -+#define DRCMR23 __REG(0x4000015c) /* Request to Channel Map Register for ASSP receive Request */ -+#define DRCMR24 __REG(0x40000160) /* Request to Channel Map Register for ASSP transmit Request */ - #define DRCMR25 __REG(0x40000164) /* Request to Channel Map Register for USB endpoint 1 Request */ - #define DRCMR26 __REG(0x40000168) /* Request to Channel Map Register for USB endpoint 2 Request */ - #define DRCMR27 __REG(0x4000016C) /* Request to Channel Map Register for USB endpoint 3 Request */ - #define DRCMR28 __REG(0x40000170) /* Request to Channel Map Register for USB endpoint 4 Request */ --#define DRCMR29 __REG(0x40000174) /* Reserved */ -+#define DRCMR29 __REG(0x40000174) /* Request to Channel Map Register for HWUART receive Request */ - #define DRCMR30 __REG(0x40000178) /* Request to Channel Map Register for USB endpoint 6 Request */ - #define DRCMR31 __REG(0x4000017C) /* Request to Channel Map Register for USB endpoint 7 Request */ - #define DRCMR32 __REG(0x40000180) /* Request to Channel Map Register for USB endpoint 8 Request */ - #define DRCMR33 __REG(0x40000184) /* Request to Channel Map Register for USB endpoint 9 Request */ --#define DRCMR34 __REG(0x40000188) /* Reserved */ -+#define DRCMR34 __REG(0x40000188) /* Request to Channel Map Register for HWUART transmit Request */ - #define DRCMR35 __REG(0x4000018C) /* Request to Channel Map Register for USB endpoint 11 Request */ - #define DRCMR36 __REG(0x40000190) /* Request to Channel Map Register for USB endpoint 12 Request */ - #define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */ -@@ -163,12 +163,16 @@ - #define DRCMRTXPCDR DRCMR12 - #define DRCMRRXSSDR DRCMR13 - #define DRCMRTXSSDR DRCMR14 -+#define DRCMRRXNSSPDR DRCMR15 -+#define DRCMRTXNSSPDR DRCMR16 - #define DRCMRRXICDR DRCMR17 - #define DRCMRTXICDR DRCMR18 - #define DRCMRRXSTRBR DRCMR19 - #define DRCMRTXSTTHR DRCMR20 - #define DRCMRRXMMC DRCMR21 - #define DRCMRTXMMC DRCMR22 -+#define DRCMRRXASSPDR DRCMR23 -+#define DRCMRTXASSPDR DRCMR24 - - #define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */ - #define DRCMR_CHLNUM 0x0f /* mask for Channel Number (read / write) */ -@@ -303,6 +307,22 @@ - #define BTDLL __REG(0x40200000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ - #define BTDLH __REG(0x40200004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ - -+/* Hardware UART (HWUART) */ -+#define HWUART HWRBR -+#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */ -+#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */ -+#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */ -+#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */ -+#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */ -+#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */ -+#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */ -+#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */ -+#define HWMSR __REG(0x41600018) /* Reserved */ -+#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */ -+#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */ -+#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */ -+#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */ -+ - /* Standard UART (STUART) */ - #define STUART STRBR - #define STRBR __REG(0x40700000) /* Receive Buffer Register (read only) */ -@@ -1078,6 +1098,111 @@ - - - /* -+ * NSSP Serial Port Registers (Network SSP) -+ */ -+ -+#define NSSCR0 __REG(0x41400000) /* NSSP Control Register 0 */ -+#define NSSCR1 __REG(0x41400004) /* NSSP Control Register 1 */ -+#define NSSSR __REG(0x41400008) /* NSSP Status Register */ -+#define NSSITR __REG(0x4140000C) /* NSSP Interrupt Test Register */ -+#define NSSDR __REG(0x41400010) /* (Write / Read) NSSP Data Write Register/NSSP Data Read Register */ -+#define NSSTO __REG(0x41400028) /* NSSP Time Out Register */ -+#define NSSPSP __REG(0x4140002C) /* NSSP Programable Serial Port Register*/ -+ -+ -+/* -+ * ASSP Serial Port Registers (Audio SSP) -+ */ -+ -+#define ASSCR0 __REG(0x41500000) /* ASSP Control Register 0 */ -+#define ASSCR1 __REG(0x41500004) /* ASSP Control Register 1 */ -+#define ASSSR __REG(0x41500008) /* ASSP Status Register */ -+#define ASSITR __REG(0x4150000C) /* ASSP Interrupt Test Register */ -+#define ASSDR __REG(0x41500010) /* (Write / Read) ASSP Data Write Register/ASSP Data Read Register */ -+#define ASSTO __REG(0x41500028) /* ASSP Time Out Register */ -+#define ASSPSP __REG(0x4150002C) /* ASSP Programable Serial Port Register*/ -+ -+ -+/* -+ * Bit definitions for SSP, NSSP and ASSP registers -+ * - note that some bits are only available on the NSSP and ASSP -+ */ -+ -+#define SSCR0_EDSS (1 << 20) /* ext. data size select */ -+#define SSCR0_SCR_MASK 0x000fff00 /* [19:8] secrial clock rate */ -+#define SSCR0_SCR(x) (((x)<<8) & XSSCR0_SCR_MASK) -+#define SSCR0_SSE (1 << 7) /* sync ser port enable */ -+#define SSCR0_FRF_MASK 0x00000030 /* [5:4] frame format */ -+#define SSCR0_FRF(x) (((x)<<4) & XSSCR0_FRF_MASK) -+#define SSCR0_FRF_SPI 0x00000000 /* ser peripheral i/f */ -+#define SSCR0_FRF_TISSP 0x00000010 /* TI sync ser port */ -+#define SSCR0_FRF_MICROWAVE 0x00000020 /* microwire */ -+#define SSCR0_FRF_PSP 0x00000030 /* prog ser protocol */ -+#define SSCR0_DSS_MASK 0x0000000f /* data size select */ -+#define SSCR0_DSS(x) ((x) & XSSCR0_DSS_MASK) -+ -+#define SSCR1_TTELP (1 << 31) /* tx hi-z later phase */ -+#define SSCR1_TTE (1 << 30) /* tx hi-z enable */ -+#define SSCR1_EBCEI (1 << 29) /* bit count error int mask */ -+#define SSCR1_SCFR (1 << 28) /* slave clock free running */ -+#define SSCR1_SCLKDIR (1 << 25) /* ssp clock direction */ -+#define SSCR1_SFRMDIR (1 << 24) /* ssp frame direction */ -+#define SSCR1_RWOT (1 << 23) /* rx without transmit */ -+#define SSCR1_TSRE (1 << 21) /* tx req enable */ -+#define SSCR1_RSRE (1 << 20) /* rx req enable */ -+#define SSCR1_TINTE (1 << 19) /* timeout int enable */ -+#define SSCR1_STRF (1 << 15) /* select fifo for efwr */ -+#define SSCR1_EFWR (1 << 14) /* fifo write/read enable */ -+#define SSCR1_RFT_MASK 0x00003c00 /* [13:10] rx fifo threshold */ -+#define SSCR1_RFT(x) (((x)<<10) & XSSCR1_RFT_MASK) -+#define SSCR1_TFT_MASK 0x000003c0 /* [9:6] tx fifo threshold */ -+#define SSCR1_TFT(x) (((x)<<6) & XSSCR1_TFT_MASK) -+#define SSCR1_MWDS (1 << 5) /* microwire tx data size */ -+#define SSCR1_SPH (1 << 4) /* SPI SSPSCLK phase */ -+#define SSCR1_SPO (1 << 3) /* motorolla SPI polarity */ -+#define SSCR1_LBM (1 << 2) /* loop-back mode */ -+#define SSCR1_TIE (1 << 1) /* tx fifo int enable */ -+#define SSCR1_RIE (1 << 0) /* rx fifo int enable */ -+ -+#define SSPSP_DMYSTOP_MASK 0x01800000 /* [24:23] dummy stop */ -+#define SSPSP_DMYSTOP(x) (((x)<<23) & XSSPSP_DMYSTOP_MASK) -+#define SSPSP_SFRMWDTH_MASK 0x007f0000 /* [22:16] serial frame width */ -+#define SSPSP_SFRMWDTH(x) (((x)<<16) & XSSPSP_SFRMWDTH_MASK) -+#define SSPSP_SFRMDLY_MASK 0x0000fe00 /* [15:9] serial frame delay */ -+#define SSPSP_SFRMDLY(x) (((x)<<9) & XSSPSP_SFRMDLY_MASK) -+#define SSPSP_DMYSTRT_MASK 0x00000180 /* [8:7] dummy start */ -+#define SSPSP_DMYSTRT(x) (((x)<<7) & XSSPSP_DMYSTRT_MASK) -+#define SSPSP_STRTDLY_MASK 0x00000070 /* [6:4] three-bit start delay */ -+#define SSPSP_STRTDLY(x) (((x)<<4) & XSSPSP_STRTDLY_MASK) -+#define SSPSP_ETDS (1 << 3) /* end of tx data state */ -+#define SSPSP_SFRMP (1 << 2) /* serial frame polarity */ -+#define SSPSP_SCMODE_MASK 0x00000003 /* bit-rate clock mode */ -+#define SSPSP_SCMODE(x) ((x) & XSSPSP_SCMODE_MASK) -+ -+#define SSTO_TIMEOUT_MASK 0x00ffffff /* [23:0] timeout */ -+#define SSTO_TIMEOUT(x) ((x) & XSSTO_TIMEOUT_MASK) -+ -+#define SSITR_TROR (1 << 7) /* test rx fifo overrun */ -+#define SSITR_TRFS (1 << 6) /* test rx fifo serv req */ -+#define SSITR_TTFS (1 << 5) /* test tx fifo serv req */ -+ -+#define SSSR_BCE (1 << 23) /* bit count error */ -+#define SSSR_CSS (1 << 22) /* clock sync stat */ -+#define SSSR_TUR (1 << 21) /* tx fifo underrun */ -+#define SSSR_TINT (1 << 19) /* rx timeout int */ -+#define SSSR_RFL_MASK 0x0000f000 /* rx fifo level */ -+#define SSSR_RFL(x) (((x)<<16) & XSSSR_RFL_MASK) -+#define SSSR_TFL_MASK 0x00000f00 /* tx fifo level */ -+#define SSSR_TFL(x) (((x)<<8) & XSSSR_TFL_MASK) -+#define SSSR_ROR (1 << 7) /* rx fifo overrun */ -+#define SSSR_RFS (1 << 6) /* rx fifo serv request */ -+#define SSSR_TFS (1 << 5) /* tx fifo serv req */ -+#define SSSR_BSY (1 << 4) /* SSP busy */ -+#define SSSR_RNE (1 << 3) /* rx fifo not empty */ -+#define SSSR_TNF (1 << 2) /* tx fifo not full */ -+ -+ -+/* - * MultiMediaCard (MMC) controller - */ - -@@ -1122,6 +1247,7 @@ - #define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */ - #define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */ - #define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */ -+#define CKEN4_HWUART (1 << 4) /* HWUART Unit Clock Enable */ - #define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */ - #define CKEN2_AC97 (1 << 2) /* AC97 Unit Clock Enable */ - #define CKEN1_PWM1 (1 << 1) /* PWM1 Clock Enable */ ---- linux-2.6.5/include/asm-arm/page.h~heh 2004-04-03 22:36:25.000000000 -0500 -+++ linux-2.6.5/include/asm-arm/page.h 2004-04-30 20:57:36.000000000 -0400 -@@ -92,6 +92,14 @@ - # endif - #endif - -+#ifdef CONFIG_CPU_COPY_V6 -+# ifdef _USER -+# define MULTI_USER 1 -+# else -+# define _USER v6 -+# endif -+#endif -+ - #ifndef _USER - #error Unknown user operations model - #endif ---- linux-2.6.5/include/asm-arm/thread_info.h~heh 2004-04-03 22:37:06.000000000 -0500 -+++ linux-2.6.5/include/asm-arm/thread_info.h 2004-04-30 20:57:36.000000000 -0400 -@@ -108,8 +108,8 @@ - #define TI_CPU 20 - #define TI_CPU_DOMAIN 24 - #define TI_CPU_SAVE 28 --#define TI_USED_MATH 76 --#define TI_FPSTATE (TI_USED_MATH+16) -+#define TI_USED_CP 76 -+#define TI_FPSTATE (TI_USED_CP+16) - - #endif - ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/asm-arm/rtc.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,45 @@ -+/* -+ * linux/include/asm-arm/rtc.h -+ * -+ * Copyright (C) 2003 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 version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef ASMARM_RTC_H -+#define ASMARM_RTC_H -+ -+struct module; -+ -+struct rtc_ops { -+ struct module *owner; -+ int (*open)(void); -+ void (*release)(void); -+ int (*ioctl)(unsigned int, unsigned long); -+ -+ void (*read_time)(struct rtc_time *); -+ int (*set_time)(struct rtc_time *); -+ void (*read_alarm)(struct rtc_wkalrm *); -+ int (*set_alarm)(struct rtc_wkalrm *); -+ int (*proc)(char *buf); -+}; -+ -+void rtc_time_to_tm(unsigned long, struct rtc_time *); -+int rtc_tm_to_time(struct rtc_time *, unsigned long *); -+void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *); -+void rtc_update(unsigned long, unsigned long); -+int register_rtc(struct rtc_ops *); -+void unregister_rtc(struct rtc_ops *); -+ -+static inline int rtc_periodic_alarm(struct rtc_time *tm) -+{ -+ return (tm->tm_year == -1) || -+ ((unsigned)tm->tm_mon >= 12) || -+ ((unsigned)(tm->tm_mday - 1) >= 31) || -+ ((unsigned)tm->tm_hour > 23) || -+ ((unsigned)tm->tm_min > 59) || -+ ((unsigned)tm->tm_sec > 59); -+} -+ -+#endif ---- linux-2.6.5/include/linux/serial.h~heh 2004-04-03 22:36:26.000000000 -0500 -+++ linux-2.6.5/include/linux/serial.h 2004-04-30 20:57:36.000000000 -0400 -@@ -81,17 +81,6 @@ - #define SERIAL_IO_HUB6 1 - #define SERIAL_IO_MEM 2 - --struct serial_uart_config { -- char *name; -- int dfl_xmit_fifo_size; -- int flags; --}; -- --#define UART_CLEAR_FIFO 0x01 --#define UART_USE_FIFO 0x02 --#define UART_STARTECH 0x04 --#define UART_NATSEMI 0x08 -- - /* - * Definitions for async_struct (and serial_struct) flags field - */ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/linux/i2c-pxa.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,76 @@ -+/* -+ * i2c_pxa.h -+ * -+ * Copyright (C) 2002 Intrinsyc Software Inc. -+ * -+ * 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. -+ * -+ */ -+#ifndef _I2C_PXA_H_ -+#define _I2C_PXA_H_ -+ -+struct i2c_algo_pxa_data -+{ -+ void (*write_byte) (u8 value); -+ u8 (*read_byte) (void); -+ void (*start) (void); -+ void (*repeat_start) (void); -+ void (*stop) (void); -+ void (*abort) (void); -+ int (*wait_bus_not_busy) (void); -+ int (*wait_for_interrupt) (int wait_type); -+ void (*transfer) (int lastbyte, int receive, int midbyte); -+ void (*reset) (void); -+ -+ int udelay; -+ int timeout; -+}; -+ -+#define DEF_TIMEOUT 3 -+#define BUS_ERROR (-EREMOTEIO) -+#define ACK_DELAY 0 /* time to delay before checking bus error */ -+#define MAX_MESSAGES 65536 /* maximum number of messages to send */ -+ -+#define I2C_SLEEP_TIMEOUT 2 /* time to sleep for on i2c transactions */ -+#define I2C_RETRY (-2000) /* an error has occurred retry transmit */ -+#define I2C_TRANSMIT 1 -+#define I2C_RECEIVE 0 -+#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */ -+#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) /* ICR initialization value */ -+/* ICR initialize bit values -+* -+* 15. FM 0 (100 Khz operation) -+* 14. UR 0 (No unit reset) -+* 13. SADIE 0 (Disables the unit from interrupting on slave addresses -+* matching its slave address) -+* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration -+* in master mode) -+* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode) -+* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent) -+* 9. IRFIE 1 (Enable interrupts from full buffer received) -+* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty) -+* 7. GCD 1 (Disables i2c unit response to general call messages as a slave) -+* 6. IUE 0 (Disable unit until we change settings) -+* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL) -+* 4. MA 0 (Only send stop with the ICR stop bit) -+* 3. TB 0 (We are not transmitting a byte initially) -+* 2. ACKNAK 0 (Send an ACK after the unit receives a byte) -+* 1. STOP 0 (Do not send a STOP) -+* 0. START 0 (Do not send a START) -+* -+*/ -+ -+#define I2C_ISR_INIT 0x7FF /* status register init */ -+/* I2C status register init values -+ * -+ * 10. BED 1 (Clear bus error detected) -+ * 9. SAD 1 (Clear slave address detected) -+ * 7. IRF 1 (Clear IDBR Receive Full) -+ * 6. ITE 1 (Clear IDBR Transmit Empty) -+ * 5. ALD 1 (Clear Arbitration Loss Detected) -+ * 4. SSD 1 (Clear Slave Stop Detected) -+ */ -+ -+#endif ---- linux-2.6.5/include/linux/ioport.h~heh 2004-04-03 22:36:26.000000000 -0500 -+++ linux-2.6.5/include/linux/ioport.h 2004-04-30 20:57:36.000000000 -0400 -@@ -99,6 +99,7 @@ - void (*alignf)(void *, struct resource *, - unsigned long, unsigned long), - void *alignf_data); -+extern int reallocate_resource(struct resource *res, unsigned long start, unsigned long size); - int adjust_resource(struct resource *res, unsigned long start, - unsigned long size); - ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/linux/switches.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,74 @@ -+/* -+ * linux/include/linux/switches.h -+ * -+ * Copyright (C) 2000 John Dorsey -+ * -+ * 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. -+ * -+ * 23 October 2000 - created. -+ */ -+ -+#if !defined(_LINUX_SWITCHES_H) -+#define _LINUX_SWITCHES_H -+ -+#define SWITCHES_MASK_SIZE (128) -+ -+typedef unsigned long switches_bitfield; -+ -+#define SWITCHES_BITS (sizeof(switches_bitfield) * 8) -+#define SWITCHES_NUM_FIELDS (SWITCHES_MASK_SIZE / SWITCHES_BITS) -+#define SWITCHES_FIELD_SELECT(i) ((i) / SWITCHES_BITS) -+#define SWITCHES_FIELD_MASK(i) ((switches_bitfield)(1 << (i) % \ -+ SWITCHES_BITS)) -+ -+typedef struct switches_mask_t { -+ unsigned int count; -+ switches_bitfield events[SWITCHES_NUM_FIELDS]; -+ switches_bitfield states[SWITCHES_NUM_FIELDS]; -+} switches_mask_t; -+ -+#define SWITCHES_ZERO(m) \ -+do { \ -+ unsigned int sz_i; \ -+ (m)->count = 0; \ -+ for(sz_i = 0; sz_i < SWITCHES_NUM_FIELDS; ++sz_i) \ -+ (m)->events[sz_i] = (m)->states[sz_i] = 0; \ -+} while (0) -+ -+/* `s' is the state of the switch, either 0 or non-zero: */ -+#define SWITCHES_SET(m, i, s) \ -+do { \ -+ ((m)->events[SWITCHES_FIELD_SELECT((i))] |= \ -+ SWITCHES_FIELD_MASK((i))); \ -+ if(s) \ -+ ((m)->states[SWITCHES_FIELD_SELECT((i))] |= \ -+ SWITCHES_FIELD_MASK((i))); \ -+ else \ -+ ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \ -+ ~SWITCHES_FIELD_MASK((i))); \ -+ ++((m)->count); \ -+} while (0) -+ -+/* Should only use to clear an event set by SWITCHES_SET(): */ -+#define SWITCHES_CLEAR(m, i) \ -+do { \ -+ ((m)->events[SWITCHES_FIELD_SELECT((i))] &= \ -+ ~SWITCHES_FIELD_MASK((i))); \ -+ ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \ -+ ~SWITCHES_FIELD_MASK((i))); \ -+ --((m)->count); \ -+} -+ -+#define SWITCHES_COUNT(m) ((m)->count) -+ -+/* Returns 0 or non-zero: */ -+#define SWITCHES_EVENT(m, i) \ -+((m)->events[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i))) -+ -+/* Returns 0 or non-zero: */ -+#define SWITCHES_STATE(m, i) \ -+((m)->states[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i))) -+ -+#endif /* !defined(_LINUX_SWITCHES_H) */ ---- linux-2.6.5/include/linux/serial_reg.h~heh 2004-04-03 22:37:38.000000000 -0500 -+++ linux-2.6.5/include/linux/serial_reg.h 2004-04-30 20:57:36.000000000 -0400 -@@ -121,6 +121,7 @@ - /* - * These are the definitions for the Modem Control Register - */ -+#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C750) */ - #define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ - #define UART_MCR_OUT2 0x08 /* Out2 complement */ - #define UART_MCR_OUT1 0x04 /* Out1 complement */ -@@ -156,6 +157,21 @@ - #define UART_FCR_PXAR32 0xc0 /* receive FIFO treshold = 32 */ - - /* -+ * The Intel PXA2xx chip defines those bits -+ */ -+#define UART_IER_DMAE 0x80 /* DMA Requests Enable */ -+#define UART_IER_UUE 0x40 /* UART Unit Enable */ -+#define UART_IER_NRZE 0x20 /* NRZ coding Enable */ -+#define UART_IER_RTOIE 0x10 /* Receiver Time Out Interrupt Enable */ -+ -+#define UART_IIR_TOD 0x08 /* Character Timeout Indication Detected */ -+ -+#define UART_FCR_PXAR1 0x00 /* receive FIFO treshold = 1 */ -+#define UART_FCR_PXAR8 0x40 /* receive FIFO treshold = 8 */ -+#define UART_FCR_PXAR16 0x80 /* receive FIFO treshold = 16 */ -+#define UART_FCR_PXAR32 0xc0 /* receive FIFO treshold = 32 */ -+ -+/* - * These are the definitions for the Extended Features Register - * (StarTech 16C660 only, when DLAB=1) - */ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/linux/mmc/card.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,83 @@ -+/* -+ * linux/include/linux/mmc/card.h -+ * -+ * 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. -+ * -+ * Card driver specific definitions. -+ */ -+#ifndef LINUX_MMC_CARD_H -+#define LINUX_MMC_CARD_H -+ -+#include -+ -+struct mmc_cid { -+ unsigned int manfid; -+ unsigned int serial; -+ char prod_name[8]; -+ unsigned char hwrev; -+ unsigned char fwrev; -+ unsigned char month; -+ unsigned char year; -+}; -+ -+struct mmc_csd { -+ unsigned char mmc_prot; -+ unsigned short cmdclass; -+ unsigned short tacc_clks; -+ unsigned int tacc_ns; -+ unsigned int max_dtr; -+ unsigned int read_blkbits; -+ unsigned int capacity; -+}; -+ -+struct mmc_host; -+ -+/* -+ * MMC device -+ */ -+struct mmc_card { -+ struct list_head node; /* node in hosts devices list */ -+ struct mmc_host *host; /* the host this device belongs to */ -+ struct device dev; /* the device */ -+ unsigned int rca; /* relative card address of device */ -+ unsigned int state; /* (our) card state */ -+#define MMC_STATE_PRESENT (1<<0) -+#define MMC_STATE_DEAD (1<<1) -+ struct mmc_cid cid; /* card identification */ -+ struct mmc_csd csd; /* card specific */ -+}; -+ -+#define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD) -+#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) -+ -+#define mmc_card_name(c) ((c)->cid.prod_name) -+#define mmc_card_id(c) ((c)->dev.bus_id) -+ -+#define mmc_list_to_card(l) container_of(l, struct mmc_card, node) -+#define mmc_get_drvdata(c) dev_get_drvdata(&(c)->dev) -+#define mmc_set_drvdata(c,d) dev_set_drvdata(&(c)->dev, d) -+ -+/* -+ * MMC device driver (e.g., Flash card, I/O card...) -+ */ -+struct mmc_driver { -+ struct device_driver drv; -+ int (*probe)(struct mmc_card *); -+ void (*remove)(struct mmc_card *); -+ int (*suspend)(struct mmc_card *, u32); -+ int (*resume)(struct mmc_card *); -+}; -+ -+extern int mmc_register_driver(struct mmc_driver *); -+extern void mmc_unregister_driver(struct mmc_driver *); -+ -+static inline int mmc_card_claim_host(struct mmc_card *card) -+{ -+ return __mmc_claim_host(card->host, card); -+} -+ -+#define mmc_card_release_host(c) mmc_release_host((c)->host) -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/linux/mmc/mmc.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,88 @@ -+/* -+ * linux/include/linux/mmc/mmc.h -+ * -+ * 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. -+ */ -+#ifndef MMC_H -+#define MMC_H -+ -+#include -+#include -+#include -+ -+struct request; -+struct mmc_data; -+struct mmc_request; -+ -+struct mmc_command { -+ u32 opcode; -+ u32 arg; -+ u32 resp[4]; -+ unsigned int flags; /* expected response type */ -+#define MMC_RSP_NONE (0 << 0) -+#define MMC_RSP_SHORT (1 << 0) -+#define MMC_RSP_LONG (2 << 0) -+#define MMC_RSP_MASK (3 << 0) -+#define MMC_RSP_CRC (1 << 3) /* expect valid crc */ -+#define MMC_RSP_BUSY (1 << 4) /* card may send busy */ -+ -+ unsigned int retries; /* max number of retries */ -+ unsigned int error; /* command error */ -+ -+#define MMC_ERR_NONE 0 -+#define MMC_ERR_TIMEOUT 1 -+#define MMC_ERR_BADCRC 2 -+#define MMC_ERR_FIFO 3 -+#define MMC_ERR_FAILED 4 -+#define MMC_ERR_INVALID 5 -+ -+ struct mmc_data *data; /* data segment associated with cmd */ -+ struct mmc_request *req; /* assoicated request */ -+}; -+ -+struct mmc_data { -+ unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ -+ unsigned int timeout_clks; /* data timeout (in clocks) */ -+ unsigned int blksz_bits; /* data block size */ -+ unsigned int blocks; /* number of blocks */ -+ struct request *rq; /* request structure */ -+ unsigned int error; /* data error */ -+ unsigned int flags; -+ -+#define MMC_DATA_WRITE (1 << 8) -+#define MMC_DATA_READ (1 << 9) -+#define MMC_DATA_STREAM (1 << 10) -+ -+ unsigned int bytes_xfered; -+ -+ struct mmc_command *stop; /* stop command */ -+ struct mmc_request *req; /* assoicated request */ -+}; -+ -+struct mmc_request { -+ struct mmc_command *cmd; -+ struct mmc_data *data; -+ struct mmc_command *stop; -+ -+ void *done_data; /* completion data */ -+ void (*done)(struct mmc_request *);/* completion function */ -+}; -+ -+struct mmc_host; -+struct mmc_card; -+ -+extern int mmc_wait_for_req(struct mmc_host *, struct mmc_request *); -+extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); -+ -+extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card); -+ -+static inline void mmc_claim_host(struct mmc_host *host) -+{ -+ __mmc_claim_host(host, (struct mmc_card *)-1); -+} -+ -+extern void mmc_release_host(struct mmc_host *host); -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/linux/mmc/host.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,67 @@ -+/* -+ * linux/include/linux/mmc/host.h -+ * -+ * 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. -+ * -+ * Host driver specific definitions. -+ */ -+#ifndef LINUX_MMC_HOST_H -+#define LINUX_MMC_HOST_H -+ -+#include -+ -+struct mmc_ios { -+ unsigned int clock; /* clock rate */ -+ unsigned short vdd; /* supply (units of 10mV) */ -+ unsigned char bus_mode; /* command output mode */ -+ -+#define MMC_BUSMODE_OPENDRAIN 1 -+#define MMC_BUSMODE_PUSHPULL 2 -+ -+ unsigned char power_mode; /* power supply mode */ -+ -+#define MMC_POWER_OFF 0 -+#define MMC_POWER_UP 1 -+#define MMC_POWER_ON 2 -+}; -+ -+struct mmc_host_ops { -+ void (*request)(struct mmc_host *host, struct mmc_request *req); -+ void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); -+}; -+ -+struct mmc_card; -+ -+struct mmc_host { -+ struct device *dev; -+ struct mmc_host_ops *ops; -+ unsigned int f_min; -+ unsigned int f_max; -+ u32 ocr_avail; -+ -+ /* private data */ -+ unsigned int host_num; /* host number */ -+ struct mmc_ios ios; /* current io bus settings */ -+ u32 ocr; /* the current OCR setting */ -+ -+ struct list_head cards; /* devices attached to this host */ -+ -+ wait_queue_head_t wq; -+ spinlock_t lock; /* card_busy lock */ -+ struct mmc_card *card_busy; /* the MMC card claiming host */ -+ struct mmc_card *card_selected; /* the selected MMC card */ -+}; -+ -+extern int mmc_init_host(struct mmc_host *); -+extern int mmc_add_host(struct mmc_host *); -+extern void mmc_remove_host(struct mmc_host *); -+extern int mmc_suspend_host(struct mmc_host *, u32); -+extern int mmc_resume_host(struct mmc_host *); -+ -+extern void mmc_detect_change(struct mmc_host *); -+extern void mmc_request_done(struct mmc_host *, struct mmc_request *); -+ -+#endif -+ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/linux/mmc/protocol.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,203 @@ -+/* -+ * Header for MultiMediaCard (MMC) -+ * -+ * Copyright 2002 Hewlett-Packard Company -+ * -+ * Use consistent with the GNU GPL is permitted, -+ * provided that this copyright notice is -+ * preserved in its entirety in all copies and derived works. -+ * -+ * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, -+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS -+ * FITNESS FOR ANY PARTICULAR PURPOSE. -+ * -+ * Many thanks to Alessandro Rubini and Jonathan Corbet! -+ * -+ * Based strongly on code by: -+ * -+ * Author: Yong-iL Joh -+ * Date : $Date: 2002/06/18 12:37:30 $ -+ * -+ * Author: Andrew Christian -+ * 15 May 2002 -+ */ -+ -+#ifndef MMC_MMC_PROTOCOL_H -+#define MMC_MMC_PROTOCOL_H -+ -+/* Standard MMC commands (3.1) type argument response */ -+ /* class 1 */ -+#define MMC_GO_IDLE_STATE 0 /* bc */ -+#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ -+#define MMC_ALL_SEND_CID 2 /* bcr R2 */ -+#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ -+#define MMC_SET_DSR 4 /* bc [31:16] RCA */ -+#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ -+#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ -+#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ -+#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ -+#define MMC_STOP_TRANSMISSION 12 /* ac R1b */ -+#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ -+#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ -+ -+ /* class 2 */ -+#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ -+#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ -+#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ -+ -+ /* class 3 */ -+#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ -+ -+ /* class 4 */ -+#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ -+#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ -+#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ -+#define MMC_PROGRAM_CID 26 /* adtc R1 */ -+#define MMC_PROGRAM_CSD 27 /* adtc R1 */ -+ -+ /* class 6 */ -+#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ -+#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */ -+#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ -+ -+ /* class 5 */ -+#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ -+#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ -+#define MMC_ERASE 37 /* ac R1b */ -+ -+ /* class 9 */ -+#define MMC_FAST_IO 39 /* ac R4 */ -+#define MMC_GO_IRQ_STATE 40 /* bcr R5 */ -+ -+ /* class 7 */ -+#define MMC_LOCK_UNLOCK 42 /* adtc R1b */ -+ -+ /* class 8 */ -+#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ -+#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */ -+ -+/* -+ MMC status in R1 -+ Type -+ e : error bit -+ s : status bit -+ r : detected and set for the actual command response -+ x : detected and set during command execution. the host must poll -+ the card by sending status command in order to read these bits. -+ Clear condition -+ a : according to the card state -+ b : always related to the previous command. Reception of -+ a valid command will clear it (with a delay of one command) -+ c : clear by read -+ */ -+ -+#define R1_OUT_OF_RANGE (1 << 31) /* er, c */ -+#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ -+#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */ -+#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */ -+#define R1_ERASE_PARAM (1 << 27) /* ex, c */ -+#define R1_WP_VIOLATION (1 << 26) /* erx, c */ -+#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */ -+#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */ -+#define R1_COM_CRC_ERROR (1 << 23) /* er, b */ -+#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */ -+#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */ -+#define R1_CC_ERROR (1 << 20) /* erx, c */ -+#define R1_ERROR (1 << 19) /* erx, c */ -+#define R1_UNDERRUN (1 << 18) /* ex, c */ -+#define R1_OVERRUN (1 << 17) /* ex, c */ -+#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */ -+#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ -+#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ -+#define R1_ERASE_RESET (1 << 13) /* sr, c */ -+#define R1_STATUS(x) (x & 0xFFFFE000) -+#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ -+#define R1_READY_FOR_DATA (1 << 8) /* sx, a */ -+#define R1_APP_CMD (1 << 7) /* sr, c */ -+ -+/* These are unpacked versions of the actual responses */ -+ -+struct _mmc_csd { -+ u8 csd_structure; -+ u8 spec_vers; -+ u8 taac; -+ u8 nsac; -+ u8 tran_speed; -+ u16 ccc; -+ u8 read_bl_len; -+ u8 read_bl_partial; -+ u8 write_blk_misalign; -+ u8 read_blk_misalign; -+ u8 dsr_imp; -+ u16 c_size; -+ u8 vdd_r_curr_min; -+ u8 vdd_r_curr_max; -+ u8 vdd_w_curr_min; -+ u8 vdd_w_curr_max; -+ u8 c_size_mult; -+ union { -+ struct { /* MMC system specification version 3.1 */ -+ u8 erase_grp_size; -+ u8 erase_grp_mult; -+ } v31; -+ struct { /* MMC system specification version 2.2 */ -+ u8 sector_size; -+ u8 erase_grp_size; -+ } v22; -+ } erase; -+ u8 wp_grp_size; -+ u8 wp_grp_enable; -+ u8 default_ecc; -+ u8 r2w_factor; -+ u8 write_bl_len; -+ u8 write_bl_partial; -+ u8 file_format_grp; -+ u8 copy; -+ u8 perm_write_protect; -+ u8 tmp_write_protect; -+ u8 file_format; -+ u8 ecc; -+}; -+ -+#define MMC_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */ -+#define MMC_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */ -+#define MMC_VDD_155_160 0x00000004 /* VDD voltage 1.55 - 1.60 */ -+#define MMC_VDD_160_165 0x00000008 /* VDD voltage 1.60 - 1.65 */ -+#define MMC_VDD_165_170 0x00000010 /* VDD voltage 1.65 - 1.70 */ -+#define MMC_VDD_17_18 0x00000020 /* VDD voltage 1.7 - 1.8 */ -+#define MMC_VDD_18_19 0x00000040 /* VDD voltage 1.8 - 1.9 */ -+#define MMC_VDD_19_20 0x00000080 /* VDD voltage 1.9 - 2.0 */ -+#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ -+#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ -+#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ -+#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ -+#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ -+#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ -+#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ -+#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ -+#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ -+#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ -+#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ -+#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ -+#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ -+#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ -+#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ -+#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ -+#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ -+ -+ -+/* -+ * CSD field definitions -+ */ -+ -+#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */ -+#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */ -+#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 */ -+ -+#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */ -+#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */ -+#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ -+#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */ -+ -+#endif /* MMC_MMC_PROTOCOL_H */ -+ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/linux/l3/algo-bit.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,39 @@ -+/* -+ * linux/include/linux/l3/algo-bit.h -+ * -+ * Copyright (C) 2001 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License. -+ * -+ * L3 Bus bit-banging algorithm. Derived from i2c-algo-bit.h by -+ * Simon G. Vogl. -+ */ -+#ifndef L3_ALGO_BIT_H -+#define L3_ALGO_BIT_H 1 -+ -+#include -+ -+struct l3_algo_bit_data { -+ void (*setdat) (void *data, int state); -+ void (*setclk) (void *data, int state); -+ void (*setmode)(void *data, int state); -+ void (*setdir) (void *data, int in); /* set data direction */ -+ int (*getdat) (void *data); -+ -+ void *data; -+ -+ /* bus timings (us) */ -+ int data_hold; -+ int data_setup; -+ int clock_high; -+ int mode_hold; -+ int mode_setup; -+ int mode; -+}; -+ -+int l3_bit_add_bus(struct l3_adapter *); -+int l3_bit_del_bus(struct l3_adapter *); -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/linux/l3/l3.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,95 @@ -+/* -+ * linux/include/linux/l3/l3.h -+ * -+ * Copyright (C) 2001 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License. -+ * -+ * Derived from i2c.h by Simon G. Vogl -+ */ -+#ifndef L3_H -+#define L3_H -+ -+struct l3_msg { -+ unsigned char addr; /* slave address */ -+ unsigned char flags; -+#define L3_M_RD 0x01 -+#define L3_M_NOADDR 0x02 -+ unsigned short len; /* msg length */ -+ unsigned char *buf; /* pointer to msg data */ -+}; -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+ -+struct l3_adapter; -+ -+struct l3_algorithm { -+ /* textual description */ -+ char name[32]; -+ -+ /* perform bus transactions */ -+ int (*xfer)(struct l3_adapter *, struct l3_msg msgs[], int num); -+}; -+ -+struct semaphore; -+ -+/* -+ * l3_adapter is the structure used to identify a physical L3 bus along -+ * with the access algorithms necessary to access it. -+ */ -+struct l3_adapter { -+ /* -+ * This name is used to uniquely identify the adapter. -+ * It should be the same as the module name. -+ */ -+ char name[32]; -+ -+ /* -+ * the algorithm to access the bus -+ */ -+ struct l3_algorithm *algo; -+ -+ /* -+ * Algorithm specific data -+ */ -+ void *algo_data; -+ -+ /* -+ * This may be NULL, or should point to the module struct -+ */ -+ struct module *owner; -+ -+ /* -+ * private data for the adapter -+ */ -+ void *data; -+ -+ /* -+ * Our lock. Unlike the i2c layer, we allow this to be used for -+ * other stuff, like the i2c layer lock. Some people implement -+ * i2c stuff using the same signals as the l3 bus. -+ */ -+ struct semaphore *lock; -+ -+ /* -+ * List of all adapters. -+ */ -+ struct list_head adapters; -+}; -+ -+extern int l3_add_adapter(struct l3_adapter *); -+extern int l3_del_adapter(struct l3_adapter *); -+extern void l3_put_adapter(struct l3_adapter *); -+extern struct l3_adapter *l3_get_adapter(const char *name); -+ -+extern int l3_write(struct l3_adapter *, int, const char *, int); -+extern int l3_read(struct l3_adapter *, int, char *, int); -+ -+#endif -+ -+#endif /* L3_H */ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/include/linux/l3/uda1341.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,61 @@ -+/* -+ * linux/include/linux/l3/uda1341.h -+ * -+ * Philips UDA1341 mixer device driver -+ * -+ * Copyright (c) 2000 Nicolas Pitre -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License. -+ */ -+ -+#define UDA1341_NAME "uda1341" -+ -+struct uda1341_cfg { -+ unsigned int fs:16; -+ unsigned int format:3; -+}; -+ -+#define FMT_I2S 0 -+#define FMT_LSB16 1 -+#define FMT_LSB18 2 -+#define FMT_LSB20 3 -+#define FMT_MSB 4 -+#define FMT_LSB16MSB 5 -+#define FMT_LSB18MSB 6 -+#define FMT_LSB20MSB 7 -+ -+#define L3_UDA1341_CONFIGURE 0x13410001 -+ -+struct l3_gain { -+ unsigned int left:8; -+ unsigned int right:8; -+ unsigned int unused:8; -+ unsigned int channel:8; -+}; -+ -+#define L3_SET_VOLUME 0x13410002 -+#define L3_SET_TREBLE 0x13410003 -+#define L3_SET_BASS 0x13410004 -+#define L3_SET_GAIN 0x13410005 -+ -+struct l3_agc { -+ unsigned int level:8; -+ unsigned int enable:1; -+ unsigned int attack:7; -+ unsigned int decay:8; -+ unsigned int channel:8; -+}; -+ -+#define L3_INPUT_AGC 0x13410006 -+ -+struct uda1341; -+ -+int uda1341_configure(struct uda1341 *uda, struct uda1341_cfg *conf); -+int uda1341_mixer_ctl(struct uda1341 *uda, int cmd, void *arg); -+int uda1341_open(struct uda1341 *uda); -+void uda1341_close(struct uda1341 *uda); -+ -+struct uda1341 *uda1341_attach(const char *adapter); -+void uda1341_detach(struct uda1341 *uda); -+ ---- linux-2.6.5/include/linux/i2c-id.h~heh 2004-04-03 22:36:16.000000000 -0500 -+++ linux-2.6.5/include/linux/i2c-id.h 2004-04-30 20:57:36.000000000 -0400 -@@ -187,6 +187,7 @@ - #define I2C_ALGO_BITHS 0x130000 /* enhanced bit style adapters */ - #define I2C_ALGO_OCP_IOP3XX 0x140000 /* XSCALE IOP3XX On-chip I2C alg */ - -+#define I2C_ALGO_PXA 0x200000 /* Intel PXA I2C algorithm */ - #define I2C_ALGO_EXP 0x800000 /* experimental */ - - #define I2C_ALGO_MASK 0xff0000 /* Mask for algorithms */ ---- linux-2.6.5/include/linux/serial_core.h~heh 2004-04-03 22:36:18.000000000 -0500 -+++ linux-2.6.5/include/linux/serial_core.h 2004-04-30 20:57:36.000000000 -0400 -@@ -17,7 +17,7 @@ - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -- * $Id: serial_core.h,v 1.49 2002/07/20 18:06:32 rmk Exp $ -+ * $Id: serial_core.h,v 1.53 2002/08/02 12:55:08 rmk Exp $ - */ - - /* -@@ -159,8 +159,6 @@ - spinlock_t lock; /* port lock */ - unsigned int iobase; /* in/out[bwl] */ - char *membase; /* read/write[bwl] */ -- unsigned int irq; /* irq number */ -- unsigned int uartclk; /* base uart clock */ - unsigned char fifosize; /* tx fifo size */ - unsigned char x_char; /* xon/xoff char */ - unsigned char regshift; /* reg offset shift */ -@@ -172,6 +170,7 @@ - - unsigned int read_status_mask; /* driver specific */ - unsigned int ignore_status_mask; /* driver specific */ -+ - struct uart_info *info; /* pointer to parent info */ - struct uart_icount icount; /* statistics */ - -@@ -182,7 +181,6 @@ - - unsigned int flags; - --#define UPF_HUP_NOTIFY (1 << 0) - #define UPF_FOURPORT (1 << 1) - #define UPF_SAK (1 << 2) - #define UPF_SPD_MASK (0x1030) -@@ -212,9 +210,12 @@ - unsigned int timeout; /* character-based timeout */ - unsigned int type; /* port type */ - struct uart_ops *ops; -+ unsigned int uartclk; /* base uart clock */ - unsigned int custom_divisor; -+ unsigned int irq; /* irq number */ - unsigned int line; /* port index */ - unsigned long mapbase; /* for ioremap */ -+ struct device *dev; /* parent device */ - unsigned char hub6; /* this should be in the 8250 driver */ - unsigned char unused[3]; - }; ---- linux-2.6.5/include/linux/vmalloc.h~heh 2004-04-03 22:38:23.000000000 -0500 -+++ linux-2.6.5/include/linux/vmalloc.h 2004-04-30 20:57:36.000000000 -0400 -@@ -35,6 +35,8 @@ - * Lowlevel-APIs (not for driver use!) - */ - extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags); -+extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, -+ unsigned long start, unsigned long end); - extern struct vm_struct *remove_vm_area(void *addr); - extern int map_vm_area(struct vm_struct *area, pgprot_t prot, - struct page ***pages); ---- linux-2.6.5/include/linux/mm.h~heh 2004-04-03 22:36:15.000000000 -0500 -+++ linux-2.6.5/include/linux/mm.h 2004-04-30 20:57:36.000000000 -0400 -@@ -655,5 +655,12 @@ - int in_gate_area(struct task_struct *task, unsigned long addr); - #endif - -+#ifndef __arm__ -+#define memc_update_addr(x,y,z) -+#define memc_update_mm(x) -+#define memc_clear(x,y) -+#endif -+ - #endif /* __KERNEL__ */ - #endif /* _LINUX_MM_H */ -+ ---- linux-2.6.5/init/do_mounts.c~heh 2004-04-03 22:36:56.000000000 -0500 -+++ linux-2.6.5/init/do_mounts.c 2004-04-30 20:57:36.000000000 -0400 -@@ -391,7 +391,7 @@ - root_device_name += 5; - } - -- is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; -+ is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR || MAJOR(ROOT_DEV) == 31; - - if (initrd_load()) - goto out; ---- linux-2.6.5/fs/binfmt_aout.c~heh 2004-04-03 22:36:26.000000000 -0500 -+++ linux-2.6.5/fs/binfmt_aout.c 2004-04-30 20:57:36.000000000 -0400 -@@ -432,7 +432,11 @@ - else - send_sig(SIGTRAP, current, 0); - } -+#ifndef __arm__ - return 0; -+#else -+ return regs->ARM_r0; -+#endif - } - - static int load_aout_library(struct file *file) -@@ -462,8 +466,11 @@ - - /* For QMAGIC, the starting address is 0x20 into the page. We mask - this off to get the starting address for the page */ -- -- start_addr = ex.a_entry & 0xfffff000; -+#ifndef __arm__ -+ start_addr = ex.a_entry & 0xfffff000; -+#else -+ start_addr = ex.a_entry & 0xffff8000; -+#endif - - if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) { - static unsigned long error_time; ---- linux-2.6.5/mm/slab.c~heh 2004-04-03 22:37:41.000000000 -0500 -+++ linux-2.6.5/mm/slab.c 2004-04-30 20:57:36.000000000 -0400 -@@ -2115,12 +2115,12 @@ - * - * Called with disabled ints. - */ --static inline void __cache_free (kmem_cache_t *cachep, void* objp) -+static inline void __cache_free (kmem_cache_t *cachep, void* objp, void *caller) - { - struct array_cache *ac = ac_data(cachep); - - check_irq_off(); -- objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); -+ objp = cache_free_debugcheck(cachep, objp, caller /*__builtin_return_address(0)*/); - - if (likely(ac->avail < ac->limit)) { - STATS_INC_FREEHIT(cachep); -@@ -2289,7 +2289,7 @@ - unsigned long flags; - - local_irq_save(flags); -- __cache_free(cachep, objp); -+ __cache_free(cachep, objp, __builtin_return_address(0)); - local_irq_restore(flags); - } - -@@ -2312,7 +2312,7 @@ - local_irq_save(flags); - kfree_debugcheck(objp); - c = GET_PAGE_CACHE(virt_to_page(objp)); -- __cache_free(c, (void*)objp); -+ __cache_free(c, (void*)objp, __builtin_return_address(0)); - local_irq_restore(flags); - } - ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/Documentation/l3/structure 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,36 @@ -+L3 Bus Driver -+------------- -+ -+The structure of the driver is as follows: -+ -+ +----------+ +----------+ +----------+ -+ | client 1 | | client 2 | | client 3 | -+ +-----^----+ +----^-----+ +----^-----+ -+ | | | -+ +-----v--------------v---------------v-----+ -+ | | -+ +-----^-------+ +-------^-----+ -+ | | core | | -+ +-----v----+ | | +----v-----+ -+ | device | | | | device | -+ | driver 1 | | | | driver 2 | -+ +-----^----+ | | +----^-----+ -+ | | services | | -+ +-----v-------+ +-------v-----+ -+ | | -+ +-----------------^----^-------------------+ -+ | | -+ | +-v---------+ -+ | | algorithm | -+ | | driver | -+ | +-v---------+ -+ | | -+ +-v----v-+ -+ | bus | -+ | driver | -+ +--------+ -+ -+Clients talk to the core to attach device drivers and bus adapters, and -+to instruct device drivers to perform actions. Device drivers then talk -+to the core to perform L3 bus transactions via the algorithm driver and -+ultimately bus driver. ---- linux-2.6.5/arch/arm/kernel/debug.S~heh 2004-04-03 22:36:55.000000000 -0500 -+++ linux-2.6.5/arch/arm/kernel/debug.S 2004-04-30 20:57:36.000000000 -0400 -@@ -192,6 +192,20 @@ - - @ if all ports are inactive, then there is nothing we can do - moveq pc, lr -+ ldr r1, [\rx, #UTCR2] -+ teq r1, #5 -+ movne r1, #0 -+ strne r1, [\rx, #UTCR3] -+ movne r1, #8 -+ strne r1, [\rx, #UTCR0] -+ movne r1, #5 -+ strne r1, [\rx, #UTCR2] -+ movne r1, #0 -+ strne r1, [\rx, #UTCR1] -+ movne r1, #3 -+ strne r1, [\rx, #UTCR3] -+ movne r1, #255 -+ strne r1, [\rx, #UTSR0] - .endm - - .macro senduart,rd,rx -@@ -287,7 +301,7 @@ - - #elif defined(CONFIG_ARCH_INTEGRATOR) - --#include -+#include - - .macro addruart,rx - mrc p15, 0, \rx, c1, c0 -@@ -298,7 +312,7 @@ - .endm - - .macro senduart,rd,rx -- strb \rd, [\rx, #AMBA_UARTDR] -+ strb \rd, [\rx, #UART01x_DR] - .endm - - .macro waituart,rd,rx ---- linux-2.6.5/arch/arm/kernel/entry-armv.S~heh 2004-04-03 22:36:54.000000000 -0500 -+++ linux-2.6.5/arch/arm/kernel/entry-armv.S 2004-04-30 20:57:36.000000000 -0400 -@@ -1181,6 +1181,9 @@ - * get out of that mode without clobbering one register. - */ - vector_FIQ: disable_fiq -+ mrs r13, spsr -+ orr r13, r13, #PSR_F_BIT -+ msr spsr, r13 - subs pc, lr, #4 - - /*============================================================================= ---- linux-2.6.5/arch/arm/kernel/irq.c~heh 2004-04-03 22:36:12.000000000 -0500 -+++ linux-2.6.5/arch/arm/kernel/irq.c 2004-04-30 20:57:36.000000000 -0400 -@@ -47,12 +47,36 @@ - #define MAX_IRQ_CNT 100000 - - static volatile unsigned long irq_err_count; --static spinlock_t irq_controller_lock; - static LIST_HEAD(irq_pending); - - struct irqdesc irq_desc[NR_IRQS]; - void (*init_arch_irq)(void) __initdata = NULL; - -+#if NR_IRQ_DEVICES > 1 -+struct irq_device { -+ spinlock_t lock; -+ int nr_irqs; -+ struct irq_desc *irqs; -+}; -+ -+static struct irq_device irq_devices[NR_IRQ_DEVICES] = { -+ [0] = { -+ .lock = SPIN_LOCK_UNLOCKED, -+ .nr_irqs = NR_IRQS, -+ .irqs = irq_desc, -+ }, -+}; -+#define IRQ_LOCK(irq) (&irq_devices[IRQ_DEVICE(irq)].lock) -+#define IRQ_DESC(irq) (&irq_devices[IRQ_DEVICE(irq)].irqs[IRQ_INDEX(irq)]) -+#define IRQ_VALID(irq) (IRQ_DEVICE(irq) < NR_IRQ_DEVICES && \ -+ IRQ_INDEX(irq) < irq_devices[IRQ_DEVICE(irq)].nr_irqs) -+#else -+static spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED; -+#define IRQ_LOCK(irq) (&irq_controller_lock) -+#define IRQ_DESC(irq) (&irq_desc[irq]) -+#define IRQ_VALID(irq) ((irq) < NR_IRQS) -+#endif -+ - /* - * Dummy mask/unmask handler - */ -@@ -95,13 +119,13 @@ - */ - void disable_irq(unsigned int irq) - { -- struct irqdesc *desc = irq_desc + irq; -+ struct irqdesc *desc = IRQ_DESC(irq); - unsigned long flags; - -- spin_lock_irqsave(&irq_controller_lock, flags); -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); - desc->disable_depth++; - list_del_init(&desc->pend); -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - } - - /** -@@ -116,10 +140,10 @@ - */ - void enable_irq(unsigned int irq) - { -- struct irqdesc *desc = irq_desc + irq; -+ struct irqdesc *desc = IRQ_DESC(irq); - unsigned long flags; - -- spin_lock_irqsave(&irq_controller_lock, flags); -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); - if (unlikely(!desc->disable_depth)) { - printk("enable_irq(%u) unbalanced from %p\n", irq, - __builtin_return_address(0)); -@@ -140,7 +164,7 @@ - list_add(&desc->pend, &irq_pending); - } - } -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - } - - /* -@@ -148,24 +172,24 @@ - */ - void enable_irq_wake(unsigned int irq) - { -- struct irqdesc *desc = irq_desc + irq; -+ struct irqdesc *desc = IRQ_DESC(irq); - unsigned long flags; - -- spin_lock_irqsave(&irq_controller_lock, flags); -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); - if (desc->chip->wake) - desc->chip->wake(irq, 1); -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - } - - void disable_irq_wake(unsigned int irq) - { -- struct irqdesc *desc = irq_desc + irq; -+ struct irqdesc *desc = IRQ_DESC(irq); - unsigned long flags; - -- spin_lock_irqsave(&irq_controller_lock, flags); -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); - if (desc->chip->wake) - desc->chip->wake(irq, 0); -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - } - - int show_interrupts(struct seq_file *p, void *v) -@@ -175,8 +199,8 @@ - unsigned long flags; - - if (i < NR_IRQS) { -- spin_lock_irqsave(&irq_controller_lock, flags); -- action = irq_desc[i].action; -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); -+ action = IRQ_DESC(i)->action; - if (!action) - goto unlock; - -@@ -187,7 +211,7 @@ - - seq_putc(p, '\n'); - unlock: -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - } else if (i == NR_IRQS) { - #ifdef CONFIG_ARCH_ACORN - show_fiq_list(p, v); -@@ -259,7 +283,7 @@ - unsigned int status; - int retval = 0; - -- spin_unlock(&irq_controller_lock); -+ spin_unlock(IRQ_LOCK(irq)); - - if (!(action->flags & SA_INTERRUPT)) - local_irq_enable(); -@@ -274,7 +298,7 @@ - if (status & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - -- spin_lock_irq(&irq_controller_lock); -+ spin_lock_irq(IRQ_LOCK(irq)); - - return retval; - } -@@ -455,7 +479,7 @@ - desc = &bad_irq_desc; - - irq_enter(); -- spin_lock(&irq_controller_lock); -+ spin_lock(IRQ_LOCK(irq)); - desc->handle(irq, desc, regs); - - /* -@@ -464,7 +488,7 @@ - if (!list_empty(&irq_pending)) - do_pending_irqs(regs); - -- spin_unlock(&irq_controller_lock); -+ spin_unlock(IRQ_LOCK(irq)); - irq_exit(); - } - -@@ -473,7 +497,7 @@ - struct irqdesc *desc; - unsigned long flags; - -- if (irq >= NR_IRQS) { -+ if (!IRQ_VALID(irq)) { - printk(KERN_ERR "Trying to install handler for IRQ%d\n", irq); - return; - } -@@ -481,12 +505,12 @@ - if (handle == NULL) - handle = do_bad_IRQ; - -- desc = irq_desc + irq; -+ desc = IRQ_DESC(irq); - - if (is_chained && desc->chip == &bad_chip) - printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq); - -- spin_lock_irqsave(&irq_controller_lock, flags); -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); - if (handle == do_bad_IRQ) { - desc->chip->mask(irq); - desc->chip->ack(irq); -@@ -499,7 +523,7 @@ - desc->disable_depth = 0; - desc->chip->unmask(irq); - } -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - } - - void set_irq_chip(unsigned int irq, struct irqchip *chip) -@@ -507,7 +531,7 @@ - struct irqdesc *desc; - unsigned long flags; - -- if (irq >= NR_IRQS) { -+ if (!IRQ_VALID(irq)) { - printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq); - return; - } -@@ -515,10 +539,10 @@ - if (chip == NULL) - chip = &bad_chip; - -- desc = irq_desc + irq; -- spin_lock_irqsave(&irq_controller_lock, flags); -+ desc = IRQ_DESC(irq); -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); - desc->chip = chip; -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - } - - int set_irq_type(unsigned int irq, unsigned int type) -@@ -527,16 +551,21 @@ - unsigned long flags; - int ret = -ENXIO; - -- if (irq >= NR_IRQS) { -+ if (!IRQ_VALID(irq)) { - printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq); - return -ENODEV; - } - -- desc = irq_desc + irq; -+ desc = IRQ_DESC(irq); -+ if (!desc->action && desc->handle != do_bad_IRQ) { -+ printk(KERN_ERR "Setting type of unclaimed IRQ%d from ", irq); -+ print_symbol("%s\n", (unsigned long)__builtin_return_address(0)); -+ } -+ - if (desc->chip->type) { -- spin_lock_irqsave(&irq_controller_lock, flags); -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); - ret = desc->chip->type(irq, type); -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - } - - return ret; -@@ -547,17 +576,17 @@ - struct irqdesc *desc; - unsigned long flags; - -- if (irq >= NR_IRQS) { -+ if (!IRQ_VALID(irq)) { - printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq); - return; - } - -- desc = irq_desc + irq; -- spin_lock_irqsave(&irq_controller_lock, flags); -+ desc = IRQ_DESC(irq); -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); - desc->valid = (iflags & IRQF_VALID) != 0; - desc->probe_ok = (iflags & IRQF_PROBE) != 0; - desc->noautoenable = (iflags & IRQF_NOAUTOEN) != 0; -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - } - - int setup_irq(unsigned int irq, struct irqaction *new) -@@ -587,13 +616,13 @@ - /* - * The following block of code has to be executed atomically - */ -- desc = irq_desc + irq; -- spin_lock_irqsave(&irq_controller_lock, flags); -+ desc = IRQ_DESC(irq); -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); - p = &desc->action; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) { -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - return -EBUSY; - } - -@@ -618,7 +647,7 @@ - } - } - -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - return 0; - } - -@@ -659,7 +688,7 @@ - unsigned long retval; - struct irqaction *action; - -- if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler || -+ if (!IRQ_VALID(irq) || !IRQ_DESC(irq)->valid || !handler || - (irq_flags & SA_SHIRQ && !dev_id)) - return -EINVAL; - -@@ -700,14 +729,14 @@ - struct irqaction * action, **p; - unsigned long flags; - -- if (irq >= NR_IRQS || !irq_desc[irq].valid) { -+ if (!IRQ_VALID(irq) || !IRQ_DESC(irq)->valid) { - printk(KERN_ERR "Trying to free IRQ%d\n",irq); - dump_stack(); - return; - } - -- spin_lock_irqsave(&irq_controller_lock, flags); -- for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) { -+ spin_lock_irqsave(IRQ_LOCK(irq), flags); -+ for (p = &IRQ_DESC(irq)->action; (action = *p) != NULL; p = &action->next) { - if (action->dev_id != dev_id) - continue; - -@@ -715,7 +744,7 @@ - *p = action->next; - break; - } -- spin_unlock_irqrestore(&irq_controller_lock, flags); -+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags); - - if (!action) { - printk(KERN_ERR "Trying to free free IRQ%d\n",irq); -@@ -747,19 +776,18 @@ - * first snaffle up any unassigned but - * probe-able interrupts - */ -- spin_lock_irq(&irq_controller_lock); - for (i = 0; i < NR_IRQS; i++) { -- if (!irq_desc[i].probe_ok || irq_desc[i].action) -- continue; -- -- irq_desc[i].probing = 1; -- irq_desc[i].triggered = 0; -- if (irq_desc[i].chip->type) -- irq_desc[i].chip->type(i, IRQT_PROBE); -- irq_desc[i].chip->unmask(i); -- irqs += 1; -+ spin_lock_irq(IRQ_LOCK(i)); -+ if (irq_desc[i].probe_ok && !irq_desc[i].action) { -+ irq_desc[i].probing = 1; -+ irq_desc[i].triggered = 0; -+ if (irq_desc[i].chip->type) -+ irq_desc[i].chip->type(i, IRQT_PROBE); -+ irq_desc[i].chip->unmask(i); -+ irqs += 1; -+ } -+ spin_unlock_irq(IRQ_LOCK(i)); - } -- spin_unlock_irq(&irq_controller_lock); - - /* - * wait for spurious interrupts to mask themselves out again -@@ -770,14 +798,14 @@ - /* - * now filter out any obviously spurious interrupts - */ -- spin_lock_irq(&irq_controller_lock); - for (i = 0; i < NR_IRQS; i++) { -+ spin_lock_irq(IRQ_LOCK(i)); - if (irq_desc[i].probing && irq_desc[i].triggered) { - irq_desc[i].probing = 0; - irqs -= 1; - } -+ spin_unlock_irq(IRQ_LOCK(i)); - } -- spin_unlock_irq(&irq_controller_lock); - - return irqs; - } -@@ -788,11 +816,13 @@ - { - unsigned int mask = 0, i; - -- spin_lock_irq(&irq_controller_lock); -- for (i = 0; i < 16 && i < NR_IRQS; i++) -- if (irq_desc[i].probing && irq_desc[i].triggered) -+ for (i = 0; i < 16 && i < NR_IRQS; i++) { -+ struct irqdesc *desc = IRQ_DESC(i); -+ spin_lock_irq(IRQ_LOCK(i)); -+ if (desc->probing && desc->triggered) - mask |= 1 << i; -- spin_unlock_irq(&irq_controller_lock); -+ spin_unlock_irq(IRQ_LOCK(i)); -+ } - - up(&probe_sem); - -@@ -813,23 +843,21 @@ - * look at the interrupts, and find exactly one - * that we were probing has been triggered - */ -- spin_lock_irq(&irq_controller_lock); - for (i = 0; i < NR_IRQS; i++) { -- if (irq_desc[i].probing && -- irq_desc[i].triggered) { -+ struct irqdesc *desc = IRQ_DESC(i); -+ -+ spin_lock_irq(IRQ_LOCK(i)); -+ if (desc->probing && desc->triggered) { - if (irq_found != NO_IRQ) { -+ spin_unlock_irq(IRQ_LOCK(i)); - irq_found = NO_IRQ; -- goto out; -+ break; - } - irq_found = i; - } -+ spin_unlock_irq(IRQ_LOCK(i)); - } - -- if (irq_found == -1) -- irq_found = NO_IRQ; --out: -- spin_unlock_irq(&irq_controller_lock); -- - up(&probe_sem); - - return irq_found; ---- linux-2.6.5/arch/arm/kernel/bios32.c~heh 2004-04-03 22:36:56.000000000 -0500 -+++ linux-2.6.5/arch/arm/kernel/bios32.c 2004-04-30 20:57:36.000000000 -0400 -@@ -565,8 +565,6 @@ - if (hw->postinit) - hw->postinit(); - -- pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq); -- - list_for_each_entry(sys, &hw->buses, node) { - struct pci_bus *bus = sys->bus; - -@@ -581,6 +579,11 @@ - pci_bus_assign_resources(bus); - - /* -+ * Fixup IRQs. -+ */ -+ pci_bus_fixup_irqs(bus, pcibios_swizzle, pcibios_map_irq); -+ -+ /* - * Tell drivers about devices found. - */ - pci_bus_add_devices(bus); ---- linux-2.6.5/arch/arm/kernel/traps.c~heh 2004-04-03 22:36:57.000000000 -0500 -+++ linux-2.6.5/arch/arm/kernel/traps.c 2004-04-30 20:57:36.000000000 -0400 -@@ -206,33 +206,43 @@ - c_backtrace(fp, 0x10); - } - --spinlock_t die_lock = SPIN_LOCK_UNLOCKED; -- --/* -- * This function is protected against re-entrancy. -- */ --NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) -+static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs) - { -- struct task_struct *tsk = current; -+ struct task_struct *tsk = thread->task; - static int die_counter; - -- console_verbose(); -- spin_lock_irq(&die_lock); -- bust_spinlocks(1); -- - printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter); - print_modules(); - printk("CPU: %d\n", smp_processor_id()); - show_regs(regs); - printk("Process %s (pid: %d, stack limit = 0x%p)\n", -- tsk->comm, tsk->pid, tsk->thread_info + 1); -+ tsk->comm, tsk->pid, thread + 1); - - if (!user_mode(regs) || in_interrupt()) { - dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info); - dump_backtrace(regs, tsk); - dump_instr(regs); - } -+} -+ -+void nmi_watchdog(struct thread_info *thread, struct pt_regs *regs) -+{ -+ __die("NMI watchdog", 0, thread, regs); -+} - -+spinlock_t die_lock = SPIN_LOCK_UNLOCKED; -+ -+/* -+ * This function is protected against re-entrancy. -+ */ -+NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) -+{ -+ struct thread_info *thread = current_thread_info(); -+ -+ console_verbose(); -+ spin_lock_irq(&die_lock); -+ bust_spinlocks(1); -+ __die(str, err, thread, regs); - bust_spinlocks(0); - spin_unlock_irq(&die_lock); - do_exit(SIGSEGV); ---- linux-2.6.5/arch/arm/Kconfig~heh 2004-04-03 22:37:07.000000000 -0500 -+++ linux-2.6.5/arch/arm/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -297,7 +297,7 @@ - - config CPU_FREQ - bool "Support CPU clock change (EXPERIMENTAL)" -- depends on (ARCH_SA1100 || ARCH_INTEGRATOR) && EXPERIMENTAL -+ depends on (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_PXA) && EXPERIMENTAL - help - CPU clock scaling allows you to change the clock speed of the - running CPU on the fly. This is a nice method to save battery power, ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/fastfpe/entry.S 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,294 @@ -+/* -+At entry the registers contain the following information: -+ -+r14 return address for undefined exception return -+r9 return address for return from exception -+r13 user registers on stack, offset 0 up to offset 4*15 contains -+ registers r0..15, then the psr -+r10 FP workspace 35 words (init, reg[8][4], fpsr, fpcr) -+ -+*/ -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .data -+fp_const: -+ .word 0, 0x00000000, 0, 0x80000000 @ 0 -+ .word 0, 0x80000000, 0, 0 @ 1 -+ .word 0, 0x80000000, 0, 1 @ 2 -+ .word 0, 0xc0000000, 0, 1 @ 3 -+ .word 0, 0x80000000, 0, 2 @ 4 -+ .word 0, 0xa0000000, 0, 2 @ 5 -+ .word 0, 0x80000000, 0, -1 @ 0.5 -+ .word 0, 0xa0000000, 0, 3 @ 10 -+fp_undef: -+ .word 0 -+fp_cond: -+ .word 0xf0f0 @ eq -+ .word 0x0f0f @ ne -+ .word 0xcccc @ cs -+ .word 0x3333 @ cc -+ .word 0xff00 @ mi -+ .word 0x00ff @ pl -+ .word 0xaaaa @ vs -+ .word 0x5555 @ vc -+ .word 0x0c0c @ hi -+ .word 0xf3f3 @ ls -+ .word 0xaa55 @ ge -+ .word 0x55aa @ lt -+ .word 0x0a05 @ gt -+ .word 0xf5fa @ le -+ .word 0xffff @ al -+ .word 0x0000 @ nv -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .text -+ .globl fastfpe_enter -+fastfpe_enter: -+ ldr r4,=fp_undef -+ str r14,[r4] @ to free one register -+ add r10,r10,#4 @ to make the code simpler -+ mov r4, r0 @ r4=trapped instruction -+ and r1,r4,#0x00000f00 @ r1=coprocessor << 8 -+next_enter: -+ cmp r1,#1<<8 @ copro 1 ? -+ beq copro_1 -+ cmp r1,#2<<8 -+ movne pc,r14 -+ -+copro_2: -+ and r1,r4,#0x0f000000 -+ cmp r1,#0x0c000000 @ CPDT with post indexing -+ cmpne r1,#0x0d000000 @ CPDT with pre indexing -+ beq CPDT_M_enter -+ mov pc,r14 -+ -+copro_1: -+ and r1,r4,#0x0f000000 -+ cmp r1,#0x0e000000 @ CPDO -+ beq CPDO_CPRT_enter -+ cmp r1,#0x0c000000 @ CPDT with post indexing -+ cmpne r1,#0x0d000000 @ CPDT with pre indexing -+ beq CPDT_1_enter -+ mov pc,r14 -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl fastfpe_next -+fastfpe_next: -+ ldr r5,[r13,#60] -+next_after_cond: -+__x1: -+ ldrt r4,[r5],#4 -+ -+ ldr r0,=fp_cond @ check condition of next instruction -+ ldr r1,[r13,#64] @ psr containing flags -+ mov r2,r4,lsr#28 -+ mov r1,r1,lsr#28 -+ ldr r0,[r0,r2,lsl#2] -+ mov r0,r0,lsr r1 -+ tst r0,#1 -+ beq next_after_cond @ must not necessarily have been an -+ @ FP instruction ! -+ and r1,r4,#0x0f000000 @ Test for copro instruction -+ cmp r1,#0x0c000000 -+ rsbgts r0,r1,#0x0e000000 @ cmpgt #0x0e000000,r1 -+ movlt pc,r9 @ next is no copro instruction, return -+ -+ ands r1,r4,#0x00000f00 @ r1 = coprocessor << 8 -+ cmpne r1,#3<<8 -+ movge pc,r9 @ copro = 0 or >=3, return -+ -+ str r5,[r13,#60] @ save updated pc -+ b next_enter -+ -+/*---------------------------------------------------------------------------*/ -+ -+undefined: -+ ldr r4,=fp_undef -+ ldr pc,[r4] -+ -+/*---------------------------------------------------------------------------*/ -+ -+CPDT_1_enter: -+ and r5,r4,#0x000f0000 @ r5=base register number << 16 -+ ldr r6,[r13,r5,lsr#14] @ r6=base address -+ cmp r5,#0x000f0000 @ base register = pc ? -+ addeq r6,r6,#4 -+ and r7,r4,#0x000000ff @ r7=offset value -+ -+ tst r4,#0x00800000 @ up or down? -+ addne r7,r6,r7,lsl#2 -+ subeq r7,r6,r7,lsl#2 @ r6=base address +/- offset -+ tst r4,#0x01000000 @ preindexing ? -+ movne r6,r7 -+ tst r4,#0x00200000 @ write back ? -+ cmpne r5,#0x000f0000 @ base register = pc ? -+ strne r7,[r13,r5,lsr#14] -+ -+ and r0,r4,#0x00007000 @ r0=fp register number << 12 -+ add r0,r10,r0,lsr#8 @ r0=address of fp register -+ mov r1,#0 -+ tst r4,#0x00008000 -+ orrne r1,r1,#1 @ T0 -+ tst r4,#0x00400000 -+ orrne r1,r1,#2 @ T1 -+ tst r4,#0x00100000 -+ orrne r1,r1,#4 @ L/S -+ -+ add pc,pc,r1,lsl#2 -+ mov r0,r0 -+ b CPDT_store_single @ these functions get -+ b CPDT_store_double @ r0=address of fp register -+ b CPDT_store_extended @ r6=address of data -+ b undefined @ CPDT_store_decimal -+ b CPDT_load_single -+ b CPDT_load_double -+ b CPDT_load_extended -+ b undefined @ CPDT_load_decimal -+ -+/*---------------------------------------------------------------------------*/ -+ -+CPDT_M_enter: -+ and r5,r4,#0x000f0000 @ r5=base register number << 16 -+ ldr r6,[r13,r5,lsr#14] @ r6=base address -+ cmp r5,#0x000f0000 @ base register = pc ? -+ addeq r6,r6,#4 -+ and r7,r4,#0x000000ff @ r7=offset value -+ -+ tst r4,#0x00800000 @ up or down? -+ addne r7,r6,r7,lsl#2 -+ subeq r7,r6,r7,lsl#2 @ r7=base address +/- offset -+ tst r4,#0x01000000 @ preindexing ? -+ movne r6,r7 -+ tst r4,#0x00200000 @ write back ? -+ cmpne r5,#0x000f0000 @ base register = pc ? -+ strne r7,[r13,r5,lsr#14] -+ -+ and r0,r4,#0x00007000 @ r0=fp register number << 12 -+ and r1,r4,#0x00008000 -+ mov r1,r1,lsr#15 @ N0 -+ and r2,r4,#0x00400000 -+ orrs r1,r1,r2,lsr#21 @ N1 -+ addeq r1,r1,#4 @ r1=register count -+ -+ tst r4,#0x00100000 @ load/store -+ beq CPDT_sfm -+ b CPDT_lfm -+ -+/*---------------------------------------------------------------------------*/ -+ -+CPDO_CPRT_enter: -+ tst r4,#0x00000010 -+ bne CPRT_enter -+ -+ and r0,r4,#0x00007000 -+ add r0,r10,r0,lsr#8 @ r0=address of Fd -+ and r1,r4,#0x00070000 -+ add r1,r10,r1,lsr#12 @ r1=address of Fn -+ tst r4,#0x00000008 -+ bne CPDO_const -+ and r2,r4,#0x00000007 -+ add r2,r10,r2,lsl#4 @ r2=address of Fm -+ -+CPDO_constback: -+ and r3,r4,#0x00f00000 -+ tst r4,#0x00008000 -+ orrne r3,r3,#0x01000000 -+ -+ add pc,pc,r3,lsr#18 -+ mov r0,r0 -+ b CPDO_adf -+ b CPDO_muf -+ b CPDO_suf -+ b CPDO_rsf -+ b CPDO_dvf -+ b CPDO_rdf -+ b undefined -+ b undefined -+ b undefined @ CPDO_rmf -+ b CPDO_muf -+ b CPDO_dvf -+ b CPDO_rdf -+ b undefined -+ b undefined -+ b undefined -+ b undefined -+ b CPDO_mvf -+ b CPDO_mnf -+ b CPDO_abs -+ b CPDO_rnd -+ b CPDO_sqt -+ b undefined -+ b undefined -+ b undefined -+ b undefined -+ b undefined -+ b undefined -+ b undefined -+ b undefined -+ b undefined -+ b CPDO_rnd -+ b fastfpe_next -+ -+CPDO_const: -+ ldr r2,=fp_const -+ and r3,r4,#0x00000007 -+ add r2,r2,r3,lsl#4 -+ b CPDO_constback -+ -+/*---------------------------------------------------------------------------*/ -+ -+CPRT_enter: -+ and r0,r4,#0x0000f000 @ r0=Rd<<12 -+ and r1,r4,#0x00070000 -+ add r1,r10,r1,lsr#12 @ r1=address of Fn -+ tst r4,#0x00000008 -+ bne CPRT_const -+ and r2,r4,#0x00000007 -+ add r2,r10,r2,lsl#4 @ r2=address of Fm -+ -+CPRT_constback: -+ and r3,r4,#0x00f00000 -+ -+ add pc,pc,r3,lsr#18 -+ mov r0,r0 -+ b CPRT_flt -+ b CPRT_fix -+ b CPRT_wfs -+ b CPRT_rfs -+ b undefined -+ b undefined -+ b undefined -+ b undefined -+ b undefined -+ b CPRT_cmf -+ b undefined -+ b CPRT_cnf -+ b undefined -+ b CPRT_cmf -+ b undefined -+ b CPRT_cnf -+ -+CPRT_const: -+ ldr r2,=fp_const -+ and r3,r4,#0x00000007 -+ add r2,r2,r3,lsl#4 -+ b CPRT_constback -+ -+/*---------------------------------------------------------------------------*/ -+ -+ @ The fetch of the next instruction to emulate could fault -+ -+ .section .fixup,"ax" -+ .align -+__f1: -+ mov pc,r9 -+ .previous -+ .section __ex_table,"a" -+ .align 3 -+ .long __x1,__f1 -+ .previous -+ -+/*---------------------------------------------------------------------------*/ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/fastfpe/module.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,62 @@ -+/* -+ Fast Floating Point Emulator -+ (c) Peter Teichmann -+ -+ 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef MODULE -+#define kern_fp_enter fp_enter -+ -+extern char fpe_type[]; -+#endif -+ -+static void (*orig_fp_enter)(void); /* old kern_fp_enter value */ -+extern void (*kern_fp_enter)(void); /* current FP handler */ -+extern void fastfpe_enter(void); /* forward declarations */ -+ -+static int __init fpe_init(void) -+{ -+ if (fpe_type[0] && strcmp(fpe_type, "fastfpe")) -+ return 0; -+ -+ printk("Fast Floating Point Emulator V0.9 (c) Peter Teichmann.\n"); -+ -+ /* Save pointer to the old FP handler and then patch ourselves in */ -+ orig_fp_enter = kern_fp_enter; -+ kern_fp_enter = fastfpe_enter; -+ -+ return 0; -+} -+ -+static void __exit fpe_exit(void) -+{ -+ /* Restore the values we saved earlier. */ -+ kern_fp_enter = orig_fp_enter; -+} -+ -+module_init(fpe_init); -+module_exit(fpe_exit); -+ -+MODULE_AUTHOR("Peter Teichmann "); -+MODULE_DESCRIPTION("Fast floating point emulator with full precision"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/fastfpe/CPDO.S 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,682 @@ -+/* -+The FP structure has 4 words reserved for each register, the first is used just -+for the sign in bit 31, the second and third are for the mantissa (unsigned -+integer, high 32 bit first) and the fourth is the exponent (signed integer). -+The mantissa is always normalized. -+ -+If the exponent is 0x80000000, that is the most negative value, the number -+represented is 0 and both mantissa words are also 0. -+ -+If the exponent is 0x7fffffff, that is the biggest positive value, the number -+represented is infinity if the high 32 mantissa bit are also 0, otherwise it is -+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity. -+ -+Decimal and packed decimal numbers are not supported yet. -+ -+The parameters to these functions are r0=destination pointer, r1 and r2 -+source pointers. r4 is the instruction. They may use r0-r8 and r14. They return -+to fastfpe_next, except CPDO_rnf_core which expects the return address in r14. -+*/ -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_adf -+CPDO_adf: -+ ldmia r1,{r1,r3,r5,r7} -+ ldmia r2,{r2,r4,r6,r8} -+ -+ cmp r7,#0x7fffffff -+ cmpne r8,#0x7fffffff -+ beq CPDO_adf_extra -+ -+ cmp r1,r2 -+ bne CPDO_suf_s -+ -+CPDO_adf_s: -+ subs r2,r7,r8 -+ bge CPDO_adf_2nd -+ -+ mov r7,r8 -+ rsb r2,r2,#0 -+ cmp r2,#32 -+ ble CPDO_adf_1st2 -+ -+ sub r2,r2,#32 -+ cmp r2,#32 -+ movgt r2,#32 -+ mov r5,r3,lsr r2 -+ mov r3,#0 -+ b CPDO_adf_add -+ -+CPDO_adf_1st2: -+ rsb r8,r2,#32 -+ mov r5,r5,lsr r2 -+ orr r5,r5,r3,lsl r8 -+ mov r3,r3,lsr r2 @ 1. op normalized -+ b CPDO_adf_add -+ -+CPDO_adf_2nd: -+ cmp r2,#32 -+ ble CPDO_adf_2nd2 -+ -+ sub r2,r2,#32 -+ cmp r2,#32 -+ movgt r2,#32 -+ mov r6,r4,lsr r2 -+ mov r4,#0 -+ b CPDO_adf_add -+ -+CPDO_adf_2nd2: -+ rsb r8,r2,#32 -+ mov r6,r6,lsr r2 -+ orr r6,r6,r4,lsl r8 -+ mov r4,r4,lsr r2 @ 2. op normalized -+ -+CPDO_adf_add: -+ adds r5,r5,r6 -+ adcs r3,r3,r4 @ do addition -+ bcc CPDO_adf_end -+ -+ add r7,r7,#1 -+ movs r3,r3,rrx -+ mov r5,r5,rrx @ correct for overflow -+ -+CPDO_adf_end: -+ cmp r7,#0x20000000 -+ bge CPDO_inf -+ -+ stmia r0,{r1,r3,r5,r7} -+ b fastfpe_next -+ -+CPDO_adf_extra: -+ cmp r7,#0x7fffffff @ was it the 1st ? -+ bne CPDO_infnan_2 @ no it was the 2nd -+ cmp r8,#0x7fffffff @ if 1st, 2nd too ? -+ bne CPDO_infnan_1 @ no only 1st -+ cmp r3,#0 -+ cmpeq r4,#0 -+ bne CPDO_nan_12 -+ b CPDO_inf -+ -+/*---------------------------------------------------------------------------*/ -+ -+CPDO_infnan_1: -+ stmia r0,{r1,r3,r5,r7} -+ b fastfpe_next -+ -+CPDO_infnan_2: -+ stmia r0,{r2,r4,r6,r8} -+ b fastfpe_next -+ -+CPDO_nan_12: -+ orr r2,r3,r4 -+ b CPDO_inf_1 -+ -+CPDO_nan: -+ mov r2,#0x40000000 @ create non signalling NaN -+ b CPDO_inf_1 -+ -+CPDO_inf: -+ mov r2,#0 -+CPDO_inf_1: -+ mov r3,#0 -+ mov r4,#0x7fffffff -+CPDO_store_1234: -+ stmia r0,{r1,r2,r3,r4} -+ b fastfpe_next -+ -+CPDO_zero: -+ mov r1,#0 -+CPDO_zero_1: -+ mov r2,#0 -+ mov r3,#0 -+ mov r4,#0x80000000 -+ stmia r0,{r1,r2,r3,r4} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_suf -+CPDO_suf: -+ ldmia r1,{r1,r3,r5,r7} -+ ldmia r2,{r2,r4,r6,r8} -+ -+CPDO_suf_l: -+ cmp r7,#0x7fffffff -+ cmpne r8,#0x7fffffff -+ beq CPDO_suf_extra -+ -+ cmp r1,r2 -+ bne CPDO_adf_s -+ -+CPDO_suf_s: -+ subs r2,r7,r8 @ determine greater number -+ bgt CPDO_suf_2nd @ first number is greater -+ blt CPDO_suf_1st @ second number is greater -+ cmp r3,r4 @ also mantissa is important -+ cmpeq r5,r6 -+ bhi CPDO_suf_2nd @ first number is greater -+ beq CPDO_zero -+ -+CPDO_suf_1st: -+ eor r1,r1,#0x80000000 @ second number is greater, invert sign -+ mov r7,r8 -+ rsb r2,r2,#0 -+ cmp r2,#32 -+ ble CPDO_suf_1st2 -+ -+ sub r2,r2,#32 -+ cmp r2,#32 -+ movgt r2,#32 -+ mov r5,r3,lsr r2 -+ mov r3,#0 -+ b CPDO_suf_1st_sub -+ -+CPDO_suf_1st2: -+ rsb r8,r2,#32 -+ mov r5,r5,lsr r2 -+ orr r5,r5,r3,lsl r8 -+ mov r3,r3,lsr r2 @ 1. op normalized -+ -+CPDO_suf_1st_sub: -+ subs r5,r6,r5 @ do subtraction -+ sbc r3,r4,r3 -+ b CPDO_suf_norm -+ -+CPDO_suf_2nd: -+ cmp r2,#32 -+ ble CPDO_suf_2nd2 -+ -+ sub r2,r2,#32 -+ cmp r2,#32 -+ movgt r2,#32 -+ mov r6,r4,lsr r2 -+ mov r4,#0 -+ b CPDO_suf_2nd_sub -+ -+CPDO_suf_2nd2: -+ rsb r8,r2,#32 -+ mov r6,r6,lsr r2 -+ orr r6,r6,r4,lsl r8 -+ mov r4,r4,lsr r2 @ 2. op normalized -+ -+CPDO_suf_2nd_sub: -+ subs r5,r5,r6 -+ sbc r3,r3,r4 @ do subtraction -+ -+CPDO_suf_norm: -+ teq r3,#0 @ normalize 32bit -+ moveq r3,r5 -+ moveq r5,#0 -+ subeq r7,r7,#32 -+ -+ cmp r3,#0x00010000 @ 16bit -+ movcc r3,r3,lsl#16 -+ orrcc r3,r3,r5,lsr#16 -+ movcc r5,r5,lsl#16 -+ subcc r7,r7,#16 -+ -+ cmp r3,#0x01000000 @ 8bit -+ movcc r3,r3,lsl#8 -+ orrcc r3,r3,r5,lsr#24 -+ movcc r5,r5,lsl#8 -+ subcc r7,r7,#8 -+ -+ cmp r3,#0x10000000 @ 4bit -+ movcc r3,r3,lsl#4 -+ orrcc r3,r3,r5,lsr#28 -+ movcc r5,r5,lsl#4 -+ subcc r7,r7,#4 -+ -+ cmp r3,#0x40000000 @ 2bit -+ movcc r3,r3,lsl#2 -+ orrcc r3,r3,r5,lsr#30 -+ movcc r5,r5,lsl#2 -+ subcc r7,r7,#2 -+ -+ cmp r3,#0x80000000 @ 1bit -+ movcc r3,r3,lsl#1 -+ orrcc r3,r3,r5,lsr#31 -+ movcc r5,r5,lsl#1 -+ subcc r7,r7,#1 -+ -+ cmp r7,#0xe0000000 -+ ble CPDO_zero_1 -+ -+ stmia r0,{r1,r3,r5,r7} -+ b fastfpe_next -+ -+CPDO_suf_extra: -+ cmp r7,#0x7fffffff @ was it the 1st ? -+ eorne r2,r2,#0x80000000 @ change sign, might have been INF -+ bne CPDO_infnan_2 @ no it was the 2nd -+ cmp r8,#0x7fffffff @ if 1st, 2nd too ? -+ bne CPDO_infnan_1 @ no only 1st -+ cmp r3,#0 -+ cmpeq r4,#0 -+ bne CPDO_nan_12 -+ b CPDO_nan @ here is difference with adf ! -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_rsf -+CPDO_rsf: -+ mov r3,r2 -+ ldmia r1,{r2,r4,r6,r8} -+ ldmia r3,{r1,r3,r5,r7} -+ b CPDO_suf_l -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_muf -+CPDO_muf: -+ ldmia r1,{r1,r3,r5,r7} -+ ldmia r2,{r2,r4,r6,r8} -+ -+ cmp r7,#0x7fffffff -+ cmpne r8,#0x7fffffff -+ beq CPDO_muf_extra -+ -+ eor r1,r1,r2 -+ adds r8,r7,r8 -+ bvs CPDO_zero_1 -+ -+ umull r7,r2,r3,r4 -+ umull r14,r3,r6,r3 -+ adds r7,r7,r3 @ r2|r7|r14 = r2|r7|#0 + #0|r3|r14 -+ adc r2,r2,#0 -+ umull r4,r3,r5,r4 -+ adds r14,r14,r4 @ r2|r7|r14 += #0|r3|r4 -+ adcs r7,r7,r3 -+ adc r2,r2,#0 -+ umull r4,r3,r5,r6 -+ adds r14,r14,r3 @ r2|r7|r14 += #0|#0|r3 -+ adcs r7,r7,#0 -+ adcs r2,r2,#0 -+ -+ bpl CPDO_muf_norm -+ -+ add r8,r8,#1 -+ b CPDO_muf_end -+ -+CPDO_muf_norm: -+ adds r14,r14,r14 -+ adcs r7,r7,r7 -+ adcs r2,r2,r2 -+ -+CPDO_muf_end: -+ cmp r8,#0x20000000 -+ bge CPDO_inf -+ cmp r8,#0xe0000000 -+ ble CPDO_zero_1 -+ stmia r0,{r1,r2,r7,r8} -+ b fastfpe_next -+ -+CPDO_muf_extra: -+ cmp r7,#0x7fffffff @ was it the first? -+ bne CPDO_muf_extra_2nd @ no, so it was the second -+ cmp r8,#0x7fffffff @ yes, second too? -+ bne CPDO_muf_extra_1st @ no, only first -+ orr r3,r3,r4 @ if both inf -> inf, otherwise nan -+ eor r1,r1,r2 @ sign for the inf case -+ b CPDO_infnan_1 -+ -+CPDO_muf_extra_1st: -+ cmp r3,#0 @ is it a nan? -+ bne CPDO_infnan_1 -+ cmp r8,#0x80000000 @ is the second 0? -+ beq CPDO_nan -+ eor r1,r1,r2 @ correct sign for inf -+ b CPDO_inf -+ -+CPDO_muf_extra_2nd: -+ cmp r4,#0 @ is it a nan? -+ bne CPDO_infnan_2 -+ cmp r7,#0x80000000 @ is the first 0? -+ beq CPDO_nan -+ eor r1,r1,r2 @ correct sign for inf -+ b CPDO_inf -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_dvf -+CPDO_dvf: -+ ldmia r1,{r1,r3,r5,r7} -+ ldmia r2,{r2,r4,r6,r8} -+ -+CPDO_dvf_l: -+ cmp r7,#0x7fffffff -+ cmpne r8,#0x7fffffff -+ beq CPDO_dvf_extra -+ cmp r8,#0x80000000 -+ beq CPDO_dvf_by0 -+ -+ eor r1,r1,r2 -+ cmp r7,#0x80000000 -+ beq CPDO_zero_1 -+ -+ sub r8,r7,r8 -+ -+ mov r2,#0 -+ mov r7,#1 -+ -+ cmp r3,r4 -+ cmpeq r5,r6 -+ bcs CPDO_dvf_loop_ -+ -+ sub r8,r8,#1 -+ -+CPDO_dvf_loop: -+ adds r5,r5,r5 -+ adcs r3,r3,r3 -+ bcs CPDO_dvf_anyway -+CPDO_dvf_loop_: -+ subs r5,r5,r6 -+ sbcs r3,r3,r4 -+ bcs CPDO_dvf_okay -+ -+ adds r5,r5,r6 -+ adc r3,r3,r4 -+ adds r7,r7,r7 -+ adcs r2,r2,r2 -+ bcc CPDO_dvf_loop -+ b CPDO_dvf_end -+ -+CPDO_dvf_anyway: -+ adcs r7,r7,r7 -+ adcs r2,r2,r2 -+ bcs CPDO_dvf_end -+ subs r5,r5,r6 -+ sbc r3,r3,r4 -+ b CPDO_dvf_loop -+ -+CPDO_dvf_okay: -+ adcs r7,r7,r7 -+ adcs r2,r2,r2 -+ bcc CPDO_dvf_loop -+ -+CPDO_dvf_end: -+ b CPDO_muf_end -+ -+CPDO_dvf_by0: -+ cmp R7,#0x80000000 -+ beq CPDO_nan @ first also 0 -> nan -+ eor r1,r1,r2 @ otherwise calculatesign for inf -+ b CPDO_inf -+ -+CPDO_dvf_extra: -+ cmp r7,#0x7fffffff @ was it the first? -+ bne CPDO_dvf_extra_2nd @ no, so it was the second -+ cmp r8,#0x7fffffff @ yes, second too? -+ bne CPDO_dvf_extra_1st @ no, only first -+ orrs r3,r3,r4 -+ beq CPDO_nan @ if both inf -> create nan -+ b CPDO_nan_12 @ otherwise keep nan -+ -+CPDO_dvf_extra_1st: -+ eor r1,r1,r2 @ correct sign for inf -+ b CPDO_infnan_1 -+ -+CPDO_dvf_extra_2nd: -+ cmp r4,#0 @ is it a nan? -+ bne CPDO_infnan_2 -+ eor r1,r1,r2 @ correct sign for zero -+ b CPDO_zero_1 -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_rdf -+CPDO_rdf: -+ mov r3,r2 -+ ldmia r1,{r2,r4,r6,r8} -+ ldmia r3,{r1,r3,r5,r7} -+ b CPDO_dvf_l -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_rmf -+CPDO_rmf: -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_mvf -+CPDO_mvf: -+ ldmia r2,{r1,r2,r3,r4} -+ stmia r0,{r1,r2,r3,r4} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_mnf -+CPDO_mnf: -+ ldmia r2,{r1,r2,r3,r4} -+ eor r1,r1,#0x80000000 -+ stmia r0,{r1,r2,r3,r4} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_abs -+CPDO_abs: -+ ldmia r2,{r1,r2,r3,r4} -+ bic r1,r1,#0x80000000 -+ stmia r0,{r1,r2,r3,r4} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_sqt -+CPDO_sqt: -+ ldmia r2,{r1,r2,r3,r4} -+ cmp r1,#0 -+ bne CPDO_nan -+ cmp r4,#0x7fffffff -+ beq CPDO_store_1234 -+ -+ tst r4,r4,lsr#1 @carry=exponent bit 0 -+ bcc CPDO_sqt_exponenteven -+ adds r3,r3,r3 -+ adcs r2,r2,r2 @carry is needed in loop! -+CPDO_sqt_exponenteven: -+ mov r4,r4,asr #1 -+ str r4,[r0,#12] -+ -+ mov r4,#0x80000000 -+ mov r5,#0 -+ sub r2,r2,#0x80000000 -+ -+ mov r8,#0x40000000 -+ mov r14,#0x80000000 -+ -+ mov r1,#1 -+ b CPDO_sqt_loop1_first -+CPDO_sqt_loop1: -+ adds r3,r3,r3 -+ adcs r2,r2,r2 -+CPDO_sqt_loop1_first: -+ add r6,r4,r8,lsr r1 @r7 const = r5 -+ bcs CPDO_sqt_loop1_1 -+ cmp r2,r6 -+ cmpeq r3,r5 @r5 for r7 -+ bcc CPDO_sqt_loop1_0 -+CPDO_sqt_loop1_1: -+ orr r4,r4,r14,lsr r1 -+ subs r3,r3,r5 @r5 for r7 -+ sbc r2,r2,r6 -+CPDO_sqt_loop1_0: -+ add r1,r1,#1 -+ cmp r1,#30 -+ ble CPDO_sqt_loop1 -+ -+ adds r3,r3,r3 -+ adcs r2,r2,r2 -+ bcs CPDO_sqt_between_1 -+ adds r7,r5,#0x80000000 -+ adc r6,r4,#0 -+ cmp r2,r6 -+ cmpeq r3,r7 -+ bcc CPDO_sqt_between_0 -+CPDO_sqt_between_1: -+ orr r4,r4,#0x00000001 -+ subs r3,r3,r5 -+ sbc r2,r2,r4 -+ subs r3,r3,#0x80000000 -+ sbc r2,r2,#0 -+CPDO_sqt_between_0: -+ mov r1,#0 -+ -+CPDO_sqt_loop2: -+ adds r3,r3,r3 -+ adcs r2,r2,r2 -+ bcs CPDO_sqt_loop2_1 -+ adds r7,r5,r8,lsr r1 -+ adc r6,r4,#0 -+ cmp r2,r6 -+ cmpeq r3,r7 -+ bcc CPDO_sqt_loop2_0 -+CPDO_sqt_loop2_1: -+ orr r5,r5,r14,lsr r1 -+ subs r3,r3,r5 -+ sbc r2,r2,r4 -+ subs r3,r3,r8,lsr r1 -+ sbc r2,r2,#0 -+CPDO_sqt_loop2_0: -+ add r1,r1,#1 -+ cmp r1,#30 -+ ble CPDO_sqt_loop2 -+ -+ adds r3,r3,r3 -+ adcs r2,r2,r2 -+ bcs CPDO_sqt_after_1 -+ cmp r2,r6 -+ cmpeq r3,r7 -+ bcc CPDO_sqt_after_0 -+CPDO_sqt_after_1: -+ orr r5,r5,#0x00000001 -+CPDO_sqt_after_0: -+ -+ mov r1,#0 -+ stmia r0,{r1,r4,r5} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_rnd -+CPDO_rnd: -+ ldmia r2,{r1,r2,r3,r5} -+ bl CPDO_rnd_core -+ -+CPDO_rnd_store: -+ stmia r0,{r1,r2,r3,r5} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDO_rnd_core -+CPDO_rnd_core: -+ and r4,r4,#0x00000060 -+ add pc,pc,r4,lsr#3 -+ mov r0,r0 -+ b CPDO_rnd_N -+ b CPDO_rnd_P -+ b CPDO_rnd_M -+ b CPDO_rnd_Z -+ -+CPDO_rnd_N: -+ cmp r5,#-1 -+ blt CPDO_rnd_zero -+ cmp r5,#63 -+ movge pc,r14 -+ mov r4,#0x40000000 -+ cmp r5,#31 -+ bge CPDO_rnd_N_2 -+ -+ adds r2,r2,r4,lsr r5 -+ bcc CPDO_rnd_end -+ b CPDO_rnd_end_norm -+ -+CPDO_rnd_N_2: -+CPDO_rnd_P_2: -+ sub r6,r5,#32 -+ adds r3,r3,r4,ror r6 @ror ist needed to handle a -1 correctly -+ adcs r2,r2,#0 -+ bcc CPDO_rnd_end -+ b CPDO_rnd_end_norm -+ -+CPDO_rnd_P: -+ tst r1,#0x80000000 -+ bne CPDO_rnd_M_entry -+CPDO_rnd_P_entry: -+ cmp r5,#0 -+ blt CPDO_rnd_P_small -+ cmp r5,#63 -+ movge pc,r14 -+ mov r4,#0x7fffffff -+ cmp r5,#32 -+ bge CPDO_rnd_P_2 -+ -+ adds r3,r3,#0xffffffff -+ adcs r2,r2,r4,lsr r5 -+ bcc CPDO_rnd_end -+ b CPDO_rnd_end_norm -+ -+CPDO_rnd_P_small: -+ cmp r5,#0x80000000 -+ moveq pc,r14 -+ b CPDO_rnd_one -+ -+CPDO_rnd_M: -+ tst r1,#0x80000000 -+ bne CPDO_rnd_P_entry -+CPDO_rnd_M_entry: -+ cmp r5,#0 -+ blt CPDO_rnd_zero -+ cmp r5,#63 -+ movge pc,r14 -+ -+ b CPDO_rnd_end -+ -+CPDO_rnd_Z: -+ cmp r5,#0 -+ blt CPDO_rnd_zero -+ cmp r5,#63 -+ movge pc,r14 -+ b CPDO_rnd_end -+ -+CPDO_rnd_end_norm: -+ add r5,r5,#1 -+ movs r2,r2,rrx -+ mov r3,r3,rrx -+CPDO_rnd_end: -+ rsbs r4,r5,#31 -+ bmi CPDO_rnd_end_2 -+ mov r3,#0 -+ mov r2,r2,lsr r4 -+ mov r2,r2,lsl r4 -+ mov pc,r14 -+ -+CPDO_rnd_end_2: -+ rsb r4,r5,#63 -+ mov r3,r3,lsr r4 -+ mov r3,r3,lsl r4 -+ mov pc,r14 -+ -+CPDO_rnd_one: -+ mov r2,#0x80000000 -+ mov r3,#0 -+ mov r5,#0 -+ mov pc,r14 -+ -+CPDO_rnd_zero: -+ mov r1,#0 -+ mov r2,#0 -+ mov r3,#0 -+ mov r5,#0x80000000 -+ mov pc,r14 -+ -+/*---------------------------------------------------------------------------*/ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/fastfpe/CPRT.S 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,185 @@ -+/* -+The FP structure has 4 words reserved for each register, the first is used -+just -+for the sign in bit 31, the second and third are for the mantissa (unsigned -+integer, high 32 bit first) and the fourth is the exponent (signed integer). -+The mantissa is always normalized. -+ -+If the exponent is 0x80000000, that is the most negative value, the number -+represented is 0 and both mantissa words are also 0. -+ -+If the exponent is 0x7fffffff, that is the biggest positive value, the -+number -+represented is infinity if the high 32 mantissa bit are also 0, otherwise it -+is -+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity. -+ -+Decimal and packed decimal numbers are not supported yet. -+*/ -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .text -+ .globl CPRT_flt -+CPRT_flt: -+ add r0,r13,r0,lsr#10 -+ ldr r2,[r0] -+ mov r3,#0 -+ cmp r2,#0 -+ beq CPRT_flt_zero -+ -+ ands r0,r2,#0x80000000 -+ rsbne r2,r2,#0 -+ mov r4,#31 -+ -+ cmp r2,#0x00010000 -+ movcc r2,r2,lsl#16 -+ subcc r4,r4,#16 -+ -+ cmp r2,#0x01000000 -+ movcc r2,r2,lsl#8 -+ subcc r4,r4,#8 -+ -+ cmp r2,#0x10000000 -+ movcc r2,r2,lsl#4 -+ subcc r4,r4,#4 -+ -+ cmp r2,#0x40000000 -+ movcc r2,r2,lsl#2 -+ subcc r4,r4,#2 -+ -+ cmp r2,#0x80000000 -+ movcc r2,r2,lsl#1 -+ subcc r4,r4,#1 -+ -+ stmia r1,{r0,r2,r3,r4} -+ b fastfpe_next -+ -+CPRT_flt_zero: -+ mov r0,#0 -+ mov r4,#0x80000000 -+ stmia r1,{r0,r2,r3,r4} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPRT_fix -+CPRT_fix: -+ ldmia r2,{r1,r2,r3,r5} -+ bl CPDO_rnd_core -+ -+CPRT_back: -+ add r0,r13,r0,lsr#10 -+ cmp r5,#0 -+ blt CPRT_int_zero -+ cmp r5,#30 -+ bgt CPRT_overflow -+ -+ rsb r5,r5,#31 -+ mov r2,r2,lsr r5 -+ tst r1,#0x80000000 -+ rsbne r2,r2,#0 -+ -+ str r2,[r0] -+ b fastfpe_next -+ -+CPRT_int_zero: -+ mov r2,#0 -+ str r2,[r0] -+ b fastfpe_next -+ -+CPRT_overflow: -+ mov r2,#0x80000000 -+ tst r1,#0x80000000 -+ subeq r2,r2,#1 -+ str r2,[r0] -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPRT_wfs -+CPRT_wfs: -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPRT_rfs -+CPRT_rfs: -+ add r0,r13,r0,lsr#10 -+ mov r1,#0x02000000 @ Software Emulation, not Acorn FPE -+ str r1,[r0] -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPRT_cmf -+CPRT_cmf: -+ ldmia r1,{r1,r3,r5,r7} -+ ldmia r2,{r2,r4,r6,r8} -+ -+CPRT_cmf_e: -+ ldr r0,[r13,#16*4] -+ -+ cmp r7,#0x7fffffff -+ bic r0,r0,#0xf0000000 -+ -+ cmpeq r3,#0xffffffff -+ beq CPRT_cmf_unordered -+ cmp r8,#0x7fffffff -+ cmpeq r4,#0xffffffff -+ beq CPRT_cmf_unordered -+ -+ cmp r1,r2 -+ beq CPRT_cmf_equalsign -+ b CPRT_cmf_sign -+ -+CPRT_cmf_equalsign: -+ cmp r7,r8 -+ beq CPRT_cmf_equalexponent -+ bgt CPRT_cmf_sign -+ b CPRT_cmf_signb -+ -+CPRT_cmf_equalexponent: -+ cmp r3,r4 -+ cmpeq r5,r6 -+ beq CPRT_cmf_equal -+ bhi CPRT_cmf_sign -+ b CPRT_cmf_signb -+ -+CPRT_cmf_sign: -+ cmp r7,#0x80000000 @ (0.0 == -0.0)? -+ cmpeq r7,r8 -+ beq CPRT_cmf_equal -+ tst r1,#0x80000000 -+ orreq r0,r0,#0x20000000 -+ orrne r0,r0,#0x80000000 -+ str r0,[r13,#16*4] -+ b fastfpe_next -+ -+CPRT_cmf_signb: -+ tst r1,#0x80000000 -+ orrne r0,r0,#0x20000000 -+ orreq r0,r0,#0x80000000 -+ str r0,[r13,#16*4] -+ b fastfpe_next -+ -+CPRT_cmf_equal: -+ orr r0,r0,#0x60000000 -+ str r0,[r13,#16*4] -+ b fastfpe_next -+ -+CPRT_cmf_unordered: -+ orr r0,r0,#0x10000000 -+ str r0,[r13,#16*4] -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPRT_cnf -+CPRT_cnf: -+ ldmia r1,{r1,r3,r5,r7} -+ ldmia r2,{r2,r4,r6,r8} -+ eor r2,r2,#0x80000000 -+ b CPRT_cmf_e -+ -+/*---------------------------------------------------------------------------*/ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/fastfpe/CPDT.S 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,430 @@ -+/* -+The FP structure has 4 words reserved for each register, the first is used just -+for the sign in bit 31, the second and third are for the mantissa (unsigned -+integer, high 32 bit first) and the fourth is the exponent (signed integer). -+The mantissa is always normalized. -+ -+If the exponent is 0x80000000, that is the most negative value, the number -+represented is 0 and both mantissa words are also 0. -+ -+If the exponent is 0x7fffffff, that is the biggest positive value, the number -+represented is infinity if the high 32 mantissa bit are also 0, otherwise it is -+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity. -+ -+Decimal and packed decimal numbers are not supported yet. -+*/ -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_load_single -+CPDT_load_single: -+ ldr r1,[r6] -+ -+ and r2,r1,#0x80000000 @ r2 = sign -+ -+ mov r5,r1,lsr#23 -+ bics r5,r5,#0x100 -+ beq CPDT_ls_e0 @ exponent = 0; zero/denormalized -+ teq r5,#255 -+ beq CPDT_ls_e255 @ exponent = 255; infinity/NaN -+ -+ sub r5,r5,#127 @ r5 = exponent, remove normalized bias -+ -+ mov r3,r1,lsl#8 -+ orr r3,r3,#0x80000000 -+ mov r4,#0 @ r3,r4 = mantissa -+ -+ stmia r0,{r2-r5} -+ b fastfpe_next -+ -+CPDT_ls_e0: -+ movs r3,r1,lsl#9 -+ beq CPDT_load_zero -+ -+ mov r5,#-127 -+ -+CPDT_ls_e0_norm: -+ tst r3,#0x80000000 -+ subeq r5,r5,#1 -+ moveq r3,r3,lsl#1 -+ beq CPDT_ls_e0_norm -+ -+ mov r4,#0 -+ stmia r0,{r2-r5} -+ b fastfpe_next -+ -+CPDT_ls_e255: -+ mov r3,r1,lsl#9 -+ mov r4,#0 -+ mov r5,#0x7fffffff -+ stmia r0,{r2-r5} -+ b fastfpe_next -+ -+CPDT_load_zero: -+ mov r3,#0 -+ mov r4,#0 -+ mov r5,#0x80000000 -+ stmia r0,{r2-r5} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_load_double -+CPDT_load_double: -+ ldr r1,[r6] -+ ldr r6,[r6,#4] -+ -+ and r2,r1,#0x80000000 @ r2 = sign -+ -+ mov r5,r1,lsr#20 -+ bics r5,r5,#0x800 -+ beq CPDT_ld_e0 @ exponent = 0; zero/denormalized -+ add r4,r5,#1 -+ teq r4,#2048 -+ beq CPDT_ld_e2047 @ exponent = 2047; infinity/NaN -+ -+ add r5,r5,#1 -+ sub r5,r5,#1024 @ r5 = exponent, remove normalized bias -+ -+ mov r3,r1,lsl#11 -+ orr r3,r3,#0x80000000 -+ orr r3,r3,r6,lsr #21 -+ mov r4,r6,lsl#11 @ r3,r4 = mantissa -+ -+ stmia r0,{r2-r5} -+ b fastfpe_next -+ -+CPDT_ld_e0: -+ mov r3,r1,lsl#12 -+ orr r3,r3,r6,lsr#20 -+ movs r4,r6,lsl#12 -+ teqeq r3,#0 -+ beq CPDT_load_zero -+ -+ mov r5,#1 -+ sub r5,r5,#1024 -+ -+CPDT_ld_e0_norm: -+ tst r3,#0x80000000 -+ subeq r5,r5,#1 -+ moveqs r4,r4,lsl#1 -+ adceq r3,r3,r3 -+ beq CPDT_ld_e0_norm -+ -+ stmia r0,{r2-r5} -+ b fastfpe_next -+ -+CPDT_ld_e2047: -+ mov r3,r1,lsl#12 -+ orr r3,r3,r6,lsr#1 -+ bic r6,r6,#0x80000000 -+ orr r3,r3,r6 @ to get all fraction bits ! -+ mov r4,#0 -+ mov r5,#0x7fffffff -+ stmia r0,{r2-r5} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_load_extended -+CPDT_load_extended: -+ ldr r1,[r6] -+ ldr r3,[r6,#4] -+ ldr r4,[r6,#8] -+ -+ and r2,r1,#0x80000000 -+ bics r5,r1,#0x80000000 -+ beq CPDT_le_e0 -+ add r1,r5,#1 -+ teq r4,#32768 -+ beq CPDT_le_e32767 -+ -+ add r5,r5,#1 -+ sub r5,r5,#16384 -+ -+ stmia r0,{r2-r5} -+ b fastfpe_next -+ -+CPDT_le_e0: -+ teq r3,#0 -+ teqeq r4,#0 -+ beq CPDT_load_zero -+ -+ mov r5,#2 -+ sub r5,r5,#16384 -+ b CPDT_ld_e0_norm -+ -+CPDT_le_e32767: -+ mov r3,r3,lsl#1 -+ orr r3,r3,r4,lsr#1 -+ bic r4,r4,#0x80000000 -+ orr r3,r3,r4 -+ mov r5,#0x7fffffff -+ stmia r0,{r2-r5} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_load_decimal -+CPDT_load_decimal: -+ -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_store_single -+CPDT_store_single: -+ ldmia r0,{r1-r4} -+ -+ cmp r4,#-127 -+ ble CPDT_ss_e0 -+ cmp r4,#128 -+ bge CPDT_ss_e255 -+ -+ adds r2,r2,#1<<7 @ round to nearest -+ bcs CPDT_ss_rnd_ovfl @ very very seldom taken -+ -+CPDT_ss_store: -+ add r4,r4,#127 -+ orr r1,r1,r4,lsl#23 -+ -+ bic r2,r2,#0x80000000 -+ orr r1,r1,r2,lsr#8 -+ -+ str r1,[r6] -+ b fastfpe_next -+ -+CPDT_ss_rnd_ovfl: -+ add r4,r4,#1 -+ cmp r4,#128 -+ bge CPDT_ss_e255 -+ -+ mov r2,#0x80000000 -+ mov r3,#0 -+ b CPDT_ss_store -+ -+CPDT_ss_e0: -+ cmp r4,#-150 -+ ble CPDT_ss_zero -+ -+ add r4,r4,#126 -+CPDT_ss_unnormalize: -+ mov r2,r2,lsr#1 -+ adds r4,r4,#1 -+ bne CPDT_ss_unnormalize -+ -+ orr r1,r1,r2,lsr#8 -+ -+CPDT_ss_zero: -+ str r1,[r6] -+ b fastfpe_next -+ -+CPDT_ss_e255: -+ cmp r4,#0x7fffffff -+ bne CPDT_ss_inf -+ cmp r2,#0 -+ beq CPDT_ss_inf -+ -+ orr r1,r1,#0x00200000 @ for safety so that it is not INF -+ orr r1,r1,r2,lsr#9 @ get highest bit of mantissa -+ -+CPDT_ss_inf: -+ orr r1,r1,#0x7f000000 -+ orr r1,r1,#0x00800000 -+ str r1,[r6] -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_store_double -+CPDT_store_double: -+ ldmia r0,{r1-r4} -+ -+ cmp r4,#1024 @ this check has to be first, or -+ bge CPDT_sd_e2047 @ overflow can occur on second ! -+ add r0,r4,#3 -+ cmp r0,#-1023+3 @ cmp with -1023 -+ ble CPDT_sd_e0 -+ -+ adds r3,r3,#1<<10 @ round to nearest -+ adcs r2,r2,#0 -+ bcs CPDT_sd_rnd_ovfl @ very very seldom taken -+ -+CPDT_sd_store: -+ sub r4,r4,#1 -+ add r4,r4,#1024 -+ orr r1,r1,r4,lsl#20 -+ -+ bic r2,r2,#0x80000000 -+ orr r1,r1,r2,lsr#11 -+ -+ mov r2,r2,lsl#21 -+ orr r2,r2,r3,lsr#11 -+ -+ stmia r6,{r1,r2} -+ b fastfpe_next -+ -+CPDT_sd_rnd_ovfl: -+ add r4,r4,#1 -+ cmp r4,#1024 -+ bge CPDT_sd_e2047 -+ -+ mov r2,#0x80000000 -+ mov r3,#0 -+ b CPDT_sd_store -+ -+CPDT_sd_e0: -+ add r0,r4,#1075-1024 -+ cmp r0,#-1024 -+ ble CPDT_sd_zero -+ -+ add r4,r4,#1024 -+ sub r4,r4,#2 -+CPDT_sd_unnormalize: -+ movs r2,r2,lsr#1 -+ mov r3,r3,rrx -+ adds r4,r4,#1 -+ bne CPDT_sd_unnormalize -+ -+ orr r1,r1,r2,lsr#11 -+ mov r2,r2,lsl#21 -+ orr r2,r2,r3,lsr#11 -+ -+ stmia r6,{r1,r2} -+ b fastfpe_next -+ -+CPDT_sd_zero: -+ mov r2,#0 -+ stmia r6,{r1,r2} -+ b fastfpe_next -+ -+CPDT_sd_e2047: -+ cmp r4,#0x7fffffff -+ bne CPDT_sd_inf -+ cmp r2,#0 -+ beq CPDT_sd_inf -+ -+ orr r1,r1,#0x00040000 @ for safety so that it is not INF -+ orr r1,r1,r2,lsr#12 @ get highest bit of mantissa -+ -+CPDT_sd_inf: -+ orr r1,r1,#0x7f000000 -+ orr r1,r1,#0x00f00000 -+ stmia r6,{r1,r2} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_store_extended -+CPDT_store_extended: -+ ldmia r0,{r1-r4} -+ -+ cmp r4,#16384 @ this check has to be first, or -+ bge CPDT_se_e32767 @ overflow can occur with second ! -+ add r0,r4,#63 -+ cmp r0,#-16383+63 -+ ble CPDT_se_e0 -+ -+ sub r4,r4,#1 -+ add r4,r4,#16384 -+ orr r1,r1,r4 -+ -+ stmia r6,{r1-r3} -+ b fastfpe_next -+ -+CPDT_se_e0: -+ add r0,r4,#16446-16384 -+ cmp r0,#-16384 -+ ble CPDT_se_zero -+ -+ add r4,r4,#16384 -+ sub r4,r4,#2 -+CPDT_se_unnormalize: -+ movs r2,r2,lsr#1 -+ mov r3,r3,rrx -+ adds r4,r4,#1 -+ bne CPDT_se_unnormalize -+ -+ stmia r6,{r1-r3} -+ b fastfpe_next -+ -+CPDT_se_zero: -+ mov r2,#0 -+ mov r3,#0 -+ stmia r6,{r1-r3} -+ b fastfpe_next -+ -+CPDT_se_e32767: -+ cmp r4,#0x7fffffff -+ bne CPDT_se_inf -+ cmp r2,#0 -+ beq CPDT_se_inf -+ -+ mov r2,r2,lsl#1 -+ orr r2,r2,#0x20000000 -+ -+CPDT_se_inf: -+ orr r1,r1,#0x00007f00 -+ orr r1,r1,#0x000000ff -+ stmia r6,{r1-r3} -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_store_decimal -+CPDT_store_decimal: -+ -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_sfm -+CPDT_sfm: -+ add r2,r10,r0,lsr#8 -+ ldr r4,[r2,#0] -+ ldr r3,[r2,#4] -+ bic r3,r3,#0x80000000 -+ orr r3,r3,r4 -+ str r3,[r6],#4 -+ ldr r3,[r2,#8] -+ str r3,[r6],#4 -+ ldr r3,[r2,#12] -+ str r3,[r6],#4 -+ -+ add r0,r0,#1<<12 -+ and r0,r0,#7<<12 -+ subs r1,r1,#1 -+ bne CPDT_sfm -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ -+ -+ .globl CPDT_lfm -+CPDT_lfm: -+ add r2,r10,r0,lsr#8 -+ ldr r4,[r6],#4 -+ and r3,r4,#0x80000000 -+ str r3,[r2,#0] -+ ldr r3,[r6],#4 -+ str r3,[r2,#8] -+ ldr r3,[r6],#4 -+ str r3,[r2,#12] -+ -+ cmp r3,#0x80000000 @ does the exp indicate zero? -+ biceq r4,r4,#0x80000000 @ if so, indicate 'denormalized' -+ beq CPDT_lfm_storer4 -+ cmp r3,#0x7fffffff @ does the exp indicate inf or NaN? -+ biceq r4,r4,#0x80000000 @ if so, indicate 'denormalized' -+ beq CPDT_lfm_storer4 -+ orrne r4,r4,#0x80000000 @ otherwise, set normalized bit -+ -+CPDT_lfm_storer4: -+ str r4,[r2,#4] -+ -+ add r0,r0,#1<<12 -+ and r0,r0,#7<<12 -+ subs r1,r1,#1 -+ bne CPDT_lfm -+ b fastfpe_next -+ -+/*---------------------------------------------------------------------------*/ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/fastfpe/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,14 @@ -+# -+# linux/arch/arm/fastfpe/Makefile -+# -+# Copyright (C) Peter Teichmann -+# -+ -+obj-y := -+obj-m := -+obj-n := -+obj- := -+ -+fastfpe-objs := module.o entry.o CPDO.o CPRT.o CPDT.o -+ -+obj-$(CONFIG_FPE_FASTFPE) += fastfpe.o ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/common/rtctime.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,482 @@ -+/* -+ * linux/arch/arm/common/rtctime.c -+ * -+ * Copyright (C) 2003 Deep Blue Solutions Ltd. -+ * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre. -+ * Based on rtc.c by Paul Gortmaker -+ * -+ * 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 -+#include -+#include -+ -+#include -+#include -+ -+static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); -+static struct fasync_struct *rtc_async_queue; -+ -+/* -+ * rtc_lock protects rtc_irq_data -+ */ -+static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; -+static unsigned long rtc_irq_data; -+ -+/* -+ * rtc_sem protects rtc_inuse and rtc_ops -+ */ -+static DECLARE_MUTEX(rtc_sem); -+static unsigned long rtc_inuse; -+static struct rtc_ops *rtc_ops; -+ -+#define rtc_epoch 1900UL -+ -+static const unsigned char days_in_month[] = { -+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -+}; -+ -+#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) -+#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) -+ -+static int month_days(unsigned int month, unsigned int year) -+{ -+ return days_in_month[month] + (LEAP_YEAR(year) && month == 1); -+} -+ -+/* -+ * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. -+ */ -+void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) -+{ -+ int days, month, year; -+ -+ days = time / 86400; -+ time -= days * 86400; -+ -+ tm->tm_wday = (days + 4) % 7; -+ -+ year = 1970 + days / 365; -+ days -= (year - 1970) * 365 -+ + LEAPS_THRU_END_OF(year - 1) -+ - LEAPS_THRU_END_OF(1970 - 1); -+ if (days < 0) { -+ year -= 1; -+ days += 365 + LEAP_YEAR(year); -+ } -+ tm->tm_year = year - 1900; -+ tm->tm_yday = days + 1; -+ -+ for (month = 0; month < 11; month++) { -+ int newdays; -+ -+ newdays = days - month_days(month, year); -+ if (newdays < 0) -+ break; -+ days = newdays; -+ } -+ tm->tm_mon = month; -+ tm->tm_mday = days + 1; -+ -+ tm->tm_hour = time / 3600; -+ time -= tm->tm_hour * 3600; -+ tm->tm_min = time / 60; -+ tm->tm_sec = time - tm->tm_min * 60; -+} -+ -+/* -+ * Convert Gregorian date to seconds since 01-01-1970 00:00:00. -+ */ -+int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) -+{ -+ unsigned int yrs = tm->tm_year + 1900; -+ -+ *time = 0; -+ -+ if (yrs < 1970 || -+ tm->tm_mon >= 12 || -+ tm->tm_mday < 1 || -+ tm->tm_mday > month_days(tm->tm_mon, yrs) || -+ tm->tm_hour >= 24 || -+ tm->tm_min >= 60 || -+ tm->tm_sec >= 60) -+ return -EINVAL; -+ -+ *time = mktime(yrs, tm->tm_mon + 1, tm->tm_mday, -+ tm->tm_hour, tm->tm_min, tm->tm_sec); -+ -+ return 0; -+} -+ -+/* -+ * Calculate the next alarm time given the requested alarm time mask -+ * and the current time. -+ * -+ * FIXME: for now, we just copy the alarm time because we're lazy (and -+ * is therefore buggy - setting a 10am alarm at 8pm will not result in -+ * the alarm triggering.) -+ */ -+void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) -+{ -+ next->tm_year = now->tm_year; -+ next->tm_mon = now->tm_mon; -+ next->tm_mday = now->tm_mday; -+ next->tm_hour = alrm->tm_hour; -+ next->tm_min = alrm->tm_min; -+ next->tm_sec = alrm->tm_sec; -+} -+ -+static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) -+{ -+ memset(tm, 0, sizeof(struct rtc_time)); -+ ops->read_time(tm); -+} -+ -+static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) -+{ -+ return ops->set_time(tm); -+} -+ -+static inline void rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -+{ -+ memset(alrm, 0, sizeof(struct rtc_wkalrm)); -+ ops->read_alarm(alrm); -+} -+ -+static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -+{ -+ return ops->set_alarm(alrm); -+} -+ -+void rtc_update(unsigned long num, unsigned long events) -+{ -+ spin_lock(&rtc_lock); -+ rtc_irq_data = (rtc_irq_data + (num << 8)) | events; -+ spin_unlock(&rtc_lock); -+ -+ wake_up_interruptible(&rtc_wait); -+ kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); -+} -+ -+ -+static ssize_t -+rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ unsigned long data; -+ ssize_t ret; -+ -+ if (count < sizeof(unsigned long)) -+ return -EINVAL; -+ -+ add_wait_queue(&rtc_wait, &wait); -+ do { -+ __set_current_state(TASK_INTERRUPTIBLE); -+ -+ spin_lock_irq(&rtc_lock); -+ data = rtc_irq_data; -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ -+ if (data != 0) { -+ ret = 0; -+ break; -+ } -+ if (file->f_flags & O_NONBLOCK) { -+ ret = -EAGAIN; -+ break; -+ } -+ if (signal_pending(current)) { -+ ret = -ERESTARTSYS; -+ break; -+ } -+ schedule(); -+ } while (1); -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&rtc_wait, &wait); -+ -+ if (ret == 0) { -+ ret = put_user(data, (unsigned long *)buf); -+ if (ret == 0) -+ ret = sizeof(unsigned long); -+ } -+ return ret; -+} -+ -+static unsigned int rtc_poll(struct file *file, poll_table *wait) -+{ -+ unsigned long data; -+ -+ poll_wait(file, &rtc_wait, wait); -+ -+ spin_lock_irq(&rtc_lock); -+ data = rtc_irq_data; -+ spin_unlock_irq(&rtc_lock); -+ -+ return data != 0 ? POLLIN | POLLRDNORM : 0; -+} -+ -+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct rtc_ops *ops = file->private_data; -+ struct rtc_time tm; -+ struct rtc_wkalrm alrm; -+ int ret; -+ -+ switch (cmd) { -+ case RTC_ALM_READ: -+ rtc_read_alarm(ops, &alrm); -+ ret = copy_to_user((void *)arg, &alrm.time, sizeof(tm)); -+ if (ret) -+ ret = -EFAULT; -+ break; -+ -+ case RTC_ALM_SET: -+ ret = copy_from_user(&alrm.time, (void *)arg, sizeof(tm)); -+ alrm.enabled = 0; -+ alrm.pending = 0; -+ alrm.time.tm_mday = -1; -+ alrm.time.tm_mon = -1; -+ alrm.time.tm_year = -1; -+ alrm.time.tm_wday = -1; -+ alrm.time.tm_yday = -1; -+ alrm.time.tm_isdst = -1; -+ if (ret == 0) -+ ret = rtc_set_alarm(ops, &alrm); -+ else -+ ret = -EFAULT; -+ break; -+ -+ case RTC_RD_TIME: -+ rtc_read_time(ops, &tm); -+ ret = copy_to_user((void *)arg, &tm, sizeof(tm)); -+ if (ret) -+ ret = -EFAULT; -+ break; -+ -+ case RTC_SET_TIME: -+ if (!capable(CAP_SYS_TIME)) { -+ ret = -EACCES; -+ break; -+ } -+ ret = copy_from_user(&tm, (void *)arg, sizeof(tm)); -+ if (ret == 0) -+ ret = rtc_set_time(ops, &tm); -+ else -+ ret = -EFAULT; -+ break; -+ -+#ifndef rtc_epoch -+ case RTC_EPOCH_SET: -+ /* -+ * There were no RTC clocks before 1900. -+ */ -+ if (arg < 1900) { -+ ret = -EINVAL; -+ break; -+ } -+ if (!capable(CAP_SYS_TIME)) { -+ ret = -EACCES; -+ break; -+ } -+ rtc_epoch = arg; -+ ret = 0; -+ break; -+#endif -+ -+ case RTC_EPOCH_READ: -+ ret = put_user(rtc_epoch, (unsigned long *)arg); -+ break; -+ -+ case RTC_WKALM_SET: -+ ret = copy_from_user(&alrm, (void *)arg, sizeof(alrm)); -+ if (ret == 0) -+ ret = rtc_set_alarm(ops, &alrm); -+ else -+ ret = -EFAULT; -+ break; -+ -+ case RTC_WKALM_RD: -+ rtc_read_alarm(ops, &alrm); -+ ret = copy_to_user((void *)arg, &alrm, sizeof(alrm)); -+ if (ret) -+ ret = -EFAULT; -+ break; -+ -+ default: -+ ret = ops->ioctl(cmd, arg); -+ } -+ return ret; -+} -+ -+static int rtc_open(struct inode *inode, struct file *file) -+{ -+ int ret; -+ -+ down(&rtc_sem); -+ -+ if (rtc_inuse) { -+ ret = -EBUSY; -+ } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) { -+ ret = -ENODEV; -+ } else { -+ file->private_data = rtc_ops; -+ -+ ret = rtc_ops->open ? rtc_ops->open() : 0; -+ if (ret == 0) { -+ spin_lock_irq(&rtc_lock); -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ -+ rtc_inuse = 1; -+ } -+ } -+ up(&rtc_sem); -+ -+ return ret; -+} -+ -+static int rtc_release(struct inode *inode, struct file *file) -+{ -+ struct rtc_ops *ops = file->private_data; -+ -+ if (ops->release) -+ ops->release(); -+ -+ spin_lock_irq(&rtc_lock); -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ -+ module_put(rtc_ops->owner); -+ rtc_inuse = 0; -+ -+ return 0; -+} -+ -+static int rtc_fasync(int fd, struct file *file, int on) -+{ -+ return fasync_helper(fd, file, on, &rtc_async_queue); -+} -+ -+static struct file_operations rtc_fops = { -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .read = rtc_read, -+ .poll = rtc_poll, -+ .ioctl = rtc_ioctl, -+ .open = rtc_open, -+ .release = rtc_release, -+ .fasync = rtc_fasync, -+}; -+ -+static struct miscdevice rtc_miscdev = { -+ .minor = RTC_MINOR, -+ .name = "rtc", -+ .fops = &rtc_fops, -+}; -+ -+ -+static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ struct rtc_ops *ops = data; -+ struct rtc_wkalrm alrm; -+ struct rtc_time tm; -+ char *p = page; -+ int len; -+ -+ rtc_read_time(ops, &tm); -+ -+ p += sprintf(p, -+ "rtc_time\t: %02d:%02d:%02d\n" -+ "rtc_date\t: %04d-%02d-%02d\n" -+ "rtc_epoch\t: %04lu\n", -+ tm.tm_hour, tm.tm_min, tm.tm_sec, -+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, -+ rtc_epoch); -+ -+ rtc_read_alarm(ops, &alrm); -+ p += sprintf(p, "alrm_time\t: "); -+ if ((unsigned int)alrm.time.tm_hour <= 24) -+ p += sprintf(p, "%02d:", alrm.time.tm_hour); -+ else -+ p += sprintf(p, "**:"); -+ if ((unsigned int)alrm.time.tm_min <= 59) -+ p += sprintf(p, "%02d:", alrm.time.tm_min); -+ else -+ p += sprintf(p, "**:"); -+ if ((unsigned int)alrm.time.tm_sec <= 59) -+ p += sprintf(p, "%02d\n", alrm.time.tm_sec); -+ else -+ p += sprintf(p, "**\n"); -+ -+ p += sprintf(p, "alrm_date\t: "); -+ if ((unsigned int)alrm.time.tm_year <= 200) -+ p += sprintf(p, "%04d-", alrm.time.tm_year + 1900); -+ else -+ p += sprintf(p, "****-"); -+ if ((unsigned int)alrm.time.tm_mon <= 11) -+ p += sprintf(p, "%02d-", alrm.time.tm_mon + 1); -+ else -+ p += sprintf(p, "**-"); -+ if ((unsigned int)alrm.time.tm_mday <= 31) -+ p += sprintf(p, "%02d\n", alrm.time.tm_mday); -+ else -+ p += sprintf(p, "**\n"); -+ p += sprintf(p, "alrm_wakeup\t: %s\n", alrm.enabled ? "yes" : "no"); -+ p += sprintf(p, "alrm_pending\t: %s\n", alrm.pending ? "yes" : "no"); -+ -+ if (ops->proc) -+ p += ops->proc(p); -+ -+ len = (p - page) - off; -+ if (len < 0) -+ len = 0; -+ *eof = len <= count; -+ *start = page + off; -+ -+ return len; -+} -+ -+int register_rtc(struct rtc_ops *ops) -+{ -+ int ret = -EBUSY; -+ -+ down(&rtc_sem); -+ if (rtc_ops == NULL) { -+ rtc_ops = ops; -+ -+ ret = misc_register(&rtc_miscdev); -+ if (ret == 0) -+ create_proc_read_entry("driver/rtc", 0, 0, -+ rtc_read_proc, ops); -+ } -+ up(&rtc_sem); -+ -+ return ret; -+} -+ -+void unregister_rtc(struct rtc_ops *rtc) -+{ -+ down(&rtc_sem); -+ if (rtc == rtc_ops) { -+ remove_proc_entry("driver/rtc", NULL); -+ misc_deregister(&rtc_miscdev); -+ rtc_ops = NULL; -+ } -+ up(&rtc_sem); -+} -+ -+EXPORT_SYMBOL(rtc_time_to_tm); -+EXPORT_SYMBOL(rtc_tm_to_time); -+EXPORT_SYMBOL(rtc_update); -+EXPORT_SYMBOL(register_rtc); -+EXPORT_SYMBOL(unregister_rtc); ---- linux-2.6.5/arch/arm/common/Makefile~heh 2004-04-03 22:36:57.000000000 -0500 -+++ linux-2.6.5/arch/arm/common/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -2,7 +2,7 @@ - # Makefile for the linux kernel. - # - --obj-y += platform.o -+obj-y += platform.o rtctime.o - obj-$(CONFIG_ARM_AMBA) += amba.o - obj-$(CONFIG_ICST525) += icst525.o - obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o ---- linux-2.6.5/arch/arm/mach-pxa/generic.c~heh 2004-04-03 22:36:53.000000000 -0500 -+++ linux-2.6.5/arch/arm/mach-pxa/generic.c 2004-04-30 20:57:36.000000000 -0400 -@@ -132,7 +132,7 @@ - /* virtual physical length type */ - { 0xf6000000, 0x20000000, 0x01000000, MT_DEVICE }, /* PCMCIA0 IO */ - { 0xf7000000, 0x30000000, 0x01000000, MT_DEVICE }, /* PCMCIA1 IO */ -- { 0xf8000000, 0x40000000, 0x01400000, MT_DEVICE }, /* Devs */ -+ { 0xf8000000, 0x40000000, 0x01800000, MT_DEVICE }, /* Devs */ - { 0xfa000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */ - { 0xfc000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */ - { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE } /* UNCACHED_PHYS_0 */ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-pxa/cpu-pxa.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,322 @@ -+/* -+ * linux/arch/arm/mach-pxa/cpu-pxa.c -+ * -+ * Copyright (C) 2002,2003 Intrinsyc Software -+ * -+ * 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 -+ * -+ * History: -+ * 31-Jul-2002 : Initial version [FB] -+ * 29-Jan-2003 : added PXA255 support [FB] -+ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) -+ * -+ * Note: -+ * This driver may change the memory bus clock rate, but will not do any -+ * platform specific access timing changes... for example if you have flash -+ * memory connected to CS0, you will need to register a platform specific -+ * notifier which will adjust the memory access strobes to maintain a -+ * minimum strobe width. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define DEBUG 0 -+ -+#ifdef DEBUG -+ static unsigned int freq_debug = DEBUG; -+ MODULE_PARM(freq_debug, "i"); -+ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); -+#else -+ #define freq_debug 0 -+#endif -+ -+typedef struct -+{ -+ unsigned int khz; -+ unsigned int membus; -+ unsigned int cccr; -+ unsigned int div2; -+} pxa_freqs_t; -+ -+/* Define the refresh period in mSec for the SDRAM and the number of rows */ -+#define SDRAM_TREF 64 /* standard 64ms SDRAM */ -+#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ -+#define MDREFR_DRI(x) ((x*SDRAM_TREF)/(SDRAM_ROWS*32)) -+ -+#define CCLKCFG_TURBO 0x1 -+#define CCLKCFG_FCS 0x2 -+#define PXA25x_MIN_FREQ 99500 -+#define PXA25x_MAX_FREQ 398100 -+#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) -+#define MDREFR_DRI_MASK 0xFFF -+ -+ -+/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */ -+static pxa_freqs_t pxa255_run_freqs[] = -+{ -+ /* CPU MEMBUS CCCR DIV2*/ -+ { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */ -+ {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */ -+ {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */ -+ {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */ -+ {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */ -+ {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */ -+ {0,} -+}; -+#define NUM_RUN_FREQS (sizeof(pxa255_run_freqs)/sizeof(pxa_freqs_t)) -+ -+static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1]; -+ -+/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ -+static pxa_freqs_t pxa255_turbo_freqs[] = -+{ -+ /* CPU MEMBUS CCCR DIV2*/ -+ { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */ -+ {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */ -+ {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */ -+ {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */ -+ {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */ -+ {0,} -+}; -+#define NUM_TURBO_FREQS (sizeof(pxa255_turbo_freqs)/sizeof(pxa_freqs_t)) -+ -+static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1]; -+ -+/* find a valid frequency point */ -+static int pxa_verify_policy(struct cpufreq_policy *policy) -+{ -+ int ret; -+ struct cpufreq_frequency_table *pxa_freqs_table; -+ -+ if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) { -+ pxa_freqs_table = pxa255_run_freq_table; -+ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { -+ pxa_freqs_table = pxa255_turbo_freq_table; -+ } else if (policy->policy == CPUFREQ_POLICY_GOVERNOR) { -+ pxa_freqs_table = pxa255_run_freq_table; -+ } else { -+ printk("CPU PXA: Unknown policy found. " -+ "Using CPUFREQ_POLICY_PERFORMANCE\n"); -+ pxa_freqs_table = pxa255_run_freq_table; -+ } -+ ret=cpufreq_frequency_table_verify(policy, pxa_freqs_table); -+ -+ if(freq_debug) { -+ printk("Verified CPU policy: %dKhz min to %dKhz max\n", -+ policy->min, policy->max); -+ } -+ -+ return ret; -+} -+ -+static int pxa_set_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, -+ unsigned int relation) -+{ -+ int idx; -+ unsigned long cpus_allowed; -+ int cpu = policy->cpu; -+ struct cpufreq_freqs freqs; -+ pxa_freqs_t *pxa_freq_settings; -+ struct cpufreq_frequency_table *pxa_freqs_table; -+ unsigned long flags; -+ unsigned int unused; -+ unsigned int preset_mdrefr, postset_mdrefr; -+ -+ /* -+ * Save this threads cpus_allowed mask. -+ */ -+ cpus_allowed = current->cpus_allowed; -+ -+ /* -+ * Bind to the specified CPU. When this call returns, -+ * we should be running on the right CPU. -+ */ -+ set_cpus_allowed(current, 1 << cpu); -+ BUG_ON(cpu != smp_processor_id()); -+ -+ /* Get the current policy */ -+ if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) { -+ pxa_freq_settings = pxa255_run_freqs; -+ pxa_freqs_table = pxa255_run_freq_table; -+ }else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { -+ pxa_freq_settings = pxa255_turbo_freqs; -+ pxa_freqs_table = pxa255_turbo_freq_table; -+ }else if (policy->policy == CPUFREQ_POLICY_GOVERNOR) { -+ pxa_freq_settings = pxa255_run_freqs; -+ pxa_freqs_table = pxa255_run_freq_table; -+ }else { -+ printk("CPU PXA: Unknown policy found. " -+ "Using CPUFREQ_POLICY_PERFORMANCE\n"); -+ pxa_freq_settings = pxa255_run_freqs; -+ pxa_freqs_table = pxa255_run_freq_table; -+ } -+ -+ /* Lookup the next frequency */ -+ if (cpufreq_frequency_table_target(policy, pxa_freqs_table, -+ target_freq, relation, &idx)) { -+ return -EINVAL; -+ } -+ -+ freqs.old = policy->cur; -+ freqs.new = pxa_freq_settings[idx].khz; -+ freqs.cpu = policy->cpu; -+ if(freq_debug) { -+ printk(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", -+ freqs.new/1000, (pxa_freq_settings[idx].div2) ? -+ (pxa_freq_settings[idx].membus/2000) : -+ (pxa_freq_settings[idx].membus/1000)); -+ } -+ -+ void *ramstart = phys_to_virt(0xa0000000); -+ -+ /* -+ * Tell everyone what we're about to do... -+ * you should add a notify client with any platform specific -+ * Vcc changing capability -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ -+ /* Calculate the next MDREFR. If we're slowing down the SDRAM clock -+ * we need to preset the smaller DRI before the change. If we're speeding -+ * up we need to set the larger DRI value after the change. -+ */ -+ preset_mdrefr = postset_mdrefr = MDREFR; -+ if((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) { -+ preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) | -+ MDREFR_DRI(pxa_freq_settings[idx].membus); -+ } -+ postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) | -+ MDREFR_DRI(pxa_freq_settings[idx].membus); -+ -+ /* If we're dividing the memory clock by two for the SDRAM clock, this -+ * must be set prior to the change. Clearing the divide must be done -+ * after the change. -+ */ -+ if(pxa_freq_settings[idx].div2) { -+ preset_mdrefr |= MDREFR_DB2_MASK; -+ postset_mdrefr |= MDREFR_DB2_MASK; -+ } else { -+ postset_mdrefr &= ~MDREFR_DB2_MASK; -+ } -+ -+ local_irq_save(flags); -+ -+ /* Set new the CCCR */ -+ CCCR = pxa_freq_settings[idx].cccr; -+ -+ __asm__ __volatile__(" \ -+ ldr r4, [%1] ; /* load MDREFR */ \ -+ b 2f ; \ -+ .align 5 ; \ -+1: \ -+ str %4, [%1] ; /* preset the MDREFR */ \ -+ mcr p14, 0, %2, c6, c0, 0 ; /* set CCLKCFG[FCS] */ \ -+ str %5, [%1] ; /* postset the MDREFR */ \ -+ \ -+ b 3f ; \ -+2: b 1b ; \ -+3: nop ; \ -+ " -+ : "=&r" (unused) -+ : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart), \ -+ "r" (preset_mdrefr), "r" (postset_mdrefr) -+ : "r4", "r5"); -+ local_irq_restore(flags); -+ -+ /* -+ * Restore the CPUs allowed mask. -+ */ -+ set_cpus_allowed(current, cpus_allowed); -+ -+ /* -+ * Tell everyone what we've just done... -+ * you should add a notify client with any platform specific -+ * SDRAM refresh timer adjustments -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+ -+ return 0; -+} -+ -+static int pxa_cpufreq_init(struct cpufreq_policy *policy) -+{ -+ unsigned long cpus_allowed; -+ unsigned int cpu = policy->cpu; -+ int i; -+ -+ cpus_allowed = current->cpus_allowed; -+ -+ set_cpus_allowed(current, 1 << cpu); -+ BUG_ON(cpu != smp_processor_id()); -+ -+ /* set default policy and cpuinfo */ -+ policy->policy = CPUFREQ_POLICY_PERFORMANCE; -+ policy->cpuinfo.max_freq = PXA25x_MAX_FREQ; -+ policy->cpuinfo.min_freq = PXA25x_MIN_FREQ; -+ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ -+ policy->cur = get_clk_frequency_khz(0); /* current freq */ -+ policy->min = policy->max = policy->cur; -+ -+ /* Generate the run cpufreq_frequency_table struct */ -+ for(i=0;i - #include -+#include - #include - - #include -@@ -29,31 +32,162 @@ - #include - #include - --static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, -- unsigned long phys_addr, pgprot_t pgprot) -+extern rwlock_t vmlist_lock; -+extern struct vm_struct *vmlist; -+ -+static struct vm_struct * -+get_io_vm_area(unsigned long size, unsigned long align, unsigned long flags) - { -+ struct vm_struct **p, *tmp, *area; -+ unsigned long addr; -+ -+ area = (struct vm_struct *)kmalloc(sizeof(*area), GFP_KERNEL); -+ if (!area) -+ return NULL; -+ -+ align -= 1; -+ -+ size += PAGE_SIZE; -+ addr = VMALLOC_START; -+ write_lock(&vmlist_lock); -+ for (p = &vmlist; (tmp = *p); p = &tmp->next) { -+ if ((unsigned long)tmp->addr < addr) -+ continue; -+ if ((size + addr) < addr) -+ goto out; -+ if (size + addr <= (unsigned long) tmp->addr) -+ break; -+ addr = tmp->size + (unsigned long) tmp->addr; -+ if ((addr + align) < addr) -+ goto out; -+ addr = (addr + align) & ~align; -+ if (addr > VMALLOC_END - size) -+ goto out; -+ } -+ area->flags = flags; -+ area->addr = (void *)addr; -+ area->size = size; -+ area->next = *p; -+ *p = area; -+ write_unlock(&vmlist_lock); -+ return area; -+ -+out: -+ write_unlock(&vmlist_lock); -+ kfree(area); -+ return NULL; -+} -+ -+static inline void unmap_area_pte(pmd_t *pmd, unsigned long address, unsigned long size) -+{ -+ pte_t *ptep; - unsigned long end; - -+ if (pmd_none(*pmd)) -+ return; -+ if (pmd_bad(*pmd)) { -+ pmd_ERROR(*pmd); -+ pmd_clear(pmd); -+ return; -+ } -+ ptep = pte_offset_kernel(pmd, address); - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; -- if (address >= end) -- BUG(); - do { -- if (!pte_none(*pte)) { -- printk("remap_area_pte: page already exists\n"); -- BUG(); -+ pte_t pte; -+ pte = ptep_get_and_clear(ptep); -+ address += PAGE_SIZE; -+ ptep++; -+ if (pte_none(pte)) -+ continue; -+ if (pte_present(pte)) { -+ unsigned long pfn = pte_pfn(pte); -+ struct page *page; -+ -+ if (!pfn_valid(pfn)) -+ continue; -+ page = pfn_to_page(pfn); -+ if (!PageReserved(page)) -+ __free_page(page); -+ continue; - } -- set_pte(pte, pfn_pte(phys_addr >> PAGE_SHIFT, pgprot)); -+ printk(KERN_CRIT "Whee.. Swapped out page in kernel page table\n"); -+ } while (address < end); -+} -+ -+static inline void unmap_area_pmd(pgd_t *dir, unsigned long address, unsigned long size) -+{ -+ pmd_t *pmd; -+ unsigned long end; -+ -+ if (pgd_none(*dir)) -+ return; -+ if (pgd_bad(*dir)) { -+ pgd_ERROR(*dir); -+ pgd_clear(dir); -+ return; -+ } -+ pmd = pmd_offset(dir, address); -+ address &= ~PGDIR_MASK; -+ end = address + size; -+ if (end > PGDIR_SIZE) -+ end = PGDIR_SIZE; -+ do { -+ unmap_area_pte(pmd, address, end - address); -+ address = (address + PMD_SIZE) & PMD_MASK; -+ pmd++; -+ } while (address < end); -+} -+ -+static void -+unmap_area_pages(unsigned long address, unsigned long size) -+{ -+ unsigned long start = address; -+ unsigned long end = address + size; -+ pgd_t *dir; -+ -+ dir = pgd_offset_k(address); -+ flush_cache_vunmap(start, end); -+ do { -+ unmap_area_pmd(dir, address, end - address); -+ address = (address + PGDIR_SIZE) & PGDIR_MASK; -+ dir++; -+ } while (address && (address < end)); -+ flush_tlb_kernel_range(start, end); -+} -+ -+static inline void -+remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, -+ unsigned long pfn, pgprot_t pgprot) -+{ -+ unsigned long end; -+ -+ address &= ~PMD_MASK; -+ end = address + size; -+ if (end > PMD_SIZE) -+ end = PMD_SIZE; -+ BUG_ON(address >= end); -+ do { -+ if (!pte_none(*pte)) -+ goto bad; -+ -+ set_pte(pte, pfn_pte(pfn, pgprot)); - address += PAGE_SIZE; -- phys_addr += PAGE_SIZE; -+ pfn++; - pte++; - } while (address && (address < end)); -+ return; -+ -+ bad: -+ printk("remap_area_pte: page already exists\n"); -+ BUG(); - } - --static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, -- unsigned long phys_addr, unsigned long flags) -+static inline int -+remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, -+ unsigned long pfn, unsigned long flags) - { - unsigned long end; - pgprot_t pgprot; -@@ -64,51 +198,53 @@ - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - -- phys_addr -= address; -- if (address >= end) -- BUG(); -+ pfn -= address >> PAGE_SHIFT; -+ BUG_ON(address >= end); - - pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags); - do { - pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); - if (!pte) - return -ENOMEM; -- remap_area_pte(pte, address, end - address, address + phys_addr, pgprot); -+ remap_area_pte(pte, address, end - address, pfn + (address >> PAGE_SHIFT), pgprot); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); - return 0; - } - --static int remap_area_pages(unsigned long address, unsigned long phys_addr, -- unsigned long size, unsigned long flags) -+static int -+remap_area_pages(unsigned long start, unsigned long pfn, -+ unsigned long size, unsigned long flags) - { -- int error; -+ unsigned long address = start; -+ unsigned long end = start + size; -+ int err = 0; - pgd_t * dir; -- unsigned long end = address + size; - -- phys_addr -= address; -+ pfn -= address >> PAGE_SHIFT; - dir = pgd_offset(&init_mm, address); -- flush_cache_all(); -- if (address >= end) -- BUG(); -+ BUG_ON(address >= end); - spin_lock(&init_mm.page_table_lock); - do { -- pmd_t *pmd; -- pmd = pmd_alloc(&init_mm, dir, address); -- error = -ENOMEM; -- if (!pmd) -+ pmd_t *pmd = pmd_alloc(&init_mm, dir, address); -+ if (!pmd) { -+ err = -ENOMEM; - break; -+ } - if (remap_area_pmd(pmd, address, end - address, -- phys_addr + address, flags)) -+ pfn + (address >> PAGE_SHIFT), flags)) { -+ err = -ENOMEM; - break; -- error = 0; -+ } -+ - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); -+ - spin_unlock(&init_mm.page_table_lock); -- flush_tlb_all(); -- return error; -+ flush_cache_vmap(start, end); -+ return err; - } - - /* -@@ -146,11 +282,11 @@ - /* - * Ok, go for it.. - */ -- area = get_vm_area(size, VM_IOREMAP); -+ area = get_io_vm_area(size, align, VM_IOREMAP); - if (!area) - return NULL; - addr = area->addr; -- if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { -+ if (remap_area_pages((unsigned long) addr, phys_addr >> PAGE_SHIFT, size, flags)) { - vfree(addr); - return NULL; - } -@@ -159,5 +295,26 @@ - - void __iounmap(void *addr) - { -- vfree((void *) (PAGE_MASK & (unsigned long) addr)); -+ struct vm_struct **p, *tmp; -+ -+ if (!addr) -+ return; -+ -+ if ((PAGE_SIZE - 1) & (unsigned long)addr) { -+ printk(KERN_ERR "Trying to iounmap() bad address (%p)\n", addr); -+ return; -+ } -+ -+ write_lock(&vmlist_lock); -+ for (p = &vmlist; (tmp = *p); p = &tmp->next) { -+ if (tmp->addr == addr) { -+ *p = tmp->next; -+ unmap_area_pages((unsigned long) tmp->addr, tmp->size); -+ write_unlock(&vmlist_lock); -+ kfree(tmp); -+ return; -+ } -+ } -+ write_unlock(&vmlist_lock); -+ printk(KERN_ERR "Trying to iounmap nonexistent area (%p)\n", addr); - } ---- linux-2.6.5/arch/arm/mm/proc-xscale.S~heh 2004-04-03 22:38:05.000000000 -0500 -+++ linux-2.6.5/arch/arm/mm/proc-xscale.S 2004-04-30 20:57:36.000000000 -0400 -@@ -563,11 +563,62 @@ - movne r2, #0 @ no -> fault - - str r2, [r0] @ hardware version -+ -+ @ We try to map 64K page entries when possible. -+ @ We do that for kernel space only since the usage pattern from -+ @ the setting of VM area is quite simple. User space is not worth -+ @ the implied complexity because of ever randomly changing PTEs -+ @ (page aging, swapout, etc) requiring constant coherency checks. -+ @ Since PTEs are usually set in increasing order, we test the -+ @ possibility for a large page only when given the last PTE of a -+ @ 64K boundary. -+ tsteq r1, #L_PTE_USER -+ andeq r1, r0, #(15 << 2) -+ teqeq r1, #(15 << 2) -+ beq 1f -+ - mov ip, #0 - mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line - mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer - mov pc, lr - -+ @ See if we have 16 identical PTEs but with consecutive base addresses -+1: bic r3, r2, #0x0000f000 -+ mov r1, #0x0000f000 -+2: eor r2, r2, r3 -+ teq r2, r1 -+ bne 4f -+ subs r1, r1, #0x00001000 -+ ldr r2, [r0, #-4]! -+ bne 2b -+ eors r2, r2, r3 -+ bne 4f -+ -+ @ Now create our LARGE PTE from the current EXT one. -+ bic r3, r3, #PTE_TYPE_MASK -+ orr r3, r3, #PTE_TYPE_LARGE -+ and r2, r3, #0x30 @ EXT_AP --> LARGE_AP0 -+ orr r2, r2, r2, lsl #2 @ add LARGE_AP1 -+ orr r2, r2, r2, lsl #4 @ add LARGE_AP3 + LARGE_AP2 -+ and r1, r3, #0x3c0 @ EXT_TEX -+ bic r3, r3, #0x3c0 -+ orr r2, r2, r1, lsl #(12 - 6) @ --> LARGE_TEX -+ orr r2, r2, r3 @ add remaining bits -+ -+ @ then put it in the pagetable -+ mov r3, r2 -+3: strd r2, [r0], #8 -+ tst r0, #(15 << 2) -+ bne 3b -+ -+ @ Then sync the 2 corresponding cache lines -+ sub r0, r0, #(16 << 2) -+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line -+4: orr r0, r0, #(15 << 2) -+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line -+ mov ip, #0 -+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer -+ mov pc, lr - - .ltorg - ---- linux-2.6.5/arch/arm/mach-sa1100/Makefile~heh 2004-04-03 22:38:26.000000000 -0500 -+++ linux-2.6.5/arch/arm/mach-sa1100/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -3,7 +3,7 @@ - # - - # Common support --obj-y := generic.o irq.o dma.o -+obj-y := generic.o irq.o dma.o nmi-oopser.o - obj-m := - obj-n := - obj- := -@@ -88,7 +88,7 @@ - obj-$(CONFIG_LEDS) += $(led-y) - - # SA1110 USB client support --#obj-$(CONFIG_SA1100_USB) += usb/ -+obj-$(CONFIG_SA1100_USB) += usb/ - - # Miscelaneous functions - obj-$(CONFIG_PM) += pm.o sleep.o ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/strings.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,43 @@ -+/* -+ * usb/strings.h -+ * -+ * Copyright (C) 2002 Russell King. -+ * -+ * USB device string handling, built upon usb buffers. -+ */ -+#ifndef USBDEV_STRINGS_H -+#define USBDEV_STRINGS_H -+ -+#include -+ -+struct usb_buf; -+ -+#define NR_STRINGS 8 -+ -+struct usb_string_descriptor; -+ -+struct usbc_strs { -+ spinlock_t lock; -+ struct usb_buf *buf[NR_STRINGS]; -+}; -+ -+#define usbc_string_desc(buf) ((struct usb_string_descriptor *)(buf)->data) -+ -+void usbc_string_from_cstr(struct usb_buf *buf, const char *str); -+struct usb_buf *usbc_string_alloc(int len); -+void usbc_string_free(struct usb_buf *buf); -+ -+int usbc_string_add(struct usbc_strs *table, struct usb_buf *buf); -+void usbc_string_del(struct usbc_strs *table, int nr); -+ -+/* -+ * Note: usbc_string_find() increments the buffer use count. -+ * You must call usbb_put() after use. -+ */ -+struct usb_buf * -+usbc_string_find(struct usbc_strs *table, unsigned int lang, unsigned int idx); -+ -+void usbc_string_free_all(struct usbc_strs *table); -+void usbc_string_init(struct usbc_strs *table); -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_ctl.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,114 @@ -+/* -+ * Copyright (C) Compaq Computer Corporation, 1998, 1999 -+ * Copyright (C) Extenex Corporation 2001 -+ * -+ * usb_ctl.h -+ * -+ * PRIVATE interface used to share info among components of the SA-1100 USB -+ * core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core -+ * should use sa1100_usb.h. -+ * -+ */ -+ -+#ifndef _USB_CTL_H -+#define _USB_CTL_H -+ -+#include /* dmach_t */ -+ -+struct usb_client; -+ -+struct usb_stats_t { -+ unsigned long ep0_fifo_write_failures; -+ unsigned long ep0_bytes_written; -+ unsigned long ep0_fifo_read_failures; -+ unsigned long ep0_bytes_read; -+}; -+ -+struct usb_info_t -+{ -+ struct usb_client *client; -+ dma_regs_t *dmach_tx, *dmach_rx; -+ int state; -+ unsigned char address; -+ struct usb_stats_t stats; -+}; -+ -+/* in usb_ctl.c */ -+extern struct usb_info_t usbd_info; -+ -+/* -+ * Function Prototypes -+ */ -+enum { kError=-1, kEvSuspend=0, kEvReset=1, -+ kEvResume=2, kEvAddress=3, kEvConfig=4, kEvDeConfig=5 }; -+int usbctl_next_state_on_event( int event ); -+ -+/* endpoint zero */ -+void ep0_reset(void); -+void ep0_int_hndlr(void); -+ -+/* receiver */ -+int ep1_recv(void); -+int ep1_init(dma_regs_t *dma); -+void ep1_int_hndlr(int status); -+void ep1_reset(void); -+void ep1_stall(void); -+ -+/* xmitter */ -+void ep2_reset(void); -+int ep2_init(dma_regs_t *dma); -+void ep2_int_hndlr(int status); -+void ep2_stall(void); -+ -+#define UDC_write(reg, val) { \ -+ int i = 10000; \ -+ do { \ -+ (reg) = (val); \ -+ if (i-- <= 0) { \ -+ printk( "%s [%d]: write %#x to %p (%#x) failed\n", \ -+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \ -+ break; \ -+ } \ -+ } while((reg) != (val)); \ -+} -+ -+#define UDC_set(reg, val) { \ -+ int i = 10000; \ -+ do { \ -+ (reg) |= (val); \ -+ if (i-- <= 0) { \ -+ printk( "%s [%d]: set %#x of %p (%#x) failed\n", \ -+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \ -+ break; \ -+ } \ -+ } while(!((reg) & (val))); \ -+} -+ -+#define UDC_clear(reg, val) { \ -+ int i = 10000; \ -+ do { \ -+ (reg) &= ~(val); \ -+ if (i-- <= 0) { \ -+ printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \ -+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \ -+ break; \ -+ } \ -+ } while((reg) & (val)); \ -+} -+ -+#define UDC_flip(reg, val) { \ -+ int i = 10000; \ -+ (reg) = (val); \ -+ do { \ -+ (reg) = (val); \ -+ if (i-- <= 0) { \ -+ printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \ -+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \ -+ break; \ -+ } \ -+ } while(((reg) & (val))); \ -+} -+ -+ -+#define CHECK_ADDRESS { if ( Ser0UDCAR == 1 ) { printk("%s:%d I lost my address!!!\n",__FUNCTION__, __LINE__);}} -+#endif /* _USB_CTL_H */ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_send.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,302 @@ -+/* -+ * Generic xmit layer for the SA1100 USB client function -+ * Copyright (c) 2001 by Nicolas Pitre -+ * -+ * This code was loosely inspired by the original version which was -+ * Copyright (c) Compaq Computer Corporation, 1998-1999 -+ * -+ * 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. -+ * -+ * This is still work in progress... -+ * -+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details. -+ * 15/03/2001 - ep2_start now sets UDCAR to overcome something that is hardware -+ * bug, I think. green@iXcelerator.com -+ */ -+ -+#include -+#include -+#include -+#include // for the massive_attack hack 28Feb01ww -+#include -+ -+#include -+ -+#include "usbdev.h" -+#include "sa1100_usb.h" -+#include "sa1100usb.h" -+ -+static unsigned int ep2_curdmalen; -+static unsigned int ep2_remain; -+ -+static struct sausb_dev *ep2_dev; -+ -+static void udc_set_cs2(u32 val, u32 mask, u32 check) -+{ -+ int i = 0; -+ -+ do { -+ Ser0UDCCS2 = val; -+ udelay(1); -+ if ((Ser0UDCCS2 & mask) == check) -+ return; -+ } while (i++ < 10000); -+ -+ printk("UDC: UDCCS2 write timed out: val=0x%08x\n", val); -+} -+ -+/* set feature stall executing, async */ -+static void ep2_start(struct sausb_dev *usb) -+{ -+ ep2_curdmalen = min(ep2_remain, usb->ep[1].maxpktsize); -+ if (ep2_curdmalen == 0) -+ return; -+ -+ /* -+ * must do this _before_ queue buffer.. -+ * stop NAKing IN tokens -+ */ -+ udc_set_cs2(usb->ep[1].udccs | UDCCS2_TPC, UDCCS2_TPC, 0); -+ -+ UDC_write(Ser0UDCIMP, ep2_curdmalen - 1); -+ -+ /* Remove if never seen...8Mar01ww */ -+ { -+ int massive_attack = 20; -+ while (Ser0UDCIMP != ep2_curdmalen - 1 && massive_attack--) { -+ printk("usbsnd: Oh no you don't! Let me spin..."); -+ udelay(500); -+ printk("and try again...\n"); -+ UDC_write(Ser0UDCIMP, ep2_curdmalen - 1); -+ } -+ if (massive_attack != 20) { -+ if (Ser0UDCIMP != ep2_curdmalen - 1) -+ printk("usbsnd: Massive attack FAILED. %d\n", -+ 20 - massive_attack); -+ else -+ printk("usbsnd: Massive attack WORKED. %d\n", -+ 20 - massive_attack); -+ } -+ } -+ /* End remove if never seen... 8Mar01ww */ -+ -+ /* -+ * fight stupid silicon bug -+ */ -+ Ser0UDCAR = usb->ctl->address; -+ -+ sa1100_start_dma(usb->ep[1].dmach, usb->ep[1].pktdma, ep2_curdmalen); -+} -+ -+static void udc_ep2_done(struct sausb_dev *usb, int flag) -+{ -+ int size = usb->ep[1].buflen - ep2_remain; -+ -+ if (!usb->ep[1].buflen) -+ return; -+ -+ dma_unmap_single(usb->dev, usb->ep[1].bufdma, usb->ep[1].buflen, -+ DMA_TO_DEVICE); -+ -+ usb->ep[1].bufdma = 0; -+ usb->ep[1].buflen = 0; -+ usb->ep[1].pktdma = 0; -+ -+ if (usb->ep[1].cb_func) -+ usb->ep[1].cb_func(usb->ep[1].cb_data, flag, size); -+} -+ -+/* -+ * Initialisation. Clear out the status. -+ */ -+void udc_ep2_init(struct sausb_dev *usb) -+{ -+ ep2_dev = usb; -+ -+ usb->ep[1].udccs = UDCCS2_FST; -+ -+ BUG_ON(usb->ep[1].buflen); -+ BUG_ON(usb->ep[1].pktlen); -+ -+ sa1100_reset_dma(usb->ep[1].dmach); -+} -+ -+/* -+ * Note: rev A0-B2 chips don't like FST -+ */ -+void udc_ep2_halt(struct sausb_dev *usb, int halt) -+{ -+ usb->ep[1].host_halt = halt; -+ -+ if (halt) { -+ usb->ep[1].udccs |= UDCCS2_FST; -+ udc_set_cs2(UDCCS2_FST, UDCCS2_FST, UDCCS2_FST); -+ } else { -+ sa1100_clear_dma(usb->ep[1].dmach); -+ -+ udc_set_cs2(UDCCS2_FST, UDCCS2_FST, UDCCS2_FST); -+ udc_set_cs2(0, UDCCS2_FST, 0); -+ udc_set_cs2(UDCCS2_SST, UDCCS2_SST, 0); -+ -+ usb->ep[1].udccs &= ~UDCCS2_FST; -+ -+ udc_ep2_done(usb, -EINTR); -+ } -+} -+ -+/* -+ * This gets called when we receive a SET_CONFIGURATION packet to EP0. -+ * We were configured. We can now send packets to the host. -+ */ -+void udc_ep2_config(struct sausb_dev *usb, unsigned int maxpktsize) -+{ -+ /* -+ * We shouldn't be transmitting anything... -+ */ -+ BUG_ON(usb->ep[1].buflen); -+ BUG_ON(usb->ep[1].pktlen); -+ -+ /* -+ * Set our configuration. -+ */ -+ usb->ep[1].maxpktsize = maxpktsize; -+ usb->ep[1].configured = 1; -+ -+ /* -+ * Clear any pending TPC status. -+ */ -+ udc_set_cs2(UDCCS2_TPC, UDCCS2_TPC, 0); -+ -+ /* -+ * Enable EP2 interrupts. -+ */ -+ usb->udccr &= ~UDCCR_TIM; -+ UDC_write(Ser0UDCCR, usb->udccr); -+ -+ usb->ep[1].udccs = 0; -+} -+ -+/* -+ * We saw a reset from the attached hub, or were deconfigured. -+ * This means we are no longer configured. -+ */ -+void udc_ep2_reset(struct sausb_dev *usb) -+{ -+ /* -+ * Disable EP2 interrupts. -+ */ -+ usb->udccr |= UDCCR_TIM; -+ UDC_write(Ser0UDCCR, usb->udccr); -+ -+ usb->ep[1].configured = 0; -+ usb->ep[1].maxpktsize = 0; -+ -+ sa1100_reset_dma(usb->ep[1].dmach); -+ udc_ep2_done(usb, -EINTR); -+} -+ -+void udc_ep2_int_hndlr(struct sausb_dev *usb) -+{ -+ u32 status = Ser0UDCCS2; -+ -+ // check for stupid silicon bug. -+ if (Ser0UDCAR != usb->ctl->address) -+ Ser0UDCAR = usb->ctl->address; -+ -+ udc_set_cs2(usb->ep[1].udccs | UDCCS2_SST, UDCCS2_SST, 0); -+ -+ if (!(status & UDCCS2_TPC)) { -+ printk("usb_send: Not TPC: UDCCS2 = %x\n", status); -+ return; -+ } -+ -+ sa1100_stop_dma(usb->ep[1].dmach); -+ -+ if (status & (UDCCS2_TPE | UDCCS2_TUR)) { -+ printk("usb_send: transmit error %x\n", status); -+ usb->ep[1].fifo_errs ++; -+ udc_ep2_done(usb, -EIO); -+ } else { -+ unsigned int imp; -+#if 1 // 22Feb01ww/Oleg -+ imp = ep2_curdmalen; -+#else -+ // this is workaround for case when setting -+ // of Ser0UDCIMP was failed -+ imp = Ser0UDCIMP + 1; -+#endif -+ usb->ep[1].pktdma += imp; -+ ep2_remain -= imp; -+ -+ usb->ep[1].bytes += imp; -+ usb->ep[1].packets++; -+ -+ sa1100_clear_dma(usb->ep[1].dmach); -+ -+ if (ep2_remain != 0) { -+ ep2_start(usb); -+ } else { -+ udc_ep2_done(usb, 0); -+ } -+ } -+} -+ -+int udc_ep2_send(struct sausb_dev *usb, char *buf, int len) -+{ -+ unsigned long flags; -+ dma_addr_t dma; -+ int ret; -+ -+ if (!buf || len == 0) -+ return -EINVAL; -+ -+ dma = dma_map_single(usb->dev, buf, len, DMA_TO_DEVICE); -+ -+ spin_lock_irqsave(&usb->lock, flags); -+ do { -+ if (!usb->ep[1].configured) { -+ ret = -ENODEV; -+ break; -+ } -+ -+ if (usb->ep[1].buflen) { -+ ret = -EBUSY; -+ break; -+ } -+ -+ usb->ep[1].bufdma = dma; -+ usb->ep[1].buflen = len; -+ usb->ep[1].pktdma = dma; -+ ep2_remain = len; -+ -+ sa1100_clear_dma(usb->ep[1].dmach); -+ -+ ep2_start(usb); -+ ret = 0; -+ } while (0); -+ spin_unlock_irqrestore(&usb->lock, flags); -+ -+ if (ret) -+ dma_unmap_single(usb->dev, dma, len, DMA_TO_DEVICE); -+ -+ return ret; -+} -+ -+void udc_ep2_send_reset(struct sausb_dev *usb) -+{ -+ sa1100_reset_dma(usb->ep[1].dmach); -+ udc_ep2_done(usb, -EINTR); -+} -+ -+int udc_ep2_idle(struct sausb_dev *usb) -+{ -+ if (!usb->ep[1].configured) -+ return -ENODEV; -+ -+ if (usb->ep[1].buflen) -+ return -EBUSY; -+ -+ return 0; -+} ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb-char.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,709 @@ -+/* -+ * (C) Copyright 2000-2001 Extenex Corporation -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * usb-char.c -+ * -+ * Miscellaneous character device interface for SA1100 USB function -+ * driver. -+ * -+ * Background: -+ * The SA1100 function driver ported from the Compaq Itsy project -+ * has an interface, usb-eth.c, to feed network packets over the -+ * usb wire and into the Linux TCP/IP stack. -+ * -+ * This file replaces that one with a simple character device -+ * interface that allows unstructured "byte pipe" style reads and -+ * writes over the USB bulk endpoints by userspace programs. -+ * -+ * A new define, CONFIG_SA1100_USB_NETLINK, has been created that, -+ * when set, (the default) causes the ethernet interface to be used. -+ * When not set, this more pedestrian character interface is linked -+ * in instead. -+ * -+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details. -+ * -+ * ward.willats@extenex.com -+ * -+ * To do: -+ * - Can't dma into ring buffer directly with dma_map/unmap usb_recv -+ * uses and get bytes out at the same time DMA is going on. Investigate: -+ * a) changing usb_recv to use alloc_consistent() at client request; or -+ * b) non-ring-buffer based data structures. In the meantime, I am using -+ * a bounce buffer. Simple, but wasteful. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "usb-char.h" -+#include "client.h" -+ -+ -+ -+////////////////////////////////////////////////////////////////////////////// -+// Driver Options -+////////////////////////////////////////////////////////////////////////////// -+ -+#define VERSION "0.4" -+ -+ -+#define VERBOSITY 1 -+ -+#if VERBOSITY -+# define PRINTK(x, a...) printk (x, ## a) -+#else -+# define PRINTK(x, a...) /**/ -+#endif -+ -+////////////////////////////////////////////////////////////////////////////// -+// Globals - Macros - Enums - Structures -+////////////////////////////////////////////////////////////////////////////// -+#ifndef MIN -+#define MIN( a, b ) ((a)<(b)?(a):(b)) -+#endif -+ -+typedef int bool; enum { false = 0, true = 1 }; -+ -+static const char pszMe[] = "usbchr: "; -+ -+static wait_queue_head_t wq_read; -+static wait_queue_head_t wq_write; -+static wait_queue_head_t wq_poll; -+ -+/* Serialze multiple writers onto the transmit hardware -+.. since we sleep the writer during transmit to stay in -+.. sync. (Multiple writers don't make much sense, but..) */ -+static DECLARE_MUTEX( xmit_sem ); -+ -+// size of usb DATA0/1 packets. 64 is standard maximum -+// for bulk transport, though most hosts seem to be able -+// to handle larger. -+#define TX_PACKET_SIZE 64 -+#define RX_PACKET_SIZE 64 -+#define RBUF_SIZE (4*PAGE_SIZE) -+ -+static struct wcirc_buf { -+ char *buf; -+ int in; -+ int out; -+} rx_ring = { NULL, 0, 0 }; -+ -+static struct { -+ unsigned long cnt_rx_complete; -+ unsigned long cnt_rx_errors; -+ unsigned long bytes_rx; -+ unsigned long cnt_tx_timeouts; -+ unsigned long cnt_tx_errors; -+ unsigned long bytes_tx; -+} charstats; -+ -+ -+static char * tx_buf = NULL; -+static char * packet_buffer = NULL; -+static int sending = 0; -+static int usb_ref_count = 0; -+static int last_tx_result = 0; -+static int last_rx_result = 0; -+static int last_tx_size = 0; -+static struct timer_list tx_timer; -+ -+////////////////////////////////////////////////////////////////////////////// -+// Prototypes -+////////////////////////////////////////////////////////////////////////////// -+static char * what_the_f( int e ); -+static void free_txrx_buffers( void ); -+static void twiddle_descriptors(struct usb_client *client); -+static int usbc_open( struct inode *pInode, struct file *pFile ); -+static void rx_done_callback_packet_buffer(void *data, int flag, int size ); -+ -+static void tx_timeout( unsigned long ); -+static void tx_done_callback(void *data, int flag, int size ); -+ -+static ssize_t usbc_read( struct file *, char *, size_t, loff_t * ); -+static ssize_t usbc_write( struct file *, const char *, size_t, loff_t * ); -+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait ); -+static int usbc_ioctl( struct inode *pInode, struct file *pFile, -+ unsigned int nCmd, unsigned long argument ); -+static int usbc_close( struct inode *pInode, struct file *pFile ); -+ -+#ifdef CONFIG_SA1100_EXTENEX1 -+static void extenex_configured_notify_proc( void ); -+#endif -+////////////////////////////////////////////////////////////////////////////// -+// Private Helpers -+////////////////////////////////////////////////////////////////////////////// -+ -+static char * what_the_f( int e ) -+{ -+ char * p; -+ switch( e ) { -+ case 0: -+ p = "noErr"; -+ break; -+ case -ENODEV: -+ p = "ENODEV - usb not in config state"; -+ break; -+ case -EBUSY: -+ p = "EBUSY - another request on the hardware"; -+ break; -+ case -EAGAIN: -+ p = "EAGAIN"; -+ break; -+ case -EINTR: -+ p = "EINTR - interrupted\n"; -+ break; -+ case -EPIPE: -+ p = "EPIPE - zero length xfer\n"; -+ break; -+ default: -+ p = "????"; -+ break; -+ } -+ return p; -+} -+ -+static void free_txrx_buffers( void ) -+{ -+ if ( rx_ring.buf != NULL ) { -+ kfree( rx_ring.buf ); -+ rx_ring.buf = NULL; -+ } -+ if ( packet_buffer != NULL ) { -+ kfree( packet_buffer ); -+ packet_buffer = NULL; -+ } -+ if ( tx_buf != NULL ) { -+ kfree( tx_buf ); -+ tx_buf = NULL; -+ } -+} -+ -+/* twiddle_descriptors() -+ * It is between open() and start(). Setup descriptors. -+ */ -+static void twiddle_descriptors(struct usb_client *client) -+{ -+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr(); -+ -+ cdb->ep1.wMaxPacketSize = cpu_to_le16(RX_PACKET_SIZE); -+ cdb->ep2.wMaxPacketSize = cpu_to_le16(TX_PACKET_SIZE); -+ -+#ifdef CONFIG_SA1100_EXTENEX1 -+ if (machine_is_extenex1()) { -+ int nr; -+ -+ cdb->cfg.bmAttributes = USB_CONFIG_SELFPOWERED; -+ cdb->cfg.MaxPower = 0; -+ -+ nr = sa1100_usb_add_string(client->ctl, "HHT Bulk Transfer"); -+ -+ if (nr > 0) -+ cdb->intf.iInterface = nr; -+ } -+#endif -+} -+ -+////////////////////////////////////////////////////////////////////////////// -+// ASYNCHRONOUS -+////////////////////////////////////////////////////////////////////////////// -+static void kick_start_rx( void ) -+{ -+ if ( usb_ref_count ) { -+ int total_space = CIRC_SPACE( rx_ring.in, rx_ring.out, RBUF_SIZE ); -+ if ( total_space >= RX_PACKET_SIZE ) { -+ sa1100_usb_recv_set_callback(rx_done_callback_packet_buffer, NULL); -+ sa1100_usb_recv( packet_buffer, RX_PACKET_SIZE); -+ } -+ } -+} -+/* -+ * rx_done_callback_packet_buffer() -+ * We have completed a DMA xfer into the temp packet buffer. -+ * Move to ring. -+ * -+ * flag values: -+ * on init, -EAGAIN -+ * on reset, -EINTR -+ * on RPE, -EIO -+ * on short packet -EPIPE -+ */ -+static void -+rx_done_callback_packet_buffer(void *data, int flag, int size ) -+{ -+ charstats.cnt_rx_complete++; -+ -+ if ( flag == 0 || flag == -EPIPE ) { -+ size_t n; -+ -+ charstats.bytes_rx += size; -+ -+ n = CIRC_SPACE_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE ); -+ n = MIN( n, size ); -+ size -= n; -+ -+ memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer, n ); -+ rx_ring.in = (rx_ring.in + n) & (RBUF_SIZE-1); -+ memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer + n, size ); -+ rx_ring.in = (rx_ring.in + size) & (RBUF_SIZE-1); -+ -+ wake_up_interruptible( &wq_read ); -+ wake_up_interruptible( &wq_poll ); -+ -+ last_rx_result = 0; -+ -+ kick_start_rx(); -+ -+ } else if ( flag != -EAGAIN ) { -+ charstats.cnt_rx_errors++; -+ last_rx_result = flag; -+ wake_up_interruptible( &wq_read ); -+ wake_up_interruptible( &wq_poll ); -+ } -+ else /* init, start a read */ -+ kick_start_rx(); -+} -+ -+ -+static void tx_timeout( unsigned long unused ) -+{ -+ printk( "%stx timeout\n", pszMe ); -+ sa1100_usb_send_reset(); -+ charstats.cnt_tx_timeouts++; -+} -+ -+ -+// on init, -EAGAIN -+// on reset, -EINTR -+// on TPE, -EIO -+static void tx_done_callback(void *data, int flags, int size ) -+{ -+ if ( flags == 0 ) -+ charstats.bytes_tx += size; -+ else -+ charstats.cnt_tx_errors++; -+ last_tx_size = size; -+ last_tx_result = flags; -+ sending = 0; -+ wake_up_interruptible( &wq_write ); -+ wake_up_interruptible( &wq_poll ); -+} -+ -+ -+static struct usb_client usbc_client = { -+ .name = "usb-char", -+ -+ /* -+ * USB client identification for host use in CPU endian. -+ */ -+ .vendor = 0, -+ .product = 0, -+ .version = 0, -+ .class = 0xff, -+ .subclass = 0, -+ .protocol = 0, -+}; -+ -+#ifdef CONFIG_SA1100_EXTENEX1 -+#include "../../../drivers/char/ex_gpio.h" -+static void extenex_state_change(void *data, int state, int oldstate) -+{ -+ if (exgpio_play_string( "440,1:698,1") == -EAGAIN) -+ printk( "%sWanted to BEEP but ex_gpio not open\n", pszMe ); -+} -+#endif -+ -+////////////////////////////////////////////////////////////////////////////// -+// Workers -+////////////////////////////////////////////////////////////////////////////// -+ -+static int usbc_open(struct inode *pInode, struct file *pFile) -+{ -+ int retval = 0; -+ -+ PRINTK( KERN_DEBUG "%sopen()\n", pszMe ); -+ -+#ifdef CONFIG_SA1100_EXTENEX1 -+ if (machine_is_extenex1()) { -+ usbc_client.vendor = 0x0c9f; -+ usbc_client.product = 0x0100; -+ usbc_client.version = 0x0001; -+ usbc_client.manufacturer_str = "Extenex"; -+ usbc_client.product_str = "Handheld Theater"; -+ usbc_client.serial_str = "00000000"; -+ usbc_client.state_change = extenex_state_change; -+ } -+#endif -+ -+ /* start usb core */ -+ retval = usbctl_open(&usbc_client); -+ if (retval) -+ return retval; -+ -+ /* allocate memory */ -+ if ( usb_ref_count == 0 ) { -+ tx_buf = (char*) kmalloc( TX_PACKET_SIZE, GFP_KERNEL | GFP_DMA ); -+ if ( tx_buf == NULL ) { -+ printk( "%sARGHH! COULD NOT ALLOCATE TX BUFFER\n", pszMe ); -+ goto malloc_fail; -+ } -+ rx_ring.buf = -+ (char*) kmalloc( RBUF_SIZE, GFP_KERNEL ); -+ -+ if ( rx_ring.buf == NULL ) { -+ printk( "%sARGHH! COULD NOT ALLOCATE RX BUFFER\n", pszMe ); -+ goto malloc_fail; -+ } -+ -+ packet_buffer = -+ (char*) kmalloc( RX_PACKET_SIZE, GFP_KERNEL | GFP_DMA ); -+ -+ if ( packet_buffer == NULL ) { -+ printk( "%sARGHH! COULD NOT ALLOCATE RX PACKET BUFFER\n", pszMe ); -+ goto malloc_fail; -+ } -+ rx_ring.in = rx_ring.out = 0; -+ memset( &charstats, 0, sizeof( charstats ) ); -+ sending = 0; -+ last_tx_result = 0; -+ last_tx_size = 0; -+ } -+ -+ /* modify default descriptors */ -+ twiddle_descriptors(&usbc_client); -+ -+ retval = usbctl_start(&usbc_client); -+ if ( retval ) { -+ printk( "%sAGHH! Could not USB core\n", pszMe ); -+ free_txrx_buffers(); -+ return retval; -+ } -+ usb_ref_count++; /* must do _before_ kick_start() */ -+ MOD_INC_USE_COUNT; -+ kick_start_rx(); -+ return 0; -+ -+ malloc_fail: -+ free_txrx_buffers(); -+ return -ENOMEM; -+} -+ -+/* -+ * Read endpoint. Note that you can issue a read to an -+ * unconfigured endpoint. Eventually, the host may come along -+ * and configure underneath this module and data will appear. -+ */ -+static ssize_t usbc_read( struct file *pFile, char *pUserBuffer, -+ size_t stCount, loff_t *pPos ) -+{ -+ ssize_t retval; -+ unsigned long flags; -+ DECLARE_WAITQUEUE( wait, current ); -+ -+ PRINTK( KERN_DEBUG "%sread()\n", pszMe ); -+ -+ local_irq_save(flags); -+ if ( last_rx_result == 0 ) { -+ local_irq_restore( flags ); -+ } else { /* an error happended and receiver is paused */ -+ local_irq_restore( flags ); -+ last_rx_result = 0; -+ kick_start_rx(); -+ } -+ -+ add_wait_queue( &wq_read, &wait ); -+ while( 1 ) { -+ ssize_t bytes_avail; -+ ssize_t bytes_to_end; -+ -+ set_current_state( TASK_INTERRUPTIBLE ); -+ -+ /* snap ring buf state */ -+ local_irq_save( flags ); -+ bytes_avail = CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE ); -+ bytes_to_end = CIRC_CNT_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE ); -+ local_irq_restore( flags ); -+ -+ if ( bytes_avail != 0 ) { -+ ssize_t bytes_to_move = MIN( stCount, bytes_avail ); -+ retval = 0; // will be bytes transfered -+ if ( bytes_to_move != 0 ) { -+ size_t n = MIN( bytes_to_end, bytes_to_move ); -+ if ( copy_to_user( pUserBuffer, -+ &rx_ring.buf[ rx_ring.out ], -+ n ) ) { -+ retval = -EFAULT; -+ break; -+ } -+ bytes_to_move -= n; -+ retval += n; -+ // might go 1 char off end, so wrap -+ rx_ring.out = ( rx_ring.out + n ) & (RBUF_SIZE-1); -+ if ( copy_to_user( pUserBuffer + n, -+ &rx_ring.buf[ rx_ring.out ], -+ bytes_to_move ) -+ ) { -+ retval = -EFAULT; -+ break; -+ } -+ rx_ring.out += bytes_to_move; // cannot wrap -+ retval += bytes_to_move; -+ kick_start_rx(); -+ } -+ break; -+ } -+ else if ( last_rx_result ) { -+ retval = last_rx_result; -+ break; -+ } -+ else if ( pFile->f_flags & O_NONBLOCK ) { // no data, can't sleep -+ retval = -EAGAIN; -+ break; -+ } -+ else if ( signal_pending( current ) ) { // no data, can sleep, but signal -+ retval = -ERESTARTSYS; -+ break; -+ } -+ schedule(); // no data, can sleep -+ } -+ set_current_state( TASK_RUNNING ); -+ remove_wait_queue( &wq_read, &wait ); -+ -+ if ( retval < 0 ) -+ printk( "%sread error %d - %s\n", pszMe, retval, what_the_f( retval ) ); -+ return retval; -+} -+ -+/* -+ * Write endpoint. This routine attempts to break the passed in buffer -+ * into usb DATA0/1 packet size chunks and send them to the host. -+ * (The lower-level driver tries to do this too, but easier for us -+ * to manage things here.) -+ * -+ * We are at the mercy of the host here, in that it must send an IN -+ * token to us to pull this data back, so hopefully some higher level -+ * protocol is expecting traffic to flow in that direction so the host -+ * is actually polling us. To guard against hangs, a 5 second timeout -+ * is used. -+ * -+ * This routine takes some care to only report bytes sent that have -+ * actually made it across the wire. Thus we try to stay in lockstep -+ * with the completion routine and only have one packet on the xmit -+ * hardware at a time. Multiple simultaneous writers will get -+ * "undefined" results. -+ * -+ */ -+static ssize_t usbc_write( struct file *pFile, const char * pUserBuffer, -+ size_t stCount, loff_t *pPos ) -+{ -+ ssize_t retval = 0; -+ ssize_t stSent = 0; -+ -+ DECLARE_WAITQUEUE( wait, current ); -+ -+ PRINTK( KERN_DEBUG "%swrite() %d bytes\n", pszMe, stCount ); -+ -+ down( &xmit_sem ); // only one thread onto the hardware at a time -+ -+ while( stCount != 0 && retval == 0 ) { -+ int nThisTime = MIN( TX_PACKET_SIZE, stCount ); -+ copy_from_user( tx_buf, pUserBuffer, nThisTime ); -+ sending = nThisTime; -+ sa1100_usb_send_set_callback(tx_done_callback, NULL); -+ retval = sa1100_usb_send( tx_buf, nThisTime); -+ if ( retval < 0 ) { -+ char * p = what_the_f( retval ); -+ printk( "%sCould not queue xmission. rc=%d - %s\n", -+ pszMe, retval, p ); -+ sending = 0; -+ break; -+ } -+ /* now have something on the diving board */ -+ add_wait_queue( &wq_write, &wait ); -+ tx_timer.expires = jiffies + ( HZ * 5 ); -+ add_timer( &tx_timer ); -+ while( 1 ) { -+ set_current_state( TASK_INTERRUPTIBLE ); -+ if ( sending == 0 ) { /* it jumped into the pool */ -+ del_timer( &tx_timer ); -+ retval = last_tx_result; -+ if ( retval == 0 ) { -+ stSent += last_tx_size; -+ pUserBuffer += last_tx_size; -+ stCount -= last_tx_size; -+ } -+ else -+ printk( "%sxmission error rc=%d - %s\n", -+ pszMe, retval, what_the_f(retval) ); -+ break; -+ } -+ else if ( signal_pending( current ) ) { -+ del_timer( &tx_timer ); -+ printk( "%ssignal\n", pszMe ); -+ retval = -ERESTARTSYS; -+ break; -+ } -+ schedule(); -+ } -+ set_current_state( TASK_RUNNING ); -+ remove_wait_queue( &wq_write, &wait ); -+ } -+ -+ up( &xmit_sem ); -+ -+ if ( 0 == retval ) -+ retval = stSent; -+ return retval; -+} -+ -+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait ) -+{ -+ unsigned int retval = 0; -+ -+ PRINTK( KERN_DEBUG "%poll()\n", pszMe ); -+ -+ poll_wait( pFile, &wq_poll, pWait ); -+ -+ if ( CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE ) ) -+ retval |= POLLIN | POLLRDNORM; -+ if ( sa1100_usb_xmitter_avail() ) -+ retval |= POLLOUT | POLLWRNORM; -+ return retval; -+} -+ -+static int usbc_ioctl( struct inode *pInode, struct file *pFile, -+ unsigned int nCmd, unsigned long argument ) -+{ -+ int retval = 0; -+ -+ switch( nCmd ) { -+ -+ case USBC_IOC_FLUSH_RECEIVER: -+ sa1100_usb_recv_reset(); -+ rx_ring.in = rx_ring.out = 0; -+ break; -+ -+ case USBC_IOC_FLUSH_TRANSMITTER: -+ sa1100_usb_send_reset(); -+ break; -+ -+ case USBC_IOC_FLUSH_ALL: -+ sa1100_usb_recv_reset(); -+ rx_ring.in = rx_ring.out = 0; -+ sa1100_usb_send_reset(); -+ break; -+ -+ default: -+ retval = -ENOIOCTLCMD; -+ break; -+ -+ } -+ return retval; -+} -+ -+ -+static int usbc_close( struct inode *pInode, struct file * pFile ) -+{ -+ PRINTK( KERN_DEBUG "%sclose()\n", pszMe ); -+ if ( --usb_ref_count == 0 ) { -+ down( &xmit_sem ); -+ usbctl_stop(&usbc_client); -+ free_txrx_buffers(); -+ del_timer( &tx_timer ); -+ usbctl_close(&usbc_client); -+ up(&xmit_sem); -+ } -+ MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+////////////////////////////////////////////////////////////////////////////// -+// Initialization -+////////////////////////////////////////////////////////////////////////////// -+ -+static struct file_operations usbc_fops = { -+ owner: THIS_MODULE, -+ open: usbc_open, -+ read: usbc_read, -+ write: usbc_write, -+ poll: usbc_poll, -+ ioctl: usbc_ioctl, -+ release: usbc_close, -+}; -+ -+static struct miscdevice usbc_misc_device = { -+ USBC_MINOR, -+ "usb_char", -+ &usbc_fops -+}; -+ -+/* -+ * usbc_init() -+ */ -+ -+static int __init usbc_init( void ) -+{ -+ int rc; -+ -+#if !defined( CONFIG_ARCH_SA1100 ) -+ return -ENODEV; -+#endif -+ -+ if ( (rc = misc_register( &usbc_misc_device )) != 0 ) { -+ printk( KERN_WARNING "%sCould not register device 10, " -+ "%d. (%d)\n", pszMe, USBC_MINOR, rc ); -+ return -EBUSY; -+ } -+ -+ // initialize wait queues -+ init_waitqueue_head( &wq_read ); -+ init_waitqueue_head( &wq_write ); -+ init_waitqueue_head( &wq_poll ); -+ -+ // initialize tx timeout timer -+ init_timer( &tx_timer ); -+ tx_timer.function = tx_timeout; -+ -+ printk( KERN_INFO "USB Function Character Driver Interface" -+ " - %s, (C) 2001, Extenex Corp.\n", VERSION -+ ); -+ -+ return rc; -+} -+ -+static void __exit usbc_exit( void ) -+{ -+} -+ -+module_init(usbc_init); -+module_exit(usbc_exit); -+ -+// end: usb-char.c -+ -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb-eth.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,535 @@ -+/* -+ * Network driver for the SA1100 USB client function -+ * Copyright (c) 2001 by Nicolas Pitre -+ * -+ * This code was loosely inspired by the original initial ethernet test driver -+ * Copyright (c) Compaq Computer Corporation, 1999 -+ * -+ * 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. -+ * -+ * Issues: -+ * - DMA needs 8 byte aligned buffer, but causes inefficiencies -+ * in the IP code. -+ * - stall endpoint operations appeared to be very unstable. -+ */ -+ -+/* -+ * Define RX_NO_COPY if you want data to arrive directly into the -+ * receive network buffers, instead of arriving into bounce buffer -+ * and then get copied to network buffer. -+ * -+ * Since the SA1100 DMA engine is unable to cope with unaligned -+ * buffer addresses, we need to use bounce buffers or suffer the -+ * alignment trap performance hit. -+ */ -+#undef RX_NO_COPY -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "client.h" -+ -+ -+#define ETHERNET_VENDOR_ID 0x049f -+#define ETHERNET_PRODUCT_ID 0x505A -+#define MAX_PACKET 32768 -+ -+/* -+ * This is our usb "packet size", and must match the host "packet size". -+ */ -+static int usb_rsize = 64; -+static int usb_wsize = 64; -+ -+struct usbe_info { -+ struct net_device dev; -+ struct usb_client client; -+ struct sk_buff *cur_tx_skb; -+ struct sk_buff *next_tx_skb; -+ struct sk_buff *cur_rx_skb; -+ struct sk_buff *next_rx_skb; -+#ifndef RX_NO_COPY -+ char *dmabuf; // dma expects it's buffers to be aligned on 8 bytes boundary -+#endif -+ struct net_device_stats stats; -+}; -+ -+ -+static int usbeth_change_mtu(struct net_device *dev, int new_mtu) -+{ -+ if (new_mtu <= sizeof(struct ethhdr) || new_mtu > MAX_PACKET) -+ return -EINVAL; -+ -+ // no second zero-length packet read wanted after mtu-sized packets -+ if (((new_mtu + sizeof(struct ethhdr)) % usb_rsize) == 0) -+ return -EDOM; -+ -+ dev->mtu = new_mtu; -+ return 0; -+} -+ -+static struct sk_buff *usb_new_recv_skb(struct usbe_info *usbe) -+{ -+ struct sk_buff *skb; -+ -+ skb = alloc_skb(2 + sizeof(struct ethhdr) + usbe->dev.mtu, -+ GFP_ATOMIC); -+ -+ if (skb) -+ skb_reserve(skb, 2); -+ -+ return skb; -+} -+ -+static void usbeth_recv_callback(void *data, int flag, int len) -+{ -+ struct usbe_info *usbe = data; -+ struct sk_buff *skb; -+ unsigned int size; -+ char *buf; -+ -+ skb = usbe->cur_rx_skb; -+ -+ /* flag validation */ -+ if (flag != 0) -+ goto error; -+ -+ /* -+ * Make sure we have enough room left in the buffer. -+ */ -+ if (len > skb_tailroom(skb)) { -+ usbe->stats.rx_over_errors++; -+ usbe->stats.rx_errors++; -+ goto oversize; -+ } -+ -+ /* -+ * If the packet is smaller than usb_rsize bytes, the packet -+ * is complete, and we need to use the next receive buffer. -+ */ -+ if (len != usb_rsize) -+ usbe->cur_rx_skb = usbe->next_rx_skb; -+ -+ /* -+ * Put the data onto the socket buffer and resume USB receive. -+ */ -+#ifndef RX_NO_COPY -+ memcpy(skb_put(skb, len), usbe->dmabuf, len); -+ buf = usbe->dmabuf; -+ size = usb_rsize; -+#else -+ skb_put(skb, len); -+ buf = usbe->cur_rx_skb->tail; -+ size = skb_tailroom(usbe->cur_rx_skb); -+#endif -+ usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size); -+ -+ if (len == usb_rsize) -+ return; -+ -+ /* -+ * A frame must contain at least an ethernet header. -+ */ -+ if (skb->len < sizeof(struct ethhdr)) { -+ usbe->stats.rx_length_errors++; -+ usbe->stats.rx_errors++; -+ goto recycle; -+ } -+ -+ /* -+ * MAC must match our address or the broadcast address. -+ * Really, we should let any packet through, otherwise -+ * things that rely on multicast won't work. -+ */ -+ if (memcmp(skb->data, usbe->dev.dev_addr, ETH_ALEN) && -+ memcmp(skb->data, usbe->dev.broadcast, ETH_ALEN)) { -+ usbe->stats.rx_frame_errors++; -+ usbe->stats.rx_errors++; -+ goto recycle; -+ } -+ -+ /* -+ * We're going to consume this SKB. Get a new skb to -+ * replace it with. IF this fails, we'd better recycle -+ * the one we have. -+ */ -+ usbe->next_rx_skb = usb_new_recv_skb(usbe); -+ if (!usbe->next_rx_skb) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "%s: can't allocate new rx skb\n", -+ usbe->dev.name); -+ usbe->stats.rx_dropped++; -+ goto recycle; -+ } -+ -+// FIXME: eth_copy_and_csum "small" packets to new SKB (small < ~200 bytes) ? -+ -+ usbe->stats.rx_packets++; -+ usbe->stats.rx_bytes += skb->len; -+ usbe->dev.last_rx = jiffies; -+ -+ skb->dev = &usbe->dev; -+ skb->protocol = eth_type_trans(skb, &usbe->dev); -+ skb->ip_summed = CHECKSUM_NONE; -+ -+ if (netif_rx(skb) == NET_RX_DROP) -+ usbe->stats.rx_dropped++; -+ return; -+ -+ error: -+ /* -+ * Oops, IO error, or stalled. -+ */ -+ switch (flag) { -+ case -EIO: /* aborted transfer */ -+ usbe->stats.rx_errors++; -+ break; -+ -+ case -EPIPE: /* fifo screwed/no data */ -+ usbe->stats.rx_fifo_errors++; -+ usbe->stats.rx_errors++; -+ break; -+ -+ case -EINTR: /* reset */ -+ break; -+ -+ case -EAGAIN: /* initialisation */ -+ break; -+ } -+ -+ oversize: -+ skb_trim(skb, 0); -+ -+#ifndef RX_NO_COPY -+ buf = usbe->dmabuf; -+ size = usb_rsize; -+#else -+ buf = skb->tail; -+ size = skb_tailroom(skb); -+#endif -+ usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size); -+ return; -+ -+ recycle: -+ skb_trim(skb, 0); -+ usbe->next_rx_skb = skb; -+ return; -+} -+ -+/* -+ * Send a skb. -+ * -+ * Note that the receiver expects the last packet to be a non-multiple -+ * of its rsize. If the packet length is a muliple of wsize (and -+ * therefore the remote rsize) tweak the length. -+ */ -+static void usbeth_send(struct sk_buff *skb, struct usbe_info *usbe) -+{ -+ unsigned int len = skb->len; -+ int ret; -+ -+ if ((len % usb_wsize) == 0) -+ len++; -+ -+ ret = usbctl_ep_queue_buffer(usbe->client.ctl, 2, skb->data, len); -+ if (ret) { -+ printk(KERN_ERR "%s: tx dropping packet: %d\n", -+ usbe->dev.name, ret); -+ -+ /* -+ * If the USB core can't accept the packet, we drop it. -+ */ -+ dev_kfree_skb_irq(skb); -+ -+ usbe->cur_tx_skb = NULL; -+ usbe->stats.tx_carrier_errors++; -+ } else { -+ usbe->dev.trans_start = jiffies; -+ } -+} -+ -+static void usbeth_send_callback(void *data, int flag, int size) -+{ -+ struct usbe_info *usbe = data; -+ struct sk_buff *skb = usbe->cur_tx_skb; -+ -+ switch (flag) { -+ case 0: -+ usbe->stats.tx_packets++; -+ usbe->stats.tx_bytes += skb->len; -+ break; -+ case -EIO: -+ usbe->stats.tx_errors++; -+ break; -+ default: -+ usbe->stats.tx_dropped++; -+ break; -+ } -+ -+ dev_kfree_skb_irq(skb); -+ -+ skb = usbe->cur_tx_skb = usbe->next_tx_skb; -+ usbe->next_tx_skb = NULL; -+ -+ if (skb) -+ usbeth_send(skb, usbe); -+ -+ netif_wake_queue(&usbe->dev); -+} -+ -+static int usbeth_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct usbe_info *usbe = dev->priv; -+ unsigned long flags; -+ -+ if (usbe->next_tx_skb) { -+ printk(KERN_ERR "%s: called with next_tx_skb != NULL\n", -+ usbe->dev.name); -+ return 1; -+ } -+ -+ local_irq_save(flags); -+ if (usbe->cur_tx_skb) { -+ usbe->next_tx_skb = skb; -+ netif_stop_queue(dev); -+ } else { -+ usbe->cur_tx_skb = skb; -+ -+ usbeth_send(skb, usbe); -+ } -+ local_irq_restore(flags); -+ return 0; -+} -+ -+/* -+ * Transmit timed out. Reset the endpoint, and re-queue the pending -+ * packet. If we have a free transmit slot, wake the transmit queue. -+ */ -+static void usbeth_xmit_timeout(struct net_device *dev) -+{ -+ struct usbe_info *usbe = dev->priv; -+ unsigned long flags; -+ -+ usbctl_ep_reset(usbe->client.ctl, 2); -+ -+ local_irq_save(flags); -+ if (usbe->cur_tx_skb) -+ usbeth_send(usbe->cur_tx_skb, usbe); -+ -+ if (usbe->next_tx_skb == NULL) -+ netif_wake_queue(dev); -+ -+ usbe->stats.tx_errors++; -+ local_irq_restore(flags); -+} -+ -+static int usbeth_open(struct net_device *dev) -+{ -+ struct usbe_info *usbe = dev->priv; -+ unsigned char *buf; -+ unsigned int size; -+ -+ usbctl_ep_set_callback(usbe->client.ctl, 2, usbeth_send_callback, usbe); -+ usbctl_ep_set_callback(usbe->client.ctl, 1, usbeth_recv_callback, usbe); -+ -+ usbe->cur_tx_skb = usbe->next_tx_skb = NULL; -+ usbe->cur_rx_skb = usb_new_recv_skb(usbe); -+ usbe->next_rx_skb = usb_new_recv_skb(usbe); -+ if (!usbe->cur_rx_skb || !usbe->next_rx_skb) { -+ printk(KERN_ERR "%s: can't allocate new skb\n", -+ usbe->dev.name); -+ if (usbe->cur_rx_skb) -+ kfree_skb(usbe->cur_rx_skb); -+ if (usbe->next_rx_skb) -+ kfree_skb(usbe->next_rx_skb); -+ return -ENOMEM;; -+ } -+#ifndef RX_NO_COPY -+ buf = usbe->dmabuf; -+ size = usb_rsize; -+#else -+ buf = usbe->cur_rx_skb->tail; -+ size = skb_tailroom(usbe->cur_rx_skb); -+#endif -+ usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size); -+ -+ if (netif_carrier_ok(dev)) -+ netif_start_queue(dev); -+ -+ return 0; -+} -+ -+static int usbeth_close(struct net_device *dev) -+{ -+ struct usbe_info *usbe = dev->priv; -+ -+ netif_stop_queue(dev); -+ -+ usbctl_ep_set_callback(usbe->client.ctl, 2, NULL, NULL); -+ usbctl_ep_set_callback(usbe->client.ctl, 1, NULL, NULL); -+ usbctl_ep_reset(usbe->client.ctl, 2); -+ usbctl_ep_reset(usbe->client.ctl, 1); -+ -+ if (usbe->cur_tx_skb) -+ kfree_skb(usbe->cur_tx_skb); -+ if (usbe->next_tx_skb) -+ kfree_skb(usbe->next_tx_skb); -+ if (usbe->cur_rx_skb) -+ kfree_skb(usbe->cur_rx_skb); -+ if (usbe->next_rx_skb) -+ kfree_skb(usbe->next_rx_skb); -+ -+ return 0; -+} -+ -+static struct net_device_stats *usbeth_stats(struct net_device *dev) -+{ -+ struct usbe_info *usbe = dev->priv; -+ -+ return &usbe->stats; -+} -+ -+static int __init usbeth_probe(struct net_device *dev) -+{ -+ u8 node_id[ETH_ALEN]; -+ -+ SET_MODULE_OWNER(dev); -+ -+ /* -+ * Assign the hardware address of the board: -+ * generate it randomly, as there can be many such -+ * devices on the bus. -+ */ -+ get_random_bytes(node_id, sizeof node_id); -+ node_id[0] &= 0xfe; // clear multicast bit -+ memcpy(dev->dev_addr, node_id, sizeof node_id); -+ -+ ether_setup(dev); -+ dev->flags &= ~IFF_MULTICAST; -+ dev->flags &= ~IFF_BROADCAST; -+ //dev->flags |= IFF_NOARP; -+ -+ return 0; -+} -+ -+/* -+ * This is called when something in the upper usb client layers -+ * changes that affects the endpoint connectivity state (eg, -+ * connection or disconnection from the host.) We probably want -+ * to do some more handling here, like kicking off a pending -+ * transmission if we're running? -+ */ -+static void usbeth_state_change(void *data, int state, int oldstate) -+{ -+ struct usbe_info *usbe = data; -+ -+ if (state == USB_STATE_CONFIGURED) { -+ netif_carrier_on(&usbe->dev); -+ if (netif_running(&usbe->dev)) -+ netif_wake_queue(&usbe->dev); -+ } else { -+ if (netif_running(&usbe->dev)) -+ netif_stop_queue(&usbe->dev); -+ netif_carrier_off(&usbe->dev); -+ } -+} -+ -+static struct usbe_info usbe_info = { -+ .dev = { -+ .name = "usbf", -+ .init = usbeth_probe, -+ .get_stats = usbeth_stats, -+ .watchdog_timeo = 1 * HZ, -+ .open = usbeth_open, -+ .stop = usbeth_close, -+ .hard_start_xmit = usbeth_xmit, -+ .change_mtu = usbeth_change_mtu, -+ .tx_timeout = usbeth_xmit_timeout, -+ .priv = &usbe_info, -+ }, -+ .client = { -+ .name = "usbeth", -+ .priv = &usbe_info, -+ .state_change = usbeth_state_change, -+ -+ /* -+ * USB client identification for host use in CPU endian. -+ */ -+ .vendor = ETHERNET_VENDOR_ID, -+ .product = ETHERNET_PRODUCT_ID, -+ .version = 0, -+ .class = 0xff, /* vendor specific */ -+ .subclass = 0, -+ .protocol = 0, -+ -+ .product_str = "SA1100 USB NIC", -+ }, -+}; -+ -+static int __init usbeth_init(void) -+{ -+ int rc; -+ -+#ifndef RX_NO_COPY -+ usbe_info.dmabuf = kmalloc(usb_rsize, GFP_KERNEL | GFP_DMA); -+ if (!usbe_info.dmabuf) -+ return -ENOMEM; -+#endif -+ -+ if (register_netdev(&usbe_info.dev) != 0) { -+#ifndef RX_NO_COPY -+ kfree(usbe_info.dmabuf); -+#endif -+ return -EIO; -+ } -+ -+ rc = usbctl_open(&usbe_info.client); -+ if (rc == 0) { -+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr(); -+ -+ cdb->ep1.wMaxPacketSize = cpu_to_le16(usb_rsize); -+ cdb->ep2.wMaxPacketSize = cpu_to_le16(usb_wsize); -+ -+ rc = usbctl_start(&usbe_info.client); -+ if (rc) -+ usbctl_close(&usbe_info.client); -+ } -+ -+ if (rc) { -+ unregister_netdev(&usbe_info.dev); -+#ifndef RX_NO_COPY -+ kfree(usbe_info.dmabuf); -+#endif -+ } -+ -+ return rc; -+} -+ -+static void __exit usbeth_cleanup(void) -+{ -+ usbctl_stop(&usbe_info.client); -+ usbctl_close(&usbe_info.client); -+ -+ unregister_netdev(&usbe_info.dev); -+#ifndef RX_NO_COPY -+ kfree(usbe_info.dmabuf); -+#endif -+} -+ -+module_init(usbeth_init); -+module_exit(usbeth_cleanup); -+ -+MODULE_DESCRIPTION("USB client ethernet driver"); -+MODULE_PARM(usb_rsize, "1i"); -+MODULE_PARM_DESC(usb_rsize, "number of bytes in packets from host to sa11x0"); -+MODULE_PARM(usb_wsize, "1i"); -+MODULE_PARM_DESC(usb_wsize, "number of bytes in packets from sa11x0 to host"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_recv.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,318 @@ -+/* -+ * Generic receive layer for the SA1100 USB client function -+ * Copyright (c) 2001 by Nicolas Pitre -+ * -+ * This code was loosely inspired by the original version which was -+ * Copyright (c) Compaq Computer Corporation, 1998-1999 -+ * -+ * 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. -+ * -+ * This is still work in progress... -+ * -+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "sa1100_usb.h" -+#include "sa1100usb.h" -+ -+static int naking; -+ -+#if 1 -+static void dump_buf(struct sausb_dev *usb, const char *prefix) -+{ -+ printk("%s: buf [dma=%08x len=%3d] pkt [cpu=%08x dma=%08x len=%3d rem=%3d]\n", -+ prefix, -+ usb->ep[0].bufdma, -+ usb->ep[0].buflen, -+ (unsigned int)usb->ep[0].pktcpu, -+ usb->ep[0].pktdma, -+ usb->ep[0].pktlen, -+ usb->ep[0].pktrem); -+} -+#endif -+ -+static void udc_ep1_done(struct sausb_dev *usb, int flag, int size) -+{ -+// printk("UDC: rxd: %3d %3d\n", flag, size); -+ dump_buf(usb, "UDC: rxd"); -+ -+ if (!usb->ep[0].buflen) -+ return; -+ -+ dma_unmap_single(usb->dev, usb->ep[0].bufdma, usb->ep[0].buflen, -+ DMA_FROM_DEVICE); -+ -+ usb->ep[0].bufdma = 0; -+ usb->ep[0].buflen = 0; -+ usb->ep[0].pktcpu = NULL; -+ usb->ep[0].pktdma = 0; -+ usb->ep[0].pktlen = 0; -+ usb->ep[0].pktrem = 0; -+ -+ if (usb->ep[0].cb_func) -+ usb->ep[0].cb_func(usb->ep[0].cb_data, flag, size); -+} -+ -+/* -+ * Initialisation. Clear out the status, and set FST. -+ */ -+void udc_ep1_init(struct sausb_dev *usb) -+{ -+ sa1100_reset_dma(usb->ep[0].dmach); -+ -+ UDC_clear(Ser0UDCCS1, UDCCS1_FST | UDCCS1_RPE | UDCCS1_RPC); -+ -+ BUG_ON(usb->ep[0].buflen); -+ BUG_ON(usb->ep[0].pktlen); -+} -+ -+void udc_ep1_halt(struct sausb_dev *usb, int halt) -+{ -+ if (halt) { -+ /* force stall at UDC */ -+ UDC_set(Ser0UDCCS1, UDCCS1_FST); -+ } else { -+ sa1100_reset_dma(usb->ep[0].dmach); -+ -+ UDC_clear(Ser0UDCCS1, UDCCS1_FST); -+ -+ udc_ep1_done(usb, -EINTR, 0); -+ } -+} -+ -+/* -+ * This gets called when we receive a SET_CONFIGURATION packet to EP0. -+ * We were configured. We can now accept packets from the host. -+ */ -+void udc_ep1_config(struct sausb_dev *usb, unsigned int maxpktsize) -+{ -+ usb->ep[0].maxpktsize = maxpktsize; -+ usb->ep[0].configured = 1; -+ -+ Ser0UDCOMP = maxpktsize - 1; -+ -+ sa1100_reset_dma(usb->ep[0].dmach); -+ udc_ep1_done(usb, -EINTR, 0); -+ -+ /* -+ * Enable EP1 interrupts. -+ */ -+ usb->udccr &= ~UDCCR_RIM; -+ UDC_write(Ser0UDCCR, usb->udccr); -+} -+ -+/* -+ * We saw a reset from the attached hub. This means we are no -+ * longer configured, and as far as the rest of the world is -+ * concerned, we don't exist. -+ */ -+void udc_ep1_reset(struct sausb_dev *usb) -+{ -+ /* -+ * Disable EP1 interrupts. -+ */ -+ usb->udccr |= UDCCR_RIM; -+ UDC_write(Ser0UDCCR, usb->udccr); -+ -+ usb->ep[0].configured = 0; -+ usb->ep[0].maxpktsize = 0; -+ -+ sa1100_reset_dma(usb->ep[0].dmach); -+ udc_ep1_done(usb, -EINTR, 0); -+} -+ -+void udc_ep1_int_hndlr(struct sausb_dev *usb) -+{ -+ dma_addr_t dma_addr; -+ unsigned int len; -+ u32 status = Ser0UDCCS1; -+ -+ dump_buf(usb, "UDC: int"); -+ -+ if (naking) { -+ printk("UDC: usbrx: in ISR but naking [0x%02x]\n", status); -+ return; -+ } -+ -+ if (!(status & UDCCS1_RPC)) -+ /* you can get here if we are holding NAK */ -+ return; -+ -+ if (!usb->ep[0].buflen) { -+ printk("UDC: usb_recv: RPC for non-existent buffer [0x%02x]\n", status); -+ naking = 1; -+ return; -+ } -+ -+ sa1100_stop_dma(usb->ep[0].dmach); -+ -+ dma_addr = sa1100_get_dma_pos(usb->ep[0].dmach); -+ -+ /* -+ * We've finished with the DMA for this packet. -+ */ -+ sa1100_clear_dma(usb->ep[0].dmach); -+ -+ if (status & UDCCS1_SST) { -+ printk("UDC: usb_recv: stall sent\n"); -+ UDC_flip(Ser0UDCCS1, UDCCS1_SST); -+ -+ /* -+ * UDC aborted current transfer, so we do. -+ * -+ * It would be better to re-queue this buffer IMHO. It -+ * hasn't gone anywhere yet. --rmk -+ */ -+ UDC_flip(Ser0UDCCS1, UDCCS1_RPC); -+ udc_ep1_done(usb, -EIO, 0); -+ return; -+ } -+ -+ if (status & UDCCS1_RPE) { -+ printk("UDC: usb_recv: RPError %x\n", status); -+ UDC_flip(Ser0UDCCS1, UDCCS1_RPC); -+ udc_ep1_done(usb, -EIO, 0); -+ return; -+ } -+ -+ len = dma_addr - usb->ep[0].pktdma; -+ if (len < 0) { -+ printk("UDC: usb_recv: dma_addr (%x) < pktdma (%x)\n", -+ dma_addr, usb->ep[0].pktdma); -+ len = 0; -+ } -+ -+ if (len > usb->ep[0].pktlen) -+ len = usb->ep[0].pktlen; -+ -+ /* -+ * If our transfer was smaller, and we have bytes left in -+ * the FIFO, we need to read them out manually. -+ */ -+ if (len < usb->ep[0].pktlen && (Ser0UDCCS1 & UDCCS1_RNE)) { -+ char *buf; -+ -+ dma_sync_single(usb->dev, usb->ep[0].pktdma + len, -+ usb->ep[0].pktlen - len, DMA_FROM_DEVICE); -+ -+ buf = (char *)usb->ep[0].pktcpu + len; -+ -+ do { -+ *buf++ = Ser0UDCDR; -+ len++; -+ } while (len < usb->ep[0].pktlen && (Ser0UDCCS1 & UDCCS1_RNE)); -+ -+ /* -+ * Note: knowing the internals of this macro is BAD, but we -+ * need this to cause the data to be written back to memory. -+ */ -+ dma_sync_single(usb->dev, usb->ep[0].pktdma + len, -+ usb->ep[0].pktlen - len, DMA_TO_DEVICE); -+ } -+ -+ /* -+ * If the FIFO still contains data, something's definitely wrong. -+ */ -+ if (Ser0UDCCS1 & UDCCS1_RNE) { -+ printk("UDC: usb_recv: fifo screwed, shouldn't contain data\n"); -+ usb->ep[0].fifo_errs++; -+ naking = 1; -+ udc_ep1_done(usb, -EPIPE, 0); -+ return; -+ } -+ -+ /* -+ * Do statistics. -+ */ -+ if (len) { -+ usb->ep[0].bytes += len; -+ usb->ep[0].packets ++; -+ } -+ -+ /* -+ * Update remaining byte count for this buffer. -+ */ -+ usb->ep[0].pktrem -= len; -+ -+ /* -+ * If we received a full-sized packet, and there's more -+ * data remaining, th, queue up another receive. -+ */ -+ if (len == usb->ep[0].pktlen && usb->ep[0].pktrem != 0) { -+ usb->ep[0].pktcpu += len; -+ usb->ep[0].pktdma += len; -+ usb->ep[0].pktlen = min(usb->ep[0].pktrem, usb->ep[0].maxpktsize); -+ sa1100_start_dma(usb->ep[0].dmach, usb->ep[0].pktdma, usb->ep[0].pktlen); -+ /* -+ * Clear RPC to receive next packet. -+ */ -+ UDC_flip(Ser0UDCCS1, UDCCS1_RPC); -+ dump_buf(usb, "UDC: req"); -+ return; -+ } -+ -+ naking = 1; -+ udc_ep1_done(usb, 0, usb->ep[0].buflen - usb->ep[0].pktrem); -+} -+ -+int udc_ep1_queue_buffer(struct sausb_dev *usb, char *buf, unsigned int len) -+{ -+ unsigned long flags; -+ dma_addr_t dma; -+ int ret; -+ -+ if (!buf || len == 0) -+ return -EINVAL; -+ -+ dma = dma_map_single(usb->dev, buf, len, DMA_FROM_DEVICE); -+ -+ spin_lock_irqsave(&usb->lock, flags); -+ do { -+ if (usb->ep[0].buflen) { -+ ret = -EBUSY; -+ break; -+ } -+ -+ sa1100_clear_dma(usb->ep[0].dmach); -+ -+ usb->ep[0].bufdma = dma; -+ usb->ep[0].buflen = len; -+ usb->ep[0].pktcpu = buf; -+ usb->ep[0].pktdma = dma; -+ usb->ep[0].pktlen = min(len, usb->ep[0].maxpktsize); -+ usb->ep[0].pktrem = len; -+ -+ sa1100_start_dma(usb->ep[0].dmach, usb->ep[0].bufdma, usb->ep[0].buflen); -+ dump_buf(usb, "UDC: que"); -+ -+ if (naking) { -+ /* turn off NAK of OUT packets, if set */ -+ UDC_flip(Ser0UDCCS1, UDCCS1_RPC); -+ naking = 0; -+ } -+ -+ ret = 0; -+ } while (0); -+ spin_unlock_irqrestore(&usb->lock, flags); -+ -+ if (ret) -+ dma_unmap_single(usb->dev, dma, len, DMA_FROM_DEVICE); -+ -+ return 0; -+} -+ -+void udc_ep1_recv_reset(struct sausb_dev *usb) -+{ -+ sa1100_reset_dma(usb->ep[0].dmach); -+ udc_ep1_done(usb, -EINTR, 0); -+} ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/buffer.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,63 @@ -+/* -+ * usb/buffer.c -+ * -+ * Copyright (C) 2002 Russell King. -+ */ -+#include -+#include -+#include -+ -+#include "buffer.h" -+ -+static LIST_HEAD(buffers); -+ -+struct usb_buf *usbb_alloc(int size, int gfp) -+{ -+ unsigned long flags; -+ struct usb_buf *buf; -+ -+ buf = kmalloc(sizeof(struct usb_buf) + size, gfp); -+ if (buf) { -+ atomic_set(&buf->users, 1); -+ local_irq_save(flags); -+ list_add(&buf->list, &buffers); -+ local_irq_restore(flags); -+ buf->len = 0; -+ buf->data = (unsigned char *) (buf + 1); -+ buf->head = (unsigned char *) (buf + 1); -+ } -+ -+ return buf; -+} -+ -+void __usbb_free(struct usb_buf *buf) -+{ -+ unsigned long flags; -+ local_irq_save(flags); -+ list_del(&buf->list); -+ local_irq_restore(flags); -+ kfree(buf); -+} -+ -+EXPORT_SYMBOL(usbb_alloc); -+EXPORT_SYMBOL(__usbb_free); -+ -+static void __exit usbb_exit(void) -+{ -+ if (!list_empty(&buffers)) { -+ struct list_head *l, *n; -+ printk("usbb: buffers not freed:\n"); -+ -+ list_for_each_safe(l, n, &buffers) { -+ struct usb_buf *b = list_entry(l, struct usb_buf, list); -+ -+ printk(" %p: alloced from %p count %d\n", -+ b, b->alloced_by, atomic_read(&b->users)); -+ -+ __usbb_free(b); -+ } -+ } -+} -+ -+module_exit(usbb_exit); -+ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb-char.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2001 Extenex Corporation -+ * -+ * usb-char.h -+ * -+ * Character device emulation client for SA-1100 client usb core. -+ * -+ * -+ * -+ */ -+#ifndef _USB_CHAR_H -+#define _USB_CHAR_H -+ -+#define USBC_MAJOR 10 /* miscellaneous character device */ -+#define USBC_MINOR 240 /* in the "reserved for local use" range */ -+ -+#define USBC_MAGIC 0x8E -+ -+/* zap everything in receive ring buffer */ -+#define USBC_IOC_FLUSH_RECEIVER _IO( USBC_MAGIC, 0x01 ) -+ -+/* reset transmitter */ -+#define USBC_IOC_FLUSH_TRANSMITTER _IO( USBC_MAGIC, 0x02 ) -+ -+/* do both of above */ -+#define USBC_IOC_FLUSH_ALL _IO( USBC_MAGIC, 0x03 ) -+ -+ -+ -+ -+ -+ -+#endif /* _USB_CHAR_H */ -+ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/buffer.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,45 @@ -+/* -+ * usb/buffer.h: USB client buffers -+ * -+ * Copyright (C) 2002 Russell King. -+ * -+ * Loosely based on linux/skbuff.h -+ */ -+#ifndef USBDEV_BUFFER_H -+#define USBDEV_BUFFER_H -+ -+#include -+ -+struct usb_buf { -+ atomic_t users; -+ struct list_head list; -+ void *alloced_by; -+ unsigned char *data; -+ unsigned char *head; -+ unsigned int len; -+}; -+ -+extern struct usb_buf *usbb_alloc(int size, int gfp); -+extern void __usbb_free(struct usb_buf *); -+ -+static inline struct usb_buf *usbb_get(struct usb_buf *buf) -+{ -+ atomic_inc(&buf->users); -+ return buf; -+} -+ -+static inline void usbb_put(struct usb_buf *buf) -+{ -+ if (atomic_dec_and_test(&buf->users)) -+ __usbb_free(buf); -+} -+ -+static inline void *usbb_push(struct usb_buf *buf, int len) -+{ -+ unsigned char *b = buf->head; -+ buf->head += len; -+ buf->len += len; -+ return b; -+} -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/sa1100usb.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,1160 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "buffer.h" -+#include "usbdev.h" -+#include "sa1100_usb.h" -+#include "sa1100usb.h" -+ -+#ifdef DEBUG -+#define DPRINTK(fmt, args...) printk( fmt , ## args) -+#else -+#define DPRINTK(fmt, args...) -+#endif -+ -+static inline void pcs(const char *prefix) -+{ -+#ifdef DEBUG -+ __u32 foo = Ser0UDCCS0; -+ -+ DPRINTK("%s UDCAR: %d\n", prefix, Ser0UDCAR); -+ -+ printk("UDC: %s: %08x [ %s%s%s%s%s%s]\n", prefix, -+ foo, -+ foo & UDCCS0_SE ? "SE " : "", -+ foo & UDCCS0_DE ? "DE " : "", -+ foo & UDCCS0_FST ? "FST " : "", -+ foo & UDCCS0_SST ? "SST " : "", -+ foo & UDCCS0_IPR ? "IPR " : "", -+ foo & UDCCS0_OPR ? "OPR " : ""); -+#endif -+} -+ -+/* -+ * soft_connect_hook() -+ * -+ * Some devices have platform-specific circuitry to make USB -+ * not seem to be plugged in, even when it is. This allows -+ * software to control when a device 'appears' on the USB bus -+ * (after Linux has booted and this driver has loaded, for -+ * example). If you have such a circuit, control it here. -+ */ -+static inline void soft_connect_hook(int enable) -+{ -+#ifdef CONFIG_SA1100_EXTENEX1 -+ if (machine_is_extenex1()) { -+ if (enable) { -+ PPDR |= PPC_USB_SOFT_CON; -+ PPSR |= PPC_USB_SOFT_CON; -+ } else { -+ PPSR &= ~PPC_USB_SOFT_CON; -+ PPDR &= ~PPC_USB_SOFT_CON; -+ } -+ } -+#endif -+} -+ -+/* -+ * disable the UDC at the source -+ */ -+static inline void udc_disable(struct sausb_dev *usb) -+{ -+ soft_connect_hook(0); -+ -+ usb->udccr = UDCCR_UDD | UDCCR_SUSIM; -+ -+ UDC_write(Ser0UDCCR, usb->udccr); -+} -+ -+/* -+ * Clear any pending write from the EP0 write buffer. -+ */ -+static void ep0_clear_write(struct sausb_dev *usb) -+{ -+ struct usb_buf *buf; -+ -+ buf = usb->wrbuf; -+ usb->wrint = NULL; -+ usb->wrbuf = NULL; -+ usb->wrptr = NULL; -+ usb->wrlen = 0; -+ -+ if (buf) -+ usbb_put(buf); -+} -+ -+static int udc_start(void *priv) -+{ -+ struct sausb_dev *usb = priv; -+ -+ usb->ep[0].maxpktsize = 0; -+ usb->ep[1].maxpktsize = 0; -+ -+ /* -+ * start UDC internal machinery running, but mask interrupts. -+ */ -+ usb->udccr = UDCCR_SUSIM | UDCCR_TIM | UDCCR_RIM | UDCCR_EIM | -+ UDCCR_RESIM; -+ UDC_write(Ser0UDCCR, usb->udccr); -+ -+ udelay(100); -+ -+ /* -+ * clear all interrupt sources -+ */ -+ Ser0UDCSR = UDCSR_RSTIR | UDCSR_RESIR | UDCSR_EIR | -+ UDCSR_RIR | UDCSR_TIR | UDCSR_SUSIR; -+ -+ /* -+ * flush DMA and fire through some -EAGAINs -+ */ -+ udc_ep1_init(usb); -+ udc_ep2_init(usb); -+ -+ /* -+ * enable any platform specific hardware -+ */ -+ soft_connect_hook(1); -+ -+ /* -+ * Enable resume, suspend and endpoint 0 interrupts. Leave -+ * endpoint 1 and 2 interrupts masked. -+ * -+ * If you are unplugged you will immediately get a suspend -+ * interrupt. If you are plugged and have a soft connect-circuit, -+ * you will get a reset. If you are plugged without a soft-connect, -+ * I think you also get suspend. -+ */ -+ usb->udccr &= ~(UDCCR_SUSIM | UDCCR_EIM | UDCCR_RESIM); -+ UDC_write(Ser0UDCCR, usb->udccr); -+ -+ return 0; -+} -+ -+static int udc_stop(void *priv) -+{ -+ struct sausb_dev *usb = priv; -+ -+ ep0_clear_write(usb); -+ -+ /* mask everything */ -+ Ser0UDCCR = 0xFC; -+ -+ udc_ep1_reset(usb); -+ udc_ep2_reset(usb); -+ -+ udc_disable(usb); -+ -+ return 0; -+} -+ -+ -+ -+ -+ -+/* -+ * some voodo I am adding, since the vanilla macros just aren't doing it -+ * 1Mar01ww -+ */ -+ -+#define ABORT_BITS (UDCCS0_SST | UDCCS0_SE) -+#define OK_TO_WRITE (!(Ser0UDCCS0 & ABORT_BITS)) -+#define BOTH_BITS (UDCCS0_IPR | UDCCS0_DE) -+ -+static void set_de(void) -+{ -+ int i = 1; -+ -+ while (1) { -+ if (OK_TO_WRITE) { -+ Ser0UDCCS0 |= UDCCS0_DE; -+ } else { -+ DPRINTK("UDC: quitting set DE because SST or SE set\n"); -+ break; -+ } -+ if (Ser0UDCCS0 & UDCCS0_DE) -+ break; -+ udelay(i); -+ if (++i == 50) { -+ printk("UDC: Dangnabbbit! Cannot set DE! (DE=%8.8X CCS0=%8.8X)\n", -+ UDCCS0_DE, Ser0UDCCS0); -+ break; -+ } -+ } -+} -+ -+static void set_ipr(void) -+{ -+ int i = 1; -+ -+ while (1) { -+ if (OK_TO_WRITE) { -+ Ser0UDCCS0 |= UDCCS0_IPR; -+ } else { -+ DPRINTK("UDC: Quitting set IPR because SST or SE set\n"); -+ break; -+ } -+ if (Ser0UDCCS0 & UDCCS0_IPR) -+ break; -+ udelay(i); -+ if (++i == 50) { -+ printk("UDC: Dangnabbbit! Cannot set IPR! (IPR=%8.8X CCS0=%8.8X)\n", -+ UDCCS0_IPR, Ser0UDCCS0); -+ break; -+ } -+ } -+} -+ -+static void set_ipr_and_de(void) -+{ -+ int i = 1; -+ -+ while (1) { -+ if (OK_TO_WRITE) { -+ Ser0UDCCS0 |= BOTH_BITS; -+ } else { -+ DPRINTK("UDC: Quitting set IPR/DE because SST or SE set\n"); -+ break; -+ } -+ if ((Ser0UDCCS0 & BOTH_BITS) == BOTH_BITS) -+ break; -+ udelay(i); -+ if (++i == 50) { -+ printk("UDC: Dangnabbbit! Cannot set DE/IPR! (DE=%8.8X IPR=%8.8X CCS0=%8.8X)\n", -+ UDCCS0_DE, UDCCS0_IPR, Ser0UDCCS0); -+ break; -+ } -+ } -+} -+ -+static inline void set_cs_bits(__u32 bits) -+{ -+ if (bits & (UDCCS0_SO | UDCCS0_SSE | UDCCS0_FST | UDCCS0_SST)) -+ Ser0UDCCS0 = bits; -+ else if ((bits & BOTH_BITS) == BOTH_BITS) -+ set_ipr_and_de(); -+ else if (bits & UDCCS0_IPR) -+ set_ipr(); -+ else if (bits & UDCCS0_DE) -+ set_de(); -+} -+ -+/* -+ * udc_ep0_write_fifo() -+ * -+ * Stick bytes in the 8 bytes endpoint zero FIFO. This version uses a -+ * variety of tricks to make sure the bytes are written correctly: -+ * 1. The count register is checked to see if the byte went in, -+ * and the write is attempted again if not. -+ * 2. An overall counter is used to break out so we don't hang in -+ * those (rare) cases where the UDC reverses direction of the -+ * FIFO underneath us without notification (in response to host -+ * aborting a setup transaction early). -+ */ -+static void udc_ep0_write_fifo(struct sausb_dev *usb) -+{ -+ unsigned int bytes_this_time = min(usb->wrlen, 8U); -+ int bytes_written = 0; -+ -+ DPRINTK("WF=%d: ", bytes_this_time); -+ -+ while (bytes_this_time--) { -+ unsigned int cwc; -+ int i; -+ -+ DPRINTK("%2.2X ", *usb->wrptr); -+ -+ cwc = Ser0UDCWC & 15; -+ -+ i = 10; -+ do { -+ Ser0UDCD0 = *usb->wrptr; -+ udelay(20); /* voodo 28Feb01ww */ -+ } while ((Ser0UDCWC & 15) == cwc && --i); -+ -+ if (i == 0) { -+ printk("UDC: udc_ep0_write_fifo: write failure\n"); -+ usb->ep0_wr_fifo_errs++; -+ } -+ -+ usb->wrptr++; -+ bytes_written++; -+ } -+ usb->wrlen -= bytes_written; -+ -+ /* following propagation voodo so maybe caller writing IPR in -+ ..a moment might actually get it to stick 28Feb01ww */ -+ udelay(300); -+ -+ usb->ep0_wr_bytes += bytes_written; -+ DPRINTK("L=%d WCR=%8.8X\n", usb->wrlen, Ser0UDCWC); -+} -+ -+/* -+ * read_fifo() -+ * -+ * Read 1-8 bytes out of FIFO and put in request. Called to do the -+ * initial read of setup requests from the host. Return number of -+ * bytes read. -+ * -+ * Like write fifo above, this driver uses multiple reads checked -+ * against the count register with an overall timeout. -+ */ -+static int -+udc_ep0_read_fifo(struct sausb_dev *usb, struct usb_ctrlrequest *request, int sz) -+{ -+ unsigned char *pOut = (unsigned char *) request; -+ unsigned int fifo_count, bytes_read = 0; -+ -+ fifo_count = Ser0UDCWC & 15; -+ -+ DPRINTK("RF=%d ", fifo_count); -+ BUG_ON(fifo_count > sz); -+ -+ while (fifo_count--) { -+ unsigned int cwc; -+ int i; -+ -+ cwc = Ser0UDCWC & 15; -+ -+ i = 10; -+ do { -+ *pOut = (unsigned char) Ser0UDCD0; -+ udelay(20); -+ } while ((Ser0UDCWC & 15) == cwc && --i); -+ -+ if (i == 0) { -+ printk(KERN_ERR "UDC: udc_ep0_read_fifo: read failure\n"); -+ usb->ep0_rd_fifo_errs++; -+ break; -+ } -+ pOut++; -+ bytes_read++; -+ } -+ -+ DPRINTK("fc=%d\n", bytes_read); -+ usb->ep0_rd_bytes += bytes_read; -+ usb->ep0_rd_packets ++; -+ return bytes_read; -+} -+ -+static void ep0_sh_write_data(struct sausb_dev *usb) -+{ -+ /* -+ * If bytes left is zero, we are coming in on the -+ * interrupt after the last packet went out. And -+ * we know we don't have to empty packet this -+ * transfer so just set DE and we are done -+ */ -+ set_cs_bits(UDCCS0_DE); -+} -+ -+static void ep0_sh_write_with_empty_packet(struct sausb_dev *usb) -+{ -+ /* -+ * If bytes left is zero, we are coming in on the -+ * interrupt after the last packet went out. -+ * We must do short packet suff, so set DE and IPR -+ */ -+ set_cs_bits(UDCCS0_IPR | UDCCS0_DE); -+ DPRINTK("UDC: sh_write_empty: Sent empty packet\n"); -+} -+ -+static int udc_clear_opr(void) -+{ -+ int i = 10000; -+ int is_clear; -+ -+ /*FIXME*/ -+ do { -+ Ser0UDCCS0 = UDCCS0_SO; -+ is_clear = !(Ser0UDCCS0 & UDCCS0_OPR); -+ if (i-- <= 0) -+ break; -+ } while (!is_clear); -+ -+ return is_clear; -+} -+ -+static int udc_ep0_queue(void *priv, struct usb_buf *buf, -+ unsigned int req_len) -+{ -+ struct sausb_dev *usb = priv; -+ __u32 cs_reg_bits = UDCCS0_IPR; -+ -+ DPRINTK("a=%d r=%d\n", buf->len, req_len); -+ -+ /* -+ * thou shalt not enter data phase until -+ * Out Packet Ready is clear -+ */ -+ if (!udc_clear_opr()) { -+ printk("UDC: SO did not clear OPR\n"); -+ set_cs_bits(UDCCS0_DE | UDCCS0_SO); -+ usbb_put(buf); -+ return 1; -+ } -+ -+ usb->ep0_wr_packets++; -+ -+ usb->wrbuf = buf; -+ usb->wrptr = buf->data; -+ usb->wrlen = min(buf->len, req_len); -+ -+ udc_ep0_write_fifo(usb); -+ -+ if (usb->wrlen == 0) { -+ /* -+ * out in one, so data end -+ */ -+ cs_reg_bits |= UDCCS0_DE; -+ ep0_clear_write(usb); -+ } else if (buf->len < req_len) { -+ /* -+ * we are going to short-change host -+ * so need nul to not stall -+ */ -+ usb->wrint = ep0_sh_write_with_empty_packet; -+ } else { -+ /* -+ * we have as much or more than requested -+ */ -+ usb->wrint = ep0_sh_write_data; -+ } -+ -+ /* -+ * note: IPR was set uncondtionally at start of routine -+ */ -+ set_cs_bits(cs_reg_bits); -+ return 0; -+} -+ -+/* -+ * When SO and DE sent, UDC will enter status phase and ack, propagating -+ * new address to udc core. Next control transfer will be on the new -+ * address. -+ * -+ * You can't see the change in a read back of CAR until then (about 250us -+ * later, on my box). The original Intel driver sets S0 and DE and code -+ * to check that address has propagated here. I tried this, but it would -+ * only sometimes work! The rest of the time it would never propagate and -+ * we'd spin forever. So now I just set it and pray... -+ */ -+static void udc_set_address(void *priv, unsigned int addr) -+{ -+ Ser0UDCAR = addr; -+} -+ -+static void udc_set_config(void *priv, struct cdb *cdb) -+{ -+ struct sausb_dev *usb = priv; -+ -+ if (cdb) { -+ udc_ep1_config(usb, le16_to_cpu(cdb->ep1.wMaxPacketSize)); -+ udc_ep2_config(usb, le16_to_cpu(cdb->ep2.wMaxPacketSize)); -+ } else { -+ udc_ep1_reset(usb); -+ udc_ep2_reset(usb); -+ } -+} -+ -+static unsigned int udc_ep_get_status(void *priv, unsigned int ep) -+{ -+ unsigned int status; -+ -+ switch (ep) { -+ case 0: -+ status = (Ser0UDCCS0 & UDCCS0_FST) ? 1 : 0; -+ break; -+ -+ case 1: -+ status = (Ser0UDCCS1 & UDCCS1_FST) ? 1 : 0; -+ break; -+ -+ case 2: -+ status = (Ser0UDCCS2 & UDCCS2_FST) ? 1 : 0; -+ break; -+ -+ default: -+ printk(KERN_ERR "UDC: get_status: bad end point %d\n", ep); -+ status = 0; -+ break; -+ } -+ -+ return status; -+} -+ -+static void udc_ep_halt(void *priv, unsigned int ep, int halt) -+{ -+ struct sausb_dev *usb = priv; -+ -+ printk("UDC: ep%d %s halt\n", ep, halt ? "set" : "clear"); -+ -+ switch (ep) { -+ case 1: -+ udc_ep1_halt(usb, halt); -+ break; -+ -+ case 2: -+ udc_ep2_halt(usb, halt); -+ break; -+ } -+} -+ -+static int udc_ep_queue(void *priv, unsigned int ep, char *buf, unsigned int len) -+{ -+ struct sausb_dev *usb = priv; -+ int ret = -EINVAL; -+ -+ switch (ep) { -+ case 1: -+ ret = udc_ep1_queue_buffer(usb, buf, len); -+ break; -+ case 2: -+ ret = udc_ep2_send(usb, buf, len); -+ break; -+ } -+ -+ return ret; -+} -+ -+static void udc_ep_reset(void *priv, unsigned int ep) -+{ -+ struct sausb_dev *usb = priv; -+ -+ switch (ep) { -+ case 1: -+ udc_ep1_recv_reset(usb); -+ break; -+ case 2: -+ udc_ep2_send_reset(usb); -+ break; -+ } -+} -+ -+static void udc_ep_callback(void *priv, unsigned int ep, usb_callback_t cb, void *data) -+{ -+ struct sausb_dev *usb = priv; -+ unsigned long flags; -+ -+ if (ep == 1 || ep == 2) { -+ ep -= 1; -+ -+ spin_lock_irqsave(&usb->lock, flags); -+ usb->ep[ep].cb_func = cb; -+ usb->ep[ep].cb_data = data; -+ spin_unlock_irqrestore(&usb->lock, flags); -+ } -+} -+ -+static int udc_ep_idle(void *priv, unsigned int ep) -+{ -+ struct sausb_dev *usb = priv; -+ int ret = -EINVAL; -+ -+ switch (ep) { -+ case 1: -+ break; -+ case 2: -+ ret = udc_ep2_idle(usb); -+ break; -+ } -+ -+ return ret; -+} -+ -+static struct usbc_driver usb_sa1100_drv = { -+ .owner = THIS_MODULE, -+ .name = "SA1100", -+ .start = udc_start, -+ .stop = udc_stop, -+ .ep0_queue = udc_ep0_queue, -+ .set_address = udc_set_address, -+ .set_config = udc_set_config, -+ .ep_get_status = udc_ep_get_status, -+ .ep_halt = udc_ep_halt, -+ .ep_queue = udc_ep_queue, -+ .ep_reset = udc_ep_reset, -+ .ep_callback = udc_ep_callback, -+ .ep_idle = udc_ep_idle, -+}; -+ -+ -+/* -+ * udc_ep0_read_packet() -+ * -+ * This setup handler is the "idle" state of endpoint zero. It looks for -+ * OPR (OUT packet ready) to see if a setup request has been been received -+ * from the host. Requests without a return data phase are immediately -+ * handled. Otherwise, the handler may be set to one of the sh_write_xxxx -+ * data pumpers if more than 8 bytes need to get back to the host. -+ */ -+static void udc_ep0_read_packet(struct sausb_dev *usb, u32 cs_reg_in) -+{ -+ struct usb_ctrlrequest req; -+ int n, ret = RET_NOACTION; -+ -+ /* -+ * A control request has been received by EP0. -+ * Read the request. -+ */ -+ n = udc_ep0_read_fifo(usb, &req, sizeof(req)); -+ -+ if (n == sizeof(req)) { -+ ret = usbctl_parse_request(usb->ctl, &req); -+ } else { -+ /* -+ * The request wasn't fully received. Force a -+ * stall. -+ */ -+ set_cs_bits(UDCCS0_FST | UDCCS0_SO); -+ printk("UDC: fifo read error: wanted %d bytes got %d\n", -+ sizeof(req), n); -+ } -+ -+ switch (ret) { -+ case RET_ERROR: -+ case RET_NOACTION: -+ break; -+ -+ case RET_ACK: -+ set_cs_bits(UDCCS0_DE | UDCCS0_SO); -+ break; -+ -+ case RET_REQERROR: -+ /* -+ * Send stall PID to host. -+ */ -+ set_cs_bits(UDCCS0_DE | UDCCS0_SO | UDCCS0_FST); -+ break; -+ } -+} -+ -+/* -+ * HACK DEBUG 3Mar01ww -+ * Well, maybe not, it really seems to help! 08Mar01ww -+ */ -+static void core_kicker(struct sausb_dev *usb) -+{ -+ __u32 car = Ser0UDCAR; -+ __u32 imp = Ser0UDCIMP; -+ __u32 omp = Ser0UDCOMP; -+ -+ UDC_set(Ser0UDCCR, UDCCR_UDD); -+ udelay(300); -+ UDC_clear(Ser0UDCCR, UDCCR_UDD); -+ -+ Ser0UDCAR = car; -+ Ser0UDCIMP = imp; -+ Ser0UDCOMP = omp; -+} -+ -+static void enable_resume_mask_suspend(struct sausb_dev *usb) -+{ -+ int i; -+ -+ usb->udccr |= UDCCR_SUSIM; -+ -+ i = 1; -+ do { -+ Ser0UDCCR = usb->udccr; -+ udelay(i); -+ if (Ser0UDCCR == usb->udccr) -+ break; -+ if (Ser0UDCSR & UDCSR_RSTIR) -+ break; -+ } while (i++ < 50); -+ -+ if (i == 50) -+ printk("UDC: enable_resume: could not set SUSIM 0x%08x\n", -+ Ser0UDCCR); -+ -+ usb->udccr &= ~UDCCR_RESIM; -+ -+ i = 1; -+ do { -+ Ser0UDCCR = usb->udccr; -+ udelay(i); -+ if (Ser0UDCCR == usb->udccr) -+ break; -+ if (Ser0UDCSR & UDCSR_RSTIR) -+ break; -+ } while (i++ < 50); -+ -+ if (i == 50) -+ printk("UDC: enable_resume: could not clear RESIM 0x%08x\n", -+ Ser0UDCCR); -+} -+ -+static void enable_suspend_mask_resume(struct sausb_dev *usb) -+{ -+ int i; -+ -+ usb->udccr |= UDCCR_RESIM; -+ -+ i = 1; -+ do { -+ Ser0UDCCR = usb->udccr; -+ udelay(i); -+ if (Ser0UDCCR == usb->udccr) -+ break; -+ if (Ser0UDCSR & UDCSR_RSTIR) -+ break; -+ } while (i++ < 50); -+ -+ if (i == 50) -+ printk("UDC: enable_resume: could not set RESIM 0x%08x\n", -+ Ser0UDCCR); -+ -+ usb->udccr &= ~UDCCR_SUSIM; -+ -+ i = 1; -+ do { -+ Ser0UDCCR = usb->udccr; -+ udelay(i); -+ if (Ser0UDCCR == usb->udccr) -+ break; -+ if (Ser0UDCSR & UDCSR_RSTIR) -+ break; -+ } while (i++ < 50); -+ -+ if (i == 50) -+ printk("UDC: enable_resume: could not clear SUSIM 0x%08x\n", -+ Ser0UDCCR); -+} -+ -+/* -+ * Reset received from HUB (or controller just went nuts and reset by -+ * itself!) so UDC core has been reset, track this state here -+ */ -+static void udc_reset(struct sausb_dev *usb) -+{ -+ if (usbctl_reset(usb->ctl)) { -+ ep0_clear_write(usb); -+ -+ /* -+ * Clean up endpoints. -+ */ -+ udc_ep1_reset(usb); -+ udc_ep2_reset(usb); -+ } -+ -+ /* -+ * mask reset ints, they flood during sequence, enable -+ * suspend and resume -+ */ -+ usb->udccr = (usb->udccr & ~(UDCCR_SUSIM | UDCCR_RESIM)) | UDCCR_REM; -+ Ser0UDCCR = usb->udccr; -+} -+ -+/* -+ * handle interrupt for endpoint zero -+ */ -+static void udc_ep0_int_hndlr(struct sausb_dev *usb) -+{ -+ u32 cs_reg_in; -+ -+ pcs("-->"); -+ -+ cs_reg_in = Ser0UDCCS0; -+ -+ /* -+ * If "setup end" has been set, the usb controller has terminated -+ * a setup transaction before we set DE. This happens during -+ * enumeration with some hosts. For example, the host will ask for -+ * our device descriptor and specify a return of 64 bytes. When we -+ * hand back the first 8, the host will know our max packet size -+ * and turn around and issue a new setup immediately. This causes -+ * the UDC to auto-ack the new setup and set SE. We must then -+ * "unload" (process) the new setup, which is what will happen -+ * after this preamble is finished executing. -+ */ -+ if (cs_reg_in & UDCCS0_SE) { -+ DPRINTK("UDC: early termination of setup\n"); -+ -+ /* -+ * Clear setup end -+ */ -+ set_cs_bits(UDCCS0_SSE); -+ -+ /* -+ * Clear any pending write. -+ */ -+ ep0_clear_write(usb); -+ } -+ -+ /* -+ * UDC sent a stall due to a protocol violation. -+ */ -+ if (cs_reg_in & UDCCS0_SST) { -+ usb->ep0_stall_sent++; -+ -+ DPRINTK("UDC: write_preamble: UDC sent stall\n"); -+ -+ /* -+ * Clear sent stall -+ */ -+ set_cs_bits(UDCCS0_SST); -+ -+ /* -+ * Clear any pending write. -+ */ -+ ep0_clear_write(usb); -+ } -+ -+ switch (cs_reg_in & (UDCCS0_OPR | UDCCS0_IPR)) { -+ case UDCCS0_OPR | UDCCS0_IPR: -+ DPRINTK("UDC: write_preamble: see OPR. Stopping write to " -+ "handle new SETUP\n"); -+ -+ /* -+ * very rarely, you can get OPR and -+ * leftover IPR. Try to clear -+ */ -+ UDC_clear(Ser0UDCCS0, UDCCS0_IPR); -+ -+ /* -+ * Clear any pending write. -+ */ -+ ep0_clear_write(usb); -+ -+ /*FALLTHROUGH*/ -+ case UDCCS0_OPR: -+ /* -+ * A new setup request is pending. Handle -+ * it. Note that we don't try to read a -+ * packet if SE was set and OPR is clear. -+ */ -+ udc_ep0_read_packet(usb, cs_reg_in); -+ break; -+ -+ case 0: -+ if (usb->wrint) { -+ if (usb->wrlen != 0) { -+ /* -+ * More data to go -+ */ -+ udc_ep0_write_fifo(usb); -+ set_ipr(); -+ } -+ -+ if (usb->wrlen == 0) { -+ /* -+ * All data sent. -+ */ -+ usb->wrint(usb); -+ -+ ep0_clear_write(usb); -+ } -+ } -+ break; -+ -+ case UDCCS0_IPR: -+ DPRINTK("UDC: IPR set, not writing\n"); -+ usb->ep0_early_irqs++; -+ break; -+ } -+ -+ pcs("<--"); -+} -+ -+static irqreturn_t udc_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ struct sausb_dev *usb = dev_id; -+ u32 status = Ser0UDCSR; -+ -+ /* -+ * ReSeT Interrupt Request - UDC has been reset -+ */ -+ if (status & UDCSR_RSTIR) { -+ udc_reset(usb); -+ -+ /* -+ * clear all pending sources -+ */ -+ UDC_flip(Ser0UDCSR, status); -+ return IRQ_HANDLED; -+ } -+ -+ /* -+ * else we have done something other than reset, -+ * so be sure reset enabled -+ */ -+ usb->udccr &= ~UDCCR_REM; -+ UDC_write(Ser0UDCCR, usb->udccr); -+ -+ /* -+ * RESume Interrupt Request -+ */ -+ if (status & UDCSR_RESIR) { -+ usbctl_resume(usb->ctl); -+ core_kicker(usb); -+ enable_suspend_mask_resume(usb); -+ } -+ -+ /* -+ * SUSpend Interrupt Request -+ */ -+ if (status & UDCSR_SUSIR) { -+ usbctl_suspend(usb->ctl); -+ enable_resume_mask_suspend(usb); -+ } -+ -+ /* -+ * clear all pending sources -+ */ -+ UDC_flip(Ser0UDCSR, status); -+ -+ if (status & UDCSR_EIR) -+ udc_ep0_int_hndlr(usb); -+ -+ if (status & UDCSR_RIR) -+ udc_ep1_int_hndlr(usb); -+ -+ if (status & UDCSR_TIR) -+ udc_ep2_int_hndlr(usb); -+ -+ return IRQ_HANDLED; -+} -+ -+#ifdef CONFIG_PROC_FS -+ -+#define SAY( fmt, args... ) p += sprintf(p, fmt, ## args ) -+#define SAYV( num ) p += sprintf(p, num_fmt, "Value", num ) -+#define SAYC( label, yn ) p += sprintf(p, yn_fmt, label, yn ) -+#define SAYS( label, v ) p += sprintf(p, cnt_fmt, label, v ) -+ -+static int -+udc_read_proc(char *page, char **start, off_t off, int cnt, int *eof, -+ void *data) -+{ -+ struct sausb_dev *usb = data; -+ char *p = page; -+ u32 v; -+ int len, i; -+ -+ p += usbctl_proc_info(usb->ctl, p); -+ p += sprintf(p, "\nUDC:\n"); -+ v = Ser0UDCAR; -+ p += sprintf(p, "Address\t: %d (0x%02x)\n", v, v); -+ v = Ser0UDCIMP; -+ p += sprintf(p, "IN max\t: %d (0x%02x)\n", v + 1, v); -+ v = Ser0UDCOMP; -+ p += sprintf(p, "OUT max\t: %d (0x%02x)\n", v + 1, v); -+ v = Ser0UDCCR; -+ p += sprintf(p, "UDCCR\t: 0x%02x " -+ "[ %cSUSIM %cTIM %cRIM %cEIM %cRESIM %cUDA %cUDD ] " -+ "(0x%02x)\n", -+ v, -+ v & UDCCR_SUSIM ? '+' : '-', v & UDCCR_TIM ? '+' : '-', -+ v & UDCCR_RIM ? '+' : '-', v & UDCCR_EIM ? '+' : '-', -+ v & UDCCR_RESIM ? '+' : '-', v & UDCCR_UDA ? '+' : '-', -+ v & UDCCR_UDD ? '+' : '-', usb->udccr); -+ v = Ser0UDCCS0; -+ p += sprintf(p, "UDCCS0\t: 0x%02x " -+ "[ %cSO %cSE %cDE %cFST %cSST %cIPR %cOPR ]\n", -+ v, -+ v & UDCCS0_SO ? '+' : '-', v & UDCCS0_SE ? '+' : '-', -+ v & UDCCS0_DE ? '+' : '-', v & UDCCS0_FST ? '+' : '-', -+ v & UDCCS0_SST ? '+' : '-', v & UDCCS0_IPR ? '+' : '-', -+ v & UDCCS0_OPR ? '+' : '-'); -+ v = Ser0UDCCS1; -+ p += sprintf(p, "UDCCS1\t: 0x%02x " -+ "[ %cRNE %cFST %cSST %cRPE %cRPC %cRFS ]\n", -+ v, -+ v & UDCCS1_RNE ? '+' : '-', v & UDCCS1_FST ? '+' : '-', -+ v & UDCCS1_SST ? '+' : '-', v & UDCCS1_RPE ? '+' : '-', -+ v & UDCCS1_RPC ? '+' : '-', v & UDCCS1_RFS ? '+' : '-'); -+ v = Ser0UDCCS2; -+ p += sprintf(p, "UDCCS2\t: 0x%02x " -+ "[ %cFST %cSST %cTUR %cTPE %cTPC %cTFS ]\n", -+ v, -+ v & UDCCS2_FST ? '+' : '-', v & UDCCS2_SST ? '+' : '-', -+ v & UDCCS2_TUR ? '+' : '-', v & UDCCS2_TPE ? '+' : '-', -+ v & UDCCS2_TPC ? '+' : '-', v & UDCCS2_TFS ? '+' : '-'); -+ -+ p += sprintf(p, "\n"); -+ p += sprintf(p, " Bytes Packets FIFO errs Max Sz\n"); -+ p += sprintf(p, "EP0 Rd: %10ld %10ld %10ld -\n", -+ usb->ep0_rd_bytes, -+ usb->ep0_rd_packets, -+ usb->ep0_rd_fifo_errs); -+ p += sprintf(p, "EP0 Wr: %10ld %10ld %10ld -\n", -+ usb->ep0_wr_bytes, -+ usb->ep0_wr_packets, -+ usb->ep0_wr_fifo_errs); -+ -+ for (i = 0; i < 2; i++) -+ p += sprintf(p, "EP%d : %10ld %10ld %10ld %6d\n", -+ i + 1, -+ usb->ep[i].bytes, -+ usb->ep[i].packets, -+ usb->ep[i].fifo_errs, -+ usb->ep[i].maxpktsize); -+ -+ p += sprintf(p, "Stalls sent\t: %ld\n", usb->ep0_stall_sent); -+ p += sprintf(p, "Early ints\t: %ld\n", usb->ep0_early_irqs); -+ -+#if 0 -+ v = Ser0UDCSR; -+ SAY("\nUDC Interrupt Request Register\n"); -+ SAYV(v); -+ SAYC("Reset pending", (v & UDCSR_RSTIR) ? yes : no); -+ SAYC("Suspend pending", (v & UDCSR_SUSIR) ? yes : no); -+ SAYC("Resume pending", (v & UDCSR_RESIR) ? yes : no); -+ SAYC("ep0 pending", (v & UDCSR_EIR) ? yes : no); -+ SAYC("receiver pending", (v & UDCSR_RIR) ? yes : no); -+ SAYC("tramsitter pending", (v & UDCSR_TIR) ? yes : no); -+ -+#ifdef CONFIG_SA1100_EXTENEX1 -+ SAYC("\nSoft connect", -+ (PPSR & PPC_USB_SOFT_CON) ? "Visible" : "Hidden"); -+#endif -+#endif -+ -+ len = (p - page) - off; -+ if (len < 0) -+ len = 0; -+ *eof = (len <= cnt) ? 1 : 0; -+ *start = page + off; -+ -+ return len; -+} -+ -+#endif -+ -+extern struct usbctl usbctl; -+ -+static int __devinit udc_probe(struct device *dev) -+{ -+ struct sausb_dev *usb; -+ int retval; -+ -+ if (!request_mem_region(0x80000000, 0x10000, "sa11x0-udc")) -+ return -EBUSY; -+ -+ usb = kmalloc(sizeof(struct sausb_dev), GFP_KERNEL); -+ if (!usb) -+ return -ENOMEM; -+ -+ memset(usb, 0, sizeof(struct sausb_dev)); -+ dev_set_drvdata(dev, usb); -+ -+ usb_sa1100_drv.priv = usb; -+ -+ usb->dev = dev; -+ usb->ctl = &usbctl; -+ -+ spin_lock_init(&usb->lock); -+ -+ udc_disable(usb); -+ -+ usbctl_init(usb->ctl, &usb_sa1100_drv); -+ -+#ifdef CONFIG_PROC_FS -+ create_proc_read_entry("sausb", 0, NULL, udc_read_proc, usb); -+#endif -+ -+ /* setup rx dma */ -+ retval = sa1100_request_dma(DMA_Ser0UDCRd, "USB receive", -+ NULL, NULL, &usb->ep[0].dmach); -+ if (retval) { -+ printk("UDC: unable to register for rx dma rc=%d\n", -+ retval); -+ goto err; -+ } -+ -+ /* setup tx dma */ -+ retval = sa1100_request_dma(DMA_Ser0UDCWr, "USB transmit", -+ NULL, NULL, &usb->ep[1].dmach); -+ if (retval) { -+ printk("UDC: unable to register for tx dma rc=%d\n", -+ retval); -+ goto err; -+ } -+ -+ /* now allocate the IRQ. */ -+ retval = request_irq(IRQ_Ser0UDC, udc_interrupt, SA_INTERRUPT, -+ "SA USB core", usb); -+ if (retval) { -+ printk("UDC: couldn't request USB irq rc=%d\n", retval); -+ goto err; -+ } -+ -+ return retval; -+ -+ err: -+ if (usb->ep[2].dmach) { -+ sa1100_free_dma(usb->ep[2].dmach); -+ usb->ep[2].dmach = NULL; -+ } -+ if (usb->ep[1].dmach) { -+ sa1100_free_dma(usb->ep[1].dmach); -+ usb->ep[1].dmach = NULL; -+ } -+#ifdef CONFIG_PROC_FS -+ remove_proc_entry("sausb", NULL); -+#endif -+ release_mem_region(0x80000000, 0x10000); -+ return retval; -+} -+ -+/* -+ * Release DMA and interrupt resources -+ */ -+static int __devexit udc_remove(struct device *dev) -+{ -+ struct sausb_dev *usb = dev_get_drvdata(dev); -+ -+ dev_set_drvdata(dev, NULL); -+ -+#ifdef CONFIG_PROC_FS -+ remove_proc_entry("sausb", NULL); -+#endif -+ -+ udc_disable(usb); -+ -+ free_irq(IRQ_Ser0UDC, usb); -+ sa1100_free_dma(usb->ep[1].dmach); -+ sa1100_free_dma(usb->ep[0].dmach); -+ -+ usbctl_exit(usb->ctl); -+ -+ release_mem_region(0x80000000, 0x10000); -+ -+ return 0; -+} -+ -+static struct device_driver sa11x0usb_driver = { -+ .name = "sa11x0-udc", -+ .bus = &platform_bus_type, -+ .probe = udc_probe, -+ .remove = __devexit_p(udc_remove), -+}; -+ -+static int __init udc_init(void) -+{ -+ return driver_register(&sa11x0usb_driver); -+} -+ -+static void __exit udc_exit(void) -+{ -+ driver_unregister(&sa11x0usb_driver); -+} -+ -+module_init(udc_init); -+module_exit(udc_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("SA1100 USB Gadget driver"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/control.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,933 @@ -+/* -+ * usb/control.c -+ * -+ * This parses and handles all the control messages to/from endpoint 0. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "buffer.h" -+#include "client.h" -+#include "usbdev.h" -+ -+#include "sa1100_usb.h" -+ -+#define USB_ENDPOINT_HALT 0 -+#define USB_DEVICE_REMOTE_WAKEUP 1 -+ -+#undef DEBUG -+ -+#ifdef DEBUG -+#define DPRINTK(fmt, args...) printk(KERN_DEBUG fmt , ## args) -+#else -+#define DPRINTK(fmt, args...) -+#endif -+ -+/* -+ * print string descriptor -+ */ -+static char * __attribute__((unused)) -+psdesc(char *str, int len, struct usb_string_descriptor *desc) -+{ -+ char *start = str; -+ int nchars = (desc->bLength - 2) / sizeof(__u16) + 2; -+ int i; -+ -+ if (nchars >= len) -+ nchars = len - 1; -+ -+ nchars -= 2; -+ -+ *str++ = '"'; -+ for(i = 0; i < nchars; i++) -+ *str++ = le16_to_cpu(desc->wData[i]); -+ *str++ = '"'; -+ *str = '\0'; -+ -+ return start; -+} -+ -+enum { -+ kError = -1, -+ kEvSuspend = 0, -+ kEvReset = 1, -+ kEvResume = 2, -+ kEvAddress = 3, -+ kEvConfig = 4, -+ kEvDeConfig = 5 -+}; -+ -+enum { -+ kStateZombie = 0, -+ kStateZombieSuspend = 1, -+ kStateDefault = 2, -+ kStateDefaultSuspend = 3, -+ kStateAddr = 4, -+ kStateAddrSuspend = 5, -+ kStateConfig = 6, -+ kStateConfigSuspend = 7 -+}; -+ -+#define kE kError -+#define kSZ kStateZombie -+#define kSZS kStateZombieSuspend -+#define kSD kStateDefault -+#define kSDS kStateDefaultSuspend -+#define kSA kStateAddr -+#define kSAS kStateAddrSuspend -+#define kSC kStateConfig -+#define kSCS kStateConfigSuspend -+ -+/* -+ * Fig 9-1 P192 -+ * Zombie == Attached | Powered -+ */ -+static int device_state_machine[8][6] = { -+// suspend reset resume addr config deconfig -+{ kSZS, kSD, kE, kE, kE, kE }, /* zombie */ -+{ kE, kSD, kSZ, kE, kE, kE }, /* zom sus */ -+{ kSDS, kError, kSD, kSA, kE, kE }, /* default */ -+{ kE, kSD, kSD, kE, kE, kE }, /* def sus */ -+{ kSAS, kSD, kE, kE, kSC, kE }, /* addr */ -+{ kE, kSD, kSA, kE, kE, kE }, /* addr sus */ -+{ kSCS, kSD, kE, kE, kE, kSA }, /* config */ -+{ kE, kSD, kSC, kE, kE, kE } /* cfg sus */ -+}; -+ -+/* -+ * "device state" is the usb device framework state, as opposed to the -+ * "state machine state" which is whatever the driver needs and is much -+ * more fine grained -+ */ -+static int sm_state_to_device_state[8] = { -+ USB_STATE_POWERED, /* zombie */ -+ USB_STATE_SUSPENDED, /* zombie suspended */ -+ USB_STATE_DEFAULT, /* default */ -+ USB_STATE_SUSPENDED, /* default suspended */ -+ USB_STATE_ADDRESS, /* address */ -+ USB_STATE_SUSPENDED, /* address suspended */ -+ USB_STATE_CONFIGURED, /* config */ -+ USB_STATE_SUSPENDED /* config suspended */ -+}; -+ -+static char * state_names[8] = { -+ "zombie", -+ "zombie suspended", -+ "default", -+ "default suspended", -+ "address", -+ "address suspended", -+ "configured", -+ "config suspended" -+}; -+ -+static char * event_names[6] = { -+ "suspend", -+ "reset", -+ "resume", -+ "address assigned", -+ "configure", -+ "de-configure" -+}; -+ -+static char * device_state_names[] = { -+ "not attached", -+ "attached", -+ "powered", -+ "default", -+ "address", -+ "configured", -+ "suspended" -+}; -+ -+static void usbctl_callbacks(struct usbctl *ctl, int state, int oldstate) -+{ -+ struct usb_client *clnt = ctl->clnt; -+ -+ /* -+ * Inform any clients currently attached -+ * that the connectivity state changed. -+ */ -+ if (clnt && clnt->state_change) -+ clnt->state_change(clnt->priv, state, oldstate); -+} -+ -+/* -+ * called by the interrupt handler here and the two endpoint -+ * files when interesting .."events" happen -+ */ -+static int usbctl_next_state_on_event(struct usbctl *ctl, int event) -+{ -+ int next_state, next_dev_state, old_dev_state; -+ -+ printk(KERN_DEBUG "usbctl: %s --[%s]--> ", state_names[ctl->sm_state], -+ event_names[event]); -+ -+ next_state = device_state_machine[ctl->sm_state][event]; -+ if (next_state != kError) { -+ next_dev_state = sm_state_to_device_state[next_state]; -+ -+ printk("%s. Device in %s state.\n", -+ state_names[next_state], -+ device_state_names[next_dev_state]); -+ -+ old_dev_state = ctl->state; -+ ctl->sm_state = next_state; -+ ctl->state = next_dev_state; -+ -+ if (old_dev_state != next_dev_state) -+ usbctl_callbacks(ctl, next_dev_state, old_dev_state); -+ } else -+ printk("(error)\n"); -+ -+ return next_state; -+} -+ -+/* -+ * Driver detected USB HUB reset. -+ */ -+int usbctl_reset(struct usbctl *ctl) -+{ -+ int ret; -+ -+ ret = usbctl_next_state_on_event(ctl, kEvReset) == kError; -+ -+ if (!ret) { -+ ctl->address = 0; -+ } -+ return ret; -+} -+ -+EXPORT_SYMBOL(usbctl_reset); -+ -+void usbctl_suspend(struct usbctl *ctl) -+{ -+ usbctl_next_state_on_event(ctl, kEvSuspend); -+} -+ -+EXPORT_SYMBOL(usbctl_suspend); -+ -+void usbctl_resume(struct usbctl *ctl) -+{ -+ usbctl_next_state_on_event(ctl, kEvResume); -+} -+ -+EXPORT_SYMBOL(usbctl_resume); -+ -+static struct usb_interface_descriptor * -+usbctl_get_interface_descriptor(struct usbctl *ctl, unsigned int interface) -+{ -+ /*FIXME*/ -+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr(); -+ -+ return (struct usb_interface_descriptor *)&cdb->intf; -+} -+ -+static inline int -+__usbctl_queue(struct usbctl *ctl, struct usb_ctrlrequest *req, -+ struct usb_buf *buf) -+{ -+ unsigned int reqlen = le16_to_cpu(req->wLength); -+ -+ return ctl->driver->ep0_queue(ctl->driver->priv, buf, reqlen) ? -+ RET_ERROR : RET_QUEUED; -+} -+ -+static int -+usbctl_queue(struct usbctl *ctl, struct usb_ctrlrequest *req, -+ void *data, unsigned int len) -+{ -+ struct usb_buf *buf; -+ -+ buf = usbb_alloc(len, GFP_ATOMIC); -+ if (!buf) { -+ printk(KERN_ERR "usb: out of memory\n"); -+ return RET_ERROR; -+ } -+ -+ if (data) -+ memcpy(usbb_push(buf, len), data, len); -+ -+ return __usbctl_queue(ctl, req, buf); -+} -+ -+/* -+ * 9.4.5: Get Status (device) -+ */ -+static int -+usbctl_parse_dev_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ u16 status; -+ -+ status = /* self_powered_hook() ? 1 : 0 */1; -+ -+ status = cpu_to_le16(status); -+ -+ return usbctl_queue(ctl, req, &status, 2); -+} -+ -+/* -+ * Send USB device description to the host. -+ */ -+static int -+usbctl_desc_device(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ return __usbctl_queue(ctl, req, usbb_get(ctl->dev_desc_buf)); -+} -+ -+/* -+ * Send USB configuration information to the host. -+ */ -+static int -+usbctl_desc_config(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ /*FIXME*/ -+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr(); -+ -+ return usbctl_queue(ctl, req, cdb, sizeof(struct cdb)); -+} -+ -+/* -+ * Send a string to the host from the string table. -+ */ -+static int -+usbctl_desc_string(struct usbctl *ctl, struct usb_ctrlrequest *req, -+ unsigned int idx) -+{ -+ struct usb_buf *buf; -+ unsigned int lang = le16_to_cpu(req->wIndex); -+ char string[32] __attribute__((unused)); -+ int ret; -+ -+ DPRINTK("usbctl: desc_string (index %u, lang 0x%04x): ", idx, lang); -+ -+ buf = usbc_string_find(&ctl->strings, lang, idx); -+ if (buf) { -+ DPRINTK("%s\n", idx == 0 ? "language" : -+ psdesc(string, sizeof(string), usbc_string_desc(buf))); -+ -+ ret = __usbctl_queue(ctl, req, buf); -+ } else { -+ DPRINTK("not found -> stall\n"); -+ ret = RET_REQERROR; -+ } -+ return ret; -+} -+ -+/* -+ * Send an interface description (and endpoints) to the host. -+ */ -+static int -+usbctl_desc_interface(struct usbctl *ctl, struct usb_ctrlrequest *req, -+ unsigned int idx) -+{ -+ struct usb_interface_descriptor *desc; -+ int ret; -+ -+ DPRINTK("usbctl: desc_interface (index %d)\n", idx); -+ -+ desc = usbctl_get_interface_descriptor(ctl, idx); -+ -+ if (desc) { -+ ret = usbctl_queue(ctl, req, desc, desc->bLength); -+ } else { -+ printk("usbctl: unknown interface %d\n", idx); -+ ret = RET_REQERROR; -+ } -+ -+ return ret; -+} -+ -+/* -+ * Send an endpoint (1 .. n) to the host. -+ */ -+static int -+usbctl_desc_endpoint(struct usbctl *ctl, struct usb_ctrlrequest *req, -+ unsigned int idx) -+{ -+ int ret; -+ -+ DPRINTK("usbctl: desc_endpoint (index %d)\n", idx); -+ -+ if (idx >= 1 && idx <= ctl->nr_ep) { -+ struct usb_endpoint_descriptor *ep = ctl->ep_desc[idx - 1]; -+ -+ ret = usbctl_queue(ctl, req, ep, ep->bLength); -+ } else { -+ printk("usbctl: unknown endpoint %d\n", idx); -+ ret = RET_REQERROR; -+ } -+ -+ return ret; -+} -+ -+/* -+ * 9.4.3: Parse a request for a descriptor. -+ * Unspecified conditions: -+ * None -+ * Valid states: default, address, configured. -+ */ -+static int -+usbctl_parse_dev_descriptor(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int idx = le16_to_cpu(req->wValue) & 255; -+ unsigned int type = le16_to_cpu(req->wValue) >> 8; -+ int ret; -+ -+ switch (type) { -+ case USB_DT_DEVICE: /* check if idx matters */ -+ ret = usbctl_desc_device(ctl, req); -+ break; -+ -+ case USB_DT_CONFIG: /* check if idx matters */ -+ ret = usbctl_desc_config(ctl, req); -+ break; -+ -+ case USB_DT_STRING: -+ ret = usbctl_desc_string(ctl, req, idx); -+ break; -+ -+ case USB_DT_INTERFACE: -+ ret = usbctl_desc_interface(ctl, req, idx); -+ break; -+ -+ case USB_DT_ENDPOINT: -+ ret = usbctl_desc_endpoint(ctl, req, idx); -+ break; -+ -+ case USB_DT_DEVICE_QUALIFIER: -+ case USB_DT_OTHER_SPEED_CONFIG: -+ case USB_DT_INTERFACE_POWER: -+ default: -+ printk(KERN_ERR "usbctl: unknown descriptor: " -+ "wValue = 0x%04x wIndex = 0x%04x\n", -+ le16_to_cpu(req->wValue), le16_to_cpu(req->wIndex)); -+ ret = RET_REQERROR; -+ break; -+ } -+ -+ return ret; -+} -+ -+/* -+ * 9.4.6: Set Address -+ * The USB1.1 spec says the response to SetAddress() with value 0 -+ * is undefined. It then goes on to define the response. We -+ * acknowledge addresses of zero, but take no further action. -+ */ -+static int -+usbctl_parse_dev_set_address(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int address = le16_to_cpu(req->wValue) & 0x7f; -+ -+ if (ctl->state == USB_STATE_CONFIGURED) -+ return RET_REQERROR; -+ -+ if (address != 0) { -+ ctl->address = address; -+ -+ usbctl_next_state_on_event(ctl, kEvAddress); -+ -+ ctl->driver->set_address(ctl->driver->priv, address); -+ } -+ -+ return RET_ACK; -+} -+ -+/* -+ * 9.4.2: Get Configuration. -+ * Unspecified conditions: -+ * - non-zero wIndex, wValue or wLength (ignored) -+ * - default state (request error) -+ * Valid states: address, configured. -+ */ -+static int -+usbctl_parse_dev_get_config(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ u8 status = 0; -+ -+ if (ctl->state == USB_STATE_CONFIGURED) -+ status = 1; -+ -+ return usbctl_queue(ctl, req, &status, 1); -+} -+ -+/* -+ * 9.4.7: Set Configuration. -+ * Unspecified conditions: -+ * - default state (request error) -+ */ -+static int -+usbctl_parse_dev_set_config(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int cfg = le16_to_cpu(req->wValue); -+ int ret = RET_REQERROR; -+ -+ if (ctl->state == USB_STATE_DEFAULT) -+ return ret; -+ -+ if (cfg == 0) { -+ /* enter address state, or remain in address state */ -+ usbctl_next_state_on_event(ctl, kEvDeConfig); -+ -+ ctl->driver->set_config(ctl->driver->priv, NULL); -+ -+ ret = RET_ACK; -+ } else if (cfg == 1) { -+ /* enter configured state, and set configuration */ -+ /*FIXME*/ -+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr(); -+ -+ usbctl_next_state_on_event(ctl, kEvConfig); -+ -+ ctl->driver->set_config(ctl->driver->priv, cdb); -+ ret = RET_ACK; -+ } -+ -+ return ret; -+} -+ -+/* -+ * Interface handling -+ */ -+ -+/* -+ * 9.4.5: Get Status (interface) -+ */ -+static int -+usbctl_parse_int_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int interface = le16_to_cpu(req->wIndex) & 255; -+ u16 status; -+ -+ switch (ctl->state) { -+ case USB_STATE_DEFAULT: -+ return RET_REQERROR; -+ -+ case USB_STATE_ADDRESS: -+ if (interface != 0) -+ return RET_REQERROR; -+ break; -+ -+ case USB_STATE_CONFIGURED: -+ if (interface != 1) -+ return RET_REQERROR; -+ break; -+ } -+ -+ status = cpu_to_le16(0); -+ -+ return usbctl_queue(ctl, req, &status, 2); -+} -+ -+/* -+ * 9.4.4: Get Interface -+ * Unspecified conditions: -+ * - -+ * States: Default (unspecified), Address (Request Error), Configured (ok) -+ */ -+static int -+usbctl_parse_int_get_interface(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int interface = le16_to_cpu(req->wIndex) & 255; -+ u8 null = 0; -+ -+ if (ctl->state != USB_STATE_CONFIGURED) -+ return RET_REQERROR; -+ -+ /* -+ * If the interface doesn't exist, respond with request error -+ */ -+ if (interface != 1) -+ return RET_REQERROR; -+ -+ printk("usbctl: get interface %d not supported\n", interface); -+ -+ return usbctl_queue(ctl, req, &null, 1); -+} -+ -+static int -+usbctl_parse_int_set_interface(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int interface = le16_to_cpu(req->wIndex) & 255; -+ -+ if (interface != 0) -+ printk("usbctl: set interface %d not supported (ignored)\n", -+ interface); -+ -+ return RET_ACK; -+} -+ -+/* -+ * Endpoint handling -+ */ -+ -+/* -+ * 9.4.5: Get Status (endpoint) -+ */ -+static int -+usbctl_parse_ep_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int ep = le16_to_cpu(req->wIndex) & 15; -+ u16 status; -+ -+ if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) || -+ ep <= ctl->nr_ep) -+ return RET_REQERROR; -+ -+ status = ctl->driver->ep_get_status(ctl->driver->priv, ep); -+ status = cpu_to_le16(status); -+ -+ return usbctl_queue(ctl, req, &status, 2); -+} -+ -+/* -+ * 9.4.1: Clear an endpoint feature. We only support ENDPOINT_HALT. -+ * Unspecified conditions: -+ * - non-zero wLength is not specified (ignored) -+ * Valid states: Address, Configured. -+ */ -+static int -+usbctl_parse_ep_clear_feature(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int feature = le16_to_cpu(req->wValue); -+ unsigned int ep = le16_to_cpu(req->wIndex) & 15; -+ int ret; -+ -+ if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) || -+ ep <= ctl->nr_ep) -+ return RET_REQERROR; -+ -+ if (feature == USB_ENDPOINT_HALT) { -+ ctl->driver->ep_halt(ctl->driver->priv, ep, 0); -+ ret = RET_ACK; -+ } else { -+ printk(KERN_ERR "usbctl: unsupported clear feature: " -+ "wValue = 0x%04x wIndex = 0x%04x\n", -+ feature, ep); -+ -+ ret = RET_REQERROR; -+ } -+ return ret; -+} -+ -+/* -+ * 9.4.9: Set Feature (endpoint) -+ */ -+static int -+usbctl_parse_ep_set_feature(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int feature = le16_to_cpu(req->wValue); -+ unsigned int ep = le16_to_cpu(req->wIndex) & 15; -+ int ret; -+ -+ if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) || -+ ep <= ctl->nr_ep) -+ return RET_REQERROR; -+ -+ if (feature == USB_ENDPOINT_HALT) { -+ ctl->driver->ep_halt(ctl->driver->priv, ep, 1); -+ ret = RET_ACK; -+ } else { -+ printk(KERN_ERR "usbctl: unsupported set feature " -+ "wValue = 0x%04x wIndex = 0x%04x\n", -+ feature, ep); -+ -+ ret = RET_REQERROR; -+ } -+ return ret; -+} -+ -+/* -+ * This reflects Table 9.3 (p186) in the USB1.1 spec. -+ * -+ * Some notes: -+ * - USB1.1 specifies remote wakeup feature, so we don't implement -+ * USB_RECIP_DEVICE USB_REQ_{SET,CLEAR}_FEATURE -+ * - USB1.1 doesn't actually specify any interface features, so we -+ * don't implement USB_RECIP_INTERFACE USB_REQ_{SET,CLEAR}_FEATURE -+ */ -+static int (*request_fns[4][16])(struct usbctl *, struct usb_ctrlrequest *) = { -+ [USB_RECIP_DEVICE] = { -+ [USB_REQ_GET_STATUS] = usbctl_parse_dev_get_status, -+ [USB_REQ_CLEAR_FEATURE] = NULL, -+ [USB_REQ_SET_FEATURE] = NULL, -+ [USB_REQ_SET_ADDRESS] = usbctl_parse_dev_set_address, -+ [USB_REQ_GET_DESCRIPTOR] = usbctl_parse_dev_descriptor, -+ [USB_REQ_SET_DESCRIPTOR] = NULL, -+ [USB_REQ_GET_CONFIGURATION] = usbctl_parse_dev_get_config, -+ [USB_REQ_SET_CONFIGURATION] = usbctl_parse_dev_set_config, -+ }, -+ -+ [USB_RECIP_INTERFACE] = { -+ [USB_REQ_GET_STATUS] = usbctl_parse_int_get_status, -+ [USB_REQ_CLEAR_FEATURE] = NULL, -+ [USB_REQ_SET_FEATURE] = NULL, -+ [USB_REQ_GET_INTERFACE] = usbctl_parse_int_get_interface, -+ [USB_REQ_SET_INTERFACE] = usbctl_parse_int_set_interface, -+ }, -+ -+ [USB_RECIP_ENDPOINT] = { -+ [USB_REQ_GET_STATUS] = usbctl_parse_ep_get_status, -+ [USB_REQ_CLEAR_FEATURE] = usbctl_parse_ep_clear_feature, -+ [USB_REQ_SET_FEATURE] = usbctl_parse_ep_set_feature, -+ }, -+}; -+ -+static void __attribute__((unused)) -+usbctl_dump_request(const char *prefix, const struct usb_ctrlrequest *req) -+{ -+ printk("%sbRequestType=0x%02x bRequest=0x%02x " -+ "wValue=0x%04x wIndex=0x%04x wLength=0x%04x\n", -+ prefix, req->bRequestType, req->bRequest, -+ le16_to_cpu(req->wValue), le16_to_cpu(req->wIndex), -+ le16_to_cpu(req->wLength)); -+} -+ -+int usbctl_parse_request(struct usbctl *ctl, struct usb_ctrlrequest *req) -+{ -+ unsigned int type; -+ int (*fn)(struct usbctl *, struct usb_ctrlrequest *) = NULL; -+ int ret = RET_REQERROR; -+ -+ //usbctl_dump_request("usbctl: ", req); -+ -+ type = req->bRequestType & USB_TYPE_MASK; -+ if (type == USB_TYPE_STANDARD) { -+ unsigned int recip; -+ -+ recip = req->bRequestType & USB_RECIP_MASK; -+ if (recip < ARRAY_SIZE(request_fns) && -+ req->bRequest < ARRAY_SIZE(request_fns[0])) -+ fn = request_fns[recip][req->bRequest]; -+ } -+ -+ if (fn) -+ ret = fn(ctl, req); -+ else -+ usbctl_dump_request(KERN_ERR "usbctl: unknown request: ", -+ req); -+ -+ /* -+ * Make sure we're doing the right thing. -+ */ -+ if (req->bRequestType & USB_DIR_IN) { -+ if (ret != RET_QUEUED && ret != RET_REQERROR) -+ printk("Error: device to host transfer expected\n"); -+ } else { -+ if (ret == RET_QUEUED) -+ printk("Error: no device to host transfer expected\n"); -+ } -+ -+ return ret; -+} -+ -+EXPORT_SYMBOL(usbctl_parse_request); -+ -+/* Start running. Must have called usb_open (above) first */ -+int usbctl_start(struct usb_client *client) -+{ -+ struct usbctl *ctl = client->ctl; -+ -+ if (ctl == NULL || ctl->clnt != client) { -+ printk("usbctl: start: no client registered\n"); -+ return -EPERM; -+ } -+ -+ ctl->sm_state = kStateZombie; -+ ctl->state = USB_STATE_POWERED; -+ -+ /* -+ * Notify the client as to our state. -+ */ -+ usbctl_callbacks(ctl, USB_STATE_POWERED, USB_STATE_SUSPENDED); -+ -+ return ctl->driver->start(ctl->driver->priv); -+} -+ -+EXPORT_SYMBOL(usbctl_start); -+ -+/* -+ * Stop USB core from running -+ */ -+void usbctl_stop(struct usb_client *client) -+{ -+ struct usbctl *ctl = client->ctl; -+ -+ if (ctl == NULL || ctl->clnt != client) { -+ printk("USBDEV: stop: no client/driver registered\n"); -+ return; -+ } -+ -+ ctl->driver->stop(ctl->driver->priv); -+} -+ -+EXPORT_SYMBOL(usbctl_stop); -+ -+struct usbctl usbctl; -+ -+EXPORT_SYMBOL(usbctl); -+ -+/* Open SA usb core on behalf of a client, but don't start running */ -+ -+int usbctl_open(struct usb_client *client) -+{ -+ struct usbctl *ctl = &usbctl; -+ int ret; -+printk("usbctl_open: ctl %p driver %p\n", ctl, ctl->driver); -+ if (!ctl->driver || !try_module_get(ctl->driver->owner)) -+ return -ENODEV; -+ -+ if (ctl->clnt != NULL) { -+ ret = -EBUSY; -+ goto err; -+ } -+ -+ ctl->clnt = client; -+ ctl->state = USB_STATE_SUSPENDED; -+ ctl->nr_ep = 2; -+ /* start in zombie suspended state */ -+ ctl->sm_state = kStateZombieSuspend; -+ ctl->state = USB_STATE_SUSPENDED; -+ client->ctl = ctl; -+ -+ ctl->dev_desc_buf = usbb_alloc(sizeof(struct usb_device_descriptor), -+ GFP_KERNEL); -+ if (!ctl->dev_desc_buf) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ ctl->dev_desc = usbb_push(ctl->dev_desc_buf, -+ sizeof(struct usb_device_descriptor)); -+ -+ /* create descriptors for enumeration */ -+ initialize_descriptors(ctl); -+ -+ return 0; -+ -+ err: -+ module_put(ctl->driver->owner); -+ return ret; -+} -+ -+EXPORT_SYMBOL(usbctl_open); -+ -+/* Tell SA core client is through using it */ -+void usbctl_close(struct usb_client *client) -+{ -+ struct usbctl *ctl = client->ctl; -+ -+ if (ctl == NULL || ctl->clnt != client) { -+ printk("usbctl: close: no client registered\n"); -+ return; -+ } -+ -+ usbb_put(ctl->dev_desc_buf); -+ -+ client->ctl = NULL; -+ ctl->clnt = NULL; -+ ctl->dev_desc = NULL; -+ ctl->dev_desc_buf = NULL; -+ /* reset to zombie suspended state */ -+ ctl->sm_state = kStateZombieSuspend; -+ ctl->state = USB_STATE_SUSPENDED; -+ -+ usbc_string_free_all(&ctl->strings); -+ -+ if (ctl->driver->owner) -+ module_put(ctl->driver->owner); -+} -+ -+EXPORT_SYMBOL(usbctl_close); -+ -+int usbctl_proc_info(struct usbctl *ctl, char *buf) -+{ -+ char *p = buf; -+ -+ p += sprintf(p, "USB Gadget Core:\n"); -+ p += sprintf(p, "Driver\t: %s\n", -+ ctl->driver ? ctl->driver->name : "none"); -+ p += sprintf(p, "Client\t: %s\n", -+ ctl->clnt ? ctl->clnt->name : "none"); -+ p += sprintf(p, "State\t: %s (%s) %d\n", -+ device_state_names[sm_state_to_device_state[ctl->sm_state]], -+ state_names[ctl->sm_state], -+ ctl->sm_state); -+ p += sprintf(p, "Address\t: %d\n", ctl->address); -+ -+ return p - buf; -+} -+ -+EXPORT_SYMBOL(usbctl_proc_info); -+ -+int -+usbctl_ep_queue_buffer(struct usbctl *ctl, unsigned int ep, -+ char *buf, unsigned int len) -+{ -+ return ctl->driver->ep_queue(ctl->driver->priv, ep, buf, len); -+} -+ -+EXPORT_SYMBOL(usbctl_ep_queue_buffer); -+ -+void usbctl_ep_reset(struct usbctl *ctl, unsigned int ep) -+{ -+ return ctl->driver->ep_reset(ctl->driver->priv, ep); -+} -+ -+EXPORT_SYMBOL(usbctl_ep_reset); -+ -+void -+usbctl_ep_set_callback(struct usbctl *ctl, unsigned int ep, -+ usb_callback_t callback, void *data) -+{ -+ ctl->driver->ep_callback(ctl->driver->priv, ep, callback, data); -+} -+ -+EXPORT_SYMBOL(usbctl_ep_set_callback); -+ -+int usbctl_ep_idle(struct usbctl *ctl, unsigned int ep) -+{ -+ return ctl->driver->ep_idle(ctl->driver->priv, ep); -+} -+ -+EXPORT_SYMBOL(usbctl_ep_idle); -+ -+/* -+ * usbctl_init() -+ * Module load time. Allocate dma and interrupt resources. Setup /proc fs -+ * entry. Leave UDC disabled. -+ */ -+int usbctl_init(struct usbctl *ctl, struct usbc_driver *drv) -+{ -+ usbc_string_init(&ctl->strings); -+printk("usbctl_init: %p %p\n", ctl, drv); -+ /* -+ * start in zombie suspended state -+ */ -+ ctl->sm_state = kStateZombieSuspend; -+ ctl->state = USB_STATE_SUSPENDED; -+ ctl->driver = drv; -+ -+ return 0; -+} -+ -+/* -+ * usbctl_exit() -+ */ -+void usbctl_exit(struct usbctl *ctl) -+{ -+ usbc_string_free_all(&ctl->strings); -+ -+ ctl->driver = NULL; -+} -+ -+EXPORT_SYMBOL(usbctl_init); -+EXPORT_SYMBOL(usbctl_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("USB gadget core"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/client.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,40 @@ -+#ifndef USBDEV_CLIENT_H -+#define USBDEV_CLIENT_H -+ -+#include "sa1100_usb.h" /* grr */ -+ -+struct usbctl; -+ -+struct usb_client { -+ struct usbctl *ctl; -+ const char *name; /* Client name */ -+ void *priv; /* Client-private data */ -+ void (*state_change)(void *priv, int state, int oldstate); -+ __u16 vendor; /* USB vendor ID */ -+ __u16 product; /* USB product ID */ -+ __u16 version; /* USB version ID */ -+ __u8 class; /* USB class */ -+ __u8 subclass; /* USB subclass */ -+ __u8 protocol; /* USB protocol */ -+ __u8 unused1; -+ __u16 unused2; -+ const char *manufacturer_str; -+ const char *product_str; -+ const char *serial_str; -+}; -+ -+int usbctl_start(struct usb_client *client); -+void usbctl_stop(struct usb_client *client); -+int usbctl_open(struct usb_client *client); -+void usbctl_close(struct usb_client *client); -+ -+int -+usbctl_ep_queue_buffer(struct usbctl *ctl, unsigned int ep, -+ char *buf, unsigned int len); -+void usbctl_ep_reset(struct usbctl *ctl, unsigned int ep); -+void -+usbctl_ep_set_callback(struct usbctl *ctl, unsigned int ep, -+ usb_callback_t callback, void *data); -+int usbctl_ep_idle(struct usbctl *ctl, unsigned int ep); -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/sa1100_usb.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,50 @@ -+/* -+ * sa1100_usb.h -+ * -+ * Public interface to the sa1100 USB core. For use by client modules -+ * like usb-eth and usb-char. -+ * -+ */ -+#ifndef _SA1100_USB_H -+#define _SA1100_USB_H -+ -+typedef void (*usb_callback_t)(void *data, int flag, int size); -+ -+/* in usb_send.c */ -+int sa1100_usb_xmitter_avail( void ); -+int sa1100_usb_send(char *buf, int len); -+void sa1100_usb_send_set_callback(usb_callback_t callback, void *data); -+void sa1100_usb_send_reset(void); -+ -+/* in usb_recev.c */ -+int sa1100_usb_recv(char *buf, int len); -+void sa1100_usb_recv_set_callback(usb_callback_t callback, void *data); -+void sa1100_usb_recv_reset(void); -+ -+////////////////////////////////////////////////////////////////////////////// -+// Descriptor Management -+////////////////////////////////////////////////////////////////////////////// -+ -+// MaxPower: -+#define USB_POWER(x) ((x)>>1) /* convert mA to descriptor units of A for MaxPower */ -+ -+/* "config descriptor buffer" - that is, one config, -+ ..one interface and 2 endpoints */ -+struct cdb { -+ struct usb_config_descriptor cfg; -+ struct usb_interface_descriptor intf; -+ struct usb_endpoint_descriptor ep1, ep2; -+} __attribute__ ((packed)); -+ -+ -+/*======================================================= -+ * Descriptor API -+ */ -+ -+/* Get the address of the statically allocated desc_t structure -+ in the usb core driver. Clients can modify this between -+ the time they call sa1100_usb_open() and sa1100_usb_start() -+*/ -+struct cdb *sa1100_usb_get_descriptor_ptr(void); -+ -+#endif /* _SA1100_USB_H */ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/sa1100usb.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,136 @@ -+/* -+ * Copyright (C) Compaq Computer Corporation, 1998, 1999 -+ * Copyright (C) Extenex Corporation 2001 -+ * -+ * usb_ctl.h -+ * -+ * PRIVATE interface used to share info among components of the SA-1100 USB -+ * core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core -+ * should use sa1100_usb.h. -+ * -+ */ -+#ifndef SA1100USB_H -+#define SA1100USB_H -+ -+struct usbctl; -+ -+struct sausb_dev { -+ struct device *dev; -+ struct usbctl *ctl; -+ spinlock_t lock; -+ -+ u32 udccr; -+ -+ /* -+ * EP0 write thread. -+ */ -+ void (*wrint)(struct sausb_dev *); -+ struct usb_buf *wrbuf; -+ unsigned char *wrptr; -+ unsigned int wrlen; -+ -+ /* -+ * EP0 statistics. -+ */ -+ unsigned long ep0_wr_fifo_errs; -+ unsigned long ep0_wr_bytes; -+ unsigned long ep0_wr_packets; -+ unsigned long ep0_rd_fifo_errs; -+ unsigned long ep0_rd_bytes; -+ unsigned long ep0_rd_packets; -+ unsigned long ep0_stall_sent; -+ unsigned long ep0_early_irqs; -+ -+ /* -+ * EP1 .. n -+ */ -+ struct { -+ dma_regs_t *dmach; -+ -+ dma_addr_t bufdma; -+ unsigned int buflen; -+ void *pktcpu; -+ dma_addr_t pktdma; -+ unsigned int pktlen; -+ unsigned int pktrem; -+ -+ void *cb_data; -+ void (*cb_func)(void *data, int flag, int size); -+ -+ u32 udccs; -+ unsigned int maxpktsize; -+ unsigned int configured; -+ unsigned int host_halt; -+ unsigned long fifo_errs; -+ unsigned long bytes; -+ unsigned long packets; -+ } ep[2]; -+}; -+ -+/* receiver */ -+int ep1_recv(void); -+void udc_ep1_init(struct sausb_dev *); -+void udc_ep1_halt(struct sausb_dev *, int); -+void udc_ep1_reset(struct sausb_dev *); -+void udc_ep1_config(struct sausb_dev *, unsigned int); -+void udc_ep1_int_hndlr(struct sausb_dev *); -+ -+/* xmitter */ -+void udc_ep2_init(struct sausb_dev *); -+void udc_ep2_halt(struct sausb_dev *, int); -+void udc_ep2_reset(struct sausb_dev *); -+void udc_ep2_config(struct sausb_dev *, unsigned int); -+void udc_ep2_int_hndlr(struct sausb_dev *); -+ -+#define UDC_write(reg, val) do { \ -+ int i = 10000; \ -+ do { \ -+ (reg) = (val); \ -+ if (i-- <= 0) { \ -+ printk( "%s [%d]: write %#x to %p (%#x) failed\n", \ -+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \ -+ break; \ -+ } \ -+ } while((reg) != (val)); \ -+} while (0) -+ -+#define UDC_set(reg, val) do { \ -+ int i = 10000; \ -+ do { \ -+ (reg) |= (val); \ -+ if (i-- <= 0) { \ -+ printk( "%s [%d]: set %#x of %p (%#x) failed\n", \ -+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \ -+ break; \ -+ } \ -+ } while(!((reg) & (val))); \ -+} while (0) -+ -+#define UDC_clear(reg, val) do { \ -+ int i = 10000; \ -+ do { \ -+ (reg) &= ~(val); \ -+ if (i-- <= 0) { \ -+ printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \ -+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \ -+ break; \ -+ } \ -+ } while((reg) & (val)); \ -+} while (0) -+ -+#define UDC_flip(reg, val) do { \ -+ int i = 10000; \ -+ (reg) = (val); \ -+ do { \ -+ (reg) = (val); \ -+ if (i-- <= 0) { \ -+ printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \ -+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \ -+ break; \ -+ } \ -+ } while(((reg) & (val))); \ -+} while (0) -+ -+#define CHECK_ADDRESS { if ( Ser0UDCAR == 1 ) { printk("%s:%d I lost my address!!!\n",__FUNCTION__, __LINE__);}} -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/strings.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,117 @@ -+/* -+ * usb/strings.c -+ * -+ * Copyright (C) 2002 Russell King. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "buffer.h" -+#include "strings.h" -+ -+struct usb_buf *usbc_string_alloc(int len) -+{ -+ struct usb_buf *buf; -+ int tot_len; -+ -+ tot_len = sizeof(struct usb_descriptor_header) + sizeof(u16) * len; -+ -+ buf = usbb_alloc(tot_len, GFP_KERNEL); -+ -+ if (buf) { -+ struct usb_string_descriptor *desc = usbb_push(buf, tot_len); -+ -+ desc->bLength = tot_len; -+ desc->bDescriptorType = USB_DT_STRING; -+ } -+ return buf; -+} -+ -+void usbc_string_free(struct usb_buf *buf) -+{ -+ if (buf) -+ usbb_put(buf); -+} -+ -+void usbc_string_from_cstr(struct usb_buf *buf, const char *str) -+{ -+ struct usb_string_descriptor *desc = usbc_string_desc(buf); -+ int i, len; -+ -+ len = strlen(str); -+ BUG_ON((sizeof(__u16) * len) > desc->bLength - sizeof(struct usb_descriptor_header)); -+ -+ for (i = 0; i < len; i++) -+ desc->wData[i] = cpu_to_le16(str[i]); -+} -+ -+int usbc_string_add(struct usbc_strs *table, struct usb_buf *buf) -+{ -+ int nr, i; -+ -+ nr = -ENOSPC; -+ spin_lock_irq(&table->lock); -+ for (i = 0; i < NR_STRINGS; i++) -+ if (table->buf[i] == NULL) { -+ table->buf[i] = buf; -+ nr = i; -+ break; -+ } -+ spin_unlock_irq(&table->lock); -+ -+ return nr; -+} -+ -+void usbc_string_del(struct usbc_strs *table, int nr) -+{ -+ if (nr < NR_STRINGS) { -+ spin_lock_irq(&table->lock); -+ table->buf[nr] = NULL; -+ spin_unlock_irq(&table->lock); -+ } -+} -+ -+struct usb_buf * -+usbc_string_find(struct usbc_strs *table, unsigned int lang, unsigned int idx) -+{ -+ struct usb_buf *buf = NULL; -+ -+ if (idx < NR_STRINGS) { -+ spin_lock_irq(&table->lock); -+ buf = usbb_get(table->buf[idx]); -+ spin_unlock_irq(&table->lock); -+ } -+ -+ return buf; -+} -+ -+void usbc_string_free_all(struct usbc_strs *table) -+{ -+ int i; -+ -+ spin_lock_irq(&table->lock); -+ for (i = 0; i < NR_STRINGS; i++) { -+ usbc_string_free(table->buf[i]); -+ table->buf[i] = NULL; -+ } -+ spin_unlock_irq(&table->lock); -+} -+ -+void usbc_string_init(struct usbc_strs *table) -+{ -+ memset(table, 0, sizeof(struct usbc_strs)); -+ spin_lock_init(&table->lock); -+} -+ -+EXPORT_SYMBOL(usbc_string_from_cstr); -+EXPORT_SYMBOL(usbc_string_alloc); -+EXPORT_SYMBOL(usbc_string_free); -+EXPORT_SYMBOL(usbc_string_add); -+EXPORT_SYMBOL(usbc_string_del); -+EXPORT_SYMBOL(usbc_string_find); -+EXPORT_SYMBOL(usbc_string_free_all); -+EXPORT_SYMBOL(usbc_string_init); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_ctl.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,171 @@ -+ /* -+ * Copyright (C) Compaq Computer Corporation, 1998, 1999 -+ * Copyright (C) Extenex Corporation, 2001 -+ * -+ * usb_ctl.c -+ * -+ * SA1100 USB controller core driver. -+ * -+ * This file provides interrupt routing and overall coordination -+ * of the three endpoints in usb_ep0, usb_receive (1), and usb_send (2). -+ * -+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details. -+ * -+ */ -+#include -+#include -+#include -+ -+#include "buffer.h" -+#include "client.h" -+#include "usbdev.h" -+#include "sa1100_usb.h" -+ -+////////////////////////////////////////////////////////////////////////////// -+// Globals -+////////////////////////////////////////////////////////////////////////////// -+ -+/* device descriptors */ -+static struct cdb cdb; -+ -+////////////////////////////////////////////////////////////////////////////// -+// Private Helpers -+////////////////////////////////////////////////////////////////////////////// -+ -+int sa1100_usb_add_string(struct usbctl *ctl, const char *str) -+{ -+ int nr = 0; -+ -+ if (str) { -+ struct usb_buf *buf; -+ int len; -+ -+ len = strlen(str); -+ -+ nr = -ENOMEM; -+ buf = usbc_string_alloc(len); -+ if (buf) { -+ usbc_string_from_cstr(buf, str); -+ nr = usbc_string_add(&ctl->strings, buf); -+ -+ if (nr < 0) -+ usbc_string_free(buf); -+ } -+ } -+ -+ return nr; -+} -+ -+EXPORT_SYMBOL(sa1100_usb_add_string); -+ -+static int sa1100_usb_add_language(struct usbctl *ctl, unsigned int lang) -+{ -+ struct usb_buf *buf; -+ int nr = -ENOMEM; -+ -+ buf = usbc_string_alloc(1); -+ if (buf) { -+ usbc_string_desc(buf)->wData[0] = cpu_to_le16(lang); /* American English */ -+ nr = usbc_string_add(&ctl->strings, buf); -+ -+ if (nr < 0) -+ usbc_string_free(buf); -+ } -+ -+ return nr; -+} -+ -+/* setup default descriptors */ -+ -+void initialize_descriptors(struct usbctl *ctl) -+{ -+ struct usb_client *clnt = ctl->clnt; -+ int r; -+ -+ ctl->ep_desc[0] = (struct usb_endpoint_descriptor *)&cdb.ep1; -+ ctl->ep_desc[1] = (struct usb_endpoint_descriptor *)&cdb.ep2; -+ -+ cdb.cfg.bLength = USB_DT_CONFIG_SIZE; -+ cdb.cfg.bDescriptorType = USB_DT_CONFIG; -+ cdb.cfg.wTotalLength = cpu_to_le16(sizeof(struct cdb)); -+ cdb.cfg.bNumInterfaces = 1; -+ cdb.cfg.bConfigurationValue = 1; -+ cdb.cfg.iConfiguration = 0; -+ cdb.cfg.bmAttributes = USB_CONFIG_ATT_ONE; -+ cdb.cfg.bMaxPower = USB_POWER( 500 ); -+ -+ cdb.intf.bLength = USB_DT_INTERFACE_SIZE; -+ cdb.intf.bDescriptorType = USB_DT_INTERFACE; -+ cdb.intf.bInterfaceNumber = 0; /* unique intf index*/ -+ cdb.intf.bAlternateSetting = 0; -+ cdb.intf.bNumEndpoints = 2; -+ cdb.intf.bInterfaceClass = 0xff; /* vendor specific */ -+ cdb.intf.bInterfaceSubClass = 0; -+ cdb.intf.bInterfaceProtocol = 0; -+ cdb.intf.iInterface = 0; -+ -+ cdb.ep1.bLength = USB_DT_INTERFACE_SIZE; -+ cdb.ep1.bDescriptorType = USB_DT_ENDPOINT; -+ cdb.ep1.bEndpointAddress = USB_DIR_OUT | 1; -+ cdb.ep1.bmAttributes = USB_ENDPOINT_XFER_BULK; -+ cdb.ep1.wMaxPacketSize = cpu_to_le16(64); -+ cdb.ep1.bInterval = 0; -+ -+ cdb.ep2.bLength = USB_DT_INTERFACE_SIZE; -+ cdb.ep2.bDescriptorType = USB_DT_ENDPOINT; -+ cdb.ep2.bEndpointAddress = USB_DIR_IN | 2; -+ cdb.ep2.bmAttributes = USB_ENDPOINT_XFER_BULK; -+ cdb.ep2.wMaxPacketSize = cpu_to_le16(64); -+ cdb.ep2.bInterval = 0; -+ -+ ctl->dev_desc->bLength = USB_DT_DEVICE_SIZE; -+ ctl->dev_desc->bDescriptorType = USB_DT_DEVICE; -+ ctl->dev_desc->bcdUSB = cpu_to_le16(0x100); /* 1.0 */ -+ ctl->dev_desc->bDeviceClass = clnt->class; -+ ctl->dev_desc->bDeviceSubClass = clnt->subclass; -+ ctl->dev_desc->bDeviceProtocol = clnt->protocol; -+ ctl->dev_desc->bMaxPacketSize0 = 8; /* ep0 max fifo size */ -+ ctl->dev_desc->idVendor = cpu_to_le16(clnt->vendor); -+ ctl->dev_desc->idProduct = cpu_to_le16(clnt->product); -+ ctl->dev_desc->bcdDevice = cpu_to_le16(clnt->version); -+ ctl->dev_desc->bNumConfigurations = 1; -+ -+ /* set language */ -+ /* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */ -+ r = sa1100_usb_add_language(ctl, 0x409); -+ if (r < 0) -+ printk(KERN_ERR "usbc: couldn't add language\n"); -+ -+ r = sa1100_usb_add_string(ctl, clnt->manufacturer_str); -+ if (r < 0) -+ printk(KERN_ERR "usbc: couldn't add manufacturer string\n"); -+ -+ ctl->dev_desc->iManufacturer = r > 0 ? r : 0; -+ -+ r = sa1100_usb_add_string(ctl, clnt->product_str); -+ if (r < 0) -+ printk(KERN_ERR "usbc: couldn't add product string\n"); -+ -+ ctl->dev_desc->iProduct = r > 0 ? r : 0; -+ -+ r = sa1100_usb_add_string(ctl, clnt->serial_str); -+ if (r < 0) -+ printk(KERN_ERR "usbc: couldn't add serial string\n"); -+ -+ ctl->dev_desc->iSerialNumber = r > 0 ? r : 0; -+} -+ -+ -+/*==================================================== -+ * Descriptor Manipulation. -+ * Use these between open() and start() above to setup -+ * the descriptors for your device. -+ */ -+ -+/* get pointer to static default descriptor */ -+struct cdb *sa1100_usb_get_descriptor_ptr(void) -+{ -+ return &cdb; -+} -+ -+EXPORT_SYMBOL(sa1100_usb_get_descriptor_ptr); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,12 @@ -+# -+# Makefile for the USB client -+# -+ -+usbdevcore-objs := buffer.o control.o strings.o usb_ctl.o -+ -+sa1100-objs := sa1100usb.o usb_recv.o usb_send.o -+ -+obj-$(CONFIG_SA1100_USB) += usbdevcore.o sa1100.o -+obj-$(CONFIG_SA1100_USB_NETLINK) += usb-eth.o -+obj-$(CONFIG_SA1100_USB_CHAR) += usb-char.o -+ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usbdev.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,91 @@ -+#ifndef USBDEV_H -+#define USBDEV_H -+ -+#include "strings.h" -+ -+struct usb_buf; -+struct module; -+struct cdb; -+struct usb_client; -+ -+struct usbc_driver { -+ struct module *owner; -+ const char *name; -+ void *priv; -+ int (*start)(void *); -+ int (*stop)(void *); -+ -+ int (*ep0_queue)(void *, struct usb_buf *buf, unsigned int req_len); -+ void (*set_address)(void *, unsigned int addr); -+ void (*set_config)(void *, struct cdb *config); -+ -+ /* -+ * Get specified endpoint status, as defined in 9.4.5. -+ */ -+ unsigned int (*ep_get_status)(void *, unsigned int ep); -+ void (*ep_halt)(void *, unsigned int ep, int halt); -+ -+ /* -+ * Client -+ */ -+ int (*ep_queue)(void *, unsigned int, char *, unsigned int); -+ void (*ep_reset)(void *, unsigned int); -+ void (*ep_callback)(void *, unsigned int, void (*)(void *, int, int), void *); -+ int (*ep_idle)(void *, unsigned int); -+}; -+ -+struct usbc_endpoint { -+ struct usb_endpoint_descriptor *desc; -+}; -+ -+struct usbc_interface { -+ struct usb_interface_descriptor *desc; -+ unsigned int nr_ep; -+ struct usbc_endpoint *ep[0]; -+}; -+ -+struct usbc_config { -+ struct usb_config_descriptor *desc; -+ unsigned int nr_interface; -+ struct usbc_interface *interface[0]; -+}; -+ -+struct usbctl { -+ struct usb_client *clnt; -+ const struct usbc_driver *driver; -+ -+ /* Internal state */ -+ unsigned int address; /* host assigned address */ -+ unsigned int state; /* our device state */ -+ unsigned int sm_state; /* state machine state */ -+ -+ struct usbc_config *config; /* active configuration */ -+ struct usbc_strs strings; -+ -+ /* Descriptors */ -+ struct usb_device_descriptor *dev_desc; /* device descriptor */ -+ struct usb_buf *dev_desc_buf; /* device descriptor buffer */ -+ -+ -+ int nr_ep; -+ struct usb_endpoint_descriptor *ep_desc[2]; -+}; -+ -+/* -+ * Function Prototypes -+ */ -+ -+#define RET_ERROR (-1) -+#define RET_NOACTION (0) -+#define RET_QUEUED (1) -+#define RET_ACK (2) -+#define RET_REQERROR (3) -+ -+int usbctl_parse_request(struct usbctl *ctl, struct usb_ctrlrequest *req); -+ -+int usbctl_reset(struct usbctl *ctl); -+void usbctl_suspend(struct usbctl *ctl); -+void usbctl_resume(struct usbctl *ctl); -+ -+#endif -+ ---- linux-2.6.5/arch/arm/mach-sa1100/pm.c~heh 2004-04-03 22:36:27.000000000 -0500 -+++ linux-2.6.5/arch/arm/mach-sa1100/pm.c 2004-04-30 20:57:36.000000000 -0400 -@@ -150,6 +150,7 @@ - */ - static int sa11x0_pm_prepare(u32 state) - { -+ nmi_watchdog_disable(); - return 0; - } - -@@ -158,6 +159,7 @@ - */ - static int sa11x0_pm_finish(u32 state) - { -+ nmi_watchdog_enable(); - return 0; - } - ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/arch/arm/mach-sa1100/nmi-oopser.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,104 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+static void *nmi_stack; -+ -+asm(" \n\ -+nmi_start: \n\ -+ mrs r8, spsr \n\ -+ ldr r9, .Lstack \n\ -+ ldr sp, [r9] \n\ -+ sub sp, sp, #18 * 4 \n\ -+ str r8, [sp, #16 * 4] \n\ -+ str lr, [sp, #15 * 4] \n\ -+ stmia sp, {r0 - r7} \n\ -+ add r0, sp, #8 * 4 \n\ -+ mrs r2, cpsr \n\ -+ bic r1, r2, #0x1f \n\ -+ orr r1, r1, #0x13 \n\ -+ msr cpsr_c, r1 \n\ -+ mov r0, r0 \n\ -+ stmia r0, {r8 - lr} \n\ -+ mov r0, r0 \n\ -+ msr cpsr_c, r2 \n\ -+ mov r0, r0 \n\ -+ mov r0, sp \n\ -+ mov lr, pc \n\ -+ ldr pc, .Lfn \n\ -+ ldmia sp, {r0 - r7} \n\ -+ ldr r8, [sp, #16 * 4] \n\ -+ ldr lr, [sp, #15 * 4] \n\ -+ add sp, sp, #18 * 4 \n\ -+ msr spsr, r8 \n\ -+ movs pc, lr \n\ -+ \n\ -+.Lstack: .long nmi_stack \n\ -+.Lfn: .long nmi_fn \n\ -+nmi_end:"); -+ -+extern unsigned char nmi_start, nmi_end; -+ -+static void __attribute__((unused)) nmi_fn(struct pt_regs *regs) -+{ -+ struct thread_info *thread; -+ unsigned long osmr0, osmr1, oscr, ossr, icmr, icip; -+ -+ oscr = OSCR; -+ osmr0 = OSMR0; -+ osmr1 = OSMR1; -+ ossr = OSSR; -+ icmr = ICMR; -+ icip = ICIP; -+ -+ OSSR = OSSR_M1; -+ ICMR &= ~IC_OST1; -+ -+ thread = (struct thread_info *)(regs->ARM_sp & ~8191); -+ -+ bust_spinlocks(1); -+ printk("OSMR0:%08lx OSMR1:%08lx OSCR:%08lx OSSR:%08lx ICMR:%08lx ICIP:%08lx\n", -+ osmr0, osmr1, oscr, ossr, icmr, icip); -+ nmi_watchdog(thread, regs); -+ bust_spinlocks(0); -+ -+ OSSR = OSSR_M1; -+ OSMR1 = OSSR + 36864000; -+ ICMR |= IC_OST1; -+} -+ -+static int nmi_init(void) -+{ -+ unsigned char *vec_base = (unsigned char *)vectors_base(); -+return 0; -+ nmi_stack = (void *)__get_free_page(GFP_KERNEL); -+ if (!nmi_stack) -+ return -ENOMEM; -+ -+ nmi_stack += PAGE_SIZE; -+ -+ modify_domain(DOMAIN_USER, DOMAIN_MANAGER); -+ memcpy(vec_base + 0x1c, &nmi_start, &nmi_end - &nmi_start); -+ modify_domain(DOMAIN_USER, DOMAIN_CLIENT); -+ -+ /* -+ * Ensure timer 1 is set to FIQ, and enabled. -+ */ -+ OSMR1 = OSCR - 1; -+ OSSR = OSSR_M1; -+ OIER |= OIER_E1; -+ ICLR |= IC_OST1; -+ ICMR |= IC_OST1; -+ -+ return 0; -+} -+ -+__initcall(nmi_init); ---- linux-2.6.5/drivers/media/Kconfig~heh 2004-04-03 22:36:51.000000000 -0500 -+++ linux-2.6.5/drivers/media/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -32,6 +32,8 @@ - - source "drivers/media/common/Kconfig" - -+source "drivers/media/mmc/Kconfig" -+ - config VIDEO_TUNER - tristate - default y if VIDEO_BT848=y || VIDEO_SAA7134=y || VIDEO_MXB=y || VIDEO_CX88=y ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,52 @@ -+# -+# MMC subsystem configuration -+# -+ -+menu "MMC/SD Card support" -+ -+config MMC -+ tristate "MMC support" -+ help -+ MMC is the "multi-media card" bus protocol. -+ -+ If you want MMC support, you should say Y here and also -+ to the specific driver for your MMC interface. -+ -+config MMC_DEBUG -+ bool "MMC debugging" -+ depends on MMC != n -+ help -+ This is an option for use by developers; most people should -+ say N here. This enables MMC core and driver debugging. -+ -+config MMC_BLOCK -+ tristate "MMC block device driver" -+ depends on MMC -+ default y -+ help -+ Say Y here to enable the MMC block device driver support. -+ This provides a block device driver, which you can use to -+ mount the filesystem. Almost everyone wishing MMC support -+ should say Y or M here. -+ -+config MMC_ARMMMCI -+ tristate "ARM AMBA Multimedia Card Interface support" -+ depends on ARM_AMBA && MMC -+ help -+ This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card -+ Interface (PL180 and PL181) support. If you have an ARM(R) -+ platform with a Multimedia Card slot, say Y or M here. -+ -+ If unsure, say N. -+ -+config MMC_PXA -+ tristate "Intel PXA255 Multimedia Card Interface support" -+ depends on ARCH_PXA && MMC -+ help -+ This selects the Intel(R) PXA(R) Multimedia card Interface. -+ If you have a PXA(R) platform with a Multimedia Card slot, -+ say Y or M here. -+ -+ If unsure, say N. -+ -+endmenu ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/mmc_queue.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,171 @@ -+/* -+ * linux/drivers/media/mmc/mmc_queue.c -+ * -+ * Copyright (C) 2003 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+#include -+#include -+ -+#include -+#include -+#include "mmc_queue.h" -+ -+/* -+ * Prepare a MMC request. Essentially, this means passing the -+ * preparation off to the media driver. The media driver will -+ * create a mmc_io_request in req->special. -+ */ -+static int mmc_prep_request(struct request_queue *q, struct request *req) -+{ -+ struct mmc_queue *mq = q->queuedata; -+ int ret = BLKPREP_KILL; -+ -+ if (req->flags & REQ_SPECIAL) { -+ /* -+ * Special commands already have the command -+ * blocks already setup in req->special. -+ */ -+ BUG_ON(!req->special); -+ -+ ret = BLKPREP_OK; -+ } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { -+ /* -+ * Block I/O requests need translating according -+ * to the protocol. -+ */ -+ ret = mq->prep_fn(mq, req); -+ } else { -+ /* -+ * Everything else is invalid. -+ */ -+ blk_dump_rq_flags(req, "MMC bad request"); -+ } -+ -+ if (ret == BLKPREP_OK) -+ req->flags |= REQ_DONTPREP; -+ -+ return ret; -+} -+ -+static int mmc_queue_thread(void *d) -+{ -+ struct mmc_queue *mq = d; -+ struct request_queue *q = mq->queue; -+ DECLARE_WAITQUEUE(wait, current); -+ int ret; -+ -+ /* -+ * Set iothread to ensure that we aren't put to sleep by -+ * the process freezing. We handle suspension ourselves. -+ */ -+ current->flags |= PF_MEMALLOC|PF_IOTHREAD; -+ -+ daemonize("mmcqd"); -+ -+ spin_lock_irq(¤t->sighand->siglock); -+ sigfillset(¤t->blocked); -+ recalc_sigpending(); -+ spin_unlock_irq(¤t->sighand->siglock); -+ -+ mq->thread = current; -+ complete(&mq->thread_complete); -+ -+ add_wait_queue(&mq->thread_wq, &wait); -+ spin_lock_irq(q->queue_lock); -+ do { -+ struct request *req = NULL; -+ -+ set_current_state(TASK_INTERRUPTIBLE); -+ if (!blk_queue_plugged(q)) -+ mq->req = req = elv_next_request(q); -+ spin_unlock(q->queue_lock); -+ -+ if (!req) { -+ if (!mq->thread) -+ break; -+ schedule(); -+ continue; -+ } -+ set_current_state(TASK_RUNNING); -+ -+ ret = mq->issue_fn(mq, req); -+ -+ spin_lock_irq(q->queue_lock); -+ end_request(req, ret); -+ } while (1); -+ remove_wait_queue(&mq->thread_wq, &wait); -+ -+ complete_and_exit(&mq->thread_complete, 0); -+ return 0; -+} -+ -+/* -+ * Generic MMC request handler. This is called for any queue on a -+ * particular host. When the host is not busy, we look for a request -+ * on any queue on this host, and attempt to issue it. This may -+ * not be the queue we were asked to process. -+ */ -+static void mmc_request(request_queue_t *q) -+{ -+ struct mmc_queue *mq = q->queuedata; -+ -+ if (!mq->req && !blk_queue_plugged(q)) -+ wake_up(&mq->thread_wq); -+} -+ -+/** -+ * mmc_init_queue - initialise a queue structure. -+ * @mq: mmc queue -+ * @card: mmc card to attach this queue -+ * @lock: queue lock -+ * -+ * Initialise a MMC card request queue. -+ */ -+int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock) -+{ -+ u64 limit = BLK_BOUNCE_HIGH; -+ int ret; -+ -+ if (card->host->dev->dma_mask) -+ limit = *card->host->dev->dma_mask; -+ -+ mq->card = card; -+ mq->queue = blk_init_queue(mmc_request, lock); -+ blk_queue_prep_rq(mq->queue, mmc_prep_request); -+ blk_queue_bounce_limit(mq->queue, limit); -+ -+ mq->queue->queuedata = mq; -+ mq->req = NULL; -+ -+ init_completion(&mq->thread_complete); -+ init_waitqueue_head(&mq->thread_wq); -+ -+ ret = kernel_thread(mmc_queue_thread, mq, CLONE_KERNEL); -+ if (ret < 0) { -+ blk_cleanup_queue(mq->queue); -+ } else { -+ wait_for_completion(&mq->thread_complete); -+ init_completion(&mq->thread_complete); -+ } -+ -+ return ret; -+} -+ -+EXPORT_SYMBOL(mmc_init_queue); -+ -+void mmc_cleanup_queue(struct mmc_queue *mq) -+{ -+ mq->thread = NULL; -+ wake_up(&mq->thread_wq); -+ wait_for_completion(&mq->thread_complete); -+ blk_cleanup_queue(mq->queue); -+ -+ mq->card = NULL; -+} -+ -+EXPORT_SYMBOL(mmc_cleanup_queue); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/pxamci.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,587 @@ -+/* -+ * linux/drivers/media/mmc/pxa.c - PXA MMCI driver -+ * -+ * Copyright (C) 2003 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This hardware is really sick. No way to clear interrupts. Have -+ * to turn off the clock whenever we touch the device. Yuck! -+ * -+ * 1 and 3 byte data transfers not supported -+ * max block length up to 1023 -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "pxamci.h" -+ -+#ifdef CONFIG_MMC_DEBUG -+#define DBG(x...) printk(KERN_DEBUG x) -+#else -+#define DBG(x...) do { } while (0) -+#endif -+ -+struct pxamci_host { -+ struct mmc_host mmc; -+ spinlock_t lock; -+ struct resource *res; -+ void *base; -+ int irq; -+ int dma; -+ unsigned int clkrt; -+ unsigned int cmdat; -+ unsigned int imask; -+ unsigned int power_mode; -+ -+ struct mmc_request *req; -+ struct mmc_command *cmd; -+ struct mmc_data *data; -+ -+ dma_addr_t sg_dma; -+ struct pxa_dma_desc *sg_cpu; -+ -+ dma_addr_t dma_buf; -+ unsigned int dma_size; -+ unsigned int dma_dir; -+}; -+ -+#define to_pxamci_host(x) container_of(x, struct pxamci_host, mmc) -+ -+/* -+ * The base MMC clock rate -+ */ -+#define CLOCKRATE 20000000 -+ -+static inline unsigned int ns_to_clocks(unsigned int ns) -+{ -+ return (ns * (CLOCKRATE / 1000000) + 999) / 1000; -+} -+ -+static void pxamci_stop_clock(struct pxamci_host *host) -+{ -+ if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { -+ unsigned long flags; -+ unsigned int v; -+ -+ writel(STOP_CLOCK, host->base + MMC_STRPCL); -+ -+ /* -+ * Wait for the "clock has stopped" interrupt. -+ * We need to unmask the interrupt to receive -+ * the notification. Sigh. -+ */ -+ spin_lock_irqsave(&host->lock, flags); -+ writel(host->imask & ~CLK_IS_OFF, host->base + MMC_I_MASK); -+ do { -+ v = readl(host->base + MMC_I_REG); -+ } while (!(v & CLK_IS_OFF)); -+ writel(host->imask, host->base + MMC_I_MASK); -+ spin_unlock_irqrestore(&host->lock, flags); -+ } -+} -+ -+static void pxamci_enable_irq(struct pxamci_host *host, unsigned int mask) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ host->imask &= ~mask; -+ writel(host->imask, host->base + MMC_I_MASK); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ host->imask |= mask; -+ writel(host->imask, host->base + MMC_I_MASK); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) -+{ -+ unsigned int nob = data->blocks; -+ unsigned int timeout, size; -+ dma_addr_t dma; -+ u32 dcmd; -+ int i; -+ -+ host->data = data; -+ -+ if (data->flags & MMC_DATA_STREAM) -+ nob = 0xffff; -+ -+ writel(nob, host->base + MMC_NOB); -+ writel(1 << data->blksz_bits, host->base + MMC_BLKLEN); -+ -+ timeout = ns_to_clocks(data->timeout_ns) + data->timeout_clks; -+ writel((timeout + 255) / 256, host->base + MMC_RDTO); -+ -+ if (data->flags & MMC_DATA_READ) { -+ host->dma_dir = DMA_FROM_DEVICE; -+ dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG; -+ DRCMRTXMMC = 0; -+ DRCMRRXMMC = host->dma | DRCMR_MAPVLD; -+ } else { -+ host->dma_dir = DMA_TO_DEVICE; -+ dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC; -+ DRCMRRXMMC = 0; -+ DRCMRTXMMC = host->dma | DRCMR_MAPVLD; -+ } -+ -+ dcmd |= DCMD_BURST32 | DCMD_WIDTH1; -+ -+ host->dma_size = data->blocks << data->blksz_bits; -+ host->dma_buf = dma_map_single(host->mmc.dev, data->rq->buffer, -+ host->dma_size, host->dma_dir); -+ -+ for (i = 0, size = host->dma_size, dma = host->dma_buf; size; i++) { -+ u32 len = size; -+ -+ if (len > DCMD_LENGTH) -+ len = 0x1000; -+ -+ if (data->flags & MMC_DATA_READ) { -+ host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO; -+ host->sg_cpu[i].dtadr = dma; -+ } else { -+ host->sg_cpu[i].dsadr = dma; -+ host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO; -+ } -+ host->sg_cpu[i].dcmd = dcmd | len; -+ -+ dma += len; -+ size -= len; -+ -+ if (size) { -+ host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) * -+ sizeof(struct pxa_dma_desc); -+ } else { -+ host->sg_cpu[i].ddadr = DDADR_STOP; -+ } -+ } -+ wmb(); -+ -+ DDADR(host->dma) = host->sg_dma; -+ DCSR(host->dma) = DCSR_RUN; -+} -+ -+static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat) -+{ -+ WARN_ON(host->cmd != NULL); -+ host->cmd = cmd; -+ -+ if (cmd->flags & MMC_RSP_BUSY) -+ cmdat |= CMDAT_BUSY; -+ -+ switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) { -+ case MMC_RSP_SHORT | MMC_RSP_CRC: -+ cmdat |= CMDAT_RESP_SHORT; -+ break; -+ case MMC_RSP_SHORT: -+ cmdat |= CMDAT_RESP_R3; -+ break; -+ case MMC_RSP_LONG | MMC_RSP_CRC: -+ cmdat |= CMDAT_RESP_R2; -+ break; -+ default: -+ break; -+ } -+ -+ writel(cmd->opcode, host->base + MMC_CMD); -+ writel(cmd->arg >> 16, host->base + MMC_ARGH); -+ writel(cmd->arg & 0xffff, host->base + MMC_ARGL); -+ writel(cmdat, host->base + MMC_CMDAT); -+ writel(host->clkrt, host->base + MMC_CLKRT); -+ -+ writel(START_CLOCK, host->base + MMC_STRPCL); -+ -+ pxamci_enable_irq(host, END_CMD_RES); -+} -+ -+static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *req) -+{ -+ DBG("PXAMCI: request done\n"); -+ host->req = NULL; -+ host->cmd = NULL; -+ host->data = NULL; -+ mmc_request_done(&host->mmc, req); -+} -+ -+static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) -+{ -+ struct mmc_command *cmd = host->cmd; -+ int i; -+ u32 v; -+ -+ if (!cmd) -+ return 0; -+ -+ host->cmd = NULL; -+ -+ /* -+ * Did I mention this is Sick. We always need to -+ * discard the upper 8 bits of the first 16-bit word. -+ */ -+ v = readl(host->base + MMC_RES) & 0xffff; -+ for (i = 0; i < 4; i++) { -+ u32 w1 = readl(host->base + MMC_RES) & 0xffff; -+ u32 w2 = readl(host->base + MMC_RES) & 0xffff; -+ cmd->resp[i] = v << 24 | w1 << 8 | w2 >> 8; -+ v = w2; -+ } -+ -+ if (stat & STAT_TIME_OUT_RESPONSE) { -+ cmd->error = MMC_ERR_TIMEOUT; -+ } else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) { -+ cmd->error = MMC_ERR_BADCRC; -+ } -+ -+ pxamci_disable_irq(host, END_CMD_RES); -+ if (host->data && cmd->error == MMC_ERR_NONE) { -+ pxamci_enable_irq(host, DATA_TRAN_DONE); -+ } else { -+ pxamci_finish_request(host, host->req); -+ } -+ -+ return 1; -+} -+ -+static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) -+{ -+ struct mmc_data *data = host->data; -+ -+ if (!data) -+ return 0; -+ -+ DCSR(host->dma) = 0; -+ dma_unmap_single(host->mmc.dev, host->dma_buf, host->dma_size, -+ host->dma_dir); -+ -+ if (stat & STAT_READ_TIME_OUT) -+ data->error = MMC_ERR_TIMEOUT; -+ else if (stat & (STAT_CRC_READ_ERROR|STAT_CRC_WRITE_ERROR)) -+ data->error = MMC_ERR_BADCRC; -+ -+ data->bytes_xfered = (data->blocks - readl(host->base + MMC_NOB)) -+ << data->blksz_bits; -+ -+ pxamci_disable_irq(host, DATA_TRAN_DONE); -+ -+ host->data = NULL; -+ if (host->req->stop && data->error == MMC_ERR_NONE) { -+ pxamci_stop_clock(host); -+ pxamci_start_cmd(host, host->req->stop, 0); -+ } else { -+ pxamci_finish_request(host, host->req); -+ } -+ -+ return 1; -+} -+ -+static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs) -+{ -+ struct pxamci_host *host = devid; -+ unsigned int ireg; -+ int handled = 0; -+ -+ ireg = readl(host->base + MMC_I_REG); -+ -+ DBG("PXAMCI: irq %08x\n", ireg); -+ -+ if (ireg) { -+ unsigned stat = readl(host->base + MMC_STAT); -+ -+ DBG("PXAMCI: stat %08x\n", stat); -+ -+ if (ireg & END_CMD_RES) -+ handled |= pxamci_cmd_done(host, stat); -+ if (ireg & DATA_TRAN_DONE) -+ handled |= pxamci_data_done(host, stat); -+ } -+ -+ return IRQ_RETVAL(handled); -+} -+ -+static void pxamci_request(struct mmc_host *mmc, struct mmc_request *req) -+{ -+ struct pxamci_host *host = to_pxamci_host(mmc); -+ unsigned int cmdat; -+ -+ WARN_ON(host->req != NULL); -+ -+ host->req = req; -+ -+ pxamci_stop_clock(host); -+ -+ cmdat = host->cmdat; -+ host->cmdat &= ~CMDAT_INIT; -+ -+ if (req->data) { -+ pxamci_setup_data(host, req->data); -+ -+ cmdat &= ~CMDAT_BUSY; -+ cmdat |= CMDAT_DATAEN | CMDAT_DMAEN; -+ if (req->data->flags & MMC_DATA_WRITE) -+ cmdat |= CMDAT_WRITE; -+ -+ if (req->data->flags & MMC_DATA_STREAM) -+ cmdat |= CMDAT_STREAM; -+ } -+ -+ pxamci_start_cmd(host, req->cmd, cmdat); -+} -+ -+static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ struct pxamci_host *host = to_pxamci_host(mmc); -+ -+ DBG("pxamci_set_ios: clock %u power %u vdd %u.%02u\n", -+ ios->clock, ios->power_mode, ios->vdd / 100, -+ ios->vdd % 100); -+ -+ if (ios->clock) { -+ unsigned int clk = CLOCKRATE / ios->clock; -+ if (CLOCKRATE / clk > ios->clock) -+ clk <<= 1; -+ host->clkrt = fls(clk) - 1; -+ -+ /* -+ * we write clkrt on the next command -+ */ -+ } else if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { -+ /* -+ * Ensure that the clock is off. -+ */ -+ writel(STOP_CLOCK, host->base + MMC_STRPCL); -+ } -+ -+ if (host->power_mode != ios->power_mode) { -+ host->power_mode = ios->power_mode; -+ -+ /* -+ * power control? none on the lubbock. -+ */ -+ -+ if (ios->power_mode == MMC_POWER_ON) -+ host->cmdat |= CMDAT_INIT; -+ } -+ -+ DBG("pxamci_set_ios: clkrt = %x cmdat = %x\n", -+ host->clkrt, host->cmdat); -+} -+ -+static struct mmc_host_ops pxamci_ops = { -+ .request = pxamci_request, -+ .set_ios = pxamci_set_ios, -+}; -+ -+static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr) -+{ -+ int i; -+ -+ for (i = 0; i < dev->num_resources; i++) -+ if (dev->resource[i].flags == mask && nr-- == 0) -+ return &dev->resource[i]; -+ return NULL; -+} -+ -+static int platform_device_irq(struct platform_device *dev, int nr) -+{ -+ int i; -+ -+ for (i = 0; i < dev->num_resources; i++) -+ if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0) -+ return dev->resource[i].start; -+ return NO_IRQ; -+} -+ -+static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs) -+{ -+ printk(KERN_ERR "DMA%d: IRQ???\n", dma); -+ DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; -+} -+ -+static int pxamci_probe(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct pxamci_host *host; -+ struct resource *r; -+ int ret, irq; -+ -+ r = platform_device_resource(pdev, IORESOURCE_MEM, 0); -+ irq = platform_device_irq(pdev, 0); -+ if (!r || irq == NO_IRQ) -+ return -ENXIO; -+ -+ r = request_mem_region(r->start, SZ_4K, "PXAMCI"); -+ if (!r) -+ return -EBUSY; -+ -+ host = kmalloc(sizeof(struct pxamci_host), GFP_KERNEL); -+ if (!host) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ memset(host, 0, sizeof(struct pxamci_host)); -+ host->dma = -1; -+ -+ host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); -+ if (!host->sg_cpu) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ret = mmc_init_host(&host->mmc); -+ if (ret) -+ goto out; -+ -+ spin_lock_init(&host->lock); -+ host->res = r; -+ host->irq = irq; -+ host->imask = TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD| -+ END_CMD_RES|PRG_DONE|DATA_TRAN_DONE; -+ host->mmc.dev = dev; -+ host->mmc.ops = &pxamci_ops; -+ host->mmc.f_min = 312500; -+ host->mmc.f_max = 20000000; -+ host->mmc.ocr_avail = MMC_VDD_32_33; -+ -+ host->base = ioremap(r->start, SZ_4K); -+ if (!host->base) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ /* -+ * Ensure that the host controller is shut down, and setup -+ * with our defaults. -+ */ -+ pxamci_stop_clock(host); -+ writel(0, host->base + MMC_SPI); -+ writel(64, host->base + MMC_RESTO); -+ -+#ifdef CONFIG_PREEMPT -+#error Not Preempt-safe -+#endif -+ pxa_gpio_mode(GPIO6_MMCCLK_MD); -+ pxa_gpio_mode(GPIO8_MMCCS0_MD); -+ CKEN |= CKEN12_MMC; -+ -+ host->dma = pxa_request_dma("PXAMCI", DMA_PRIO_LOW, pxamci_dma_irq, host); -+ if (host->dma < 0) -+ goto out; -+ -+ ret = request_irq(host->irq, pxamci_irq, 0, "PXAMCI", host); -+ if (ret) -+ goto out; -+ -+ dev_set_drvdata(dev, host); -+ -+ mmc_add_host(&host->mmc); -+ -+ return 0; -+ -+ out: -+ if (host) { -+ if (host->dma >= 0) -+ pxa_free_dma(host->dma); -+ if (host->base) -+ iounmap(host->base); -+ if (host->sg_cpu) -+ dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); -+ kfree(host); -+ } -+ release_resource(r); -+ return ret; -+} -+ -+static int pxamci_remove(struct device *dev) -+{ -+ struct pxamci_host *host = dev_get_drvdata(dev); -+ -+ dev_set_drvdata(dev, NULL); -+ -+ if (host) { -+ mmc_remove_host(&host->mmc); -+ -+ pxamci_stop_clock(host); -+ writel(TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD| -+ END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, -+ host->base + MMC_I_MASK); -+ -+ free_irq(host->irq, host); -+ pxa_free_dma(host->dma); -+ iounmap(host->base); -+ dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); -+ -+ release_resource(host->res); -+ -+ kfree(host); -+ } -+ return 0; -+} -+ -+static int pxamci_suspend(struct device *dev, u32 state, u32 level) -+{ -+ struct pxamci_host *host = dev_get_drvdata(dev); -+ int ret = 0; -+ -+ if (host && level == SUSPEND_DISABLE) -+ ret = mmc_suspend_host(&host->mmc, state); -+ return ret; -+} -+ -+static int pxamci_resume(struct device *dev, u32 level) -+{ -+ struct pxamci_host *host = dev_get_drvdata(dev); -+ int ret = 0; -+ -+ if (host && level == RESUME_ENABLE) -+ ret = mmc_resume_host(&host->mmc); -+ return ret; -+} -+ -+static struct device_driver pxamci_driver = { -+ .name = "pxamci", -+ .bus = &platform_bus_type, -+ .probe = pxamci_probe, -+ .remove = pxamci_remove, -+ .suspend = pxamci_suspend, -+ .resume = pxamci_resume, -+}; -+ -+static int __init pxamci_init(void) -+{ -+ return driver_register(&pxamci_driver); -+} -+ -+static void __exit pxamci_exit(void) -+{ -+ driver_unregister(&pxamci_driver); -+} -+ -+module_init(pxamci_init); -+module_exit(pxamci_exit); -+ -+MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/mmc.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,15 @@ -+/* -+ * linux/drivers/media/mmc/mmc.h -+ * -+ * Copyright (C) 2003 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef _MMC_H -+/* core-internal functions */ -+void mmc_init_card(struct mmc_card *card, struct mmc_host *host); -+int mmc_register_card(struct mmc_card *card); -+void mmc_remove_card(struct mmc_card *card); -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/mmc_sysfs.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,231 @@ -+/* -+ * linux/drivers/media/mmc/mmc_sysfs.c -+ * -+ * Copyright (C) 2003 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * MMC sysfs/driver model support. -+ */ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "mmc.h" -+ -+#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) -+#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) -+ -+static void mmc_release_card(struct device *dev) -+{ -+ struct mmc_card *card = dev_to_mmc_card(dev); -+ -+ kfree(card); -+} -+ -+/* -+ * This currently matches any MMC driver to any MMC card - drivers -+ * themselves make the decision whether to drive this card in their -+ * probe method. -+ */ -+static int mmc_bus_match(struct device *dev, struct device_driver *drv) -+{ -+ return 1; -+} -+ -+static int -+mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf, -+ int buf_size) -+{ -+ struct mmc_card *card = dev_to_mmc_card(dev); -+ char ccc[13]; -+ int i = 0; -+ -+#define add_env(fmt,val) \ -+ ({ \ -+ int len, ret = -ENOMEM; \ -+ if (i < num_envp) { \ -+ envp[i++] = buf; \ -+ len = snprintf(buf, buf_size, fmt, val) + 1; \ -+ buf_size -= len; \ -+ buf += len; \ -+ if (buf_size >= 0) \ -+ ret = 0; \ -+ } \ -+ ret; \ -+ }) -+ -+ for (i = 0; i < 12; i++) -+ ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0'; -+ ccc[12] = '\0'; -+ -+ i = 0; -+ add_env("MMC_CCC=%s", ccc); -+ add_env("MMC_MANFID=%03x", card->cid.manfid); -+ add_env("MMC_SLOT_NAME=%s", card->dev.bus_id); -+ -+ return 0; -+} -+ -+static int mmc_bus_suspend(struct device *dev, u32 state) -+{ -+ struct mmc_driver *drv = to_mmc_driver(dev->driver); -+ struct mmc_card *card = dev_to_mmc_card(dev); -+ int ret = 0; -+ -+ if (dev->driver && drv->suspend) -+ ret = drv->suspend(card, state); -+ return ret; -+} -+ -+static int mmc_bus_resume(struct device *dev) -+{ -+ struct mmc_driver *drv = to_mmc_driver(dev->driver); -+ struct mmc_card *card = dev_to_mmc_card(dev); -+ int ret = 0; -+ -+ if (dev->driver && drv->resume) -+ ret = drv->resume(card); -+ return ret; -+} -+ -+static struct bus_type mmc_bus_type = { -+ .name = "mmc", -+ .match = mmc_bus_match, -+ .hotplug = mmc_bus_hotplug, -+ .suspend = mmc_bus_suspend, -+ .resume = mmc_bus_resume, -+}; -+ -+ -+static int mmc_drv_probe(struct device *dev) -+{ -+ struct mmc_driver *drv = to_mmc_driver(dev->driver); -+ struct mmc_card *card = dev_to_mmc_card(dev); -+ -+ return drv->probe(card); -+} -+ -+static int mmc_drv_remove(struct device *dev) -+{ -+ struct mmc_driver *drv = to_mmc_driver(dev->driver); -+ struct mmc_card *card = dev_to_mmc_card(dev); -+ -+ drv->remove(card); -+ -+ return 0; -+} -+ -+ -+/** -+ * mmc_register_driver - register a media driver -+ * @drv: MMC media driver -+ */ -+int mmc_register_driver(struct mmc_driver *drv) -+{ -+ drv->drv.bus = &mmc_bus_type; -+ drv->drv.probe = mmc_drv_probe; -+ drv->drv.remove = mmc_drv_remove; -+ return driver_register(&drv->drv); -+} -+ -+EXPORT_SYMBOL(mmc_register_driver); -+ -+/** -+ * mmc_unregister_driver - unregister a media driver -+ * @drv: MMC media driver -+ */ -+void mmc_unregister_driver(struct mmc_driver *drv) -+{ -+ drv->drv.bus = &mmc_bus_type; -+ driver_unregister(&drv->drv); -+} -+ -+EXPORT_SYMBOL(mmc_unregister_driver); -+ -+ -+#define MMC_ATTR(name, fmt, args...) \ -+static ssize_t mmc_dev_show_##name (struct device *dev, char *buf) \ -+{ \ -+ struct mmc_card *card = dev_to_mmc_card(dev); \ -+ return sprintf(buf, fmt, args); \ -+} \ -+static DEVICE_ATTR(name, S_IRUGO, mmc_dev_show_##name, NULL) -+ -+MMC_ATTR(date, "%02d/%04d\n", card->cid.month, 1997 + card->cid.year); -+MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev); -+MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev); -+MMC_ATTR(manfid, "0x%03x\n", card->cid.manfid); -+MMC_ATTR(serial, "0x%06x\n", card->cid.serial); -+MMC_ATTR(name, "%s\n", card->cid.prod_name); -+ -+static struct device_attribute *mmc_dev_attributes[] = { -+ &dev_attr_date, -+ &dev_attr_fwrev, -+ &dev_attr_hwrev, -+ &dev_attr_manfid, -+ &dev_attr_serial, -+ &dev_attr_name, -+}; -+ -+/* -+ * Internal function. Initialise a MMC card structure. -+ */ -+void mmc_init_card(struct mmc_card *card, struct mmc_host *host) -+{ -+ memset(card, 0, sizeof(struct mmc_card)); -+ card->host = host; -+ device_initialize(&card->dev); -+ card->dev.parent = card->host->dev; -+ card->dev.bus = &mmc_bus_type; -+ card->dev.release = mmc_release_card; -+} -+ -+/* -+ * Internal function. Register a new MMC card with the driver model. -+ */ -+int mmc_register_card(struct mmc_card *card) -+{ -+ int ret, i; -+ -+ snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), -+ "mmc%02x:%04x", card->host->host_num, card->rca); -+ -+ ret = device_add(&card->dev); -+ if (ret == 0) -+ for (i = 0; i < ARRAY_SIZE(mmc_dev_attributes); i++) -+ device_create_file(&card->dev, mmc_dev_attributes[i]); -+ -+ return ret; -+} -+ -+/* -+ * Internal function. Unregister a new MMC card with the -+ * driver model, and (eventually) free it. -+ */ -+void mmc_remove_card(struct mmc_card *card) -+{ -+ if (mmc_card_present(card)) -+ device_del(&card->dev); -+ -+ put_device(&card->dev); -+} -+ -+ -+static int __init mmc_init(void) -+{ -+ return bus_register(&mmc_bus_type); -+} -+ -+static void __exit mmc_exit(void) -+{ -+ bus_unregister(&mmc_bus_type); -+} -+ -+module_init(mmc_init); -+module_exit(mmc_exit); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/mmci.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,445 @@ -+/* -+ * linux/drivers/media/mmc/mmci.c - ARM PrimeCell MMCI PL180/1 driver -+ * -+ * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "mmci.h" -+ -+#define DRIVER_NAME "mmci-pl18x" -+ -+#ifdef CONFIG_MMC_DEBUG -+#define DBG(x...) printk(KERN_DEBUG x) -+#else -+#define DBG(x...) do { } while (0) -+#endif -+ -+static int fmax = 515633; -+ -+static void -+mmci_request_end(struct mmci_host *host, struct mmc_request *req) -+{ -+ writel(0, host->base + MMCICOMMAND); -+ host->req = NULL; -+ host->cmd = NULL; -+ host->data = NULL; -+ -+ if (req->data) -+ req->data->bytes_xfered = host->data_xfered; -+ -+ mmc_request_done(&host->mmc, req); -+} -+ -+static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) -+{ -+ unsigned int datactrl; -+ -+ DBG("MMCI: data: blksz %04x blks %04x flags %08x\n", -+ 1 << data->blksz_bits, data->blocks, data->flags); -+ -+ datactrl = MCI_DPSM_ENABLE | data->blksz_bits << 4; -+ -+ if (data->flags & MMC_DATA_READ) -+ datactrl |= MCI_DPSM_DIRECTION; -+ -+ host->data = data; -+ host->buffer = data->rq->buffer; -+ host->size = data->blocks << data->blksz_bits; -+ host->data_xfered = 0; -+ -+ writel(0x800000, host->base + MMCIDATATIMER); -+ writel(host->size, host->base + MMCIDATALENGTH); -+ writel(datactrl, host->base + MMCIDATACTRL); -+} -+ -+static void -+mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) -+{ -+ DBG("MMCI: cmd: op %02x arg %08x flags %08x\n", -+ cmd->opcode, cmd->arg, cmd->flags); -+ -+ if (readl(host->base + MMCICOMMAND) & MCI_CPSM_ENABLE) { -+ writel(0, host->base + MMCICOMMAND); -+ udelay(1); -+ } -+ -+ c |= cmd->opcode | MCI_CPSM_ENABLE; -+ switch (cmd->flags & MMC_RSP_MASK) { -+ case MMC_RSP_NONE: -+ default: -+ break; -+ case MMC_RSP_LONG: -+ c |= MCI_CPSM_LONGRSP; -+ case MMC_RSP_SHORT: -+ c |= MCI_CPSM_RESPONSE; -+ break; -+ } -+ if (/*interrupt*/0) -+ c |= MCI_CPSM_INTERRUPT; -+ -+ host->cmd = cmd; -+ -+ writel(cmd->arg, host->base + MMCIARGUMENT); -+ writel(c, host->base + MMCICOMMAND); -+} -+ -+static void -+mmci_data_irq(struct mmci_host *host, struct mmc_data *data, -+ unsigned int status) -+{ -+ if (status & MCI_DATABLOCKEND) { -+ host->data_xfered += 1 << data->blksz_bits; -+ } -+ if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { -+ if (status & MCI_DATACRCFAIL) -+ data->error = MMC_ERR_BADCRC; -+ else if (status & MCI_DATATIMEOUT) -+ data->error = MMC_ERR_TIMEOUT; -+ else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) -+ data->error = MMC_ERR_FIFO; -+ status |= MCI_DATAEND; -+ } -+ if (status & MCI_DATAEND) { -+ host->data = NULL; -+ if (!data->stop) { -+ mmci_request_end(host, data->req); -+ } else /*if (readl(host->base + MMCIDATACNT) > 6)*/ { -+ mmci_start_command(host, data->stop, 0); -+ } -+ } -+} -+ -+static void -+mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, -+ unsigned int status) -+{ -+ host->cmd = NULL; -+ -+ cmd->resp[0] = readl(host->base + MMCIRESPONSE0); -+ cmd->resp[1] = readl(host->base + MMCIRESPONSE1); -+ cmd->resp[2] = readl(host->base + MMCIRESPONSE2); -+ cmd->resp[3] = readl(host->base + MMCIRESPONSE3); -+ -+ if (status & MCI_CMDTIMEOUT) { -+ cmd->error = MMC_ERR_TIMEOUT; -+ } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { -+ cmd->error = MMC_ERR_BADCRC; -+ } -+ -+ if (!cmd->data || cmd->error != MMC_ERR_NONE) { -+ mmci_request_end(host, cmd->req); -+ } else if (!(cmd->data->flags & MMC_DATA_READ)) { -+ mmci_start_data(host, cmd->data); -+ } -+} -+ -+static irqreturn_t mmci_irq(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ struct mmci_host *host = dev_id; -+ u32 status; -+ int ret = 0; -+ -+ do { -+ struct mmc_command *cmd; -+ struct mmc_data *data; -+ -+ status = readl(host->base + MMCISTATUS); -+ writel(status, host->base + MMCICLEAR); -+ -+ if (!(status & MCI_IRQMASK)) -+ break; -+ -+ DBG("MMCI: irq %08x\n", status); -+ -+ if (status & (MCI_RXDATAAVLBL|MCI_RXFIFOHALFFULL)) { -+ int count = host->size - (readl(host->base + MMCIFIFOCNT) << 2); -+ if (count < 0) -+ count = 0; -+ if (count && host->buffer) { -+ readsl(host->base + MMCIFIFO, host->buffer, count >> 2); -+ host->buffer += count; -+ host->size -= count; -+ if (host->size == 0) -+ host->buffer = NULL; -+ } else { -+ static int first = 1; -+ if (first) { -+ first = 0; -+ printk(KERN_ERR "MMCI: sinking excessive data\n"); -+ } -+ readl(host->base + MMCIFIFO); -+ } -+ } -+ if (status & (MCI_TXFIFOEMPTY|MCI_TXFIFOHALFEMPTY)) { -+ int count = host->size; -+ if (count > MCI_FIFOHALFSIZE) -+ count = MCI_FIFOHALFSIZE; -+ if (count && host->buffer) { -+ writesl(host->base + MMCIFIFO, host->buffer, count >> 2); -+ host->buffer += count; -+ host->size -= count; -+ if (host->size == 0) -+ host->buffer = NULL; -+ } else { -+ static int first = 1; -+ if (first) { -+ first = 0; -+ printk(KERN_ERR "MMCI: ran out of source data\n"); -+ } -+ } -+ } -+ -+ data = host->data; -+ if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| -+ MCI_RXOVERRUN|MCI_DATAEND|MCI_DATABLOCKEND)) -+ mmci_data_irq(host, data, status); -+ -+ cmd = host->cmd; -+ if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND) && cmd) -+ mmci_cmd_irq(host, cmd, status); -+ -+ ret = 1; -+ } while (status); -+ -+ return IRQ_RETVAL(ret); -+} -+ -+static void mmci_request(struct mmc_host *mmc, struct mmc_request *req) -+{ -+ struct mmci_host *host = to_mmci_host(mmc); -+ -+ WARN_ON(host->req != NULL); -+ -+ host->req = req; -+ -+ if (req->data && req->data->flags & MMC_DATA_READ) -+ mmci_start_data(host, req->data); -+ -+ mmci_start_command(host, req->cmd, 0); -+} -+ -+static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ struct mmci_host *host = to_mmci_host(mmc); -+ u32 clk = 0, pwr = 0; -+ -+ DBG("MMCI: set_ios: clock %dHz busmode %d powermode %d Vdd %d.%02d\n", -+ ios->clock, ios->bus_mode, ios->power_mode, -+ ios->vdd / 100, ios->vdd % 100); -+ -+ if (ios->clock) { -+ clk = host->mclk / (2 * ios->clock) - 1; -+ if (clk > 256) -+ clk = 255; -+ clk |= MCI_CLK_ENABLE; -+ } -+ -+ switch (ios->power_mode) { -+ case MMC_POWER_OFF: -+ break; -+ case MMC_POWER_UP: -+ pwr |= MCI_PWR_UP; -+ break; -+ case MMC_POWER_ON: -+ pwr |= MCI_PWR_ON; -+ break; -+ } -+ -+ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) -+ pwr |= MCI_ROD; -+ -+ writel(clk, host->base + MMCICLOCK); -+ -+ if (host->pwr != pwr) { -+ host->pwr = pwr; -+ writel(pwr, host->base + MMCIPOWER); -+ } -+} -+ -+static struct mmc_host_ops mmci_ops = { -+ .request = mmci_request, -+ .set_ios = mmci_set_ios, -+}; -+ -+static int mmci_probe(struct amba_device *dev, void *id) -+{ -+ struct mmci_host *host; -+ int ret; -+// void *tmp; -+ -+ /* enable the interrupt via the VIC */ -+// tmp = ioremap(0xc3000000, SZ_4K); -+// if (tmp) { -+// u32 val = readl(tmp + 0x10); -+// writel(val | 0x180, tmp + 0x10); -+// iounmap(tmp); -+// } -+ -+ if (!request_mem_region(dev->res.start, SZ_4K, DRIVER_NAME)) -+ return -EBUSY; -+ -+ host = kmalloc(sizeof(struct mmci_host), GFP_KERNEL); -+ if (!host) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ memset(host, 0, sizeof(struct mmci_host)); -+ -+ ret = mmc_init_host(&host->mmc); -+ if (ret) -+ goto out; -+ -+ host->base = ioremap(dev->res.start, SZ_4K); -+ if (!host->base) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ host->irq = dev->irq; -+ host->mclk = 33000000; /* impd1 */ -+ host->mmc.dev = &dev->dev; -+ host->mmc.ops = &mmci_ops; -+ host->mmc.f_min = (host->mclk + 511) / 512; -+ host->mmc.f_max = host->mclk / 2; -+ if (host->mmc.f_max > fmax) -+ host->mmc.f_max = fmax; -+ -+ host->mmc.ocr_avail = MMC_VDD_35_36; -+ -+ writel(0, host->base + MMCIMASK0); -+ writel(0, host->base + MMCIMASK1); -+ writel(0xfff, host->base + MMCICLEAR); -+ -+ ret = request_irq(host->irq, mmci_irq, SA_SHIRQ, DRIVER_NAME, host); -+ if (ret) -+ goto out; -+ -+ writel(MCI_IRQENABLE, host->base + MMCIMASK0); -+ -+ amba_set_drvdata(dev, host); -+ -+ mmc_add_host(&host->mmc); -+ -+ return 0; -+ -+ out: -+ if (host) { -+ if (host->base) -+ iounmap(host->base); -+ kfree(host); -+ } -+ release_mem_region(dev->res.start, SZ_4K); -+ return ret; -+} -+ -+static int mmci_remove(struct amba_device *dev) -+{ -+ struct mmci_host *host = amba_get_drvdata(dev); -+ -+ amba_set_drvdata(dev, NULL); -+ -+ if (host) { -+ mmc_remove_host(&host->mmc); -+ -+ writel(0, host->base + MMCIMASK0); -+ writel(0, host->base + MMCIMASK1); -+ -+ writel(0, host->base + MMCICOMMAND); -+ writel(0, host->base + MMCIDATACTRL); -+ -+ free_irq(host->irq, host); -+ -+ iounmap(host->base); -+ -+ kfree(host); -+ -+ release_mem_region(dev->res.start, SZ_4K); -+ } -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int mmci_suspend(struct amba_device *dev, u32 state) -+{ -+ struct mmci_host *host = amba_get_drvdata(dev); -+ -+ return host ? mmc_suspend_host(&host->mmc, state) : 0; -+} -+ -+static int mmci_resume(struct amba_device *dev) -+{ -+ struct mmci_host *host = amba_get_drvdata(dev); -+ int ret = 0; -+ -+ if (host) { -+ writel(MCI_IRQENABLE, host->base + MMCIMASK0); -+ ret = mmc_resume_host(&host->mmc); -+ } -+ -+ return ret; -+} -+#else -+#define mmci_suspend NULL -+#define mmci_resume NULL -+#endif -+ -+static struct amba_id mmci_ids[] = { -+ { -+ .id = 0x00041180, -+ .mask = 0x000fffff, -+ }, -+ { -+ .id = 0x00041181, -+ .mask = 0x000fffff, -+ }, -+ { 0, 0 }, -+}; -+ -+static struct amba_driver mmci_driver = { -+ .drv = { -+ .name = DRIVER_NAME, -+ }, -+ .probe = mmci_probe, -+ .remove = mmci_remove, -+ .suspend = mmci_suspend, -+ .resume = mmci_resume, -+ .id_table = mmci_ids, -+}; -+ -+static int __init mmci_init(void) -+{ -+ return amba_driver_register(&mmci_driver); -+} -+ -+static void __exit mmci_exit(void) -+{ -+ amba_driver_unregister(&mmci_driver); -+} -+ -+module_init(mmci_init); -+module_exit(mmci_exit); -+module_param(fmax, int, 0444); -+ -+MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/mmc_queue.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,29 @@ -+#ifndef MMC_QUEUE_H -+#define MMC_QUEUE_H -+ -+struct request; -+struct task_struct; -+ -+struct mmc_queue { -+ struct mmc_card *card; -+ struct completion thread_complete; -+ wait_queue_head_t thread_wq; -+ struct task_struct *thread; -+ struct request *req; -+ int (*prep_fn)(struct mmc_queue *, struct request *); -+ int (*issue_fn)(struct mmc_queue *, struct request *); -+ void *data; -+ struct request_queue *queue; -+}; -+ -+struct mmc_io_request { -+ struct request *rq; -+ int num; -+ struct mmc_command selcmd; /* mmc_queue private */ -+ struct mmc_command cmd[4]; /* max 4 commands */ -+}; -+ -+extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *); -+extern void mmc_cleanup_queue(struct mmc_queue *); -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/mmc_block.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,482 @@ -+/* -+ * Block driver for media (i.e., flash cards) -+ * -+ * Copyright 2002 Hewlett-Packard Company -+ * -+ * Use consistent with the GNU GPL is permitted, -+ * provided that this copyright notice is -+ * preserved in its entirety in all copies and derived works. -+ * -+ * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, -+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS -+ * FITNESS FOR ANY PARTICULAR PURPOSE. -+ * -+ * Many thanks to Alessandro Rubini and Jonathan Corbet! -+ * -+ * Author: Andrew Christian -+ * 28 May 2002 -+ */ -+#include -+#include -+#include -+ -+#include -+#include /* printk() */ -+#include /* everything... */ -+#include /* error codes */ -+#include /* HDIO_GETGEO */ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "mmc_queue.h" -+ -+#define MMC_SHIFT 3 /* max 8 partitions per card */ -+ -+static int mmc_major; -+static int maxsectors = 8; -+ -+/* -+ * There is one mmc_blk_data per slot. -+ */ -+struct mmc_blk_data { -+ spinlock_t lock; -+ struct gendisk *disk; -+ struct mmc_queue queue; -+ -+ unsigned int usage; -+ unsigned int block_bits; -+ unsigned int suspended; -+}; -+ -+static DECLARE_MUTEX(open_lock); -+ -+static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) -+{ -+ struct mmc_blk_data *md; -+ -+ down(&open_lock); -+ md = disk->private_data; -+ if (md && md->usage == 0) -+ md = NULL; -+ if (md) -+ md->usage++; -+ up(&open_lock); -+ -+ return md; -+} -+ -+static void mmc_blk_put(struct mmc_blk_data *md) -+{ -+ down(&open_lock); -+ md->usage--; -+ if (md->usage == 0) { -+ put_disk(md->disk); -+ mmc_cleanup_queue(&md->queue); -+ kfree(md); -+ } -+ up(&open_lock); -+} -+ -+static int mmc_blk_open(struct inode *inode, struct file *filp) -+{ -+ struct mmc_blk_data *md; -+ int ret = -ENXIO; -+ -+ md = mmc_blk_get(inode->i_bdev->bd_disk); -+ if (md) { -+ if (md->usage == 2) -+ check_disk_change(inode->i_bdev); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+static int mmc_blk_release(struct inode *inode, struct file *filp) -+{ -+ struct mmc_blk_data *md = inode->i_bdev->bd_disk->private_data; -+ -+ mmc_blk_put(md); -+ return 0; -+} -+ -+static int -+mmc_blk_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ struct block_device *bdev = inode->i_bdev; -+ -+ if (cmd == HDIO_GETGEO) { -+ struct hd_geometry geo; -+ -+ memset(&geo, 0, sizeof(struct hd_geometry)); -+ -+ geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16); -+ geo.heads = 4; -+ geo.sectors = 16; -+ geo.start = get_start_sect(bdev); -+ -+ return copy_to_user((void *)arg, &geo, sizeof(geo)) -+ ? -EFAULT : 0; -+ } -+ -+ return -ENOTTY; -+} -+ -+static struct block_device_operations mmc_bdops = { -+ .open = mmc_blk_open, -+ .release = mmc_blk_release, -+ .ioctl = mmc_blk_ioctl, -+ .owner = THIS_MODULE, -+}; -+ -+struct mmc_blk_request { -+ struct mmc_request req; -+ struct mmc_command cmd; -+ struct mmc_command stop; -+ struct mmc_data data; -+}; -+ -+static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req) -+{ -+ struct mmc_blk_data *md = mq->data; -+ -+ /* -+ * If we have no device, we haven't finished initialising. -+ */ -+ if (!md || !mq->card) { -+ printk("killing request - no device/host\n"); -+ goto kill; -+ } -+ -+ if (md->suspended) { -+ blk_plug_device(md->queue.queue); -+ goto defer; -+ } -+ -+ /* -+ * Check for excessive requests. -+ */ -+ if (req->sector + req->nr_sectors > get_capacity(req->rq_disk)) { -+ printk("bad request size\n"); -+ goto kill; -+ } -+ -+ return BLKPREP_OK; -+ -+ defer: -+ return BLKPREP_DEFER; -+ kill: -+ return BLKPREP_KILL; -+} -+ -+static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) -+{ -+ struct mmc_blk_data *md = mq->data; -+ struct mmc_card *card = md->queue.card; -+ int err, sz = 0; -+ -+ err = mmc_card_claim_host(card); -+ if (err) -+ goto cmd_err; -+ -+ do { -+ struct mmc_blk_request rq; -+ struct mmc_command cmd; -+ -+ memset(&rq, 0, sizeof(struct mmc_blk_request)); -+ rq.req.cmd = &rq.cmd; -+ rq.req.data = &rq.data; -+ -+ rq.cmd.arg = req->sector << 9; -+ rq.cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC; -+ rq.data.rq = req; -+ rq.data.timeout_ns = card->csd.tacc_ns * 10; -+ rq.data.timeout_clks = card->csd.tacc_clks * 10; -+ rq.data.blksz_bits = md->block_bits; -+ rq.data.blocks = req->current_nr_sectors >> (md->block_bits - 9); -+ rq.stop.opcode = MMC_STOP_TRANSMISSION; -+ rq.stop.arg = 0; -+ rq.stop.flags = MMC_RSP_SHORT | MMC_RSP_CRC | MMC_RSP_BUSY; -+ -+ if (rq_data_dir(req) == READ) { -+ rq.cmd.opcode = rq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; -+ rq.data.flags |= MMC_DATA_READ; -+ } else { -+ rq.cmd.opcode = MMC_WRITE_BLOCK; -+ rq.cmd.flags |= MMC_RSP_BUSY; -+ rq.data.flags |= MMC_DATA_WRITE; -+ rq.data.blocks = 1; -+ } -+ rq.req.stop = rq.data.blocks > 1 ? &rq.stop : NULL; -+ -+ mmc_wait_for_req(card->host, &rq.req); -+ if (rq.cmd.error) { -+ err = rq.cmd.error; -+ printk("error %d sending read/write command\n", err); -+ goto cmd_err; -+ } -+ -+ if (rq_data_dir(req) == READ) { -+ sz = rq.data.bytes_xfered; -+ } else { -+ sz = 0; -+ } -+ -+ if (rq.data.error) { -+ err = rq.data.error; -+ printk("error %d transferring data\n", err); -+ goto cmd_err; -+ } -+ -+ if (rq.stop.error) { -+ err = rq.stop.error; -+ printk("error %d sending stop command\n", err); -+ goto cmd_err; -+ } -+ -+ do { -+ cmd.opcode = MMC_SEND_STATUS; -+ cmd.arg = card->rca << 16; -+ cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC; -+ err = mmc_wait_for_cmd(card->host, &cmd, 5); -+ if (err) { -+ printk("error %d requesting status\n", err); -+ goto cmd_err; -+ } -+ } while (!(cmd.resp[0] & R1_READY_FOR_DATA)); -+ -+#if 0 -+ if (cmd.resp[0] & ~0x00000900) -+ printk("status = %08x\n", cmd.resp[0]); -+ err = mmc_decode_status(cmd.resp); -+ if (err) -+ goto cmd_err; -+#endif -+ -+ sz = rq.data.bytes_xfered; -+ } while (end_that_request_chunk(req, 1, sz)); -+ -+ mmc_card_release_host(card); -+ -+ return 1; -+ -+ cmd_err: -+ mmc_card_release_host(card); -+ -+ end_that_request_chunk(req, 1, sz); -+ req->errors = err; -+ -+ return 0; -+} -+ -+#define MMC_NUM_MINORS (256 >> MMC_SHIFT) -+ -+static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))]; -+ -+static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) -+{ -+ struct mmc_blk_data *md; -+ int devidx; -+ -+ devidx = find_first_zero_bit(dev_use, MMC_NUM_MINORS); -+ if (devidx >= MMC_NUM_MINORS) -+ return NULL; -+ __set_bit(devidx, dev_use); -+ -+ md = kmalloc(sizeof(struct mmc_blk_data), GFP_KERNEL); -+ if (md) { -+ memset(md, 0, sizeof(struct mmc_blk_data)); -+ -+ md->disk = alloc_disk(1 << MMC_SHIFT); -+ if (md->disk == NULL) { -+ kfree(md); -+ md = NULL; -+ goto out; -+ } -+ -+ spin_lock_init(&md->lock); -+ md->usage = 1; -+ -+ mmc_init_queue(&md->queue, card, &md->lock); -+ md->queue.prep_fn = mmc_blk_prep_rq; -+ md->queue.issue_fn = mmc_blk_issue_rq; -+ md->queue.data = md; -+ -+ md->disk->major = mmc_major; -+ md->disk->first_minor = devidx << MMC_SHIFT; -+ md->disk->fops = &mmc_bdops; -+ md->disk->private_data = md; -+ md->disk->queue = md->queue.queue; -+ md->disk->driverfs_dev = &card->dev; -+ -+ sprintf(md->disk->disk_name, "mmcblk%d", devidx); -+ sprintf(md->disk->devfs_name, "mmc/blk%d", devidx); -+ -+ md->block_bits = md->queue.card->csd.read_blkbits; -+ -+ blk_queue_max_sectors(md->queue.queue, maxsectors); -+ blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); -+ set_capacity(md->disk, md->queue.card->csd.capacity); -+ } -+ out: -+ return md; -+} -+ -+static int -+mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) -+{ -+ struct mmc_command cmd; -+ int err; -+ -+ mmc_card_claim_host(card); -+ cmd.opcode = MMC_SET_BLOCKLEN; -+ cmd.arg = 1 << card->csd.read_blkbits; -+ cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC; -+ err = mmc_wait_for_cmd(card->host, &cmd, 5); -+ mmc_card_release_host(card); -+ -+ if (err) { -+ printk(KERN_ERR "%s: unable to set block size to %d: %d\n", -+ md->disk->disk_name, cmd.arg, err); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int mmc_blk_probe(struct mmc_card *card) -+{ -+ struct mmc_blk_data *md; -+ int err; -+ -+ if (card->csd.cmdclass & ~0x1ff) -+ return -ENODEV; -+ -+ if (card->csd.read_blkbits < 9) { -+ printk(KERN_WARNING "%s: read blocksize too small (%u)\n", -+ mmc_card_id(card), 1 << card->csd.read_blkbits); -+ return -ENODEV; -+ } -+ -+ md = mmc_blk_alloc(card); -+ if (md == NULL) -+ return -ENOMEM; -+ -+ err = mmc_blk_set_blksize(md, card); -+ if (err) -+ goto out; -+ -+ printk(KERN_INFO "%s: %s %s %dKiB\n", -+ md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), -+ (card->csd.capacity << card->csd.read_blkbits) / 1024); -+ -+ mmc_set_drvdata(card, md); -+ add_disk(md->disk); -+ return 0; -+ -+ out: -+ mmc_blk_put(md); -+ -+ return err; -+} -+ -+static void mmc_blk_remove(struct mmc_card *card) -+{ -+ struct mmc_blk_data *md = mmc_get_drvdata(card); -+ -+ if (md) { -+ int devidx; -+ -+ del_gendisk(md->disk); -+ -+ /* -+ * I think this is needed. -+ */ -+ md->disk->queue = NULL; -+ -+ devidx = md->disk->first_minor >> MMC_SHIFT; -+ __clear_bit(devidx, dev_use); -+ -+ mmc_blk_put(md); -+ } -+ mmc_set_drvdata(card, NULL); -+} -+ -+#ifdef CONFIG_PM -+static int mmc_blk_suspend(struct mmc_card *card, u32 state) -+{ -+ struct mmc_blk_data *md = mmc_get_drvdata(card); -+ -+ if (md) { -+ blk_stop_queue(md->queue.queue); -+ } -+ return 0; -+} -+ -+static int mmc_blk_resume(struct mmc_card *card) -+{ -+ struct mmc_blk_data *md = mmc_get_drvdata(card); -+ -+ if (md) { -+ mmc_blk_set_blksize(md, md->queue.card); -+ blk_start_queue(md->queue.queue); -+ } -+ return 0; -+} -+#else -+#define mmc_blk_suspend NULL -+#define mmc_blk_resume NULL -+#endif -+ -+static struct mmc_driver mmc_driver = { -+ .drv = { -+ .name = "mmcblk", -+ }, -+ .probe = mmc_blk_probe, -+ .remove = mmc_blk_remove, -+ .suspend = mmc_blk_suspend, -+ .resume = mmc_blk_resume, -+}; -+ -+static int __init mmc_blk_init(void) -+{ -+ int res = -ENOMEM; -+ -+ res = register_blkdev(mmc_major, "mmc"); -+ if (res < 0) { -+ printk(KERN_WARNING "Unable to get major %d for MMC media: %d\n", -+ mmc_major, res); -+ goto out; -+ } -+ if (mmc_major == 0) -+ mmc_major = res; -+ -+ devfs_mk_dir("mmc"); -+ return mmc_register_driver(&mmc_driver); -+ -+ out: -+ return res; -+} -+ -+static void __exit mmc_blk_exit(void) -+{ -+ mmc_unregister_driver(&mmc_driver); -+ devfs_remove("mmc"); -+ unregister_blkdev(mmc_major, "mmc"); -+} -+ -+module_init(mmc_blk_init); -+module_exit(mmc_blk_exit); -+module_param(maxsectors, int, 0444); -+ -+MODULE_PARM_DESC(maxsectors, "Maximum number of sectors for a single request"); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/pxamci.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,94 @@ -+#undef MMC_STRPCL -+#undef MMC_STAT -+#undef MMC_CLKRT -+#undef MMC_SPI -+#undef MMC_CMDAT -+#undef MMC_RESTO -+#undef MMC_RDTO -+#undef MMC_BLKLEN -+#undef MMC_NOB -+#undef MMC_PRTBUF -+#undef MMC_I_MASK -+#undef END_CMD_RES -+#undef PRG_DONE -+#undef DATA_TRAN_DONE -+#undef MMC_I_REG -+#undef MMC_CMD -+#undef MMC_ARGH -+#undef MMC_ARGL -+#undef MMC_RES -+#undef MMC_RXFIFO -+#undef MMC_TXFIFO -+ -+#define MMC_STRPCL 0x0000 -+#define STOP_CLOCK (1 << 0) -+#define START_CLOCK (2 << 0) -+ -+#define MMC_STAT 0x0004 -+#define STAT_END_CMD_RES (1 << 13) -+#define STAT_PRG_DONE (1 << 12) -+#define STAT_DATA_TRAN_DONE (1 << 11) -+#define STAT_CLK_EN (1 << 8) -+#define STAT_RECV_FIFO_FULL (1 << 7) -+#define STAT_XMIT_FIFO_EMPTY (1 << 6) -+#define STAT_RES_CRC_ERR (1 << 5) -+#define STAT_SPI_READ_ERROR_TOKEN (1 << 4) -+#define STAT_CRC_READ_ERROR (1 << 3) -+#define STAT_CRC_WRITE_ERROR (1 << 2) -+#define STAT_TIME_OUT_RESPONSE (1 << 1) -+#define STAT_READ_TIME_OUT (1 << 0) -+ -+#define MMC_CLKRT 0x0008 /* 3 bit */ -+ -+#define MMC_SPI 0x000c -+#define SPI_CS_ADDRESS (1 << 3) -+#define SPI_CS_EN (1 << 2) -+#define CRC_ON (1 << 1) -+#define SPI_EN (1 << 0) -+ -+#define MMC_CMDAT 0x0010 -+#define CMDAT_DMAEN (1 << 7) -+#define CMDAT_INIT (1 << 6) -+#define CMDAT_BUSY (1 << 5) -+#define CMDAT_STREAM (1 << 4) /* 1 = stream */ -+#define CMDAT_WRITE (1 << 3) /* 1 = write */ -+#define CMDAT_DATAEN (1 << 2) -+#define CMDAT_RESP_NONE (0 << 0) -+#define CMDAT_RESP_SHORT (1 << 0) -+#define CMDAT_RESP_R2 (2 << 0) -+#define CMDAT_RESP_R3 (3 << 0) -+ -+#define MMC_RESTO 0x0014 /* 7 bit */ -+ -+#define MMC_RDTO 0x0018 /* 16 bit */ -+ -+#define MMC_BLKLEN 0x001c /* 10 bit */ -+ -+#define MMC_NOB 0x0020 /* 16 bit */ -+ -+#define MMC_PRTBUF 0x0024 -+#define BUF_PART_FULL (1 << 0) -+ -+#define MMC_I_MASK 0x0028 -+#define TXFIFO_WR_REQ (1 << 6) -+#define RXFIFO_RD_REQ (1 << 5) -+#define CLK_IS_OFF (1 << 4) -+#define STOP_CMD (1 << 3) -+#define END_CMD_RES (1 << 2) -+#define PRG_DONE (1 << 1) -+#define DATA_TRAN_DONE (1 << 0) -+ -+#define MMC_I_REG 0x002c -+/* same as MMC_I_MASK */ -+ -+#define MMC_CMD 0x0030 -+ -+#define MMC_ARGH 0x0034 /* 16 bit */ -+ -+#define MMC_ARGL 0x0038 /* 16 bit */ -+ -+#define MMC_RES 0x003c /* 16 bit */ -+ -+#define MMC_RXFIFO 0x0040 /* 8 bit */ -+ -+#define MMC_TXFIFO 0x0044 /* 8 bit */ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/mmci.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,147 @@ -+/* -+ * linux/drivers/media/mmc/mmci.h - ARM PrimeCell MMCI PL180/1 driver -+ * -+ * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#define MMCIPOWER 0x000 -+#define MCI_PWR_OFF 0x00 -+#define MCI_PWR_UP 0x02 -+#define MCI_PWR_ON 0x03 -+#define MCI_OD (1 << 6) -+#define MCI_ROD (1 << 7) -+ -+#define MMCICLOCK 0x004 -+#define MCI_CLK_ENABLE (1 << 8) -+#define MCI_PWRSAVE (1 << 9) -+#define MCI_BYPASS (1 << 10) -+ -+#define MMCIARGUMENT 0x008 -+#define MMCICOMMAND 0x00c -+#define MCI_CPSM_RESPONSE (1 << 6) -+#define MCI_CPSM_LONGRSP (1 << 7) -+#define MCI_CPSM_INTERRUPT (1 << 8) -+#define MCI_CPSM_PENDING (1 << 9) -+#define MCI_CPSM_ENABLE (1 << 10) -+ -+#define MMCIRESPCMD 0x010 -+#define MMCIRESPONSE0 0x014 -+#define MMCIRESPONSE1 0x018 -+#define MMCIRESPONSE2 0x01c -+#define MMCIRESPONSE3 0x020 -+#define MMCIDATATIMER 0x024 -+#define MMCIDATALENGTH 0x028 -+#define MMCIDATACTRL 0x02c -+#define MCI_DPSM_ENABLE (1 << 0) -+#define MCI_DPSM_DIRECTION (1 << 1) -+#define MCI_DPSM_MODE (1 << 2) -+#define MCI_DPSM_DMAENABLE (1 << 3) -+ -+#define MMCIDATACNT 0x030 -+#define MMCISTATUS 0x034 -+#define MCI_CMDCRCFAIL (1 << 0) -+#define MCI_DATACRCFAIL (1 << 1) -+#define MCI_CMDTIMEOUT (1 << 2) -+#define MCI_DATATIMEOUT (1 << 3) -+#define MCI_TXUNDERRUN (1 << 4) -+#define MCI_RXOVERRUN (1 << 5) -+#define MCI_CMDRESPEND (1 << 6) -+#define MCI_CMDSENT (1 << 7) -+#define MCI_DATAEND (1 << 8) -+#define MCI_DATABLOCKEND (1 << 10) -+#define MCI_CMDACTIVE (1 << 11) -+#define MCI_TXACTIVE (1 << 12) -+#define MCI_RXACTIVE (1 << 13) -+#define MCI_TXFIFOHALFEMPTY (1 << 14) -+#define MCI_RXFIFOHALFFULL (1 << 15) -+#define MCI_TXFIFOFULL (1 << 16) -+#define MCI_RXFIFOFULL (1 << 17) -+#define MCI_TXFIFOEMPTY (1 << 18) -+#define MCI_RXFIFOEMPTY (1 << 19) -+#define MCI_TXDATAAVLBL (1 << 20) -+#define MCI_RXDATAAVLBL (1 << 21) -+ -+#define MMCICLEAR 0x038 -+#define MCI_CMDCRCFAILCLR (1 << 0) -+#define MCI_DATACRCFAILCLR (1 << 1) -+#define MCI_CMDTIMEOUTCLR (1 << 2) -+#define MCI_DATATIMEOUTCLR (1 << 3) -+#define MCI_TXUNDERRUNCLR (1 << 4) -+#define MCI_RXOVERRUNCLR (1 << 5) -+#define MCI_CMDRESPENDCLR (1 << 6) -+#define MCI_CMDSENTCLR (1 << 7) -+#define MCI_DATAENDCLR (1 << 8) -+#define MCI_DATABLOCKENDCLR (1 << 10) -+ -+#define MMCIMASK0 0x03c -+#define MCI_CMDCRCFAILMASK (1 << 0) -+#define MCI_DATACRCFAILMASK (1 << 1) -+#define MCI_CMDTIMEOUTMASK (1 << 2) -+#define MCI_DATATIMEOUTMASK (1 << 3) -+#define MCI_TXUNDERRUNMASK (1 << 4) -+#define MCI_RXOVERRUNMASK (1 << 5) -+#define MCI_CMDRESPENDMASK (1 << 6) -+#define MCI_CMDSENTMASK (1 << 7) -+#define MCI_DATAENDMASK (1 << 8) -+#define MCI_DATABLOCKENDMASK (1 << 10) -+#define MCI_CMDACTIVEMASK (1 << 11) -+#define MCI_TXACTIVEMASK (1 << 12) -+#define MCI_RXACTIVEMASK (1 << 13) -+#define MCI_TXFIFOHALFEMPTYMASK (1 << 14) -+#define MCI_RXFIFOHALFFULLMASK (1 << 15) -+#define MCI_TXFIFOFULLMASK (1 << 16) -+#define MCI_RXFIFOFULLMASK (1 << 17) -+#define MCI_TXFIFOEMPTYMASK (1 << 18) -+#define MCI_RXFIFOEMPTYMASK (1 << 19) -+#define MCI_TXDATAAVLBLMASK (1 << 20) -+#define MCI_RXDATAAVLBLMASK (1 << 21) -+ -+#define MMCIMASK1 0x040 -+#define MMCIFIFOCNT 0x048 -+#define MMCIFIFO 0x080 /* to 0x0bc */ -+ -+#define MCI_IRQMASK \ -+ (MCI_CMDCRCFAIL|MCI_DATACRCFAIL|MCI_CMDTIMEOUT|MCI_DATATIMEOUT| \ -+ MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_CMDRESPEND|MCI_CMDSENT| \ -+ MCI_DATAEND|MCI_DATABLOCKEND| \ -+ MCI_TXFIFOHALFEMPTY|MCI_RXFIFOHALFFULL| \ -+ MCI_TXFIFOEMPTY|MCI_RXDATAAVLBL) -+ -+#define MCI_IRQENABLE \ -+ (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ -+ MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ -+ MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK| \ -+ MCI_DATABLOCKENDMASK|MCI_TXFIFOHALFEMPTYMASK| \ -+ MCI_RXFIFOHALFFULLMASK) -+ -+#define MCI_FIFOSIZE 16 -+ -+#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2) -+ -+struct mmci_host { -+ struct mmc_host mmc; -+ void *base; -+ int irq; -+ unsigned int mclk; -+ u32 pwr; -+ -+ struct mmc_request *req; -+ struct mmc_command *cmd; -+ struct mmc_data *data; -+ -+ unsigned int data_xfered; -+ -+ /* pio stuff */ -+ void *buffer; -+ unsigned int size; -+ -+ /* dma stuff */ -+// struct scatterlist *sg_list; -+// int sg_len; -+// int sg_dir; -+}; -+ -+#define to_mmci_host(mmc) container_of(mmc, struct mmci_host, mmc) ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/mmc.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,801 @@ -+/* -+ * linux/drivers/media/mmc/mmc.c -+ * -+ * Copyright (C) 2003 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "mmc.h" -+ -+#ifdef CONFIG_MMC_DEBUG -+#define DBG(x...) printk(KERN_DEBUG x) -+#else -+#define DBG(x...) do { } while (0) -+#endif -+ -+#define CMD_RETRIES 3 -+ -+/* -+ * OCR Bit positions to 10s of Vdd mV. -+ */ -+static const unsigned short mmc_ocr_bit_to_vdd[] = { -+ 150, 155, 160, 165, 170, 180, 190, 200, -+ 210, 220, 230, 240, 250, 260, 270, 280, -+ 290, 300, 310, 320, 330, 340, 350, 360 -+}; -+ -+static const unsigned int tran_exp[] = { -+ 10000, 100000, 1000000, 10000000, -+ 0, 0, 0, 0 -+}; -+ -+static const unsigned char tran_mant[] = { -+ 0, 10, 12, 13, 15, 20, 25, 30, -+ 35, 40, 45, 50, 55, 60, 70, 80, -+}; -+ -+static const unsigned int tacc_exp[] = { -+ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, -+}; -+ -+static const unsigned int tacc_mant[] = { -+ 0, 10, 12, 13, 15, 20, 25, 30, -+ 35, 40, 45, 50, 55, 60, 70, 80, -+}; -+ -+ -+/** -+ * mmc_request_done - finish processing an MMC command -+ * @host: MMC host which completed command -+ * @cmd: MMC command which completed -+ * @err: MMC error code -+ * -+ * MMC drivers should call this function when they have completed -+ * their processing of a command. This should be called before the -+ * data part of the command has completed. -+ */ -+void mmc_request_done(struct mmc_host *host, struct mmc_request *req) -+{ -+ struct mmc_command *cmd = req->cmd; -+ int err = req->cmd->error; -+ DBG("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", cmd->opcode, -+ err, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); -+ -+ if (err && cmd->retries) { -+ cmd->retries--; -+ cmd->error = 0; -+ host->ops->request(host, req); -+ } else if (req->done) { -+ req->done(req); -+ } -+} -+ -+EXPORT_SYMBOL(mmc_request_done); -+ -+/** -+ * mmc_start_request - start a command on a host -+ * @host: MMC host to start command on -+ * @cmd: MMC command to start -+ * -+ * Queue a command on the specified host. We expect the -+ * caller to be holding the host lock with interrupts disabled. -+ */ -+void -+mmc_start_request(struct mmc_host *host, struct mmc_request *req) -+{ -+ DBG("MMC: starting cmd %02x arg %08x flags %08x\n", -+ req->cmd->opcode, req->cmd->arg, req->cmd->flags); -+ -+ req->cmd->error = 0; -+ req->cmd->req = req; -+ if (req->data) { -+ req->cmd->data = req->data; -+ req->data->error = 0; -+ req->data->req = req; -+ if (req->stop) { -+ req->data->stop = req->stop; -+ req->stop->error = 0; -+ req->stop->req = req; -+ } -+ } -+ host->ops->request(host, req); -+} -+ -+EXPORT_SYMBOL(mmc_start_request); -+ -+static void mmc_wait_done(struct mmc_request *req) -+{ -+ complete(req->done_data); -+} -+ -+int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *req) -+{ -+ DECLARE_COMPLETION(complete); -+ -+ req->done_data = &complete; -+ req->done = mmc_wait_done; -+ -+ mmc_start_request(host, req); -+ -+ wait_for_completion(&complete); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL(mmc_wait_for_req); -+ -+/** -+ * mmc_wait_for_cmd - start a command and wait for completion -+ * @host: MMC host to start command -+ * @cmd: MMC command to start -+ * @retries: maximum number of retries -+ * -+ * Start a new MMC command for a host, and wait for the command -+ * to complete. Return any error that occurred while the command -+ * was executing. Do not attempt to parse the response. -+ */ -+int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) -+{ -+ struct mmc_request req; -+ -+ BUG_ON(host->card_busy == NULL); -+ -+ memset(&req, 0, sizeof(struct mmc_request)); -+ -+ memset(cmd->resp, 0, sizeof(cmd->resp)); -+ cmd->retries = retries; -+ -+ req.cmd = cmd; -+ cmd->data = NULL; -+ -+ mmc_wait_for_req(host, &req); -+ -+ return cmd->error; -+} -+ -+EXPORT_SYMBOL(mmc_wait_for_cmd); -+ -+ -+ -+/** -+ * __mmc_claim_host - exclusively claim a host -+ * @host: mmc host to claim -+ * @card: mmc card to claim host for -+ * -+ * Claim a host for a set of operations. If a valid card -+ * is passed and this wasn't the last card selected, select -+ * the card before returning. -+ * -+ * Note: you should use mmc_card_claim_host or mmc_claim_host. -+ */ -+int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ unsigned long flags; -+ int err = 0; -+ -+ add_wait_queue(&host->wq, &wait); -+ spin_lock_irqsave(&host->lock, flags); -+ while (1) { -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ if (host->card_busy == NULL) -+ break; -+ spin_unlock_irqrestore(&host->lock, flags); -+ schedule(); -+ spin_lock_irqsave(&host->lock, flags); -+ } -+ set_current_state(TASK_RUNNING); -+ host->card_busy = card; -+ spin_unlock_irqrestore(&host->lock, flags); -+ remove_wait_queue(&host->wq, &wait); -+ -+ if (card != (void *)-1 && host->card_selected != card) { -+ struct mmc_command cmd; -+ -+ host->card_selected = card; -+ -+ cmd.opcode = MMC_SELECT_CARD; -+ cmd.arg = card->rca << 16; -+ cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC; -+ -+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); -+ } -+ -+ return err; -+} -+ -+EXPORT_SYMBOL(__mmc_claim_host); -+ -+/** -+ * mmc_release_host - release a host -+ * @host: mmc host to release -+ * -+ * Release a MMC host, allowing others to claim the host -+ * for their operations. -+ */ -+void mmc_release_host(struct mmc_host *host) -+{ -+ unsigned long flags; -+ -+ BUG_ON(host->card_busy == NULL); -+ -+ spin_lock_irqsave(&host->lock, flags); -+ host->card_busy = NULL; -+ spin_unlock_irqrestore(&host->lock, flags); -+ -+ wake_up(&host->wq); -+} -+ -+EXPORT_SYMBOL(mmc_release_host); -+ -+static void mmc_deselect_cards(struct mmc_host *host) -+{ -+ struct mmc_command cmd; -+ -+ /* -+ * Ensure that no card is selected. -+ */ -+ if (host->card_selected) { -+ host->card_selected = NULL; -+ -+ cmd.opcode = MMC_SELECT_CARD; -+ cmd.arg = 0; -+ cmd.flags = MMC_RSP_NONE; -+ -+ mmc_wait_for_cmd(host, &cmd, 0); -+ } -+} -+ -+ -+static inline void mmc_delay(unsigned int ms) -+{ -+ if (ms < HZ / 1000) { -+ yield(); -+ mdelay(ms); -+ } else { -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(ms * HZ / 1000); -+ } -+} -+ -+static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) -+{ -+ int bit; -+ -+ /* -+ * Mask off any voltages we don't support -+ */ -+ ocr &= host->ocr_avail; -+ -+ /* -+ * Select the lowest voltage -+ */ -+ bit = ffs(ocr); -+ if (bit) { -+ bit -= 1; -+ -+ ocr = 1 << bit; -+ -+ host->ios.vdd = mmc_ocr_bit_to_vdd[bit]; -+ host->ops->set_ios(host, &host->ios); -+ } else { -+ ocr = 0; -+ } -+ -+ return ocr; -+} -+ -+static void mmc_decode_cid(struct mmc_cid *cid, u32 *resp) -+{ -+ memset(cid, 0, sizeof(struct mmc_cid)); -+ -+ cid->manfid = resp[0] >> 8; -+ cid->prod_name[0] = resp[0]; -+ cid->prod_name[1] = resp[1] >> 24; -+ cid->prod_name[2] = resp[1] >> 16; -+ cid->prod_name[3] = resp[1] >> 8; -+ cid->prod_name[4] = resp[1]; -+ cid->prod_name[5] = resp[2] >> 24; -+ cid->prod_name[6] = resp[2] >> 16; -+ cid->prod_name[7] = '\0'; -+ cid->hwrev = (resp[2] >> 12) & 15; -+ cid->fwrev = (resp[2] >> 8) & 15; -+ cid->serial = (resp[2] & 255) << 16 | (resp[3] >> 16); -+ cid->month = (resp[3] >> 12) & 15; -+ cid->year = (resp[3] >> 8) & 15; -+} -+ -+static void mmc_decode_csd(struct mmc_csd *csd, u32 *resp) -+{ -+ unsigned int e, m; -+ -+ csd->mmc_prot = (resp[0] >> 26) & 15; -+ m = (resp[0] >> 19) & 15; -+ e = (resp[0] >> 16) & 7; -+ csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; -+ csd->tacc_clks = ((resp[0] >> 8) & 255) * 100; -+ -+ m = (resp[0] >> 3) & 15; -+ e = resp[0] & 7; -+ csd->max_dtr = tran_exp[e] * tran_mant[m]; -+ csd->cmdclass = (resp[1] >> 20) & 0xfff; -+ -+ e = (resp[2] >> 15) & 7; -+ m = (resp[1] << 2 | resp[2] >> 30) & 0x3fff; -+ csd->capacity = (1 + m) << (e + 2); -+ -+ csd->read_blkbits = (resp[1] >> 16) & 15; -+} -+ -+/* -+ * Locate a MMC card on this MMC host given a CID. -+ */ -+static struct mmc_card * -+mmc_find_card(struct mmc_host *host, struct mmc_cid *cid) -+{ -+ struct mmc_card *card; -+ -+ list_for_each_entry(card, &host->cards, node) { -+ if (memcmp(&card->cid, cid, sizeof(struct mmc_cid)) == 0) -+ return card; -+ } -+ return NULL; -+} -+ -+/* -+ * Allocate a new MMC card, and assign a unique RCA. -+ */ -+static struct mmc_card * -+mmc_alloc_card(struct mmc_host *host, struct mmc_cid *cid, unsigned int *frca) -+{ -+ struct mmc_card *card, *c; -+ unsigned int rca = *frca; -+ -+ card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); -+ if (!card) -+ return ERR_PTR(-ENOMEM); -+ -+ mmc_init_card(card, host); -+ memcpy(&card->cid, cid, sizeof(struct mmc_cid)); -+ -+ again: -+ list_for_each_entry(c, &host->cards, node) -+ if (c->rca == rca) { -+ rca++; -+ goto again; -+ } -+ -+ card->rca = rca; -+ -+ *frca = rca; -+ -+ return card; -+} -+ -+/* -+ * Apply power to the MMC stack. -+ */ -+static void mmc_power_up(struct mmc_host *host) -+{ -+ struct mmc_command cmd; -+ int bit = fls(host->ocr_avail) - 1; -+ -+ host->ios.vdd = mmc_ocr_bit_to_vdd[bit]; -+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; -+ host->ios.power_mode = MMC_POWER_UP; -+ host->ops->set_ios(host, &host->ios); -+ -+ mmc_delay(1); -+ -+ host->ios.clock = host->f_min; -+ host->ios.power_mode = MMC_POWER_ON; -+ host->ops->set_ios(host, &host->ios); -+ -+ mmc_delay(2); -+ -+ cmd.opcode = MMC_GO_IDLE_STATE; -+ cmd.arg = 0; -+ cmd.flags = MMC_RSP_NONE; -+ -+ mmc_wait_for_cmd(host, &cmd, 0); -+} -+ -+static void mmc_power_off(struct mmc_host *host) -+{ -+ host->ios.clock = 0; -+ host->ios.vdd = 0; -+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; -+ host->ios.power_mode = MMC_POWER_OFF; -+ host->ops->set_ios(host, &host->ios); -+} -+ -+static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) -+{ -+ struct mmc_command cmd; -+ int i, err = 0; -+ -+ cmd.opcode = MMC_SEND_OP_COND; -+ cmd.arg = ocr; -+ cmd.flags = MMC_RSP_SHORT; -+ -+ for (i = 100; i; i--) { -+ err = mmc_wait_for_cmd(host, &cmd, 0); -+ if (err != MMC_ERR_NONE) -+ break; -+ -+ if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) -+ break; -+ -+ err = MMC_ERR_TIMEOUT; -+ } -+ -+ if (rocr) -+ *rocr = cmd.resp[0]; -+ -+ return err; -+} -+ -+/* -+ * Discover cards by requesting their CID. If this command -+ * times out, it is not an error; there are no further cards -+ * to be discovered. Add new cards to the list. -+ * -+ * Create a mmc_card entry for each discovered card, assigning -+ * it an RCA, and save the CID. -+ */ -+static void mmc_discover_cards(struct mmc_host *host) -+{ -+ struct mmc_card *card; -+ unsigned int first_rca = 1, err; -+ -+ while (1) { -+ struct mmc_command cmd; -+ struct mmc_cid cid; -+ -+ /* -+ * Read CID -+ */ -+ cmd.opcode = MMC_ALL_SEND_CID; -+ cmd.arg = 0; -+ cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC; -+ -+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); -+ if (err == MMC_ERR_TIMEOUT) { -+ err = MMC_ERR_NONE; -+ break; -+ } -+ if (err != MMC_ERR_NONE) { -+ printk(KERN_ERR "MMC: mmc%d error requesting CID: %d\n", -+ host->host_num, err); -+ break; -+ } -+ -+ mmc_decode_cid(&cid, cmd.resp); -+ -+ card = mmc_find_card(host, &cid); -+ if (!card) { -+ card = mmc_alloc_card(host, &cid, &first_rca); -+ if (IS_ERR(card)) { -+ err = PTR_ERR(card); -+ break; -+ } -+ list_add(&card->node, &host->cards); -+ } -+ -+ card->state &= ~MMC_STATE_DEAD; -+ -+ cmd.opcode = MMC_SET_RELATIVE_ADDR; -+ cmd.arg = card->rca << 16; -+ cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC; -+ -+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); -+ if (err != MMC_ERR_NONE) -+ card->state |= MMC_STATE_DEAD; -+ } -+} -+ -+static void mmc_read_csds(struct mmc_host *host) -+{ -+ struct mmc_card *card; -+ -+ list_for_each_entry(card, &host->cards, node) { -+ struct mmc_command cmd; -+ int err; -+ -+ if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) -+ continue; -+ -+ cmd.opcode = MMC_SEND_CSD; -+ cmd.arg = card->rca << 16; -+ cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC; -+ -+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); -+ if (err != MMC_ERR_NONE) { -+ card->state |= MMC_STATE_DEAD; -+ continue; -+ } -+ -+ mmc_decode_csd(&card->csd, cmd.resp); -+ } -+} -+ -+static unsigned int mmc_calculate_clock(struct mmc_host *host) -+{ -+ struct mmc_card *card; -+ unsigned int max_dtr = host->f_max; -+ -+ list_for_each_entry(card, &host->cards, node) -+ if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr) -+ max_dtr = card->csd.max_dtr; -+ -+ DBG("MMC: selected %d.%03dMHz transfer rate\n", -+ max_dtr / 1000000, (max_dtr / 1000) % 1000); -+ -+ return max_dtr; -+} -+ -+/* -+ * Check whether cards we already know about are still present. -+ * We do this by requesting status, and checking whether a card -+ * responds. -+ * -+ * A request for status does not cause a state change in data -+ * transfer mode. -+ */ -+static void mmc_check_cards(struct mmc_host *host) -+{ -+ struct list_head *l, *n; -+ -+ mmc_deselect_cards(host); -+ -+ list_for_each_safe(l, n, &host->cards) { -+ struct mmc_card *card = mmc_list_to_card(l); -+ struct mmc_command cmd; -+ int err; -+ -+ cmd.opcode = MMC_SEND_STATUS; -+ cmd.arg = card->rca << 16; -+ cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC; -+ -+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); -+ if (err == MMC_ERR_NONE) -+ continue; -+ -+ /* -+ * Ok, we believe this card has been removed. -+ */ -+ card->state |= MMC_STATE_DEAD; -+ } -+} -+ -+static void mmc_setup(struct mmc_host *host) -+{ -+ if (host->ios.power_mode != MMC_POWER_ON) { -+ int err; -+ u32 ocr; -+ -+ mmc_power_up(host); -+ -+ err = mmc_send_op_cond(host, 0, &ocr); -+ if (err != MMC_ERR_NONE) -+ return; -+ -+ host->ocr = mmc_select_voltage(host, ocr); -+ } else { -+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; -+ host->ios.clock = host->f_min; -+ host->ops->set_ios(host, &host->ios); -+ -+ /* -+ * We should remember the OCR mask from the existing -+ * cards, and detect the new cards OCR mask, combine -+ * the two and re-select the VDD. However, if we do -+ * change VDD, we should do an idle, and then do a -+ * full re-initialisation. We would need to notify -+ * drivers so that they can re-setup the cards as -+ * well, while keeping their queues at bay. -+ * -+ * For the moment, we take the easy way out - if the -+ * new cards don't like our currently selected VDD, -+ * they drop off the bus. -+ */ -+ } -+ -+ if (host->ocr == 0) -+ return; -+ -+ /* -+ * Send the selected OCR multiple times... until the cards -+ * all get the idea that they should be ready for CMD2. -+ * (My SanDisk card seems to need this.) -+ */ -+ mmc_send_op_cond(host, host->ocr, NULL); -+ -+ mmc_discover_cards(host); -+ -+ /* -+ * Ok, now switch to push-pull mode. -+ */ -+ host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; -+ host->ops->set_ios(host, &host->ios); -+ -+ mmc_read_csds(host); -+} -+ -+ -+/** -+ * mmc_detect_change - process change of state on a MMC socket -+ * @host: host which changed state. -+ * -+ * All we know is that card(s) have been inserted or removed -+ * from the socket(s). We don't know which socket or cards. -+ */ -+void mmc_detect_change(struct mmc_host *host) -+{ -+ struct list_head *l, *n; -+ -+ mmc_claim_host(host); -+ -+ if (host->ios.power_mode == MMC_POWER_ON) -+ mmc_check_cards(host); -+ -+ mmc_setup(host); -+ -+ if (!list_empty(&host->cards)) { -+ /* -+ * (Re-)calculate the fastest clock rate which the -+ * attached cards and the host support. -+ */ -+ host->ios.clock = mmc_calculate_clock(host); -+ host->ops->set_ios(host, &host->ios); -+ } -+ -+ mmc_release_host(host); -+ -+ list_for_each_safe(l, n, &host->cards) { -+ struct mmc_card *card = mmc_list_to_card(l); -+ -+ /* -+ * If this is a new and good card, register it. -+ */ -+ if (!mmc_card_present(card) && !mmc_card_dead(card)) { -+ if (mmc_register_card(card)) -+ card->state |= MMC_STATE_DEAD; -+ else -+ card->state |= MMC_STATE_PRESENT; -+ } -+ -+ /* -+ * If this card is dead, destroy it. -+ */ -+ if (mmc_card_dead(card)) { -+ list_del(&card->node); -+ mmc_remove_card(card); -+ } -+ } -+ -+ /* -+ * If we discover that there are no cards on the -+ * bus, turn off the clock and power down. -+ */ -+ if (list_empty(&host->cards)) -+ mmc_power_off(host); -+} -+ -+EXPORT_SYMBOL(mmc_detect_change); -+ -+ -+/** -+ * mmc_init_host - initialise the per-host structure. -+ * @host: mmc host -+ * -+ * Initialise the per-host structure. -+ */ -+int mmc_init_host(struct mmc_host *host) -+{ -+ static unsigned int host_num; -+ -+ memset(host, 0, sizeof(struct mmc_host)); -+ -+ host->host_num = host_num++; -+ -+ spin_lock_init(&host->lock); -+ init_waitqueue_head(&host->wq); -+ INIT_LIST_HEAD(&host->cards); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL(mmc_init_host); -+ -+/** -+ * mmc_add_host - initialise host hardware -+ * @host: mmc host -+ */ -+int mmc_add_host(struct mmc_host *host) -+{ -+ mmc_power_off(host); -+ mmc_detect_change(host); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL(mmc_add_host); -+ -+/** -+ * mmc_remove_host - remove host hardware -+ * @host: mmc host -+ * -+ * Unregister and remove all cards associated with this host, -+ * and power down the MMC bus. -+ */ -+void mmc_remove_host(struct mmc_host *host) -+{ -+ struct list_head *l, *n; -+ -+ list_for_each_safe(l, n, &host->cards) { -+ struct mmc_card *card = mmc_list_to_card(l); -+ -+ mmc_remove_card(card); -+ } -+ -+ mmc_power_off(host); -+} -+ -+EXPORT_SYMBOL(mmc_remove_host); -+ -+#ifdef CONFIG_PM -+ -+/** -+ * mmc_suspend_host - suspend a host -+ * @host: mmc host -+ * @state: suspend mode (PM_SUSPEND_xxx) -+ */ -+int mmc_suspend_host(struct mmc_host *host, u32 state) -+{ -+ mmc_claim_host(host); -+ mmc_deselect_cards(host); -+ mmc_power_off(host); -+ mmc_release_host(host); -+ -+ return 0; -+} -+ -+/** -+ * mmc_resume_host - resume a previously suspended host -+ * @host: mmc host -+ */ -+int mmc_resume_host(struct mmc_host *host) -+{ -+ mmc_detect_change(host); -+ -+ return 0; -+} -+ -+ -+#else /* CONFIG_PM is not set */ -+ -+int mmc_suspend_host(struct mmc_host *host, u32 state) { return 0; } -+int mmc_resume_host(struct mmc_host *host) { return 0; } -+ -+#endif -+ -+EXPORT_SYMBOL(mmc_suspend_host); -+EXPORT_SYMBOL(mmc_resume_host); -+ -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/media/mmc/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,21 @@ -+# -+# Makefile for the kernel mmc device drivers. -+# -+ -+# -+# Core -+# -+obj-$(CONFIG_MMC) += mmc_core.o -+ -+# -+# Media drivers -+# -+obj-$(CONFIG_MMC_BLOCK) += mmc_block.o -+ -+# -+# Host drivers -+# -+obj-$(CONFIG_MMC_ARMMMCI) += mmci.o -+obj-$(CONFIG_MMC_PXA) += pxamci.o -+ -+mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o ---- linux-2.6.5/drivers/media/Makefile~heh 2004-04-03 22:38:15.000000000 -0500 -+++ linux-2.6.5/drivers/media/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -3,3 +3,6 @@ - # - - obj-y := video/ radio/ dvb/ common/ -+ -+obj-$(CONFIG_MMC) += mmc/ -+ ---- linux-2.6.5/drivers/serial/Kconfig~heh 2004-04-03 22:38:15.000000000 -0500 -+++ linux-2.6.5/drivers/serial/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -315,6 +315,29 @@ - your boot loader (lilo or loadlin) about how to pass options to the - kernel at boot time.) - -+config SERIAL_PXA -+ bool "PXA serial port support" -+ depends on ARM && ARCH_PXA -+ select SERIAL_CORE -+ help -+ If you have a machine based on an Intel XScale PXA2xx CPU you -+ can enable its onboard serial ports by enabling this option. -+ -+config SERIAL_PXA_CONSOLE -+ bool "Console on PXA serial port" -+ depends on SERIAL_PXA -+ select SERIAL_CORE_CONSOLE -+ help -+ If you have enabled the serial port on the Intel XScale PXA -+ CPU you can make it the console by answering Y to this option. -+ -+ Even if you say Y here, the currently visible virtual console -+ (/dev/tty0) will still be used as the system console by default, but -+ you can alter that using a kernel command line option such as -+ "console=ttySA0". (Try "man bootparam" or see the documentation of -+ your boot loader (lilo or loadlin) about how to pass options to the -+ kernel at boot time.) -+ - config SERIAL_SA1100 - bool "SA1100 serial port support" - depends on ARM && ARCH_SA1100 ---- linux-2.6.5/drivers/serial/pxa.c~heh 2004-04-03 22:38:16.000000000 -0500 -+++ linux-2.6.5/drivers/serial/pxa.c 2004-04-30 20:57:36.000000000 -0400 -@@ -294,7 +294,6 @@ - unsigned char status; - unsigned int ret; - --return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; - spin_lock_irqsave(&up->port.lock, flags); - status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); -@@ -800,6 +799,21 @@ - .ops = &serial_pxa_pops, - .line = 2, - }, -+ }, { /* HWUART */ -+ .name = "HWUART", -+ .cken = CKEN4_HWUART, -+ .port = { -+ .type = PORT_PXA, -+ .iotype = SERIAL_IO_MEM, -+ .membase = (void *)&HWUART, -+ .mapbase = __PREG(HWUART), -+ .irq = IRQ_HWUART, -+ .uartclk = 921600 * 16, -+ .fifosize = 64, -+ .flags = ASYNC_SKIP_TEST, -+ .ops = &serial_pxa_pops, -+ .line = 3, -+ }, - } - }; - ---- linux-2.6.5/drivers/serial/sa1100.c~heh 2004-04-03 22:36:24.000000000 -0500 -+++ linux-2.6.5/drivers/serial/sa1100.c 2004-04-30 20:57:36.000000000 -0400 -@@ -448,6 +448,15 @@ - unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; - - /* -+ * If we don't support modem control lines, don't allow -+ * these to be set. -+ */ -+ if (0) { -+ termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR); -+ termios->c_cflag |= CLOCAL; -+ } -+ -+ /* - * We only support CS7 and CS8. - */ - while ((termios->c_cflag & CSIZE) != CS7 && -@@ -894,6 +903,7 @@ - if (sa1100_ports[i].port.mapbase != res->start) - continue; - -+ sa1100_ports[i].port.dev = _dev; - uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port); - dev_set_drvdata(_dev, &sa1100_ports[i]); - break; ---- linux-2.6.5/drivers/mtd/mtd_blkdevs.c~heh 2004-04-03 22:36:14.000000000 -0500 -+++ linux-2.6.5/drivers/mtd/mtd_blkdevs.c 2004-04-30 20:57:36.000000000 -0400 -@@ -81,7 +81,7 @@ - struct request_queue *rq = tr->blkcore_priv->rq; - - /* we might get involved when memory gets low, so use PF_MEMALLOC */ -- current->flags |= PF_MEMALLOC; -+ current->flags |= PF_MEMALLOC|PF_IOTHREAD; - - daemonize("%sd", tr->name); - ---- linux-2.6.5/drivers/mtd/devices/doc1000.c~heh 2004-04-03 22:37:36.000000000 -0500 -+++ linux-2.6.5/drivers/mtd/devices/doc1000.c 2004-04-30 20:57:36.000000000 -0400 -@@ -1,6 +1,6 @@ - /*====================================================================== - -- $Id: doc1000.c,v 1.15 2001/10/02 15:05:13 dwmw2 Exp $ -+ $Id: doc1000.c,v 1.16 2001/12/28 22:45:17 dwmw2 Exp $ - - ======================================================================*/ - -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -482,7 +483,7 @@ - else - priv->devstat[erase->dev] = erase->state = MTD_ERASE_PENDING; - } -- else if (erase->time + erase_timeout < jiffies) -+ else if (time_after(jiffies, erase->time + erase_timeout)) - { - printk("Flash erase timed out. The world is broken.\n"); - ---- linux-2.6.5/drivers/mtd/mtdconcat.c~heh 2004-04-03 22:37:37.000000000 -0500 -+++ linux-2.6.5/drivers/mtd/mtdconcat.c 2004-04-30 20:57:36.000000000 -0400 -@@ -7,7 +7,7 @@ - * - * This code is GPL - * -- * $Id: mtdconcat.c,v 1.4 2003/03/07 17:44:59 rkaiser Exp $ -+ * $Id: mtdconcat.c,v 1.7 2003/06/29 21:26:34 dwmw2 Exp $ - */ - - #include -@@ -26,7 +26,7 @@ - */ - struct mtd_concat { - struct mtd_info mtd; -- int num_subdev; -+ int num_subdev; - struct mtd_info **subdev; - }; - -@@ -37,21 +37,20 @@ - #define SIZEOF_STRUCT_MTD_CONCAT(num_subdev) \ - ((sizeof(struct mtd_concat) + (num_subdev) * sizeof(struct mtd_info *))) - -- - /* - * Given a pointer to the MTD object in the mtd_concat structure, - * we can retrieve the pointer to that structure with this macro. - */ - #define CONCAT(x) ((struct mtd_concat *)(x)) - -- - /* - * MTD methods which look up the relevant subdevice, translate the - * effective address and pass through to the subdevice. - */ - --static int concat_read (struct mtd_info *mtd, loff_t from, size_t len, -- size_t *retlen, u_char *buf) -+static int -+concat_read(struct mtd_info *mtd, loff_t from, size_t len, -+ size_t * retlen, u_char * buf) - { - struct mtd_concat *concat = CONCAT(mtd); - int err = -EINVAL; -@@ -59,43 +58,43 @@ - - *retlen = 0; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - size_t size, retsize; - -- if (from >= subdev->size) -- { /* Not destined for this subdev */ -- size = 0; -+ if (from >= subdev->size) { -+ /* Not destined for this subdev */ -+ size = 0; - from -= subdev->size; -+ continue; - } -+ if (from + len > subdev->size) -+ /* First part goes into this subdev */ -+ size = subdev->size - from; - else -- { -- if (from + len > subdev->size) -- size = subdev->size - from; /* First part goes into this subdev */ -- else -- size = len; /* Entire transaction goes into this subdev */ -+ /* Entire transaction goes into this subdev */ -+ size = len; - -- err = subdev->read(subdev, from, size, &retsize, buf); -+ err = subdev->read(subdev, from, size, &retsize, buf); - -- if(err) -- break; -+ if (err) -+ break; - -- *retlen += retsize; -- len -= size; -- if(len == 0) -- break; -+ *retlen += retsize; -+ len -= size; -+ if (len == 0) -+ break; - -- err = -EINVAL; -- buf += size; -- from = 0; -- } -+ err = -EINVAL; -+ buf += size; -+ from = 0; - } - return err; - } - --static int concat_write (struct mtd_info *mtd, loff_t to, size_t len, -- size_t *retlen, const u_char *buf) -+static int -+concat_write(struct mtd_info *mtd, loff_t to, size_t len, -+ size_t * retlen, const u_char * buf) - { - struct mtd_concat *concat = CONCAT(mtd); - int err = -EINVAL; -@@ -106,46 +105,44 @@ - - *retlen = 0; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - size_t size, retsize; - -- if (to >= subdev->size) -- { -- size = 0; -+ if (to >= subdev->size) { -+ size = 0; - to -= subdev->size; -+ continue; - } -+ if (to + len > subdev->size) -+ size = subdev->size - to; - else -- { -- if (to + len > subdev->size) -- size = subdev->size - to; -- else -- size = len; -+ size = len; - -- if (!(subdev->flags & MTD_WRITEABLE)) -- err = -EROFS; -- else -- err = subdev->write(subdev, to, size, &retsize, buf); -+ if (!(subdev->flags & MTD_WRITEABLE)) -+ err = -EROFS; -+ else -+ err = subdev->write(subdev, to, size, &retsize, buf); - -- if(err) -- break; -+ if (err) -+ break; - -- *retlen += retsize; -- len -= size; -- if(len == 0) -- break; -+ *retlen += retsize; -+ len -= size; -+ if (len == 0) -+ break; - -- err = -EINVAL; -- buf += size; -- to = 0; -- } -+ err = -EINVAL; -+ buf += size; -+ to = 0; - } - return err; - } - --static int concat_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, -- size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel) -+static int -+concat_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, -+ size_t * retlen, u_char * buf, u_char * eccbuf, -+ struct nand_oobinfo *oobsel) - { - struct mtd_concat *concat = CONCAT(mtd); - int err = -EINVAL; -@@ -153,53 +150,56 @@ - - *retlen = 0; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - size_t size, retsize; -- -- if (from >= subdev->size) -- { /* Not destined for this subdev */ -- size = 0; -+ -+ if (from >= subdev->size) { -+ /* Not destined for this subdev */ -+ size = 0; - from -= subdev->size; -+ continue; - } -+ -+ if (from + len > subdev->size) -+ /* First part goes into this subdev */ -+ size = subdev->size - from; - else -- { -- if (from + len > subdev->size) -- size = subdev->size - from; /* First part goes into this subdev */ -- else -- size = len; /* Entire transaction goes into this subdev */ -- -- if (subdev->read_ecc) -- err = subdev->read_ecc(subdev, from, size, &retsize, buf, eccbuf, oobsel); -- else -- err = -EINVAL; -+ /* Entire transaction goes into this subdev */ -+ size = len; - -- if(err) -- break; -+ if (subdev->read_ecc) -+ err = subdev->read_ecc(subdev, from, size, -+ &retsize, buf, eccbuf, oobsel); -+ else -+ err = -EINVAL; - -- *retlen += retsize; -- len -= size; -- if(len == 0) -- break; -+ if (err) -+ break; - -- err = -EINVAL; -- buf += size; -- if (eccbuf) -- { -- eccbuf += subdev->oobsize; -- /* in nand.c at least, eccbufs are tagged with 2 (int)eccstatus', -- we must account for these */ -- eccbuf += 2 * (sizeof(int)); -- } -- from = 0; -+ *retlen += retsize; -+ len -= size; -+ if (len == 0) -+ break; -+ -+ err = -EINVAL; -+ buf += size; -+ if (eccbuf) { -+ eccbuf += subdev->oobsize; -+ /* in nand.c at least, eccbufs are -+ tagged with 2 (int)eccstatus'; we -+ must account for these */ -+ eccbuf += 2 * (sizeof (int)); - } -+ from = 0; - } - return err; - } - --static int concat_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, -- size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel) -+static int -+concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, -+ size_t * retlen, const u_char * buf, u_char * eccbuf, -+ struct nand_oobinfo *oobsel) - { - struct mtd_concat *concat = CONCAT(mtd); - int err = -EINVAL; -@@ -210,50 +210,48 @@ - - *retlen = 0; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - size_t size, retsize; -- -- if (to >= subdev->size) -- { -- size = 0; -+ -+ if (to >= subdev->size) { -+ size = 0; - to -= subdev->size; -+ continue; - } -+ if (to + len > subdev->size) -+ size = subdev->size - to; - else -- { -- if (to + len > subdev->size) -- size = subdev->size - to; -- else -- size = len; -+ size = len; - -- if (!(subdev->flags & MTD_WRITEABLE)) -- err = -EROFS; -- else if (subdev->write_ecc) -- err = subdev->write_ecc(subdev, to, size, &retsize, buf, eccbuf, oobsel); -- else -- err = -EINVAL; -+ if (!(subdev->flags & MTD_WRITEABLE)) -+ err = -EROFS; -+ else if (subdev->write_ecc) -+ err = subdev->write_ecc(subdev, to, size, -+ &retsize, buf, eccbuf, oobsel); -+ else -+ err = -EINVAL; - -- if(err) -- break; -+ if (err) -+ break; - -- *retlen += retsize; -- len -= size; -- if(len == 0) -- break; -+ *retlen += retsize; -+ len -= size; -+ if (len == 0) -+ break; - -- err = -EINVAL; -- buf += size; -- if (eccbuf) -- eccbuf += subdev->oobsize; -- to = 0; -- } -+ err = -EINVAL; -+ buf += size; -+ if (eccbuf) -+ eccbuf += subdev->oobsize; -+ to = 0; - } - return err; - } - --static int concat_read_oob (struct mtd_info *mtd, loff_t from, size_t len, -- size_t *retlen, u_char *buf) -+static int -+concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len, -+ size_t * retlen, u_char * buf) - { - struct mtd_concat *concat = CONCAT(mtd); - int err = -EINVAL; -@@ -261,46 +259,47 @@ - - *retlen = 0; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - size_t size, retsize; -- -- if (from >= subdev->size) -- { /* Not destined for this subdev */ -- size = 0; -+ -+ if (from >= subdev->size) { -+ /* Not destined for this subdev */ -+ size = 0; - from -= subdev->size; -+ continue; - } -+ if (from + len > subdev->size) -+ /* First part goes into this subdev */ -+ size = subdev->size - from; - else -- { -- if (from + len > subdev->size) -- size = subdev->size - from; /* First part goes into this subdev */ -- else -- size = len; /* Entire transaction goes into this subdev */ -- -- if (subdev->read_oob) -- err = subdev->read_oob(subdev, from, size, &retsize, buf); -- else -- err = -EINVAL; -+ /* Entire transaction goes into this subdev */ -+ size = len; - -- if(err) -- break; -+ if (subdev->read_oob) -+ err = subdev->read_oob(subdev, from, size, -+ &retsize, buf); -+ else -+ err = -EINVAL; - -- *retlen += retsize; -- len -= size; -- if(len == 0) -- break; -+ if (err) -+ break; - -- err = -EINVAL; -- buf += size; -- from = 0; -- } -+ *retlen += retsize; -+ len -= size; -+ if (len == 0) -+ break; -+ -+ err = -EINVAL; -+ buf += size; -+ from = 0; - } - return err; - } - --static int concat_write_oob (struct mtd_info *mtd, loff_t to, size_t len, -- size_t *retlen, const u_char *buf) -+static int -+concat_write_oob(struct mtd_info *mtd, loff_t to, size_t len, -+ size_t * retlen, const u_char * buf) - { - struct mtd_concat *concat = CONCAT(mtd); - int err = -EINVAL; -@@ -311,50 +310,46 @@ - - *retlen = 0; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - size_t size, retsize; -- -- if (to >= subdev->size) -- { -- size = 0; -+ -+ if (to >= subdev->size) { -+ size = 0; - to -= subdev->size; -+ continue; - } -+ if (to + len > subdev->size) -+ size = subdev->size - to; - else -- { -- if (to + len > subdev->size) -- size = subdev->size - to; -- else -- size = len; -+ size = len; - -- if (!(subdev->flags & MTD_WRITEABLE)) -- err = -EROFS; -- else if (subdev->write_oob) -- err = subdev->write_oob(subdev, to, size, &retsize, buf); -- else -- err = -EINVAL; -+ if (!(subdev->flags & MTD_WRITEABLE)) -+ err = -EROFS; -+ else if (subdev->write_oob) -+ err = subdev->write_oob(subdev, to, size, &retsize, -+ buf); -+ else -+ err = -EINVAL; - -- if(err) -- break; -+ if (err) -+ break; - -- *retlen += retsize; -- len -= size; -- if(len == 0) -- break; -+ *retlen += retsize; -+ len -= size; -+ if (len == 0) -+ break; - -- err = -EINVAL; -- buf += size; -- to = 0; -- } -+ err = -EINVAL; -+ buf += size; -+ to = 0; - } - return err; - } - -- --static void concat_erase_callback (struct erase_info *instr) -+static void concat_erase_callback(struct erase_info *instr) - { -- wake_up((wait_queue_head_t *)instr->priv); -+ wake_up((wait_queue_head_t *) instr->priv); - } - - static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase) -@@ -370,18 +365,18 @@ - - erase->mtd = mtd; - erase->callback = concat_erase_callback; -- erase->priv = (unsigned long)&waitq; -- -+ erase->priv = (unsigned long) &waitq; -+ - /* - * FIXME: Allow INTERRUPTIBLE. Which means - * not having the wait_queue head on the stack. - */ - err = mtd->erase(mtd, erase); -- if (!err) -- { -+ if (!err) { - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&waitq, &wait); -- if (erase->state != MTD_ERASE_DONE && erase->state != MTD_ERASE_FAILED) -+ if (erase->state != MTD_ERASE_DONE -+ && erase->state != MTD_ERASE_FAILED) - schedule(); - remove_wait_queue(&waitq, &wait); - set_current_state(TASK_RUNNING); -@@ -391,7 +386,7 @@ - return err; - } - --static int concat_erase (struct mtd_info *mtd, struct erase_info *instr) -+static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) - { - struct mtd_concat *concat = CONCAT(mtd); - struct mtd_info *subdev; -@@ -402,10 +397,10 @@ - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - -- if(instr->addr > concat->mtd.size) -+ if (instr->addr > concat->mtd.size) - return -EINVAL; - -- if(instr->len + instr->addr > concat->mtd.size) -+ if (instr->len + instr->addr > concat->mtd.size) - return -EINVAL; - - /* -@@ -414,23 +409,22 @@ - * region info rather than looking at each particular sub-device - * in turn. - */ -- if (!concat->mtd.numeraseregions) -- { /* the easy case: device has uniform erase block size */ -- if(instr->addr & (concat->mtd.erasesize - 1)) -+ if (!concat->mtd.numeraseregions) { -+ /* the easy case: device has uniform erase block size */ -+ if (instr->addr & (concat->mtd.erasesize - 1)) - return -EINVAL; -- if(instr->len & (concat->mtd.erasesize - 1)) -+ if (instr->len & (concat->mtd.erasesize - 1)) - return -EINVAL; -- } -- else -- { /* device has variable erase size */ -- struct mtd_erase_region_info *erase_regions = concat->mtd.eraseregions; -+ } else { -+ /* device has variable erase size */ -+ struct mtd_erase_region_info *erase_regions = -+ concat->mtd.eraseregions; - - /* - * Find the erase region where the to-be-erased area begins: - */ -- for(i = 0; i < concat->mtd.numeraseregions && -- instr->addr >= erase_regions[i].offset; i++) -- ; -+ for (i = 0; i < concat->mtd.numeraseregions && -+ instr->addr >= erase_regions[i].offset; i++) ; - --i; - - /* -@@ -438,25 +432,26 @@ - * to-be-erased area begins. Verify that the starting - * offset is aligned to this region's erase size: - */ -- if (instr->addr & (erase_regions[i].erasesize-1)) -+ if (instr->addr & (erase_regions[i].erasesize - 1)) - return -EINVAL; - - /* - * now find the erase region where the to-be-erased area ends: - */ -- for(; i < concat->mtd.numeraseregions && -- (instr->addr + instr->len) >= erase_regions[i].offset ; ++i) -- ; -+ for (; i < concat->mtd.numeraseregions && -+ (instr->addr + instr->len) >= erase_regions[i].offset; -+ ++i) ; - --i; - /* - * check if the ending offset is aligned to this region's erase size - */ -- if ((instr->addr + instr->len) & (erase_regions[i].erasesize-1)) -+ if ((instr->addr + instr->len) & (erase_regions[i].erasesize - -+ 1)) - return -EINVAL; - } - - /* make a local copy of instr to avoid modifying the caller's struct */ -- erase = kmalloc(sizeof(struct erase_info),GFP_KERNEL); -+ erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL); - - if (!erase) - return -ENOMEM; -@@ -468,39 +463,40 @@ - * find the subdevice where the to-be-erased area begins, adjust - * starting offset to be relative to the subdevice start - */ -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - subdev = concat->subdev[i]; -- if(subdev->size <= erase->addr) -+ if (subdev->size <= erase->addr) - erase->addr -= subdev->size; - else - break; -- } -- if(i >= concat->num_subdev) /* must never happen since size */ -- BUG(); /* limit has been verified above */ -+ } -+ -+ /* must never happen since size limit has been verified above */ -+ if (i >= concat->num_subdev) -+ BUG(); - - /* now do the erase: */ - err = 0; -- for(;length > 0; i++) /* loop for all subevices affected by this request */ -- { -- subdev = concat->subdev[i]; /* get current subdevice */ -+ for (; length > 0; i++) { -+ /* loop for all subdevices affected by this request */ -+ subdev = concat->subdev[i]; /* get current subdevice */ - - /* limit length to subdevice's size: */ -- if(erase->addr + length > subdev->size) -+ if (erase->addr + length > subdev->size) - erase->len = subdev->size - erase->addr; - else - erase->len = length; - -- if (!(subdev->flags & MTD_WRITEABLE)) -- { -+ if (!(subdev->flags & MTD_WRITEABLE)) { - err = -EROFS; - break; - } - length -= erase->len; -- if ((err = concat_dev_erase(subdev, erase))) -- { -- if(err == -EINVAL) /* sanity check: must never happen since */ -- BUG(); /* block alignment has been checked above */ -+ if ((err = concat_dev_erase(subdev, erase))) { -+ /* sanity check: should never happen since -+ * block alignment has been checked above */ -+ if (err == -EINVAL) -+ BUG(); - break; - } - /* -@@ -523,85 +519,79 @@ - return 0; - } - --static int concat_lock (struct mtd_info *mtd, loff_t ofs, size_t len) -+static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len) - { - struct mtd_concat *concat = CONCAT(mtd); - int i, err = -EINVAL; - -- if ((len + ofs) > mtd->size) -+ if ((len + ofs) > mtd->size) - return -EINVAL; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - size_t size; - -- if (ofs >= subdev->size) -- { -- size = 0; -+ if (ofs >= subdev->size) { -+ size = 0; - ofs -= subdev->size; -+ continue; - } -+ if (ofs + len > subdev->size) -+ size = subdev->size - ofs; - else -- { -- if (ofs + len > subdev->size) -- size = subdev->size - ofs; -- else -- size = len; -+ size = len; - -- err = subdev->lock(subdev, ofs, size); -+ err = subdev->lock(subdev, ofs, size); - -- if(err) -- break; -+ if (err) -+ break; - -- len -= size; -- if(len == 0) -- break; -+ len -= size; -+ if (len == 0) -+ break; - -- err = -EINVAL; -- ofs = 0; -- } -+ err = -EINVAL; -+ ofs = 0; - } -+ - return err; - } - --static int concat_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) -+static int concat_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) - { - struct mtd_concat *concat = CONCAT(mtd); - int i, err = 0; - -- if ((len + ofs) > mtd->size) -+ if ((len + ofs) > mtd->size) - return -EINVAL; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - size_t size; - -- if (ofs >= subdev->size) -- { -- size = 0; -+ if (ofs >= subdev->size) { -+ size = 0; - ofs -= subdev->size; -+ continue; - } -+ if (ofs + len > subdev->size) -+ size = subdev->size - ofs; - else -- { -- if (ofs + len > subdev->size) -- size = subdev->size - ofs; -- else -- size = len; -+ size = len; - -- err = subdev->unlock(subdev, ofs, size); -+ err = subdev->unlock(subdev, ofs, size); - -- if(err) -- break; -+ if (err) -+ break; - -- len -= size; -- if(len == 0) -- break; -+ len -= size; -+ if (len == 0) -+ break; - -- err = -EINVAL; -- ofs = 0; -- } -+ err = -EINVAL; -+ ofs = 0; - } -+ - return err; - } - -@@ -610,8 +600,7 @@ - struct mtd_concat *concat = CONCAT(mtd); - int i; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - subdev->sync(subdev); - } -@@ -622,10 +611,9 @@ - struct mtd_concat *concat = CONCAT(mtd); - int i, rc = 0; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; -- if((rc = subdev->suspend(subdev)) < 0) -+ if ((rc = subdev->suspend(subdev)) < 0) - return rc; - } - return rc; -@@ -636,8 +624,7 @@ - struct mtd_concat *concat = CONCAT(mtd); - int i; - -- for(i = 0; i < concat->num_subdev; i++) -- { -+ for (i = 0; i < concat->num_subdev; i++) { - struct mtd_info *subdev = concat->subdev[i]; - subdev->resume(subdev); - } -@@ -649,11 +636,10 @@ - * stored to *new_dev upon success. This function does _not_ - * register any devices: this is the caller's responsibility. - */ --struct mtd_info *mtd_concat_create( -- struct mtd_info *subdev[], /* subdevices to concatenate */ -- int num_devs, /* number of subdevices */ -- char *name) /* name for the new device */ --{ -+struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to concatenate */ -+ int num_devs, /* number of subdevices */ -+ char *name) -+{ /* name for the new device */ - int i; - size_t size; - struct mtd_concat *concat; -@@ -661,94 +647,103 @@ - int num_erase_region; - - printk(KERN_NOTICE "Concatenating MTD devices:\n"); -- for(i = 0; i < num_devs; i++) -+ for (i = 0; i < num_devs; i++) - printk(KERN_NOTICE "(%d): \"%s\"\n", i, subdev[i]->name); - printk(KERN_NOTICE "into device \"%s\"\n", name); - - /* allocate the device structure */ - size = SIZEOF_STRUCT_MTD_CONCAT(num_devs); -- concat = kmalloc (size, GFP_KERNEL); -- if(!concat) -- { -- printk ("memory allocation error while creating concatenated device \"%s\"\n", -- name); -- return NULL; -+ concat = kmalloc(size, GFP_KERNEL); -+ if (!concat) { -+ printk -+ ("memory allocation error while creating concatenated device \"%s\"\n", -+ name); -+ return NULL; - } - memset(concat, 0, size); -- concat->subdev = (struct mtd_info **)(concat + 1); -+ concat->subdev = (struct mtd_info **) (concat + 1); - - /* - * Set up the new "super" device's MTD object structure, check for - * incompatibilites between the subdevices. - */ -- concat->mtd.type = subdev[0]->type; -- concat->mtd.flags = subdev[0]->flags; -- concat->mtd.size = subdev[0]->size; -+ concat->mtd.type = subdev[0]->type; -+ concat->mtd.flags = subdev[0]->flags; -+ concat->mtd.size = subdev[0]->size; - concat->mtd.erasesize = subdev[0]->erasesize; -- concat->mtd.oobblock = subdev[0]->oobblock; -- concat->mtd.oobsize = subdev[0]->oobsize; -- concat->mtd.ecctype = subdev[0]->ecctype; -- concat->mtd.eccsize = subdev[0]->eccsize; -+ concat->mtd.oobblock = subdev[0]->oobblock; -+ concat->mtd.oobsize = subdev[0]->oobsize; -+ concat->mtd.ecctype = subdev[0]->ecctype; -+ concat->mtd.eccsize = subdev[0]->eccsize; -+ if (subdev[0]->read_ecc) -+ concat->mtd.read_ecc = concat_read_ecc; -+ if (subdev[0]->write_ecc) -+ concat->mtd.write_ecc = concat_write_ecc; -+ if (subdev[0]->read_oob) -+ concat->mtd.read_oob = concat_read_oob; -+ if (subdev[0]->write_oob) -+ concat->mtd.write_oob = concat_write_oob; - -- concat->subdev[0] = subdev[0]; -+ concat->subdev[0] = subdev[0]; - -- for(i = 1; i < num_devs; i++) -- { -- if(concat->mtd.type != subdev[i]->type) -- { -+ for (i = 1; i < num_devs; i++) { -+ if (concat->mtd.type != subdev[i]->type) { - kfree(concat); -- printk ("Incompatible device type on \"%s\"\n", subdev[i]->name); -+ printk("Incompatible device type on \"%s\"\n", -+ subdev[i]->name); - return NULL; - } -- if(concat->mtd.flags != subdev[i]->flags) -- { /* -- * Expect all flags except MTD_WRITEABLE to be equal on -- * all subdevices. -+ if (concat->mtd.flags != subdev[i]->flags) { -+ /* -+ * Expect all flags except MTD_WRITEABLE to be -+ * equal on all subdevices. - */ -- if((concat->mtd.flags ^ subdev[i]->flags) & ~MTD_WRITEABLE) -- { -+ if ((concat->mtd.flags ^ subdev[i]-> -+ flags) & ~MTD_WRITEABLE) { - kfree(concat); -- printk ("Incompatible device flags on \"%s\"\n", subdev[i]->name); -+ printk("Incompatible device flags on \"%s\"\n", -+ subdev[i]->name); - return NULL; -- } -- else /* if writeable attribute differs, make super device writeable */ -- concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE; -+ } else -+ /* if writeable attribute differs, -+ make super device writeable */ -+ concat->mtd.flags |= -+ subdev[i]->flags & MTD_WRITEABLE; - } - concat->mtd.size += subdev[i]->size; -- if(concat->mtd.oobblock != subdev[i]->oobblock || -- concat->mtd.oobsize != subdev[i]->oobsize || -- concat->mtd.ecctype != subdev[i]->ecctype || -- concat->mtd.eccsize != subdev[i]->eccsize) -- { -+ if (concat->mtd.oobblock != subdev[i]->oobblock || -+ concat->mtd.oobsize != subdev[i]->oobsize || -+ concat->mtd.ecctype != subdev[i]->ecctype || -+ concat->mtd.eccsize != subdev[i]->eccsize || -+ !concat->mtd.read_ecc != !subdev[i]->read_ecc || -+ !concat->mtd.write_ecc != !subdev[i]->write_ecc || -+ !concat->mtd.read_oob != !subdev[i]->read_oob || -+ !concat->mtd.write_oob != !subdev[i]->write_oob) { - kfree(concat); -- printk ("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name); -+ printk("Incompatible OOB or ECC data on \"%s\"\n", -+ subdev[i]->name); - return NULL; - } - concat->subdev[i] = subdev[i]; -- -+ - } - -- concat->num_subdev = num_devs; -- concat->mtd.name = name; -+ concat->num_subdev = num_devs; -+ concat->mtd.name = name; - - /* - * NOTE: for now, we do not provide any readv()/writev() methods - * because they are messy to implement and they are not - * used to a great extent anyway. - */ -- concat->mtd.erase = concat_erase; -- concat->mtd.read = concat_read; -- concat->mtd.write = concat_write; -- concat->mtd.read_ecc = concat_read_ecc; -- concat->mtd.write_ecc = concat_write_ecc; -- concat->mtd.read_oob = concat_read_oob; -- concat->mtd.write_oob = concat_write_oob; -- concat->mtd.sync = concat_sync; -- concat->mtd.lock = concat_lock; -- concat->mtd.unlock = concat_unlock; -- concat->mtd.suspend = concat_suspend; -- concat->mtd.resume = concat_resume; -- -+ concat->mtd.erase = concat_erase; -+ concat->mtd.read = concat_read; -+ concat->mtd.write = concat_write; -+ concat->mtd.sync = concat_sync; -+ concat->mtd.lock = concat_lock; -+ concat->mtd.unlock = concat_unlock; -+ concat->mtd.suspend = concat_suspend; -+ concat->mtd.resume = concat_resume; - - /* - * Combine the erase block size info of the subdevices: -@@ -758,44 +753,44 @@ - */ - max_erasesize = curr_erasesize = subdev[0]->erasesize; - num_erase_region = 1; -- for(i = 0; i < num_devs; i++) -- { -- if(subdev[i]->numeraseregions == 0) -- { /* current subdevice has uniform erase size */ -- if(subdev[i]->erasesize != curr_erasesize) -- { /* if it differs from the last subdevice's erase size, count it */ -+ for (i = 0; i < num_devs; i++) { -+ if (subdev[i]->numeraseregions == 0) { -+ /* current subdevice has uniform erase size */ -+ if (subdev[i]->erasesize != curr_erasesize) { -+ /* if it differs from the last subdevice's erase size, count it */ - ++num_erase_region; - curr_erasesize = subdev[i]->erasesize; -- if(curr_erasesize > max_erasesize) -+ if (curr_erasesize > max_erasesize) - max_erasesize = curr_erasesize; - } -- } -- else -- { /* current subdevice has variable erase size */ -+ } else { -+ /* current subdevice has variable erase size */ - int j; -- for(j = 0; j < subdev[i]->numeraseregions; j++) -- { /* walk the list of erase regions, count any changes */ -- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize) -- { -+ for (j = 0; j < subdev[i]->numeraseregions; j++) { -+ -+ /* walk the list of erase regions, count any changes */ -+ if (subdev[i]->eraseregions[j].erasesize != -+ curr_erasesize) { - ++num_erase_region; -- curr_erasesize = subdev[i]->eraseregions[j].erasesize; -- if(curr_erasesize > max_erasesize) -+ curr_erasesize = -+ subdev[i]->eraseregions[j]. -+ erasesize; -+ if (curr_erasesize > max_erasesize) - max_erasesize = curr_erasesize; - } - } - } - } - -- if(num_erase_region == 1) -- { /* -+ if (num_erase_region == 1) { -+ /* - * All subdevices have the same uniform erase size. - * This is easy: - */ - concat->mtd.erasesize = curr_erasesize; - concat->mtd.numeraseregions = 0; -- } -- else -- { /* -+ } else { -+ /* - * erase block size varies across the subdevices: allocate - * space to store the data describing the variable erase regions - */ -@@ -804,13 +799,14 @@ - - concat->mtd.erasesize = max_erasesize; - concat->mtd.numeraseregions = num_erase_region; -- concat->mtd.eraseregions = erase_region_p = kmalloc ( -- num_erase_region * sizeof(struct mtd_erase_region_info), GFP_KERNEL); -- if(!erase_region_p) -- { -+ concat->mtd.eraseregions = erase_region_p = -+ kmalloc(num_erase_region * -+ sizeof (struct mtd_erase_region_info), GFP_KERNEL); -+ if (!erase_region_p) { - kfree(concat); -- printk ("memory allocation error while creating erase region list" -- " for device \"%s\"\n", name); -+ printk -+ ("memory allocation error while creating erase region list" -+ " for device \"%s\"\n", name); - return NULL; - } - -@@ -820,46 +816,53 @@ - */ - curr_erasesize = subdev[0]->erasesize; - begin = position = 0; -- for(i = 0; i < num_devs; i++) -- { -- if(subdev[i]->numeraseregions == 0) -- { /* current subdevice has uniform erase size */ -- if(subdev[i]->erasesize != curr_erasesize) -- { /* -+ for (i = 0; i < num_devs; i++) { -+ if (subdev[i]->numeraseregions == 0) { -+ /* current subdevice has uniform erase size */ -+ if (subdev[i]->erasesize != curr_erasesize) { -+ /* - * fill in an mtd_erase_region_info structure for the area - * we have walked so far: - */ -- erase_region_p->offset = begin; -- erase_region_p->erasesize = curr_erasesize; -- erase_region_p->numblocks = (position - begin) / curr_erasesize; -+ erase_region_p->offset = begin; -+ erase_region_p->erasesize = -+ curr_erasesize; -+ erase_region_p->numblocks = -+ (position - begin) / curr_erasesize; - begin = position; - - curr_erasesize = subdev[i]->erasesize; - ++erase_region_p; - } - position += subdev[i]->size; -- } -- else -- { /* current subdevice has variable erase size */ -+ } else { -+ /* current subdevice has variable erase size */ - int j; -- for(j = 0; j < subdev[i]->numeraseregions; j++) -- { /* walk the list of erase regions, count any changes */ -- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize) -- { -- erase_region_p->offset = begin; -- erase_region_p->erasesize = curr_erasesize; -- erase_region_p->numblocks = (position - begin) / curr_erasesize; -+ for (j = 0; j < subdev[i]->numeraseregions; j++) { -+ /* walk the list of erase regions, count any changes */ -+ if (subdev[i]->eraseregions[j]. -+ erasesize != curr_erasesize) { -+ erase_region_p->offset = begin; -+ erase_region_p->erasesize = -+ curr_erasesize; -+ erase_region_p->numblocks = -+ (position - -+ begin) / curr_erasesize; - begin = position; - -- curr_erasesize = subdev[i]->eraseregions[j].erasesize; -+ curr_erasesize = -+ subdev[i]->eraseregions[j]. -+ erasesize; - ++erase_region_p; - } -- position += subdev[i]->eraseregions[j].numblocks * curr_erasesize; -+ position += -+ subdev[i]->eraseregions[j]. -+ numblocks * curr_erasesize; - } - } - } - /* Now write the final entry */ -- erase_region_p->offset = begin; -+ erase_region_p->offset = begin; - erase_region_p->erasesize = curr_erasesize; - erase_region_p->numblocks = (position - begin) / curr_erasesize; - } -@@ -874,16 +877,14 @@ - void mtd_concat_destroy(struct mtd_info *mtd) - { - struct mtd_concat *concat = CONCAT(mtd); -- if(concat->mtd.numeraseregions) -+ if (concat->mtd.numeraseregions) - kfree(concat->mtd.eraseregions); - kfree(concat); - } - -- - EXPORT_SYMBOL(mtd_concat_create); - EXPORT_SYMBOL(mtd_concat_destroy); - -- - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Robert Kaiser "); - MODULE_DESCRIPTION("Generic support for concatenating of MTD devices"); ---- linux-2.6.5/drivers/mtd/maps/Makefile~heh 2004-04-03 22:36:12.000000000 -0500 -+++ linux-2.6.5/drivers/mtd/maps/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -17,12 +17,14 @@ - obj-$(CONFIG_MTD_ELAN_104NC) += elan-104nc.o - obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o - obj-$(CONFIG_MTD_IQ80310) += iq80310.o -+obj-$(CONFIG_MTD_IQ80321) += iq80321.o - obj-$(CONFIG_MTD_L440GX) += l440gx.o - obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o - obj-$(CONFIG_MTD_ICH2ROM) += ich2rom.o - obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o - obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o - obj-$(CONFIG_MTD_MBX860) += mbx860.o -+obj-$(CONFIG_MTD_NORA) += nora.o - obj-$(CONFIG_MTD_CEIVA) += ceiva.o - obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o - obj-$(CONFIG_MTD_PHYSMAP) += physmap.o ---- linux-2.6.5/drivers/mtd/maps/sa1100-flash.c~heh 2004-04-03 22:36:51.000000000 -0500 -+++ linux-2.6.5/drivers/mtd/maps/sa1100-flash.c 2004-04-30 20:57:36.000000000 -0400 -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -887,6 +888,7 @@ - int width; - void *vbase; - void (*set_vpp)(struct map_info *, int); -+ char name[16]; - struct map_info *map; - struct mtd_info *mtd; - struct resource *res; -@@ -925,6 +927,8 @@ - } - - sa[i].map = maps + i; -+ sa[i].map->name = sa[i].name; -+ sprintf(sa[i].name, "sa1100-%d", i); - - sa[i].vbase = ioremap(sa[i].base, sa[i].size); - if (!sa[i].vbase) { -@@ -986,7 +990,7 @@ - */ - #ifdef CONFIG_MTD_CONCAT - *rmtd = mtd_concat_create(subdev, found, -- "sa1100 flash"); -+ "sa1100"); - if (*rmtd == NULL) - ret = -ENXIO; - #else -@@ -1044,13 +1048,9 @@ - * - Is the MSC setup for flash (no -> failure) - * - Probe for flash - */ -- --static struct map_info sa1100_probe_map __initdata = { -- .name = "SA1100-flash", --}; -- --static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys) -+static void sa1100_probe_one_cs(unsigned int msc, unsigned long phys) - { -+ struct map_info map; - struct mtd_info *mtd; - - printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ", -@@ -1066,19 +1066,23 @@ - return; - } - -- sa1100_probe_map.buswidth = msc & MSC_RBW ? 2 : 4; -- sa1100_probe_map.size = SZ_1M; -- sa1100_probe_map.phys = phys; -- sa1100_probe_map.virt = (unsigned long)ioremap(phys, SZ_1M); -- if (sa1100_probe_map.virt == 0) -+ memset(&map, 0, sizeof(map)); -+ -+ map.name = "Probe"; -+ map.buswidth = msc & MSC_RBW ? 2 : 4; -+ map.size = SZ_1M; -+ map.phys = NO_XIP; -+ map.virt = (unsigned long)ioremap(phys, SZ_1M); -+ if (map.virt == 0) - goto fail; -- simple_map_init(&sa1100_probe_map); -+ -+ simple_map_init(&map); - - /* Shame cfi_probe blurts out kernel messages... */ -- mtd = do_map_probe("cfi_probe", &sa1100_probe_map); -+ mtd = do_map_probe("cfi_probe", &map); - if (mtd) - map_destroy(mtd); -- iounmap((void *)sa1100_probe_map.virt); -+ iounmap((void *)map.virt); - - if (!mtd) - goto fail; -@@ -1090,7 +1094,7 @@ - printk("failed\n"); - } - --static void __init sa1100_probe_flash(void) -+static void sa1100_probe_flash(void) - { - printk(KERN_INFO "-- SA11xx Flash probe. Please report results.\n"); - sa1100_probe_one_cs(MSC0, SA1100_CS0_PHYS); -@@ -1321,10 +1325,9 @@ - kfree(parsed_parts); - } - --static struct mtd_info *mymtd; -- --static int __init sa1100_mtd_init(void) -+static int __init sa1100_mtd_probe(struct device *dev) - { -+ struct mtd_info *mtd; - int ret; - int nr; - -@@ -1332,21 +1335,74 @@ - if (nr < 0) - return nr; - -- ret = sa1100_setup_mtd(info, nr, &mymtd); -- if (ret == 0) -- sa1100_locate_partitions(mymtd); -+ ret = sa1100_setup_mtd(info, nr, &mtd); -+ if (ret == 0) { -+ sa1100_locate_partitions(mtd); -+ dev_set_drvdata(dev, mtd); -+ } - - return ret; - } - --static void __exit sa1100_mtd_cleanup(void) -+static int __exit sa1100_mtd_remove(struct device *dev) - { -- sa1100_destroy_mtd(info, mymtd); -+ struct mtd_info *mtd = dev_get_drvdata(dev); -+ sa1100_destroy_mtd(info, mtd); - sa1100_destroy_partitions(); -+ return 0; -+} -+ -+static int sa1100_mtd_suspend(struct device *dev, u32 level, u32 state) -+{ -+ struct mtd_info *mtd = dev_get_drvdata(dev); -+ if (level == SUSPEND_SAVE_STATE) -+ mtd->suspend(mtd); -+ return 0; -+} -+ -+static int sa1100_mtd_resume(struct device *dev, u32 level) -+{ -+ struct mtd_info *mtd = dev_get_drvdata(dev); -+ if (level == RESUME_RESTORE_STATE) -+ mtd->resume(mtd); -+ return 0; -+} -+ -+static struct platform_device sa1100_mtd_device = { -+ .name = "flash", -+ .id = 0, -+}; -+ -+static struct device_driver sa1100_mtd_driver = { -+ .name = "flash", -+ .bus = &platform_bus_type, -+ .probe = sa1100_mtd_probe, -+#ifdef MODULE -+ .remove = sa1100_mtd_remove, -+#endif -+ .suspend = sa1100_mtd_suspend, -+ .resume = sa1100_mtd_resume, -+}; -+ -+static int __init sa1100_mtd_init(void) -+{ -+ int ret = driver_register(&sa1100_mtd_driver); -+ if (ret == 0) { -+ ret = platform_device_register(&sa1100_mtd_device); -+ if (ret) -+ driver_unregister(&sa1100_mtd_driver); -+ } -+ return ret; -+} -+ -+static void __exit sa1100_mtd_exit(void) -+{ -+ platform_device_unregister(&sa1100_mtd_device); -+ driver_unregister(&sa1100_mtd_driver); - } - - module_init(sa1100_mtd_init); --module_exit(sa1100_mtd_cleanup); -+module_exit(sa1100_mtd_exit); - - MODULE_AUTHOR("Nicolas Pitre"); - MODULE_DESCRIPTION("SA1100 CFI map driver"); ---- linux-2.6.5/drivers/mtd/maps/pcmciamtd.c~heh 2004-04-03 22:36:19.000000000 -0500 -+++ linux-2.6.5/drivers/mtd/maps/pcmciamtd.c 2004-04-30 20:57:36.000000000 -0400 -@@ -25,10 +25,9 @@ - #include - - #include --#include - --#ifdef CONFIG_MTD_DEBUG --static int debug = CONFIG_MTD_DEBUG_VERBOSE; -+#if 1 //def CONFIG_MTD_DEBUG -+static int debug = 5; //CONFIG_MTD_DEBUG_VERBOSE; - MODULE_PARM(debug, "i"); - MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy"); - #undef DEBUG -@@ -88,7 +87,7 @@ - static int setvpp; - - /* Force card to be treated as FLASH, ROM or RAM */ --static int mem_type; -+static int mem_type = 1; - - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Simon Evans "); ---- linux-2.6.5/drivers/mtd/maps/pci.c~heh 2004-04-03 22:36:56.000000000 -0500 -+++ linux-2.6.5/drivers/mtd/maps/pci.c 2004-04-30 20:57:36.000000000 -0400 -@@ -22,6 +22,8 @@ - #include - #include - -+#include -+ - struct map_pci_info; - - struct mtd_pci_info { ---- linux-2.6.5/drivers/input/Kconfig~heh 2004-04-03 22:36:18.000000000 -0500 -+++ linux-2.6.5/drivers/input/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -80,7 +80,7 @@ - module will be called joydev. - - config INPUT_TSDEV -- tristate "Touchscreen interface" -+ tristate "Compaq Touchscreen interface" - depends on INPUT - ---help--- - Say Y here if you have an application that only can understand the -@@ -102,6 +102,10 @@ - depends on INPUT_TSDEV - default "320" - -+config INPUT_TSLIBDEV -+ tristate "TSLIB Touchscreen interface" -+ depends on INPUT -+ - config INPUT_EVDEV - tristate "Event interface" - depends on INPUT ---- linux-2.6.5/drivers/input/serio/Kconfig~heh 2004-04-03 22:37:07.000000000 -0500 -+++ linux-2.6.5/drivers/input/serio/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -80,7 +80,7 @@ - - config SERIO_RPCKBD - tristate "Acorn RiscPC keyboard controller" -- depends on ARCH_ACORN && SERIO -+ depends on (ARCH_ACORN || ARCH_CLPS7500) && SERIO - default y - help - Say Y here if you have the Acorn RiscPC and want to use an AT -@@ -89,6 +89,18 @@ - To compile this driver as a module, choose M here: the - module will be called rpckbd. - -+config SERIO_CLPS7500 -+ tristate "CLPS7500 PS/2 mouse port controller" -+ depends on ARCH_CLPS7500 && SERIO -+ help -+ Say Y here if you have CLPS7500 based hardware and want to use -+ the mouse port. -+ -+ This driver is also available as a module ( = code which can be -+ inserted in and removed from the running kernel whenever you want). -+ The module will be called clps7500ps2. If you want to compile it -+ as a module, say M here and read . -+ - config SERIO_AMBAKMI - tristate "AMBA KMI keyboard controller" - depends on ARCH_INTEGRATOR && SERIO ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/input/serio/sa1100ir.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,90 @@ -+/* -+ * linux/drivers/input/serio/sa1100ir.c -+ * -+ * 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. -+ */ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+ -+ -+struct sa1100_kbd { -+ struct serio io; -+ void *base; -+ int irq; -+}; -+ -+static void sa1100ir_int(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ struct sa1100_kbd *kbd = dev_id; -+ unsigned int status; -+ -+ do { -+ unsigned int flag, data; -+ -+ status = readl(kbd->base + UTSR1); -+ if (!(status & UTSR1_RNE)) -+ break; -+ -+ flag = (status & UTSR1_FRE ? SERIO_FRAME : 0) | -+ (status & UTSR1_PRE ? SERIO_PARITY : 0); -+ -+ data = readl(kbd->base + UTDR); -+ -+ serio_interrupt(&kbd->io, data, flag); -+ } while (1); -+ -+ status = readl(kbd->base + UTSR0) & UTSR0_RID | UTSR0_RBB | UTSR0_REB; -+ if (status) -+ writel(status, kbd->base + UTSR0); -+} -+ -+static int sa1100ir_kbd_open(struct serio *io) -+{ -+ struct sa1100_kbd *kbd = io->driver; -+ int ret; -+ -+ ret = request_irq(kbd->irq, sa1100ir_int, 0, kbd->io.phys, kbd); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static void sa1100ir_kbd_close(struct serio *io) -+{ -+ struct sa1100_kbd *kbd = io->driver; -+ -+ free_irq(kbd->irq, kbd); -+} -+ -+static struct sa1100_kbd sa1100_kbd = { -+ .io = { -+ .type = 0, -+ .open = sa1100ir_kbd_open, -+ .close = sa1100ir_kbd_close, -+ .name = "SA11x0 IR port", -+ .phys = "sa11x0/ir", -+ .driver = &sa1100_kbd, -+ }, -+}; -+ -+static int __init sa1100_kbd_init(void) -+{ -+ serio_register_port(&sa1100_kbd.io); -+} -+ -+static void __exit sa1100_kbd_exit(void) -+{ -+ serio_unregister_port(&sa1100_kbd.io); -+} -+ -+module_init(sa1100_kbd_init); -+module_exit(sa1100_kbd_exit); ---- linux-2.6.5/drivers/input/serio/Makefile~heh 2004-04-03 22:36:16.000000000 -0500 -+++ linux-2.6.5/drivers/input/serio/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -10,6 +10,7 @@ - obj-$(CONFIG_SERIO_SERPORT) += serport.o - obj-$(CONFIG_SERIO_CT82C710) += ct82c710.o - obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o -+obj-$(CONFIG_SERIO_CLPS7500) += clps7500ps2.o - obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o - obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o - obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/input/tslibdev.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,358 @@ -+/* -+ * linux/drivers/input/tslibdev.c -+ * -+ * Copyright (C) 2002 Russell King -+ * -+ * From tsdev.c: -+ * -+ * Copyright (c) 2001 "Crazy" james Simmons -+ * -+ * Input driver to Touchscreen device driver module. -+ * -+ * Sponsored by Transvirtual Technology -+ */ -+ -+/* -+ * 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 -+ * -+ * Should you need to contact me, the author, you can do so either by -+ * e-mail - mail your message to . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct ucb1x00_dev { -+ int exist; -+ char name[16]; -+ wait_queue_head_t wait; -+ struct list_head list; -+ struct input_handle handle; -+ int x; -+ int y; -+ int pressure; -+}; -+ -+struct ts_event { -+ u16 pressure; -+ u16 x; -+ u16 y; -+ u16 pad; -+ struct timeval stamp; -+}; -+ -+#define TSDEV_BUFFER_SIZE 64 -+ -+struct ucb1x00_list { -+ struct list_head list; -+ struct fasync_struct *fasync; -+ struct ucb1x00_dev *tsdev; -+ unsigned int head; -+ unsigned int tail; -+ struct ts_event event[TSDEV_BUFFER_SIZE]; -+}; -+ -+static struct input_handler ucb1x00_handler; -+static struct ucb1x00_dev *ucb1x00_dev; -+ -+static void ucb1x00_remove(struct ucb1x00_dev *tsdev); -+ -+ -+static int ucb1x00_fasync(int fd, struct file *file, int on) -+{ -+ struct ucb1x00_list *list = file->private_data; -+ int retval; -+ -+ retval = fasync_helper(fd, file, on, &list->fasync); -+ return retval < 0 ? retval : 0; -+} -+ -+static int ucb1x00_open(struct inode *inode, struct file *file) -+{ -+ struct ucb1x00_list *list; -+ int empty; -+ -+ if (!ucb1x00_dev || !ucb1x00_dev->exist) -+ return -ENODEV; -+ -+ printk(KERN_WARNING -+ "tslibdev: process %s (%d) uses obsolete tslib device\n", -+ current->comm, current->pid); -+ -+ list = kmalloc(sizeof(struct ucb1x00_list), GFP_KERNEL); -+ if (!list) -+ return -ENOMEM; -+ -+ memset(list, 0, sizeof(struct ucb1x00_list)); -+ -+ empty = list_empty(&ucb1x00_dev->list); -+ -+ list->tsdev = ucb1x00_dev; -+ list_add(&list->list, &list->tsdev->list); -+ -+ file->private_data = list; -+ -+ if (empty && list->tsdev->exist) -+ input_open_device(&list->tsdev->handle); -+ -+ return 0; -+} -+ -+static int ucb1x00_release(struct inode *inode, struct file *file) -+{ -+ struct ucb1x00_list *list = file->private_data; -+ -+ ucb1x00_fasync(-1, file, 0); -+ -+ list_del(&list->list); -+ -+ ucb1x00_remove(list->tsdev); -+ -+ kfree(list); -+ -+ return 0; -+} -+ -+static ssize_t -+ucb1x00_read(struct file *file, char *buffer, size_t count, loff_t * ppos) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ struct ucb1x00_list *list = file->private_data; -+ int retval = 0; -+ -+ if (list->head == list->tail) { -+ add_wait_queue(&list->tsdev->wait, &wait); -+ -+ while (list->head == list->tail) { -+ set_current_state(TASK_INTERRUPTIBLE); -+ -+ if (!list->tsdev->exist) { -+ retval = -ENODEV; -+ break; -+ } -+ if (file->f_flags & O_NONBLOCK) { -+ retval = -EAGAIN; -+ break; -+ } -+ if (signal_pending(current)) { -+ retval = -ERESTARTSYS; -+ break; -+ } -+ schedule(); -+ } -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&list->tsdev->wait, &wait); -+ } -+ -+ if (retval) -+ return retval; -+ -+ while (list->head != list->tail && count >= sizeof(struct ts_event)) { -+ if (copy_to_user(buffer, list->event + list->tail, -+ sizeof(struct ts_event))) -+ return retval ? retval : -EFAULT; -+ list->tail = (list->tail + 1) & (TSDEV_BUFFER_SIZE - 1); -+ retval += sizeof(struct ts_event); -+ buffer += sizeof(struct ts_event); -+ count -= sizeof(struct ts_event); -+ } -+ return retval; -+} -+ -+/* No kernel lock - fine */ -+static unsigned int ucb1x00_poll(struct file *file, poll_table * wait) -+{ -+ struct ucb1x00_list *list = file->private_data; -+ -+ poll_wait(file, &list->tsdev->wait, wait); -+ if (list->head != list->tail || !list->tsdev->exist) -+ return POLLIN | POLLRDNORM; -+ return 0; -+} -+ -+static int -+ucb1x00_ioctl(struct inode *inode, struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ return -EINVAL; -+} -+ -+struct file_operations ucb1x00_fops = { -+ .owner = THIS_MODULE, -+ .open = ucb1x00_open, -+ .release = ucb1x00_release, -+ .read = ucb1x00_read, -+ .poll = ucb1x00_poll, -+ .fasync = ucb1x00_fasync, -+ .ioctl = ucb1x00_ioctl, -+}; -+ -+/* -+ * The official UCB1x00 touchscreen is a miscdevice: -+ * 10 char Non-serial mice, misc features -+ * 14 = /dev/touchscreen/ucb1x00 UCB 1x00 touchscreen -+ */ -+static struct miscdevice ucb1x00_ts_dev = { -+ .minor = 14, -+ .name = "touchscreen/ucb1x00", -+ .fops = &ucb1x00_fops, -+ .devfs_name = "touchscreen/ucb1x00", -+}; -+ -+static void ucb1x00_remove(struct ucb1x00_dev *tsdev) -+{ -+ if (list_empty(&tsdev->list)) { -+ if (tsdev->exist) { -+ input_close_device(&tsdev->handle); -+ wake_up_interruptible(&tsdev->wait); -+ } else { -+ misc_deregister(&ucb1x00_ts_dev); -+ ucb1x00_dev = NULL; -+ kfree(tsdev); -+ } -+ } -+} -+ -+ -+static void -+ucb1x00_event(struct input_handle *handle, unsigned int type, unsigned int code, -+ int value) -+{ -+ struct ucb1x00_dev *tsdev = handle->private; -+ struct list_head *l; -+ -+ /* sorry, we only handle absolute stuff */ -+ if (type == EV_ABS) { -+ switch (code) { -+ case ABS_X: -+ tsdev->x = value; -+ break; -+ case ABS_Y: -+ tsdev->y = value; -+ break; -+ case ABS_PRESSURE: -+ tsdev->pressure = value; -+ break; -+ } -+ return; -+ } -+ -+ if (type != EV_SYN || code != SYN_REPORT) -+ return; -+ -+ list_for_each(l, &tsdev->list) { -+ struct ucb1x00_list *list = list_entry(l, struct ucb1x00_list, list); -+ list->event[list->head].pressure = tsdev->pressure; -+ if (tsdev->pressure) { -+ list->event[list->head].x = tsdev->x; -+ list->event[list->head].y = tsdev->y; -+ } else { -+ list->event[list->head].x = 0; -+ list->event[list->head].y = 0; -+ } -+ do_gettimeofday(&list->event[list->head].stamp); -+ list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1); -+ kill_fasync(&list->fasync, SIGIO, POLL_IN); -+ } -+ wake_up_interruptible(&tsdev->wait); -+} -+ -+static struct input_handle * -+ucb1x00_connect(struct input_handler *handler, struct input_dev *dev, -+ struct input_device_id *id) -+{ -+ struct ucb1x00_dev *tsdev; -+ -+ if (ucb1x00_dev) -+ return NULL; -+ -+ tsdev = kmalloc(sizeof(struct ucb1x00_dev), GFP_KERNEL); -+ if (!tsdev) -+ return NULL; -+ -+ memset(tsdev, 0, sizeof(struct ucb1x00_dev)); -+ init_waitqueue_head(&tsdev->wait); -+ INIT_LIST_HEAD(&tsdev->list); -+ -+ ucb1x00_dev = tsdev; -+ -+ strcpy(tsdev->name, ucb1x00_ts_dev.name); -+ -+ tsdev->handle.dev = dev; -+ tsdev->handle.name = tsdev->name; -+ tsdev->handle.handler = handler; -+ tsdev->handle.private = tsdev; -+ -+ misc_register(&ucb1x00_ts_dev); -+ -+ tsdev->exist = 1; -+ -+ return &tsdev->handle; -+} -+ -+static void ucb1x00_disconnect(struct input_handle *handle) -+{ -+ struct ucb1x00_dev *tsdev = handle->private; -+ -+ tsdev->exist = 0; -+ ucb1x00_remove(tsdev); -+} -+ -+static struct input_device_id ucb1x00_ids[] = { -+ { -+ .flags = INPUT_DEVICE_ID_MATCH_ABSBIT, -+ .evbit = { BIT(EV_ABS) }, -+ .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) }, -+ }, -+ -+ {},/* Terminating entry */ -+}; -+ -+MODULE_DEVICE_TABLE(input, ucb1x00_ids); -+ -+static struct input_handler ucb1x00_handler = { -+ .event = ucb1x00_event, -+ .connect = ucb1x00_connect, -+ .disconnect = ucb1x00_disconnect, -+ .name = "touchscreen/ucb1x00", -+ .id_table = ucb1x00_ids, -+}; -+ -+static int __init ucb1x00_init(void) -+{ -+ input_register_handler(&ucb1x00_handler); -+ printk(KERN_INFO "ts: UCB1x00 touchscreen protocol output\n"); -+ return 0; -+} -+ -+static void __exit ucb1x00_exit(void) -+{ -+ input_unregister_handler(&ucb1x00_handler); -+} -+ -+module_init(ucb1x00_init); -+module_exit(ucb1x00_exit); -+ -+MODULE_AUTHOR("Russell King "); -+MODULE_DESCRIPTION("Input driver to UCB1x00 touchscreen converter"); ---- linux-2.6.5/drivers/input/Makefile~heh 2004-04-03 22:38:17.000000000 -0500 -+++ linux-2.6.5/drivers/input/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -8,6 +8,7 @@ - obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o - obj-$(CONFIG_INPUT_JOYDEV) += joydev.o - obj-$(CONFIG_INPUT_EVDEV) += evdev.o -+obj-$(CONFIG_INPUT_TSLIBDEV) += tslibdev.o - obj-$(CONFIG_INPUT_TSDEV) += tsdev.o - obj-$(CONFIG_INPUT_POWER) += power.o - obj-$(CONFIG_INPUT_EVBUG) += evbug.o ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/char/sa1100-rtc.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,416 @@ -+/* -+ * Real Time Clock interface for Linux on Intel SA11x0/PXA2xx -+ * -+ * Copyright (c) 2000 Nils Faerber -+ * -+ * Based on rtc.c by Paul Gortmaker -+ * Date/time conversion routines taken from arch/arm/kernel/time.c -+ * by Linus Torvalds and Russel King -+ * and the GNU C Library -+ * ( ... I love the GPL ... just take what you need! ;) -+ * -+ * 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. -+ * -+ * 1.00 2001-06-08 Nicolas Pitre -+ * - added periodic timer capability using OSMR1 -+ * - flag compatibility with other RTC chips -+ * - permission checks for ioctls -+ * - major cleanup, partial rewrite -+ * -+ * 0.03 2001-03-07 CIH -+ * - Modify the bug setups RTC clock. -+ * -+ * 0.02 2001-02-27 Nils Faerber -+ * - removed mktime(), added alarm irq clear -+ * -+ * 0.01 2000-10-01 Nils Faerber -+ * - initial release -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define TIMER_FREQ 3686400 -+ -+#define RTC_DEF_DIVIDER 32768 - 1 -+#define RTC_DEF_TRIM 0 -+ -+/* Those are the bits from a classic RTC we want to mimic */ -+#define RTC_IRQF 0x80 /* any of the following 3 is active */ -+#define RTC_PF 0x40 -+#define RTC_AF 0x20 -+#define RTC_UF 0x10 -+ -+static unsigned long rtc_freq = 1024; -+static struct rtc_time rtc_alarm = { -+ .tm_year = 0, -+ .tm_mon = 0, -+ .tm_mday = 0, -+ .tm_hour = 0, -+ .tm_mon = 0, -+ .tm_sec = 0, -+}; -+ -+extern spinlock_t rtc_lock; -+ -+static int rtc_update_alarm(struct rtc_time *alrm) -+{ -+ struct rtc_time alarm_tm, now_tm; -+ unsigned long now, time; -+ int ret; -+ -+ do { -+ now = RCNR; -+ rtc_time_to_tm(now, &now_tm); -+ rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); -+ ret = rtc_tm_to_time(&alarm_tm, &time); -+ if (ret != 0) -+ break; -+ -+ RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); -+ RTAR = time; -+ } while (now != RCNR); -+ -+ return ret; -+} -+ -+static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ unsigned int rtsr; -+ unsigned long events = 0; -+ -+ spin_lock(&rtc_lock); -+ -+ rtsr = RTSR; -+ /* clear interrupt sources */ -+ RTSR = 0; -+ RTSR = (RTSR_AL|RTSR_HZ) & (rtsr >> 2); -+ -+ /* clear alarm interrupt if it has occurred */ -+ if (rtsr & RTSR_AL) -+ rtsr &= ~RTSR_ALE; -+ RTSR = rtsr & (RTSR_ALE|RTSR_HZE); -+ -+ /* update irq data & counter */ -+ if (rtsr & RTSR_AL) -+ events |= (RTC_AF|RTC_IRQF); -+ if (rtsr & RTSR_HZ) -+ events |= (RTC_UF|RTC_IRQF); -+ -+ rtc_update(1, events); -+ -+ if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) -+ rtc_update_alarm(&rtc_alarm); -+ -+ spin_unlock(&rtc_lock); -+ -+ return IRQ_HANDLED; -+} -+ -+#if 0 -+static unsigned long rtc_irq_data; -+ -+static irqreturn_t timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ /* -+ * If we match for the first time, the periodic interrupt flag won't -+ * be set. If it is, then we did wrap around (very unlikely but -+ * still possible) and compute the amount of missed periods. -+ * The match reg is updated only when the data is actually retrieved -+ * to avoid unnecessary interrupts. -+ */ -+ OSSR = OSSR_M1; /* clear match on timer1 */ -+ if (rtc_irq_data & RTC_PF) { -+ rtc_irq_data += (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))) << 8; -+ } else { -+ rtc_update(1, RTC_PF | RTC_IRQF); -+ } -+ -+ wake_up_interruptible(&rtc_wait); -+ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); -+ -+ return IRQ_HANDLED; -+} -+#endif -+ -+static int sa1100_rtc_open(void) -+{ -+ int ret; -+ -+ ret = request_irq(IRQ_RTC1Hz, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL); -+ if (ret) { -+ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz); -+ goto fail_ui; -+ } -+ ret = request_irq(IRQ_RTCAlrm, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL); -+ if (ret) { -+ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm); -+ goto fail_ai; -+ } -+#if 0 -+ ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, "rtc timer", NULL); -+ if (ret) { -+ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1); -+ goto fail_pi; -+ } -+ rtc_irq_data = 0; -+#endif -+ return 0; -+ -+ fail_pi: -+ free_irq(IRQ_RTCAlrm, NULL); -+ fail_ai: -+ free_irq(IRQ_RTC1Hz, NULL); -+ fail_ui: -+ return ret; -+} -+ -+static void sa1100_rtc_release(void) -+{ -+ spin_lock_irq (&rtc_lock); -+ RTSR = 0; -+ OIER &= ~OIER_E1; -+ OSSR = OSSR_M1; -+ spin_unlock_irq (&rtc_lock); -+ -+// free_irq(IRQ_OST1, NULL); -+ free_irq(IRQ_RTCAlrm, NULL); -+ free_irq(IRQ_RTC1Hz, NULL); -+} -+ -+#if 0 -+ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ unsigned long data; -+ ssize_t retval; -+ -+ if (count < sizeof(unsigned long)) -+ return -EINVAL; -+ -+ add_wait_queue(&rtc_wait, &wait); -+ set_current_state(TASK_INTERRUPTIBLE); -+ for (;;) { -+ spin_lock_irq (&rtc_lock); -+ data = rtc_irq_data; -+ if (data != 0) { -+ rtc_irq_data = 0; -+ break; -+ } -+ spin_unlock_irq (&rtc_lock); -+ -+ if (file->f_flags & O_NONBLOCK) { -+ retval = -EAGAIN; -+ goto out; -+ } -+ -+ if (signal_pending(current)) { -+ retval = -ERESTARTSYS; -+ goto out; -+ } -+ -+ schedule(); -+ } -+ -+ if (data & RTC_PF) { -+ /* interpolate missed periods and set match for the next one */ -+ unsigned long period = TIMER_FREQ/rtc_freq; -+ unsigned long oscr = OSCR; -+ unsigned long osmr1 = OSMR1; -+ unsigned long missed = (oscr - osmr1)/period; -+ data += missed << 8; -+ OSSR = OSSR_M1; /* clear match on timer 1 */ -+ OSMR1 = osmr1 + (missed + 1)*period; -+ /* ensure we didn't miss another match in the mean time */ -+ while( (signed long)((osmr1 = OSMR1) - OSCR) <= 0 ) { -+ data += 0x100; -+ OSSR = OSSR_M1; /* clear match on timer 1 */ -+ OSMR1 = osmr1 + period; -+ } -+ } -+ spin_unlock_irq (&rtc_lock); -+ -+ data -= 0x100; /* the first IRQ wasn't actually missed */ -+ -+ retval = put_user(data, (unsigned long *)buf); -+ if (!retval) -+ retval = sizeof(unsigned long); -+ -+out: -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&rtc_wait, &wait); -+ return retval; -+} -+#endif -+ -+static int sa1100_rtc_ioctl(unsigned int cmd, unsigned long arg) -+{ -+ switch (cmd) { -+ case RTC_AIE_OFF: -+ spin_lock_irq(&rtc_lock); -+ RTSR &= ~RTSR_ALE; -+// rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_AIE_ON: -+ spin_lock_irq(&rtc_lock); -+ RTSR |= RTSR_ALE; -+// rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_UIE_OFF: -+ spin_lock_irq(&rtc_lock); -+ RTSR &= ~RTSR_HZE; -+// rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_UIE_ON: -+ spin_lock_irq(&rtc_lock); -+ RTSR |= RTSR_HZE; -+// rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+#if 0 -+ case RTC_PIE_OFF: -+ spin_lock_irq(&rtc_lock); -+ OIER &= ~OIER_E1; -+// rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_PIE_ON: -+ if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE)) -+ return -EACCES; -+ spin_lock_irq(&rtc_lock); -+ OSMR1 = TIMER_FREQ/rtc_freq + OSCR; -+ OIER |= OIER_E1; -+// rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_IRQP_READ: -+ return put_user(rtc_freq, (unsigned long *)arg); -+ case RTC_IRQP_SET: -+ if (arg < 1 || arg > TIMER_FREQ) -+ return -EINVAL; -+ if ((arg > 64) && (!capable(CAP_SYS_RESOURCE))) -+ return -EACCES; -+ rtc_freq = arg; -+ return 0; -+#endif -+ } -+ return -EINVAL; -+} -+ -+static void sa1100_rtc_read_time(struct rtc_time *tm) -+{ -+ rtc_time_to_tm(RCNR, tm); -+} -+ -+static int sa1100_rtc_set_time(struct rtc_time *tm) -+{ -+ unsigned long time; -+ int ret; -+ -+ ret = rtc_tm_to_time(tm, &time); -+ if (ret == 0) -+ RCNR = time; -+ return ret; -+} -+ -+static void sa1100_rtc_read_alarm(struct rtc_wkalrm *alrm) -+{ -+ memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); -+ alrm->pending = RTSR & RTSR_AL ? 1 : 0; -+} -+ -+static int sa1100_rtc_set_alarm(struct rtc_wkalrm *alrm) -+{ -+ int ret; -+ -+ spin_lock_irq(&rtc_lock); -+ ret = rtc_update_alarm(&alrm->time); -+ if (ret == 0) { -+ memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time)); -+ -+ if (alrm->enabled) -+ enable_irq_wake(IRQ_RTCAlrm); -+ else -+ disable_irq_wake(IRQ_RTCAlrm); -+ } -+ spin_unlock_irq(&rtc_lock); -+ -+ return ret; -+} -+ -+static int sa1100_rtc_proc(char *buf) -+{ -+ char *p = buf; -+ -+ p += sprintf(p, "trim/divider\t: 0x%08x\n", RTTR); -+ p += sprintf(p, "alarm_IRQ\t: %s\n", (RTSR & RTSR_ALE) ? "yes" : "no" ); -+ p += sprintf(p, "update_IRQ\t: %s\n", (RTSR & RTSR_HZE) ? "yes" : "no"); -+ p += sprintf(p, "periodic_IRQ\t: %s\n", (OIER & OIER_E1) ? "yes" : "no"); -+ p += sprintf(p, "periodic_freq\t: %ld\n", rtc_freq); -+ -+ return p - buf; -+} -+ -+static struct rtc_ops sa1100_rtc_ops = { -+ .owner = THIS_MODULE, -+ .open = sa1100_rtc_open, -+ .release = sa1100_rtc_release, -+ .ioctl = sa1100_rtc_ioctl, -+ -+ .read_time = sa1100_rtc_read_time, -+ .set_time = sa1100_rtc_set_time, -+ .read_alarm = sa1100_rtc_read_alarm, -+ .set_alarm = sa1100_rtc_set_alarm, -+ .proc = sa1100_rtc_proc, -+}; -+ -+static int __init rtc_init(void) -+{ -+ /* -+ * According to the manual we should be able to let RTTR be zero -+ * and then a default diviser for a 32.768KHz clock is used. -+ * Apparently this doesn't work, at least for my SA1110 rev 5. -+ * If the clock divider is uninitialized then reset it to the -+ * default value to get the 1Hz clock. -+ */ -+ if (RTTR == 0) { -+ RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); -+ printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n"); -+ /* The current RTC value probably doesn't make sense either */ -+ RCNR = 0; -+ } -+ -+ register_rtc(&sa1100_rtc_ops); -+ -+ return 0; -+} -+ -+static void __exit rtc_exit(void) -+{ -+ unregister_rtc(&sa1100_rtc_ops); -+} -+ -+module_init(rtc_init); -+module_exit(rtc_exit); -+ -+MODULE_AUTHOR("Nils Faerber "); -+MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); -+MODULE_LICENSE("GPL"); /* so says the header */ ---- linux-2.6.5/drivers/char/Kconfig~heh 2004-04-03 22:36:15.000000000 -0500 -+++ linux-2.6.5/drivers/char/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -814,6 +814,10 @@ - - If unsure, say N. - -+config SA1100_RTC -+ tristate "SA1100 or PXA Real Time Clock" -+ depends on ARCH_SA1100 || ARCH_PXA -+ - config DTLK - tristate "Double Talk PC internal speech card support" - help ---- linux-2.6.5/drivers/char/tty_io.c~heh 2004-04-03 22:37:23.000000000 -0500 -+++ linux-2.6.5/drivers/char/tty_io.c 2004-04-30 20:57:36.000000000 -0400 -@@ -1535,10 +1535,17 @@ - return 0; - } - -+/* -+ * In the case of pty's, "tty" is the master side -+ * and "real_tty" is the slave side. -+ */ - static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, - struct winsize * arg) - { - struct winsize tmp_ws; -+ struct task_struct *p; -+ struct list_head *l; -+ struct pid *pid; - - if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) - return -EFAULT; -@@ -1558,8 +1565,21 @@ - #endif - if (tty->pgrp > 0) - kill_pg(tty->pgrp, SIGWINCH, 1); -- if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0)) -- kill_pg(real_tty->pgrp, SIGWINCH, 1); -+ -+ /* -+ * Send SIGWINCH to the whole session on the slave tty. -+ * However, in the case of non-master pty's, be careful -+ * not to send two SIGWINCH to the same procress group. -+ */ -+ if (real_tty->session > 0) { -+ read_lock(&tasklist_lock); -+ for_each_task_pid(real_tty->session, PIDTYPE_SID, p, l, pid) { -+ if (process_group(p) != tty->pgrp) -+ group_send_sig_info(SIGWINCH, (void *)1L, p); -+ } -+ read_unlock(&tasklist_lock); -+ } -+ - tty->winsize = tmp_ws; - real_tty->winsize = tmp_ws; - return 0; ---- linux-2.6.5/drivers/Makefile~heh 2004-04-03 22:37:43.000000000 -0500 -+++ linux-2.6.5/drivers/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -11,6 +11,8 @@ - # PnP must come after ACPI since it will eventually need to check if acpi - # was used and do nothing if so - obj-$(CONFIG_PNP) += pnp/ -+obj-$(CONFIG_I2C) += i2c/ -+obj-$(CONFIG_L3) += l3/ - - # char/ comes before serial/ etc so that the VT console is the boot-time - # default. -@@ -41,7 +43,6 @@ - obj-$(CONFIG_GAMEPORT) += input/gameport/ - obj-$(CONFIG_SERIO) += input/serio/ - obj-$(CONFIG_I2O) += message/ --obj-$(CONFIG_I2C) += i2c/ - obj-$(CONFIG_PHONE) += telephony/ - obj-$(CONFIG_MD) += md/ - obj-$(CONFIG_BT) += bluetooth/ ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/l3/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,24 @@ -+# -+# L3 bus configuration -+# -+ -+menu "L3 serial bus support" -+ -+config L3 -+ tristate "L3 support" -+ -+config L3_ALGOBIT -+ bool "L3 bit-banging interfaces" -+ depends on L3=y -+ -+config L3_BIT_SA1100_GPIO -+ bool "SA11x0 GPIO adapter" -+ depends on L3_ALGOBIT && ARCH_SA1100 -+ -+# i2c must come before this -+config BIT_SA1100_GPIO -+ bool -+ depends on L3_BIT_SA1100_GPIO || I2C_BIT_SA1100_GPIO=y -+ default y -+ -+endmenu ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/l3/l3-core.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,203 @@ -+/* -+ * linux/drivers/l3/l3-core.c -+ * -+ * Copyright (C) 2001 Russell King -+ * -+ * General structure taken from i2c-core.c by Simon G. Vogl -+ * -+ * 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. -+ * -+ * See linux/Documentation/l3 for further documentation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static DECLARE_MUTEX(adapter_lock); -+static LIST_HEAD(adapter_list); -+ -+static DECLARE_MUTEX(driver_lock); -+static LIST_HEAD(driver_list); -+ -+/** -+ * l3_add_adapter - register a new L3 bus adapter -+ * @adap: l3_adapter structure for the registering adapter -+ * -+ * Make the adapter available for use by clients using name adap->name. -+ * The adap->adapters list is initialised by this function. -+ * -+ * Returns 0; -+ */ -+int l3_add_adapter(struct l3_adapter *adap) -+{ -+ down(&adapter_lock); -+ list_add(&adap->adapters, &adapter_list); -+ up(&adapter_lock); -+ return 0; -+} -+ -+/** -+ * l3_del_adapter - unregister a L3 bus adapter -+ * @adap: l3_adapter structure to unregister -+ * -+ * Remove an adapter from the list of available L3 Bus adapters. -+ * -+ * Returns 0; -+ */ -+int l3_del_adapter(struct l3_adapter *adap) -+{ -+ down(&adapter_lock); -+ list_del(&adap->adapters); -+ up(&adapter_lock); -+ return 0; -+} -+ -+static struct l3_adapter *__l3_get_adapter(const char *name) -+{ -+ struct list_head *l; -+ -+ list_for_each(l, &adapter_list) { -+ struct l3_adapter *adap = list_entry(l, struct l3_adapter, adapters); -+ -+ if (strcmp(adap->name, name) == 0) -+ return adap; -+ } -+ -+ return NULL; -+} -+ -+/** -+ * l3_get_adapter - get a reference to an adapter -+ * @name: driver name -+ * -+ * Obtain a l3_adapter structure for the specified adapter. If the adapter -+ * is not currently load, then load it. The adapter will be locked in core -+ * until all references are released via l3_put_adapter. -+ */ -+struct l3_adapter *l3_get_adapter(const char *name) -+{ -+ struct l3_adapter *adap; -+ int try; -+ -+ for (try = 0; try < 2; try ++) { -+ down(&adapter_lock); -+ adap = __l3_get_adapter(name); -+ if (adap && !try_module_get(adap->owner)) -+ adap = NULL; -+ up(&adapter_lock); -+ -+ if (adap) -+ break; -+ -+ if (try == 0) -+ request_module(name); -+ } -+ -+ return adap; -+} -+ -+/** -+ * l3_put_adapter - release a reference to an adapter -+ * @adap: driver to release reference -+ * -+ * Indicate to the L3 core that you no longer require the adapter reference. -+ * The adapter module may be unloaded when there are no references to its -+ * data structure. -+ * -+ * You must not use the reference after calling this function. -+ */ -+void l3_put_adapter(struct l3_adapter *adap) -+{ -+ if (adap && adap->owner) -+ module_put(adap->owner); -+} -+ -+/** -+ * l3_transfer - transfer information on an L3 bus -+ * @adap: adapter structure to perform transfer on -+ * @msgs: array of l3_msg structures describing transfer -+ * @num: number of l3_msg structures -+ * -+ * Transfer the specified messages to/from a device on the L3 bus. -+ * -+ * Returns number of messages successfully transferred, otherwise negative -+ * error code. -+ */ -+int l3_transfer(struct l3_adapter *adap, struct l3_msg msgs[], int num) -+{ -+ int ret = -ENOSYS; -+ -+ if (adap->algo->xfer) { -+ down(adap->lock); -+ ret = adap->algo->xfer(adap, msgs, num); -+ up(adap->lock); -+ } -+ return ret; -+} -+ -+/** -+ * l3_write - send data to a device on an L3 bus -+ * @adap: L3 bus adapter -+ * @addr: L3 bus address -+ * @buf: buffer for bytes to send -+ * @len: number of bytes to send -+ * -+ * Send len bytes pointed to by buf to device address addr on the L3 bus -+ * described by client. -+ * -+ * Returns the number of bytes transferred, or negative error code. -+ */ -+int l3_write(struct l3_adapter *adap, int addr, const char *buf, int len) -+{ -+ struct l3_msg msg; -+ int ret; -+ -+ msg.addr = addr; -+ msg.flags = 0; -+ msg.buf = (char *)buf; -+ msg.len = len; -+ -+ ret = l3_transfer(adap, &msg, 1); -+ return ret == 1 ? len : ret; -+} -+ -+/** -+ * l3_read - receive data from a device on an L3 bus -+ * @adap: L3 bus adapter -+ * @addr: L3 bus address -+ * @buf: buffer for bytes to receive -+ * @len: number of bytes to receive -+ * -+ * Receive len bytes from device address addr on the L3 bus described by -+ * client to a buffer pointed to by buf. -+ * -+ * Returns the number of bytes transferred, or negative error code. -+ */ -+int l3_read(struct l3_adapter *adap, int addr, char *buf, int len) -+{ -+ struct l3_msg msg; -+ int ret; -+ -+ msg.addr = addr; -+ msg.flags = L3_M_RD; -+ msg.buf = buf; -+ msg.len = len; -+ -+ ret = l3_transfer(adap, &msg, 1); -+ return ret == 1 ? len : ret; -+} -+ -+EXPORT_SYMBOL(l3_add_adapter); -+EXPORT_SYMBOL(l3_del_adapter); -+EXPORT_SYMBOL(l3_get_adapter); -+EXPORT_SYMBOL(l3_put_adapter); -+EXPORT_SYMBOL(l3_transfer); -+EXPORT_SYMBOL(l3_write); -+EXPORT_SYMBOL(l3_read); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/l3/l3-algo-bit.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,175 @@ -+/* -+ * L3 bus algorithm module. -+ * -+ * Copyright (C) 2001 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * Note that L3 buses can share the same pins as I2C buses, so we must -+ * _not_ generate an I2C start condition. An I2C start condition is -+ * defined as a high-to-low transition of the data line while the clock -+ * is high. Therefore, we must only change the data line while the -+ * clock is low. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define setdat(adap,val) adap->setdat(adap->data, val) -+#define setclk(adap,val) adap->setclk(adap->data, val) -+#define setmode(adap,val) adap->setmode(adap->data, val) -+#define setdatin(adap) adap->setdir(adap->data, 1) -+#define setdatout(adap) adap->setdir(adap->data, 0) -+#define getdat(adap) adap->getdat(adap->data) -+ -+/* -+ * Send one byte of data to the chip. Data is latched into the chip on -+ * the rising edge of the clock. -+ */ -+static void sendbyte(struct l3_algo_bit_data *adap, unsigned int byte) -+{ -+ int i; -+ -+ for (i = 0; i < 8; i++) { -+ setclk(adap, 0); -+ udelay(adap->data_hold); -+ setdat(adap, byte & 1); -+ udelay(adap->data_setup); -+ setclk(adap, 1); -+ udelay(adap->clock_high); -+ byte >>= 1; -+ } -+} -+ -+/* -+ * Send a set of bytes to the chip. We need to pulse the MODE line -+ * between each byte, but never at the start nor at the end of the -+ * transfer. -+ */ -+static void sendbytes(struct l3_algo_bit_data *adap, const char *buf, int len) -+{ -+ int i; -+ -+ for (i = 0; i < len; i++) { -+ if (i) { -+ udelay(adap->mode_hold); -+ setmode(adap, 0); -+ udelay(adap->mode); -+ } -+ setmode(adap, 1); -+ udelay(adap->mode_setup); -+ sendbyte(adap, buf[i]); -+ } -+} -+ -+/* -+ * Read one byte of data from the chip. Data is latched into the chip on -+ * the rising edge of the clock. -+ */ -+static unsigned int readbyte(struct l3_algo_bit_data *adap) -+{ -+ unsigned int byte = 0; -+ int i; -+ -+ for (i = 0; i < 8; i++) { -+ setclk(adap, 0); -+ udelay(adap->data_hold + adap->data_setup); -+ setclk(adap, 1); -+ if (getdat(adap)) -+ byte |= 1 << i; -+ udelay(adap->clock_high); -+ } -+ -+ return byte; -+} -+ -+/* -+ * Read a set of bytes from the chip. We need to pulse the MODE line -+ * between each byte, but never at the start nor at the end of the -+ * transfer. -+ */ -+static void readbytes(struct l3_algo_bit_data *adap, char *buf, int len) -+{ -+ int i; -+ -+ for (i = 0; i < len; i++) { -+ if (i) { -+ udelay(adap->mode_hold); -+ setmode(adap, 0); -+ } -+ setmode(adap, 1); -+ udelay(adap->mode_setup); -+ buf[i] = readbyte(adap); -+ } -+} -+ -+static int l3_xfer(struct l3_adapter *l3_adap, struct l3_msg msgs[], int num) -+{ -+ struct l3_algo_bit_data *adap = l3_adap->algo_data; -+ int i; -+ -+ /* -+ * If we share an I2C bus, ensure that it is in STOP mode -+ */ -+ setclk(adap, 1); -+ setdat(adap, 1); -+ setmode(adap, 1); -+ setdatout(adap); -+ udelay(adap->mode); -+ -+ for (i = 0; i < num; i++) { -+ struct l3_msg *pmsg = &msgs[i]; -+ -+ if (!(pmsg->flags & L3_M_NOADDR)) { -+ setmode(adap, 0); -+ udelay(adap->mode_setup); -+ sendbyte(adap, pmsg->addr); -+ udelay(adap->mode_hold); -+ } -+ -+ if (pmsg->flags & L3_M_RD) { -+ setdatin(adap); -+ readbytes(adap, pmsg->buf, pmsg->len); -+ } else { -+ setdatout(adap); -+ sendbytes(adap, pmsg->buf, pmsg->len); -+ } -+ } -+ -+ /* -+ * Ensure that we leave the bus in I2C stop mode. -+ */ -+ setclk(adap, 1); -+ setdat(adap, 1); -+ setmode(adap, 0); -+ setdatin(adap); -+ -+ return num; -+} -+ -+static struct l3_algorithm l3_bit_algo = { -+ name: "L3 bit-shift algorithm", -+ xfer: l3_xfer, -+}; -+ -+int l3_bit_add_bus(struct l3_adapter *adap) -+{ -+ adap->algo = &l3_bit_algo; -+ return l3_add_adapter(adap); -+} -+ -+int l3_bit_del_bus(struct l3_adapter *adap) -+{ -+ return l3_del_adapter(adap); -+} -+ -+EXPORT_SYMBOL(l3_bit_add_bus); -+EXPORT_SYMBOL(l3_bit_del_bus); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/l3/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,11 @@ -+# -+# Makefile for the L3 bus driver. -+# -+ -+# Link order: -+# (core, adapters, algorithms, drivers) then clients -+ -+l3-$(CONFIG_L3_ALGOBIT) += l3-algo-bit.o -+l3-$(CONFIG_BIT_SA1100_GPIO) += l3-bit-sa1100.o -+ -+obj-$(CONFIG_L3) += l3-core.o $(l3-y) $(l3-drv-y) ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/l3/l3-bit-sa1100.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,271 @@ -+/* -+ * linux/drivers/l3/l3-bit-sa1100.c -+ * -+ * Copyright (C) 2001 Russell King -+ * -+ * 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. -+ * -+ * This is a combined I2C and L3 bus driver. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define NAME "l3-bit-sa1100-gpio" -+ -+struct bit_data { -+ unsigned int sda; -+ unsigned int scl; -+ unsigned int l3_mode; -+}; -+ -+static int getsda(void *data) -+{ -+ struct bit_data *bits = data; -+ -+ return GPLR & bits->sda; -+} -+ -+#ifdef CONFIG_I2C_BIT_SA1100_GPIO -+static void i2c_setsda(void *data, int state) -+{ -+ struct bit_data *bits = data; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ if (state) -+ GPDR &= ~bits->sda; -+ else { -+ GPCR = bits->sda; -+ GPDR |= bits->sda; -+ } -+ local_irq_restore(flags); -+} -+ -+static void i2c_setscl(void *data, int state) -+{ -+ struct bit_data *bits = data; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ if (state) -+ GPDR &= ~bits->scl; -+ else { -+ GPCR = bits->scl; -+ GPDR |= bits->scl; -+ } -+ local_irq_restore(flags); -+} -+ -+static int i2c_getscl(void *data) -+{ -+ struct bit_data *bits = data; -+ -+ return GPLR & bits->scl; -+} -+ -+static struct i2c_algo_bit_data i2c_bit_data = { -+ .setsda = i2c_setsda, -+ .setscl = i2c_setscl, -+ .getsda = getsda, -+ .getscl = i2c_getscl, -+ .udelay = 10, -+ .mdelay = 10, -+ .timeout = 100, -+}; -+ -+static struct i2c_adapter i2c_adapter = { -+ .algo_data = &i2c_bit_data, -+}; -+ -+#define LOCK &i2c_adapter.bus_lock -+ -+static int __init i2c_init(struct bit_data *bits) -+{ -+ i2c_bit_data.data = bits; -+ return i2c_bit_add_bus(&i2c_adapter); -+} -+ -+static void i2c_exit(void) -+{ -+ i2c_bit_del_bus(&i2c_adapter); -+} -+ -+#else -+static DECLARE_MUTEX(l3_lock); -+#define LOCK &l3_lock -+#define i2c_init(bits) (0) -+#define i2c_exit() do { } while (0) -+#endif -+ -+#ifdef CONFIG_L3_BIT_SA1100_GPIO -+/* -+ * iPAQs need the clock line driven hard high and low. -+ */ -+static void l3_setscl(void *data, int state) -+{ -+ struct bit_data *bits = data; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ if (state) -+ GPSR = bits->scl; -+ else -+ GPCR = bits->scl; -+ GPDR |= bits->scl; -+ local_irq_restore(flags); -+} -+ -+static void l3_setsda(void *data, int state) -+{ -+ struct bit_data *bits = data; -+ -+ if (state) -+ GPSR = bits->sda; -+ else -+ GPCR = bits->sda; -+} -+ -+static void l3_setdir(void *data, int in) -+{ -+ struct bit_data *bits = data; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ if (in) -+ GPDR &= ~bits->sda; -+ else -+ GPDR |= bits->sda; -+ local_irq_restore(flags); -+} -+ -+static void l3_setmode(void *data, int state) -+{ -+ struct bit_data *bits = data; -+ -+ if (state) -+ GPSR = bits->l3_mode; -+ else -+ GPCR = bits->l3_mode; -+} -+ -+static struct l3_algo_bit_data l3_bit_data = { -+ .data = NULL, -+ .setdat = l3_setsda, -+ .setclk = l3_setscl, -+ .setmode = l3_setmode, -+ .setdir = l3_setdir, -+ .getdat = getsda, -+ .data_hold = 1, -+ .data_setup = 1, -+ .clock_high = 1, -+ .mode_hold = 1, -+ .mode_setup = 1, -+}; -+ -+static struct l3_adapter l3_adapter = { -+ .owner = THIS_MODULE, -+ .name = NAME, -+ .algo_data = &l3_bit_data, -+ .lock = LOCK, -+}; -+ -+static int __init l3_init(struct bit_data *bits) -+{ -+ l3_bit_data.data = bits; -+ return l3_bit_add_bus(&l3_adapter); -+} -+ -+static void __exit l3_exit(void) -+{ -+ l3_bit_del_bus(&l3_adapter); -+} -+#else -+#define l3_init(bits) (0) -+#define l3_exit() do { } while (0) -+#endif -+ -+static struct bit_data bit_data; -+ -+static int __init bus_init(void) -+{ -+ struct bit_data *bit = &bit_data; -+ unsigned long flags; -+ int ret; -+ -+ if (machine_is_assabet() || machine_is_pangolin()) { -+ bit->sda = GPIO_GPIO15; -+ bit->scl = GPIO_GPIO18; -+ bit->l3_mode = GPIO_GPIO17; -+ } -+ -+ if (machine_is_h3600() || machine_is_h3100()) { -+ bit->sda = GPIO_GPIO14; -+ bit->scl = GPIO_GPIO16; -+ bit->l3_mode = GPIO_GPIO15; -+ } -+ -+ if (machine_is_stork()) { -+ bit->sda = GPIO_GPIO15; -+ bit->scl = GPIO_GPIO18; -+ bit->l3_mode = GPIO_GPIO17; -+ } -+ -+ if (!bit->sda) -+ return -ENODEV; -+ -+ /* -+ * Default level for L3 mode is low. -+ * We set SCL and SDA high (i2c idle state). -+ */ -+ local_irq_save(flags); -+ GPDR &= ~(bit->scl | bit->sda); -+ GPCR = bit->l3_mode | bit->scl | bit->sda; -+ GPDR |= bit->l3_mode; -+ local_irq_restore(flags); -+ -+ if (machine_is_assabet()) { -+ /* -+ * Release reset on UCB1300, ADI7171 and UDA1341. We -+ * need to do this here so that we can communicate on -+ * the I2C/L3 buses. -+ */ -+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); -+ mdelay(1); -+ ASSABET_BCR_clear(ASSABET_BCR_CODEC_RST); -+ mdelay(1); -+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); -+ } -+ -+ ret = i2c_init(bit); -+ if (ret == 0 && bit->l3_mode) { -+ ret = l3_init(bit); -+ if (ret) -+ i2c_exit(); -+ } -+ -+ return ret; -+} -+ -+static void __exit bus_exit(void) -+{ -+ l3_exit(); -+ i2c_exit(); -+} -+ -+module_init(bus_init); -+module_exit(bus_exit); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/switches.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,22 @@ -+/* -+ * linux/drivers/misc/switches.h -+ * -+ * Copyright (C) 2001 John Dorsey -+ * -+ * 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. -+ * -+ * 19 December 2001 - created. -+ */ -+ -+#if !defined(_SWITCHES_H) -+# define _SWITCHES_H -+ -+#include -+ -+#define SWITCHES_NAME "switches" -+ -+extern int switches_event(switches_mask_t *mask); -+ -+#endif /* !defined(_SWITCHES_H) */ ---- linux-2.6.5/drivers/misc/Kconfig~heh 2004-04-03 22:36:26.000000000 -0500 -+++ linux-2.6.5/drivers/misc/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -21,5 +21,62 @@ - - If unsure, say N. - -+menu "Multimedia Capabilities Port drivers" -+ -+config MCP -+ tristate "Multimedia drivers" -+ -+# Interface drivers -+config MCP_SA1100 -+ tristate "Support SA1100 MCP interface" -+ depends on MCP && ARCH_SA1100 -+ -+# Chip drivers -+config MCP_UCB1200 -+ tristate "Support for UCB1200 / UCB1300" -+ depends on MCP -+ -+config MCP_UCB1200_AUDIO -+ tristate "Audio / Telephony interface support" -+ depends on MCP_UCB1200 && SOUND -+ -+config MCP_UCB1200_TS -+ tristate "Touchscreen interface support" -+ depends on MCP_UCB1200 && INPUT -+ -+endmenu -+ -+ -+menu "Console Switches" -+ -+config SWITCHES -+ tristate "Console Switch Support" -+ help -+ Say Y here to include support for simple console momentary switches. -+ This driver implements a miscellaneous character device (named -+ `switches' in /proc/misc) which can be read by userland programs -+ to respond to switch press events. This mechanism is efficient for -+ systems which may not implement a traditional heavyweight console -+ server. -+ -+ It is also possible to say M to build this driver as a module (named -+ `switches.o'). -+ -+config SWITCHES_SA1100 -+ tristate "SA-1100 switches" -+ depends on SWITCHES && ARCH_SA1100 -+ help -+ Say Y here to include support for switches routed directly to -+ interruptable signals on StrongARM SA-1100 systems. -+ -+config SWITCHES_UCB1X00 -+ tristate "UCB1x00 switches" -+ depends on SWITCHES && MCP_UCB1200 -+ help -+ Say Y here to include support for switches routed through a -+ UCB1x00 modem/audio analog front-end device. -+ -+endmenu -+ - endmenu - ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/ucb1x00-assabet.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,73 @@ -+/* -+ * linux/drivers/misc/ucb1x00-assabet.c -+ * -+ * Copyright (C) 2001-2003 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License. -+ * -+ * We handle the machine-specific bits of the UCB1x00 driver here. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "ucb1x00.h" -+ -+#define UCB1X00_ATTR(name,input)\ -+static ssize_t name##_show(struct class_device *dev, char *buf) \ -+{ \ -+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ -+ int val; \ -+ ucb1x00_adc_enable(ucb); \ -+ val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \ -+ ucb1x00_adc_disable(ucb); \ -+ return sprintf(buf, "%d\n", val); \ -+} \ -+static CLASS_DEVICE_ATTR(name,0444,name##_show,NULL) -+ -+UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1); -+UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0); -+UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2); -+ -+static int ucb1x00_assabet_add(struct class_device *dev) -+{ -+ class_device_create_file(dev, &class_device_attr_vbatt); -+ class_device_create_file(dev, &class_device_attr_vcharger); -+ class_device_create_file(dev, &class_device_attr_batt_temp); -+ return 0; -+} -+ -+static void ucb1x00_assabet_remove(struct class_device *dev) -+{ -+ class_device_remove_file(dev, &class_device_attr_batt_temp); -+ class_device_remove_file(dev, &class_device_attr_vcharger); -+ class_device_remove_file(dev, &class_device_attr_vbatt); -+} -+ -+static struct class_interface ucb1x00_assabet_interface = { -+ .add = ucb1x00_assabet_add, -+ .remove = ucb1x00_assabet_remove, -+}; -+ -+static int __init ucb1x00_assabet_init(void) -+{ -+ return ucb1x00_register_interface(&ucb1x00_assabet_interface); -+} -+ -+static void __exit ucb1x00_assabet_exit(void) -+{ -+ ucb1x00_unregister_interface(&ucb1x00_assabet_interface); -+} -+ -+module_init(ucb1x00_assabet_init); -+module_exit(ucb1x00_assabet_exit); -+ -+MODULE_AUTHOR("Russell King "); -+MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/mcp-pxa.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,57 @@ -+/* -+ * linux/drivers/misc/mcp-pxa.c -+ * -+ * 2002-01-10 Jeff Sutherland -+ * -+ * 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. -+ * -+ * NOTE: This is a quick hack to gain access to the aclink codec's -+ * touch screen facility. Its audio is handled by a separate -+ * (non-mcp) driver at the present time. -+ */ -+ -+#include -+#include -+#include -+ -+#include "mcp.h" -+ -+ -+extern int pxa_ac97_get(struct ac97_codec **codec); -+extern void pxa_ac97_put(void); -+ -+ -+struct mcp *mcp_get(void) -+{ -+ struct ac97_codec *codec; -+ if (pxa_ac97_get(&codec) < 0) -+ return NULL; -+ return (struct mcp *)codec; -+} -+ -+void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val) -+{ -+ struct ac97_codec *codec = (struct ac97_codec *)mcp; -+ codec->codec_write(codec, reg, val); -+} -+ -+unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg) -+{ -+ struct ac97_codec *codec = (struct ac97_codec *)mcp; -+ return codec->codec_read(codec, reg); -+} -+ -+void mcp_enable(struct mcp *mcp) -+{ -+ /* -+ * Should we do something here to make sure the aclink -+ * codec is alive??? -+ * A: not for now --NP -+ */ -+} -+ -+void mcp_disable(struct mcp *mcp) -+{ -+} ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/mcp-core.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,235 @@ -+/* -+ * linux/drivers/misc/mcp-core.c -+ * -+ * Copyright (C) 2001 Russell King -+ * -+ * 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. -+ * -+ * Generic MCP (Multimedia Communications Port) layer. All MCP locking -+ * is solely held within this file. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "mcp.h" -+ -+#define to_mcp(d) container_of(d, struct mcp, attached_device) -+#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) -+ -+static int mcp_bus_match(struct device *dev, struct device_driver *drv) -+{ -+ return 1; -+} -+ -+static int mcp_bus_probe(struct device *dev) -+{ -+ struct mcp *mcp = to_mcp(dev); -+ struct mcp_driver *drv = to_mcp_driver(dev->driver); -+ -+ return drv->probe(mcp); -+} -+ -+static int mcp_bus_remove(struct device *dev) -+{ -+ struct mcp *mcp = to_mcp(dev); -+ struct mcp_driver *drv = to_mcp_driver(dev->driver); -+ -+ drv->remove(mcp); -+ return 0; -+} -+ -+static int mcp_bus_suspend(struct device *dev, u32 state) -+{ -+ struct mcp *mcp = to_mcp(dev); -+ int ret = 0; -+ -+ if (dev->driver) { -+ struct mcp_driver *drv = to_mcp_driver(dev->driver); -+ -+ ret = drv->suspend(mcp, state); -+ } -+ return ret; -+} -+ -+static int mcp_bus_resume(struct device *dev) -+{ -+ struct mcp *mcp = to_mcp(dev); -+ int ret = 0; -+ -+ if (dev->driver) { -+ struct mcp_driver *drv = to_mcp_driver(dev->driver); -+ -+ ret = drv->resume(mcp); -+ } -+ return ret; -+} -+ -+static struct bus_type mcp_bus_type = { -+ .name = "mcp", -+ .match = mcp_bus_match, -+ .suspend = mcp_bus_suspend, -+ .resume = mcp_bus_resume, -+}; -+ -+/** -+ * mcp_set_telecom_divisor - set the telecom divisor -+ * @mcp: MCP interface structure -+ * @div: SIB clock divisor -+ * -+ * Set the telecom divisor on the MCP interface. The resulting -+ * sample rate is SIBCLOCK/div. -+ */ -+void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div) -+{ -+ spin_lock_irq(&mcp->lock); -+ mcp->set_telecom_divisor(mcp, div); -+ spin_unlock_irq(&mcp->lock); -+} -+ -+/** -+ * mcp_set_audio_divisor - set the audio divisor -+ * @mcp: MCP interface structure -+ * @div: SIB clock divisor -+ * -+ * Set the audio divisor on the MCP interface. -+ */ -+void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div) -+{ -+ spin_lock_irq(&mcp->lock); -+ mcp->set_audio_divisor(mcp, div); -+ spin_unlock_irq(&mcp->lock); -+} -+ -+/** -+ * mcp_reg_write - write a device register -+ * @mcp: MCP interface structure -+ * @reg: 4-bit register index -+ * @val: 16-bit data value -+ * -+ * Write a device register. The MCP interface must be enabled -+ * to prevent this function hanging. -+ */ -+void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&mcp->lock, flags); -+ mcp->reg_write(mcp, reg, val); -+ spin_unlock_irqrestore(&mcp->lock, flags); -+} -+ -+/** -+ * mcp_reg_read - read a device register -+ * @mcp: MCP interface structure -+ * @reg: 4-bit register index -+ * -+ * Read a device register and return its value. The MCP interface -+ * must be enabled to prevent this function hanging. -+ */ -+unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg) -+{ -+ unsigned long flags; -+ unsigned int val; -+ -+ spin_lock_irqsave(&mcp->lock, flags); -+ val = mcp->reg_read(mcp, reg); -+ spin_unlock_irqrestore(&mcp->lock, flags); -+ -+ return val; -+} -+ -+/** -+ * mcp_enable - enable the MCP interface -+ * @mcp: MCP interface to enable -+ * -+ * Enable the MCP interface. Each call to mcp_enable will need -+ * a corresponding call to mcp_disable to disable the interface. -+ */ -+void mcp_enable(struct mcp *mcp) -+{ -+ spin_lock_irq(&mcp->lock); -+ if (mcp->use_count++ == 0) -+ mcp->enable(mcp); -+ spin_unlock_irq(&mcp->lock); -+} -+ -+/** -+ * mcp_disable - disable the MCP interface -+ * @mcp: MCP interface to disable -+ * -+ * Disable the MCP interface. The MCP interface will only be -+ * disabled once the number of calls to mcp_enable matches the -+ * number of calls to mcp_disable. -+ */ -+void mcp_disable(struct mcp *mcp) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&mcp->lock, flags); -+ if (--mcp->use_count == 0) -+ mcp->disable(mcp); -+ spin_unlock_irqrestore(&mcp->lock, flags); -+} -+ -+int mcp_host_register(struct mcp *mcp, struct device *parent) -+{ -+ mcp->attached_device.parent = parent; -+ mcp->attached_device.bus = &mcp_bus_type; -+ mcp->attached_device.dma_mask = parent->dma_mask; -+ strcpy(mcp->attached_device.bus_id, "mcp0"); -+ return device_register(&mcp->attached_device); -+} -+ -+void mcp_host_unregister(struct mcp *mcp) -+{ -+ device_unregister_wait(&mcp->attached_device); -+} -+ -+int mcp_driver_register(struct mcp_driver *mcpdrv) -+{ -+ mcpdrv->drv.bus = &mcp_bus_type; -+ mcpdrv->drv.probe = mcp_bus_probe; -+ mcpdrv->drv.remove = mcp_bus_remove; -+ return driver_register(&mcpdrv->drv); -+} -+ -+void mcp_driver_unregister(struct mcp_driver *mcpdrv) -+{ -+ driver_unregister(&mcpdrv->drv); -+} -+ -+static int __init mcp_init(void) -+{ -+ return bus_register(&mcp_bus_type); -+} -+ -+static void __exit mcp_exit(void) -+{ -+ bus_unregister(&mcp_bus_type); -+} -+ -+module_init(mcp_init); -+module_exit(mcp_exit); -+ -+EXPORT_SYMBOL(mcp_set_telecom_divisor); -+EXPORT_SYMBOL(mcp_set_audio_divisor); -+EXPORT_SYMBOL(mcp_reg_write); -+EXPORT_SYMBOL(mcp_reg_read); -+EXPORT_SYMBOL(mcp_enable); -+EXPORT_SYMBOL(mcp_disable); -+EXPORT_SYMBOL(mcp_host_register); -+EXPORT_SYMBOL(mcp_host_unregister); -+EXPORT_SYMBOL(mcp_driver_register); -+EXPORT_SYMBOL(mcp_driver_unregister); -+ -+MODULE_AUTHOR("Russell King "); -+MODULE_DESCRIPTION("Core multimedia communications port driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/ucb1x00-ts.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,465 @@ -+/* -+ * linux/drivers/misc/ucb1x00-ts.c -+ * -+ * Copyright (C) 2001 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * 21-Jan-2002 : -+ * -+ * Added support for synchronous A/D mode. This mode is useful to -+ * avoid noise induced in the touchpanel by the LCD, provided that -+ * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin. -+ * It is important to note that the signal connected to the ADCSYNC -+ * pin should provide pulses even when the LCD is blanked, otherwise -+ * a pen touch needed to unblank the LCD will never be read. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "ucb1x00.h" -+ -+ -+struct ucb1x00_ts { -+ struct input_dev idev; -+ struct ucb1x00 *ucb; -+ -+ struct semaphore irq_wait; -+ struct semaphore sem; -+ struct completion init_exit; -+ struct task_struct *rtask; -+ int use_count; -+ u16 x_res; -+ u16 y_res; -+ -+ int restart:1; -+ int adcsync:1; -+}; -+ -+static int adcsync = UCB_NOSYNC; -+ -+static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y) -+{ -+ input_report_abs(&ts->idev, ABS_X, x); -+ input_report_abs(&ts->idev, ABS_Y, y); -+ input_report_abs(&ts->idev, ABS_PRESSURE, pressure); -+ input_sync(&ts->idev); -+} -+ -+static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts) -+{ -+ input_report_abs(&ts->idev, ABS_PRESSURE, 0); -+ input_sync(&ts->idev); -+} -+ -+/* -+ * Switch to interrupt mode. -+ */ -+static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts) -+{ -+ if (ts->ucb->id == UCB_ID_1400_BUGGY) -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | -+ UCB_TS_CR_MODE_INT); -+ else -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | -+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | -+ UCB_TS_CR_MODE_INT); -+} -+ -+/* -+ * Switch to pressure mode, and read pressure. We don't need to wait -+ * here, since both plates are being driven. -+ */ -+static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts) -+{ -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | -+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | -+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); -+ -+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync); -+} -+ -+/* -+ * Switch to X position mode and measure Y plate. We switch the plate -+ * configuration in pressure mode, then switch to position mode. This -+ * gives a faster response time. Even so, we need to wait about 55us -+ * for things to stabilise. -+ */ -+static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts) -+{ -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | -+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | -+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | -+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); -+ -+ udelay(55); -+ -+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync); -+} -+ -+/* -+ * Switch to Y position mode and measure X plate. We switch the plate -+ * configuration in pressure mode, then switch to position mode. This -+ * gives a faster response time. Even so, we need to wait about 55us -+ * for things to stabilise. -+ */ -+static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts) -+{ -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | -+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | -+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | -+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); -+ -+ udelay(55); -+ -+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync); -+} -+ -+/* -+ * Switch to X plate resistance mode. Set MX to ground, PX to -+ * supply. Measure current. -+ */ -+static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts) -+{ -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | -+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); -+ return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync); -+} -+ -+/* -+ * Switch to Y plate resistance mode. Set MY to ground, PY to -+ * supply. Measure current. -+ */ -+static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts) -+{ -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, -+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | -+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); -+ return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync); -+} -+ -+/* -+ * This is a RT kernel thread that handles the ADC accesses -+ * (mainly so we can use semaphores in the UCB1200 core code -+ * to serialise accesses to the ADC, and in the UCB1400 case where -+ * any register access may sleep). -+ */ -+static int ucb1x00_thread(void *_ts) -+{ -+ struct ucb1x00_ts *ts = _ts; -+ struct task_struct *tsk = current; -+ int valid; -+ -+ ts->rtask = tsk; -+ -+ daemonize("ktsd"); -+ /* only want to receive SIGKILL */ -+ allow_signal(SIGKILL); -+ -+ /* -+ * We could run as a real-time thread. However, thus far -+ * this doesn't seem to be necessary. -+ */ -+// tsk->policy = SCHED_FIFO; -+// tsk->rt_priority = 1; -+ -+ complete(&ts->init_exit); -+ -+ valid = 0; -+ -+ for (;;) { -+ unsigned int x, y, p, val; -+ -+ ts->restart = 0; -+ -+ ucb1x00_adc_enable(ts->ucb); -+ -+ x = ucb1x00_ts_read_xpos(ts); -+ y = ucb1x00_ts_read_ypos(ts); -+ p = ucb1x00_ts_read_pressure(ts); -+ -+ /* -+ * Switch back to interrupt mode. -+ */ -+ ucb1x00_ts_mode_int(ts); -+ ucb1x00_adc_disable(ts->ucb); -+ -+ set_task_state(tsk, TASK_UNINTERRUPTIBLE); -+ schedule_timeout(HZ / 100); -+ if (signal_pending(tsk)) -+ break; -+ -+ ucb1x00_enable(ts->ucb); -+ val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR); -+ -+ if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) { -+ ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING); -+ ucb1x00_disable(ts->ucb); -+ -+ /* -+ * If we spat out a valid sample set last time, -+ * spit out a "pen off" sample here. -+ */ -+ if (valid) { -+ ucb1x00_ts_event_release(ts); -+ valid = 0; -+ } -+ -+ /* -+ * Since ucb1x00_enable_irq() might sleep due -+ * to the way the UCB1400 regs are accessed, we -+ * can't use set_task_state() before that call, -+ * and not changing state before enabling the -+ * interrupt is racy. A semaphore solves all -+ * those issues quite nicely. -+ */ -+ down_interruptible(&ts->irq_wait); -+ } else { -+ ucb1x00_disable(ts->ucb); -+ -+ /* -+ * Filtering is policy. Policy belongs in user -+ * space. We therefore leave it to user space -+ * to do any filtering they please. -+ */ -+ if (!ts->restart) { -+ ucb1x00_ts_evt_add(ts, p, x, y); -+ valid = 1; -+ } -+ -+ set_task_state(tsk, TASK_INTERRUPTIBLE); -+ } -+ -+ schedule_timeout(HZ / 100); -+ if (signal_pending(tsk)) -+ break; -+ } -+ -+ ts->rtask = NULL; -+ complete_and_exit(&ts->init_exit, 0); -+} -+ -+/* -+ * We only detect touch screen _touches_ with this interrupt -+ * handler, and even then we just schedule our task. -+ */ -+static void ucb1x00_ts_irq(int idx, void *id) -+{ -+ struct ucb1x00_ts *ts = id; -+ ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING); -+ up(&ts->irq_wait); -+} -+ -+static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts) -+{ -+ input_report_abs(&ts->idev, ABS_PRESSURE, 0); -+} -+ -+static int ucb1x00_ts_open(struct input_dev *idev) -+{ -+ struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev; -+ int ret = 0; -+ -+ if (down_interruptible(&ts->sem)) -+ return -EINTR; -+ -+ if (ts->use_count++ != 0) -+ goto out; -+ -+ if (ts->rtask) -+ panic("ucb1x00: rtask running?"); -+ -+ sema_init(&ts->irq_wait, 0); -+ ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts); -+ if (ret < 0) -+ goto out; -+ -+ /* -+ * If we do this at all, we should allow the user to -+ * measure and read the X and Y resistance at any time. -+ */ -+ ucb1x00_adc_enable(ts->ucb); -+ ts->x_res = ucb1x00_ts_read_xres(ts); -+ ts->y_res = ucb1x00_ts_read_yres(ts); -+ ucb1x00_adc_disable(ts->ucb); -+ -+ init_completion(&ts->init_exit); -+ ret = kernel_thread(ucb1x00_thread, ts, CLONE_KERNEL); -+ if (ret >= 0) { -+ wait_for_completion(&ts->init_exit); -+ ret = 0; -+ } else { -+ ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts); -+ } -+ -+ out: -+ if (ret) -+ ts->use_count--; -+ up(&ts->sem); -+ return ret; -+} -+ -+/* -+ * Release touchscreen resources. Disable IRQs. -+ */ -+static void ucb1x00_ts_close(struct input_dev *idev) -+{ -+ struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev; -+ -+ down(&ts->sem); -+ if (--ts->use_count == 0) { -+ if (ts->rtask) { -+ send_sig(SIGKILL, ts->rtask, 1); -+ wait_for_completion(&ts->init_exit); -+ } -+ -+ ucb1x00_enable(ts->ucb); -+ ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts); -+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0); -+ ucb1x00_disable(ts->ucb); -+ } -+ up(&ts->sem); -+} -+ -+#if 0 -+static int ucb1x00_ts_resume(struct device *_dev, u32 level) -+{ -+ struct ucb1x00_device *dev = ucb1x00_dev(_dev); -+ struct ucb1x00_ts *ts = ucb1x00_get_drvdata(dev); -+ -+ if (level == RESUME_ENABLE && ts->rtask != NULL) { -+ /* -+ * Restart the TS thread to ensure the -+ * TS interrupt mode is set up again -+ * after sleep. -+ */ -+ ts->restart = 1; -+ up(&ts->irq_wait); -+ } -+ return 0; -+} -+#endif -+ -+ -+/* -+ * Initialisation. -+ */ -+static int ucb1x00_ts_add(struct class_device *dev) -+{ -+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); -+ struct ucb1x00_ts *ts; -+ -+ ts = kmalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL); -+ if (!ts) -+ return -ENOMEM; -+ -+ memset(ts, 0, sizeof(struct ucb1x00_ts)); -+ -+ ts->ucb = ucb; -+ ts->adcsync = adcsync; -+ init_MUTEX(&ts->sem); -+ -+ ts->idev.name = "Touchscreen panel"; -+ ts->idev.id.product = ts->ucb->id; -+ ts->idev.open = ucb1x00_ts_open; -+ ts->idev.close = ucb1x00_ts_close; -+ -+ __set_bit(EV_ABS, ts->idev.evbit); -+ __set_bit(ABS_X, ts->idev.absbit); -+ __set_bit(ABS_Y, ts->idev.absbit); -+ __set_bit(ABS_PRESSURE, ts->idev.absbit); -+ -+ input_register_device(&ts->idev); -+ -+ ucb->ts_data = ts; -+ -+ return 0; -+} -+ -+static void ucb1x00_ts_remove(struct class_device *dev) -+{ -+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); -+ struct ucb1x00_ts *ts = ucb->ts_data; -+ -+ input_unregister_device(&ts->idev); -+ kfree(ts); -+} -+ -+static struct class_interface ucb1x00_ts_interface = { -+ .add = ucb1x00_ts_add, -+ .remove = ucb1x00_ts_remove, -+}; -+ -+static int __init ucb1x00_ts_init(void) -+{ -+ return ucb1x00_register_interface(&ucb1x00_ts_interface); -+} -+ -+static void __exit ucb1x00_ts_exit(void) -+{ -+ ucb1x00_unregister_interface(&ucb1x00_ts_interface); -+} -+ -+#ifndef MODULE -+ -+/* -+ * Parse kernel command-line options. -+ * -+ * syntax : ucbts=[sync|nosync],... -+ */ -+static int __init ucb1x00_ts_setup(char *str) -+{ -+ char *p; -+ -+ while ((p = strsep(&str, ",")) != NULL) { -+ if (strcmp(p, "sync") == 0) -+ adcsync = UCB_SYNC; -+ } -+ -+ return 1; -+} -+ -+__setup("ucbts=", ucb1x00_ts_setup); -+ -+#else -+ -+MODULE_PARM(adcsync, "i"); -+MODULE_PARM_DESC(adcsync, "Enable use of ADCSYNC signal"); -+ -+#endif -+ -+module_init(ucb1x00_ts_init); -+module_exit(ucb1x00_ts_exit); -+ -+MODULE_AUTHOR("Russell King "); -+MODULE_DESCRIPTION("UCB1x00 touchscreen driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/ucb1x00-core.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,624 @@ -+/* -+ * linux/drivers/misc/ucb1x00-core.c -+ * -+ * Copyright (C) 2001 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License. -+ * -+ * The UCB1x00 core driver provides basic services for handling IO, -+ * the ADC, interrupts, and accessing registers. It is designed -+ * such that everything goes through this layer, thereby providing -+ * a consistent locking methodology, as well as allowing the drivers -+ * to be used on other non-MCP-enabled hardware platforms. -+ * -+ * Note that all locks are private to this file. Nothing else may -+ * touch them. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "ucb1x00.h" -+ -+/** -+ * ucb1x00_io_set_dir - set IO direction -+ * @ucb: UCB1x00 structure describing chip -+ * @in: bitfield of IO pins to be set as inputs -+ * @out: bitfield of IO pins to be set as outputs -+ * -+ * Set the IO direction of the ten general purpose IO pins on -+ * the UCB1x00 chip. The @in bitfield has priority over the -+ * @out bitfield, in that if you specify a pin as both input -+ * and output, it will end up as an input. -+ * -+ * ucb1x00_enable must have been called to enable the comms -+ * before using this function. -+ * -+ * This function takes a spinlock, disabling interrupts. -+ */ -+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int in, unsigned int out) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ucb->io_lock, flags); -+ ucb->io_dir |= out; -+ ucb->io_dir &= ~in; -+ -+ ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); -+ spin_unlock_irqrestore(&ucb->io_lock, flags); -+} -+ -+/** -+ * ucb1x00_io_write - set or clear IO outputs -+ * @ucb: UCB1x00 structure describing chip -+ * @set: bitfield of IO pins to set to logic '1' -+ * @clear: bitfield of IO pins to set to logic '0' -+ * -+ * Set the IO output state of the specified IO pins. The value -+ * is retained if the pins are subsequently configured as inputs. -+ * The @clear bitfield has priority over the @set bitfield - -+ * outputs will be cleared. -+ * -+ * ucb1x00_enable must have been called to enable the comms -+ * before using this function. -+ * -+ * This function takes a spinlock, disabling interrupts. -+ */ -+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ucb->io_lock, flags); -+ ucb->io_out |= set; -+ ucb->io_out &= ~clear; -+ -+ ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); -+ spin_unlock_irqrestore(&ucb->io_lock, flags); -+} -+ -+/** -+ * ucb1x00_io_read - read the current state of the IO pins -+ * @ucb: UCB1x00 structure describing chip -+ * -+ * Return a bitfield describing the logic state of the ten -+ * general purpose IO pins. -+ * -+ * ucb1x00_enable must have been called to enable the comms -+ * before using this function. -+ * -+ * This function does not take any semaphores or spinlocks. -+ */ -+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb) -+{ -+ return ucb1x00_reg_read(ucb, UCB_IO_DATA); -+} -+ -+/* -+ * UCB1300 data sheet says we must: -+ * 1. enable ADC => 5us (including reference startup time) -+ * 2. select input => 51*tsibclk => 4.3us -+ * 3. start conversion => 102*tsibclk => 8.5us -+ * (tsibclk = 1/11981000) -+ * Period between SIB 128-bit frames = 10.7us -+ */ -+ -+/** -+ * ucb1x00_adc_enable - enable the ADC converter -+ * @ucb: UCB1x00 structure describing chip -+ * -+ * Enable the ucb1x00 and ADC converter on the UCB1x00 for use. -+ * Any code wishing to use the ADC converter must call this -+ * function prior to using it. -+ * -+ * This function takes the ADC semaphore to prevent two or more -+ * concurrent uses, and therefore may sleep. As a result, it -+ * can only be called from process context, not interrupt -+ * context. -+ * -+ * You should release the ADC as soon as possible using -+ * ucb1x00_adc_disable. -+ */ -+void ucb1x00_adc_enable(struct ucb1x00 *ucb) -+{ -+ down(&ucb->adc_sem); -+ -+ ucb->adc_cr |= UCB_ADC_ENA; -+ -+ ucb1x00_enable(ucb); -+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr); -+} -+ -+/** -+ * ucb1x00_adc_read - read the specified ADC channel -+ * @ucb: UCB1x00 structure describing chip -+ * @adc_channel: ADC channel mask -+ * @sync: wait for syncronisation pulse. -+ * -+ * Start an ADC conversion and wait for the result. Note that -+ * synchronised ADC conversions (via the ADCSYNC pin) must wait -+ * until the trigger is asserted and the conversion is finished. -+ * -+ * This function currently spins waiting for the conversion to -+ * complete (2 frames max without sync). -+ * -+ * If called for a synchronised ADC conversion, it may sleep -+ * with the ADC semaphore held. -+ * -+ * See ucb1x00.h for definition of the UCB_ADC_DAT macro. It -+ * addresses a bug in the ucb1200/1300 which, of course, Philips -+ * decided to finally fix in the ucb1400 ;-) -jws -+ */ -+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync) -+{ -+ unsigned int val; -+ -+ if (sync) -+ adc_channel |= UCB_ADC_SYNC_ENA; -+ -+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel); -+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel | UCB_ADC_START); -+ -+ for (;;) { -+ val = ucb1x00_reg_read(ucb, UCB_ADC_DATA); -+ if (val & UCB_ADC_DAT_VAL) -+ break; -+ /* yield to other processes */ -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(1); -+ } -+ -+ return UCB_ADC_DAT(val); -+} -+ -+/** -+ * ucb1x00_adc_disable - disable the ADC converter -+ * @ucb: UCB1x00 structure describing chip -+ * -+ * Disable the ADC converter and release the ADC semaphore. -+ */ -+void ucb1x00_adc_disable(struct ucb1x00 *ucb) -+{ -+ ucb->adc_cr &= ~UCB_ADC_ENA; -+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr); -+ ucb1x00_disable(ucb); -+ -+ up(&ucb->adc_sem); -+} -+ -+/* -+ * UCB1x00 Interrupt handling. -+ * -+ * The UCB1x00 can generate interrupts when the SIBCLK is stopped. -+ * Since we need to read an internal register, we must re-enable -+ * SIBCLK to talk to the chip. We leave the clock running until -+ * we have finished processing all interrupts from the chip. -+ * -+ * A restriction with interrupts exists when using the ucb1400, as -+ * the codec read/write routines may sleep while waiting for codec -+ * access completion and uses semaphores for access control to the -+ * AC97 bus. A complete codec read cycle could take anywhere from -+ * 60 to 100uSec so we *definitely* don't want to spin inside the -+ * interrupt handler waiting for codec access. So, we handle the -+ * interrupt by scheduling a RT kernel thread to run in process -+ * context instead of interrupt context. -+ */ -+ -+static int ucb1x00_thread(void *_ucb) -+{ -+ struct task_struct *tsk = current; -+ DECLARE_WAITQUEUE(wait, tsk); -+ struct ucb1x00 *ucb = _ucb; -+ struct ucb1x00_irq *irq; -+ unsigned int isr, i; -+ -+ ucb->rtask = tsk; -+ -+ daemonize(); -+ reparent_to_init(); -+ tsk->tty = NULL; -+ tsk->policy = SCHED_FIFO; -+ tsk->rt_priority = 1; -+ strcpy(tsk->comm, "kUCB1x00d"); -+ -+ /* only want to receive SIGKILL */ -+ spin_lock_irq(&tsk->sigmask_lock); -+ siginitsetinv(&tsk->blocked, sigmask(SIGKILL)); -+ recalc_sigpending(); -+ spin_unlock_irq(&tsk->sigmask_lock); -+ -+ add_wait_queue(&ucb->irq_wait, &wait); -+ set_task_state(tsk, TASK_INTERRUPTIBLE); -+ complete(&ucb->complete); -+ -+ for (;;) { -+ if (signal_pending(tsk)) -+ break; -+ enable_irq(ucb->irq); -+ schedule(); -+ -+ ucb1x00_enable(ucb); -+ isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS); -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr); -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); -+ -+ for (i = 0, irq = ucb->irq_handler; -+ i < 16 && isr; -+ i++, isr >>= 1, irq++) -+ if (isr & 1 && irq->fn) -+ irq->fn(i, irq->devid); -+ ucb1x00_disable(ucb); -+ -+ set_task_state(tsk, TASK_INTERRUPTIBLE); -+ } -+ -+ remove_wait_queue(&ucb->irq_wait, &wait); -+ ucb->rtask = NULL; -+ complete_and_exit(&ucb->complete, 0); -+} -+ -+static irqreturn_t ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs) -+{ -+ struct ucb1x00 *ucb = devid; -+ disable_irq(irqnr); -+ wake_up(&ucb->irq_wait); -+ return IRQ_HANDLED; -+} -+ -+/** -+ * ucb1x00_hook_irq - hook a UCB1x00 interrupt -+ * @ucb: UCB1x00 structure describing chip -+ * @idx: interrupt index -+ * @fn: function to call when interrupt is triggered -+ * @devid: device id to pass to interrupt handler -+ * -+ * Hook the specified interrupt. You can only register one handler -+ * for each interrupt source. The interrupt source is not enabled -+ * by this function; use ucb1x00_enable_irq instead. -+ * -+ * Interrupt handlers will be called with other interrupts enabled. -+ * -+ * Returns zero on success, or one of the following errors: -+ * -EINVAL if the interrupt index is invalid -+ * -EBUSY if the interrupt has already been hooked -+ */ -+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid) -+{ -+ struct ucb1x00_irq *irq; -+ int ret = -EINVAL; -+ -+ if (idx < 16) { -+ irq = ucb->irq_handler + idx; -+ ret = -EBUSY; -+ -+ spin_lock_irq(&ucb->lock); -+ if (irq->fn == NULL) { -+ irq->devid = devid; -+ irq->fn = fn; -+ ret = 0; -+ } -+ spin_unlock_irq(&ucb->lock); -+ } -+ return ret; -+} -+ -+/** -+ * ucb1x00_enable_irq - enable an UCB1x00 interrupt source -+ * @ucb: UCB1x00 structure describing chip -+ * @idx: interrupt index -+ * @edges: interrupt edges to enable -+ * -+ * Enable the specified interrupt to trigger on %UCB_RISING, -+ * %UCB_FALLING or both edges. The interrupt should have been -+ * hooked by ucb1x00_hook_irq. -+ */ -+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges) -+{ -+ unsigned long flags; -+ -+ if (idx < 16) { -+ spin_lock_irqsave(&ucb->lock, flags); -+ -+ ucb1x00_enable(ucb); -+ -+ /* This prevents spurious interrupts on the UCB1400 */ -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 1 << idx); -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); -+ -+ if (edges & UCB_RISING) { -+ ucb->irq_ris_enbl |= 1 << idx; -+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); -+ } -+ if (edges & UCB_FALLING) { -+ ucb->irq_fal_enbl |= 1 << idx; -+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); -+ } -+ ucb1x00_disable(ucb); -+ spin_unlock_irqrestore(&ucb->lock, flags); -+ } -+} -+ -+/** -+ * ucb1x00_disable_irq - disable an UCB1x00 interrupt source -+ * @ucb: UCB1x00 structure describing chip -+ * @edges: interrupt edges to disable -+ * -+ * Disable the specified interrupt triggering on the specified -+ * (%UCB_RISING, %UCB_FALLING or both) edges. -+ */ -+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges) -+{ -+ unsigned long flags; -+ -+ if (idx < 16) { -+ spin_lock_irqsave(&ucb->lock, flags); -+ -+ ucb1x00_enable(ucb); -+ if (edges & UCB_RISING) { -+ ucb->irq_ris_enbl &= ~(1 << idx); -+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); -+ } -+ if (edges & UCB_FALLING) { -+ ucb->irq_fal_enbl &= ~(1 << idx); -+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); -+ } -+ ucb1x00_disable(ucb); -+ spin_unlock_irqrestore(&ucb->lock, flags); -+ } -+} -+ -+/** -+ * ucb1x00_free_irq - disable and free the specified UCB1x00 interrupt -+ * @ucb: UCB1x00 structure describing chip -+ * @idx: interrupt index -+ * @devid: device id. -+ * -+ * Disable the interrupt source and remove the handler. devid must -+ * match the devid passed when hooking the interrupt. -+ * -+ * Returns zero on success, or one of the following errors: -+ * -EINVAL if the interrupt index is invalid -+ * -ENOENT if devid does not match -+ */ -+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid) -+{ -+ struct ucb1x00_irq *irq; -+ int ret; -+ -+ if (idx >= 16) -+ goto bad; -+ -+ irq = ucb->irq_handler + idx; -+ ret = -ENOENT; -+ -+ spin_lock_irq(&ucb->lock); -+ if (irq->devid == devid) { -+ ucb->irq_ris_enbl &= ~(1 << idx); -+ ucb->irq_fal_enbl &= ~(1 << idx); -+ -+ ucb1x00_enable(ucb); -+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); -+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); -+ ucb1x00_disable(ucb); -+ -+ irq->fn = NULL; -+ irq->devid = NULL; -+ ret = 0; -+ } -+ spin_unlock_irq(&ucb->lock); -+ return ret; -+ -+bad: -+ printk(KERN_ERR "Freeing bad UCB1x00 irq %d\n", idx); -+ return -EINVAL; -+} -+ -+/* -+ * Try to probe our interrupt, rather than relying on lots of -+ * hard-coded machine dependencies. For reference, the expected -+ * IRQ mappings are: -+ * -+ * Machine Default IRQ -+ * adsbitsy IRQ_GPCIN4 -+ * cerf IRQ_GPIO_UCB1200_IRQ -+ * flexanet IRQ_GPIO_GUI -+ * freebird IRQ_GPIO_FREEBIRD_UCB1300_IRQ -+ * graphicsclient ADS_EXT_IRQ(8) -+ * graphicsmaster ADS_EXT_IRQ(8) -+ * lart LART_IRQ_UCB1200 -+ * omnimeter IRQ_GPIO23 -+ * pfs168 IRQ_GPIO_UCB1300_IRQ -+ * simpad IRQ_GPIO_UCB1300_IRQ -+ * shannon SHANNON_IRQ_GPIO_IRQ_CODEC -+ * yopy IRQ_GPIO_UCB1200_IRQ -+ */ -+static int ucb1x00_detect_irq(struct ucb1x00 *ucb) -+{ -+ unsigned long mask; -+ -+ mask = probe_irq_on(); -+ if (!mask) -+ return NO_IRQ; -+ -+ /* -+ * Enable the ADC interrupt. -+ */ -+ ucb1x00_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC); -+ ucb1x00_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC); -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff); -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); -+ -+ /* -+ * Cause an ADC interrupt. -+ */ -+ ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA); -+ ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START); -+ -+ /* -+ * Wait for the conversion to complete. -+ */ -+ while ((ucb1x00_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VAL) == 0); -+ ucb1x00_reg_write(ucb, UCB_ADC_CR, 0); -+ -+ /* -+ * Disable and clear interrupt. -+ */ -+ ucb1x00_reg_write(ucb, UCB_IE_RIS, 0); -+ ucb1x00_reg_write(ucb, UCB_IE_FAL, 0); -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff); -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); -+ -+ /* -+ * Read triggered interrupt. -+ */ -+ return probe_irq_off(mask); -+} -+ -+static int ucb1x00_probe(struct mcp *mcp) -+{ -+ struct ucb1x00 *ucb; -+ unsigned int id; -+ int ret = -ENODEV; -+ -+ mcp_enable(mcp); -+ id = mcp_reg_read(mcp, UCB_ID); -+ -+ if (id != UCB_ID_1200 && id != UCB_ID_1300) { -+ printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); -+ goto err_disable; -+ } -+ -+ ucb = kmalloc(sizeof(struct ucb1x00), GFP_KERNEL); -+ ret = -ENOMEM; -+ if (!ucb) -+ goto err_disable; -+ -+ memset(ucb, 0, sizeof(struct ucb1x00)); -+ -+ ucb->cdev.class = &ucb1x00_class; -+ ucb->cdev.dev = &mcp->attached_device; -+ strlcpy(ucb->cdev.class_id, "ucb1x00", sizeof(ucb->cdev.class_id)); -+ -+ spin_lock_init(&ucb->lock); -+ spin_lock_init(&ucb->io_lock); -+ sema_init(&ucb->adc_sem, 1); -+ -+ ucb->id = id; -+ ucb->mcp = mcp; -+ ucb->irq = ucb1x00_detect_irq(ucb); -+ if (ucb->irq == NO_IRQ) { -+ printk(KERN_ERR "UCB1x00: IRQ probe failed\n"); -+ ret = -ENODEV; -+ goto err_free; -+ } -+ -+ ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb); -+ if (ret) { -+ printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", -+ ucb->irq, ret); -+ goto err_free; -+ } -+ -+ set_irq_type(ucb->irq, IRQT_RISING); -+ mcp_set_drvdata(mcp, ucb); -+ -+ ret = class_device_register(&ucb->cdev); -+ if (ret) { -+ free_irq(ucb->irq, ucb); -+ err_free: -+ kfree(ucb); -+ } -+ err_disable: -+ mcp_disable(mcp); -+ return ret; -+} -+ -+static void ucb1x00_remove(struct mcp *mcp) -+{ -+ struct ucb1x00 *ucb = mcp_get_drvdata(mcp); -+ -+ class_device_unregister(&ucb->cdev); -+ free_irq(ucb->irq, ucb); -+} -+ -+static void ucb1x00_release(struct class_device *dev) -+{ -+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); -+ kfree(ucb); -+} -+ -+static struct class ucb1x00_class = { -+ .name = "ucb1x00", -+ .release = ucb1x00_release, -+}; -+ -+int ucb1x00_register_interface(struct class_interface *intf) -+{ -+ intf->class = &ucb1x00_class; -+ return class_interface_register(intf); -+} -+ -+void ucb1x00_unregister_interface(struct class_interface *intf) -+{ -+ class_interface_unregister(intf); -+} -+ -+static struct mcp_driver ucb1x00_driver = { -+ .drv = { -+ .name = "ucb1x00", -+ }, -+ .probe = ucb1x00_probe, -+ .remove = ucb1x00_remove, -+}; -+ -+static int __init ucb1x00_init(void) -+{ -+ int ret = class_register(&ucb1x00_class); -+ if (ret == 0) { -+ ret = mcp_driver_register(&ucb1x00_driver); -+ if (ret) -+ class_unregister(&ucb1x00_class); -+ } -+ return ret; -+} -+ -+static void __exit ucb1x00_exit(void) -+{ -+ mcp_driver_unregister(&ucb1x00_driver); -+ class_unregister(&ucb1x00_class); -+} -+ -+module_init(ucb1x00_init); -+module_exit(ucb1x00_exit); -+ -+EXPORT_SYMBOL(ucb1x00_class); -+ -+EXPORT_SYMBOL(ucb1x00_io_set_dir); -+EXPORT_SYMBOL(ucb1x00_io_write); -+EXPORT_SYMBOL(ucb1x00_io_read); -+ -+EXPORT_SYMBOL(ucb1x00_adc_enable); -+EXPORT_SYMBOL(ucb1x00_adc_read); -+EXPORT_SYMBOL(ucb1x00_adc_disable); -+ -+EXPORT_SYMBOL(ucb1x00_hook_irq); -+EXPORT_SYMBOL(ucb1x00_free_irq); -+EXPORT_SYMBOL(ucb1x00_enable_irq); -+EXPORT_SYMBOL(ucb1x00_disable_irq); -+ -+EXPORT_SYMBOL(ucb1x00_register_interface); -+EXPORT_SYMBOL(ucb1x00_unregister_interface); -+ -+MODULE_AUTHOR("Russell King "); -+MODULE_DESCRIPTION("UCB1x00 core driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/switches-ucb1x00.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,214 @@ -+/* -+ * linux/drivers/misc/switches-ucb1x00.c -+ * -+ * Copyright (C) 2001 John Dorsey -+ * -+ * 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. -+ * -+ * 19 December 2001 - created from sa1100_switches.c. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_SA1100_ASSABET -+#include -+#endif -+ -+#include "switches.h" -+#include "ucb1x00.h" -+ -+ -+static void switches_ucb1x00_handler(int irq, void *devid); -+ -+ -+#ifdef CONFIG_SA1100_ASSABET -+ -+/* Assabet -+ * ^^^^^^^ -+ * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8. -+ * This code sets bits in the range [3, 8] in the mask that we -+ * return to userland. Note that we transpose signals SW7 and SW8; -+ * see assabet_switches_ucb1x00_handler(). -+ */ -+ -+static int assabet_switches_ucb1x00_init(struct ucb1x00 *ucb) -+{ -+ int i; -+ -+ ucb1x00_enable(ucb); -+ -+ ucb1x00_io_set_dir(ucb, -+ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 | -+ UCB_IO_3 | UCB_IO_4 | UCB_IO_5, 0); -+ -+ for (i = 0; i < 6; ++i) { -+ ucb1x00_enable_irq(ucb, i, UCB_RISING | UCB_FALLING); -+ -+ if (ucb1x00_hook_irq(ucb, i, -+ switches_ucb1x00_handler, ucb) < 0) { -+ printk(KERN_ERR "%s: unable to hook IRQ for " -+ "UCB1300 IO_%d\n", SWITCHES_NAME, i); -+ -+ /* FIXME: BUGGY ERROR HANDLING */ -+ return -EBUSY; -+ } -+ -+ } -+ -+ ucb1x00_disable(ucb); -+ -+ return 0; -+ -+} -+ -+static void assabet_switches_ucb1x00_shutdown(struct ucb1x00 *ucb) -+{ -+ int i; -+ -+ ucb1x00_enable(ucb); -+ -+ for (i = 5; i >= 0; --i) { -+ ucb1x00_disable_irq(ucb, i, UCB_RISING | UCB_FALLING); -+ -+ /* Only error conditions are ENOENT and EINVAL; silently -+ * ignore: -+ */ -+ ucb1x00_free_irq(ucb, i, ucb); -+ } -+ -+ ucb1x00_disable(ucb); -+} -+ -+static void assabet_switches_ucb1x00_handler(struct ucb1x00 *ucb, int irq, switches_mask_t *mask) -+{ -+ unsigned int last, this; -+ static unsigned int states = 0; -+ -+ last = ((states & (1 << irq)) != 0); -+ this = ((ucb1x00_io_read(ucb) & (1 << irq)) != 0); -+ -+ if (last == this) /* debounce */ -+ return; -+ -+ /* Intel StrongARM SA-1110 Development Board -+ * Schematics Figure 5, Sheet 5 of 12 -+ * -+ * See switches S8 and S7. Notice their -+ * relationship to signals SW7 and SW8. Hmmm. -+ */ -+ -+ switch (irq) { -+ -+ case 4: -+ -+ SWITCHES_SET(mask, 8, this); -+ break; -+ -+ case 5: -+ -+ SWITCHES_SET(mask, 7, this); -+ break; -+ -+ default: -+ -+ SWITCHES_SET(mask, irq + 3, this); -+ -+ } -+ -+ states = this ? (states | (1 << irq)) : (states & ~(1 << irq)); -+ -+} -+#endif /* CONFIG_SA1100_ASSABET */ -+ -+ -+/* switches_ucb1x00_handler() -+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^ -+ * This routine is a generalized handler for UCB1x00 GPIO switches -+ * which calls a board-specific service routine and passes an event -+ * mask to the core event handler. This routine is appropriate for -+ * systems which use the ucb1x00 framework, and can be registered -+ * using ucb1x00_hook_irq(). -+ */ -+static void switches_ucb1x00_handler(int irq, void *devid) -+{ -+ struct ucb1x00 *ucb = devid; -+ switches_mask_t mask; -+ -+ SWITCHES_ZERO(&mask); -+ -+ /* Porting note: call a board-specific UCB1x00 switch handler here. -+ * The handler can assume that sufficient storage for `mask' has -+ * been allocated, and that the corresponding switches_mask_t -+ * structure has been zeroed. -+ */ -+ -+#ifdef CONFIG_SA1100_ASSABET -+ if (machine_is_assabet()) { -+ assabet_switches_ucb1x00_handler(ucb, irq, &mask); -+ } -+#endif -+ -+ switches_event(&mask); -+} -+ -+static int switches_add(struct class_device *dev) -+{ -+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); -+ int ret = -ENODEV; -+ -+#ifdef CONFIG_SA1100_ASSABET -+ if (machine_is_assabet()) { -+ ret = assabet_switches_ucb1x00_init(ucb); -+ } -+#endif -+ /* Porting note: call a board-specific init routine here. */ -+ -+ return ret; -+} -+ -+static void switches_remove(struct class_device *dev) -+{ -+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); -+ -+ /* Porting note: call a board-specific shutdown routine here. */ -+ -+#ifdef CONFIG_SA1100_ASSABET -+ if (machine_is_assabet()) { -+ assabet_switches_ucb1x00_shutdown(ucb); -+ } -+#endif -+} -+ -+static struct class_interface ucb1x00_switches_interface = { -+ .add = switches_add, -+ .remove = switches_remove, -+}; -+ -+static int __init switches_ucb1x00_init(void) -+{ -+ return ucb1x00_register_interface(&ucb1x00_switches_interface); -+} -+ -+static void __exit switches_ucb1x00_exit(void) -+{ -+ ucb1x00_unregister_interface(&ucb1x00_switches_interface); -+} -+ -+module_init(switches_ucb1x00_init); -+module_exit(switches_ucb1x00_exit); -+ -+MODULE_DESCRIPTION("ucb1x00 switches driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/switches-core.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,200 @@ -+/* -+ * linux/drivers/misc/switches-core.c -+ * -+ * Copyright (C) 2000-2001 John Dorsey -+ * -+ * 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. -+ * -+ * 5 October 2000 - created. -+ * -+ * 25 October 2000 - userland file interface added. -+ * -+ * 13 January 2001 - added support for Spot. -+ * -+ * 11 September 2001 - UCB1200 driver framework support added. -+ * -+ * 19 December 2001 - separated out SA-1100 and UCB1x00 code. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "switches.h" -+ -+ -+MODULE_AUTHOR("John Dorsey"); -+MODULE_DESCRIPTION("Console switch support"); -+MODULE_LICENSE("GPL"); -+ -+ -+struct switches_action { -+ struct list_head list; -+ switches_mask_t mask; -+}; -+ -+ -+static int switches_users = 0; -+ -+static spinlock_t switches_lock = SPIN_LOCK_UNLOCKED; -+ -+DECLARE_WAIT_QUEUE_HEAD(switches_wait); -+LIST_HEAD(switches_event_queue); -+ -+ -+static ssize_t switches_read(struct file *file, char *buffer, -+ size_t count, loff_t *pos) -+{ -+ unsigned long flags; -+ struct list_head *event; -+ struct switches_action *action; -+ -+ if (count < sizeof(struct switches_mask_t)) -+ return -EINVAL; -+ -+ while (list_empty(&switches_event_queue)) { -+ -+ if (file->f_flags & O_NDELAY) -+ return -EAGAIN; -+ -+ interruptible_sleep_on(&switches_wait); -+ -+ if (signal_pending(current)) -+ return -ERESTARTSYS; -+ -+ } -+ -+ if (verify_area(VERIFY_WRITE, buffer, sizeof(struct switches_mask_t))) -+ return -EFAULT; -+ -+ spin_lock_irqsave(&switches_lock, flags); -+ -+ event = switches_event_queue.next; -+ action = list_entry(event, struct switches_action, list); -+ copy_to_user(buffer, &(action->mask), sizeof(struct switches_mask_t)); -+ list_del(event); -+ kfree(action); -+ -+ spin_unlock_irqrestore(&switches_lock, flags); -+ -+ return 0; -+ -+} -+ -+static ssize_t switches_write(struct file *file, const char *buffer, -+ size_t count, loff_t *ppos) -+{ -+ return -EINVAL; -+} -+ -+static unsigned int switches_poll(struct file *file, poll_table *wait) -+{ -+ -+ poll_wait(file, &switches_wait, wait); -+ -+ if (!list_empty(&switches_event_queue)) -+ return POLLIN | POLLRDNORM; -+ -+ return 0; -+ -+} -+ -+static int switches_open(struct inode *inode, struct file *file) -+{ -+ -+ if (switches_users > 0) -+ return -EBUSY; -+ -+ ++switches_users; -+ return 0; -+ -+} -+ -+static int switches_release(struct inode *inode, struct file *file) -+{ -+ -+ --switches_users; -+ return 0; -+ -+} -+ -+static struct file_operations switches_ops = { -+ .owner = THIS_MODULE, -+ .read = switches_read, -+ .write = switches_write, -+ .poll = switches_poll, -+ .open = switches_open, -+ .release = switches_release, -+}; -+ -+static struct miscdevice switches_misc = { -+ .minor = MISC_DYNAMIC_MINOR, -+ .name = SWITCHES_NAME, -+ .fops = &switches_ops, -+}; -+ -+int switches_event(switches_mask_t *mask) -+{ -+ struct switches_action *action; -+ -+ if ((switches_users > 0) && (SWITCHES_COUNT(mask) > 0)) { -+ -+ if ((action = (struct switches_action *) -+ kmalloc(sizeof(struct switches_action), -+ GFP_KERNEL)) == NULL) { -+ printk(KERN_ERR "%s: unable to allocate action " -+ "descriptor\n", SWITCHES_NAME); -+ return -1; -+ } -+ -+ action->mask = *mask; -+ -+ spin_lock(&switches_lock); -+ list_add_tail(&action->list, &switches_event_queue); -+ spin_unlock(&switches_lock); -+ -+ wake_up_interruptible(&switches_wait); -+ -+ } -+ -+ return 0; -+ -+} -+ -+EXPORT_SYMBOL(switches_event); -+ -+ -+static int __init switches_init(void) -+{ -+ if (misc_register(&switches_misc) < 0) { -+ printk(KERN_ERR "%s: unable to register misc device\n", -+ SWITCHES_NAME); -+ return -EIO; -+ } -+ -+ printk(KERN_INFO "Console switches initialized\n"); -+ -+ return 0; -+} -+ -+static void __exit switches_exit(void) -+{ -+ if (misc_deregister(&switches_misc) < 0) -+ printk(KERN_ERR "%s: unable to deregister misc device\n", -+ SWITCHES_NAME); -+} -+ -+module_init(switches_init); -+module_exit(switches_exit); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/ucb1x00-audio.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,439 @@ -+/* -+ * linux/drivers/misc/ucb1x00-audio.c -+ * -+ * Copyright (C) 2001 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "ucb1x00.h" -+ -+#include "../sound/oss/sa1100-audio.h" -+ -+#define MAGIC 0x41544154 -+ -+struct ucb1x00_audio { -+ struct file_operations fops; -+ struct file_operations mops; -+ struct ucb1x00 *ucb; -+ audio_stream_t output_stream; -+ audio_stream_t input_stream; -+ audio_state_t state; -+ unsigned int rate; -+ int dev_id; -+ int mix_id; -+ unsigned int daa_oh_bit; -+ unsigned int telecom; -+ unsigned int magic; -+ unsigned int ctrl_a; -+ unsigned int ctrl_b; -+ -+ /* mixer info */ -+ unsigned int mod_cnt; -+ unsigned short output_level; -+ unsigned short input_level; -+}; -+ -+#define REC_MASK (SOUND_MASK_VOLUME | SOUND_MASK_MIC) -+#define DEV_MASK REC_MASK -+ -+static int -+ucb1x00_mixer_ioctl(struct inode *ino, struct file *filp, uint cmd, ulong arg) -+{ -+ struct ucb1x00_audio *ucba; -+ unsigned int val, gain; -+ int ret = 0; -+ -+ ucba = list_entry(filp->f_op, struct ucb1x00_audio, mops); -+ -+ if (_IOC_TYPE(cmd) != 'M') -+ return -EINVAL; -+ -+ if (cmd == SOUND_MIXER_INFO) { -+ struct mixer_info mi; -+ -+ strncpy(mi.id, "UCB1x00", sizeof(mi.id)); -+ strncpy(mi.name, "Philips UCB1x00", sizeof(mi.name)); -+ mi.modify_counter = ucba->mod_cnt; -+ return copy_to_user((void *)arg, &mi, sizeof(mi)) ? -EFAULT : 0; -+ } -+ -+ if (_IOC_DIR(cmd) & _IOC_WRITE) { -+ unsigned int left, right; -+ -+ ret = get_user(val, (unsigned int *)arg); -+ if (ret) -+ goto out; -+ -+ left = val & 255; -+ right = val >> 8; -+ -+ if (left > 100) -+ left = 100; -+ if (right > 100) -+ right = 100; -+ -+ gain = (left + right) / 2; -+ -+ ret = -EINVAL; -+ if (!ucba->telecom) { -+ switch(_IOC_NR(cmd)) { -+ case SOUND_MIXER_VOLUME: -+ ucba->output_level = gain | gain << 8; -+ ucba->mod_cnt++; -+ ucba->ctrl_b = (ucba->ctrl_b & 0xff00) | -+ ((gain * 31) / 100); -+ ucb1x00_reg_write(ucba->ucb, UCB_AC_B, -+ ucba->ctrl_b); -+ ret = 0; -+ break; -+ -+ case SOUND_MIXER_MIC: -+ ucba->input_level = gain | gain << 8; -+ ucba->mod_cnt++; -+ ucba->ctrl_a = (ucba->ctrl_a & 0x7f) | -+ (((gain * 31) / 100) << 7); -+ ucb1x00_reg_write(ucba->ucb, UCB_AC_A, -+ ucba->ctrl_a); -+ ret = 0; -+ break; -+ } -+ } -+ } -+ -+ if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) { -+ switch (_IOC_NR(cmd)) { -+ case SOUND_MIXER_VOLUME: -+ val = ucba->output_level; -+ break; -+ -+ case SOUND_MIXER_MIC: -+ val = ucba->input_level; -+ break; -+ -+ case SOUND_MIXER_RECSRC: -+ case SOUND_MIXER_RECMASK: -+ val = ucba->telecom ? 0 : REC_MASK; -+ break; -+ -+ case SOUND_MIXER_DEVMASK: -+ val = ucba->telecom ? 0 : DEV_MASK; -+ break; -+ -+ case SOUND_MIXER_CAPS: -+ case SOUND_MIXER_STEREODEVS: -+ val = 0; -+ break; -+ -+ default: -+ val = 0; -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = put_user(val, (int *)arg); -+ } -+ out: -+ return ret; -+} -+ -+static int ucb1x00_audio_setrate(struct ucb1x00_audio *ucba, int rate) -+{ -+ unsigned int div_rate = ucb1x00_clkrate(ucba->ucb) / 32; -+ unsigned int div; -+ -+ div = (div_rate + (rate / 2)) / rate; -+ if (div < 6) -+ div = 6; -+ if (div > 127) -+ div = 127; -+ -+ ucba->ctrl_a = (ucba->ctrl_a & ~0x7f) | div; -+ -+ if (ucba->telecom) { -+ ucb1x00_reg_write(ucba->ucb, UCB_TC_B, 0); -+ ucb1x00_set_telecom_divisor(ucba->ucb, div * 32); -+ ucb1x00_reg_write(ucba->ucb, UCB_TC_A, ucba->ctrl_a); -+ ucb1x00_reg_write(ucba->ucb, UCB_TC_B, ucba->ctrl_b); -+ } else { -+ ucb1x00_reg_write(ucba->ucb, UCB_AC_B, 0); -+ ucb1x00_set_audio_divisor(ucba->ucb, div * 32); -+ ucb1x00_reg_write(ucba->ucb, UCB_AC_A, ucba->ctrl_a); -+ ucb1x00_reg_write(ucba->ucb, UCB_AC_B, ucba->ctrl_b); -+ } -+ -+ ucba->rate = div_rate / div; -+ -+ return ucba->rate; -+} -+ -+static int ucb1x00_audio_getrate(struct ucb1x00_audio *ucba) -+{ -+ return ucba->rate; -+} -+ -+static void ucb1x00_audio_startup(void *data) -+{ -+ struct ucb1x00_audio *ucba = data; -+ -+ ucb1x00_enable(ucba->ucb); -+ ucb1x00_audio_setrate(ucba, ucba->rate); -+ -+ ucb1x00_reg_write(ucba->ucb, UCB_MODE, UCB_MODE_DYN_VFLAG_ENA); -+ -+ /* -+ * Take off-hook -+ */ -+ if (ucba->daa_oh_bit) -+ ucb1x00_io_write(ucba->ucb, 0, ucba->daa_oh_bit); -+} -+ -+static void ucb1x00_audio_shutdown(void *data) -+{ -+ struct ucb1x00_audio *ucba = data; -+ -+ /* -+ * Place on-hook -+ */ -+ if (ucba->daa_oh_bit) -+ ucb1x00_io_write(ucba->ucb, ucba->daa_oh_bit, 0); -+ -+ ucb1x00_reg_write(ucba->ucb, ucba->telecom ? UCB_TC_B : UCB_AC_B, 0); -+ ucb1x00_disable(ucba->ucb); -+} -+ -+static int -+ucb1x00_audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) -+{ -+ struct ucb1x00_audio *ucba; -+ int val, ret = 0; -+ -+ ucba = list_entry(file->f_op, struct ucb1x00_audio, fops); -+ -+ /* -+ * Make sure we have our magic number -+ */ -+ if (ucba->magic != MAGIC) -+ return -ENODEV; -+ -+ switch (cmd) { -+ case SNDCTL_DSP_STEREO: -+ ret = get_user(val, (int *)arg); -+ if (ret) -+ return ret; -+ if (val != 0) -+ return -EINVAL; -+ val = 0; -+ break; -+ -+ case SNDCTL_DSP_CHANNELS: -+ case SOUND_PCM_READ_CHANNELS: -+ val = 1; -+ break; -+ -+ case SNDCTL_DSP_SPEED: -+ ret = get_user(val, (int *)arg); -+ if (ret) -+ return ret; -+ val = ucb1x00_audio_setrate(ucba, val); -+ break; -+ -+ case SOUND_PCM_READ_RATE: -+ val = ucb1x00_audio_getrate(ucba); -+ break; -+ -+ case SNDCTL_DSP_SETFMT: -+ case SNDCTL_DSP_GETFMTS: -+ val = AFMT_S16_LE; -+ break; -+ -+ default: -+ return ucb1x00_mixer_ioctl(inode, file, cmd, arg); -+ } -+ -+ return put_user(val, (int *)arg); -+} -+ -+static int ucb1x00_audio_open(struct inode *inode, struct file *file) -+{ -+ struct ucb1x00_audio *ucba; -+ -+ ucba = list_entry(file->f_op, struct ucb1x00_audio, fops); -+ -+ return sa1100_audio_attach(inode, file, &ucba->state); -+} -+ -+static struct ucb1x00_audio *ucb1x00_audio_alloc(struct ucb1x00 *ucb) -+{ -+ struct ucb1x00_audio *ucba; -+ -+ ucba = kmalloc(sizeof(*ucba), GFP_KERNEL); -+ if (ucba) { -+ memset(ucba, 0, sizeof(*ucba)); -+ -+ ucba->magic = MAGIC; -+ ucba->ucb = ucb; -+ ucba->fops.owner = THIS_MODULE; -+ ucba->fops.open = ucb1x00_audio_open; -+ ucba->mops.owner = THIS_MODULE; -+ ucba->mops.ioctl = ucb1x00_mixer_ioctl; -+ ucba->state.output_stream = &ucba->output_stream; -+ ucba->state.input_stream = &ucba->input_stream; -+ ucba->state.data = ucba; -+ ucba->state.hw_init = ucb1x00_audio_startup; -+ ucba->state.hw_shutdown = ucb1x00_audio_shutdown; -+ ucba->state.client_ioctl = ucb1x00_audio_ioctl; -+ -+ /* There is a bug in the StrongARM causes corrupt MCP data to be sent to -+ * the codec when the FIFOs are empty and writes are made to the OS timer -+ * match register 0. To avoid this we must make sure that data is always -+ * sent to the codec. -+ */ -+ ucba->state.need_tx_for_rx = 1; -+ -+ init_MUTEX(&ucba->state.sem); -+ ucba->rate = 8000; -+ } -+ return ucba; -+} -+ -+static struct ucb1x00_audio *ucb1x00_audio_add_one(struct ucb1x00 *ucb, int telecom) -+{ -+ struct ucb1x00_audio *a; -+ -+ a = ucb1x00_audio_alloc(ucb); -+ if (a) { -+ a->telecom = telecom; -+ -+ a->input_stream.dev = ucb->cdev.dev; -+ a->output_stream.dev = ucb->cdev.dev; -+ a->ctrl_a = 0; -+ -+ if (a->telecom) { -+ a->input_stream.dma_dev = ucb->mcp->dma_telco_rd; -+ a->input_stream.id = "UCB1x00 telco in"; -+ a->output_stream.dma_dev = ucb->mcp->dma_telco_wr; -+ a->output_stream.id = "UCB1x00 telco out"; -+ a->ctrl_b = UCB_TC_B_IN_ENA|UCB_TC_B_OUT_ENA; -+#if 0 -+ a->daa_oh_bit = UCB_IO_8; -+ -+ ucb1x00_enable(ucb); -+ ucb1x00_io_write(ucb, a->daa_oh_bit, 0); -+ ucb1x00_io_set_dir(ucb, UCB_IO_7 | UCB_IO_6, a->daa_oh_bit); -+ ucb1x00_disable(ucb); -+#endif -+ } else { -+ a->input_stream.dma_dev = ucb->mcp->dma_audio_rd; -+ a->input_stream.id = "UCB1x00 audio in"; -+ a->output_stream.dma_dev = ucb->mcp->dma_audio_wr; -+ a->output_stream.id = "UCB1x00 audio out"; -+ a->ctrl_b = UCB_AC_B_IN_ENA|UCB_AC_B_OUT_ENA; -+ } -+ -+ a->dev_id = register_sound_dsp(&a->fops, -1); -+ a->mix_id = register_sound_mixer(&a->mops, -1); -+ -+ printk("Sound: UCB1x00 %s: dsp id %d mixer id %d\n", -+ a->telecom ? "telecom" : "audio", -+ a->dev_id, a->mix_id); -+ } -+ -+ return a; -+} -+ -+static void ucb1x00_audio_remove_one(struct ucb1x00_audio *a) -+{ -+ unregister_sound_dsp(a->dev_id); -+ unregister_sound_mixer(a->mix_id); -+ kfree(a); -+} -+ -+static int ucb1x00_audio_add(struct class_device *cdev) -+{ -+ struct ucb1x00 *ucb = classdev_to_ucb1x00(cdev); -+ -+ if (ucb->cdev.dev == NULL || ucb->cdev.dev->dma_mask == NULL) -+ return -ENXIO; -+ -+ ucb->audio_data = ucb1x00_audio_add_one(ucb, 0); -+ ucb->telecom_data = ucb1x00_audio_add_one(ucb, 1); -+ -+ return 0; -+} -+ -+static void ucb1x00_audio_remove(struct class_device *cdev) -+{ -+ struct ucb1x00 *ucb = classdev_to_ucb1x00(cdev); -+ -+ ucb1x00_audio_remove_one(ucb->audio_data); -+ ucb1x00_audio_remove_one(ucb->telecom_data); -+} -+ -+#if 0 //def CONFIG_PM -+static int ucb1x00_audio_suspend(struct ucb1x00 *ucb, u32 state) -+{ -+ struct ucb1x00_audio *a; -+ -+ a = ucb->audio_data; -+ sa1100_audio_suspend(&a->state, state); -+ a = ucb->telecom_data; -+ sa1100_audio_suspend(&a->state, state); -+ -+ return 0; -+} -+ -+static int ucb1x00_audio_resume(struct ucb1x00 *ucb) -+{ -+ struct ucb1x00_audio *a; -+ -+ a = ucb->audio_data; -+ sa1100_audio_resume(&a->state); -+ a = ucb->telecom_data; -+ sa1100_audio_resume(&a->state); -+ -+ return 0; -+} -+#else -+#define ucb1x00_audio_suspend NULL -+#define ucb1x00_audio_resume NULL -+#endif -+ -+static struct class_interface ucb1x00_audio_interface = { -+ .add = ucb1x00_audio_add, -+ .remove = ucb1x00_audio_remove, -+}; -+ -+static int __init ucb1x00_audio_init(void) -+{ -+ return ucb1x00_register_interface(&ucb1x00_audio_interface); -+} -+ -+static void __exit ucb1x00_audio_exit(void) -+{ -+ ucb1x00_unregister_interface(&ucb1x00_audio_interface); -+} -+ -+module_init(ucb1x00_audio_init); -+module_exit(ucb1x00_audio_exit); -+ -+MODULE_AUTHOR("Russell King "); -+MODULE_DESCRIPTION("UCB1x00 telecom/audio driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/mcp-sa1100.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,275 @@ -+/* -+ * linux/drivers/misc/mcp-sa1100.c -+ * -+ * Copyright (C) 2001 Russell King -+ * -+ * 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. -+ * -+ * SA1100 MCP (Multimedia Communications Port) driver. -+ * -+ * MCP read/write timeouts from Jordi Colomer, rehacked by rmk. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "mcp.h" -+ -+static void -+mcp_sa1100_set_telecom_divisor(struct mcp *mcp, unsigned int divisor) -+{ -+ unsigned int mccr0; -+ -+ divisor /= 32; -+ -+ mccr0 = Ser4MCCR0 & ~0x00007f00; -+ mccr0 |= divisor << 8; -+ Ser4MCCR0 = mccr0; -+} -+ -+static void -+mcp_sa1100_set_audio_divisor(struct mcp *mcp, unsigned int divisor) -+{ -+ unsigned int mccr0; -+ -+ divisor /= 32; -+ -+ mccr0 = Ser4MCCR0 & ~0x0000007f; -+ mccr0 |= divisor; -+ Ser4MCCR0 = mccr0; -+} -+ -+/* -+ * Write data to the device. The bit should be set after 3 subframe -+ * times (each frame is 64 clocks). We wait a maximum of 6 subframes. -+ * We really should try doing something more productive while we -+ * wait. -+ */ -+static void -+mcp_sa1100_write(struct mcp *mcp, unsigned int reg, unsigned int val) -+{ -+ int ret = -ETIME; -+ int i; -+ -+ Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff); -+ -+ for (i = 0; i < 2; i++) { -+ udelay(mcp->rw_timeout); -+ if (Ser4MCSR & MCSR_CWC) { -+ ret = 0; -+ break; -+ } -+ } -+ -+ if (ret < 0) -+ printk(KERN_WARNING "mcp: write timed out\n"); -+} -+ -+/* -+ * Read data from the device. The bit should be set after 3 subframe -+ * times (each frame is 64 clocks). We wait a maximum of 6 subframes. -+ * We really should try doing something more productive while we -+ * wait. -+ */ -+static unsigned int -+mcp_sa1100_read(struct mcp *mcp, unsigned int reg) -+{ -+ int ret = -ETIME; -+ int i; -+ -+ Ser4MCDR2 = reg << 17 | MCDR2_Rd; -+ -+ for (i = 0; i < 2; i++) { -+ udelay(mcp->rw_timeout); -+ if (Ser4MCSR & MCSR_CRC) { -+ ret = Ser4MCDR2 & 0xffff; -+ break; -+ } -+ } -+ -+ if (ret < 0) -+ printk(KERN_WARNING "mcp: read timed out\n"); -+ -+ return ret; -+} -+ -+static void mcp_sa1100_enable(struct mcp *mcp) -+{ -+ Ser4MCSR = -1; -+ Ser4MCCR0 |= MCCR0_MCE; -+} -+ -+static void mcp_sa1100_disable(struct mcp *mcp) -+{ -+ Ser4MCCR0 &= ~MCCR0_MCE; -+} -+ -+/* -+ * Our methods. -+ */ -+static struct mcp mcp_sa1100 = { -+ .owner = THIS_MODULE, -+ .lock = SPIN_LOCK_UNLOCKED, -+ .sclk_rate = 11981000, -+ .dma_audio_rd = DMA_Ser4MCP0Rd, -+ .dma_audio_wr = DMA_Ser4MCP0Wr, -+ .dma_telco_rd = DMA_Ser4MCP1Rd, -+ .dma_telco_wr = DMA_Ser4MCP1Wr, -+ .set_telecom_divisor = mcp_sa1100_set_telecom_divisor, -+ .set_audio_divisor = mcp_sa1100_set_audio_divisor, -+ .reg_write = mcp_sa1100_write, -+ .reg_read = mcp_sa1100_read, -+ .enable = mcp_sa1100_enable, -+ .disable = mcp_sa1100_disable, -+}; -+ -+static int mcp_sa1100_probe(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct mcp *mcp = &mcp_sa1100; -+ int ret; -+ -+ if (!machine_is_adsbitsy() && !machine_is_assabet() && -+ !machine_is_cerf() && !machine_is_flexanet() && -+ !machine_is_freebird() && !machine_is_graphicsclient() && -+ !machine_is_graphicsmaster() && !machine_is_lart() && -+ !machine_is_omnimeter() && !machine_is_pfs168() && -+ !machine_is_shannon() && !machine_is_simpad() && -+ !machine_is_yopy()) -+ return -ENODEV; -+ -+ if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) -+ return -EBUSY; -+ -+ mcp->me = dev; -+ dev_set_drvdata(dev, mcp); -+ -+ if (machine_is_assabet()) { -+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); -+ } -+ -+ /* -+ * Setup the PPC unit correctly. -+ */ -+ PPDR &= ~PPC_RXD4; -+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; -+ PSDR |= PPC_RXD4; -+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); -+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); -+ -+ Ser4MCSR = -1; -+ Ser4MCCR1 = 0; -+ Ser4MCCR0 = 0x00007f7f | MCCR0_ADM; -+ -+ /* -+ * Calculate the read/write timeout (us) from the bit clock -+ * rate. This is the period for 3 64-bit frames. Always -+ * round this time up. -+ */ -+ mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / -+ mcp->sclk_rate; -+ -+ ret = mcp_host_register(mcp, &pdev->dev); -+ if (ret != 0) { -+ release_mem_region(0x80060000, 0x60); -+ dev_set_drvdata(dev, NULL); -+ } -+ -+ return ret; -+} -+ -+static int mcp_sa1100_remove(struct device *dev) -+{ -+ struct mcp *mcp = dev_get_drvdata(dev); -+ -+ dev_set_drvdata(dev, NULL); -+ -+ mcp_host_unregister(mcp); -+ release_mem_region(0x80060000, 0x60); -+ -+ return 0; -+} -+ -+struct mcp_sa1100_state { -+ u32 mccr0; -+ u32 mccr1; -+}; -+ -+static int mcp_sa1100_suspend(struct device *dev, u32 state, u32 level) -+{ -+ struct mcp_sa1100_state *s = (struct mcp_sa1100_state *)dev->saved_state; -+ -+ if (!s) { -+ s = kmalloc(sizeof(struct mcp_sa1100_state), GFP_KERNEL); -+ dev->saved_state = (unsigned char *)s; -+ } -+ -+ if (s) { -+ s->mccr0 = Ser4MCCR0; -+ s->mccr1 = Ser4MCCR1; -+ } -+ -+ if (level == SUSPEND_DISABLE) -+ Ser4MCCR0 &= ~MCCR0_MCE; -+ return 0; -+} -+ -+static int mcp_sa1100_resume(struct device *dev, u32 level) -+{ -+ struct mcp_sa1100_state *s = (struct mcp_sa1100_state *)dev->saved_state; -+ -+ if (s && level == RESUME_RESTORE_STATE) { -+ Ser4MCCR1 = s->mccr1; -+ Ser4MCCR0 = s->mccr0; -+ -+ dev->saved_state = NULL; -+ kfree(s); -+ } -+ return 0; -+} -+ -+/* -+ * The driver for the SA11x0 MCP port. -+ */ -+static struct device_driver mcp_sa1100_driver = { -+ .name = "sa11x0-mcp", -+ .bus = &platform_bus_type, -+ .probe = mcp_sa1100_probe, -+ .remove = mcp_sa1100_remove, -+ .suspend = mcp_sa1100_suspend, -+ .resume = mcp_sa1100_resume, -+}; -+ -+/* -+ * This needs re-working -+ */ -+static int __init mcp_sa1100_init(void) -+{ -+ return driver_register(&mcp_sa1100_driver); -+} -+ -+static void __exit mcp_sa1100_exit(void) -+{ -+ driver_unregister(&mcp_sa1100_driver); -+} -+ -+module_init(mcp_sa1100_init); -+module_exit(mcp_sa1100_exit); -+ -+MODULE_AUTHOR("Russell King "); -+MODULE_DESCRIPTION("SA11x0 multimedia communications port driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/mcp.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,58 @@ -+/* -+ * linux/drivers/misc/mcp.h -+ * -+ * Copyright (C) 2001 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License. -+ */ -+#ifndef MCP_H -+#define MCP_H -+ -+struct mcp { -+ struct module *owner; -+ struct device *me; -+ spinlock_t lock; -+ int use_count; -+ unsigned int sclk_rate; -+ unsigned int rw_timeout; -+ dma_device_t dma_audio_rd; -+ dma_device_t dma_audio_wr; -+ dma_device_t dma_telco_rd; -+ dma_device_t dma_telco_wr; -+ void (*set_telecom_divisor)(struct mcp *, unsigned int); -+ void (*set_audio_divisor)(struct mcp *, unsigned int); -+ void (*reg_write)(struct mcp *, unsigned int, unsigned int); -+ unsigned int (*reg_read)(struct mcp *, unsigned int); -+ void (*enable)(struct mcp *); -+ void (*disable)(struct mcp *); -+ struct device attached_device; -+}; -+ -+void mcp_set_telecom_divisor(struct mcp *, unsigned int); -+void mcp_set_audio_divisor(struct mcp *, unsigned int); -+void mcp_reg_write(struct mcp *, unsigned int, unsigned int); -+unsigned int mcp_reg_read(struct mcp *, unsigned int); -+void mcp_enable(struct mcp *); -+void mcp_disable(struct mcp *); -+#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate) -+ -+int mcp_host_register(struct mcp *, struct device *); -+void mcp_host_unregister(struct mcp *); -+ -+struct mcp_driver { -+ struct device_driver drv; -+ int (*probe)(struct mcp *); -+ void (*remove)(struct mcp *); -+ int (*suspend)(struct mcp *, u32); -+ int (*resume)(struct mcp *); -+}; -+ -+int mcp_driver_register(struct mcp_driver *); -+void mcp_driver_unregister(struct mcp_driver *); -+ -+#define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device) -+#define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d) -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/ucb1x00-input.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,233 @@ -+/* -+ * linux/drivers/misc/ucb1x00.h -+ * -+ * Copyright (C) 2001 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License. -+ */ -+#ifndef UCB1200_H -+#define UCB1200_H -+ -+#define UCB_IO_DATA 0x00 -+#define UCB_IO_DIR 0x01 -+ -+#define UCB_IO_0 (1 << 0) -+#define UCB_IO_1 (1 << 1) -+#define UCB_IO_2 (1 << 2) -+#define UCB_IO_3 (1 << 3) -+#define UCB_IO_4 (1 << 4) -+#define UCB_IO_5 (1 << 5) -+#define UCB_IO_6 (1 << 6) -+#define UCB_IO_7 (1 << 7) -+#define UCB_IO_8 (1 << 8) -+#define UCB_IO_9 (1 << 9) -+ -+#define UCB_IE_RIS 0x02 -+#define UCB_IE_FAL 0x03 -+#define UCB_IE_STATUS 0x04 -+#define UCB_IE_CLEAR 0x04 -+#define UCB_IE_ADC (1 << 11) -+#define UCB_IE_TSPX (1 << 12) -+#define UCB_IE_TSMX (1 << 13) -+#define UCB_IE_TCLIP (1 << 14) -+#define UCB_IE_ACLIP (1 << 15) -+ -+#define UCB_IRQ_TSPX 12 -+ -+#define UCB_TC_A 0x05 -+#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */ -+#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */ -+ -+#define UCB_TC_B 0x06 -+#define UCB_TC_B_VOICE_ENA (1 << 3) -+#define UCB_TC_B_CLIP (1 << 4) -+#define UCB_TC_B_ATT (1 << 6) -+#define UCB_TC_B_SIDE_ENA (1 << 11) -+#define UCB_TC_B_MUTE (1 << 13) -+#define UCB_TC_B_IN_ENA (1 << 14) -+#define UCB_TC_B_OUT_ENA (1 << 15) -+ -+#define UCB_AC_A 0x07 -+#define UCB_AC_B 0x08 -+#define UCB_AC_B_LOOP (1 << 8) -+#define UCB_AC_B_MUTE (1 << 13) -+#define UCB_AC_B_IN_ENA (1 << 14) -+#define UCB_AC_B_OUT_ENA (1 << 15) -+ -+#define UCB_TS_CR 0x09 -+#define UCB_TS_CR_TSMX_POW (1 << 0) -+#define UCB_TS_CR_TSPX_POW (1 << 1) -+#define UCB_TS_CR_TSMY_POW (1 << 2) -+#define UCB_TS_CR_TSPY_POW (1 << 3) -+#define UCB_TS_CR_TSMX_GND (1 << 4) -+#define UCB_TS_CR_TSPX_GND (1 << 5) -+#define UCB_TS_CR_TSMY_GND (1 << 6) -+#define UCB_TS_CR_TSPY_GND (1 << 7) -+#define UCB_TS_CR_MODE_INT (0 << 8) -+#define UCB_TS_CR_MODE_PRES (1 << 8) -+#define UCB_TS_CR_MODE_POS (2 << 8) -+#define UCB_TS_CR_BIAS_ENA (1 << 11) -+#define UCB_TS_CR_TSPX_LOW (1 << 12) -+#define UCB_TS_CR_TSMX_LOW (1 << 13) -+ -+#define UCB_ADC_CR 0x0a -+#define UCB_ADC_SYNC_ENA (1 << 0) -+#define UCB_ADC_VREFBYP_CON (1 << 1) -+#define UCB_ADC_INP_TSPX (0 << 2) -+#define UCB_ADC_INP_TSMX (1 << 2) -+#define UCB_ADC_INP_TSPY (2 << 2) -+#define UCB_ADC_INP_TSMY (3 << 2) -+#define UCB_ADC_INP_AD0 (4 << 2) -+#define UCB_ADC_INP_AD1 (5 << 2) -+#define UCB_ADC_INP_AD2 (6 << 2) -+#define UCB_ADC_INP_AD3 (7 << 2) -+#define UCB_ADC_EXT_REF (1 << 5) -+#define UCB_ADC_START (1 << 7) -+#define UCB_ADC_ENA (1 << 15) -+ -+#define UCB_ADC_DATA 0x0b -+#define UCB_ADC_DAT_VAL (1 << 15) -+#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5) -+ -+#define UCB_ID 0x0c -+#define UCB_ID_1200 0x1004 -+#define UCB_ID_1300 0x1005 -+#define UCB_ID_1400 0x4304 -+#define UCB_ID_1400_BUGGY 0x4303 /* fake ID */ -+ -+#define UCB_MODE 0x0d -+#define UCB_MODE_DYN_VFLAG_ENA (1 << 12) -+#define UCB_MODE_AUD_OFF_CAN (1 << 13) -+ -+#include "mcp.h" -+ -+struct ucb1x00; -+ -+struct ucb1x00_irq { -+ void *devid; -+ void (*fn)(int, void *); -+}; -+ -+struct ucb1x00 { -+ spinlock_t lock; -+ struct mcp *mcp; -+ unsigned int irq; -+ struct semaphore adc_sem; -+ spinlock_t io_lock; -+ u16 id; -+ u16 io_dir; -+ u16 io_out; -+ u16 adc_cr; -+ u16 irq_fal_enbl; -+ u16 irq_ris_enbl; -+ struct ucb1x00_irq irq_handler[16]; -+}; -+ -+/** -+ * ucb1x00_clkrate - return the UCB1x00 SIB clock rate -+ * @ucb: UCB1x00 structure describing chip -+ * -+ * Return the SIB clock rate in Hz. -+ */ -+static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb) -+{ -+ return mcp_get_sclk_rate(ucb->mcp); -+} -+ -+/** -+ * ucb1x00_enable - enable the UCB1x00 SIB clock -+ * @ucb: UCB1x00 structure describing chip -+ * -+ * Enable the SIB clock. This can be called multiple times. -+ */ -+static inline void ucb1x00_enable(struct ucb1x00 *ucb) -+{ -+ mcp_enable(ucb->mcp); -+} -+ -+/** -+ * ucb1x00_disable - disable the UCB1x00 SIB clock -+ * @ucb: UCB1x00 structure describing chip -+ * -+ * Disable the SIB clock. The SIB clock will only be disabled -+ * when the number of ucb1x00_enable calls match the number of -+ * ucb1x00_disable calls. -+ */ -+static inline void ucb1x00_disable(struct ucb1x00 *ucb) -+{ -+ mcp_disable(ucb->mcp); -+} -+ -+/** -+ * ucb1x00_reg_write - write a UCB1x00 register -+ * @ucb: UCB1x00 structure describing chip -+ * @reg: UCB1x00 4-bit register index to write -+ * @val: UCB1x00 16-bit value to write -+ * -+ * Write the UCB1x00 register @reg with value @val. The SIB -+ * clock must be running for this function to return. -+ */ -+static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val) -+{ -+ mcp_reg_write(ucb->mcp, reg, val); -+} -+ -+/** -+ * ucb1x00_reg_read - read a UCB1x00 register -+ * @ucb: UCB1x00 structure describing chip -+ * @reg: UCB1x00 4-bit register index to write -+ * -+ * Read the UCB1x00 register @reg and return its value. The SIB -+ * clock must be running for this function to return. -+ */ -+static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg) -+{ -+ return mcp_reg_read(ucb->mcp, reg); -+} -+/** -+ * ucb1x00_set_audio_divisor - -+ * @ucb: UCB1x00 structure describing chip -+ * @div: SIB clock divisor -+ */ -+static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div) -+{ -+ mcp_set_audio_divisor(ucb->mcp, div); -+} -+ -+/** -+ * ucb1x00_set_telecom_divisor - -+ * @ucb: UCB1x00 structure describing chip -+ * @div: SIB clock divisor -+ */ -+static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div) -+{ -+ mcp_set_telecom_divisor(ucb->mcp, div); -+} -+ -+struct ucb1x00 *ucb1x00_get(void); -+ -+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int); -+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int); -+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb); -+ -+#define UCB_NOSYNC (0) -+#define UCB_SYNC (1) -+ -+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync); -+void ucb1x00_adc_enable(struct ucb1x00 *ucb); -+void ucb1x00_adc_disable(struct ucb1x00 *ucb); -+ -+/* -+ * Which edges of the IRQ do you want to control today? -+ */ -+#define UCB_RISING (1 << 0) -+#define UCB_FALLING (1 << 1) -+ -+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid); -+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges); -+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges); -+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid); -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/ucb1x00.h 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,271 @@ -+/* -+ * linux/drivers/misc/ucb1x00.h -+ * -+ * Copyright (C) 2001 Russell King, All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License. -+ */ -+#ifndef UCB1200_H -+#define UCB1200_H -+ -+#ifdef CONFIG_ARCH_PXA -+ -+/* ucb1400 aclink register mappings: */ -+ -+#define UCB_IO_DATA 0x5a -+#define UCB_IO_DIR 0x5c -+#define UCB_IE_RIS 0x5e -+#define UCB_IE_FAL 0x60 -+#define UCB_IE_STATUS 0x62 -+#define UCB_IE_CLEAR 0x62 -+#define UCB_TS_CR 0x64 -+#define UCB_ADC_CR 0x66 -+#define UCB_ADC_DATA 0x68 -+#define UCB_ID 0x7e /* 7c is mfr id, 7e part id (from aclink spec) */ -+ -+#define UCB_ADC_DAT(x) ((x) & 0x3ff) -+ -+#else -+ -+/* ucb1x00 SIB register mappings: */ -+ -+#define UCB_IO_DATA 0x00 -+#define UCB_IO_DIR 0x01 -+#define UCB_IE_RIS 0x02 -+#define UCB_IE_FAL 0x03 -+#define UCB_IE_STATUS 0x04 -+#define UCB_IE_CLEAR 0x04 -+#define UCB_TC_A 0x05 -+#define UCB_TC_B 0x06 -+#define UCB_AC_A 0x07 -+#define UCB_AC_B 0x08 -+#define UCB_TS_CR 0x09 -+#define UCB_ADC_CR 0x0a -+#define UCB_ADC_DATA 0x0b -+#define UCB_ID 0x0c -+#define UCB_MODE 0x0d -+ -+#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5) -+ -+#endif -+ -+ -+#define UCB_IO_0 (1 << 0) -+#define UCB_IO_1 (1 << 1) -+#define UCB_IO_2 (1 << 2) -+#define UCB_IO_3 (1 << 3) -+#define UCB_IO_4 (1 << 4) -+#define UCB_IO_5 (1 << 5) -+#define UCB_IO_6 (1 << 6) -+#define UCB_IO_7 (1 << 7) -+#define UCB_IO_8 (1 << 8) -+#define UCB_IO_9 (1 << 9) -+ -+#define UCB_IE_ADC (1 << 11) -+#define UCB_IE_TSPX (1 << 12) -+#define UCB_IE_TSMX (1 << 13) -+#define UCB_IE_TCLIP (1 << 14) -+#define UCB_IE_ACLIP (1 << 15) -+ -+#define UCB_IRQ_TSPX 12 -+ -+#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */ -+#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */ -+ -+#define UCB_TC_B_VOICE_ENA (1 << 3) -+#define UCB_TC_B_CLIP (1 << 4) -+#define UCB_TC_B_ATT (1 << 6) -+#define UCB_TC_B_SIDE_ENA (1 << 11) -+#define UCB_TC_B_MUTE (1 << 13) -+#define UCB_TC_B_IN_ENA (1 << 14) -+#define UCB_TC_B_OUT_ENA (1 << 15) -+ -+#define UCB_AC_B_LOOP (1 << 8) -+#define UCB_AC_B_MUTE (1 << 13) -+#define UCB_AC_B_IN_ENA (1 << 14) -+#define UCB_AC_B_OUT_ENA (1 << 15) -+ -+#define UCB_TS_CR_TSMX_POW (1 << 0) -+#define UCB_TS_CR_TSPX_POW (1 << 1) -+#define UCB_TS_CR_TSMY_POW (1 << 2) -+#define UCB_TS_CR_TSPY_POW (1 << 3) -+#define UCB_TS_CR_TSMX_GND (1 << 4) -+#define UCB_TS_CR_TSPX_GND (1 << 5) -+#define UCB_TS_CR_TSMY_GND (1 << 6) -+#define UCB_TS_CR_TSPY_GND (1 << 7) -+#define UCB_TS_CR_MODE_INT (0 << 8) -+#define UCB_TS_CR_MODE_PRES (1 << 8) -+#define UCB_TS_CR_MODE_POS (2 << 8) -+#define UCB_TS_CR_BIAS_ENA (1 << 11) -+#define UCB_TS_CR_TSPX_LOW (1 << 12) -+#define UCB_TS_CR_TSMX_LOW (1 << 13) -+ -+#define UCB_ADC_SYNC_ENA (1 << 0) -+#define UCB_ADC_VREFBYP_CON (1 << 1) -+#define UCB_ADC_INP_TSPX (0 << 2) -+#define UCB_ADC_INP_TSMX (1 << 2) -+#define UCB_ADC_INP_TSPY (2 << 2) -+#define UCB_ADC_INP_TSMY (3 << 2) -+#define UCB_ADC_INP_AD0 (4 << 2) -+#define UCB_ADC_INP_AD1 (5 << 2) -+#define UCB_ADC_INP_AD2 (6 << 2) -+#define UCB_ADC_INP_AD3 (7 << 2) -+#define UCB_ADC_EXT_REF (1 << 5) -+#define UCB_ADC_START (1 << 7) -+#define UCB_ADC_ENA (1 << 15) -+ -+#define UCB_ADC_DAT_VAL (1 << 15) -+ -+#define UCB_ID_1200 0x1004 -+#define UCB_ID_1300 0x1005 -+#define UCB_ID_1400 0x4304 -+#define UCB_ID_1400_BUGGY 0x4303 /* fake ID */ -+ -+#define UCB_MODE_DYN_VFLAG_ENA (1 << 12) -+#define UCB_MODE_AUD_OFF_CAN (1 << 13) -+ -+#include -+#include "mcp.h" -+ -+struct ucb1x00_irq { -+ void *devid; -+ void (*fn)(int, void *); -+}; -+ -+extern struct class ucb1x00_class; -+ -+struct ucb1x00 { -+ spinlock_t lock; -+ struct mcp *mcp; -+ unsigned int irq; -+ struct semaphore adc_sem; -+ spinlock_t io_lock; -+ wait_queue_head_t irq_wait; -+ struct completion complete; -+ struct task_struct *rtask; -+ u16 id; -+ u16 io_dir; -+ u16 io_out; -+ u16 adc_cr; -+ u16 irq_fal_enbl; -+ u16 irq_ris_enbl; -+ struct ucb1x00_irq irq_handler[16]; -+ struct class_device cdev; -+ void *audio_data; -+ void *telecom_data; -+ void *ts_data; -+}; -+ -+#define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, cdev) -+ -+int ucb1x00_register_interface(struct class_interface *intf); -+void ucb1x00_unregister_interface(struct class_interface *intf); -+ -+/** -+ * ucb1x00_clkrate - return the UCB1x00 SIB clock rate -+ * @ucb: UCB1x00 structure describing chip -+ * -+ * Return the SIB clock rate in Hz. -+ */ -+static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb) -+{ -+ return mcp_get_sclk_rate(ucb->mcp); -+} -+ -+/** -+ * ucb1x00_enable - enable the UCB1x00 SIB clock -+ * @ucb: UCB1x00 structure describing chip -+ * -+ * Enable the SIB clock. This can be called multiple times. -+ */ -+static inline void ucb1x00_enable(struct ucb1x00 *ucb) -+{ -+ mcp_enable(ucb->mcp); -+} -+ -+/** -+ * ucb1x00_disable - disable the UCB1x00 SIB clock -+ * @ucb: UCB1x00 structure describing chip -+ * -+ * Disable the SIB clock. The SIB clock will only be disabled -+ * when the number of ucb1x00_enable calls match the number of -+ * ucb1x00_disable calls. -+ */ -+static inline void ucb1x00_disable(struct ucb1x00 *ucb) -+{ -+ mcp_disable(ucb->mcp); -+} -+ -+/** -+ * ucb1x00_reg_write - write a UCB1x00 register -+ * @ucb: UCB1x00 structure describing chip -+ * @reg: UCB1x00 4-bit register index to write -+ * @val: UCB1x00 16-bit value to write -+ * -+ * Write the UCB1x00 register @reg with value @val. The SIB -+ * clock must be running for this function to return. -+ */ -+static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val) -+{ -+ mcp_reg_write(ucb->mcp, reg, val); -+} -+ -+/** -+ * ucb1x00_reg_read - read a UCB1x00 register -+ * @ucb: UCB1x00 structure describing chip -+ * @reg: UCB1x00 4-bit register index to write -+ * -+ * Read the UCB1x00 register @reg and return its value. The SIB -+ * clock must be running for this function to return. -+ */ -+static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg) -+{ -+ return mcp_reg_read(ucb->mcp, reg); -+} -+/** -+ * ucb1x00_set_audio_divisor - -+ * @ucb: UCB1x00 structure describing chip -+ * @div: SIB clock divisor -+ */ -+static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div) -+{ -+ mcp_set_audio_divisor(ucb->mcp, div); -+} -+ -+/** -+ * ucb1x00_set_telecom_divisor - -+ * @ucb: UCB1x00 structure describing chip -+ * @div: SIB clock divisor -+ */ -+static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div) -+{ -+ mcp_set_telecom_divisor(ucb->mcp, div); -+} -+ -+#define ucb1x00_get() NULL -+ -+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int); -+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int); -+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb); -+ -+#define UCB_NOSYNC (0) -+#define UCB_SYNC (1) -+ -+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync); -+void ucb1x00_adc_enable(struct ucb1x00 *ucb); -+void ucb1x00_adc_disable(struct ucb1x00 *ucb); -+ -+/* -+ * Which edges of the IRQ do you want to control today? -+ */ -+#define UCB_RISING (1 << 0) -+#define UCB_FALLING (1 << 1) -+ -+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid); -+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges); -+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges); -+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid); -+ -+#endif ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/misc/switches-sa1100.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,323 @@ -+/* -+ * linux/drivers/misc/switches-sa1100.c -+ * -+ * Copyright (C) 2001 John Dorsey -+ * -+ * 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. -+ * -+ * 19 December 2001 - created from sa1100_switches.c. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "switches.h" -+ -+ -+static irqreturn_t switches_sa1100_handler(int irq, void *dev_id, -+ struct pt_regs *regs); -+ -+ -+#ifdef CONFIG_SA1100_ASSABET -+ -+/* Assabet -+ * ^^^^^^^ -+ * We have two general-purpose switches, S1 and S2, available via GPIO -+ * on Assabet. This code sets bits in the range [1, 2] in the mask that -+ * we return to userland. -+ */ -+ -+static int assabet_switches_sa1100_init(void) -+{ -+ -+ if (machine_has_neponset()) -+ NCR_0 |= NCR_GP01_OFF; -+ -+ if (request_irq(IRQ_GPIO0, switches_sa1100_handler, SA_INTERRUPT, -+ SWITCHES_NAME, NULL) < 0) { -+ printk(KERN_ERR "%s: unable to register IRQ for GPIO 0\n", -+ SWITCHES_NAME); -+ return -EIO; -+ } -+ -+ if (request_irq(IRQ_GPIO1, switches_sa1100_handler, SA_INTERRUPT, -+ SWITCHES_NAME, NULL) < 0) { -+ printk(KERN_ERR "%s: unable to register IRQ for GPIO 1\n", -+ SWITCHES_NAME); -+ free_irq(IRQ_GPIO0, NULL); -+ return -EIO; -+ } -+ -+ set_irq_type(IRQ_GPIO0, IRQT_BOTHEDGE); -+ set_irq_type(IRQ_GPIO1, IRQT_BOTHEDGE); -+ -+ return 0; -+ -+} -+ -+static void assabet_switches_sa1100_shutdown(void) -+{ -+ -+ free_irq(IRQ_GPIO1, NULL); -+ free_irq(IRQ_GPIO0, NULL); -+ -+} -+ -+static irqreturn_t assabet_switches_sa1100_handler(int irq, switches_mask_t *mask) -+{ -+ unsigned int s, last, this; -+ static unsigned int states = 0; -+ -+ switch (irq) { -+ -+ case IRQ_GPIO0: s = 0; break; -+ -+ case IRQ_GPIO1: s = 1; break; -+ -+ default: return IRQ_NONE; -+ -+ } -+ -+ last = ((states & (1 << s)) != 0); -+ this = ((GPLR & GPIO_GPIO(s)) != 0); -+ -+ if (last == this) /* debounce */ -+ return IRQ_HANDLED; -+ -+ SWITCHES_SET(mask, s + 1, this); -+ -+ states = this ? (states | (1 << s)) : (states & ~(1 << s)); -+ -+ return IRQ_HANDLED; -+} -+#endif /* CONFIG_SA1100_ASSABET */ -+ -+#ifdef CONFIG_SA1100_BADGE4 -+ -+/* BadgePAD 4 -+ * ^^^^^^^^^^ -+ * -+ * Here we use test point J6 (BADGE4_GPIO_TESTPT_J6 aka GPIO 23) as a -+ * general purpose switch input. We map this to switch #0. -+ */ -+ -+#define BADGE4_SW0_GPIO GPIO_GPIO23 /* aka BADGE4_GPIO_TESTPT_J6 */ -+#define BADGE4_SW0_IRQ IRQ_GPIO23 -+ -+static int badge4_switches_sa1100_init(void) -+{ -+ if (request_irq(BADGE4_SW0_IRQ, switches_sa1100_handler, SA_INTERRUPT, -+ SWITCHES_NAME, NULL) < 0) { -+ printk(KERN_ERR "%s: unable to register IRQ for SW0\n", -+ SWITCHES_NAME); -+ return -EIO; -+ } -+ -+ set_irq_type(BADGE4_SW0_IRQ, IRQT_BOTHEDGE); -+ -+ return 0; -+} -+ -+static void badge4_switches_sa1100_shutdown(void) -+{ -+ free_irq(BADGE4_SW0_IRQ, NULL); -+} -+ -+static irqreturn_t badge4_switches_sa1100_handler(int irq, switches_mask_t *mask) -+{ -+ unsigned int swno, last, this, gpio; -+ static unsigned int states = 0; -+ -+ switch (irq) { -+ case BADGE4_SW0_IRQ: -+ swno = 0; -+ gpio = BADGE4_SW0_GPIO; -+ break; -+ default: -+ return IRQ_NONE; -+ } -+ -+ last = ((states & gpio) != 0); -+ this = ((GPLR & gpio) != 0); -+ -+ if (last == this) /* debounce */ -+ return IRQ_HANDLED; -+ -+ SWITCHES_SET(mask, swno, this); -+ -+ states = this ? (states | gpio) : (states & ~gpio); -+ -+ return IRQ_HANDLED; -+} -+#endif /* CONFIG_SA1100_BADGE4 */ -+ -+ -+#ifdef CONFIG_SA1100_SPOT -+ -+/* Spot -+ * ^^^^ -+ * Spot (R2, R3) has a single general-purpose switch (S1), which is -+ * also the power-on switch. We set bit [1] in the mask we return to -+ * userland. -+ */ -+ -+static int spot_switches_sa1100_init(void) -+{ -+ -+ set_GPIO_IRQ_edge(GPIO_SW1, GPIO_BOTH_EDGES); -+ -+ if (request_irq(IRQ_GPIO_SW1, switches_sa1100_handler, SA_INTERRUPT, -+ SWITCHES_NAME, NULL) < 0) { -+ printk(KERN_ERR "%s: unable to register IRQ for SW1\n", -+ SWITCHES_NAME); -+ return -EIO; -+ } -+ -+ return 0; -+ -+} -+ -+static void spot_switches_sa1100_shutdown(void) -+{ -+ -+ free_irq(IRQ_GPIO_SW1, NULL); -+ -+} -+ -+static irqreturn_t spot_switches_sa1100_handler(int irq, switches_mask_t *mask) -+{ -+ unsigned int s, last, this; -+ static unsigned int states = 0; -+ -+ switch (irq) { -+ -+ case IRQ_GPIO_SW1: s = 0; break; -+ -+ default: return IRQ_NONE; -+ -+ } -+ -+ last = ((states & (1 << s)) != 0); -+ this = ((GPLR & GPIO_GPIO(s)) != 0); -+ -+ if (last == this) /* debounce */ -+ return IRQ_HANDLED; -+ -+ SWITCHES_SET(mask, s + 1, this); -+ -+ states = this ? (states | (1 << s)) : (states & ~(1 << s)); -+ -+ return IRQ_HANDLED; -+ -+} -+#endif /* CONFIG_SA1100_SPOT */ -+ -+ -+/* switches_sa1100_handler() -+ * ^^^^^^^^^^^^^^^^^^^^^^^^^ -+ * This routine is a generalized handler for SA-1100 switches -+ * which manages action descriptors and calls a board-specific -+ * service routine. This routine is appropriate for GPIO switches -+ * or other primary interrupt sources, and can be registered as a -+ * first-class IRQ handler using request_irq(). -+ */ -+static irqreturn_t switches_sa1100_handler(int irq, void *dev_id, -+ struct pt_regs *regs) -+{ -+ switches_mask_t mask; -+ irqreturn_t ret = IRQ_NONE; -+ -+ SWITCHES_ZERO(&mask); -+ -+ /* Porting note: call a board-specific switch interrupt handler -+ * here. The handler can assume that sufficient storage for -+ * `mask' has been allocated, and that the corresponding -+ * switches_mask_t structure has been zeroed. -+ */ -+ -+ if (machine_is_assabet()) { -+#ifdef CONFIG_SA1100_ASSABET -+ ret = assabet_switches_sa1100_handler(irq, &mask); -+#endif -+ } else if (machine_is_badge4()) { -+#ifdef CONFIG_SA1100_BADGE4 -+ ret = badge4_switches_sa1100_handler(irq, &mask); -+#endif -+ } else if (machine_is_spot()) { -+#ifdef CONFIG_SA1100_SPOT -+ ret = spot_switches_sa1100_handler(irq, &mask); -+#endif -+ } -+ -+ switches_event(&mask); -+ -+ return ret; -+} -+ -+int __init switches_sa1100_init(void) -+{ -+ -+ /* Porting note: call a board-specific init routine here. */ -+ -+ if (machine_is_assabet()) { -+#ifdef CONFIG_SA1100_ASSABET -+ if (assabet_switches_sa1100_init() < 0) -+ return -EIO; -+#endif -+ } else if (machine_is_badge4()) { -+#ifdef CONFIG_SA1100_BADGE4 -+ if (badge4_switches_sa1100_init() < 0) -+ return -EIO; -+#endif -+ } else if (machine_is_spot()) { -+#ifdef CONFIG_SA1100_SPOT -+ if (spot_switches_sa1100_init() < 0) -+ return -EIO; -+#endif -+ } -+ -+ return 0; -+ -+} -+ -+void __exit switches_sa1100_exit(void) -+{ -+ -+ /* Porting note: call a board-specific shutdown routine here. */ -+ -+ if (machine_is_assabet()) { -+#ifdef CONFIG_SA1100_ASSABET -+ assabet_switches_sa1100_shutdown(); -+#endif -+ } else if (machine_is_badge4()) { -+#ifdef CONFIG_SA1100_BADGE4 -+ badge4_switches_sa1100_shutdown(); -+#endif -+ } else if (machine_is_spot()) { -+#ifdef CONFIG_SA1100_SPOT -+ spot_switches_sa1100_shutdown(); -+#endif -+ } -+ -+} -+ -+module_init(switches_sa1100_init); -+module_exit(switches_sa1100_exit); -+ -+MODULE_DESCRIPTION("SA-1100 switches driver"); -+MODULE_LICENSE("GPL"); ---- linux-2.6.5/drivers/misc/Makefile~heh 2004-04-03 22:38:17.000000000 -0500 -+++ linux-2.6.5/drivers/misc/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -4,3 +4,21 @@ - obj- := misc.o # Dummy rule to force built-in.o to be made - - obj-$(CONFIG_IBM_ASM) += ibmasm/ -+ -+obj-$(CONFIG_MCP) += mcp-core.o -+obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o -+obj-$(CONFIG_MCP_UCB1200_AUDIO) += ucb1x00-audio.o -+obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o -+ -+ifeq ($(CONFIG_SA1100_ASSABET),y) -+obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o -+endif -+ -+obj-$(CONFIG_SWITCHES) += switches-core.o -+obj-$(CONFIG_SWITCHES_SA1100) += switches-sa1100.o -+obj-$(CONFIG_SWITCHES_UCB1X00) += switches-ucb1x00.o -+ -+obj-$(CONFIG_MCP_SA1100) += mcp-sa1100.o -+ -+obj-$(CONFIG_UCB1400_TS) += mcp-pxa.o ucb1x00-core.o ucb1x00-ts.o -+ ---- linux-2.6.5/drivers/i2c/busses/Kconfig~heh 2004-04-03 22:38:10.000000000 -0500 -+++ linux-2.6.5/drivers/i2c/busses/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -70,6 +70,16 @@ - This support is also available as a module. If so, the module - will be called i2c-hydra. - -+config I2C_BIT_SA1100_GPIO -+ bool "SA1100 I2C GPIO adapter" -+ depends on ARCH_SA1100 && I2C_ALGOBIT -+ help -+ This supports I2C on the SA11x0 processor GPIO pins. This -+ shares support with the L3 driver. -+ -+ This support is also available as a module. If so, the module -+ will be called l3-bit-sa1100. -+ - config I2C_I801 - tristate "Intel 801" - depends on I2C && PCI && EXPERIMENTAL -@@ -241,6 +251,18 @@ - This support is also available as a module. If so, the module - will be called i2c-prosavage. - -+config I2C_PXA2XX -+ tristate "PXA I2C Interface" -+ depends on I2C && ARCH_PXA -+ select I2C_ALGOPXA -+ help -+ This supports the use of the PXA I2C interface found on the Intel -+ PXA 25x and PXA 26x systems. Say Y if you have one of these. -+ -+ This support is also available as a module. If you want to compile -+ it as a module, say M here and read Documentation/modules.txt. -+ The module will be called i2c-adap-pxa. -+ - config I2C_RPXLITE - tristate "Embedded Planet RPX Lite/Classic support" - depends on (RPXLITE || RPXCLASSIC) && I2C ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/i2c/busses/pxa2xx_i2c.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,388 @@ -+/* -+ * i2c_adap_pxa.c -+ * -+ * I2C adapter for the PXA I2C bus access. -+ * -+ * Copyright (C) 2002 Intrinsyc Software Inc. -+ * -+ * 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. -+ * -+ * History: -+ * Apr 2002: Initial version [CS] -+ * Jun 2002: Properly seperated algo/adap [FB] -+ * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem] -+ * Jan 2003: added limited signal handling [Kai-Uwe Bloem] -+ * Jun 2003: updated for 2.5 [Dustin McIntire] -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include /* for IRQ_I2C */ -+ -+#include -+ -+/* -+ * Set this to zero to remove all debug statements via dead code elimination. -+ */ -+//#define DEBUG 1 -+ -+#if DEBUG -+static unsigned int i2c_debug = DEBUG; -+#else -+#define i2c_debug 0 -+#endif -+ -+static int irq = 0; -+static volatile int i2c_pending = 0; /* interrupt pending when 1 */ -+static volatile int bus_error = 0; -+static volatile int tx_finished = 0; -+static volatile int rx_finished = 0; -+ -+static wait_queue_head_t i2c_wait; -+static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte); -+ -+/* place a byte in the transmit register */ -+static void i2c_pxa_write_byte(u8 value) -+{ -+ IDBR = value; -+} -+ -+/* read byte in the receive register */ -+static u8 i2c_pxa_read_byte(void) -+{ -+ return (u8) (0xff & IDBR); -+} -+ -+static void i2c_pxa_start(void) -+{ -+ unsigned long icr = ICR; -+ icr |= ICR_START; -+ icr &= ~(ICR_STOP | ICR_ALDIE | ICR_ACKNAK); -+ ICR = icr; -+ -+ bus_error=0; /* clear any bus_error from previous txfers */ -+ tx_finished=0; /* clear rx and tx interrupts from previous txfers */ -+ rx_finished=0; -+ i2c_pending = 0; -+} -+ -+static void i2c_pxa_repeat_start(void) -+{ -+ unsigned long icr = ICR; -+ icr |= ICR_START; -+ icr &= ~(ICR_STOP | ICR_ALDIE); -+ ICR = icr; -+ -+ bus_error=0; /* clear any bus_error from previous txfers */ -+ tx_finished=0; /* clear rx and tx interrupts from previous txfers */ -+ rx_finished=0; -+ i2c_pending = 0; -+} -+ -+static void i2c_pxa_stop(void) -+{ -+ unsigned long icr = ICR; -+ icr |= ICR_STOP; -+ icr &= ~(ICR_START); -+ ICR = icr; -+} -+ -+static void i2c_pxa_midbyte(void) -+{ -+ unsigned long icr = ICR; -+ icr &= ~(ICR_START | ICR_STOP); -+ ICR = icr; -+} -+ -+static void i2c_pxa_abort(void) -+{ -+ unsigned long timeout = jiffies + HZ/4; -+ -+#ifdef PXA_ABORT_MA -+ while ((long)(timeout - jiffies) > 0 && (ICR & ICR_TB)) { -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(1); -+ } -+ -+ ICR |= ICR_MA; -+ udelay(100); -+#else -+ while ((long)(timeout - jiffies) > 0 && (IBMR & 0x1) == 0) { -+ i2c_pxa_transfer( 1, I2C_RECEIVE, 1); -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(1); -+ } -+#endif -+ ICR &= ~(ICR_MA | ICR_START | ICR_STOP); -+} -+ -+static int i2c_pxa_wait_bus_not_busy( void) -+{ -+ int timeout = DEF_TIMEOUT; -+ -+ while (timeout-- && (ISR & ISR_IBB)) { -+ udelay(100); /* wait for 100 us */ -+ } -+ -+ return (timeout<=0); -+} -+ -+spinlock_t i2c_pxa_irqlock = SPIN_LOCK_UNLOCKED; -+ -+static void i2c_pxa_wait_for_ite(void){ -+ unsigned long flags; -+ if (irq > 0) { -+ spin_lock_irqsave(&i2c_pxa_irqlock, flags); -+ if (i2c_pending == 0) { -+ interruptible_sleep_on_timeout(&i2c_wait, I2C_SLEEP_TIMEOUT ); -+ } -+ i2c_pending = 0; -+ spin_unlock_irqrestore(&i2c_pxa_irqlock, flags); -+ } else { -+ udelay(100); -+ } -+} -+ -+static int i2c_pxa_wait_for_int( int wait_type) -+{ -+ int timeout = DEF_TIMEOUT; -+#ifdef DEBUG -+ if (bus_error) -+ printk(KERN_INFO"i2c_pxa_wait_for_int: Bus error on enter\n"); -+ if (rx_finished) -+ printk(KERN_INFO"i2c_pxa_wait_for_int: Receive interrupt on enter\n"); -+ if (tx_finished) -+ printk(KERN_INFO"i2c_pxa_wait_for_int: Transmit interrupt on enter\n"); -+#endif -+ -+ if (wait_type == I2C_RECEIVE){ /* wait on receive */ -+ -+ do { -+ i2c_pxa_wait_for_ite(); -+ } while (!(rx_finished) && timeout-- && !signal_pending(current)); -+ -+#ifdef DEBUG -+ if (timeout<0){ -+ if (tx_finished) -+ printk("Error: i2c-algo-pxa.o: received a tx" -+ " interrupt while waiting on a rx in wait_for_int"); -+ } -+#endif -+ } else { /* wait on transmit */ -+ -+ do { -+ i2c_pxa_wait_for_ite(); -+ } while (!(tx_finished) && timeout-- && !signal_pending(current)); -+ -+#ifdef DEBUG -+ if (timeout<0){ -+ if (rx_finished) -+ printk("Error: i2c-algo-pxa.o: received a rx" -+ " interrupt while waiting on a tx in wait_for_int"); -+ } -+#endif -+ } -+ -+ udelay(ACK_DELAY); /* this is needed for the bus error */ -+ -+ tx_finished=0; -+ rx_finished=0; -+ -+ if (bus_error){ -+ bus_error=0; -+ if( i2c_debug > 2)printk("wait_for_int: error - no ack.\n"); -+ return BUS_ERROR; -+ } -+ -+ if (signal_pending(current)) { -+ return (-ERESTARTSYS); -+ } else if (timeout < 0) { -+ if( i2c_debug > 2)printk("wait_for_int: timeout.\n"); -+ return(-EIO); -+ } else -+ return(0); -+} -+ -+static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte) -+{ -+ if( lastbyte) -+ { -+ if( receive==I2C_RECEIVE) ICR |= ICR_ACKNAK; -+ i2c_pxa_stop(); -+ } -+ else if( midbyte) -+ { -+ i2c_pxa_midbyte(); -+ } -+ ICR |= ICR_TB; -+} -+ -+static void i2c_pxa_reset( void) -+{ -+#ifdef DEBUG -+ printk("Resetting I2C Controller Unit\n"); -+#endif -+ -+ /* abort any transfer currently under way */ -+ i2c_pxa_abort(); -+ -+ /* reset according to 9.8 */ -+ ICR = ICR_UR; -+ ISR = I2C_ISR_INIT; -+ ICR &= ~ICR_UR; -+ -+ /* set the global I2C clock on */ -+ CKEN |= CKEN14_I2C; -+ -+ /* set our slave address */ -+ ISAR = I2C_PXA_SLAVE_ADDR; -+ -+ /* set control register values */ -+ ICR = I2C_ICR_INIT; -+ -+ /* clear any leftover states from prior transmissions */ -+ i2c_pending = rx_finished = tx_finished = bus_error = 0; -+ -+ /* enable unit */ -+ ICR |= ICR_IUE; -+ udelay(100); -+} -+ -+static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs) -+{ -+ unsigned long flags; -+ int status, wakeup = 0; -+ status = (ISR); -+ -+ if (status & ISR_BED){ -+ (ISR) |= ISR_BED; -+ bus_error=ISR_BED; -+ wakeup = 1; -+ } -+ if (status & ISR_ITE){ -+ (ISR) |= ISR_ITE; -+ tx_finished=ISR_ITE; -+ wakeup = 1; -+ } -+ if (status & ISR_IRF){ -+ (ISR) |= ISR_IRF; -+ rx_finished=ISR_IRF; -+ wakeup = 1; -+ } -+ if (wakeup) { -+ spin_lock_irqsave(&i2c_pxa_irqlock, flags); -+ i2c_pending = 1; -+ spin_unlock_irqrestore(&i2c_pxa_irqlock, flags); -+ wake_up_interruptible(&i2c_wait); -+ } -+ return IRQ_HANDLED; -+} -+ -+static int i2c_pxa_resource_init( void) -+{ -+ init_waitqueue_head(&i2c_wait); -+ -+ if (request_irq(IRQ_I2C, &i2c_pxa_handler, SA_INTERRUPT, "I2C", 0) < 0) { -+ irq = 0; -+ if(i2c_debug) -+ printk(KERN_INFO "I2C: Failed to register I2C irq %i\n", IRQ_I2C); -+ return -ENODEV; -+ } -+ return 0; -+} -+ -+static void i2c_pxa_resource_release( void) -+{ -+ if( irq > 0) -+ { -+ disable_irq(irq); -+ free_irq(irq,0); -+ irq=0; -+ } -+} -+ -+static int i2c_pxa_client_register(struct i2c_client *client) -+{ -+ return 0; -+} -+ -+static int i2c_pxa_client_unregister(struct i2c_client *client) -+{ -+ return 0; -+} -+ -+static struct i2c_algo_pxa_data i2c_pxa_data = { -+ write_byte: i2c_pxa_write_byte, -+ read_byte: i2c_pxa_read_byte, -+ -+ start: i2c_pxa_start, -+ repeat_start: i2c_pxa_repeat_start, -+ stop: i2c_pxa_stop, -+ abort: i2c_pxa_abort, -+ -+ wait_bus_not_busy: i2c_pxa_wait_bus_not_busy, -+ wait_for_interrupt: i2c_pxa_wait_for_int, -+ transfer: i2c_pxa_transfer, -+ reset: i2c_pxa_reset, -+ -+ udelay: 10, -+ timeout: DEF_TIMEOUT, -+}; -+ -+static struct i2c_adapter i2c_pxa_ops = { -+ .owner = THIS_MODULE, -+ .id = I2C_ALGO_PXA, -+ .algo_data = &i2c_pxa_data, -+ .dev = { -+ .name = "PXA I2C Adapter", -+ }, -+ .client_register = i2c_pxa_client_register, -+ .client_unregister = i2c_pxa_client_unregister, -+ .retries = 2, -+}; -+ -+extern int i2c_pxa_add_bus(struct i2c_adapter *); -+extern int i2c_pxa_del_bus(struct i2c_adapter *); -+ -+static int __init i2c_adap_pxa_init(void) -+{ -+ if( i2c_pxa_resource_init() == 0) { -+ -+ if (i2c_pxa_add_bus(&i2c_pxa_ops) < 0) { -+ i2c_pxa_resource_release(); -+ printk(KERN_INFO "I2C: Failed to add bus\n"); -+ return -ENODEV; -+ } -+ } else { -+ return -ENODEV; -+ } -+ -+ printk(KERN_INFO "I2C: Successfully added bus\n"); -+ -+ return 0; -+} -+ -+static void i2c_adap_pxa_exit(void) -+{ -+ i2c_pxa_del_bus( &i2c_pxa_ops); -+ i2c_pxa_resource_release(); -+ -+ printk(KERN_INFO "I2C: Successfully removed bus\n"); -+} -+ -+module_init(i2c_adap_pxa_init); -+module_exit(i2c_adap_pxa_exit); ---- linux-2.6.5/drivers/i2c/busses/Makefile~heh 2004-04-03 22:36:17.000000000 -0500 -+++ linux-2.6.5/drivers/i2c/busses/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -21,6 +21,7 @@ - obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o - obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o - obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o -+obj-$(CONFIG_I2C_PXA) += pxa2xx_i2c.o - obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o - obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o - obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o ---- linux-2.6.5/drivers/i2c/algos/Kconfig~heh 2004-04-03 22:37:59.000000000 -0500 -+++ linux-2.6.5/drivers/i2c/algos/Kconfig 2004-04-30 20:57:36.000000000 -0400 -@@ -38,6 +38,18 @@ - This support is also available as a module. If so, the module - will be called i2c-algo-ite. - -+config I2C_ALGOPXA -+ tristate "PXA I2C Algorithm" -+ depends on ARCH_PXA && I2C -+ help -+ This supports the use of the PXA I2C interface found on the Intel -+ PXA 25x and PXA 26x systems. Say Y if you have one of these. -+ You should also say Y for the PXA I2C peripheral driver support below. -+ -+ This support is also available as a module. If you want to compile -+ it as a module, say M here and read Documentation/modules.txt. -+ The module will be called i2c-algo-pxa. -+ - config I2C_ALGO8XX - tristate "MPC8xx CPM I2C interface" - depends on 8xx && I2C ---- /dev/null 2003-09-23 18:19:32.000000000 -0400 -+++ linux-2.6.5/drivers/i2c/algos/i2c-algo-pxa.c 2004-04-30 20:57:36.000000000 -0400 -@@ -0,0 +1,384 @@ -+/* -+ * i2c-algo-pxa.c -+ * -+ * I2C algorithm for the PXA I2C bus access. -+ * Byte driven algorithm similar to pcf. -+ * -+ * Copyright (C) 2002 Intrinsyc Software Inc. -+ * -+ * 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. -+ * -+ * History: -+ * Apr 2002: Initial version [CS] -+ * Jun 2002: Properly seperated algo/adap [FB] -+ * Jan 2003: added limited signal handling [Kai-Uwe Bloem] -+ * Jan 2003: allow SMBUS_QUICK as valid msg [FB] -+ * Jun 2003: updated for 2.5 [Dustin McIntire] -+ * -+ */ -+#include -+#include -+ -+#include -+#include -+#include -+#include /* struct i2c_msg and others */ -+#include -+ -+#include -+ -+/* -+ * Set this to zero to remove all the debug statements via dead code elimination. -+ */ -+//#define DEBUG 1 -+ -+#if DEBUG -+static unsigned int i2c_debug = DEBUG; -+#else -+#define i2c_debug 0 -+#endif -+ -+static int pxa_scan = 1; -+ -+static int i2c_pxa_valid_messages( struct i2c_msg msgs[], int num) -+{ -+ int i; -+ if (num < 1 || num > MAX_MESSAGES){ -+ if( i2c_debug) -+ printk(KERN_INFO "Invalid number of messages (max=%d, num=%d)\n", -+ MAX_MESSAGES, num); -+ return -EINVAL; -+ } -+ -+ /* check consistency of our messages */ -+ for (i=0;ialgo_data; -+ -+ /* increment number of bytes to read by one -- read dummy byte */ -+ for (i = 0; i <= count; i++) { -+ if (i!=0){ -+ /* set ACK to NAK for last received byte ICR[ACKNAK] = 1 -+ only if not a repeated start */ -+ -+ if ((i == count) && last) { -+ adap->transfer( last, I2C_RECEIVE, 0); -+ }else{ -+ adap->transfer( 0, I2C_RECEIVE, 1); -+ } -+ -+ timeout = adap->wait_for_interrupt(I2C_RECEIVE); -+ -+#ifdef DEBUG -+ if (timeout==BUS_ERROR){ -+ printk(KERN_INFO "i2c_pxa_readbytes: bus error -> forcing reset\n"); -+ adap->reset(); -+ return I2C_RETRY; -+ } else -+#endif -+ if (timeout == -ERESTARTSYS) { -+ adap->abort(); -+ return timeout; -+ } else -+ if (timeout){ -+#ifdef DEBUG -+ printk(KERN_INFO "i2c_pxa_readbytes: timeout -> forcing reset\n"); -+#endif -+ adap->reset(); -+ return I2C_RETRY; -+ } -+ -+ } -+ -+ if (i) { -+ buf[i - 1] = adap->read_byte(); -+ } else { -+ adap->read_byte(); /* dummy read */ -+ } -+ } -+ return (i - 1); -+} -+ -+static int i2c_pxa_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, -+ int count, int last) -+{ -+ -+ struct i2c_algo_pxa_data *adap = i2c_adap->algo_data; -+ int wrcount, timeout; -+ -+ for (wrcount=0; wrcountwrite_byte(buf[wrcount]); -+ if ((wrcount==(count-1)) && last) { -+ adap->transfer( last, I2C_TRANSMIT, 0); -+ }else{ -+ adap->transfer( 0, I2C_TRANSMIT, 1); -+ } -+ -+ timeout = adap->wait_for_interrupt(I2C_TRANSMIT); -+ -+#ifdef DEBUG -+ if (timeout==BUS_ERROR) { -+ printk(KERN_INFO "i2c_pxa_sendbytes: bus error -> forcing reset.\n"); -+ adap->reset(); -+ return I2C_RETRY; -+ } else -+#endif -+ if (timeout == -ERESTARTSYS) { -+ adap->abort(); -+ return timeout; -+ } else -+ if (timeout) { -+#ifdef DEBUG -+ printk(KERN_INFO "i2c_pxa_sendbytes: timeout -> forcing reset\n"); -+#endif -+ adap->reset(); -+ return I2C_RETRY; -+ } -+ } -+ return (wrcount); -+} -+ -+ -+static inline int i2c_pxa_set_ctrl_byte(struct i2c_algo_pxa_data * adap, struct i2c_msg *msg) -+{ -+ u16 flags = msg->flags; -+ u8 addr; -+ addr = (u8) ( (0x7f & msg->addr) << 1 ); -+ if (flags & I2C_M_RD ) -+ addr |= 1; -+ if (flags & I2C_M_REV_DIR_ADDR ) -+ addr ^= 1; -+ adap->write_byte(addr); -+ return 0; -+} -+ -+static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) -+{ -+ struct i2c_algo_pxa_data * adap; -+ struct i2c_msg *pmsg=NULL; -+ int i; -+ int ret=0, timeout; -+ -+ adap = i2c_adap->algo_data; -+ -+ timeout = adap->wait_bus_not_busy(); -+ -+ if (timeout) { -+ return I2C_RETRY; -+ } -+ -+ for (i = 0;ret >= 0 && i < num; i++) { -+ int last = i + 1 == num; -+ pmsg = &msgs[i]; -+ -+ ret = i2c_pxa_set_ctrl_byte(adap,pmsg); -+ -+ /* Send START */ -+ if (i == 0) { -+ adap->start(); -+ }else{ -+ adap->repeat_start(); -+ } -+ -+ adap->transfer(0, I2C_TRANSMIT, 0); -+ -+ /* Wait for ITE (transmit empty) */ -+ timeout = adap->wait_for_interrupt(I2C_TRANSMIT); -+ -+#ifdef DEBUG -+ /* Check for ACK (bus error) */ -+ if (timeout==BUS_ERROR){ -+ printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n"); -+ adap->reset(); -+ return I2C_RETRY; -+ } else -+#endif -+ if (timeout == -ERESTARTSYS) { -+ adap->abort(); -+ return timeout; -+ } else -+ if (timeout) { -+#ifdef DEBUG -+ printk(KERN_INFO "i2c_pxa_do_xfer: timeout -> forcing reset\n"); -+#endif -+ adap->reset(); -+ return I2C_RETRY; -+ } -+/* FIXME: handle arbitration... */ -+#if 0 -+ /* Check for bus arbitration loss */ -+ if (adap->arbitration_loss()){ -+ printk("Arbitration loss detected \n"); -+ adap->reset(); -+ return I2C_RETRY; -+ } -+#endif -+ -+ /* Read */ -+ if (pmsg->flags & I2C_M_RD) { -+ /* read bytes into buffer*/ -+ ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last); -+#if DEBUG > 2 -+ if (ret != pmsg->len) { -+ printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n", -+ ret, pmsg->len); -+ } else { -+ printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret); -+ } -+#endif -+ } else { /* Write */ -+ ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last); -+#if DEBUG > 2 -+ if (ret != pmsg->len) { -+ printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n", -+ ret, pmsg->len); -+ } else { -+ printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret); -+ } -+#endif -+ } -+ } -+ -+ if (ret<0){ -+ return ret; -+ }else{ -+ return i; -+ } -+} -+ -+static int i2c_pxa_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) -+{ -+ int retval = i2c_pxa_valid_messages( msgs, num); -+ if( retval > 0) -+ { -+ int i; -+ for (i=i2c_adap->retries; i>=0; i--){ -+ int retval = i2c_pxa_do_xfer(i2c_adap,msgs,num); -+ if (retval!=I2C_RETRY){ -+ return retval; -+ } -+ if( i2c_debug)printk(KERN_INFO"Retrying transmission \n"); -+ udelay(100); -+ } -+ if( i2c_debug)printk(KERN_INFO"Retried %i times\n",i2c_adap->retries); -+ return -EREMOTEIO; -+ -+ } -+ return retval; -+} -+ -+static u32 i2c_pxa_functionality(struct i2c_adapter * adapter) -+{ -+ /* Emulate the SMBUS functions */ -+ return I2C_FUNC_SMBUS_EMUL; -+} -+ -+struct i2c_algorithm i2c_pxa_algorithm = { -+ name: "PXA I2C Algorithm", -+ id: I2C_ALGO_PXA, -+ master_xfer: i2c_pxa_xfer, -+ smbus_xfer: NULL, -+ slave_send: NULL, -+ slave_recv: NULL, -+ algo_control: NULL, -+ functionality: i2c_pxa_functionality, -+}; -+ -+/* -+ * registering functions to load algorithms at runtime -+ */ -+int i2c_pxa_add_bus(struct i2c_adapter *i2c_adap) -+{ -+ struct i2c_algo_pxa_data *adap = i2c_adap->algo_data; -+ -+ printk(KERN_INFO"I2C: Adding %s.\n", i2c_adap->dev.name); -+ -+ i2c_adap->algo = &i2c_pxa_algorithm; -+ -+ MOD_INC_USE_COUNT; -+ -+ /* register new adapter to i2c module... */ -+ i2c_add_adapter(i2c_adap); -+ -+ adap->reset(); -+ -+ /* scan bus */ -+ if (pxa_scan) { -+ int i; -+ printk(KERN_INFO "I2C: Scanning bus "); -+ for (i = 0x02; i < 0xff; i+=2) { -+ if( i==(I2C_PXA_SLAVE_ADDR<<1)) continue; -+ -+ if (adap->wait_bus_not_busy()) { -+ printk(KERN_INFO "I2C: scanning bus %s - TIMEOUT.\n", -+ i2c_adap->dev.name); -+ return -EIO; -+ } -+ adap->write_byte(i); -+ adap->start(); -+ adap->transfer(0, I2C_TRANSMIT, 0); -+ -+ if ((adap->wait_for_interrupt(I2C_TRANSMIT) != BUS_ERROR)) { -+ printk("(%02x)",i>>1); -+ adap->abort(); -+ } else { -+// printk("."); -+ adap->stop(); -+ } -+ udelay(adap->udelay); -+ } -+ printk("\n"); -+ } -+ return 0; -+} -+ -+int i2c_pxa_del_bus(struct i2c_adapter *i2c_adap) -+{ -+ int res; -+ if ((res = i2c_del_adapter(i2c_adap)) < 0) -+ return res; -+ -+ MOD_DEC_USE_COUNT; -+ -+ printk(KERN_INFO "I2C: Removing %s.\n", i2c_adap->dev.name); -+ -+ return 0; -+} -+ -+static int __init i2c_algo_pxa_init (void) -+{ -+ printk(KERN_INFO "I2C: PXA algorithm module loaded.\n"); -+ return 0; -+} -+ -+EXPORT_SYMBOL(i2c_pxa_add_bus); -+EXPORT_SYMBOL(i2c_pxa_del_bus); -+ -+MODULE_PARM(pxa_scan, "i"); -+MODULE_PARM_DESC(pxa_scan, "Scan for active chips on the bus"); -+ -+MODULE_AUTHOR("Intrinsyc Software Inc."); -+MODULE_LICENSE("GPL"); -+ -+module_init(i2c_algo_pxa_init); ---- linux-2.6.5/drivers/i2c/algos/Makefile~heh 2004-04-03 22:37:37.000000000 -0500 -+++ linux-2.6.5/drivers/i2c/algos/Makefile 2004-04-30 20:57:36.000000000 -0400 -@@ -4,6 +4,7 @@ - - obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o - obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o -+obj-$(CONFIG_I2C_ALGOPXA) += i2c-algo-pxa.o - obj-$(CONFIG_I2C_ALGOITE) += i2c-algo-ite.o - - ifeq ($(CONFIG_I2C_DEBUG_ALGO),y) ---- linux-2.6.5/Makefile~heh 2004-04-03 22:37:36.000000000 -0500 -+++ linux-2.6.5/Makefile 2004-04-30 20:57:58.000000000 -0400 -@@ -1,7 +1,7 @@ - VERSION = 2 - PATCHLEVEL = 6 - SUBLEVEL = 5 --EXTRAVERSION = -+EXTRAVERSION = -gnalm1 - NAME=Zonked Quokka - - # *DOCUMENTATION* diff --git a/recipes/linux/gumstix_2.6.5-gnalm1-gum0.bb b/recipes/linux/gumstix_2.6.5-gnalm1-gum0.bb deleted file mode 100644 index e32f35bf08..0000000000 --- a/recipes/linux/gumstix_2.6.5-gnalm1-gum0.bb +++ /dev/null @@ -1,30 +0,0 @@ -BROKEN = "1" -#linux-2.6.5-gnalm1-gum0.patch is not fetchable - -SECTION = "kernel" -DESCRIPTION = "Linux kernel for OMAP processors" -LICENSE = "GPLv2" - -COMPATIBLE_MACHINE = "gumstix" - -# NOTE: pulled local linux-2.6.5-gnalm1, since it didn't apply cleanly -SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.5.tar.bz2;name=kernel \ - file://linux-2.6.5-gnalm1.patch \ - http://gumstix.superlucidity.net/downloads/kernel/patches/linux-2.6.5-gnalm1-gum0.patch;name=patch \ - file://defconfig" -S = "${WORKDIR}/linux-2.6.5" - -inherit kernel - - -do_configure_prepend() { - install -m 0644 ${WORKDIR}/defconfig ${S}/.config || die "no default configuration for ${MACHINE} available." - oe_runmake oldconfig -} - -COMPATIBLE_HOST = 'arm.*-linux' - -SRC_URI[kernel.md5sum] = "9a76bf64c1151369b250f967d83077aa" -SRC_URI[kernel.sha256sum] = "e405000ad0b74af383b5f9c6db30b309e8cb872bb5df55ddef0413970f2e18c2" -SRC_URI[patch.md5sum] = "10c494456bd3a17f351ce1bef1618d55" -SRC_URI[patch.sha256sum] = "942e391ab93d55e18ef07c5653ae8fd09e12b11d1c789711277407e10371350f" diff --git a/recipes/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch b/recipes/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch deleted file mode 100644 index 8829a0cea7..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch +++ /dev/null @@ -1,13 +0,0 @@ -Oddly, drivers/input/input.c seems to reference a symbol which is apparently in another module but not exported. -Index: linux-2.6.15gum/drivers/char/random.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/char/random.c -+++ linux-2.6.15gum/drivers/char/random.c -@@ -646,6 +646,7 @@ extern void add_input_randomness(unsigne - add_timer_randomness(&input_timer_state, - (type << 4) ^ code ^ (code >> 4) ^ value); - } -+EXPORT_SYMBOL(add_input_randomness); - - void add_interrupt_randomness(int irq) - { diff --git a/recipes/linux/linux-gumstix-2.6.15/arch-config.patch b/recipes/linux/linux-gumstix-2.6.15/arch-config.patch deleted file mode 100644 index 411a117953..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/arch-config.patch +++ /dev/null @@ -1,55 +0,0 @@ -Index: linux-2.6.15gum/arch/arm/mach-pxa/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-pxa/Kconfig -+++ linux-2.6.15gum/arch/arm/mach-pxa/Kconfig -@@ -5,6 +5,10 @@ menu "Intel PXA2xx Implementations" - choice - prompt "Select target board" - -+config ARCH_GUMSTIX -+ bool "Gumstix Platform" -+ depends on ARCH_PXA -+ - config ARCH_LUBBOCK - bool "Intel DBPXA250 Development Platform" - select PXA25x -@@ -94,6 +98,27 @@ config MACH_TOSA - bool "Enable Sharp SL-6000x (Tosa) Support" - depends PXA_SHARPSL_25x - -+choice -+ depends on ARCH_GUMSTIX -+ prompt "Gumstix Platform Version" -+ default ARCH_GUMSTIX_F -+ -+config ARCH_GUMSTIX_ORIG -+ bool "Original Gumstix" -+ select PXA25x -+ help -+ The original gumstix platform, including the gs-200x and gs-400x and the waysmall -+ systems using these boards. -+ -+config ARCH_GUMSTIX_F -+ bool "Gumstix-F" -+ select PXA25x -+ help -+ The updated Gumstix boards with 60-pin connector, including gs-200f, gs-400f and the -+ waysmall systems using these boards, including ws-200ax and ws-400ax. -+ -+endchoice -+ - config PXA25x - bool - help -Index: linux-2.6.15gum/arch/arm/mach-pxa/Makefile -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-pxa/Makefile -+++ linux-2.6.15gum/arch/arm/mach-pxa/Makefile -@@ -8,6 +8,7 @@ obj-$(CONFIG_PXA25x) += pxa25x.o - obj-$(CONFIG_PXA27x) += pxa27x.o - - # Specific board support -+obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o - obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o - obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o - obj-$(CONFIG_ARCH_PXA_IDP) += idp.o diff --git a/recipes/linux/linux-gumstix-2.6.15/audio.patch b/recipes/linux/linux-gumstix-2.6.15/audio.patch deleted file mode 100644 index d565b70582..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/audio.patch +++ /dev/null @@ -1,454 +0,0 @@ -Index: linux-2.6.15gum/sound/oss/ac97_codec.c -=================================================================== ---- linux-2.6.15gum.orig/sound/oss/ac97_codec.c -+++ linux-2.6.15gum/sound/oss/ac97_codec.c -@@ -59,6 +59,9 @@ - - #define CODEC_ID_BUFSZ 14 - -+static int ucb1400_read_mixer(struct ac97_codec *codec, int oss_channel); -+static void ucb1400_write_mixer(struct ac97_codec *codec, int oss_channel, -+ unsigned int left, unsigned int right); - static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel); - static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel, - unsigned int left, unsigned int right); -@@ -85,6 +88,7 @@ static int cmedia_init(struct ac97_codec - static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode); - static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode); - static int ucb1400_init(struct ac97_codec *codec); -+static int ucb1400_control(struct ac97_codec *codec, int on); - - - /* -@@ -120,7 +124,7 @@ static struct ac97_ops crystal_digital_o - static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL }; - static struct ac97_ops cmedia_ops = { NULL, eapd_control, NULL}; - static struct ac97_ops cmedia_digital_ops = { cmedia_init, eapd_control, cmedia_digital_control}; --static struct ac97_ops ucb1400_ops = { ucb1400_init, eapd_control, NULL }; -+static struct ac97_ops ucb1400_ops = { ucb1400_init, ucb1400_control, NULL }; - - /* sorted by vendor/device id */ - static const struct { -@@ -309,6 +313,143 @@ static LIST_HEAD(codecs); - static LIST_HEAD(codec_drivers); - static DECLARE_MUTEX(codec_sem); - -+// Values of UCB1400 register addresses -+#define AC97_UCB1400_FCR1 (0x6a) -+#define AC97_UCB1400_FCR2 (0x6c) -+// Masks for bits of interest in those registers -+#define AC97_UCB1400_BASS_BOOST_MASK (0xf << 11) -+#define AC97_UCB1400_TREB_BOOST_MASK (0x3 << 9) -+#define AC97_UCB1400_BOOST_MODE_MASK (0x3 << 7) -+// Calculate the boost mode from the register by extracting the bits, then shifting it down -+// Mode 0 == flat, 1 == minimum, 2 == minimum, 3 == maximum -+#define AC97_UCB1400_BOOST_MODE(x) (((x) & AC97_UCB1400_BOOST_MODE_MASK) >> 7) -+// Caculate the treble boost -+#define AC97_UCB1400_TREB_BOOST(x) (((x) & AC97_UCB1400_TREB_BOOST_MASK) >> 9) -+// Calculate the bass boost -+#define AC97_UCB1400_BASS_BOOST(x) (((x) & AC97_UCB1400_BASS_BOOST_MASK) >> 11) -+ -+// Use a conversion table to translate from the register values to dB values -+#define AC97_UCB1400_BASS_LOOKUP(x,l) ((l)[AC97_UCB1400_BASS_BOOST(x) | (AC97_UCB1400_BOOST_MODE(x) << 4)]) -+#define AC97_UCB1400_TREB_LOOKUP(x,l) ((l)[AC97_UCB1400_TREB_BOOST(x) | (AC97_UCB1400_BOOST_MODE(x) << 4)]) -+ -+// This lookup table is indexed by a 6 bit number: -+// Two high bits are the boost mode from teh register -+// Four low bits are from the BASS or TREB boost value in the register -+// The lookup value is the dB boost calculated from the UCB1400 spec sheet -+// The lookup values will be calculated and populated during ucb1400_init() -+static const u8 ac97_ucb1400_boost_lookup[] = { -+ [0] = 0, [1] = 0, [2] = 0, [3] = 0, -+ [4] = 0, [5] = 0, [6] = 0, [7] = 0, // flat 00 -+ [8] = 0, [9] = 0, [10] = 0, [11] = 0, -+ [12] = 0, [13] = 0, [14] = 0, [15] = 0, -+ -+ [16] = 0, [17] = 2, [18] = 4, [19] = 6, -+ [20] = 8, [21] = 10, [22] = 12, [23] = 14, // min 01 -+ [24] = 16, [25] = 18, [26] = 18, [27] = 18, -+ [28] = 18, [29] = 18, [30] = 18, [31] = 18, -+ -+ [32] = 0, [33] = 2, [34] = 4, [35] = 6, -+ [36] = 8, [37] = 10, [38] = 12, [39] = 14, // min 10 -+ [40] = 16, [41] = 18, [42] = 18, [43] = 18, -+ [44] = 18, [45] = 18, [46] = 18, [47] = 18, -+ -+ [48] = 0, [49] = 2, [50] = 4, [51] = 6, -+ [52] = 8, [53] = 10, [54] = 12, [55] = 14, // max 11 -+ [56] = 16, [57] = 18, [58] = 20, [59] = 22, -+ [60] = 24, [61] = 24, [62] = 24, [63] = 24 -+}; -+ -+static int ucb1400_read_mixer(struct ac97_codec *codec, int oss_channel) -+{ -+ u16 val; -+ -+ switch(oss_channel) -+ { -+ -+ case SOUND_MIXER_BASS: -+ // Convert from the 24-dB max BASS boost level to a %age -+ val = codec->codec_read(codec, AC97_UCB1400_FCR1); // Read the register -+ return (AC97_UCB1400_BASS_LOOKUP(val, ac97_ucb1400_boost_lookup)*100)/24; -+ -+ case SOUND_MIXER_TREBLE: -+ // Convert from the 6-dB max TREB boost level to a %age -+ val = codec->codec_read(codec, AC97_UCB1400_FCR1); // Read the register -+ return (AC97_UCB1400_TREB_LOOKUP(val, ac97_ucb1400_boost_lookup)*100)/6; -+ -+ case SOUND_MIXER_MIC: -+ val = codec->codec_read(codec, AC97_MIC_VOL); -+ return (val & AC97_MICBOOST ? 100 : 0); -+ -+ default: -+ return ac97_read_mixer(codec, oss_channel); -+ } -+} -+ -+#ifndef MAX -+#define MAX(a,b) (((a)>(b)) ? (a) : (b)) -+#endif -+ -+static void ucb1400_write_mixer(struct ac97_codec *codec, int oss_channel, -+ unsigned int left, unsigned int right) -+{ -+ u16 old_val,new_val; -+ u8 treb,bass; -+ -+ switch(oss_channel) -+ { -+ case SOUND_MIXER_BASS: -+ case SOUND_MIXER_TREBLE: -+ old_val = codec->codec_read(codec, AC97_UCB1400_FCR1); // Read the register -+ -+ // Determine which one changed, set old one to old value (or 0 if old mode was flat) -+ bass = (oss_channel==SOUND_MIXER_BASS) ? -+ (left*24)/100 : // Convert from %age to 0-24dB scale for bass -+ AC97_UCB1400_BASS_LOOKUP(old_val, ac97_ucb1400_boost_lookup); -+ treb = (oss_channel==SOUND_MIXER_TREBLE) ? -+ (left*6)/100 : // convert from %age to 0-6dB scale for bass -+ AC97_UCB1400_TREB_LOOKUP(old_val, ac97_ucb1400_boost_lookup); -+ -+ // Now convert both treble and bass to values for the register. -+ // If both are 0, then use mode flat -+ // If either is non-zero, then use mode min if bass <=18 -+ // Otherwise, use mode max -+ new_val = old_val & ~(AC97_UCB1400_BASS_BOOST_MASK | // First clear the bits -+ AC97_UCB1400_TREB_BOOST_MASK | // which is same as flat mode -+ AC97_UCB1400_BOOST_MODE_MASK); // with both boosts at 0 -+ if(bass > 18) -+ { -+ new_val |= (3 << 7); // Set boost mode to 0b11 which is "max" -+ } -+ else if(bass > 0 || treb > 0) -+ { -+ new_val |= (1 << 7); // Set boost mode to 0b01 which is "min" -+ } -+ else -+ { -+ // Set boost mode to 0b00 which is "flat" -+ } -+ -+ if(bass || treb) -+ { -+ // The value to stick in the register the boost in dB divided by 2 -+ // Dividing by 2 is the same as shifting right by 1 -+ // We fix overflows by anding with the mask -+ new_val |= ((bass >> 1) << 11) & AC97_UCB1400_BASS_BOOST_MASK; -+ new_val |= ((treb >> 1) << 9) & AC97_UCB1400_TREB_BOOST_MASK; -+ } -+ -+ // Ok, now poke the value back to the codec -+ codec->codec_write(codec, AC97_UCB1400_FCR1, new_val); -+ break; -+ -+ case SOUND_MIXER_MIC: -+ codec->codec_write(codec, AC97_MIC_VOL, (left >= 50 ? AC97_MICBOOST : 0)); -+ break; -+ -+ default: ac97_write_mixer(codec, oss_channel, left, right); -+ } -+} -+ - /* reads the given OSS mixer from the ac97 the caller must have insured that the ac97 knows - about that given mixer, and should be holding a spinlock for the card */ - static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel) -@@ -526,6 +667,7 @@ static int ac97_recmask_io(struct ac97_c - #endif - - codec->codec_write(codec, AC97_RECORD_SELECT, val); -+ val = codec->codec_read(codec, AC97_RECORD_SELECT); - - return 0; - }; -@@ -634,6 +776,8 @@ int ac97_read_proc (char *page, char **s - { - int len = 0, cap, extid, val, id1, id2; - struct ac97_codec *codec; -+ u8 ac97_register_query_list[] = {0x02,0x0e,0x1a,0x1c,0x26,0x2a,0x2c,0x32,0x6a,0x6c,0x00}; -+ size_t i=0; - int is_ac97_20 = 0; - - if ((codec = data) == NULL) -@@ -702,6 +846,13 @@ int ac97_read_proc (char *page, char **s - codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE)); - } - -+ do -+ { -+ len += sprintf(page+len, "Reg. 0x%02x : 0x%04x\n", -+ ac97_register_query_list[i], -+ codec->codec_read(codec, ac97_register_query_list[i])); -+ i++; -+ } while(ac97_register_query_list[i]); - return len; - } - -@@ -1180,7 +1331,25 @@ static int ad1886_init(struct ac97_codec - } - - -+static int ucb1400_control(struct ac97_codec *codec, int on) -+{ -+ if(on) -+ { -+ codec->codec_write(codec, AC97_POWER_CONTROL, 0x0000); // turn everything on - -+ // Now we wait for everything to settle -+ udelay(100); -+ } -+ else -+ { -+ codec->codec_write(codec, AC97_POWER_CONTROL, -+ (1 << 11) | // PR3: Audio Vref power-down -+ (1 << 9) | // PR1: Audio DAC and output path power-down -+ (1 << 8) // PR0: Audio ADC and input path power-down -+ ); -+ } -+ return 0; -+} - - /* - * This is basically standard AC97. It should work as a default for -@@ -1336,10 +1505,55 @@ static int pt101_init(struct ac97_codec - - static int ucb1400_init(struct ac97_codec *codec) - { -- codec->codec_write(codec,AC97_EXTENDED_STATUS,1); -- //codec->codec_write(codec, 0x6a, 0x1ff7); -- codec->codec_write(codec, 0x6a, 0x0050); -- codec->codec_write(codec, 0x6c, 0x0030); -+ codec->supported_mixers = SOUND_MASK_VOLUME | // Specify what UCB1400 supports -+ SOUND_MASK_BASS | -+ SOUND_MASK_TREBLE | -+ SOUND_MASK_MIC | -+ SOUND_MASK_IGAIN; -+ -+ codec->stereo_mixers = SOUND_MASK_VOLUME | // Specify what UCB1400 supports -+ SOUND_MASK_LINE | -+ SOUND_MASK_IGAIN; -+ -+ codec->record_sources = SOUND_MASK_MIC | // Specify what UCB1400 supports -+ SOUND_MASK_LINE; -+ -+ codec->read_mixer = ucb1400_read_mixer; // The UCB1400 bass and treble implementations -+ codec->write_mixer = ucb1400_write_mixer; // need special code -+ -+ codec->codec_write(codec,AC97_EXTENDED_STATUS, 1); // Ensure that VRA is on -+ -+ ucb1400_control(codec, 1); // Turn on DAC/ADC paths first to prevent click -+ -+ codec->codec_write(codec, AC97_UCB1400_FCR1, -+ (0 << 11) | // 0 base boost -+ (0 << 9) | // 0 treble boost -+ (0 << 7) | // Mode = flat -+ (1 << 6) | // Headphones enable -+ (0 << 5) | // De-emphasis disabled -+ (1 << 4) | // DC filter enabled -+ (1 << 3) | // Hi-pass filter enabled -+ (0 << 2) | // disable interrupt signalling via GPIO_INT -+ (1 << 0) // clear ADC overflow status if set -+ ); -+ -+ codec->codec_write(codec, AC97_UCB1400_FCR2, -+ (0 << 15) | // must be 0 -+ (0 << 13) | // must be 0 -+ (1 << 12) | // ADC filter enabled -+ (0 << 10) | // must be 0 -+ (0 << 4) | // Smart low power mode on neither Codec nor PLL -+ (0 << 0) // must be 0 -+ ); -+ -+ codec->codec_write(codec, AC97_RECORD_SELECT, 0); // default source is MIC -+ -+ codec->codec_write(codec, AC97_MIC_VOL, (1 << 6)); // 20dB MIC boost -+ -+ codec->codec_write(codec, AC97_RECORD_GAIN, 0); // no master record gain -+ -+ codec->codec_write(codec, AC97_GENERAL_PURPOSE, 0); // no ADC to DAC loopback -+ - return 0; - } - -@@ -1368,30 +1582,9 @@ unsigned int ac97_set_dac_rate(struct ac - - if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE)) - { -- /* Mute several registers */ -- mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO); -- mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO); -- phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL); -- pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL); -- codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol); -- codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol); -- codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol); -- codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol); -- -- /* Power down the DAC */ -- dacp=codec->codec_read(codec, AC97_POWER_CONTROL); -- codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200); - /* Load the rate and read the effective rate */ - codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate); - new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE); -- /* Power it back up */ -- codec->codec_write(codec, AC97_POWER_CONTROL, dacp); -- -- /* Restore volumes */ -- codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol); -- codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol); -- codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol); -- codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol); - } - return new_rate; - } -@@ -1414,14 +1607,9 @@ unsigned int ac97_set_adc_rate(struct ac - - if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE)) - { -- /* Power down the ADC */ -- dacp=codec->codec_read(codec, AC97_POWER_CONTROL); -- codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100); - /* Load the rate and read the effective rate */ - codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate); - new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE); -- /* Power it back up */ -- codec->codec_write(codec, AC97_POWER_CONTROL, dacp); - } - return new_rate; - } -Index: linux-2.6.15gum/sound/oss/pxa-ac97.c -=================================================================== ---- linux-2.6.15gum.orig/sound/oss/pxa-ac97.c -+++ linux-2.6.15gum/sound/oss/pxa-ac97.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -55,10 +56,10 @@ static u16 pxa_ac97_read(struct ac97_cod - if (GSR & GSR_RDCS) { - GSR = GSR_RDCS; //write a 1 to clear - printk(KERN_CRIT "%s: read codec register timeout.\n", __FUNCTION__); -- } -+ } - - init_completion(&CAR_completion); -- val = *reg_addr; //valid data now but we've just started another cycle... -+ val = *reg_addr; //valid data now but we've just started another cycle... - wait_for_completion(&CAR_completion); - - } else { -@@ -116,7 +117,7 @@ int pxa_ac97_get(struct ac97_codec **cod - if (ret) - return ret; - -- CKEN |= CKEN2_AC97; -+ pxa_set_cken(CKEN2_AC97,1); - - pxa_gpio_mode(GPIO31_SYNC_AC97_MD); - pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); -@@ -134,7 +135,7 @@ int pxa_ac97_get(struct ac97_codec **cod - if (ret != 1) { - free_irq(IRQ_AC97, NULL); - GCR = GCR_ACLINK_OFF; -- CKEN &= ~CKEN2_AC97; -+ pxa_set_cken(CKEN2_AC97,0); - return ret; - } - } -@@ -151,7 +152,7 @@ void pxa_ac97_put(void) - pxa_ac97_refcount--; - if (!pxa_ac97_refcount) { - GCR = GCR_ACLINK_OFF; -- CKEN &= ~CKEN2_AC97; -+ pxa_set_cken(CKEN2_AC97,0); - free_irq(IRQ_AC97, NULL); - } - up(&pxa_ac97_mutex); -@@ -179,7 +180,7 @@ static audio_stream_t ac97_audio_in; - */ - static void update_audio_in (void) - { --#if 1 -+#if 0 - long val; - - /* Use the value stuffed by ac97_recmask_io() -@@ -335,6 +336,13 @@ static int __init pxa_ac97_init(void) - - update_audio_in (); - -+ if(!proc_mkdir("driver/ucb1400",NULL)) return -EIO; -+ if(!create_proc_read_entry("driver/ucb1400/ac97",0,NULL,ac97_read_proc,&pxa_ac97_codec)) -+ { -+ remove_proc_entry("driver/ucb1400",NULL); -+ return -EIO; -+ } -+ - ac97_audio_state.dev_dsp = register_sound_dsp(&ac97_audio_fops, -1); - pxa_ac97_codec.dev_mixer = register_sound_mixer(&mixer_fops, -1); - -@@ -345,6 +353,8 @@ static void __exit pxa_ac97_exit(void) - { - unregister_sound_dsp(ac97_audio_state.dev_dsp); - unregister_sound_mixer(pxa_ac97_codec.dev_mixer); -+ remove_proc_entry("driver/ucb1400/ac97",NULL); -+ remove_proc_entry("driver/ucb1400",NULL); - pxa_ac97_put(); - } - -Index: linux-2.6.15gum/sound/oss/pxa-audio.c -=================================================================== ---- linux-2.6.15gum.orig/sound/oss/pxa-audio.c -+++ linux-2.6.15gum/sound/oss/pxa-audio.c -@@ -293,8 +293,6 @@ static int audio_write(struct file *file - audio_stream_t *s = state->output_stream; - int chunksize, ret = 0; - -- if (ppos != &file->f_pos) -- return -ESPIPE; - if (s->mapped) - return -ENXIO; - if (!s->buffers && audio_setup_buf(s)) -@@ -365,8 +363,6 @@ static int audio_read(struct file *file, - audio_stream_t *s = state->input_stream; - int chunksize, ret = 0; - -- if (ppos != &file->f_pos) -- return -ESPIPE; - if (s->mapped) - return -ENXIO; - if (!s->buffers && audio_setup_buf(s)) -@@ -684,6 +680,9 @@ static int audio_ioctl( struct inode *in - file->f_flags |= O_NONBLOCK; - return 0; - -+ case SNDCTL_DSP_GETODELAY: -+ printk("%s: GETODELAY not implemented!\n",__FILE__); -+ - case SNDCTL_DSP_RESET: - if (file->f_mode & FMODE_WRITE) - audio_clear_buf(os); diff --git a/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch b/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch deleted file mode 100644 index efb7e73e15..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch +++ /dev/null @@ -1,1415 +0,0 @@ -Index: linux-2.6.15gum/include/linux/ac97_codec.h -=================================================================== ---- linux-2.6.15gum.orig/include/linux/ac97_codec.h -+++ linux-2.6.15gum/include/linux/ac97_codec.h -@@ -259,7 +259,8 @@ struct ac97_codec { - int type; - u32 model; - -- int modem:1; -+ unsigned modem:1; -+ unsigned power:1; - - struct ac97_ops *codec_ops; - -Index: linux-2.6.15gum/sound/oss/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/sound/oss/Kconfig -+++ linux-2.6.15gum/sound/oss/Kconfig -@@ -178,6 +178,14 @@ config SOUND_MAESTRO3 - Say Y or M if you have a sound system driven by ESS's Maestro 3 - PCI sound chip. - -+config SOUND_PXA_AC97 -+ tristate "PXA AC97 support" -+ depends on SOUND_PRIME!=n && ARCH_PXA && SOUND -+ -+config SOUND_PXA_AUDIO -+ tristate "PXA audio support" -+ depends on SOUND_PXA_AC97 -+ - config SOUND_ICH - tristate "Intel ICH (i8xx) audio support" - depends on SOUND_PRIME && PCI -@@ -1125,6 +1133,9 @@ config SOUND_AD1980 - tristate "AD1980 front/back switch plugin" - depends on SOUND_PRIME && OBSOLETE_OSS_DRIVER - -+config SOUND_WM97XX -+ tristate "WM97XX sound/touchscreen codec" -+ - config SOUND_SH_DAC_AUDIO - tristate "SuperH DAC audio support" - depends on SOUND_PRIME && CPU_SH3 -Index: linux-2.6.15gum/sound/oss/Makefile -=================================================================== ---- linux-2.6.15gum.orig/sound/oss/Makefile -+++ linux-2.6.15gum/sound/oss/Makefile -@@ -44,6 +44,8 @@ obj-$(CONFIG_SOUND_VIA82CXXX) += via82cx - ifeq ($(CONFIG_MIDI_VIA82CXXX),y) - obj-$(CONFIG_SOUND_VIA82CXXX) += sound.o uart401.o - endif -+obj-$(CONFIG_SOUND_PXA_AC97) += pxa-ac97.o ac97_codec.o -+obj-$(CONFIG_SOUND_PXA_AUDIO) += pxa-audio.o - obj-$(CONFIG_SOUND_YMFPCI) += ymfpci.o ac97_codec.o - ifeq ($(CONFIG_SOUND_YMFPCI_LEGACY),y) - obj-$(CONFIG_SOUND_YMFPCI) += opl3.o uart401.o -Index: linux-2.6.15gum/sound/oss/ac97_codec.c -=================================================================== ---- linux-2.6.15gum.orig/sound/oss/ac97_codec.c -+++ linux-2.6.15gum/sound/oss/ac97_codec.c -@@ -84,6 +84,7 @@ static int crystal_digital_control(struc - static int cmedia_init(struct ac97_codec * codec); - static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode); - static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode); -+static int ucb1400_init(struct ac97_codec *codec); - - - /* -@@ -119,6 +120,7 @@ static struct ac97_ops crystal_digital_o - static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL }; - static struct ac97_ops cmedia_ops = { NULL, eapd_control, NULL}; - static struct ac97_ops cmedia_digital_ops = { cmedia_init, eapd_control, cmedia_digital_control}; -+static struct ac97_ops ucb1400_ops = { ucb1400_init, eapd_control, NULL }; - - /* sorted by vendor/device id */ - static const struct { -@@ -164,6 +166,7 @@ static const struct { - {0x4e534331, "National Semiconductor LM4549", &null_ops}, - {0x53494c22, "Silicon Laboratory Si3036", &null_ops}, - {0x53494c23, "Silicon Laboratory Si3038", &null_ops}, -+ {0x50534304, "Philips UCB1400", &ucb1400_ops}, - {0x545200FF, "TriTech TR?????", &tritech_m_ops}, - {0x54524102, "TriTech TR28022", &null_ops}, - {0x54524103, "TriTech TR28023", &null_ops}, -@@ -461,6 +464,17 @@ static void ac97_write_mixer(struct ac97 - val = codec->codec_read(codec, mh->offset); - printk(" -> 0x%04x\n", val); - #endif -+ -+ if (val & AC97_MUTE) -+ val = 0; -+ else -+ val = 1; -+ if ((oss_channel == SOUND_MIXER_VOLUME) && -+ (codec->codec_ops->amplifier) && -+ (codec->power != val)) { -+ codec->power = val; -+ codec->codec_ops->amplifier (codec, codec->power); -+ } - } - - /* a thin wrapper for write_mixer */ -@@ -1092,6 +1106,13 @@ static int wolfson_init05(struct ac97_co - { - /* set front mixer volume */ - codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808); -+ /*codec->codec_write(codec, 0x78, 0xc004); -+ while(1){ -+ codec->codec_write(codec, 0x76, 0xa020); -+ printk("%08x ", codec->codec_read(codec, 0x76)); -+ printk("%08x ", codec->codec_read(codec, 0x78)); -+ printk("%08x\n", codec->codec_read(codec, 0x7A)); -+ }*/ - return 0; - } - -@@ -1313,6 +1334,14 @@ static int pt101_init(struct ac97_codec - } - #endif - -+static int ucb1400_init(struct ac97_codec *codec) -+{ -+ codec->codec_write(codec,AC97_EXTENDED_STATUS,1); -+ //codec->codec_write(codec, 0x6a, 0x1ff7); -+ codec->codec_write(codec, 0x6a, 0x0050); -+ codec->codec_write(codec, 0x6c, 0x0030); -+ return 0; -+} - - EXPORT_SYMBOL(ac97_read_proc); - EXPORT_SYMBOL(ac97_probe_codec); -Index: linux-2.6.15gum/sound/oss/pxa-ac97.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/sound/oss/pxa-ac97.c -@@ -0,0 +1,357 @@ -+/* -+ * linux/drivers/sound/pxa-ac97.c -- AC97 interface for the Cotula chip -+ * -+ * Author: Nicolas Pitre -+ * Created: Aug 15, 2001 -+ * Copyright: MontaVista Software Inc. -+ * -+ * Forward ported to 2.6 by Ian Molton 15/09/2003 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pxa-audio.h" -+ -+static struct completion CAR_completion; -+static int waitingForMask; -+static DECLARE_MUTEX(CAR_mutex); -+ -+static u16 pxa_ac97_read(struct ac97_codec *codec, u8 reg) -+{ -+ u16 val = -1; -+ -+ down(&CAR_mutex); -+ if (!(CAR & CAR_CAIP)) { -+ volatile u32 *reg_addr = (u32 *)&PAC_REG_BASE + (reg >> 1); -+ -+ waitingForMask=GSR_SDONE; -+ -+ init_completion(&CAR_completion); -+ (void)*reg_addr; //start read access across the ac97 link -+ wait_for_completion(&CAR_completion); -+ -+ if (GSR & GSR_RDCS) { -+ GSR = GSR_RDCS; //write a 1 to clear -+ printk(KERN_CRIT "%s: read codec register timeout.\n", __FUNCTION__); -+ } -+ -+ init_completion(&CAR_completion); -+ val = *reg_addr; //valid data now but we've just started another cycle... -+ wait_for_completion(&CAR_completion); -+ -+ } else { -+ printk(KERN_CRIT"%s: CAR_CAIP already set\n", __FUNCTION__); -+ } -+ up(&CAR_mutex); -+ //printk("%s(0x%02x) = 0x%04x\n", __FUNCTION__, reg, val); -+ return val; -+} -+ -+static void pxa_ac97_write(struct ac97_codec *codec, u8 reg, u16 val) -+{ -+ down(&CAR_mutex); -+ if (!(CAR & CAR_CAIP)) { -+ volatile u32 *reg_addr = (u32 *)&PAC_REG_BASE + (reg >> 1); -+ -+ waitingForMask=GSR_CDONE; -+ init_completion(&CAR_completion); -+ *reg_addr = val; -+ wait_for_completion(&CAR_completion); -+ } else { -+ printk(KERN_CRIT "%s: CAR_CAIP already set\n", __FUNCTION__); -+ } -+ up(&CAR_mutex); -+ //printk("%s(0x%02x, 0x%04x)\n", __FUNCTION__, reg, val); -+} -+ -+static irqreturn_t pxa_ac97_irq(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ int gsr = GSR; -+ GSR = gsr & (GSR_SDONE|GSR_CDONE); //write a 1 to clear -+ if (gsr & waitingForMask) -+ complete(&CAR_completion); -+ -+ return IRQ_HANDLED; -+} -+ -+static struct ac97_codec pxa_ac97_codec = { -+ codec_read: pxa_ac97_read, -+ codec_write: pxa_ac97_write, -+}; -+ -+static DECLARE_MUTEX(pxa_ac97_mutex); -+static int pxa_ac97_refcount; -+ -+int pxa_ac97_get(struct ac97_codec **codec) -+{ -+ int ret; -+ -+ *codec = NULL; -+ down(&pxa_ac97_mutex); -+ -+ if (!pxa_ac97_refcount) { -+ ret = request_irq(IRQ_AC97, pxa_ac97_irq, 0, "AC97", NULL); -+ if (ret) -+ return ret; -+ -+ CKEN |= CKEN2_AC97; -+ -+ pxa_gpio_mode(GPIO31_SYNC_AC97_MD); -+ pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); -+ pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); -+ pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); -+ -+ GCR = 0; -+ udelay(10); -+ GCR = GCR_COLD_RST|GCR_CDONE_IE|GCR_SDONE_IE; -+ while (!(GSR & GSR_PCR)) { -+ schedule(); -+ } -+ -+ ret = ac97_probe_codec(&pxa_ac97_codec); -+ if (ret != 1) { -+ free_irq(IRQ_AC97, NULL); -+ GCR = GCR_ACLINK_OFF; -+ CKEN &= ~CKEN2_AC97; -+ return ret; -+ } -+ } -+ -+ pxa_ac97_refcount++; -+ up(&pxa_ac97_mutex); -+ *codec = &pxa_ac97_codec; -+ return 0; -+} -+ -+void pxa_ac97_put(void) -+{ -+ down(&pxa_ac97_mutex); -+ pxa_ac97_refcount--; -+ if (!pxa_ac97_refcount) { -+ GCR = GCR_ACLINK_OFF; -+ CKEN &= ~CKEN2_AC97; -+ free_irq(IRQ_AC97, NULL); -+ } -+ up(&pxa_ac97_mutex); -+} -+ -+EXPORT_SYMBOL(pxa_ac97_get); -+EXPORT_SYMBOL(pxa_ac97_put); -+ -+ -+/* -+ * Audio Mixer stuff -+ */ -+ -+static audio_state_t ac97_audio_state; -+static audio_stream_t ac97_audio_in; -+ -+/* -+ * According to the PXA250 spec, mic-in should use different -+ * DRCMR and different AC97 FIFO. -+ * Unfortunately current UCB1400 versions (up to ver 2A) don't -+ * produce slot 6 for the audio input frame, therefore the PXA -+ * AC97 mic-in FIFO is always starved. -+ * But since UCB1400 is not the only audio CODEC out there, -+ * this is still enabled by default. -+ */ -+static void update_audio_in (void) -+{ -+#if 1 -+ long val; -+ -+ /* Use the value stuffed by ac97_recmask_io() -+ * into recording select register -+ */ -+ val = pxa_ac97_codec.codec_read(&pxa_ac97_codec, AC97_RECORD_SELECT); -+ pxa_audio_clear_buf(&ac97_audio_in); -+ *ac97_audio_in.drcmr = 0; -+ if (val == 0) { -+ ac97_audio_in.dcmd = DCMD_RXMCDR; -+ ac97_audio_in.drcmr = &DRCMRRXMCDR; -+ ac97_audio_in.dev_addr = __PREG(MCDR); -+ } else { -+ ac97_audio_in.dcmd = DCMD_RXPCDR; -+ ac97_audio_in.drcmr = &DRCMRRXPCDR; -+ ac97_audio_in.dev_addr = __PREG(PCDR); -+ } -+ if (ac97_audio_state.rd_ref) -+ *ac97_audio_in.drcmr = -+ ac97_audio_in.dma_ch | DRCMR_MAPVLD; -+#endif -+} -+ -+static int mixer_ioctl( struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ int ret; -+ -+ ret = pxa_ac97_codec.mixer_ioctl(&pxa_ac97_codec, cmd, arg); -+ if (ret) -+ return ret; -+ -+ /* We must snoop for some commands to provide our own extra processing */ -+ switch (cmd) { -+ case SOUND_MIXER_WRITE_RECSRC: -+ update_audio_in (); -+ break; -+ } -+ return 0; -+} -+ -+static struct file_operations mixer_fops = { -+ ioctl: mixer_ioctl, -+ llseek: no_llseek, -+ owner: THIS_MODULE -+}; -+ -+/* -+ * AC97 codec ioctls -+ */ -+ -+static int codec_adc_rate = 48000; -+static int codec_dac_rate = 48000; -+ -+static int ac97_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ int ret; -+ long val = 0; -+ -+ switch(cmd) { -+ case SNDCTL_DSP_STEREO: -+ ret = get_user(val, (int *) arg); -+ if (ret) -+ return ret; -+ /* FIXME: do we support mono? */ -+ ret = (val == 0) ? -EINVAL : 1; -+ return put_user(ret, (int *) arg); -+ -+ case SNDCTL_DSP_CHANNELS: -+ case SOUND_PCM_READ_CHANNELS: -+ /* FIXME: do we support mono? */ -+ return put_user(2, (long *) arg); -+ -+ case SNDCTL_DSP_SPEED: -+ ret = get_user(val, (long *) arg); -+ if (ret) -+ return ret; -+ if (file->f_mode & FMODE_READ) -+ codec_adc_rate = ac97_set_adc_rate(&pxa_ac97_codec, val); -+ if (file->f_mode & FMODE_WRITE) -+ codec_dac_rate = ac97_set_dac_rate(&pxa_ac97_codec, val); -+ /* fall through */ -+ case SOUND_PCM_READ_RATE: -+ if (file->f_mode & FMODE_READ) -+ val = codec_adc_rate; -+ if (file->f_mode & FMODE_WRITE) -+ val = codec_dac_rate; -+ return put_user(val, (long *) arg); -+ -+ case SNDCTL_DSP_SETFMT: -+ case SNDCTL_DSP_GETFMTS: -+ /* FIXME: can we do other fmts? */ -+ return put_user(AFMT_S16_LE, (long *) arg); -+ -+ default: -+ /* Maybe this is meant for the mixer (As per OSS Docs) */ -+ return mixer_ioctl(inode, file, cmd, arg); -+ } -+ return 0; -+} -+ -+ -+/* -+ * Audio stuff -+ */ -+ -+static audio_stream_t ac97_audio_out = { -+ name: "AC97 audio out", -+ dcmd: DCMD_TXPCDR, -+ drcmr: &DRCMRTXPCDR, -+ dev_addr: __PREG(PCDR), -+}; -+ -+static audio_stream_t ac97_audio_in = { -+ name: "AC97 audio in", -+ dcmd: DCMD_RXPCDR, -+ drcmr: &DRCMRRXPCDR, -+ dev_addr: __PREG(PCDR), -+}; -+ -+static audio_state_t ac97_audio_state = { -+ output_stream: &ac97_audio_out, -+ input_stream: &ac97_audio_in, -+ client_ioctl: ac97_ioctl, -+ sem: __MUTEX_INITIALIZER(ac97_audio_state.sem), -+}; -+ -+static int ac97_audio_open(struct inode *inode, struct file *file) -+{ -+ return pxa_audio_attach(inode, file, &ac97_audio_state); -+} -+ -+/* -+ * Missing fields of this structure will be patched with the call -+ * to pxa_audio_attach(). -+ */ -+ -+static struct file_operations ac97_audio_fops = { -+ open: ac97_audio_open, -+ owner: THIS_MODULE -+}; -+ -+ -+static int __init pxa_ac97_init(void) -+{ -+ int ret; -+ struct ac97_codec *dummy; -+ -+ ret = pxa_ac97_get(&dummy); -+ if (ret) -+ return ret; -+ -+ update_audio_in (); -+ -+ ac97_audio_state.dev_dsp = register_sound_dsp(&ac97_audio_fops, -1); -+ pxa_ac97_codec.dev_mixer = register_sound_mixer(&mixer_fops, -1); -+ -+ return 0; -+} -+ -+static void __exit pxa_ac97_exit(void) -+{ -+ unregister_sound_dsp(ac97_audio_state.dev_dsp); -+ unregister_sound_mixer(pxa_ac97_codec.dev_mixer); -+ pxa_ac97_put(); -+} -+ -+ -+module_init(pxa_ac97_init); -+module_exit(pxa_ac97_exit); -+ -+MODULE_AUTHOR("Nicolas Pitre"); -+MODULE_DESCRIPTION("AC97 interface for the Cotula chip"); -+MODULE_LICENSE("GPL"); -Index: linux-2.6.15gum/sound/oss/pxa-audio.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/sound/oss/pxa-audio.c -@@ -0,0 +1,858 @@ -+/* -+ * linux/drivers/sound/pxa-audio.c -- audio interface for the Cotula chip -+ * -+ * Author: Nicolas Pitre -+ * Created: Aug 15, 2001 -+ * Copyright: MontaVista Software Inc. -+ * -+ * 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 -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pxa-audio.h" -+ -+ -+#define AUDIO_NBFRAGS_DEFAULT 8 -+#define AUDIO_FRAGSIZE_DEFAULT 8192 -+ -+#define MAX_DMA_SIZE 4096 -+#define DMA_DESC_SIZE sizeof(pxa_dma_desc) -+ -+ -+/* -+ * This function frees all buffers -+ */ -+#define audio_clear_buf pxa_audio_clear_buf -+ -+void pxa_audio_clear_buf(audio_stream_t * s) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ int frag; -+ -+ if (!s->buffers) -+ return; -+ -+ /* Ensure DMA isn't running */ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ add_wait_queue(&s->stop_wq, &wait); -+ DCSR(s->dma_ch) = DCSR_STOPIRQEN; -+ schedule(); -+ remove_wait_queue(&s->stop_wq, &wait); -+ -+ /* free DMA buffers */ -+ for (frag = 0; frag < s->nbfrags; frag++) { -+ audio_buf_t *b = &s->buffers[frag]; -+ if (!b->master) -+ continue; -+ dma_free_writecombine(NULL, b->master, b->data, b->dma_desc->dsadr); -+ } -+ -+ /* free descriptor ring */ -+ if (s->buffers->dma_desc) -+ dma_free_writecombine(NULL, s->nbfrags * s->descs_per_frag * DMA_DESC_SIZE, -+ s->buffers->dma_desc, s->dma_desc_phys); -+ -+ /* free buffer structure array */ -+ kfree(s->buffers); -+ s->buffers = NULL; -+} -+ -+/* -+ * This function allocates the DMA descriptor array and buffer data space -+ * according to the current number of fragments and fragment size. -+ */ -+static int audio_setup_buf(audio_stream_t * s) -+{ -+ pxa_dma_desc *dma_desc; -+ dma_addr_t dma_desc_phys; -+ int nb_desc, frag, i, buf_size = 0; -+ char *dma_buf = NULL; -+ dma_addr_t dma_buf_phys = 0; -+ -+ if (s->buffers) -+ return -EBUSY; -+ -+ /* Our buffer structure array */ -+ s->buffers = kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL); -+ if (!s->buffers) -+ goto err; -+ memzero(s->buffers, sizeof(audio_buf_t) * s->nbfrags); -+ -+ /* -+ * Our DMA descriptor array: -+ * for Each fragment we have one checkpoint descriptor plus one -+ * descriptor per MAX_DMA_SIZE byte data blocks. -+ */ -+ nb_desc = (1 + (s->fragsize + MAX_DMA_SIZE - 1)/MAX_DMA_SIZE) * s->nbfrags; -+ dma_desc = dma_alloc_writecombine(NULL, nb_desc * DMA_DESC_SIZE, -+ &dma_desc_phys, GFP_KERNEL); -+ -+ if (!dma_desc) -+ goto err; -+ s->descs_per_frag = nb_desc / s->nbfrags; -+ s->buffers->dma_desc = dma_desc; -+ s->dma_desc_phys = dma_desc_phys; -+ for (i = 0; i < nb_desc - 1; i++) -+ dma_desc[i].ddadr = dma_desc_phys + (i + 1) * DMA_DESC_SIZE; -+ dma_desc[i].ddadr = dma_desc_phys; -+ -+ /* Our actual DMA buffers */ -+ for (frag = 0; frag < s->nbfrags; frag++) { -+ audio_buf_t *b = &s->buffers[frag]; -+ -+ /* -+ * Let's allocate non-cached memory for DMA buffers. -+ * We try to allocate all memory at once. -+ * If this fails (a common reason is memory fragmentation), -+ * then we'll try allocating smaller buffers. -+ */ -+ if (!buf_size) { -+ buf_size = (s->nbfrags - frag) * s->fragsize; -+ do { -+ dma_buf = dma_alloc_writecombine(NULL, buf_size, -+ &dma_buf_phys, -+ GFP_KERNEL); -+ if (!dma_buf) -+ buf_size -= s->fragsize; -+ } while (!dma_buf && buf_size); -+ if (!dma_buf) -+ goto err; -+ b->master = buf_size; -+ memzero(dma_buf, buf_size); -+ } -+ -+ /* -+ * Set up our checkpoint descriptor. Since the count -+ * is always zero, we'll abuse the dsadr and dtadr fields -+ * just in case this one is picked up by the hardware -+ * while processing SOUND_DSP_GETPTR. -+ */ -+ dma_desc->dsadr = dma_buf_phys; -+ dma_desc->dtadr = dma_buf_phys; -+ dma_desc->dcmd = DCMD_ENDIRQEN; -+ if (s->output && !s->mapped) -+ dma_desc->ddadr |= DDADR_STOP; -+ b->dma_desc = dma_desc++; -+ -+ /* set up the actual data descriptors */ -+ for (i = 0; (i * MAX_DMA_SIZE) < s->fragsize; i++) { -+ dma_desc[i].dsadr = (s->output) ? -+ (dma_buf_phys + i*MAX_DMA_SIZE) : s->dev_addr; -+ dma_desc[i].dtadr = (s->output) ? -+ s->dev_addr : (dma_buf_phys + i*MAX_DMA_SIZE); -+ dma_desc[i].dcmd = s->dcmd | -+ ((s->fragsize < MAX_DMA_SIZE) ? -+ s->fragsize : MAX_DMA_SIZE); -+ } -+ dma_desc += i; -+ -+ /* handle buffer pointers */ -+ b->data = dma_buf; -+ dma_buf += s->fragsize; -+ dma_buf_phys += s->fragsize; -+ buf_size -= s->fragsize; -+ } -+ -+ s->usr_frag = s->dma_frag = 0; -+ s->bytecount = 0; -+ s->fragcount = 0; -+ sema_init(&s->sem, (s->output) ? s->nbfrags : 0); -+ return 0; -+ -+err: -+ printk("pxa-audio: unable to allocate audio memory\n "); -+ audio_clear_buf(s); -+ return -ENOMEM; -+} -+ -+/* -+ * Our DMA interrupt handler -+ */ -+static void audio_dma_irq(int ch, void *dev_id, struct pt_regs *regs) -+{ -+ audio_stream_t *s = dev_id; -+ u_int dcsr; -+ -+ dcsr = DCSR(ch); -+ DCSR(ch) = dcsr & ~DCSR_STOPIRQEN; -+ -+ if (!s->buffers) { -+ printk("AC97 DMA: wow... received IRQ for channel %d but no buffer exists\n", ch); -+ return; -+ } -+ -+ if (dcsr & DCSR_BUSERR) -+ printk("AC97 DMA: bus error interrupt on channel %d\n", ch); -+ -+ if (dcsr & DCSR_ENDINTR) { -+ u_long cur_dma_desc; -+ u_int cur_dma_frag; -+ -+ /* -+ * Find out which DMA desc is current. Note that DDADR -+ * points to the next desc, not the current one. -+ */ -+ cur_dma_desc = DDADR(ch) - s->dma_desc_phys - DMA_DESC_SIZE; -+ -+ /* -+ * Let the compiler nicely optimize constant divisors into -+ * multiplications for the common cases which is much faster. -+ * Common cases: x = 1 + (1 << y) for y = [0..3] -+ */ -+ switch (s->descs_per_frag) { -+ case 2: cur_dma_frag = cur_dma_desc / (2*DMA_DESC_SIZE); break; -+ case 3: cur_dma_frag = cur_dma_desc / (3*DMA_DESC_SIZE); break; -+ case 5: cur_dma_frag = cur_dma_desc / (5*DMA_DESC_SIZE); break; -+ case 9: cur_dma_frag = cur_dma_desc / (9*DMA_DESC_SIZE); break; -+ default: cur_dma_frag = -+ cur_dma_desc / (s->descs_per_frag * DMA_DESC_SIZE); -+ } -+ -+ /* Account for possible wrap back of cur_dma_desc above */ -+ if (cur_dma_frag >= s->nbfrags) -+ cur_dma_frag = s->nbfrags - 1; -+ -+ while (s->dma_frag != cur_dma_frag) { -+ if (!s->mapped) { -+ /* -+ * This fragment is done - set the checkpoint -+ * descriptor to STOP until it is gets -+ * processed by the read or write function. -+ */ -+ s->buffers[s->dma_frag].dma_desc->ddadr |= DDADR_STOP; -+ up(&s->sem); -+ } -+ if (++s->dma_frag >= s->nbfrags) -+ s->dma_frag = 0; -+ -+ /* Accounting */ -+ s->bytecount += s->fragsize; -+ s->fragcount++; -+ } -+ -+ /* ... and for polling processes */ -+ wake_up(&s->frag_wq); -+ } -+ -+ if ((dcsr & DCSR_STOPIRQEN) && (dcsr & DCSR_STOPSTATE)) -+ wake_up(&s->stop_wq); -+} -+ -+/* -+ * Validate and sets up buffer fragments, etc. -+ */ -+static int audio_set_fragments(audio_stream_t *s, int val) -+{ -+ if (s->mapped || DCSR(s->dma_ch) & DCSR_RUN) -+ return -EBUSY; -+ if (s->buffers) -+ audio_clear_buf(s); -+ s->nbfrags = (val >> 16) & 0x7FFF; -+ val &= 0xffff; -+ if (val < 5) -+ val = 5; -+ if (val > 15) -+ val = 15; -+ s->fragsize = 1 << val; -+ if (s->nbfrags < 2) -+ s->nbfrags = 2; -+ if (s->nbfrags * s->fragsize > 256 * 1024) -+ s->nbfrags = 256 * 1024 / s->fragsize; -+ if (audio_setup_buf(s)) -+ return -ENOMEM; -+ return val|(s->nbfrags << 16); -+} -+ -+ -+/* -+ * The fops functions -+ */ -+ -+static int audio_write(struct file *file, const char *buffer, -+ size_t count, loff_t * ppos) -+{ -+ const char *buffer0 = buffer; -+ audio_state_t *state = (audio_state_t *)file->private_data; -+ audio_stream_t *s = state->output_stream; -+ int chunksize, ret = 0; -+ -+ if (ppos != &file->f_pos) -+ return -ESPIPE; -+ if (s->mapped) -+ return -ENXIO; -+ if (!s->buffers && audio_setup_buf(s)) -+ return -ENOMEM; -+ -+ while (count > 0) { -+ audio_buf_t *b = &s->buffers[s->usr_frag]; -+ -+ /* Grab a fragment */ -+ if (file->f_flags & O_NONBLOCK) { -+ ret = -EAGAIN; -+ if (down_trylock(&s->sem)) -+ break; -+ } else { -+ ret = -ERESTARTSYS; -+ if (down_interruptible(&s->sem)) -+ break; -+ } -+ -+ /* Feed the current buffer */ -+ chunksize = s->fragsize - b->offset; -+ if (chunksize > count) -+ chunksize = count; -+ if (copy_from_user(b->data + b->offset, buffer, chunksize)) { -+ up(&s->sem); -+ return -EFAULT; -+ } -+ -+ b->offset += chunksize; -+ buffer += chunksize; -+ count -= chunksize; -+ if (b->offset < s->fragsize) { -+ ret = 0; -+ up(&s->sem); -+ break; -+ } -+ -+ /* -+ * Activate DMA on current buffer. -+ * We unlock this fragment's checkpoint descriptor and -+ * kick DMA if it is idle. Using checkpoint descriptors -+ * allows for control operations without the need for -+ * stopping the DMA channel if it is already running. -+ */ -+ b->offset = 0; -+ b->dma_desc->ddadr &= ~DDADR_STOP; -+ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) { -+ DDADR(s->dma_ch) = b->dma_desc->ddadr; -+ DCSR(s->dma_ch) = DCSR_RUN; -+ } -+ -+ /* move the index to the next fragment */ -+ if (++s->usr_frag >= s->nbfrags) -+ s->usr_frag = 0; -+ } -+ -+ if ((buffer - buffer0)) -+ ret = buffer - buffer0; -+ return ret; -+} -+ -+ -+static int audio_read(struct file *file, char *buffer, -+ size_t count, loff_t * ppos) -+{ -+ char *buffer0 = buffer; -+ audio_state_t *state = file->private_data; -+ audio_stream_t *s = state->input_stream; -+ int chunksize, ret = 0; -+ -+ if (ppos != &file->f_pos) -+ return -ESPIPE; -+ if (s->mapped) -+ return -ENXIO; -+ if (!s->buffers && audio_setup_buf(s)) -+ return -ENOMEM; -+ -+ while (count > 0) { -+ audio_buf_t *b = &s->buffers[s->usr_frag]; -+ -+ /* prime DMA */ -+ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) { -+ DDADR(s->dma_ch) = -+ s->buffers[s->dma_frag].dma_desc->ddadr; -+ DCSR(s->dma_ch) = DCSR_RUN; -+ } -+ -+ /* Wait for a buffer to become full */ -+ if (file->f_flags & O_NONBLOCK) { -+ ret = -EAGAIN; -+ if (down_trylock(&s->sem)) -+ break; -+ } else { -+ ret = -ERESTARTSYS; -+ if (down_interruptible(&s->sem)) -+ break; -+ } -+ -+ /* Grab data from current buffer */ -+ chunksize = s->fragsize - b->offset; -+ if (chunksize > count) -+ chunksize = count; -+ if (copy_to_user(buffer, b->data + b->offset, chunksize)) { -+ up(&s->sem); -+ return -EFAULT; -+ } -+ b->offset += chunksize; -+ buffer += chunksize; -+ count -= chunksize; -+ if (b->offset < s->fragsize) { -+ ret = 0; -+ up(&s->sem); -+ break; -+ } -+ -+ /* -+ * Make this buffer available for DMA again. -+ * We unlock this fragment's checkpoint descriptor and -+ * kick DMA if it is idle. Using checkpoint descriptors -+ * allows for control operations without the need for -+ * stopping the DMA channel if it is already running. -+ */ -+ b->offset = 0; -+ b->dma_desc->ddadr &= ~DDADR_STOP; -+ -+ /* move the index to the next fragment */ -+ if (++s->usr_frag >= s->nbfrags) -+ s->usr_frag = 0; -+ } -+ -+ if ((buffer - buffer0)) -+ ret = buffer - buffer0; -+ return ret; -+} -+ -+ -+static int audio_sync(struct file *file) -+{ -+ audio_state_t *state = file->private_data; -+ audio_stream_t *s = state->output_stream; -+ audio_buf_t *b; -+ pxa_dma_desc *final_desc; -+ u_long dcmd_save = 0; -+ DECLARE_WAITQUEUE(wait, current); -+ -+ if (!(file->f_mode & FMODE_WRITE) || !s->buffers || s->mapped) -+ return 0; -+ -+ /* -+ * Send current buffer if it contains data. Be sure to send -+ * a full sample count. -+ */ -+ final_desc = NULL; -+ b = &s->buffers[s->usr_frag]; -+ if (b->offset &= ~3) { -+ final_desc = &b->dma_desc[1 + b->offset/MAX_DMA_SIZE]; -+ b->offset &= (MAX_DMA_SIZE-1); -+ dcmd_save = final_desc->dcmd; -+ final_desc->dcmd = b->offset | s->dcmd | DCMD_ENDIRQEN; -+ final_desc->ddadr |= DDADR_STOP; -+ b->offset = 0; -+ b->dma_desc->ddadr &= ~DDADR_STOP; -+ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) { -+ DDADR(s->dma_ch) = b->dma_desc->ddadr; -+ DCSR(s->dma_ch) = DCSR_RUN; -+ } -+ } -+ -+ /* Wait for DMA to complete. */ -+ set_current_state(TASK_INTERRUPTIBLE); -+#if 0 -+ /* -+ * The STOPSTATE IRQ never seem to occur if DCSR_STOPIRQEN is set -+ * along wotj DCSR_RUN. Silicon bug? -+ */ -+ add_wait_queue(&s->stop_wq, &wait); -+ DCSR(s->dma_ch) |= DCSR_STOPIRQEN; -+ schedule(); -+#else -+ add_wait_queue(&s->frag_wq, &wait); -+ while ((DCSR(s->dma_ch) & DCSR_RUN) && !signal_pending(current)) { -+ schedule(); -+ set_current_state(TASK_INTERRUPTIBLE); -+ } -+#endif -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&s->frag_wq, &wait); -+ -+ /* Restore the descriptor chain. */ -+ if (final_desc) { -+ final_desc->dcmd = dcmd_save; -+ final_desc->ddadr &= ~DDADR_STOP; -+ b->dma_desc->ddadr |= DDADR_STOP; -+ } -+ return 0; -+} -+ -+ -+static unsigned int audio_poll(struct file *file, -+ struct poll_table_struct *wait) -+{ -+ audio_state_t *state = file->private_data; -+ audio_stream_t *is = state->input_stream; -+ audio_stream_t *os = state->output_stream; -+ unsigned int mask = 0; -+ -+ if (file->f_mode & FMODE_READ) { -+ /* Start audio input if not already active */ -+ if (!is->buffers && audio_setup_buf(is)) -+ return -ENOMEM; -+ if (DCSR(is->dma_ch) & DCSR_STOPSTATE) { -+ DDADR(is->dma_ch) = -+ is->buffers[is->dma_frag].dma_desc->ddadr; -+ DCSR(is->dma_ch) = DCSR_RUN; -+ } -+ poll_wait(file, &is->frag_wq, wait); -+ } -+ -+ if (file->f_mode & FMODE_WRITE) { -+ if (!os->buffers && audio_setup_buf(os)) -+ return -ENOMEM; -+ poll_wait(file, &os->frag_wq, wait); -+ } -+ -+ if (file->f_mode & FMODE_READ) -+ if (( is->mapped && is->bytecount > 0) || -+ (!is->mapped && atomic_read(&is->sem.count) > 0)) -+ mask |= POLLIN | POLLRDNORM; -+ -+ if (file->f_mode & FMODE_WRITE) -+ if (( os->mapped && os->bytecount > 0) || -+ (!os->mapped && atomic_read(&os->sem.count) > 0)) -+ mask |= POLLOUT | POLLWRNORM; -+ -+ return mask; -+} -+ -+ -+static int audio_ioctl( struct inode *inode, struct file *file, -+ uint cmd, ulong arg) -+{ -+ audio_state_t *state = file->private_data; -+ audio_stream_t *os = state->output_stream; -+ audio_stream_t *is = state->input_stream; -+ long val; -+ -+ switch (cmd) { -+ case OSS_GETVERSION: -+ return put_user(SOUND_VERSION, (int *)arg); -+ -+ case SNDCTL_DSP_GETBLKSIZE: -+ if (file->f_mode & FMODE_WRITE) -+ return put_user(os->fragsize, (int *)arg); -+ else -+ return put_user(is->fragsize, (int *)arg); -+ -+ case SNDCTL_DSP_GETCAPS: -+ val = DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP; -+ if (is && os) -+ val |= DSP_CAP_DUPLEX; -+ return put_user(val, (int *)arg); -+ -+ case SNDCTL_DSP_SETFRAGMENT: -+ if (get_user(val, (long *) arg)) -+ return -EFAULT; -+ if (file->f_mode & FMODE_READ) { -+ int ret = audio_set_fragments(is, val); -+ if (ret < 0) -+ return ret; -+ ret = put_user(ret, (int *)arg); -+ if (ret) -+ return ret; -+ } -+ if (file->f_mode & FMODE_WRITE) { -+ int ret = audio_set_fragments(os, val); -+ if (ret < 0) -+ return ret; -+ ret = put_user(ret, (int *)arg); -+ if (ret) -+ return ret; -+ } -+ return 0; -+ -+ case SNDCTL_DSP_SYNC: -+ return audio_sync(file); -+ -+ case SNDCTL_DSP_SETDUPLEX: -+ return 0; -+ -+ case SNDCTL_DSP_POST: -+ return 0; -+ -+ case SNDCTL_DSP_GETTRIGGER: -+ val = 0; -+ if (file->f_mode & FMODE_READ && DCSR(is->dma_ch) & DCSR_RUN) -+ val |= PCM_ENABLE_INPUT; -+ if (file->f_mode & FMODE_WRITE && DCSR(os->dma_ch) & DCSR_RUN) -+ val |= PCM_ENABLE_OUTPUT; -+ return put_user(val, (int *)arg); -+ -+ case SNDCTL_DSP_SETTRIGGER: -+ if (get_user(val, (int *)arg)) -+ return -EFAULT; -+ if (file->f_mode & FMODE_READ) { -+ if (val & PCM_ENABLE_INPUT) { -+ if (!is->buffers && audio_setup_buf(is)) -+ return -ENOMEM; -+ if (!(DCSR(is->dma_ch) & DCSR_RUN)) { -+ audio_buf_t *b = &is->buffers[is->dma_frag]; -+ DDADR(is->dma_ch) = b->dma_desc->ddadr; -+ DCSR(is->dma_ch) = DCSR_RUN; -+ } -+ } else { -+ DCSR(is->dma_ch) = 0; -+ } -+ } -+ if (file->f_mode & FMODE_WRITE) { -+ if (val & PCM_ENABLE_OUTPUT) { -+ if (!os->buffers && audio_setup_buf(os)) -+ return -ENOMEM; -+ if (!(DCSR(os->dma_ch) & DCSR_RUN)) { -+ audio_buf_t *b = &os->buffers[os->dma_frag]; -+ DDADR(os->dma_ch) = b->dma_desc->ddadr; -+ DCSR(os->dma_ch) = DCSR_RUN; -+ } -+ } else { -+ DCSR(os->dma_ch) = 0; -+ } -+ } -+ return 0; -+ -+ case SNDCTL_DSP_GETOSPACE: -+ case SNDCTL_DSP_GETISPACE: -+ { -+ audio_buf_info inf = { 0, }; -+ audio_stream_t *s = (cmd == SNDCTL_DSP_GETOSPACE) ? os : is; -+ -+ if ((s == is && !(file->f_mode & FMODE_READ)) || -+ (s == os && !(file->f_mode & FMODE_WRITE))) -+ return -EINVAL; -+ if (!s->buffers && audio_setup_buf(s)) -+ return -ENOMEM; -+ inf.bytes = atomic_read(&s->sem.count) * s->fragsize; -+ inf.bytes -= s->buffers[s->usr_frag].offset; -+ inf.fragments = inf.bytes / s->fragsize; -+ inf.fragsize = s->fragsize; -+ inf.fragstotal = s->nbfrags; -+ return copy_to_user((void *)arg, &inf, sizeof(inf)); -+ } -+ -+ case SNDCTL_DSP_GETOPTR: -+ case SNDCTL_DSP_GETIPTR: -+ { -+ count_info inf = { 0, }; -+ audio_stream_t *s = (cmd == SNDCTL_DSP_GETOPTR) ? os : is; -+ dma_addr_t ptr; -+ int bytecount, offset; -+ unsigned long flags; -+ -+ if ((s == is && !(file->f_mode & FMODE_READ)) || -+ (s == os && !(file->f_mode & FMODE_WRITE))) -+ return -EINVAL; -+ local_irq_save(flags); -+ if (DCSR(s->dma_ch) & DCSR_RUN) { -+ audio_buf_t *b; -+ ptr = (s->output) ? DSADR(s->dma_ch) : DTADR(s->dma_ch); -+ b = &s->buffers[s->dma_frag]; -+ offset = ptr - b->dma_desc->dsadr; -+ if (offset >= s->fragsize) -+ offset = s->fragsize - 4; -+ } else { -+ offset = 0; -+ } -+ inf.ptr = s->dma_frag * s->fragsize + offset; -+ bytecount = s->bytecount + offset; -+ s->bytecount = -offset; -+ inf.blocks = s->fragcount; -+ s->fragcount = 0; -+ local_irq_restore(flags); -+ if (bytecount < 0) -+ bytecount = 0; -+ inf.bytes = bytecount; -+ return copy_to_user((void *)arg, &inf, sizeof(inf)); -+ } -+ -+ case SNDCTL_DSP_NONBLOCK: -+ file->f_flags |= O_NONBLOCK; -+ return 0; -+ -+ case SNDCTL_DSP_RESET: -+ if (file->f_mode & FMODE_WRITE) -+ audio_clear_buf(os); -+ if (file->f_mode & FMODE_READ) -+ audio_clear_buf(is); -+ return 0; -+ -+ default: -+ return state->client_ioctl ? -+ state->client_ioctl(inode, file, cmd, arg) : -EINVAL; -+ } -+ -+ return 0; -+} -+ -+ -+static int audio_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ audio_state_t *state = file->private_data; -+ audio_stream_t *s; -+ unsigned long size, vma_addr; -+ int i, ret; -+ -+ if (vma->vm_pgoff != 0) -+ return -EINVAL; -+ -+ if (vma->vm_flags & VM_WRITE) { -+ if (!state->wr_ref) -+ return -EINVAL;; -+ s = state->output_stream; -+ } else if (vma->vm_flags & VM_READ) { -+ if (!state->rd_ref) -+ return -EINVAL; -+ s = state->input_stream; -+ } else return -EINVAL; -+ -+ if (s->mapped) -+ return -EINVAL; -+ size = vma->vm_end - vma->vm_start; -+ if (size != s->fragsize * s->nbfrags) -+ return -EINVAL; -+ if (!s->buffers && audio_setup_buf(s)) -+ return -ENOMEM; -+ vma_addr = vma->vm_start; -+ for (i = 0; i < s->nbfrags; i++) { -+ audio_buf_t *buf = &s->buffers[i]; -+ if (!buf->master) -+ continue; -+ ret = remap_page_range(vma, vma->vm_start, buf->dma_desc->dsadr, -+ buf->master, vma->vm_page_prot); -+ if (ret) -+ return ret; -+ vma_addr += buf->master; -+ } -+ for (i = 0; i < s->nbfrags; i++) -+ s->buffers[i].dma_desc->ddadr &= ~DDADR_STOP; -+ s->mapped = 1; -+ return 0; -+} -+ -+ -+static int audio_release(struct inode *inode, struct file *file) -+{ -+ audio_state_t *state = file->private_data; -+ -+ down(&state->sem); -+ -+ if (file->f_mode & FMODE_READ) { -+ audio_clear_buf(state->input_stream); -+ *state->input_stream->drcmr = 0; -+ pxa_free_dma(state->input_stream->dma_ch); -+ state->rd_ref = 0; -+ } -+ -+ if (file->f_mode & FMODE_WRITE) { -+ audio_sync(file); -+ audio_clear_buf(state->output_stream); -+ *state->output_stream->drcmr = 0; -+ pxa_free_dma(state->output_stream->dma_ch); -+ state->wr_ref = 0; -+ } -+ -+ up(&state->sem); -+ return 0; -+} -+ -+ -+int pxa_audio_attach(struct inode *inode, struct file *file, -+ audio_state_t *state) -+{ -+ audio_stream_t *is = state->input_stream; -+ audio_stream_t *os = state->output_stream; -+ int err; -+ -+ down(&state->sem); -+ -+ /* access control */ -+ err = -ENODEV; -+ if ((file->f_mode & FMODE_WRITE) && !os) -+ goto out; -+ if ((file->f_mode & FMODE_READ) && !is) -+ goto out; -+ err = -EBUSY; -+ if ((file->f_mode & FMODE_WRITE) && state->wr_ref) -+ goto out; -+ if ((file->f_mode & FMODE_READ) && state->rd_ref) -+ goto out; -+ -+ /* request DMA channels */ -+ if (file->f_mode & FMODE_WRITE) { -+ err = pxa_request_dma(os->name, DMA_PRIO_LOW, -+ audio_dma_irq, os); -+ if (err < 0) -+ goto out; -+ os->dma_ch = err; -+ } -+ if (file->f_mode & FMODE_READ) { -+ err = pxa_request_dma(is->name, DMA_PRIO_LOW, -+ audio_dma_irq, is); -+ if (err < 0) { -+ if (file->f_mode & FMODE_WRITE) { -+ *os->drcmr = 0; -+ pxa_free_dma(os->dma_ch); -+ } -+ goto out; -+ } -+ is->dma_ch = err; -+ } -+ -+ file->private_data = state; -+ file->f_op->release = audio_release; -+ file->f_op->write = audio_write; -+ file->f_op->read = audio_read; -+ file->f_op->mmap = audio_mmap; -+ file->f_op->poll = audio_poll; -+ file->f_op->ioctl = audio_ioctl; -+ file->f_op->llseek = no_llseek; -+ -+ if ((file->f_mode & FMODE_WRITE)) { -+ state->wr_ref = 1; -+ os->fragsize = AUDIO_FRAGSIZE_DEFAULT; -+ os->nbfrags = AUDIO_NBFRAGS_DEFAULT; -+ os->output = 1; -+ os->mapped = 0; -+ init_waitqueue_head(&os->frag_wq); -+ init_waitqueue_head(&os->stop_wq); -+ *os->drcmr = os->dma_ch | DRCMR_MAPVLD; -+ } -+ if (file->f_mode & FMODE_READ) { -+ state->rd_ref = 1; -+ is->fragsize = AUDIO_FRAGSIZE_DEFAULT; -+ is->nbfrags = AUDIO_NBFRAGS_DEFAULT; -+ is->output = 0; -+ is->mapped = 0; -+ init_waitqueue_head(&is->frag_wq); -+ init_waitqueue_head(&is->stop_wq); -+ *is->drcmr = is->dma_ch | DRCMR_MAPVLD; -+ } -+ -+ err = 0; -+ -+out: -+ up(&state->sem); -+ return err; -+} -+ -+EXPORT_SYMBOL(pxa_audio_attach); -+EXPORT_SYMBOL(pxa_audio_clear_buf); -+ -+MODULE_AUTHOR("Nicolas Pitre, MontaVista Software Inc."); -+MODULE_DESCRIPTION("audio interface for the Cotula chip"); -+MODULE_LICENSE("GPL"); -Index: linux-2.6.15gum/sound/oss/pxa-audio.h -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/sound/oss/pxa-audio.h -@@ -0,0 +1,54 @@ -+/* -+ * linux/drivers/sound/pxa-audio.h -- audio interface for the Cotula chip -+ * -+ * Author: Nicolas Pitre -+ * Created: Aug 15, 2001 -+ * Copyright: MontaVista Software Inc. -+ * -+ * 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. -+ */ -+ -+typedef struct { -+ int offset; /* current buffer position */ -+ char *data; /* actual buffer */ -+ pxa_dma_desc *dma_desc; /* pointer to the starting desc */ -+ int master; /* owner for buffer allocation, contain size whn true */ -+} audio_buf_t; -+ -+typedef struct { -+ char *name; /* stream identifier */ -+ audio_buf_t *buffers; /* pointer to audio buffer array */ -+ u_int usr_frag; /* user fragment index */ -+ u_int dma_frag; /* DMA fragment index */ -+ u_int fragsize; /* fragment size */ -+ u_int nbfrags; /* number of fragments */ -+ u_int dma_ch; /* DMA channel number */ -+ dma_addr_t dma_desc_phys; /* phys addr of descriptor ring */ -+ u_int descs_per_frag; /* nbr descriptors per fragment */ -+ int bytecount; /* nbr of processed bytes */ -+ int fragcount; /* nbr of fragment transitions */ -+ struct semaphore sem; /* account for fragment usage */ -+ wait_queue_head_t frag_wq; /* for poll(), etc. */ -+ wait_queue_head_t stop_wq; /* for users of DCSR_STOPIRQEN */ -+ u_long dcmd; /* DMA descriptor dcmd field */ -+ volatile u32 *drcmr; /* the DMA request channel to use */ -+ u_long dev_addr; /* device physical address for DMA */ -+ int mapped:1; /* mmap()'ed buffers */ -+ int output:1; /* 0 for input, 1 for output */ -+} audio_stream_t; -+ -+typedef struct { -+ audio_stream_t *output_stream; -+ audio_stream_t *input_stream; -+ int dev_dsp; /* audio device handle */ -+ int rd_ref:1; /* open reference for recording */ -+ int wr_ref:1; /* open reference for playback */ -+ int (*client_ioctl)(struct inode *, struct file *, uint, ulong); -+ struct semaphore sem; /* prevent races in attach/release */ -+} audio_state_t; -+ -+extern int pxa_audio_attach(struct inode *inode, struct file *file, -+ audio_state_t *state); -+extern void pxa_audio_clear_buf(audio_stream_t *s); diff --git a/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch b/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch deleted file mode 100644 index e989c72b70..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch +++ /dev/null @@ -1,117 +0,0 @@ -Status: WORKS -PXA CPU enhancements - -from patch 1667: -- 64K PTEs -from hh.org-cvs: -- support in pxa_gpio_mode for active low - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - -Index: linux-2.6.15gum/arch/arm/mm/proc-xscale.S -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mm/proc-xscale.S -+++ linux-2.6.15gum/arch/arm/mm/proc-xscale.S -@@ -444,11 +444,62 @@ ENTRY(cpu_xscale_set_pte) - movne r2, #0 @ no -> fault - - str r2, [r0] @ hardware version -+ -+ @ We try to map 64K page entries when possible. -+ @ We do that for kernel space only since the usage pattern from -+ @ the setting of VM area is quite simple. User space is not worth -+ @ the implied complexity because of ever randomly changing PTEs -+ @ (page aging, swapout, etc) requiring constant coherency checks. -+ @ Since PTEs are usually set in increasing order, we test the -+ @ possibility for a large page only when given the last PTE of a -+ @ 64K boundary. -+ tsteq r1, #L_PTE_USER -+ andeq r1, r0, #(15 << 2) -+ teqeq r1, #(15 << 2) -+ beq 1f -+ - mov ip, #0 - mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line - mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer - mov pc, lr - -+ @ See if we have 16 identical PTEs but with consecutive base addresses -+1: bic r3, r2, #0x0000f000 -+ mov r1, #0x0000f000 -+2: eor r2, r2, r3 -+ teq r2, r1 -+ bne 4f -+ subs r1, r1, #0x00001000 -+ ldr r2, [r0, #-4]! -+ bne 2b -+ eors r2, r2, r3 -+ bne 4f -+ -+ @ Now create our LARGE PTE from the current EXT one. -+ bic r3, r3, #PTE_TYPE_MASK -+ orr r3, r3, #PTE_TYPE_LARGE -+ and r2, r3, #0x30 @ EXT_AP --> LARGE_AP0 -+ orr r2, r2, r2, lsl #2 @ add LARGE_AP1 -+ orr r2, r2, r2, lsl #4 @ add LARGE_AP3 + LARGE_AP2 -+ and r1, r3, #0x3c0 @ EXT_TEX -+ bic r3, r3, #0x3c0 -+ orr r2, r2, r1, lsl #(12 - 6) @ --> LARGE_TEX -+ orr r2, r2, r3 @ add remaining bits -+ -+ @ then put it in the pagetable -+ mov r3, r2 -+3: strd r2, [r0], #8 -+ tst r0, #(15 << 2) -+ bne 3b -+ -+ @ Then sync the 2 corresponding cache lines -+ sub r0, r0, #(16 << 2) -+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line -+4: orr r0, r0, #(15 << 2) -+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line -+ mov ip, #0 -+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer -+ mov pc, lr - - .ltorg - -Index: linux-2.6.15gum/include/asm-arm/arch-pxa/pxa-regs.h -=================================================================== ---- linux-2.6.15gum.orig/include/asm-arm/arch-pxa/pxa-regs.h -+++ linux-2.6.15gum/include/asm-arm/arch-pxa/pxa-regs.h -@@ -1348,6 +1348,7 @@ - #define GPIO_ALT_FN_2_OUT 0x280 - #define GPIO_ALT_FN_3_IN 0x300 - #define GPIO_ALT_FN_3_OUT 0x380 -+#define GPIO_ACTIVE_LOW 0x1000 - #define GPIO_MD_MASK_NR 0x07f - #define GPIO_MD_MASK_DIR 0x080 - #define GPIO_MD_MASK_FN 0x300 -@@ -1598,6 +1599,25 @@ - #define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */ - #define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */ - -+#define PWER_GPIO(Nb) (1 << Nb) /* GPIO [0..15] wake-up enable */ -+#define PWER_GPIO0 PWER_GPIO (0) /* GPIO [0] wake-up enable */ -+#define PWER_GPIO1 PWER_GPIO (1) /* GPIO [1] wake-up enable */ -+#define PWER_GPIO2 PWER_GPIO (2) /* GPIO [2] wake-up enable */ -+#define PWER_GPIO3 PWER_GPIO (3) /* GPIO [3] wake-up enable */ -+#define PWER_GPIO4 PWER_GPIO (4) /* GPIO [4] wake-up enable */ -+#define PWER_GPIO5 PWER_GPIO (5) /* GPIO [5] wake-up enable */ -+#define PWER_GPIO6 PWER_GPIO (6) /* GPIO [6] wake-up enable */ -+#define PWER_GPIO7 PWER_GPIO (7) /* GPIO [7] wake-up enable */ -+#define PWER_GPIO8 PWER_GPIO (8) /* GPIO [8] wake-up enable */ -+#define PWER_GPIO9 PWER_GPIO (9) /* GPIO [9] wake-up enable */ -+#define PWER_GPIO10 PWER_GPIO (10) /* GPIO [10] wake-up enable */ -+#define PWER_GPIO11 PWER_GPIO (11) /* GPIO [11] wake-up enable */ -+#define PWER_GPIO12 PWER_GPIO (12) /* GPIO [12] wake-up enable */ -+#define PWER_GPIO13 PWER_GPIO (13) /* GPIO [13] wake-up enable */ -+#define PWER_GPIO14 PWER_GPIO (14) /* GPIO [14] wake-up enable */ -+#define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */ -+#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */ -+ - - /* - * SSP Serial Port Registers diff --git a/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch b/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch deleted file mode 100644 index be522995f6..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch +++ /dev/null @@ -1,403 +0,0 @@ -Status: WORKS -PXA CPU frequency change support -added mods from Stefan Eletzhofer and Lothar Weissmann - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - -Index: linux-2.6.15gum/arch/arm/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/Kconfig -+++ linux-2.6.15gum/arch/arm/Kconfig -@@ -549,7 +549,7 @@ config XIP_PHYS_ADDR - - endmenu - --if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1) -+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1 || ARCH_PXA) - - menu "CPU Frequency scaling" - -@@ -578,6 +578,12 @@ config CPU_FREQ_INTEGRATOR - - endmenu - -+config CPU_FREQ_PXA -+ bool -+ depends on CPU_FREQ && ARCH_PXA -+ default y -+ select CPU_FREQ_DEFAULT_GOV_USERSPACE -+ - endif - - menu "Floating point emulation" -Index: linux-2.6.15gum/arch/arm/mach-pxa/Makefile -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-pxa/Makefile -+++ linux-2.6.15gum/arch/arm/mach-pxa/Makefile -@@ -29,6 +29,7 @@ obj-$(CONFIG_LEDS) += $(led-y) - # Misc features - obj-$(CONFIG_PM) += pm.o sleep.o - obj-$(CONFIG_PXA_SSP) += ssp.o -+obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o - - ifeq ($(CONFIG_PXA27x),y) - obj-$(CONFIG_PM) += standby.o -Index: linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c -@@ -0,0 +1,321 @@ -+/* -+ * linux/arch/arm/mach-pxa/cpu-pxa.c -+ * -+ * Copyright (C) 2002,2003 Intrinsyc Software -+ * -+ * 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 -+ * -+ * History: -+ * 31-Jul-2002 : Initial version [FB] -+ * 29-Jan-2003 : added PXA255 support [FB] -+ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) -+ * -+ * Note: -+ * This driver may change the memory bus clock rate, but will not do any -+ * platform specific access timing changes... for example if you have flash -+ * memory connected to CS0, you will need to register a platform specific -+ * notifier which will adjust the memory access strobes to maintain a -+ * minimum strobe width. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define DEBUG 0 -+ -+#ifdef DEBUG -+ static unsigned int freq_debug = DEBUG; -+ MODULE_PARM(freq_debug, "i"); -+ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); -+#else -+ #define freq_debug 0 -+#endif -+ -+typedef struct -+{ -+ unsigned int khz; -+ unsigned int membus; -+ unsigned int cccr; -+ unsigned int div2; -+} pxa_freqs_t; -+ -+/* Define the refresh period in mSec for the SDRAM and the number of rows */ -+#define SDRAM_TREF 64 /* standard 64ms SDRAM */ -+#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ -+#define MDREFR_DRI(x) ((x*SDRAM_TREF)/(SDRAM_ROWS*32)) -+ -+#define CCLKCFG_TURBO 0x1 -+#define CCLKCFG_FCS 0x2 -+#define PXA25x_MIN_FREQ 99500 -+#define PXA25x_MAX_FREQ 398100 -+#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) -+#define MDREFR_DRI_MASK 0xFFF -+ -+ -+/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */ -+static pxa_freqs_t pxa255_run_freqs[] = -+{ -+ /* CPU MEMBUS CCCR DIV2*/ -+ { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */ -+ {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */ -+ {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */ -+ {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */ -+ {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */ -+ {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */ -+ {0,} -+}; -+#define NUM_RUN_FREQS (sizeof(pxa255_run_freqs)/sizeof(pxa_freqs_t)) -+ -+static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1]; -+ -+/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ -+static pxa_freqs_t pxa255_turbo_freqs[] = -+{ -+ /* CPU MEMBUS CCCR DIV2*/ -+ { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */ -+ {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */ -+ {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */ -+ {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */ -+ {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */ -+ {0,} -+}; -+#define NUM_TURBO_FREQS (sizeof(pxa255_turbo_freqs)/sizeof(pxa_freqs_t)) -+ -+static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1]; -+ -+extern unsigned get_clk_frequency_khz(int info); -+ -+/* find a valid frequency point */ -+static int pxa_verify_policy(struct cpufreq_policy *policy) -+{ -+ int ret; -+ struct cpufreq_frequency_table *pxa_freqs_table; -+ -+ if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) { -+ pxa_freqs_table = pxa255_run_freq_table; -+ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { -+ pxa_freqs_table = pxa255_turbo_freq_table; -+ } else { -+ printk("CPU PXA: Unknown policy found. " -+ "Using CPUFREQ_POLICY_PERFORMANCE\n"); -+ pxa_freqs_table = pxa255_run_freq_table; -+ } -+ ret=cpufreq_frequency_table_verify(policy, pxa_freqs_table); -+ -+ if(freq_debug) { -+ printk("Verified CPU policy: %dKhz min to %dKhz max\n", -+ policy->min, policy->max); -+ } -+ -+ return ret; -+} -+ -+static int pxa_set_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, -+ unsigned int relation) -+{ -+ int idx; -+ unsigned long cpus_allowed; -+ int cpu = policy->cpu; -+ struct cpufreq_freqs freqs; -+ pxa_freqs_t *pxa_freq_settings; -+ struct cpufreq_frequency_table *pxa_freqs_table; -+ unsigned long flags; -+ unsigned int unused; -+ unsigned int preset_mdrefr, postset_mdrefr; -+ -+ /* -+ * Save this threads cpus_allowed mask. -+ */ -+ cpus_allowed = current->cpus_allowed; -+ -+ /* -+ * Bind to the specified CPU. When this call returns, -+ * we should be running on the right CPU. -+ */ -+ set_cpus_allowed(current, 1 << cpu); -+ BUG_ON(cpu != smp_processor_id()); -+ -+ /* Get the current policy */ -+ if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) { -+ pxa_freq_settings = pxa255_run_freqs; -+ pxa_freqs_table = pxa255_run_freq_table; -+ }else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { -+ pxa_freq_settings = pxa255_turbo_freqs; -+ pxa_freqs_table = pxa255_turbo_freq_table; -+ }else { -+ printk("CPU PXA: Unknown policy found. " -+ "Using CPUFREQ_POLICY_PERFORMANCE\n"); -+ pxa_freq_settings = pxa255_run_freqs; -+ pxa_freqs_table = pxa255_run_freq_table; -+ } -+ -+ /* Lookup the next frequency */ -+ if (cpufreq_frequency_table_target(policy, pxa_freqs_table, -+ target_freq, relation, &idx)) { -+ return -EINVAL; -+ } -+ -+ freqs.old = policy->cur; -+ freqs.new = pxa_freq_settings[idx].khz; -+ freqs.cpu = policy->cpu; -+ if(freq_debug) { -+ printk(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", -+ freqs.new/1000, (pxa_freq_settings[idx].div2) ? -+ (pxa_freq_settings[idx].membus/2000) : -+ (pxa_freq_settings[idx].membus/1000)); -+ } -+ -+ void *ramstart = phys_to_virt(0xa0000000); -+ -+ /* -+ * Tell everyone what we're about to do... -+ * you should add a notify client with any platform specific -+ * Vcc changing capability -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ -+ /* Calculate the next MDREFR. If we're slowing down the SDRAM clock -+ * we need to preset the smaller DRI before the change. If we're speeding -+ * up we need to set the larger DRI value after the change. -+ */ -+ preset_mdrefr = postset_mdrefr = MDREFR; -+ if((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) { -+ preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) | -+ MDREFR_DRI(pxa_freq_settings[idx].membus); -+ } -+ postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) | -+ MDREFR_DRI(pxa_freq_settings[idx].membus); -+ -+ /* If we're dividing the memory clock by two for the SDRAM clock, this -+ * must be set prior to the change. Clearing the divide must be done -+ * after the change. -+ */ -+ if(pxa_freq_settings[idx].div2) { -+ preset_mdrefr |= MDREFR_DB2_MASK; -+ postset_mdrefr |= MDREFR_DB2_MASK; -+ } else { -+ postset_mdrefr &= ~MDREFR_DB2_MASK; -+ } -+ -+ local_irq_save(flags); -+ -+ /* Set new the CCCR */ -+ CCCR = pxa_freq_settings[idx].cccr; -+ -+ __asm__ __volatile__(" \ -+ ldr r4, [%1] ; /* load MDREFR */ \ -+ b 2f ; \ -+ .align 5 ; \ -+1: \ -+ str %4, [%1] ; /* preset the MDREFR */ \ -+ mcr p14, 0, %2, c6, c0, 0 ; /* set CCLKCFG[FCS] */ \ -+ str %5, [%1] ; /* postset the MDREFR */ \ -+ \ -+ b 3f ; \ -+2: b 1b ; \ -+3: nop ; \ -+ " -+ : "=&r" (unused) -+ : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart), \ -+ "r" (preset_mdrefr), "r" (postset_mdrefr) -+ : "r4", "r5"); -+ local_irq_restore(flags); -+ -+ /* -+ * Restore the CPUs allowed mask. -+ */ -+ set_cpus_allowed(current, cpus_allowed); -+ -+ /* -+ * Tell everyone what we've just done... -+ * you should add a notify client with any platform specific -+ * SDRAM refresh timer adjustments -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+ -+ return 0; -+} -+ -+static int pxa_cpufreq_init(struct cpufreq_policy *policy) -+{ -+ unsigned long cpus_allowed; -+ unsigned int cpu = policy->cpu; -+ int i; -+ -+ cpus_allowed = current->cpus_allowed; -+ -+ set_cpus_allowed(current, 1 << cpu); -+ BUG_ON(cpu != smp_processor_id()); -+ -+ /* set default policy and cpuinfo */ -+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; -+ policy->policy = CPUFREQ_POLICY_PERFORMANCE; -+ policy->cpuinfo.max_freq = PXA25x_MAX_FREQ; -+ policy->cpuinfo.min_freq = PXA25x_MIN_FREQ; -+ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ -+ policy->cur = get_clk_frequency_khz(0); /* current freq */ -+ policy->min = policy->max = policy->cur; -+ -+ /* Generate the run cpufreq_frequency_table struct */ -+ for(i=0;i -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "generic.h" -+ -+static int gumstix_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data) -+{ -+ // Set up MMC controller -+ pxa_gpio_mode(GPIO6_MMCCLK_MD); -+ pxa_gpio_mode(GPIO53_MMCCLK_MD); -+ pxa_gpio_mode(GPIO8_MMCCS0_MD); -+ -+ return 0; -+} -+ -+static struct pxamci_platform_data gumstix_mci_platform_data = { -+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, -+ .init = &gumstix_mci_init, -+}; -+ -+static int gumstix_udc_is_connected(void) -+{ -+ return !! (GPLR(GPIO_GUMSTIX_USB_GPIOn) & GPIO_bit(GPIO_GUMSTIX_USB_GPIOn)); -+} -+ -+static void gumstix_udc_command(int connect_command) -+{ -+ if (connect_command == PXA2XX_UDC_CMD_CONNECT) { -+ pxa_gpio_mode(GPIO_GUMSTIX_USB_GPIOx_CON_MD); -+ GPSR(GPIO_GUMSTIX_USB_GPIOx) = GPIO_bit(GPIO_GUMSTIX_USB_GPIOx); -+ } -+ if (connect_command == PXA2XX_UDC_CMD_DISCONNECT) { -+ GPCR(GPIO_GUMSTIX_USB_GPIOx) = GPIO_bit(GPIO_GUMSTIX_USB_GPIOx); -+ pxa_gpio_mode(GPIO_GUMSTIX_USB_GPIOx_DIS_MD); -+ } -+} -+ -+static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = { -+ .udc_is_connected = gumstix_udc_is_connected, -+ .udc_command = gumstix_udc_command, -+}; -+ -+static struct platform_device gum_audio_device = { -+ .name = "pxa2xx-ac97", -+ .id = -1, -+}; -+ -+static struct platform_device *devices[] __initdata = { -+ &gum_audio_device, -+}; -+ -+static void __init gumstix_init(void) -+{ -+ pxa_set_mci_info(&gumstix_mci_platform_data); -+ pxa_set_udc_info(&gumstix_udc_info); -+ (void) platform_add_devices(devices, ARRAY_SIZE(devices)); -+} -+ -+MACHINE_START(GUMSTIX, "The Gumstix Platform") -+ .phys_ram = 0xa0000000, -+ .phys_io = 0x40000000, -+ .boot_params = 0xa0000100, -+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, -+ .timer = &pxa_timer, -+ .map_io = pxa_map_io, -+ .init_irq = pxa_init_irq, -+ .init_machine = gumstix_init, -+MACHINE_END diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-i2c-include.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-i2c-include.patch deleted file mode 100644 index 5cc3a0bcfa..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bugfix-i2c-include.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: linux-2.6.15gum/drivers/i2c/busses/i2c-pxa.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/i2c/busses/i2c-pxa.c -+++ linux-2.6.15gum/drivers/i2c/busses/i2c-pxa.c -@@ -32,6 +32,7 @@ - #include - #include - -+#include - #include - #include - #include diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-mmc-clock.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-mmc-clock.patch deleted file mode 100644 index 0b93fffaef..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bugfix-mmc-clock.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: linux-2.6.15gum/drivers/mmc/pxamci.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/mmc/pxamci.c -+++ linux-2.6.15gum/drivers/mmc/pxamci.c -@@ -381,8 +381,7 @@ static void pxamci_set_ios(struct mmc_ho - - if (ios->clock) { - unsigned int clk = CLOCKRATE / ios->clock; -- if (CLOCKRATE / clk > ios->clock) -- clk <<= 1; -+ if(clk > (1<<6)) clk = (1<<6); - host->clkrt = fls(clk) - 1; - pxa_set_cken(CKEN12_MMC, 1); - diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-mtd-onenand.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-mtd-onenand.patch deleted file mode 100644 index 1b1662e963..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bugfix-mtd-onenand.patch +++ /dev/null @@ -1,22 +0,0 @@ -Index: linux-2.6.15gum/drivers/mtd/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/drivers/mtd/Kconfig -+++ linux-2.6.15gum/drivers/mtd/Kconfig -@@ -271,7 +271,5 @@ source "drivers/mtd/devices/Kconfig" - - source "drivers/mtd/nand/Kconfig" - --source "drivers/mtd/onenand/Kconfig" -- - endmenu - -Index: linux-2.6.15gum/drivers/mtd/Makefile -=================================================================== ---- linux-2.6.15gum.orig/drivers/mtd/Makefile -+++ linux-2.6.15gum/drivers/mtd/Makefile -@@ -25,4 +25,4 @@ obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_ - nftl-objs := nftlcore.o nftlmount.o - inftl-objs := inftlcore.o inftlmount.o - --obj-y += chips/ maps/ devices/ nand/ onenand/ -+obj-y += chips/ maps/ devices/ nand/ diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-audio.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-audio.patch deleted file mode 100644 index a8d04f0e20..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-audio.patch +++ /dev/null @@ -1,25 +0,0 @@ -Index: linux-2.6.15gum/sound/oss/pxa-audio.c -=================================================================== ---- linux-2.6.15gum.orig/sound/oss/pxa-audio.c -+++ linux-2.6.15gum/sound/oss/pxa-audio.c -@@ -731,7 +731,7 @@ static int audio_mmap(struct file *file, - audio_buf_t *buf = &s->buffers[i]; - if (!buf->master) - continue; -- ret = remap_page_range(vma, vma->vm_start, buf->dma_desc->dsadr, -+ ret = io_remap_page_range(vma, vma_addr, buf->dma_desc->dsadr, - buf->master, vma->vm_page_prot); - if (ret) - return ret; -Index: linux-2.6.15gum/sound/oss/pxa-audio.h -=================================================================== ---- linux-2.6.15gum.orig/sound/oss/pxa-audio.h -+++ linux-2.6.15gum/sound/oss/pxa-audio.h -@@ -52,3 +52,7 @@ typedef struct { - extern int pxa_audio_attach(struct inode *inode, struct file *file, - audio_state_t *state); - extern void pxa_audio_clear_buf(audio_stream_t *s); -+ -+#define DCMD_TXPCDR (DCMD_INCSRCADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4) -+#define DCMD_RXMCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4) -+#define DCMD_RXPCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4) diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch deleted file mode 100644 index 6d2f2b3267..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch +++ /dev/null @@ -1,64 +0,0 @@ -Index: linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-pxa/cpu-pxa.c -+++ linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c -@@ -60,7 +60,7 @@ typedef struct - - /* Define the refresh period in mSec for the SDRAM and the number of rows */ - #define SDRAM_TREF 64 /* standard 64ms SDRAM */ --#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ -+#define SDRAM_ROWS 8192 /* 64MB=8192 32MB=4096 */ - #define MDREFR_DRI(x) ((x*SDRAM_TREF)/(SDRAM_ROWS*32)) - - #define CCLKCFG_TURBO 0x1 -@@ -136,7 +136,7 @@ static int pxa_set_target(struct cpufreq - unsigned int relation) - { - int idx; -- unsigned long cpus_allowed; -+ cpumask_t cpus_allowed; - int cpu = policy->cpu; - struct cpufreq_freqs freqs; - pxa_freqs_t *pxa_freq_settings; -@@ -144,6 +144,7 @@ static int pxa_set_target(struct cpufreq - unsigned long flags; - unsigned int unused; - unsigned int preset_mdrefr, postset_mdrefr; -+ void *ramstart; - - /* - * Save this threads cpus_allowed mask. -@@ -154,7 +155,7 @@ static int pxa_set_target(struct cpufreq - * Bind to the specified CPU. When this call returns, - * we should be running on the right CPU. - */ -- set_cpus_allowed(current, 1 << cpu); -+ set_cpus_allowed(current, cpumask_of_cpu(cpu)); - BUG_ON(cpu != smp_processor_id()); - - /* Get the current policy */ -@@ -187,7 +188,7 @@ static int pxa_set_target(struct cpufreq - (pxa_freq_settings[idx].membus/1000)); - } - -- void *ramstart = phys_to_virt(0xa0000000); -+ ramstart = phys_to_virt(0xa0000000); - - /* - * Tell everyone what we're about to do... -@@ -260,13 +261,13 @@ static int pxa_set_target(struct cpufreq - - static int pxa_cpufreq_init(struct cpufreq_policy *policy) - { -- unsigned long cpus_allowed; -+ cpumask_t cpus_allowed; - unsigned int cpu = policy->cpu; - int i; - - cpus_allowed = current->cpus_allowed; - -- set_cpus_allowed(current, 1 << cpu); -+ set_cpus_allowed(current, cpumask_of_cpu(cpu)); - BUG_ON(cpu != smp_processor_id()); - - /* set default policy and cpuinfo */ diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-serial-mctrl.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-serial-mctrl.patch deleted file mode 100644 index 574ac1ac62..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bugfix-pxa-serial-mctrl.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: linux-2.6.15gum/drivers/serial/pxa.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/serial/pxa.c -+++ linux-2.6.15gum/drivers/serial/pxa.c -@@ -277,7 +277,6 @@ static unsigned int serial_pxa_get_mctrl - unsigned char status; - unsigned int ret; - --return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; - status = serial_in(up, UART_MSR); - - ret = 0; diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-rndis.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-rndis.patch deleted file mode 100644 index d51597f94b..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bugfix-rndis.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: linux-2.6.15gum/drivers/usb/gadget/ether.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/usb/gadget/ether.c -+++ linux-2.6.15gum/drivers/usb/gadget/ether.c -@@ -2328,7 +2328,9 @@ autoconf_fail: - #ifdef DEV_CONFIG_CDC - /* pxa25x only does CDC subset; often used with RNDIS */ - } else if (cdc) { -+#ifdef DEV_CONFIG_CDC - control_intf.bNumEndpoints = 0; -+#endif - /* FIXME remove endpoint from descriptor list */ - #endif - } diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-interrupt.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-interrupt.patch deleted file mode 100644 index df4a46e030..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-interrupt.patch +++ /dev/null @@ -1,25 +0,0 @@ -Index: linux-2.6.15gum/drivers/serial/pxa.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/serial/pxa.c -+++ linux-2.6.15gum/drivers/serial/pxa.c -@@ -246,15 +246,19 @@ serial_pxa_irq(int irq, void *dev_id, st - struct uart_pxa_port *up = (struct uart_pxa_port *)dev_id; - unsigned int iir, lsr; - -+ serial_out(up, UART_MCR, serial_in(up, UART_MCR) & ~UART_MCR_RTS); // Clear RTS - iir = serial_in(up, UART_IIR); - if (iir & UART_IIR_NO_INT) -- return IRQ_NONE; -+ { -+ //printk(KERN_WARNING "serial_pxa_irq: odd -- interrupt triggered, but no interrupt in IIR: %08x\n",iir); -+ } - lsr = serial_in(up, UART_LSR); - if (lsr & UART_LSR_DR) - receive_chars(up, &lsr, regs); - check_modem_status(up); - if (lsr & UART_LSR_THRE) - transmit_chars(up); -+ serial_out(up, UART_MCR, serial_in(up, UART_MCR) | UART_MCR_RTS); // Assert RTS - return IRQ_HANDLED; - } - diff --git a/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-register-status.patch b/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-register-status.patch deleted file mode 100644 index fcef7c27c3..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/bugfix-serial-register-status.patch +++ /dev/null @@ -1,70 +0,0 @@ -Index: linux-2.6.15gum/drivers/serial/pxa.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/serial/pxa.c -+++ linux-2.6.15gum/drivers/serial/pxa.c -@@ -58,6 +58,8 @@ struct uart_pxa_port { - unsigned int lsr_break_flag; - unsigned int cken; - char *name; -+ unsigned int msr; //djf -+ unsigned int lsr; //djf - }; - - static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) -@@ -169,6 +171,7 @@ receive_chars(struct uart_pxa_port *up, - - ignore_char: - *status = serial_in(up, UART_LSR); -+ up->lsr = *status; - } while ((*status & UART_LSR_DR) && (max_count-- > 0)); - tty_flip_buffer_push(tty); - } -@@ -221,7 +224,7 @@ static inline void check_modem_status(st - int status; - - status = serial_in(up, UART_MSR); -- -+ up->msr = status; - if ((status & UART_MSR_ANY_DELTA) == 0) - return; - -@@ -253,6 +256,7 @@ serial_pxa_irq(int irq, void *dev_id, st - //printk(KERN_WARNING "serial_pxa_irq: odd -- interrupt triggered, but no interrupt in IIR: %08x\n",iir); - } - lsr = serial_in(up, UART_LSR); -+ up->lsr = lsr; - if (lsr & UART_LSR_DR) - receive_chars(up, &lsr, regs); - check_modem_status(up); -@@ -269,7 +273,8 @@ static unsigned int serial_pxa_tx_empty( - unsigned int ret; - - spin_lock_irqsave(&up->port.lock, flags); -- ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; -+ //ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; -+ ret = up->lsr * UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); - - return ret; -@@ -281,7 +286,7 @@ static unsigned int serial_pxa_get_mctrl - unsigned char status; - unsigned int ret; - -- status = serial_in(up, UART_MSR); -+ status = up->msr; - - ret = 0; - if (status & UART_MSR_DCD) -@@ -411,10 +416,10 @@ static int serial_pxa_startup(struct uar - /* - * And clear the interrupt registers again for luck. - */ -- (void) serial_in(up, UART_LSR); -+ up->lsr = serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); -- (void) serial_in(up, UART_MSR); -+ up->msr = serial_in(up, UART_MSR); - - return 0; - } diff --git a/recipes/linux/linux-gumstix-2.6.15/compact-flash.patch b/recipes/linux/linux-gumstix-2.6.15/compact-flash.patch deleted file mode 100644 index c3913a23df..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/compact-flash.patch +++ /dev/null @@ -1,171 +0,0 @@ -Index: linux-2.6.15gum/drivers/pcmcia/Makefile -=================================================================== ---- linux-2.6.15gum.orig/drivers/pcmcia/Makefile -+++ linux-2.6.15gum/drivers/pcmcia/Makefile -@@ -68,4 +68,4 @@ - pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o - pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o - pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o -- -+pxa2xx_cs-$(CONFIG_ARCH_GUMSTIX) += pxa2xx_gumstix.o -Index: linux-2.6.15gum/drivers/pcmcia/pxa2xx_gumstix.c ---- /dev/null -+++ linux-2.6.15gum/drivers/pcmcia/pxa2xx_gumstix.c -@@ -0,0 +1,157 @@ -+/* -+ * linux/drivers/pcmcia/pxa2xx_gumstix.c -+ * -+ * Gumstix PCMCIA specific routines. Based on Mainstone -+ * -+ * Copyright 2004, Craig Hughes -+ * -+ * 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 -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "soc_common.h" -+ -+static struct pcmcia_irqs irqs[] = { -+ { 0, GUMSTIX_nPCD1_IRQ, "CF nCD" }, -+ { 0, GUMSTIX_nSTSCHG_IRQ, "CF nSTSCHG" }, -+}; -+ -+static int gumstix_pcmcia_hw_init(struct soc_pcmcia_socket *skt) -+{ -+ pxa_gpio_mode(GPIO8_RESET_MD); -+ GPSR(GPIO8_RESET) = GPIO_bit(GPIO8_RESET); -+ udelay(50); -+ GPCR(GPIO8_RESET) = GPIO_bit(GPIO8_RESET); -+ -+ pxa_gpio_mode(GPIO4_nBVD1_MD); -+ pxa_gpio_mode(GPIO36_nBVD2_MD); -+ pxa_gpio_mode(GPIO11_nPCD1_MD); -+ pxa_gpio_mode(GPIO26_PRDY_nBSY0_MD); -+ -+ /* -+ * Setup default state of GPIO outputs -+ * before we enable them as outputs. -+ */ -+ GPSR(GPIO48_nPOE) = -+ GPIO_bit(GPIO48_nPOE) | -+ GPIO_bit(GPIO49_nPWE) | -+ GPIO_bit(GPIO50_nPIOR) | -+ GPIO_bit(GPIO51_nPIOW) | -+ GPIO_bit(GPIO52_nPCE_1) | -+ GPIO_bit(GPIO53_nPCE_2); -+ -+ pxa_gpio_mode(GPIO48_nPOE_MD); -+ pxa_gpio_mode(GPIO49_nPWE_MD); -+ pxa_gpio_mode(GPIO50_nPIOR_MD); -+ pxa_gpio_mode(GPIO51_nPIOW_MD); -+ pxa_gpio_mode(GPIO52_nPCE_1_MD); -+ pxa_gpio_mode(GPIO53_nPCE_2_MD); -+ pxa_gpio_mode(GPIO54_pSKTSEL_MD); -+ pxa_gpio_mode(GPIO55_nPREG_MD); -+ pxa_gpio_mode(GPIO56_nPWAIT_MD); -+ pxa_gpio_mode(GPIO57_nIOIS16_MD); -+ -+ skt->irq = GUMSTIX_PRDY_nBSY0_IRQ; -+ -+ return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -+} -+ -+static void gumstix_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -+{ -+ soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); -+} -+ -+static unsigned long gum_pcmcia_status; -+ -+static void gumstix_pcmcia_socket_state(struct soc_pcmcia_socket *skt, -+ struct pcmcia_state *state) -+{ -+ state->detect = !(GPLR(GPIO11_nPCD1) & GPIO_bit(GPIO11_nPCD1)); -+ state->ready = !!(GPLR(GPIO26_PRDY_nBSY0) & GPIO_bit(GPIO26_PRDY_nBSY0)); -+ state->bvd1 = !!(GPLR(GPIO4_nBVD1) & GPIO_bit(GPIO4_nBVD1)); -+ state->bvd2 = 1; -+ state->vs_3v = 0; -+ state->vs_Xv = 0; -+ state->wrprot = 0; -+} -+ -+static int gumstix_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, -+ const socket_state_t *state) -+{ -+ return 0; -+} -+ -+static void gumstix_pcmcia_socket_init(struct soc_pcmcia_socket *skt) -+{ -+ soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); -+} -+ -+static void gumstix_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) -+{ -+ soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); -+} -+ -+static struct pcmcia_low_level gumstix_pcmcia_ops = { -+ .owner = THIS_MODULE, -+ .hw_init = gumstix_pcmcia_hw_init, -+ .hw_shutdown = gumstix_pcmcia_hw_shutdown, -+ .socket_state = gumstix_pcmcia_socket_state, -+ .configure_socket = gumstix_pcmcia_configure_socket, -+ .socket_init = gumstix_pcmcia_socket_init, -+ .socket_suspend = gumstix_pcmcia_socket_suspend, -+ .nr = 1, -+}; -+ -+static struct platform_device *gumstix_pcmcia_device; -+ -+static int __init gumstix_pcmcia_init(void) -+{ -+ int ret; -+ -+ gumstix_pcmcia_device = kmalloc(sizeof(*gumstix_pcmcia_device), GFP_KERNEL); -+ if (!gumstix_pcmcia_device) -+ return -ENOMEM; -+ memset(gumstix_pcmcia_device, 0, sizeof(*gumstix_pcmcia_device)); -+ gumstix_pcmcia_device->name = "pxa2xx-pcmcia"; -+ gumstix_pcmcia_device->dev.platform_data = &gumstix_pcmcia_ops; -+ -+ ret = platform_device_register(gumstix_pcmcia_device); -+ if (ret) -+ kfree(gumstix_pcmcia_device); -+ -+ return ret; -+} -+ -+static void __exit gumstix_pcmcia_exit(void) -+{ -+ /* -+ * This call is supposed to free our gumstix_pcmcia_device. -+ * Unfortunately platform_device don't have a free method, and -+ * we can't assume it's free of any reference at this point so we -+ * can't free it either. -+ */ -+ platform_device_unregister(gumstix_pcmcia_device); -+} -+ -+fs_initcall(gumstix_pcmcia_init); -+module_exit(gumstix_pcmcia_exit); -+ -+MODULE_LICENSE("GPL"); diff --git a/recipes/linux/linux-gumstix-2.6.15/cpufreq-better-freqs.patch b/recipes/linux/linux-gumstix-2.6.15/cpufreq-better-freqs.patch deleted file mode 100644 index 875d316f3e..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/cpufreq-better-freqs.patch +++ /dev/null @@ -1,53 +0,0 @@ -Index: linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-pxa/cpu-pxa.c -+++ linux-2.6.15gum/arch/arm/mach-pxa/cpu-pxa.c -@@ -65,8 +65,8 @@ typedef struct - - #define CCLKCFG_TURBO 0x1 - #define CCLKCFG_FCS 0x2 --#define PXA25x_MIN_FREQ 99500 --#define PXA25x_MAX_FREQ 398100 -+#define PXA25x_MIN_FREQ 99533 -+#define PXA25x_MAX_FREQ 530842 - #define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) - #define MDREFR_DRI_MASK 0xFFF - -@@ -75,12 +75,14 @@ typedef struct - static pxa_freqs_t pxa255_run_freqs[] = - { - /* CPU MEMBUS CCCR DIV2*/ -- { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */ -- {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */ -- {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */ -- {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */ -- {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */ -- {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */ -+ { 99533, 99533, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */ -+ {132710, 132710, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */ -+ {199066, 99533, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */ -+ {265421, 132710, 0x143, 0}, /* run=265, turbo=265, PXbus=133, SDRAM=133 */ -+ {331776, 165888, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */ -+ {398131, 99533, 0x161, 0}, /* run=398, turbo=398, PXbus=99, SDRAM=99 */ -+ {398131, 132710, 0x1c3, 0}, /* run=265, turbo=398, PXbus=133, SDRAM=133 */ -+ {530842, 132710, 0x163, 0}, /* run=531, turbo=531, PXbus=133, SDRAM=133 */ - {0,} - }; - #define NUM_RUN_FREQS (sizeof(pxa255_run_freqs)/sizeof(pxa_freqs_t)) -@@ -91,11 +93,11 @@ static struct cpufreq_frequency_table px - static pxa_freqs_t pxa255_turbo_freqs[] = - { - /* CPU MEMBUS CCCR DIV2*/ -- { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */ -- {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */ -- {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */ -- {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */ -- {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */ -+ { 99533, 99533, 0x121, 1}, /* run=99, turbo= 99, PXbus=99, SDRAM=50 */ -+ {149299, 99533, 0x1a1, 0}, /* run=99, turbo=149, PXbus=99, SDRAM=99 */ -+ {199066, 99533, 0x221, 0}, /* run=99, turbo=199, PXbus=99, SDRAM=99 */ -+ {298598, 99533, 0x321, 0}, /* run=99, turbo=299, PXbus=99, SDRAM=99 */ -+ {398131, 99533, 0x241, 1}, /* run=199, turbo=398, PXbus=99, SDRAM=50 */ - {0,} - }; - #define NUM_TURBO_FREQS (sizeof(pxa255_turbo_freqs)/sizeof(pxa_freqs_t)) diff --git a/recipes/linux/linux-gumstix-2.6.15/cpufreq-ondemand-by-default.patch b/recipes/linux/linux-gumstix-2.6.15/cpufreq-ondemand-by-default.patch deleted file mode 100644 index 5903ab275b..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/cpufreq-ondemand-by-default.patch +++ /dev/null @@ -1,42 +0,0 @@ -Index: linux-2.6.15gum/drivers/cpufreq/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/drivers/cpufreq/Kconfig -+++ linux-2.6.15gum/drivers/cpufreq/Kconfig -@@ -52,7 +52,7 @@ config CPU_FREQ_STAT_DETAILS - - choice - prompt "Default CPUFreq governor" -- default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 -+ default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 || CPU_FREQ_PXA - default CPU_FREQ_DEFAULT_GOV_PERFORMANCE - help - This option sets which CPUFreq governor shall be loaded at -@@ -75,6 +75,14 @@ config CPU_FREQ_DEFAULT_GOV_USERSPACE - program shall be able to set the CPU dynamically without having - to enable the userspace governor manually. - -+config CPU_FREQ_DEFAULT_GOV_ONDEMAND -+ bool "ondemand" -+ select CPU_FREQ_GOV_ONDEMAND -+ help -+ Use the CPUFreq governor 'ondemand' as default. This sets -+ the frequency dynamically based on CPU load, throttling up -+ and down as necessary. -+ - endchoice - - config CPU_FREQ_GOV_PERFORMANCE -Index: linux-2.6.15gum/include/linux/cpufreq.h -=================================================================== ---- linux-2.6.15gum.orig/include/linux/cpufreq.h -+++ linux-2.6.15gum/include/linux/cpufreq.h -@@ -268,6 +268,9 @@ extern struct cpufreq_governor cpufreq_g - #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE) - extern struct cpufreq_governor cpufreq_gov_userspace; - #define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace -+#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND) -+extern struct cpufreq_governor cpufreq_gov_dbs; -+#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs; - #endif - - diff --git a/recipes/linux/linux-gumstix-2.6.15/defconfig-gumstix b/recipes/linux/linux-gumstix-2.6.15/defconfig-gumstix deleted file mode 100644 index 24c1aca43f..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/defconfig-gumstix +++ /dev/null @@ -1,995 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.15 -# Thu Jan 19 11:07:15 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="gum" -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 is not set -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 is not set -# CONFIG_EPOLL is not set -# CONFIG_SHMEM is not set -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -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 is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - -# -# 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_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=y -# 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 - -# -# Intel PXA2xx Implementations -# -CONFIG_ARCH_GUMSTIX=y -# CONFIG_ARCH_LUBBOCK is not set -# CONFIG_MACH_MAINSTONE is not set -# CONFIG_ARCH_PXA_IDP is not set -# CONFIG_PXA_SHARPSL is not set -# CONFIG_ARCH_GUMSTIX_ORIG is not set -CONFIG_ARCH_GUMSTIX_F=y -CONFIG_PXA25x=y - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_XSCALE=y -CONFIG_CPU_32v5=y -CONFIG_CPU_ABRT_EV5T=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_TLB_V4WBI=y - -# -# Processor Features -# -# CONFIG_ARM_THUMB is not set -CONFIG_XSCALE_PMU=y - -# -# Bus support -# -CONFIG_ISA_DMA_API=y -CONFIG_PROC_GPIO=m - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=m -# CONFIG_PCMCIA_DEBUG is not set -CONFIG_PCMCIA=m -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y - -# -# PC-card bridges -# -CONFIG_PCMCIA_PXA2XX=m - -# -# 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=ttyS0,115200n8 root=1f02 rootfstype=jffs2 reboot=cold,hard" -# CONFIG_XIP_KERNEL is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -# CONFIG_FPE_NWFPE is not set -# 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_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# 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=m -CONFIG_BT_GUMSTIX=m -CONFIG_BT_L2CAP=m -CONFIG_BT_SCO=m -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -# CONFIG_BT_HIDP is not set - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_H4=y -# CONFIG_BT_HCIUART_BCSP is not set -# CONFIG_BT_HCIDTL1 is not set -# CONFIG_BT_HCIBT3C is not set -# CONFIG_BT_HCIBLUECARD is not set -# CONFIG_BT_HCIBTUART is not set -# CONFIG_BT_HCIVHCI is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -# CONFIG_IEEE80211_CRYPT_CCMP is not set -# CONFIG_IEEE80211_CRYPT_TKIP is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# 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 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=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set -CONFIG_MTD_MAP_BANK_WIDTH_2=y -# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set -# 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 is not set -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set - -# -# Mapping drivers for chip access -# -CONFIG_MTD_COMPLEX_MAPPINGS=y -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_MULTI_PHYSMAP is not set -CONFIG_MTD_GUMSTIX=y -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_SHARP_SL 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_RAMTD 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 - -# -# 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=m -# CONFIG_BLK_DEV_CRYPTOLOOP 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 - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=m -CONFIG_BLK_DEV_IDE=m - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=m -# CONFIG_IDEDISK_MULTI_MODE is not set -CONFIG_BLK_DEV_IDECS=m -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=m -# CONFIG_IDE_ARM is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD 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=m -CONFIG_SMC91X=m -CONFIG_SMC91X_GUMSTIX=m -# CONFIG_DM9000 is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set -# CONFIG_PCMCIA_WAVELAN is not set -# CONFIG_PCMCIA_NETWAVE is not set - -# -# Wireless 802.11 Frequency Hopping cards support -# -# CONFIG_PCMCIA_RAYCS is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -CONFIG_HERMES=m -# CONFIG_ATMEL is not set - -# -# Wireless 802.11b Pcmcia/Cardbus cards support -# -CONFIG_PCMCIA_HERMES=m -CONFIG_PCMCIA_SPECTRUM=m -# CONFIG_AIRO_CS is not set -# CONFIG_PCMCIA_WL3501 is not set -CONFIG_HOSTAP=m -CONFIG_HOSTAP_FIRMWARE=y -CONFIG_HOSTAP_CS=m -CONFIG_NET_WIRELESS=y - -# -# PCMCIA network device support -# -# CONFIG_NET_PCMCIA 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_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y -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=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_SA1100_WATCHDOG=m -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_SA1100_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# - -# -# 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_I2C is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID 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=m - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=m -CONFIG_SND_AC97_CODEC=m -CONFIG_SND_AC97_BUS=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m -# CONFIG_SND_SEQUENCER is not set -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# ALSA ARM devices -# -CONFIG_SND_PXA2XX_PCM=m -CONFIG_SND_PXA2XX_AC97=m - -# -# PCMCIA devices -# - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set -# CONFIG_SOUND_WM97XX 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=m -# CONFIG_USB_GADGET_DEBUG_FILES is not set -CONFIG_USB_GADGET_SELECTED=y -CONFIG_USB_GADGET_GUMSTIX=m -# CONFIG_USB_GADGET_NET2280 is not set -CONFIG_USB_GADGET_PXA2XX=y -CONFIG_USB_PXA2XX=m -# CONFIG_USB_PXA2XX_SMALL is not set -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -# CONFIG_USB_GADGET_DUALSPEED is not set -# CONFIG_USB_ZERO is not set -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FILE_STORAGE is not set -# CONFIG_USB_G_SERIAL is not set - -# -# MMC/SD Card support -# -CONFIG_MMC=m -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_BLOCK=m -CONFIG_MMC_PXA=m -# CONFIG_MMC_WBSD 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=m -# 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 is not set -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# 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=m -# CONFIG_MSDOS_FS is not set -CONFIG_VFAT_FS=m -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=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -CONFIG_JFFS2_RUBIN=y -# CONFIG_JFFS2_CMODE_NONE is not set -CONFIG_JFFS2_CMODE_PRIORITY=y -# CONFIG_JFFS2_CMODE_SIZE 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=m -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_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -# 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=m -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -# 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=m -# 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 is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -# 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 is not set -CONFIG_DEBUG_ERRORS=y -# CONFIG_DEBUG_LL is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -CONFIG_CRYPTO_ARC4=m -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/recipes/linux/linux-gumstix-2.6.15/defconfig.patch b/recipes/linux/linux-gumstix-2.6.15/defconfig.patch deleted file mode 100644 index 0cafd7e774..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/defconfig.patch +++ /dev/null @@ -1,766 +0,0 @@ -Index: linux-2.6.15gum/arch/arm/configs/gumstix_defconfig -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/arch/arm/configs/gumstix_defconfig -@@ -0,0 +1,761 @@ -+# -+# Automatically generated make config: don't edit -+# -+CONFIG_ARM=y -+CONFIG_MMU=y -+CONFIG_UID16=y -+CONFIG_RWSEM_GENERIC_SPINLOCK=y -+ -+# -+# Code maturity level options -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_CLEAN_COMPILE=y -+CONFIG_BROKEN_ON_SMP=y -+ -+# -+# General setup -+# -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+# CONFIG_POSIX_MQUEUE is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_SYSCTL is not set -+# CONFIG_AUDIT is not set -+CONFIG_LOG_BUF_SHIFT=14 -+CONFIG_HOTPLUG=y -+# CONFIG_IKCONFIG is not set -+CONFIG_EMBEDDED=y -+# CONFIG_KALLSYMS is not set -+# CONFIG_FUTEX is not set -+# CONFIG_EPOLL is not set -+CONFIG_IOSCHED_NOOP=y -+# CONFIG_IOSCHED_AS is not set -+# CONFIG_IOSCHED_DEADLINE is not set -+# CONFIG_IOSCHED_CFQ is not set -+CONFIG_CC_OPTIMIZE_FOR_SIZE=y -+ -+# -+# Loadable module support -+# -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+CONFIG_OBSOLETE_MODPARM=y -+# CONFIG_MODVERSIONS is not set -+CONFIG_KMOD=y -+ -+# -+# 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_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_L7200 is not set -+CONFIG_ARCH_PXA=y -+# 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_PB is not set -+# CONFIG_ARCH_IMX is not set -+ -+# -+# Intel PXA2xx Implementations -+# -+CONFIG_ARCH_GUMSTIX=y -+# CONFIG_ARCH_LUBBOCK is not set -+# CONFIG_MACH_MAINSTONE is not set -+# CONFIG_ARCH_PXA_IDP is not set -+# CONFIG_ARCH_GUMSTIX_ORIG is not set -+CONFIG_ARCH_GUMSTIX_F=y -+CONFIG_PXA25x=y -+ -+# -+# Processor Type -+# -+CONFIG_CPU_32=y -+CONFIG_CPU_XSCALE=y -+CONFIG_CPU_32v5=y -+CONFIG_CPU_ABRT_EV5T=y -+CONFIG_CPU_TLB_V4WBI=y -+CONFIG_CPU_MINICACHE=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_THUMB is not set -+CONFIG_XSCALE_PMU=y -+ -+# -+# General setup -+# -+# CONFIG_ZBOOT_ROM is not set -+CONFIG_ZBOOT_ROM_TEXT=0x0 -+CONFIG_ZBOOT_ROM_BSS=0x0 -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_TABLE=y -+CONFIG_CPU_FREQ_PXA=y -+# CONFIG_CPU_FREQ_PROC_INTF is not set -+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=m -+CONFIG_CPU_FREQ_GOV_POWERSAVE=m -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_PROC_GPIO=m -+ -+# -+# PCMCIA/CardBus support -+# -+CONFIG_PCMCIA=m -+# CONFIG_PCMCIA_DEBUG is not set -+# CONFIG_TCIC is not set -+CONFIG_PCMCIA_PXA2XX=m -+ -+# -+# At least one math emulation must be selected -+# -+CONFIG_FPE_NWFPE=y -+# CONFIG_FPE_NWFPE_XP is not set -+# CONFIG_FPE_FASTFPE is not set -+# CONFIG_VFP is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+ -+# -+# Generic Driver Options -+# -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_FW_LOADER is not set -+# CONFIG_PM is not set -+# CONFIG_PREEMPT is not set -+# CONFIG_ARTHUR is not set -+CONFIG_CMDLINE="console=ttyS0,115200n8 root=1f02 rootfstype=jffs2 reboot=cold,hard" -+CONFIG_ALIGNMENT_TRAP=y -+ -+# -+# Parallel port support -+# -+# CONFIG_PARPORT is not set -+ -+# -+# Memory Technology Devices (MTD) -+# -+CONFIG_MTD=y -+# CONFIG_MTD_DEBUG is not set -+CONFIG_MTD_PARTITIONS=y -+# CONFIG_MTD_CONCAT is not set -+# CONFIG_MTD_REDBOOT_PARTS 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 -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+CONFIG_MTD_CFI=y -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_GEN_PROBE=y -+CONFIG_MTD_CFI_ADV_OPTIONS=y -+CONFIG_MTD_CFI_NOSWAP=y -+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -+CONFIG_MTD_CFI_GEOMETRY=y -+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set -+# 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 is not set -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+CONFIG_MTD_CFI_INTELEXT=y -+# CONFIG_MTD_CFI_AMDSTD is not set -+# CONFIG_MTD_CFI_STAA is not set -+CONFIG_MTD_CFI_UTIL=y -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+CONFIG_MTD_COMPLEX_MAPPINGS=y -+CONFIG_MTD_PHYSMAP=y -+CONFIG_MTD_PHYSMAP_START=0x00000000 -+CONFIG_MTD_PHYSMAP_LEN=0x00400000 -+CONFIG_MTD_PHYSMAP_BANKWIDTH=2 -+CONFIG_MTD_GUMSTIX=y -+# CONFIG_MTD_ARM_INTEGRATOR is not set -+# CONFIG_MTD_EDB7312 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 -+ -+# -+# 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 -+ -+# -+# Plug and Play support -+# -+ -+# -+# Block devices -+# -+# CONFIG_BLK_DEV_FD is not set -+CONFIG_BLK_DEV_LOOP=m -+# CONFIG_BLK_DEV_CRYPTOLOOP is not set -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_RAM is not set -+ -+# -+# Multi-device support (RAID and LVM) -+# -+# CONFIG_MD is not set -+ -+# -+# Networking support -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=m -+CONFIG_PACKET_MMAP=y -+# CONFIG_NETLINK_DEV is not set -+CONFIG_UNIX=m -+# CONFIG_NET_KEY is not set -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# CONFIG_IP_ADVANCED_ROUTER is not set -+# CONFIG_IP_PNP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE is not set -+# CONFIG_ARPD is not set -+# CONFIG_SYN_COOKIES is not set -+# 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_IPV6 is not set -+# CONFIG_NETFILTER 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 -+# CONFIG_NET_HW_FLOWCONTROL is not set -+ -+# -+# QoS and/or fair queueing -+# -+# CONFIG_NET_SCHED is not set -+# CONFIG_NET_CLS_ROUTE is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_IRDA is not set -+CONFIG_BT=m -+CONFIG_BT_GUMSTIX=m -+CONFIG_BT_L2CAP=m -+CONFIG_BT_SCO=m -+CONFIG_BT_RFCOMM=m -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_BNEP=m -+CONFIG_BT_BNEP_MC_FILTER=y -+CONFIG_BT_BNEP_PROTO_FILTER=y -+CONFIG_BT_HIDP=m -+ -+# -+# Bluetooth device drivers -+# -+CONFIG_BT_HCIUART=m -+CONFIG_BT_HCIUART_H4=y -+# CONFIG_BT_HCIUART_BCSP is not set -+# CONFIG_BT_HCIDTL1 is not set -+# CONFIG_BT_HCIBT3C is not set -+# CONFIG_BT_HCIBLUECARD is not set -+# CONFIG_BT_HCIBTUART is not set -+CONFIG_BT_HCIVHCI=m -+CONFIG_NETDEVICES=y -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+ -+# -+# Ethernet (10 or 100Mbit) -+# -+CONFIG_NET_ETHERNET=y -+CONFIG_MII=m -+CONFIG_SMC91X=m -+CONFIG_SMC91X_GUMSTIX=m -+ -+# -+# Ethernet (1000 Mbit) -+# -+ -+# -+# Ethernet (10000 Mbit) -+# -+ -+# -+# Token Ring devices -+# -+ -+# -+# Wireless LAN (non-hamradio) -+# -+# CONFIG_NET_RADIO is not set -+ -+# -+# PCMCIA network device support -+# -+# CONFIG_NET_PCMCIA 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 -+ -+# -+# ATA/ATAPI/MFM/RLL support -+# -+CONFIG_IDE=m -+CONFIG_BLK_DEV_IDE=m -+ -+# -+# Please see Documentation/ide.txt for help/info on IDE drives -+# -+# CONFIG_BLK_DEV_IDE_SATA is not set -+# CONFIG_BLK_DEV_IDEDISK is not set -+CONFIG_BLK_DEV_IDECS=m -+# CONFIG_BLK_DEV_IDECD is not set -+# CONFIG_BLK_DEV_IDETAPE is not set -+# CONFIG_BLK_DEV_IDEFLOPPY is not set -+# CONFIG_IDE_TASK_IOCTL is not set -+# CONFIG_IDE_TASKFILE_IO is not set -+ -+# -+# IDE chipset support/bugfixes -+# -+CONFIG_IDE_GENERIC=m -+# CONFIG_IDE_ARM is not set -+# CONFIG_BLK_DEV_IDEDMA is not set -+# CONFIG_IDEDMA_AUTO is not set -+# CONFIG_BLK_DEV_HD is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_SCSI is not set -+ -+# -+# Fusion MPT device support -+# -+ -+# -+# IEEE 1394 (FireWire) support -+# -+ -+# -+# I2O device support -+# -+ -+# -+# ISDN subsystem -+# -+# CONFIG_ISDN is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=m -+ -+# -+# Userland interfaces -+# -+# CONFIG_INPUT_MOUSEDEV is not set -+# CONFIG_INPUT_JOYDEV is not set -+# CONFIG_INPUT_TSDEV is not set -+# CONFIG_INPUT_EVDEV is not set -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input I/O drivers -+# -+# CONFIG_GAMEPORT is not set -+CONFIG_SOUND_GAMEPORT=y -+CONFIG_SERIO=y -+# CONFIG_SERIO_I8042 is not set -+# CONFIG_SERIO_SERPORT is not set -+# CONFIG_SERIO_CT82C710 is not set -+ -+# -+# Input Device Drivers -+# -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+# CONFIG_INPUT_MISC 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_PXA=y -+CONFIG_SERIAL_PXA_CONSOLE=y -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_QIC02_TAPE is not set -+ -+# -+# IPMI -+# -+# CONFIG_IPMI_HANDLER is not set -+ -+# -+# Watchdog Cards -+# -+CONFIG_WATCHDOG=y -+# CONFIG_WATCHDOG_NOWAYOUT is not set -+ -+# -+# Watchdog Device Drivers -+# -+# CONFIG_SOFT_WATCHDOG is not set -+CONFIG_SA1100_WATCHDOG=y -+# CONFIG_NVRAM is not set -+# CONFIG_RTC is not set -+# CONFIG_GEN_RTC is not set -+CONFIG_SA1100_RTC=m -+# CONFIG_DTLK is not set -+# CONFIG_R3964 is not set -+ -+# -+# Ftape, the floppy tape device driver -+# -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set -+ -+# -+# PCMCIA character devices -+# -+# CONFIG_SYNCLINK_CS is not set -+# CONFIG_RAW_DRIVER is not set -+ -+# -+# I2C support -+# -+# CONFIG_I2C is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+ -+# -+# Digital Video Broadcasting Devices -+# -+# CONFIG_DVB 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_XFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_QUOTA is not set -+# CONFIG_AUTOFS_FS is not set -+# CONFIG_AUTOFS4_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=m -+CONFIG_MSDOS_FS=m -+CONFIG_VFAT_FS=m -+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_DEVFS_FS is not set -+# CONFIG_DEVPTS_FS_XATTR is not set -+CONFIG_TMPFS=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_RAMFS=y -+ -+# -+# 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=y -+CONFIG_JFFS2_FS_DEBUG=0 -+# CONFIG_JFFS2_FS_NAND is not set -+CONFIG_JFFS2_COMPRESSION_OPTIONS=y -+CONFIG_JFFS2_ZLIB=y -+CONFIG_JFFS2_RTIME=y -+CONFIG_JFFS2_RUBIN=y -+# CONFIG_JFFS2_CMODE_NONE is not set -+# CONFIG_JFFS2_CMODE_PRIORITY is not set -+CONFIG_JFFS2_CMODE_SIZE=y -+# 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=m -+CONFIG_NFS_V3=y -+# CONFIG_NFS_V4 is not set -+# CONFIG_NFS_DIRECTIO is not set -+# CONFIG_NFSD is not set -+CONFIG_LOCKD=m -+CONFIG_LOCKD_V4=y -+# CONFIG_EXPORTFS is not set -+CONFIG_SUNRPC=m -+# 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 -+ -+# -+# 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=m -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=m -+# 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=m -+# 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 -+ -+# -+# Graphics support -+# -+# CONFIG_FB is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+ -+# -+# Misc devices -+# -+ -+# -+# USB support -+# -+ -+# -+# USB Gadget Support -+# -+CONFIG_USB_GADGET=m -+CONFIG_USB_GADGET_GUMSTIX=m -+# CONFIG_USB_GADGET_NET2280 is not set -+CONFIG_USB_GADGET_PXA2XX=y -+CONFIG_USB_PXA2XX=m -+# CONFIG_USB_PXA2XX_SMALL is not set -+# CONFIG_USB_GADGET_GOKU is not set -+# CONFIG_USB_GADGET_SA1100 is not set -+# CONFIG_USB_GADGET_DUMMY_HCD is not set -+# CONFIG_USB_GADGET_DUALSPEED is not set -+# CONFIG_USB_ZERO is not set -+CONFIG_USB_ETH=m -+CONFIG_USB_ETH_RNDIS=y -+# CONFIG_USB_GADGETFS is not set -+# CONFIG_USB_FILE_STORAGE is not set -+# CONFIG_USB_G_SERIAL is not set -+ -+# -+# MMC/SD Card support -+# -+CONFIG_MMC=m -+# CONFIG_MMC_DEBUG is not set -+CONFIG_MMC_BLOCK=m -+CONFIG_MMC_PXA=m -+ -+# -+# Kernel hacking -+# -+# CONFIG_DEBUG_KERNEL is not set -+# CONFIG_DEBUG_INFO is not set -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_USER is not set -+ -+# -+# Security options -+# -+# CONFIG_SECURITY is not set -+ -+# -+# Cryptographic options -+# -+# CONFIG_CRYPTO is not set -+ -+# -+# Library routines -+# -+# CONFIG_CRC_CCITT is not set -+CONFIG_CRC32=y -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y diff --git a/recipes/linux/linux-gumstix-2.6.15/disable-uncompress-message.patch b/recipes/linux/linux-gumstix-2.6.15/disable-uncompress-message.patch deleted file mode 100644 index 34399a9578..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/disable-uncompress-message.patch +++ /dev/null @@ -1,32 +0,0 @@ -Index: linux-2.6.15gum/arch/arm/boot/compressed/misc.c -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/boot/compressed/misc.c -+++ linux-2.6.15gum/arch/arm/boot/compressed/misc.c -@@ -280,7 +280,6 @@ void flush_window(void) - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; -- putstr("."); - } - - #ifndef arch_error -@@ -312,9 +311,7 @@ decompress_kernel(ulg output_start, ulg - arch_decomp_setup(); - - makecrc(); -- putstr("Uncompressing Linux..."); - gunzip(); -- putstr(" done, booting the kernel.\n"); - return output_ptr; - } - #else -@@ -326,9 +323,7 @@ int main() - output_data = output_buffer; - - makecrc(); -- putstr("Uncompressing Linux..."); - gunzip(); -- putstr("done.\n"); - return 0; - } - #endif diff --git a/recipes/linux/linux-gumstix-2.6.15/ethernet-config.patch b/recipes/linux/linux-gumstix-2.6.15/ethernet-config.patch deleted file mode 100644 index 1e6ac5bbda..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/ethernet-config.patch +++ /dev/null @@ -1,26 +0,0 @@ -Index: linux-2.6.15gum/drivers/net/smc91x.h -=================================================================== ---- linux-2.6.15gum.orig/drivers/net/smc91x.h -+++ linux-2.6.15gum/drivers/net/smc91x.h -@@ -55,6 +55,21 @@ - #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) - #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) - -+#elif defined(CONFIG_ARCH_GUMSTIX) -+#define SMC_CAN_USE_8BIT 0 -+#define SMC_CAN_USE_16BIT 1 -+#define SMC_CAN_USE_32BIT 0 -+#define SMC_NOWAIT 1 -+#define SMC_USE_PXA_DMA 1 -+#define SMC_IO_SHIFT 0 -+#define SMC_inw(a, r) readw((a) + (r)) -+#define SMC_outw(v, a, r) writew(v, (a) + (r)) -+#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) -+#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) -+#define RPC_LSA_DEFAULT RPC_LED_100_10 -+#define RPC_LSB_DEFAULT RPC_LED_TX_RX -+ -+ - #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6) - - /* We can only do 16-bit reads and writes in the static memory space. */ diff --git a/recipes/linux/linux-gumstix-2.6.15/flash.patch b/recipes/linux/linux-gumstix-2.6.15/flash.patch deleted file mode 100644 index b0ec106770..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/flash.patch +++ /dev/null @@ -1,171 +0,0 @@ -Index: linux-2.6.15gum/drivers/mtd/maps/gumstix-flash.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/drivers/mtd/maps/gumstix-flash.c -@@ -0,0 +1,136 @@ -+/* -+ * Map driver for the Gumstix platform -+ * -+ * Author: Craig Hughes -+ * -+ * 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 -+#include -+#include -+#include -+ -+ -+#define ROM_ADDR 0x00000000 -+#define FLASH_ADDR 0x00000000 -+ -+#define WINDOW_SIZE 64*1024*1024 -+ -+static struct map_info gumstix_flash_maps[1] = { { -+ .name = "Gumstix Flash ROM", -+ .size = WINDOW_SIZE, -+ .phys = FLASH_ADDR, -+ .bankwidth = 2, -+} }; -+ -+static struct mtd_partition gumstix_flash_partitions[] = { -+ { -+ .name = "Bootloader", -+ .size = 0x00040000, -+ .offset = FLASH_ADDR -+ },{ -+ .name = "RootFS", -+ .size = MTDPART_SIZ_FULL, -+ .offset = MTDPART_OFS_APPEND -+ } -+}; -+ -+static struct mtd_info *mymtds[1]; -+static struct mtd_partition *parsed_parts[1]; -+static int nr_parsed_parts[1]; -+ -+static const char *probes[] = { NULL }; -+ -+static int __init gumstix_flashmap_init(void) -+{ -+ int ret = 0, i; -+ -+ for (i = 0; i < 1; i++) { -+ gumstix_flash_maps[i].virt = ioremap(gumstix_flash_maps[i].phys, WINDOW_SIZE); -+ if (!gumstix_flash_maps[i].virt) { -+ printk(KERN_WARNING "Failed to ioremap %s\n", gumstix_flash_maps[i].name); -+ if (!ret) -+ ret = -ENOMEM; -+ continue; -+ } -+ simple_map_init(&gumstix_flash_maps[i]); -+ -+ printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n", -+ gumstix_flash_maps[i].name, gumstix_flash_maps[i].phys, -+ gumstix_flash_maps[i].bankwidth * 8); -+ -+ mymtds[i] = do_map_probe("cfi_probe", &gumstix_flash_maps[i]); -+ -+ if (!mymtds[i]) { -+ iounmap((void *)gumstix_flash_maps[i].virt); -+ if (gumstix_flash_maps[i].cached) -+ iounmap(gumstix_flash_maps[i].cached); -+ if (!ret) -+ ret = -EIO; -+ continue; -+ } -+ mymtds[i]->owner = THIS_MODULE; -+ -+ ret = parse_mtd_partitions(mymtds[i], probes, -+ &parsed_parts[i], 0); -+ -+ if (ret > 0) -+ nr_parsed_parts[i] = ret; -+ } -+ -+ if (!mymtds[0]) -+ return ret; -+ -+ for (i = 0; i < 1; i++) { -+ if (!mymtds[i]) { -+ printk(KERN_WARNING "%s is absent. Skipping\n", gumstix_flash_maps[i].name); -+ } else if (nr_parsed_parts[i]) { -+ add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]); -+ } else if (!i) { -+ printk("Using static partitions on %s\n", gumstix_flash_maps[i].name); -+ add_mtd_partitions(mymtds[i], gumstix_flash_partitions, ARRAY_SIZE(gumstix_flash_partitions)); -+ } else { -+ printk("Registering %s as whole device\n", gumstix_flash_maps[i].name); -+ add_mtd_device(mymtds[i]); -+ } -+ } -+ return 0; -+} -+ -+static void __exit gumstix_flashmap_cleanup(void) -+{ -+ int i; -+ for (i = 0; i < 1; i++) { -+ if (!mymtds[i]) -+ continue; -+ -+ if (nr_parsed_parts[i] || !i) -+ del_mtd_partitions(mymtds[i]); -+ else -+ del_mtd_device(mymtds[i]); -+ -+ map_destroy(mymtds[i]); -+ iounmap((void *)gumstix_flash_maps[i].virt); -+ if (gumstix_flash_maps[i].cached) -+ iounmap(gumstix_flash_maps[i].cached); -+ -+ if (parsed_parts[i]) -+ kfree(parsed_parts[i]); -+ } -+} -+ -+module_init(gumstix_flashmap_init); -+module_exit(gumstix_flashmap_cleanup); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Gumstix, Inc. "); -+MODULE_DESCRIPTION("MTD map driver for the Gumstix Platform"); -Index: linux-2.6.15gum/drivers/mtd/maps/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/drivers/mtd/maps/Kconfig -+++ linux-2.6.15gum/drivers/mtd/maps/Kconfig -@@ -208,6 +208,13 @@ config MTD_SBC_GXX - More info at - . - -+config MTD_GUMSTIX -+ tristate "CFI Flash device mapped on Gumstix" -+ depends on ARCH_GUMSTIX && MTD_CFI_INTELEXT && MTD_PARTITIONS -+ help -+ This provides a driver for the on-board flash of the Gumstix -+ single board computers. -+ - config MTD_PXA2XX - tristate "CFI Flash device mapped on Intel XScale PXA2xx eval board" - depends on (ARCH_LUBBOCK || MACH_MAINSTONE) && MTD_CFI_INTELEXT -Index: linux-2.6.15gum/drivers/mtd/maps/Makefile -=================================================================== ---- linux-2.6.15gum.orig/drivers/mtd/maps/Makefile -+++ linux-2.6.15gum/drivers/mtd/maps/Makefile -@@ -22,6 +22,7 @@ obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom - obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o - obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o - obj-$(CONFIG_MTD_PXA2XX) += pxa2xx-flash.o -+obj-$(CONFIG_MTD_GUMSTIX) += gumstix-flash.o - obj-$(CONFIG_MTD_MBX860) += mbx860.o - obj-$(CONFIG_MTD_CEIVA) += ceiva.o - obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o diff --git a/recipes/linux/linux-gumstix-2.6.15/gumstix-mmc.patch b/recipes/linux/linux-gumstix-2.6.15/gumstix-mmc.patch deleted file mode 100644 index e526712091..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/gumstix-mmc.patch +++ /dev/null @@ -1,91 +0,0 @@ -diff -udrp linux-2.6.15/arch/arm/mach-pxa/gumstix.c linux-2.6.15.mine/arch/arm/mach-pxa/gumstix.c ---- linux-2.6.15/arch/arm/mach-pxa/gumstix.c 2006-04-11 00:29:42.000000000 -0400 -+++ linux-2.6.15.mine/arch/arm/mach-pxa/gumstix.c 2006-04-11 00:11:38.000000000 -0400 -@@ -28,19 +28,60 @@ - - #include "generic.h" - --static int gumstix_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data) -+static struct pxamci_platform_data gumstix_mci_platform_data; -+ -+static int gumstix_mci_init(struct device *dev, irqreturn_t (*gumstix_detect_int)(int, void *, struct pt_regs *), void *data) - { -- // Set up MMC controller -+ int err; -+ -+ //printk("entering gumstix_mci_init\n"); -+ - pxa_gpio_mode(GPIO6_MMCCLK_MD); - pxa_gpio_mode(GPIO53_MMCCLK_MD); - pxa_gpio_mode(GPIO8_MMCCS0_MD); - -+ //printk(" setting gpio sd detect\n"); -+ pxa_gpio_mode(GUMSTIX_GPIO_nSD_DETECT | GPIO_IN); -+ pxa_gpio_mode(GUMSTIX_GPIO_nSD_WP | GPIO_IN); -+ -+ //printk(" setting delay to "); -+ gumstix_mci_platform_data.detect_delay = msecs_to_jiffies(200); -+ //printk("%d\n", gumstix_mci_platform_data.detect_delay); -+ -+ err = request_irq(GUMSTIX_IRQ_GPIO_nSD_DETECT, gumstix_detect_int, SA_INTERRUPT, -+ "MMC card detect", data); -+ if (err) { -+ printk(KERN_ERR "gumstix_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); -+ return -1; -+ } -+ -+ //printk(" set_irq_type returned a "); -+ err = set_irq_type(GUMSTIX_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); -+ //printk("%d\n", err); -+ - return 0; - } - -+static int gumstix_mci_get_ro(struct device *dev) -+{ -+ int ro; -+ //printk("entering gumstix_mci_get_ro\n"); -+ ro = GPLR(GUMSTIX_GPIO_nSD_WP) & GPIO_bit(GUMSTIX_GPIO_nSD_WP); -+ //printk(" ro is %d\n", ro); -+ return ro; -+} -+ -+static void gumstix_mci_exit(struct device *dev, void *data) -+{ -+ //printk("entering gumstix_mci_exit\n"); -+ free_irq(GUMSTIX_IRQ_GPIO_nSD_DETECT, data); -+} -+ - static struct pxamci_platform_data gumstix_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, -- .init = &gumstix_mci_init, -+ .init = gumstix_mci_init, -+ .get_ro = gumstix_mci_get_ro, -+ .exit = gumstix_mci_exit, - }; - - static int gumstix_udc_is_connected(void) -@@ -76,6 +117,7 @@ static struct platform_device *devices[] - - static void __init gumstix_init(void) - { -+ //printk("entering gumstix_init\n"); - pxa_set_mci_info(&gumstix_mci_platform_data); - pxa_set_udc_info(&gumstix_udc_info); - (void) platform_add_devices(devices, ARRAY_SIZE(devices)); -diff -udrp linux-2.6.15/include/asm-arm/arch-pxa/gumstix.h linux-2.6.15.mine/include/asm-arm/arch-pxa/gumstix.h ---- linux-2.6.15/include/asm-arm/arch-pxa/gumstix.h 2006-04-11 00:29:43.000000000 -0400 -+++ linux-2.6.15.mine/include/asm-arm/arch-pxa/gumstix.h 2006-04-10 22:26:20.000000000 -0400 -@@ -36,6 +36,12 @@ - #define GPIO_GUMSTIX_USB_GPIOx_CON_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT) - #define GPIO_GUMSTIX_USB_GPIOx_DIS_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_IN) - -+/* -+ * SD/MMC definitions -+ */ -+#define GUMSTIX_GPIO_nSD_WP (22) /* SD Write Protect? */ -+#define GUMSTIX_GPIO_nSD_DETECT (11) /* MMC/SD Card Detect */ -+#define GUMSTIX_IRQ_GPIO_nSD_DETECT IRQ_GPIO(11) - - /* - * SMC Ethernet definitions diff --git a/recipes/linux/linux-gumstix-2.6.15/header.patch b/recipes/linux/linux-gumstix-2.6.15/header.patch deleted file mode 100644 index 51cfa08cc6..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/header.patch +++ /dev/null @@ -1,87 +0,0 @@ -Index: linux-2.6.15gum/include/asm-arm/arch-pxa/gumstix.h -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/include/asm-arm/arch-pxa/gumstix.h -@@ -0,0 +1,82 @@ -+/* -+ * linux/include/asm-arm/arch-pxa/gumstix.h -+ * -+ * 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. -+ */ -+ -+ -+/* BTRESET - Reset line to Bluetooth module, active low signal. */ -+#define GPIO_GUMSTIX_BTRESET 7 -+#define GPIO_GUMSTIX_BTRESET_MD (GPIO_GUMSTIX_BTRESET | GPIO_OUT) -+ -+ -+/* GPIOn - Input from MAX823 (or equiv), normalizing USB +5V -+ into a clean interrupt signal for determining cable presence -+ On the original gumstix, this is GPIO81, and GPIO83 needs to be defined as well. -+ On the gumstix F, this moves to GPIO17 and GPIO37 */ -+/* GPIOx - Connects to USB D+ and used as a pull-up after GPIOn -+ has detected a cable insertion; driven low otherwise. */ -+ -+#ifdef CONFIG_ARCH_GUMSTIX_ORIG -+ -+#define GPIO_GUMSTIX_USB_GPIOn 81 -+#define GPIO_GUMSTIX_USB_GPIOx 83 -+ -+#else -+ -+#define GPIO_GUMSTIX_USB_GPIOn 35 -+#define GPIO_GUMSTIX_USB_GPIOx 41 -+ -+#endif -+ -+#define GUMSTIX_USB_INTR_IRQ IRQ_GPIO(GPIO_GUMSTIX_USB_GPIOn) /* usb state change */ -+#define GPIO_GUMSTIX_USB_GPIOn_MD (GPIO_GUMSTIX_USB_GPIOn | GPIO_IN) -+#define GPIO_GUMSTIX_USB_GPIOx_CON_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT) -+#define GPIO_GUMSTIX_USB_GPIOx_DIS_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_IN) -+ -+ -+/* -+ * SMC Ethernet definitions -+ * ETH_RST provides a hardware reset line to the ethernet chip -+ * ETH is the IRQ line in from the ethernet chip to the PXA -+ */ -+#define GPIO_GUMSTIX_ETH0_RST 80 -+#define GPIO_GUMSTIX_ETH0_RST_MD (GPIO_GUMSTIX_ETH0_RST | GPIO_OUT) -+#define GPIO_GUMSTIX_ETH1_RST 52 -+#define GPIO_GUMSTIX_ETH1_RST_MD (GPIO_GUMSTIX_ETH1_RST | GPIO_OUT) -+ -+#define GPIO_GUMSTIX_ETH0 36 -+#define GPIO_GUMSTIX_ETH0_MD (GPIO_GUMSTIX_ETH0 | GPIO_IN) -+#define GUMSTIX_ETH0_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH0) -+#define GPIO_GUMSTIX_ETH1 27 -+#define GPIO_GUMSTIX_ETH1_MD (GPIO_GUMSTIX_ETH1 | GPIO_IN) -+#define GUMSTIX_ETH1_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH1) -+ -+ -+/* -+ * The following are missing from pxa-regs.h -+ */ -+ -+#define GPIO4_nBVD1 4 -+#define GPIO4_nSTSCHG GPIO4_nBVD1 -+#define GPIO8_RESET 8 -+#define GPIO11_nPCD1 11 -+#define GPIO22_nINPACK 22 -+#define GPIO26_PRDY_nBSY0 26 -+#define GPIO36_nBVD2 36 -+ -+#define GPIO4_nBVD1_MD ( GPIO4_nBVD1| GPIO_IN ) -+#define GPIO4_nSTSCHG_MD ( GPIO4_nSTSCHG | GPIO_IN ) -+#define GPIO8_RESET_MD ( GPIO8_RESET | GPIO_OUT ) -+#define GPIO11_nPCD1_MD ( GPIO11_nPCD1 | GPIO_IN ) -+#define GPIO22_nINPACK_MD ( GPIO22_nINPACK | GPIO_IN ) -+#define GPIO26_PRDY_nBSY0_MD ( GPIO26_PRDY_nBSY0 | GPIO_IN ) -+#define GPIO36_nBVD2_MD ( GPIO36_nBVD2 | GPIO_IN ) -+ -+#define GUMSTIX_nSTSCHG_IRQ IRQ_GPIO(GPIO4_nSTSCHG) -+#define GUMSTIX_nPCD1_IRQ IRQ_GPIO(GPIO11_nPCD1) -+#define GUSMTIX_nBVD1_IRQ IRQ_GPIO(GPIO4_nBVD1) -+#define GUMSTIX_nBVD2_IRQ IRQ_GPIO(GPIO36_nBVD2) -+#define GUMSTIX_PRDY_nBSY0_IRQ IRQ_GPIO(GPIO26_PRDY_nBSY0) diff --git a/recipes/linux/linux-gumstix-2.6.15/i2c-gpl-module-fix.patch b/recipes/linux/linux-gumstix-2.6.15/i2c-gpl-module-fix.patch deleted file mode 100644 index 408bb1854d..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/i2c-gpl-module-fix.patch +++ /dev/null @@ -1,43 +0,0 @@ -Index: linux-2.6.15gum/drivers/i2c/busses/i2c-pxa.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/i2c/busses/i2c-pxa.c -+++ linux-2.6.15gum/drivers/i2c/busses/i2c-pxa.c -@@ -32,7 +32,6 @@ - #include - #include - --#include - #include - #include - #include -@@ -900,6 +899,12 @@ static int i2c_pxa_xfer(struct i2c_adapt - struct pxa_i2c *i2c = adap->algo_data; - int ret, i; - -+ /* If the I2C controller is disabled we need to reset it (probably due -+ to a suspend/resume destroying state). We do this here as we can then -+ avoid worrying about resuming the controller before its users. */ -+ if (!(ICR & ICR_IUE)) -+ i2c_pxa_reset(i2c); -+ - for (i = adap->retries; i >= 0; i--) { - ret = i2c_pxa_do_xfer(i2c, msgs, num); - if (ret != I2C_RETRY) -@@ -940,7 +945,9 @@ static struct pxa_i2c i2c_pxa = { - static int i2c_pxa_probe(struct platform_device *dev) - { - struct pxa_i2c *i2c = &i2c_pxa; -+#ifdef CONFIG_I2C_PXA_SLAVE - struct i2c_pxa_platform_data *plat = dev->dev.platform_data; -+#endif - int ret; - - #ifdef CONFIG_PXA27x -@@ -1025,5 +1032,7 @@ static void i2c_adap_pxa_exit(void) - return platform_driver_unregister(&i2c_pxa_driver); - } - -+MODULE_LICENSE("GPL"); -+ - module_init(i2c_adap_pxa_init); - module_exit(i2c_adap_pxa_exit); diff --git a/recipes/linux/linux-gumstix-2.6.15/kconfig-arch-cleanup.patch b/recipes/linux/linux-gumstix-2.6.15/kconfig-arch-cleanup.patch deleted file mode 100644 index 1d35bfa805..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/kconfig-arch-cleanup.patch +++ /dev/null @@ -1,72 +0,0 @@ -Index: linux-2.6.15gum/arch/arm/mach-clps711x/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-clps711x/Kconfig -+++ linux-2.6.15gum/arch/arm/mach-clps711x/Kconfig -@@ -1,6 +1,7 @@ - if ARCH_CLPS711X - - menu "CLPS711X/EP721X Implementations" -+ depends on ARCH_CLPS711X - - config ARCH_AUTCPU12 - bool "AUTCPU12" -Index: linux-2.6.15gum/arch/arm/mach-epxa10db/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-epxa10db/Kconfig -+++ linux-2.6.15gum/arch/arm/mach-epxa10db/Kconfig -@@ -1,6 +1,7 @@ - if ARCH_CAMELOT - - menu "Epxa10db" -+ depends on ARCH_CAMELOT - - comment "PLD hotswap support" - -Index: linux-2.6.15gum/arch/arm/mach-footbridge/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-footbridge/Kconfig -+++ linux-2.6.15gum/arch/arm/mach-footbridge/Kconfig -@@ -1,6 +1,7 @@ - if ARCH_FOOTBRIDGE - - menu "Footbridge Implementations" -+ depends on ARCH_FOOTBRIDGE - - config ARCH_CATS - bool "CATS" -Index: linux-2.6.15gum/arch/arm/mach-iop3xx/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-iop3xx/Kconfig -+++ linux-2.6.15gum/arch/arm/mach-iop3xx/Kconfig -@@ -1,6 +1,7 @@ - if ARCH_IOP3XX - - menu "IOP3xx Implementation Options" -+ depends on ARCH_IOP3XX - - comment "IOP3xx Platform Types" - -Index: linux-2.6.15gum/arch/arm/mach-lh7a40x/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-lh7a40x/Kconfig -+++ linux-2.6.15gum/arch/arm/mach-lh7a40x/Kconfig -@@ -1,6 +1,7 @@ - if ARCH_LH7A40X - - menu "LH7A40X Implementations" -+ depends on ARCH_LH7A40X - - config MACH_KEV7A400 - bool "KEV7A400" -Index: linux-2.6.15gum/arch/arm/mach-sa1100/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/mach-sa1100/Kconfig -+++ linux-2.6.15gum/arch/arm/mach-sa1100/Kconfig -@@ -1,6 +1,7 @@ - if ARCH_SA1100 - - menu "SA11x0 Implementations" -+ depends on ARCH_SA1100 - - config SA1100_ASSABET - bool "Assabet" diff --git a/recipes/linux/linux-gumstix-2.6.15/kernel-osx.patch b/recipes/linux/linux-gumstix-2.6.15/kernel-osx.patch deleted file mode 100644 index b50001db57..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/kernel-osx.patch +++ /dev/null @@ -1,50 +0,0 @@ -Index: linux-2.6.15gum/scripts/Makefile.host -=================================================================== ---- linux-2.6.15gum.orig/scripts/Makefile.host -+++ linux-2.6.15gum/scripts/Makefile.host -@@ -137,15 +137,17 @@ $(host-cxxobjs): %.o: %.cc FORCE - - # Compile .c file, create position independent .o file - # host-cshobjs -> .o --quiet_cmd_host-cshobjs = HOSTCC -fPIC $@ -- cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $< -+quiet_cmd_host-cshobjs = HOSTCC -fPIC -fno-common $@ -+ cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -fno-common -c -o $@ $< - $(host-cshobjs): %.o: %.c FORCE - $(call if_changed_dep,host-cshobjs) - - # Link a shared library, based on position independent .o files - # *.o -> .so shared library (host-cshlib) --quiet_cmd_host-cshlib = HOSTLLD -shared $@ -- cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \ -+SHARED_SWITCH = `if $(HOSTCC) -dM -E - < /dev/null | grep -q APPLE; \ -+ then echo "-dynamiclib"; else echo "-shared"; fi` -+quiet_cmd_host-cshlib = HOSTLLD $(SHARED_SWITCH) $@ -+ cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) $(SHARED_SWITCH) -o $@ \ - $(addprefix $(obj)/,$($(@F:.so=-objs))) \ - $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) - $(host-cshlib): %: $(host-cshobjs) FORCE -Index: linux-2.6.15gum/Makefile -=================================================================== ---- linux-2.6.15gum.orig/Makefile -+++ linux-2.6.15gum/Makefile -@@ -203,7 +203,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" - - HOSTCC = gcc - HOSTCXX = g++ --HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -+HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -idirafter "`$(CC) -print-file-name=include`/../../../../../include/" -+ - HOSTCXXFLAGS = -O2 - - # Decide whether to build built-in, modular, or both. -Index: linux-2.6.15gum/scripts/mod/sumversion.c -=================================================================== ---- linux-2.6.15gum.orig/scripts/mod/sumversion.c -+++ linux-2.6.15gum/scripts/mod/sumversion.c -@@ -1,4 +1,4 @@ --#include -+#include - #ifdef __sun__ - #include - #else diff --git a/recipes/linux/linux-gumstix-2.6.15/kobject_get_path_export.patch b/recipes/linux/linux-gumstix-2.6.15/kobject_get_path_export.patch deleted file mode 100644 index e54351155a..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/kobject_get_path_export.patch +++ /dev/null @@ -1,13 +0,0 @@ -Oddly, devices/input/input.c seems to reference a symbol which is in another module but is not exported. -Index: linux-2.6.15gum/lib/kobject.c -=================================================================== ---- linux-2.6.15gum.orig/lib/kobject.c -+++ linux-2.6.15gum/lib/kobject.c -@@ -115,6 +115,7 @@ char *kobject_get_path(struct kobject *k - - return path; - } -+EXPORT_SYMBOL(kobject_get_path); - - /** - * kobject_init - initialize object. diff --git a/recipes/linux/linux-gumstix-2.6.15/mach-types-fix.patch b/recipes/linux/linux-gumstix-2.6.15/mach-types-fix.patch deleted file mode 100644 index a74edf0bf6..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/mach-types-fix.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: linux-2.6.15gum/arch/arm/tools/mach-types -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/tools/mach-types -+++ linux-2.6.15gum/arch/arm/tools/mach-types -@@ -387,7 +387,7 @@ s5c7375 ARCH_S5C7375 S5C7375 369 - spearhead ARCH_SPEARHEAD SPEARHEAD 370 - pantera ARCH_PANTERA PANTERA 371 - prayoglite ARCH_PRAYOGLITE PRAYOGLITE 372 --gumstix ARCH_GUMSTIK GUMSTIK 373 -+gumstix ARCH_GUMSTIX GUMSTIX 373 - rcube ARCH_RCUBE RCUBE 374 - rea_olv ARCH_REA_OLV REA_OLV 375 - pxa_iphone ARCH_PXA_IPHONE PXA_IPHONE 376 diff --git a/recipes/linux/linux-gumstix-2.6.15/mmc-version4.patch b/recipes/linux/linux-gumstix-2.6.15/mmc-version4.patch deleted file mode 100644 index c572dbcc2a..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/mmc-version4.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: linux-2.6.15gum/drivers/mmc/mmc.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/mmc/mmc.c -+++ linux-2.6.15gum/drivers/mmc/mmc.c -@@ -495,6 +495,7 @@ static void mmc_decode_cid(struct mmc_ca - - case 2: /* MMC v2.0 - v2.2 */ - case 3: /* MMC v3.1 - v3.3 */ -+ case 4: /* MMC v4.x */ - card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); - card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); - card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); diff --git a/recipes/linux/linux-gumstix-2.6.15/modular-init-bluetooth.patch b/recipes/linux/linux-gumstix-2.6.15/modular-init-bluetooth.patch deleted file mode 100644 index c5d96f87d9..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/modular-init-bluetooth.patch +++ /dev/null @@ -1,106 +0,0 @@ -Index: linux-2.6.15gum/net/bluetooth/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/net/bluetooth/Kconfig -+++ linux-2.6.15gum/net/bluetooth/Kconfig -@@ -30,6 +30,12 @@ menuconfig BT - Bluetooth kernel modules are provided in the BlueZ packages. - For more information, see . - -+config BT_GUMSTIX -+ tristate -+ default m if BT=m -+ default y if BT=y -+ depends on BT && ARCH_GUMSTIX -+ - config BT_L2CAP - tristate "L2CAP protocol support" - depends on BT -Index: linux-2.6.15gum/net/bluetooth/Makefile -=================================================================== ---- linux-2.6.15gum.orig/net/bluetooth/Makefile -+++ linux-2.6.15gum/net/bluetooth/Makefile -@@ -9,5 +9,6 @@ obj-$(CONFIG_BT_RFCOMM) += rfcomm/ - obj-$(CONFIG_BT_BNEP) += bnep/ - obj-$(CONFIG_BT_CMTP) += cmtp/ - obj-$(CONFIG_BT_HIDP) += hidp/ -+obj-$(CONFIG_BT_GUMSTIX)+= gumstix_bluetooth.o - - bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o -Index: linux-2.6.15gum/net/bluetooth/af_bluetooth.c -=================================================================== ---- linux-2.6.15gum.orig/net/bluetooth/af_bluetooth.c -+++ linux-2.6.15gum/net/bluetooth/af_bluetooth.c -@@ -304,10 +304,18 @@ static struct net_proto_family bt_sock_f - .create = bt_sock_create, - }; - -+#ifdef CONFIG_ARCH_GUMSTIX -+extern void gumstix_bluetooth_load(void); -+#endif -+ - static int __init bt_init(void) - { - BT_INFO("Core ver %s", VERSION); - -+#ifdef CONFIG_ARCH_GUMSTIX -+ gumstix_bluetooth_load(); -+#endif -+ - sock_register(&bt_sock_family_ops); - - BT_INFO("HCI device and connection manager initialized"); -Index: linux-2.6.15gum/net/bluetooth/gumstix_bluetooth.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/net/bluetooth/gumstix_bluetooth.c -@@ -0,0 +1,50 @@ -+/* -+ * Gumstix bluetooth module intialization driver -+ * -+ * Author: Craig Hughes -+ * Created: December 9, 2004 -+ * Copyright: (C) 2004 Craig Hughes -+ * -+ * 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 -+ -+static void gumstix_bluetooth_load(void) -+{ -+} -+ -+EXPORT_SYMBOL(gumstix_bluetooth_load); -+ -+int __init gumstix_bluetooth_init(void) -+{ -+ /* Set up GPIOs to use the BTUART */ -+ pxa_gpio_mode(GPIO42_HWRXD_MD); -+ pxa_gpio_mode(GPIO43_HWTXD_MD); -+ pxa_gpio_mode(GPIO44_HWCTS_MD); -+ pxa_gpio_mode(GPIO45_HWRTS_MD); -+ -+ return 0; -+} -+ -+void __exit gumstix_bluetooth_exit(void) -+{ -+} -+ -+module_init(gumstix_bluetooth_init); -+module_exit(gumstix_bluetooth_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Craig Hughes "); -+MODULE_DESCRIPTION("Gumstix board bluetooth module initialization driver"); -+MODULE_VERSION("1:0.1"); diff --git a/recipes/linux/linux-gumstix-2.6.15/modular-init-smc91x.patch b/recipes/linux/linux-gumstix-2.6.15/modular-init-smc91x.patch deleted file mode 100644 index 15a2bc06be..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/modular-init-smc91x.patch +++ /dev/null @@ -1,171 +0,0 @@ -Index: linux-2.6.15gum/drivers/net/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/drivers/net/Kconfig -+++ linux-2.6.15gum/drivers/net/Kconfig -@@ -826,6 +826,12 @@ config SMC91X - module, say M here and read as well - as . - -+config SMC91X_GUMSTIX -+ tristate -+ default m if SMC91X=m -+ default y if SMC91X=y -+ depends on SMC91X && ARCH_GUMSTIX -+ - config SMC9194 - tristate "SMC 9194 support" - depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN) -Index: linux-2.6.15gum/drivers/net/Makefile -=================================================================== ---- linux-2.6.15gum.orig/drivers/net/Makefile -+++ linux-2.6.15gum/drivers/net/Makefile -@@ -191,6 +191,7 @@ obj-$(CONFIG_SMC91X) += smc91x.o - obj-$(CONFIG_DM9000) += dm9000.o - obj-$(CONFIG_FEC_8XX) += fec_8xx/ - -+obj-$(CONFIG_SMC91X_GUMSTIX) += gumstix-smc91x.o - obj-$(CONFIG_ARM) += arm/ - obj-$(CONFIG_DEV_APPLETALK) += appletalk/ - obj-$(CONFIG_TR) += tokenring/ -Index: linux-2.6.15gum/drivers/net/smc91x.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/net/smc91x.c -+++ linux-2.6.15gum/drivers/net/smc91x.c -@@ -2366,6 +2366,10 @@ static struct platform_driver smc_driver - }, - }; - -+#ifdef CONFIG_ARCH_GUMSTIX -+extern void gumstix_smc91x_load(void); -+#endif -+ - static int __init smc_init(void) - { - #ifdef MODULE -@@ -2377,6 +2381,10 @@ static int __init smc_init(void) - #endif - #endif - -+#ifdef CONFIG_ARCH_GUMSTIX -+ gumstix_smc91x_load(); -+#endif -+ - return platform_driver_register(&smc_driver); - } - -Index: linux-2.6.15gum/drivers/net/gumstix-smc91x.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/drivers/net/gumstix-smc91x.c -@@ -0,0 +1,111 @@ -+/* -+ * Gumstix SMC91C111 chip intialization driver -+ * -+ * Author: Craig Hughes -+ * Created: December 9, 2004 -+ * Copyright: (C) 2004 Craig Hughes -+ * -+ * 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 -+ -+static struct resource gumstix_smc91x0_resources[] = { -+ [0] = { -+ .name = "smc91x-regs", -+ .start = PXA_CS1_PHYS + 0x00000300, -+ .end = PXA_CS1_PHYS + 0x000fffff, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = GUMSTIX_ETH0_IRQ, -+ .end = GUMSTIX_ETH0_IRQ, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct resource gumstix_smc91x1_resources[] = { -+ [0] = { -+ .name = "smc91x-regs", -+ .start = PXA_CS2_PHYS + 0x00000300, -+ .end = PXA_CS2_PHYS + 0x000fffff, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = GUMSTIX_ETH1_IRQ, -+ .end = GUMSTIX_ETH1_IRQ, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct platform_device gumstix_smc91x0_device = { -+ .name = "smc91x", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(gumstix_smc91x0_resources), -+ .resource = gumstix_smc91x0_resources, -+}; -+ -+static struct platform_device gumstix_smc91x1_device = { -+ .name = "smc91x", -+ .id = 1, -+ .num_resources = ARRAY_SIZE(gumstix_smc91x1_resources), -+ .resource = gumstix_smc91x1_resources, -+}; -+ -+static struct platform_device *smc91x_devices[] __initdata = { -+ &gumstix_smc91x0_device, -+ &gumstix_smc91x1_device, -+}; -+ -+int __init gumstix_smc91x_init(void) -+{ -+ /* Set up nPWE */ -+ pxa_gpio_mode(GPIO49_nPWE_MD); -+ -+ /* Set up the chip selects */ -+ pxa_gpio_mode(GPIO15_nCS_1_MD); -+ pxa_gpio_mode(GPIO78_nCS_2_MD); -+ -+ /* Reset the SMC91c111(s) */ -+ pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD); -+ pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD); -+ GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST); -+ GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST); -+ udelay(1); // Hold RESET pin high for at least 100ns -+ GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST); -+ GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST); -+ msleep(50); -+ -+ return platform_add_devices(smc91x_devices, ARRAY_SIZE(smc91x_devices)); -+} -+ -+void __exit gumstix_smc91x_exit(void) -+{ -+ platform_device_unregister(&gumstix_smc91x1_device); -+ platform_device_unregister(&gumstix_smc91x0_device); -+} -+ -+void gumstix_smc91x_load(void) {} -+EXPORT_SYMBOL(gumstix_smc91x_load); -+ -+module_init(gumstix_smc91x_init); -+module_exit(gumstix_smc91x_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Craig Hughes "); -+MODULE_DESCRIPTION("Gumstix board SMC91C111 chip initialization driver"); -+MODULE_VERSION("1:0.1"); diff --git a/recipes/linux/linux-gumstix-2.6.15/modular-init-usb-gadget.patch b/recipes/linux/linux-gumstix-2.6.15/modular-init-usb-gadget.patch deleted file mode 100644 index 94666ff812..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/modular-init-usb-gadget.patch +++ /dev/null @@ -1,105 +0,0 @@ -Index: linux-2.6.15gum/drivers/usb/gadget/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/drivers/usb/gadget/Kconfig -+++ linux-2.6.15gum/drivers/usb/gadget/Kconfig -@@ -56,6 +56,14 @@ config USB_GADGET_DEBUG_FILES - config USB_GADGET_SELECTED - boolean - -+config USB_GADGET_GUMSTIX -+ tristate -+ default m if USB_GADGET=m -+ default y if USB_GADGET=y -+ depends on USB_GADGET && ARCH_GUMSTIX -+ help -+ USB Gadget support for the Gumstix platform -+ - # - # USB Peripheral Controller Support - # -Index: linux-2.6.15gum/drivers/usb/gadget/Makefile -=================================================================== ---- linux-2.6.15gum.orig/drivers/usb/gadget/Makefile -+++ linux-2.6.15gum/drivers/usb/gadget/Makefile -@@ -7,6 +7,7 @@ obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o - obj-$(CONFIG_USB_GOKU) += goku_udc.o - obj-$(CONFIG_USB_OMAP) += omap_udc.o - obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o -+obj-$(CONFIG_USB_GADGET_GUMSTIX) += gumstix_gadget.o - - # - # USB gadget drivers -Index: linux-2.6.15gum/drivers/usb/gadget/pxa2xx_udc.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/usb/gadget/pxa2xx_udc.c -+++ linux-2.6.15gum/drivers/usb/gadget/pxa2xx_udc.c -@@ -2679,8 +2679,16 @@ static struct platform_driver udc_driver - }, - }; - -+#ifdef CONFIG_ARCH_GUMSTIX -+extern void gumstix_usb_gadget_load(void); -+#endif -+ - static int __init udc_init(void) - { -+#ifdef CONFIG_ARCH_GUMSTIX -+ gumstix_usb_gadget_load(); -+#endif -+ - printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); - return platform_driver_register(&udc_driver); - } -Index: linux-2.6.15gum/drivers/usb/gadget/gumstix_gadget.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/drivers/usb/gadget/gumstix_gadget.c -@@ -0,0 +1,48 @@ -+/* -+ * Gumstix USB gadget intialization driver -+ * -+ * Author: Craig Hughes -+ * Created: December 9, 2004 -+ * Copyright: (C) 2004 Craig Hughes -+ * -+ * 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 -+ -+int __init gumstix_usb_gadget_init(void) -+{ -+ pxa_gpio_mode(GPIO_GUMSTIX_USB_GPIOx_DIS_MD); -+ pxa_gpio_mode(GPIO_GUMSTIX_USB_GPIOn_MD); -+ -+ set_irq_type(GUMSTIX_USB_INTR_IRQ, IRQT_BOTHEDGE); -+ -+ return 0; -+} -+ -+void __exit gumstix_usb_gadget_exit(void) -+{ -+} -+ -+void gumstix_usb_gadget_load(void) {} -+EXPORT_SYMBOL(gumstix_usb_gadget_load); -+ -+module_init(gumstix_usb_gadget_init); -+module_exit(gumstix_usb_gadget_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Craig Hughes "); -+MODULE_DESCRIPTION("Gumstix board USB gadget initialization driver"); -+MODULE_VERSION("1:0.1"); diff --git a/recipes/linux/linux-gumstix-2.6.15/proc-gpio.patch b/recipes/linux/linux-gumstix-2.6.15/proc-gpio.patch deleted file mode 100644 index 1a53d1b1d0..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/proc-gpio.patch +++ /dev/null @@ -1,401 +0,0 @@ -Index: linux-2.6.15gum/arch/arm/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/arch/arm/Kconfig -+++ linux-2.6.15gum/arch/arm/Kconfig -@@ -316,6 +316,8 @@ config PCI_HOST_VIA82C505 - depends on PCI && ARCH_SHARK - default y - -+source "drivers/gpio/Kconfig" -+ - source "drivers/pci/Kconfig" - - source "drivers/pcmcia/Kconfig" -Index: linux-2.6.15gum/drivers/Makefile -=================================================================== ---- linux-2.6.15gum.orig/drivers/Makefile -+++ linux-2.6.15gum/drivers/Makefile -@@ -70,3 +70,4 @@ obj-$(CONFIG_SGI_IOC4) += sn/ - obj-y += firmware/ - obj-$(CONFIG_CRYPTO) += crypto/ - obj-$(CONFIG_SUPERH) += sh/ -+obj-$(CONFIG_PROC_GPIO) += gpio/ -Index: linux-2.6.15gum/drivers/gpio/Kconfig -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/drivers/gpio/Kconfig -@@ -0,0 +1,6 @@ -+config PROC_GPIO -+ tristate "GPIO /proc interface" -+ depends on PXA25x -+ help -+ This enables an interface under /proc/gpio which allows reading or setting -+ of any GPIO. Currently only reading is supported. -Index: linux-2.6.15gum/drivers/gpio/Makefile -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/drivers/gpio/Makefile -@@ -0,0 +1,3 @@ -+# Expose GPIOs under /proc -+obj-$(CONFIG_PROC_GPIO) += proc_gpio.o -+ -Index: linux-2.6.15gum/drivers/gpio/proc_gpio.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/drivers/gpio/proc_gpio.c -@@ -0,0 +1,355 @@ -+/* -+ * -+ * PXA25x GPIOs exposed under /proc for reading and writing -+ * They will show up under /proc/gpio/NN -+ * -+ * Based on patch 1773/1 in the arm kernel patch repository at arm.linux.co.uk -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+static struct proc_dir_entry *proc_gpio_parent; -+static struct proc_dir_entry *proc_gpios[85]; -+ -+typedef struct -+{ -+ int gpio; -+ char name[32]; -+} gpio_summary_type; -+ -+static gpio_summary_type gpio_summaries[85] = -+{ -+ { 0, "GPIO0" }, -+ { 1, "GPIO1" }, -+ { 2, "GPIO2" }, -+ { 3, "GPIO3" }, -+ { 4, "GPIO4" }, -+ { 5, "GPIO5" }, -+ { 6, "GPIO6" }, -+ { 7, "GPIO7" }, -+ { 8, "GPIO8" }, -+ { 9, "GPIO9" }, -+ { 10, "GPIO10" }, -+ { 11, "GPIO11" }, -+ { 12, "GPIO12" }, -+ { 13, "GPIO13" }, -+ { 14, "GPIO14" }, -+ { 15, "GPIO15" }, -+ { 16, "GPIO16" }, -+ { 17, "GPIO17" }, -+ { 18, "GPIO18" }, -+ { 19, "GPIO19" }, -+ { 20, "GPIO20" }, -+ { 21, "GPIO21" }, -+ { 22, "GPIO22" }, -+ { 23, "GPIO23" }, -+ { 24, "GPIO24" }, -+ { 25, "GPIO25" }, -+ { 26, "GPIO26" }, -+ { 27, "GPIO27" }, -+ { 28, "GPIO28" }, -+ { 29, "GPIO29" }, -+ { 30, "GPIO30" }, -+ { 31, "GPIO31" }, -+ { 32, "GPIO32" }, -+ { 33, "GPIO33" }, -+ { 34, "GPIO34" }, -+ { 35, "GPIO35" }, -+ { 36, "GPIO36" }, -+ { 37, "GPIO37" }, -+ { 38, "GPIO38" }, -+ { 39, "GPIO39" }, -+ { 40, "GPIO40" }, -+ { 41, "GPIO41" }, -+ { 42, "GPIO42" }, -+ { 43, "GPIO43" }, -+ { 44, "GPIO44" }, -+ { 45, "GPIO45" }, -+ { 46, "GPIO46" }, -+ { 47, "GPIO47" }, -+ { 48, "GPIO48" }, -+ { 49, "GPIO49" }, -+ { 50, "GPIO50" }, -+ { 51, "GPIO51" }, -+ { 52, "GPIO52" }, -+ { 53, "GPIO53" }, -+ { 54, "GPIO54" }, -+ { 55, "GPIO55" }, -+ { 56, "GPIO56" }, -+ { 57, "GPIO57" }, -+ { 58, "GPIO58" }, -+ { 59, "GPIO59" }, -+ { 60, "GPIO60" }, -+ { 61, "GPIO61" }, -+ { 62, "GPIO62" }, -+ { 63, "GPIO63" }, -+ { 64, "GPIO64" }, -+ { 65, "GPIO65" }, -+ { 66, "GPIO66" }, -+ { 67, "GPIO67" }, -+ { 68, "GPIO68" }, -+ { 69, "GPIO69" }, -+ { 70, "GPIO70" }, -+ { 71, "GPIO71" }, -+ { 72, "GPIO72" }, -+ { 73, "GPIO73" }, -+ { 74, "GPIO74" }, -+ { 75, "GPIO75" }, -+ { 76, "GPIO76" }, -+ { 77, "GPIO77" }, -+ { 78, "GPIO78" }, -+ { 79, "GPIO79" }, -+ { 80, "GPIO80" }, -+ { 81, "GPIO81" }, -+ { 82, "GPIO82" }, -+ { 83, "GPIO83" }, -+ { 84, "GPIO84" }, -+}; -+ -+static int proc_gpio_write(struct file *file, const char __user *buf, -+ unsigned long count, void *data) -+{ -+ char *cur, lbuf[count + 1]; -+ gpio_summary_type *summary = data; -+ u32 altfn, direction, setclear, gafr; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ memset(lbuf, 0, count + 1); -+ -+ if (copy_from_user(lbuf, buf, count)) -+ return -EFAULT; -+ -+ cur = lbuf; -+ -+ // Initialize to current state -+ altfn = ((GAFR(summary->gpio) >> ((summary->gpio & 0x0f) << 0x01)) & 0x03); -+ direction = GPDR(summary->gpio) & GPIO_bit(summary->gpio); -+ setclear = GPLR(summary->gpio) & GPIO_bit(summary->gpio); -+ while(1) -+ { -+ // We accept options: {GPIO|AF1|AF2|AF3}, {set|clear}, {in|out} -+ // Anything else is an error -+ while(cur[0] && (isspace(cur[0]) || ispunct(cur[0]))) cur = &(cur[1]); -+ -+ if('\0' == cur[0]) break; -+ -+ // Ok, so now we're pointing at the start of something -+ switch(cur[0]) -+ { -+ case 'G': -+ // Check that next is "PIO" -- '\0' will cause safe short-circuit if end of buf -+ if(!(cur[1] == 'P' && cur[2] == 'I' && cur[3] == 'O')) goto parse_error; -+ // Ok, so set this GPIO to GPIO (non-ALT) function -+ altfn = 0; -+ cur = &(cur[4]); -+ break; -+ case 'A': -+ if(!(cur[1] == 'F' && cur[2] >= '1' && cur[2] <= '3')) goto parse_error; -+ altfn = cur[2] - '0'; -+ cur = &(cur[3]); -+ break; -+ case 's': -+ if(!(cur[1] == 'e' && cur[2] == 't')) goto parse_error; -+ setclear = 1; -+ cur = &(cur[3]); -+ break; -+ case 'c': -+ if(!(cur[1] == 'l' && cur[2] == 'e' && cur[3] == 'a' && cur[4] == 'r')) goto parse_error; -+ setclear = 0; -+ cur = &(cur[5]); -+ break; -+ case 'i': -+ if(!(cur[1] == 'n')) goto parse_error; -+ direction = 0; -+ cur = &(cur[2]); -+ break; -+ case 'o': -+ if(!(cur[1] == 'u' && cur[2] == 't')) goto parse_error; -+ direction = 1; -+ cur = &(cur[3]); -+ break; -+ default: goto parse_error; -+ } -+ } -+ // Ok, now set gpio mode and value -+ if(direction) -+ GPDR(summary->gpio) |= GPIO_bit(summary->gpio); -+ else -+ GPDR(summary->gpio) &= ~GPIO_bit(summary->gpio); -+ -+ gafr = GAFR(summary->gpio) & ~(0x3 << (((summary->gpio) & 0xf)*2)); -+ GAFR(summary->gpio) = gafr | (altfn << (((summary->gpio) & 0xf)*2)); -+ -+ if(direction && !altfn) -+ { -+ if(setclear) GPSR(summary->gpio) = GPIO_bit(summary->gpio); -+ else GPCR(summary->gpio) = GPIO_bit(summary->gpio); -+ } -+ -+ printk(KERN_INFO "Set (%s,%s,%s) via /proc/gpio/%s\n",altfn ? (altfn == 1 ? "AF1" : (altfn == 2 ? "AF2" : "AF3")) : "GPIO", -+ direction ? "out" : "in", -+ setclear ? "set" : "clear", -+ summary->name); -+ -+ return count; -+ -+parse_error: -+ printk(KERN_CRIT "Parse error: Expect \"[GPIO|AF1|AF2|AF3]|[set|clear]|[in|out] ...\"\n"); -+ return -EINVAL; -+} -+ -+static int proc_gpio_read(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ char *p = page; -+ gpio_summary_type *summary = data; -+ int len, i, af; -+ i = summary->gpio; -+ -+ p += sprintf(p, "%d\t%s\t%s\t%s\n", i, -+ (af = ((GAFR(i) >> ((i & 0x0f) << 0x01)) & 0x03)) ? (af == 1 ? "AF1" : (af == 2 ? "AF2" : "AF3")) : "GPIO", -+ (GPDR(i) & GPIO_bit(i)) ? "out" : "in", -+ (GPLR(i) & GPIO_bit(i)) ? "set" : "clear"); -+ -+ len = (p - page) - off; -+ -+ if(len < 0) -+ { -+ len = 0; -+ } -+ -+ *eof = (len <= count) ? 1 : 0; -+ *start = page + off; -+ -+ return len; -+} -+ -+static const char const *GAFR_DESC[] = { "GAFR0_L", "GAFR0_U", "GAFR1_L", "GAFR1_U", "GAFR2_L", "GAFR2_U" }; -+ -+static int proc_gafr_read(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ char *p = page; -+ int i, len; -+ -+ for(i=0; i<=5; i++) -+ { -+ p += sprintf(p, "%s: %08x\n", GAFR_DESC[i], GAFR(i*16)); -+ } -+ -+ len = (p - page) - off; -+ -+ if(len < 0) -+ { -+ len = 0; -+ } -+ -+ *eof = (len <= count) ? 1 : 0; -+ *start = page + off; -+ -+ return len; -+} -+ -+static int proc_gpdr_read(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ char *p = page; -+ int i, len; -+ -+ for(i=0; i<=2; i++) -+ { -+ p += sprintf(p, "GPDR%d: %08x\n", i, GPDR(i * 32)); -+ } -+ -+ len = (p - page) - off; -+ -+ if(len < 0) -+ { -+ len = 0; -+ } -+ -+ *eof = (len <= count) ? 1 : 0; -+ *start = page + off; -+ -+ return len; -+} -+ -+static int proc_gplr_read(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ char *p = page; -+ int i, len; -+ -+ for(i=0; i<=2; i++) -+ { -+ p += sprintf(p, "GPLR%d: %08x\n", i, GPLR(i * 32)); -+ } -+ -+ len = (p - page) - off; -+ -+ if(len < 0) -+ { -+ len = 0; -+ } -+ -+ *eof = (len <= count) ? 1 : 0; -+ *start = page + off; -+ -+ return len; -+} -+ -+static int __init gpio_init(void) -+{ -+ int i; -+ -+ proc_gpio_parent = create_proc_entry("gpio", S_IFDIR | S_IRUGO | S_IXUGO, NULL); -+ if(!proc_gpio_parent) return 0; -+ -+ for(i=0; i < 85; i++) -+ { -+ proc_gpios[i] = create_proc_entry(gpio_summaries[i].name, 0644, proc_gpio_parent); -+ if(proc_gpios[i]) -+ { -+ proc_gpios[i]->data = &gpio_summaries[i]; -+ proc_gpios[i]->read_proc = proc_gpio_read; -+ proc_gpios[i]->write_proc = proc_gpio_write; -+ } -+ } -+ -+ create_proc_read_entry("GAFR", 0444, proc_gpio_parent, proc_gafr_read, NULL); -+ create_proc_read_entry("GPDR", 0444, proc_gpio_parent, proc_gpdr_read, NULL); -+ create_proc_read_entry("GPLR", 0444, proc_gpio_parent, proc_gplr_read, NULL); -+ -+ return 0; -+} -+ -+static void gpio_exit(void) -+{ -+ int i; -+ -+ remove_proc_entry("GAFR", proc_gpio_parent); -+ remove_proc_entry("GPDR", proc_gpio_parent); -+ remove_proc_entry("GPLR", proc_gpio_parent); -+ -+ for(i=0; i < 85; i++) -+ { -+ if(proc_gpios[i]) remove_proc_entry(gpio_summaries[i].name, proc_gpio_parent); -+ } -+ if(proc_gpio_parent) remove_proc_entry("gpio", NULL); -+} -+ -+module_init(gpio_init); -+module_exit(gpio_exit); -+MODULE_LICENSE("GPL"); diff --git a/recipes/linux/linux-gumstix-2.6.15/pxa255-gpio-count-bugfix.patch b/recipes/linux/linux-gumstix-2.6.15/pxa255-gpio-count-bugfix.patch deleted file mode 100644 index 655f6c577d..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/pxa255-gpio-count-bugfix.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: linux-2.6.15gum/include/asm-arm/arch-pxa/irqs.h -=================================================================== ---- linux-2.6.15gum.orig/include/asm-arm/arch-pxa/irqs.h -+++ linux-2.6.15gum/include/asm-arm/arch-pxa/irqs.h -@@ -74,7 +74,7 @@ - #define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i)) - - #if defined(CONFIG_PXA25x) --#define PXA_LAST_GPIO 80 -+#define PXA_LAST_GPIO 84 - #elif defined(CONFIG_PXA27x) - #define PXA_LAST_GPIO 127 - #endif diff --git a/recipes/linux/linux-gumstix-2.6.15/pxa2xx_udc.patch b/recipes/linux/linux-gumstix-2.6.15/pxa2xx_udc.patch deleted file mode 100644 index 1e17679907..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/pxa2xx_udc.patch +++ /dev/null @@ -1,57 +0,0 @@ -Index: linux-2.6.15gum/drivers/usb/gadget/pxa2xx_udc.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/usb/gadget/pxa2xx_udc.c -+++ linux-2.6.15gum/drivers/usb/gadget/pxa2xx_udc.c -@@ -101,6 +101,10 @@ static const char ep0name [] = "ep0"; - - #endif - -+#ifdef CONFIG_ARCH_GUMSTIX -+#undef CONFIG_USB_PXA2XX_SMALL -+#endif -+ - #include "pxa2xx_udc.h" - - -@@ -2494,6 +2498,41 @@ static int __init pxa2xx_udc_probe(struc - } - #endif - -+ /* Reset UDCCS register to be able to recover from whatever -+ * state UDC was previously in. */ -+ *dev->ep[ 2].reg_udccs = UDCCS_BO_RPC | UDCCS_BO_SST; -+#ifndef CONFIG_USB_PXA2XX_SMALL -+ *dev->ep[ 7].reg_udccs = UDCCS_BO_RPC | UDCCS_BO_SST; -+ *dev->ep[12].reg_udccs = UDCCS_BO_RPC | UDCCS_BO_SST; -+#endif -+ -+ *dev->ep[ 1].reg_udccs = UDCCS_BI_TPC | UDCCS_BI_FTF | -+ UDCCS_BI_TUR | UDCCS_BI_SST | UDCCS_BI_TSP; -+#ifndef CONFIG_USB_PXA2XX_SMALL -+ *dev->ep[ 6].reg_udccs = UDCCS_BI_TPC | UDCCS_BI_FTF | -+ UDCCS_BI_TUR | UDCCS_BI_SST | UDCCS_BI_TSP; -+ *dev->ep[11].reg_udccs = UDCCS_BI_TPC | UDCCS_BI_FTF | -+ UDCCS_BI_TUR | UDCCS_BI_SST | UDCCS_BI_TSP; -+ -+ *dev->ep[ 3].reg_udccs = UDCCS_II_TPC | UDCCS_II_FTF | -+ UDCCS_II_TUR | UDCCS_II_TSP; -+ *dev->ep[ 8].reg_udccs = UDCCS_II_TPC | UDCCS_II_FTF | -+ UDCCS_II_TUR | UDCCS_II_TSP; -+ *dev->ep[13].reg_udccs = UDCCS_II_TPC | UDCCS_II_FTF | -+ UDCCS_II_TUR | UDCCS_II_TSP; -+ -+ *dev->ep[ 4].reg_udccs = UDCCS_IO_RPC | UDCCS_IO_ROF; -+ *dev->ep[ 9].reg_udccs = UDCCS_IO_RPC | UDCCS_IO_ROF; -+ *dev->ep[11].reg_udccs = UDCCS_IO_RPC | UDCCS_IO_ROF; -+ -+ *dev->ep[ 5].reg_udccs = UDCCS_INT_TPC | UDCCS_INT_FTF | -+ UDCCS_INT_TUR | UDCCS_INT_SST; -+ *dev->ep[10].reg_udccs = UDCCS_INT_TPC | UDCCS_INT_FTF | -+ UDCCS_INT_TUR | UDCCS_INT_SST; -+ *dev->ep[15].reg_udccs = UDCCS_INT_TPC | UDCCS_INT_FTF | -+ UDCCS_INT_TUR | UDCCS_INT_SST; -+#endif -+ - /* other non-static parts of init */ - dev->dev = &pdev->dev; - dev->mach = pdev->dev.platform_data; diff --git a/recipes/linux/linux-gumstix-2.6.15/rmk-2022-2-rtctime-sa110-pxa255-driver.patch b/recipes/linux/linux-gumstix-2.6.15/rmk-2022-2-rtctime-sa110-pxa255-driver.patch deleted file mode 100644 index 87f4ebdc38..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/rmk-2022-2-rtctime-sa110-pxa255-driver.patch +++ /dev/null @@ -1,329 +0,0 @@ -Index: linux-2.6.15gum/drivers/char/sa1100-rtc.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/drivers/char/sa1100-rtc.c -@@ -0,0 +1,297 @@ -+/* -+ * Real Time Clock interface for Linux on StrongARM SA1100 -+ * -+ * Copyright (c) 2000 Nils Faerber -+ * -+ * Based on rtc.c by Paul Gortmaker -+ * Date/time conversion routines taken from arch/arm/kernel/time.c -+ * by Linus Torvalds and Russel King -+ * and the GNU C Library -+ * ( ... I love the GPL ... just take what you need! ;) -+ * -+ * 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. -+ * -+ * 1.00 2001-06-08 Nicolas Pitre -+ * - added periodic timer capability using OSMR1 -+ * - flag compatibility with other RTC chips -+ * - permission checks for ioctls -+ * - major cleanup, partial rewrite -+ * -+ * 0.03 2001-03-07 CIH -+ * - Modify the bug setups RTC clock. -+ * -+ * 0.02 2001-02-27 Nils Faerber -+ * - removed mktime(), added alarm irq clear -+ * -+ * 0.01 2000-10-01 Nils Faerber -+ * - initial release -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_ARCH_PXA -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+ -+#define TIMER_FREQ 3686400 -+ -+#define RTC_DEF_DIVIDER 32768 - 1 -+#define RTC_DEF_TRIM 0 -+ -+/* Those are the bits from a classic RTC we want to mimic */ -+#define RTC_IRQF 0x80 /* any of the following 3 is active */ -+#define RTC_PF 0x40 -+#define RTC_AF 0x20 -+#define RTC_UF 0x10 -+ -+static unsigned long rtc_freq = 1024; -+static struct rtc_time rtc_alarm = { -+ .tm_year = 0, -+ .tm_mon = 0, -+ .tm_mday = 0, -+ .tm_hour = 0, -+ .tm_mon = 0, -+ .tm_sec = 0, -+}; -+ -+extern spinlock_t rtc_lock; -+ -+static int rtc_update_alarm(struct rtc_time *alrm) -+{ -+ struct rtc_time alarm_tm, now_tm; -+ unsigned long now, time; -+ int ret; -+ -+ printk("Updating alarm\n"); -+ do { -+ now = RCNR; -+ rtc_time_to_tm(now, &now_tm); -+ rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); -+ ret = rtc_tm_to_time(&alarm_tm, &time); -+ if (ret != 0) -+ break; -+ -+ RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); -+ RTAR = time; -+ } while (now != RCNR); -+ printk("set RTAR to %lx, now is %lx\n", time, now); -+ -+ return ret; -+} -+ -+static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ unsigned int rtsr; -+ unsigned long events = 0; -+ -+ spin_lock(&rtc_lock); -+ -+ rtsr = RTSR; -+ /* clear interrupt sources */ -+ RTSR = 0; -+ RTSR = (RTSR_AL|RTSR_HZ) & (rtsr >> 2); -+ -+ printk(KERN_CRIT "rtc_interrupt: rtsr = %x\n", rtsr); -+ -+ /* clear alarm interrupt if it has occurred */ -+ if (rtsr & RTSR_AL) { -+ printk(KERN_CRIT "ALARM INTRRUPT\n"); -+ rtsr &= ~RTSR_ALE; -+ } -+ RTSR = rtsr & (RTSR_ALE|RTSR_HZE); -+ -+ /* update irq data & counter */ -+ if (rtsr & RTSR_AL) -+ events |= (RTC_AF|RTC_IRQF); -+ if (rtsr & RTSR_HZ) -+ events |= (RTC_UF|RTC_IRQF); -+ -+ rtc_update(1, events); -+ -+ if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) -+ rtc_update_alarm(&rtc_alarm); -+ -+ spin_unlock(&rtc_lock); -+ -+ return IRQ_HANDLED; -+} -+ -+ -+static int sa1100_rtc_open(void) -+{ -+ int ret; -+ -+ ret = request_irq(IRQ_RTC1Hz, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL); -+ if (ret) { -+ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz); -+ goto fail_ui; -+ } -+ ret = request_irq(IRQ_RTCAlrm, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL); -+ if (ret) { -+ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm); -+ goto fail_ai; -+ } -+ return 0; -+ -+ fail_ai: -+ free_irq(IRQ_RTC1Hz, NULL); -+ fail_ui: -+ return ret; -+} -+ -+static void sa1100_rtc_release(void) -+{ -+ spin_lock_irq (&rtc_lock); -+ RTSR = 0; -+ OIER &= ~OIER_E1; -+ OSSR = OSSR_M1; -+ spin_unlock_irq (&rtc_lock); -+ -+ free_irq(IRQ_RTCAlrm, NULL); -+ free_irq(IRQ_RTC1Hz, NULL); -+} -+ -+static int sa1100_rtc_ioctl(unsigned int cmd, unsigned long arg) -+{ -+ switch (cmd) { -+ case RTC_AIE_OFF: -+ spin_lock_irq(&rtc_lock); -+ RTSR &= ~RTSR_ALE; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_AIE_ON: -+ spin_lock_irq(&rtc_lock); -+ RTSR |= RTSR_ALE; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_UIE_OFF: -+ spin_lock_irq(&rtc_lock); -+ RTSR &= ~RTSR_HZE; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ case RTC_UIE_ON: -+ spin_lock_irq(&rtc_lock); -+ RTSR |= RTSR_HZE; -+ spin_unlock_irq(&rtc_lock); -+ return 0; -+ } -+ return -EINVAL; -+} -+ -+static void sa1100_rtc_read_time(struct rtc_time *tm) -+{ -+ rtc_time_to_tm(RCNR, tm); -+} -+ -+static int sa1100_rtc_set_time(struct rtc_time *tm) -+{ -+ unsigned long time; -+ int ret; -+ -+ ret = rtc_tm_to_time(tm, &time); -+ if (ret == 0) -+ RCNR = time; -+ return ret; -+} -+ -+static void sa1100_rtc_read_alarm(struct rtc_wkalrm *alrm) -+{ -+ memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); -+ alrm->pending = RTSR & RTSR_AL ? 1 : 0; -+} -+ -+static int sa1100_rtc_set_alarm(struct rtc_wkalrm *alrm) -+{ -+ int ret; -+ -+ printk("sa1100_rtc_set_alarm\n"); -+ -+ spin_lock_irq(&rtc_lock); -+ ret = rtc_update_alarm(&alrm->time); -+ if (ret == 0) { -+ memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time)); -+ -+ if (alrm->enabled) -+ enable_irq_wake(IRQ_RTCAlrm); -+ else -+ disable_irq_wake(IRQ_RTCAlrm); -+ } -+ spin_unlock_irq(&rtc_lock); -+ -+ return ret; -+} -+ -+static int sa1100_rtc_proc(char *buf) -+{ -+ char *p = buf; -+ -+ p += sprintf(p, "trim/divider\t: 0x%08x\n", RTTR); -+ p += sprintf(p, "alarm_IRQ\t: %s\n", (RTSR & RTSR_ALE) ? "yes" : "no" ); -+ p += sprintf(p, "update_IRQ\t: %s\n", (RTSR & RTSR_HZE) ? "yes" : "no"); -+ p += sprintf(p, "periodic_IRQ\t: %s\n", (OIER & OIER_E1) ? "yes" : "no"); -+ p += sprintf(p, "periodic_freq\t: %ld\n", rtc_freq); -+ -+ return p - buf; -+} -+ -+static struct rtc_ops sa1100_rtc_ops = { -+ .owner = THIS_MODULE, -+ .open = sa1100_rtc_open, -+ .release = sa1100_rtc_release, -+ .ioctl = sa1100_rtc_ioctl, -+ -+ .read_time = sa1100_rtc_read_time, -+ .set_time = sa1100_rtc_set_time, -+ .read_alarm = sa1100_rtc_read_alarm, -+ .set_alarm = sa1100_rtc_set_alarm, -+ .proc = sa1100_rtc_proc, -+}; -+ -+static int __init rtc_init(void) -+{ -+ /* -+ * According to the manual we should be able to let RTTR be zero -+ * and then a default diviser for a 32.768KHz clock is used. -+ * Apparently this doesn't work, at least for my SA1110 rev 5. -+ * If the clock divider is uninitialized then reset it to the -+ * default value to get the 1Hz clock. -+ */ -+ if (RTTR == 0) { -+ RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); -+ printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n"); -+ /* The current RTC value probably doesn't make sense either */ -+ RCNR = 0; -+ } -+ -+ register_rtc(&sa1100_rtc_ops); -+ -+ return 0; -+} -+ -+static void __exit rtc_exit(void) -+{ -+ unregister_rtc(&sa1100_rtc_ops); -+} -+ -+module_init(rtc_init); -+module_exit(rtc_exit); -+ -+MODULE_AUTHOR("Nils Faerber "); -+MODULE_DESCRIPTION("SA1100 Realtime Clock Driver (RTC)"); -+MODULE_LICENSE("GPL"); /* so says the header */ -Index: linux-2.6.15gum/drivers/char/Makefile -=================================================================== ---- linux-2.6.15gum.orig/drivers/char/Makefile -+++ linux-2.6.15gum/drivers/char/Makefile -@@ -60,6 +60,7 @@ obj-$(CONFIG_RTC) += rtc.o - obj-$(CONFIG_HPET) += hpet.o - obj-$(CONFIG_GEN_RTC) += genrtc.o - obj-$(CONFIG_EFI_RTC) += efirtc.o -+obj-$(CONFIG_SA1100_RTC) += sa1100-rtc.o - obj-$(CONFIG_SGI_DS1286) += ds1286.o - obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o - obj-$(CONFIG_DS1302) += ds1302.o -Index: linux-2.6.15gum/drivers/char/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/drivers/char/Kconfig -+++ linux-2.6.15gum/drivers/char/Kconfig -@@ -790,6 +790,10 @@ config COBALT_LCD - This option enables support for the LCD display and buttons found - on Cobalt systems through a misc device. - -+config SA1100_RTC -+ tristate "SA1100/PXA2xx Real Time Clock" -+ depends on ARCH_SA1100 || ARCH_PXA -+ - config DTLK - tristate "Double Talk PC internal speech card support" - help diff --git a/recipes/linux/linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch b/recipes/linux/linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch deleted file mode 100644 index d7d5fda08c..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c ---- a/drivers/mmc/pxamci.c -+++ b/drivers/mmc/pxamci.c -@@ -71,11 +71,6 @@ struct pxamci_host { - unsigned int dma_dir; - }; - --static inline unsigned int ns_to_clocks(unsigned int ns) --{ -- return (ns * (CLOCKRATE / 1000000) + 999) / 1000; --} -- - static void pxamci_stop_clock(struct pxamci_host *host) - { - if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { -@@ -119,6 +114,7 @@ static void pxamci_disable_irq(struct px - static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) - { - unsigned int nob = data->blocks; -+ unsigned long long clks; - unsigned int timeout; - u32 dcmd; - int i; -@@ -131,7 +127,9 @@ static void pxamci_setup_data(struct pxa - writel(nob, host->base + MMC_NOB); - writel(1 << data->blksz_bits, host->base + MMC_BLKLEN); - -- timeout = ns_to_clocks(data->timeout_ns) + data->timeout_clks; -+ clks = (unsigned long long)data->timeout_ns * CLOCKRATE; -+ do_div(clks, 1000000000UL); -+ timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt); - writel((timeout + 255) / 256, host->base + MMC_RDTO); - - if (data->flags & MMC_DATA_READ) { diff --git a/recipes/linux/linux-gumstix-2.6.15/serial-ether-addr.patch b/recipes/linux/linux-gumstix-2.6.15/serial-ether-addr.patch deleted file mode 100644 index 88442655e4..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/serial-ether-addr.patch +++ /dev/null @@ -1,46 +0,0 @@ -Index: linux-2.6.15gum/drivers/usb/gadget/ether.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/usb/gadget/ether.c -+++ linux-2.6.15gum/drivers/usb/gadget/ether.c -@@ -2153,6 +2153,29 @@ static u8 __init nibble (unsigned char c - return 0; - } - -+/** -+ * gen_serial_ether_addr - Generate software assigned Ethernet address -+ * based on the system_serial number -+ * @addr: Pointer to a six-byte array containing the Ethernet address -+ * -+ * Generate an Ethernet address (MAC) that is not multicast -+ * and has the local assigned bit set, keyed on the system_serial -+ */ -+static inline void gen_serial_ether_addr(u8 *addr) -+{ -+ static u8 ether_serial_digit = 1; -+ addr [0] = system_serial_high >> 8; -+ addr [1] = system_serial_high; -+ addr [2] = system_serial_low >> 24; -+ addr [3] = system_serial_low >> 16; -+ addr [4] = system_serial_low >> 8; -+ addr [5] = (system_serial_low & 0xc0) | /* top bits are from system serial */ -+ (2 << 4) | /* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */ -+ ((ether_serial_digit++) & 0x0f); /* 15 possible interfaces of each type */ -+ addr [0] &= 0xfe; /* clear multicast bit */ -+ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ -+} -+ - static void __init get_ether_addr (const char *str, u8 *dev_addr) - { - if (str) { -@@ -2170,7 +2193,10 @@ static void __init get_ether_addr (const - if (is_valid_ether_addr (dev_addr)) - return; - } -- random_ether_addr(dev_addr); -+ if(system_serial_high | system_serial_low) -+ gen_serial_ether_addr(dev_addr); -+ else -+ random_ether_addr(dev_addr); - } - - static int __init diff --git a/recipes/linux/linux-gumstix-2.6.15/smc-ether-addr.patch b/recipes/linux/linux-gumstix-2.6.15/smc-ether-addr.patch deleted file mode 100644 index 920aa53ad8..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/smc-ether-addr.patch +++ /dev/null @@ -1,53 +0,0 @@ -Index: linux-2.6.15gum/drivers/net/smc91x.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/net/smc91x.c -+++ linux-2.6.15gum/drivers/net/smc91x.c -@@ -1818,6 +1818,30 @@ static int __init smc_findirq(void __iom - return probe_irq_off(cookie); - } - -+/** -+ * gen_serial_ether_addr - Generate software assigned Ethernet address -+ * based on the system_serial number -+ * @addr: Pointer to a six-byte array containing the Ethernet address -+ * -+ * Generate an Ethernet address (MAC) that is not multicast -+ * and has the local assigned bit set, keyed on the system_serial -+ */ -+static inline void gen_serial_ether_addr(u8 *addr) -+{ -+ static u8 ether_serial_digit = 1; -+ addr [0] = system_serial_high >> 8; -+ addr [1] = system_serial_high; -+ addr [2] = system_serial_low >> 24; -+ addr [3] = system_serial_low >> 16; -+ addr [4] = system_serial_low >> 8; -+ addr [5] = (system_serial_low & 0xc0) | /* top bits are from system serial */ -+ (1 << 4) | /* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */ -+ ((ether_serial_digit++) & 0x0f); /* 15 possible interfaces of each type */ -+ addr [0] &= 0xfe; /* clear multicast bit */ -+ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ -+} -+ -+ - /* - * Function: smc_probe(unsigned long ioaddr) - * -@@ -2036,15 +2060,13 @@ static int __init smc_probe(struct net_d - THROTTLE_TX_PKTS ? " [throttle_tx]" : ""); - - if (!is_valid_ether_addr(dev->dev_addr)) { -- printk("%s: Invalid ethernet MAC address. Please " -- "set using ifconfig\n", dev->name); -- } else { -+ gen_serial_ether_addr(dev->dev_addr); -+ } - /* Print the Ethernet address */ - printk("%s: Ethernet addr: ", dev->name); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x\n", dev->dev_addr[5]); -- } - - if (lp->phy_type == 0) { - PRINTK("%s: No PHY found\n", dev->name); diff --git a/recipes/linux/linux-gumstix-2.6.15/ucb1400-ac97-audio.patch b/recipes/linux/linux-gumstix-2.6.15/ucb1400-ac97-audio.patch deleted file mode 100644 index 32a0af5a05..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/ucb1400-ac97-audio.patch +++ /dev/null @@ -1,84 +0,0 @@ -Index: linux-2.6.15gum/sound/pci/ac97/ac97_codec.c -=================================================================== ---- linux-2.6.15gum.orig/sound/pci/ac97/ac97_codec.c -+++ linux-2.6.15gum/sound/pci/ac97/ac97_codec.c -@@ -150,7 +150,7 @@ static const ac97_codec_id_t snd_ac97_co - { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk - { 0x4e534331, 0xffffffff, "LM4549", NULL, NULL }, - { 0x4e534350, 0xffffffff, "LM4550", NULL, NULL }, --{ 0x50534304, 0xffffffff, "UCB1400", NULL, NULL }, -+{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL, AC97_HAS_NO_STD_PCM }, - { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, - { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, - { 0x54524106, 0xffffffff, "TR28026", NULL, NULL }, -Index: linux-2.6.15gum/sound/pci/ac97/ac97_patch.c -=================================================================== ---- linux-2.6.15gum.orig/sound/pci/ac97/ac97_patch.c -+++ linux-2.6.15gum/sound/pci/ac97/ac97_patch.c -@@ -375,6 +375,56 @@ int patch_yamaha_ymf753(ac97_t * ac97) - } - - /* -+ * UCB1400 codec -+ */ -+ -+#define AC97_UCB1400_FCSR1 0x6a -+#define AC97_UCB1400_FCSR2 0x6c -+ -+static const snd_kcontrol_new_t ucb1400_snd_ac97_controls[] = { -+ AC97_SINGLE("Tone Control - Bass", AC97_UCB1400_FCSR1, 11, 4, 0), -+ AC97_SINGLE("Tone Control - Treble", AC97_UCB1400_FCSR1, 9, 2, 0), -+ AC97_SINGLE("Headphone Playback Switch", AC97_UCB1400_FCSR1, 6, 1, 0), -+ AC97_SINGLE("De-emphasis", AC97_UCB1400_FCSR1, 5, 1, 0), -+ AC97_SINGLE("DC Filter", AC97_UCB1400_FCSR1, 4, 1, 0), -+ AC97_SINGLE("Hi-pass Filter", AC97_UCB1400_FCSR1, 3, 1, 0), -+ AC97_SINGLE("ADC Filter", AC97_UCB1400_FCSR2, 12, 1, 0), -+}; -+ -+int patch_ucb1400(ac97_t * ac97) -+{ -+ int err, i; -+ -+ for(i = 0; i < ARRAY_SIZE(ucb1400_snd_ac97_controls); i++) { -+ if((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&ucb1400_snd_ac97_controls[i], ac97))) < 0) -+ return err; -+ } -+ -+ snd_ac97_write_cache(ac97, AC97_UCB1400_FCSR1, -+ (0 << 11) | // 0 base boost -+ (0 << 9) | // 0 treble boost -+ (0 << 7) | // Mode = flat -+ (1 << 6) | // Headphones enable -+ (0 << 5) | // De-emphasis disabled -+ (1 << 4) | // DC filter enabled -+ (1 << 3) | // Hi-pass filter enabled -+ (0 << 2) | // disable interrupt signalling via GPIO_INT -+ (1 << 0) // clear ADC overflow status if set -+ ); -+ -+ snd_ac97_write_cache(ac97, AC97_UCB1400_FCSR2, -+ (0 << 15) | // must be 0 -+ (0 << 13) | // must be 0 -+ (1 << 12) | // ADC filter enabled -+ (0 << 10) | // must be 0 -+ (0 << 4) | // Smart low power mode on neither Codec nor PLL -+ (0 << 0) // must be 0 -+ ); -+ -+ return 0; -+} -+ -+/* - * May 2, 2003 Liam Girdwood - * removed broken wolfson00 patch. - * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. -Index: linux-2.6.15gum/sound/pci/ac97/ac97_patch.h -=================================================================== ---- linux-2.6.15gum.orig/sound/pci/ac97/ac97_patch.h -+++ linux-2.6.15gum/sound/pci/ac97/ac97_patch.h -@@ -58,4 +58,5 @@ int patch_cm9780(ac97_t * ac97); - int patch_vt1616(ac97_t * ac97); - int patch_vt1617a(ac97_t * ac97); - int patch_it2646(ac97_t * ac97); -+int patch_ucb1400(ac97_t * ac97); - int mpatch_si3036(ac97_t * ac97); diff --git a/recipes/linux/linux-gumstix-2.6.15/ucb1400-touchscreen.patch b/recipes/linux/linux-gumstix-2.6.15/ucb1400-touchscreen.patch deleted file mode 100644 index cd7fe41661..0000000000 --- a/recipes/linux/linux-gumstix-2.6.15/ucb1400-touchscreen.patch +++ /dev/null @@ -1,704 +0,0 @@ -This patch is slightly adjusted from - -http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3073/1 -http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3074/2 -http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3075/2 - -in order to get it to apply cleanly to the released 2.6.15 codebase -and to put the Kconfig stuff in a more reasonable place in the tree. -Actually, I think Kconfig should probably separate the notion of the -touchscreen driver and the AC97-MCP layer thing; but that problem is -basically in the underlying mcp-based ucb1x00 driver layout in the -first place. -Index: linux-2.6.15gum/drivers/mfd/Makefile -=================================================================== ---- linux-2.6.15gum.orig/drivers/mfd/Makefile -+++ linux-2.6.15gum/drivers/mfd/Makefile -@@ -10,3 +10,6 @@ obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00- - ifeq ($(CONFIG_SA1100_ASSABET),y) - obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o - endif -+ -+obj-$(CONFIG_TOUCHSCREEN_UCB1400) += mcp-ac97.o ucb1x00-core.o ucb1x00-ts.o -+ -Index: linux-2.6.15gum/drivers/mfd/mcp-core.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/mfd/mcp-core.c -+++ linux-2.6.15gum/drivers/mfd/mcp-core.c -@@ -18,7 +18,6 @@ - #include - #include - --#include - #include - - #include "mcp.h" -@@ -206,6 +205,7 @@ struct mcp *mcp_host_alloc(struct device - mcp->attached_device.bus = &mcp_bus_type; - mcp->attached_device.dma_mask = parent->dma_mask; - mcp->attached_device.release = mcp_release; -+ mcp->dev = &mcp->attached_device; - } - return mcp; - } -Index: linux-2.6.15gum/drivers/mfd/mcp-sa11x0.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/mfd/mcp-sa11x0.c -+++ linux-2.6.15gum/drivers/mfd/mcp-sa11x0.c -@@ -31,8 +31,12 @@ - #include "mcp.h" - - struct mcp_sa11x0 { -- u32 mccr0; -- u32 mccr1; -+ u32 mccr0; -+ u32 mccr1; -+ dma_device_t dma_audio_rd; -+ dma_device_t dma_audio_wr; -+ dma_device_t dma_telco_rd; -+ dma_device_t dma_telco_wr; - }; - - #define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp)) -@@ -159,10 +163,10 @@ static int mcp_sa11x0_probe(struct platf - mcp->owner = THIS_MODULE; - mcp->ops = &mcp_sa11x0; - mcp->sclk_rate = data->sclk_rate; -- mcp->dma_audio_rd = DMA_Ser4MCP0Rd; -- mcp->dma_audio_wr = DMA_Ser4MCP0Wr; -- mcp->dma_telco_rd = DMA_Ser4MCP1Rd; -- mcp->dma_telco_wr = DMA_Ser4MCP1Wr; -+ priv(mcp)->dma_audio_rd = DMA_Ser4MCP0Rd; -+ priv(mcp)->dma_audio_wr = DMA_Ser4MCP0Wr; -+ priv(mcp)->dma_telco_rd = DMA_Ser4MCP1Rd; -+ priv(mcp)->dma_telco_wr = DMA_Ser4MCP1Wr; - - platform_set_drvdata(pdev, mcp); - -Index: linux-2.6.15gum/drivers/mfd/mcp.h -=================================================================== ---- linux-2.6.15gum.orig/drivers/mfd/mcp.h -+++ linux-2.6.15gum/drivers/mfd/mcp.h -@@ -19,11 +19,8 @@ struct mcp { - int use_count; - unsigned int sclk_rate; - unsigned int rw_timeout; -- dma_device_t dma_audio_rd; -- dma_device_t dma_audio_wr; -- dma_device_t dma_telco_rd; -- dma_device_t dma_telco_wr; - struct device attached_device; -+ struct device *dev; - }; - - struct mcp_ops { -Index: linux-2.6.15gum/drivers/mfd/ucb1x00-assabet.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/mfd/ucb1x00-assabet.c -+++ linux-2.6.15gum/drivers/mfd/ucb1x00-assabet.c -@@ -15,8 +15,6 @@ - #include - #include - --#include -- - #include "ucb1x00.h" - - #define UCB1X00_ATTR(name,input)\ -Index: linux-2.6.15gum/drivers/mfd/ucb1x00-core.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/mfd/ucb1x00-core.c -+++ linux-2.6.15gum/drivers/mfd/ucb1x00-core.c -@@ -23,14 +23,17 @@ - #include - #include - #include -+#include - #include - --#include --#include --#include -- - #include "ucb1x00.h" - -+#ifdef CONFIG_UCB1400 -+#define UCB_IS_1400(id) ((id) == UCB_ID_1400) -+#else -+#define UCB_IS_1400(id) (0) -+#endif -+ - static DECLARE_MUTEX(ucb1x00_sem); - static LIST_HEAD(ucb1x00_drivers); - static LIST_HEAD(ucb1x00_devices); -@@ -58,9 +61,9 @@ void ucb1x00_io_set_dir(struct ucb1x00 * - spin_lock_irqsave(&ucb->io_lock, flags); - ucb->io_dir |= out; - ucb->io_dir &= ~in; -+ spin_unlock_irqrestore(&ucb->io_lock, flags); - - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); -- spin_unlock_irqrestore(&ucb->io_lock, flags); - } - - /** -@@ -86,9 +89,9 @@ void ucb1x00_io_write(struct ucb1x00 *uc - spin_lock_irqsave(&ucb->io_lock, flags); - ucb->io_out |= set; - ucb->io_out &= ~clear; -+ spin_unlock_irqrestore(&ucb->io_lock, flags); - - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); -- spin_unlock_irqrestore(&ucb->io_lock, flags); - } - - /** -@@ -178,7 +181,7 @@ unsigned int ucb1x00_adc_read(struct ucb - schedule_timeout(1); - } - -- return UCB_ADC_DAT(val); -+ return UCB_IS_1400(ucb->id) ? (val & 0x3ff) : ((val & 0x7fe0) >> 5); - } - - /** -@@ -223,6 +226,47 @@ static irqreturn_t ucb1x00_irq(int irqnr - return IRQ_HANDLED; - } - -+/* -+ * A restriction with interrupts exists when using the ucb1400, as -+ * the codec read/write routines may sleep while waiting for codec -+ * access completion and uses semaphores for access control to the -+ * AC97 bus. A complete codec read cycle could take anywhere from -+ * 60 to 100uSec so we *definitely* don't want to spin inside the -+ * interrupt handler waiting for codec access. So, we handle the -+ * interrupt by scheduling a RT kernel thread to run in process -+ * context instead of interrupt context. -+ */ -+static int ucb1x00_thread(void *_ucb) -+{ -+ struct task_struct *tsk = current; -+ struct ucb1x00 *ucb = _ucb; -+ -+ tsk->policy = SCHED_FIFO; -+ tsk->rt_priority = 1; -+ -+ while (!kthread_should_stop()) { -+ wait_for_completion_interruptible(&ucb->irq_wait); -+ if (try_to_freeze()) -+ continue; -+ ucb1x00_irq(ucb->irq, ucb, NULL); -+ enable_irq(ucb->irq); -+ } -+ -+ ucb->irq_task = NULL; -+ return 0; -+} -+ -+static irqreturn_t ucb1x00_threaded_irq(int irqnr, void *devid, struct pt_regs *regs) -+{ -+ struct ucb1x00 *ucb = devid; -+ if (irqnr == ucb->irq) { -+ disable_irq(ucb->irq); -+ complete(&ucb->irq_wait); -+ return IRQ_HANDLED; -+ } -+ return IRQ_NONE; -+} -+ - /** - * ucb1x00_hook_irq - hook a UCB1x00 interrupt - * @ucb: UCB1x00 structure describing chip -@@ -276,18 +320,22 @@ void ucb1x00_enable_irq(struct ucb1x00 * - - if (idx < 16) { - spin_lock_irqsave(&ucb->lock, flags); -- -- ucb1x00_enable(ucb); -- if (edges & UCB_RISING) { -+ if (edges & UCB_RISING) - ucb->irq_ris_enbl |= 1 << idx; -- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); -- } -- if (edges & UCB_FALLING) { -+ if (edges & UCB_FALLING) - ucb->irq_fal_enbl |= 1 << idx; -- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); -- } -- ucb1x00_disable(ucb); - spin_unlock_irqrestore(&ucb->lock, flags); -+ -+ ucb1x00_enable(ucb); -+ -+ /* This prevents spurious interrupts on the UCB1400 */ -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 1 << idx); -+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); -+ -+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); -+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); -+ -+ ucb1x00_disable(ucb); - } - } - -@@ -305,18 +353,16 @@ void ucb1x00_disable_irq(struct ucb1x00 - - if (idx < 16) { - spin_lock_irqsave(&ucb->lock, flags); -- -- ucb1x00_enable(ucb); -- if (edges & UCB_RISING) { -+ if (edges & UCB_RISING) - ucb->irq_ris_enbl &= ~(1 << idx); -- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); -- } -- if (edges & UCB_FALLING) { -+ if (edges & UCB_FALLING) - ucb->irq_fal_enbl &= ~(1 << idx); -- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); -- } -- ucb1x00_disable(ucb); - spin_unlock_irqrestore(&ucb->lock, flags); -+ -+ ucb1x00_enable(ucb); -+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); -+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); -+ ucb1x00_disable(ucb); - } - } - -@@ -349,16 +395,17 @@ int ucb1x00_free_irq(struct ucb1x00 *ucb - ucb->irq_ris_enbl &= ~(1 << idx); - ucb->irq_fal_enbl &= ~(1 << idx); - -- ucb1x00_enable(ucb); -- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); -- ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); -- ucb1x00_disable(ucb); -- - irq->fn = NULL; - irq->devid = NULL; - ret = 0; - } - spin_unlock_irq(&ucb->lock); -+ -+ ucb1x00_enable(ucb); -+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl); -+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl); -+ ucb1x00_disable(ucb); -+ - return ret; - - bad: -@@ -478,7 +525,7 @@ static int ucb1x00_probe(struct mcp *mcp - mcp_enable(mcp); - id = mcp_reg_read(mcp, UCB_ID); - -- if (id != UCB_ID_1200 && id != UCB_ID_1300) { -+ if (id != UCB_ID_1200 && id != UCB_ID_1300 && !UCB_IS_1400(id)) { - printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); - goto err_disable; - } -@@ -491,12 +538,13 @@ static int ucb1x00_probe(struct mcp *mcp - memset(ucb, 0, sizeof(struct ucb1x00)); - - ucb->cdev.class = &ucb1x00_class; -- ucb->cdev.dev = &mcp->attached_device; -+ ucb->cdev.dev = mcp->dev; - strlcpy(ucb->cdev.class_id, "ucb1x00", sizeof(ucb->cdev.class_id)); - - spin_lock_init(&ucb->lock); - spin_lock_init(&ucb->io_lock); - sema_init(&ucb->adc_sem, 1); -+ init_completion(&ucb->irq_wait); - - ucb->id = id; - ucb->mcp = mcp; -@@ -507,12 +555,22 @@ static int ucb1x00_probe(struct mcp *mcp - goto err_free; - } - -- ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb); -+ ret = request_irq(ucb->irq, -+ UCB_IS_1400(id) ? ucb1x00_threaded_irq : ucb1x00_irq, -+ 0, "UCB1x00", ucb); - if (ret) { - printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", - ucb->irq, ret); - goto err_free; - } -+ if (UCB_IS_1400(id)) { -+ ucb->irq_task = kthread_run(ucb1x00_thread, ucb, "kUCB1x00d"); -+ if (IS_ERR(ucb->irq_task)) { -+ ret = PTR_ERR(ucb->irq_task); -+ ucb->irq_task = NULL; -+ goto err_irq; -+ } -+ } - - set_irq_type(ucb->irq, IRQT_RISING); - mcp_set_drvdata(mcp, ucb); -@@ -531,6 +589,8 @@ static int ucb1x00_probe(struct mcp *mcp - goto out; - - err_irq: -+ if (UCB_IS_1400(id) && ucb->irq_task) -+ kthread_stop(ucb->irq_task); - free_irq(ucb->irq, ucb); - err_free: - kfree(ucb); -@@ -553,6 +613,8 @@ static void ucb1x00_remove(struct mcp *m - } - up(&ucb1x00_sem); - -+ if (UCB_IS_1400(ucb->id) && ucb->irq_task) -+ kthread_stop(ucb->irq_task); - free_irq(ucb->irq, ucb); - class_device_unregister(&ucb->cdev); - } -Index: linux-2.6.15gum/drivers/mfd/ucb1x00-ts.c -=================================================================== ---- linux-2.6.15gum.orig/drivers/mfd/ucb1x00-ts.c -+++ linux-2.6.15gum/drivers/mfd/ucb1x00-ts.c -@@ -34,10 +34,8 @@ - #include - #include - --#include --#include --#include - #include -+#include - - #include "ucb1x00.h" - -@@ -46,7 +44,7 @@ struct ucb1x00_ts { - struct input_dev *idev; - struct ucb1x00 *ucb; - -- wait_queue_head_t irq_wait; -+ struct completion irq_wait; - struct task_struct *rtask; - u16 x_res; - u16 y_res; -@@ -206,7 +204,6 @@ static int ucb1x00_thread(void *_ts) - { - struct ucb1x00_ts *ts = _ts; - struct task_struct *tsk = current; -- DECLARE_WAITQUEUE(wait, tsk); - int valid; - - /* -@@ -218,10 +215,8 @@ static int ucb1x00_thread(void *_ts) - - valid = 0; - -- add_wait_queue(&ts->irq_wait, &wait); - while (!kthread_should_stop()) { - unsigned int x, y, p; -- signed long timeout; - - ts->restart = 0; - -@@ -243,8 +238,6 @@ static int ucb1x00_thread(void *_ts) - - - if (ucb1x00_ts_pen_down(ts)) { -- set_task_state(tsk, TASK_INTERRUPTIBLE); -- - ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING); - ucb1x00_disable(ts->ucb); - -@@ -257,7 +250,15 @@ static int ucb1x00_thread(void *_ts) - valid = 0; - } - -- timeout = MAX_SCHEDULE_TIMEOUT; -+ /* -+ * Since ucb1x00_enable_irq() might sleep due -+ * to the way the UCB1400 regs are accessed, we -+ * can't use set_task_state() before that call, -+ * and not changing state before enabling the -+ * interrupt is racy. A completion handler avoids -+ * the issue. -+ */ -+ wait_for_completion_interruptible(&ts->irq_wait); - } else { - ucb1x00_disable(ts->ucb); - -@@ -272,16 +273,12 @@ static int ucb1x00_thread(void *_ts) - } - - set_task_state(tsk, TASK_INTERRUPTIBLE); -- timeout = HZ / 100; -+ schedule_timeout(HZ/100); - } - - try_to_freeze(); -- -- schedule_timeout(timeout); - } - -- remove_wait_queue(&ts->irq_wait, &wait); -- - ts->rtask = NULL; - return 0; - } -@@ -294,7 +291,7 @@ static void ucb1x00_ts_irq(int idx, void - { - struct ucb1x00_ts *ts = id; - ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING); -- wake_up(&ts->irq_wait); -+ complete(&ts->irq_wait); - } - - static int ucb1x00_ts_open(struct input_dev *idev) -@@ -304,7 +301,7 @@ static int ucb1x00_ts_open(struct input_ - - BUG_ON(ts->rtask); - -- init_waitqueue_head(&ts->irq_wait); -+ init_completion(&ts->irq_wait); - ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts); - if (ret < 0) - goto out; -@@ -359,7 +356,7 @@ static int ucb1x00_ts_resume(struct ucb1 - * after sleep. - */ - ts->restart = 1; -- wake_up(&ts->irq_wait); -+ complete(&ts->irq_wait); - } - return 0; - } -Index: linux-2.6.15gum/drivers/mfd/ucb1x00.h -=================================================================== ---- linux-2.6.15gum.orig/drivers/mfd/ucb1x00.h -+++ linux-2.6.15gum/drivers/mfd/ucb1x00.h -@@ -94,6 +94,7 @@ - #define UCB_ID 0x0c - #define UCB_ID_1200 0x1004 - #define UCB_ID_1300 0x1005 -+#define UCB_ID_1400 0x4304 - - #define UCB_MODE 0x0d - #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) -@@ -110,6 +111,8 @@ struct ucb1x00 { - spinlock_t lock; - struct mcp *mcp; - unsigned int irq; -+ struct task_struct *irq_task; -+ struct completion irq_wait; - struct semaphore adc_sem; - spinlock_t io_lock; - u16 id; -@@ -122,6 +125,7 @@ struct ucb1x00 { - struct class_device cdev; - struct list_head node; - struct list_head devs; -+ - }; - - struct ucb1x00_driver; -Index: linux-2.6.15gum/drivers/mfd/mcp-ac97.c -=================================================================== ---- /dev/null -+++ linux-2.6.15gum/drivers/mfd/mcp-ac97.c -@@ -0,0 +1,153 @@ -+/* -+ * linux/drivers/misc/mcp-ac97.c -+ * -+ * Author: Nicolas Pitre -+ * Created: Jan 14, 2005 -+ * Copyright: (C) MontaVista Software Inc. -+ * -+ * 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. -+ * -+ * This module provides the minimum replacement for mcp-core.c allowing for -+ * the UCB1400 chip to be driven by the ucb1x00 driver over an AC97 link. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "mcp.h" -+ -+/* ucb1x00 SIB register to ucb1400 AC-link register mapping */ -+ -+static const unsigned char regmap[] = { -+ 0x5a, /* UCB_IO_DATA */ -+ 0X5C, /* UCB_IO_DIR */ -+ 0X5E, /* UCB_IE_RIS */ -+ 0x60, /* UCB_IE_FAL */ -+ 0x62, /* UCB_IE_STATUS */ -+ 0, /* UCB_TC_A */ -+ 0, /* UCB_TC_B */ -+ 0, /* UCB_AC_A */ -+ 0, /* UCB_AC_B */ -+ 0x64, /* UCB_TS_CR */ -+ 0x66, /* UCB_ADC_CR */ -+ 0x68, /* UCB_ADC_DATA */ -+ 0x7e, /* UCB_ID */ -+ 0, /* UCB_MODE */ -+}; -+ -+unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg) -+{ -+ ac97_t *ac97 = to_ac97_t(mcp->dev); -+ if (reg < ARRAY_SIZE(regmap)) { -+ reg = regmap[reg]; -+ if (reg) -+ return ac97->bus->ops->read(ac97, reg); -+ } -+ return -1; -+} -+EXPORT_SYMBOL(mcp_reg_read); -+ -+void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val) -+{ -+ ac97_t *ac97 = to_ac97_t(mcp->dev); -+ if (reg < ARRAY_SIZE(regmap)) { -+ reg = regmap[reg]; -+ if (reg) -+ ac97->bus->ops->write(ac97, reg, val); -+ } -+} -+EXPORT_SYMBOL(mcp_reg_write); -+ -+void mcp_enable(struct mcp *mcp) -+{ -+} -+EXPORT_SYMBOL(mcp_enable); -+ -+void mcp_disable(struct mcp *mcp) -+{ -+} -+EXPORT_SYMBOL(mcp_disable); -+ -+#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) -+ -+static int mcp_probe(struct device *dev) -+{ -+ struct mcp_driver *drv = to_mcp_driver(dev->driver); -+ struct mcp *mcp; -+ int ret; -+ -+ ret = -ENOMEM; -+ mcp = kmalloc(sizeof(*mcp), GFP_KERNEL); -+ if (mcp) { -+ memset(mcp, 0, sizeof(*mcp)); -+ mcp->owner = THIS_MODULE; -+ mcp->dev = dev; -+ ret = drv->probe(mcp); -+ if (ret) -+ kfree(mcp); -+ } -+ if (!ret) -+ dev_set_drvdata(dev, mcp); -+ return ret; -+} -+ -+static int mcp_remove(struct device *dev) -+{ -+ struct mcp_driver *drv = to_mcp_driver(dev->driver); -+ struct mcp *mcp = dev_get_drvdata(dev); -+ -+ drv->remove(mcp); -+ dev_set_drvdata(dev, NULL); -+ kfree(mcp); -+ return 0; -+} -+ -+static int mcp_suspend(struct device *dev, pm_message_t state) -+{ -+ struct mcp_driver *drv = to_mcp_driver(dev->driver); -+ struct mcp *mcp = dev_get_drvdata(dev); -+ int ret = 0; -+ -+ if (drv->suspend) -+ ret = drv->suspend(mcp, state); -+ return ret; -+} -+ -+static int mcp_resume(struct device *dev) -+{ -+ struct mcp_driver *drv = to_mcp_driver(dev->driver); -+ struct mcp *mcp = dev_get_drvdata(dev); -+ int ret = 0; -+ -+ if (drv->resume) -+ ret = drv->resume(mcp); -+ return ret; -+} -+ -+int mcp_driver_register(struct mcp_driver *mcpdrv) -+{ -+ mcpdrv->drv.owner = THIS_MODULE; -+ mcpdrv->drv.bus = &ac97_bus_type; -+ mcpdrv->drv.probe = mcp_probe; -+ mcpdrv->drv.remove = mcp_remove; -+ mcpdrv->drv.suspend = mcp_suspend; -+ mcpdrv->drv.resume = mcp_resume; -+ return driver_register(&mcpdrv->drv); -+} -+EXPORT_SYMBOL(mcp_driver_register); -+ -+void mcp_driver_unregister(struct mcp_driver *mcpdrv) -+{ -+ driver_unregister(&mcpdrv->drv); -+} -+EXPORT_SYMBOL(mcp_driver_unregister); -+ -+MODULE_LICENSE("GPL"); -Index: linux-2.6.15gum/drivers/input/touchscreen/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/drivers/input/touchscreen/Kconfig -+++ linux-2.6.15gum/drivers/input/touchscreen/Kconfig -@@ -11,6 +11,25 @@ menuconfig INPUT_TOUCHSCREEN - - if INPUT_TOUCHSCREEN - -+config UCB1400 -+ bool -+ -+config TOUCHSCREEN_UCB1400 -+ tristate "UCB1400 Touchscreen support" -+ depends on ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_GUMSTIX -+ select SND_AC97_BUS -+ select UCB1400 -+ help -+ Say Y here if you have a touchscreen connected to a UCB1400 ADC chip -+ on the AC97 bus of a PXA255/PXA270 host. -+ -+ If unsure, say N. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called ucb1x00-ts. It will also build the modules -+ ucb1x00-core and mcp-ac97 which provide the compatibility layers -+ down to the AC97 bus. -+ - config TOUCHSCREEN_BITSY - tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" - depends on SA1100_BITSY -Index: linux-2.6.15gum/drivers/input/Kconfig -=================================================================== ---- linux-2.6.15gum.orig/drivers/input/Kconfig -+++ linux-2.6.15gum/drivers/input/Kconfig -@@ -87,7 +87,7 @@ config INPUT_JOYDEV - module will be called joydev. - - config INPUT_TSDEV -- tristate "Touchscreen interface" -+ tristate "Compaq touchscreen interface" - ---help--- - Say Y here if you have an application that only can understand the - Compaq touchscreen protocol for absolute pointer data. This is diff --git a/recipes/linux/linux-gumstix_2.6.15.bb b/recipes/linux/linux-gumstix_2.6.15.bb deleted file mode 100644 index 2c4a6132fc..0000000000 --- a/recipes/linux/linux-gumstix_2.6.15.bb +++ /dev/null @@ -1,110 +0,0 @@ -DESCRIPTION = "Linux Kernel for the Gumstix" -SECTION = "kernel" -LICENSE = "GPLv2" -PR = "r2" - -COMPATIBLE_MACHINE = "gumstix" - -SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2;name=kernel \ - cvs://anoncvs:anoncvs@cvs.infradead.org/home/cvs;module=mtd;date=20060223 \ - file://defconfig-gumstix \ - file://arch-config.patch \ - file://board-init.patch \ - file://compact-flash.patch \ - file://defconfig.patch \ - file://flash.patch \ - file://header.patch \ - file://kconfig-arch-cleanup.patch \ - file://pxa255-gpio-count-bugfix.patch \ - file://pxa2xx_udc.patch \ - file://bkpxa-pxa-cpu.patch \ - file://bkpxa-pxa-cpufreq.patch \ - file://bkpxa-pxa-ac97.patch \ - file://rmk-2022-2-rtctime-sa110-pxa255-driver.patch \ - file://proc-gpio.patch \ - file://serial-ether-addr.patch \ - file://cpufreq-better-freqs.patch \ - file://ethernet-config.patch \ - file://smc-ether-addr.patch \ - file://audio.patch \ - file://cpufreq-ondemand-by-default.patch \ - file://modular-init-bluetooth.patch \ - file://modular-init-smc91x.patch \ - file://modular-init-usb-gadget.patch \ - file://bugfix-i2c-include.patch \ - file://bugfix-mmc-clock.patch \ - file://bugfix-mtd-onenand.patch \ - file://bugfix-pxa-audio.patch \ - file://bugfix-pxa-cpufreq.patch \ - file://bugfix-pxa-serial-mctrl.patch \ - file://bugfix-rndis.patch \ - file://bugfix-serial-interrupt.patch \ - file://bugfix-serial-register-status.patch \ - file://mach-types-fix.patch \ - file://mmc-version4.patch \ - file://kernel-osx.patch \ - file://ucb1400-touchscreen.patch \ - file://add_input_randomness_export.patch \ - file://kobject_get_path_export.patch \ - file://ucb1400-ac97-audio.patch \ - file://i2c-gpl-module-fix.patch \ - file://disable-uncompress-message.patch \ - file://gumstix-mmc.patch \ - file://rmk_pxa_mmc_timeout.patch" - -S = "${WORKDIR}/linux-${PV}" - -inherit kernel - -COMPATIBLE_HOST = "arm.*-linux" -ARCH = "arm" -KERNEL_IMAGETYPE = "uImage" - -do_unpack_extra() { - cd ${WORKDIR}/mtd - ./patchkernel.sh -c -2 -y ${WORKDIR}/linux-${PV} -} -addtask unpack_extra after do_unpack before do_patch - -do_configure_prepend() { - install -m 0644 ${WORKDIR}/defconfig-gumstix ${S}/.config -} - -do_deploy_append() { - ${HOST_PREFIX}objcopy -O binary -R .note -R .comment -S arch/arm/boot/compressed/vmlinux arch/arm/boot/compressed/linux.bin - uboot-mkimage -A arm -O linux -T kernel -C none -a 0xa0008000 -e 0xa0008000 -n "gumstix" -d arch/arm/boot/compressed/linux.bin arch/arm/boot/uImage - install -d ${DEPLOY_DIR_IMAGE} - cp arch/arm/boot/uImage ${DEPLOY_DIR_IMAGE}/uImage-${PN}-${PV} -} - -PACKAGES += "kernel-modules-sound kernel-modules-bluetooth kernel-modules-pcmcia kernel-modules-ide kernel-modules-ethernet kernel-modules-wireless kernel-modules-usb kernel-modules-mmc kernel-modules-fat kernel-modules-nfs" - -ALLOW_EMPTY_kernel-modules-sound = "1" -ALLOW_EMPTY_kernel-modules-bluetooth = "1" -ALLOW_EMPTY_kernel-modules-pcmcia = "1" -ALLOW_EMPTY_kernel-modules-ide = "1" -ALLOW_EMPTY_kernel-modules-ethernet = "1" -ALLOW_EMPTY_kernel-modules-wireless = "1" -ALLOW_EMPTY_kernel-modules-usb = "1" -ALLOW_EMPTY_kernel-modules-mmc = "1" -ALLOW_EMPTY_kernel-modules-fat = "1" -ALLOW_EMPTY_kernel-modules-nfs = "1" - -RDEPENDS_kernel-modules-sound = "kernel-module-soundcore kernel-module-snd kernel-module-snd-timer kernel-module-snd-pxa2xx-pcm kernel-module-snd-pxa2xx-ac97 kernel-module-snd-pcm kernel-module-snd-pcm-oss kernel-module-snd-page-alloc kernel-module-snd-mixer-oss kernel-module-snd-ac97-codec kernel-module-snd-ac97-bus" -RDEPENDS_kernel-modules-bluetooth = "kernel-module-bluetooth kernel-module-bnep kernel-module-gumstix-bluetooth kernel-module-hci-uart kernel-module-l2cap kernel-module-sco kernel-module-rfcomm" -RDEPENDS_kernel-modules-pcmcia = "kernel-module-pcmcia-core kernel-module-pcmcia kernel-module-pxa2xx-core kernel-module-pxa2xx-cs " -RDEPENDS_kernel-modules-ide = "kernel-modules-pcmcia kernel-module-ide-core kernel-module-ide-cs kernel-module-ide-disk kernel-module-ide-generic kernel-module-firmware-class" -RDEPENDS_kernel-modules-ethernet = "kernel-module-mii kernel-module-smc91x kernel-module-gumstix-smc91x" -RDEPENDS_kernel-modules-wireless = "kernel-module-ieee80211 kernel-module-ieee80211-crypt kernel-module-ieee80211-crypt-wep kernel-modules-pcmcia kernel-module-hermes kernel-module-hostap-cs kernel-module-hostap kernel-module-orinoco kernel-module-orinoco-cs kernel-module-spectrum-cs" -RDEPENDS_kernel-modules-usb = "kernel-module-gumstix-gadget kernel-module-g-ether kernel-module-pxa2xx-udc " -RDEPENDS_kernel-modules-mmc = "kernel-module-mmc-core kernel-module-mmc-block kernel-module-pxamci" -RDEPENDS_kernel-modules-fat = "kernel-module-vfat kernel-module-nls-base kernel-module-fat kernel-module-nls-cp437 kernel-module-nls-iso8859-1" -RDEPENDS_kernel-modules-nfs = "kernel-module-nfs kernel-module-sunrpc kernel-module-lockd" - -module_autoload_pxamci = "pxamci" -module_autoload_mmc_block = "mmc_block" -module_autoload_gumstix_gadget = "gumstix_gadget" -module_autoload_g_ether = "g_ether" - -SRC_URI[kernel.md5sum] = "cdf95e00f5111e31f78e1d97304d9522" -SRC_URI[kernel.sha256sum] = "066ec56ce5f57c79a526b6bb3541d32dbf796c11c26c32073fc64b93f09825db" -- cgit 1.2.3-korg