diff options
| author | Len Brown <len.brown@intel.com> | 2004-12-21 07:12:23 -0500 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2004-12-21 07:12:23 -0500 |
| commit | 1c5e7c210e6212e7b9c74b8f3605bae4eabd1dde (patch) | |
| tree | 6f9b822a6ea36e59f5f860ca04691682f2630141 | |
| parent | 112e959c5808d7ec51254d208c332d8274c17da8 (diff) | |
| parent | 2954a9c4ce173441b4e48ea1d45efba6ea64f49d (diff) | |
Merge intel.com:/home/lenb/bk/26-latest-ref
into intel.com:/home/lenb/src/26-latest-dev
32 files changed, 2426 insertions, 535 deletions
diff --git a/Documentation/scsi/ChangeLog.megaraid b/Documentation/scsi/ChangeLog.megaraid index b239d4c778d4..79a9aed8e5d7 100644 --- a/Documentation/scsi/ChangeLog.megaraid +++ b/Documentation/scsi/ChangeLog.megaraid @@ -1,3 +1,10 @@ +Release Date : Thu Dec 9 19:02:14 EST 2004 - Sreenivas Bagalkote <sreenib@lsil.com> + +Current Version : 2.20.4.1 (scsi module), 2.20.2.3 (cmm module) +Older Version : 2.20.4.1 (scsi module), 2.20.2.2 (cmm module) + +i. Fix a bug in kioc's dma buffer deallocation + Release Date : Thu Nov 4 18:24:56 EST 2004 - Sreenivas Bagalkote <sreenib@lsil.com> Current Version : 2.20.4.1 (scsi module), 2.20.2.2 (cmm module) diff --git a/MAINTAINERS b/MAINTAINERS index 8217e83941ad..d3dc9555cdcc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2495,6 +2495,13 @@ M: johnpol@2ka.mipt.ru L: sensors@stimpy.netroedge.com S: Maintained +W83L51xD SD/MMC CARD INTERFACE DRIVER +P: Pierre Ossman +M: drzeus-wbsd@drzeus.cx +L: wbsd-devel@list.drzeus.cx +W: http://projects.drzeus.cx/wbsd +S: Maintained + W83L785TS HARDWARE MONITOR DRIVER P: Jean Delvare M: khali@linux-fr.org diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index e8c1f0592287..5efaeef3e758 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig @@ -1,139 +1,167 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.10-rc3 +# Mon Dec 20 16:08:21 2004 # CONFIG_ARM=y -# CONFIG_EISA is not set -# CONFIG_SBUS is not set -# CONFIG_MCA is not set +CONFIG_MMU=y CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_GENERIC_IOMAP=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y -# CONFIG_OBSOLETE is not set +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +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_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set # # 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 is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y # # System Type # -# CONFIG_ARCH_ARCA5K is not set # CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_CAMELOT is not set # CONFIG_ARCH_FOOTBRIDGE is not set CONFIG_ARCH_INTEGRATOR=y +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_CLPS711X is not set - -# -# Archimedes/A5000 Implementations -# +# 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_IMX is not set +# CONFIG_ARCH_H720X is not set # -# Archimedes/A5000 Implementations (select only ONE) +# Integrator Options # -# CONFIG_ARCH_ARC is not set -# CONFIG_ARCH_A5K is not set - -# -# Footbridge Implementations -# -# CONFIG_ARCH_CATS is not set -# CONFIG_ARCH_PERSONAL_SERVER is not set -# CONFIG_ARCH_EBSA285_ADDIN is not set -# CONFIG_ARCH_EBSA285_HOST is not set -# CONFIG_ARCH_NETWINDER is not set - -# -# SA11x0 Implementations -# -# CONFIG_SA1100_ASSABET is not set -# CONFIG_ASSABET_NEPONSET is not set -# CONFIG_SA1100_BRUTUS is not set -# CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_BITSY is not set -# CONFIG_SA1100_EXTENEX1 is not set -# CONFIG_SA1100_FREEBIRD is not set -# CONFIG_SA1100_GRAPHICSCLIENT is not set -# CONFIG_SA1100_JORNADA720 is not set -# CONFIG_SA1100_HUW_WEBPANEL is not set -# CONFIG_SA1100_ITSY is not set -# CONFIG_SA1100_LART is not set -# CONFIG_SA1100_NANOENGINE is not set -# CONFIG_SA1100_OMNIMETER is not set -# CONFIG_SA1100_PANGOLIN is not set -# CONFIG_SA1100_PLEB is not set -# CONFIG_SA1100_SHERMAN is not set -# CONFIG_SA1100_PFS168 is not set -# CONFIG_SA1100_VICTOR is not set -# CONFIG_SA1100_XP860 is not set -# CONFIG_SA1100_YOPY is not set - -# -# CLPS711X/EP721X Implementations -# -# CONFIG_ARCH_P720T is not set -# CONFIG_ARCH_ACORN is not set -# CONFIG_FOOTBRIDGE is not set -# CONFIG_FOOTBRIDGE_HOST is not set -# CONFIG_FOOTBRIDGE_ADDIN is not set -CONFIG_CPU_32=y -# CONFIG_CPU_26 is not set +CONFIG_ARCH_INTEGRATOR_AP=y +# CONFIG_ARCH_INTEGRATOR_CP is not set +# CONFIG_INTEGRATOR_IMPD1 is not set # # Processor Type # -# CONFIG_CPU_32v3 is not set -CONFIG_CPU_32v4=y -# CONFIG_CPU_ARM610 is not set -# CONFIG_CPU_ARM710 is not set +CONFIG_CPU_32=y CONFIG_CPU_ARM720T=y CONFIG_CPU_ARM920T=y -CONFIG_CPU_ARM920_CPU_IDLE=y -CONFIG_CPU_ARM920_I_CACHE_ON=y -CONFIG_CPU_ARM920_D_CACHE_ON=y -# CONFIG_CPU_ARM920_WRITETHROUGH is not set +# CONFIG_CPU_ARM926T is not set # CONFIG_CPU_ARM1020 is not set -# CONFIG_CPU_SA110 is not set -# CONFIG_CPU_SA1100 is not set -# CONFIG_DISCONTIGMEM is not set +# CONFIG_CPU_ARM1022 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_V6 is not set +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_ABRT_LV4T=y +CONFIG_CPU_CACHE_V4=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WT=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set # # General setup # -CONFIG_PCI_INTEGRATOR=y CONFIG_PCI=y -# CONFIG_ISA is not set -# CONFIG_ISA_DMA is not set -CONFIG_CPU_CLOCK=y +CONFIG_ICST525=y +CONFIG_ARM_AMBA=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_XIP_KERNEL is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_PROC_INTF is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_24_API is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_INTEGRATOR=y +CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_NET=y -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y + +# +# At least one math emulation must be selected +# CONFIG_FPE_NWFPE=y # CONFIG_FPE_NWFPE_XP is not set -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=y +# CONFIG_FPE_FASTFPE 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_DEBUG_DRIVER is not set CONFIG_PM=y +# CONFIG_PREEMPT is not set +# CONFIG_APM is not set # CONFIG_ARTHUR is not set -CONFIG_CMDLINE="root=1f03 mem=32M" +CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp mem=32M" CONFIG_LEDS=y CONFIG_LEDS_TIMER=y CONFIG_LEDS_CPU=y @@ -150,8 +178,9 @@ CONFIG_ALIGNMENT_TRAP=y 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_BOOTLDR_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_AFS_PARTS=y # @@ -161,259 +190,264 @@ 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_CFI_VIRTUAL_ER is not set +# 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_LART_BIT_SWAP is not set # CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP 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_JEDEC is not set +# CONFIG_MTD_ABSENT is not set # # Mapping drivers for chip access # +# CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_SUN_UFLASH is not set -# CONFIG_MTD_NORA is not set -# CONFIG_MTD_PNC2000 is not set -# CONFIG_MTD_RPXLITE is not set -# CONFIG_MTD_SC520CDP is not set -# CONFIG_MTD_NETSC520 is not set -# CONFIG_MTD_SBC_GXX is not set -# CONFIG_MTD_ELAN_104NC is not set -# CONFIG_MTD_SA1100 is not set -# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set -# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set -# CONFIG_MTD_DC21285 is not set -# CONFIG_MTD_IQ80310 is not set -# CONFIG_MTD_DBOX2 is not set -# CONFIG_MTD_CSTM_MIPS_IXX is not set -# CONFIG_MTD_CFI_FLAGADM is not set -# CONFIG_MTD_MIXMEM is not set -# CONFIG_MTD_OCTAGON is not set -# CONFIG_MTD_VMAX is not set -CONFIG_MTD_ARMFLASH=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set # 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_DOC1000 is not set # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOC2001PLUS is not set # # NAND Flash Device Drivers # # CONFIG_MTD_NAND is not set -# CONFIG_MTD_NAND_SPIA is not set # -# Plug and Play configuration +# Plug and Play support # -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set # # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Networking support +# +CONFIG_NET=y # # Networking options # CONFIG_PACKET=y CONFIG_PACKET_MMAP=y -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +# CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_INET_ECN=y +# 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_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM 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_DECNET is not set -# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC 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 device support +# 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 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 # # ARCnet devices # # CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set -# CONFIG_NET_SB1000 is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -# CONFIG_TULIP is not set -# CONFIG_DE4X5 is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -CONFIG_EEPRO100=y -CONFIG_EEPRO100_PM=y -# CONFIG_LNE390 is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set # CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set # -# Wireless LAN (non-hamradio) +# Ethernet (10000 Mbit) # -# CONFIG_NET_RADIO is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set # # Token Ring devices # # CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set # -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support +# Wireless LAN (non-hamradio) # -# CONFIG_HAMRADIO is not set +# CONFIG_NET_RADIO is not set # -# IrDA (infrared) support +# Wan interfaces # -# CONFIG_IRDA is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set # -# ATA/IDE/MFM/RLL support +# SCSI device support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_HD is not set +# CONFIG_SCSI is not set # -# SCSI support +# Fusion MPT device support # -# CONFIG_SCSI is not set # # IEEE 1394 (FireWire) support @@ -424,11 +458,6 @@ CONFIG_EEPRO100_PM=y # I2O device support # # CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set # # ISDN subsystem @@ -436,62 +465,85 @@ CONFIG_EEPRO100_PM=y # CONFIG_ISDN is not set # -# Input core support +# 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_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers # -# CONFIG_INPUT is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA 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_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_SERIAL_21285 is not set -# CONFIG_SERIAL_21285_OLD is not set -# CONFIG_SERIAL_21285_CONSOLE is not set -# CONFIG_SERIAL_SA1100 is not set -# CONFIG_SERIAL_SA1100_CONSOLE is not set -CONFIG_SERIAL_AMBA=y -CONFIG_SERIAL_AMBA_CONSOLE=y -CONFIG_SERIAL_INTEGRATOR=y -# CONFIG_SERIAL_CLPS711X is not set -# CONFIG_SERIAL_CLPS711X_CONSOLE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 # -# I2C support +# Serial drivers # -# CONFIG_I2C is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set +# CONFIG_SERIAL_8250 is not set # -# Joysticks +# Non-8250 serial port support # -# CONFIG_JOYSTICK is not set +CONFIG_SERIAL_AMBA_PL010=y +CONFIG_SERIAL_AMBA_PL010_CONSOLE=y +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -501,9 +553,13 @@ CONFIG_PSMOUSE=y # # 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 is not set # # Multimedia devices @@ -511,75 +567,100 @@ CONFIG_PSMOUSE=y # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR 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_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# 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_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW 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_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_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_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -CONFIG_MINIX_FS=y +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=y -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_SYSV_FS_WRITE is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y -CONFIG_SUNRPC=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -590,51 +671,70 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_AMIGA_PARTITION is not set # CONFIG_ATARI_PARTITION is not set # CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_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_SMB_NLS is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# # CONFIG_NLS is not set # -# Console drivers +# Profiling support # -CONFIG_KMI_KEYB=y -CONFIG_KMI_MOUSE=y -CONFIG_PC_KEYMAP=y -CONFIG_VGA_CONSOLE=y -CONFIG_FB=y +# CONFIG_PROFILING is not set # -# Frame-buffer support +# Graphics support # CONFIG_FB=y -CONFIG_DUMMY_CONSOLE=y -# CONFIG_FB_RIVA is not set -# CONFIG_FB_CLGEN is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set -# CONFIG_FB_ACORN is not set -# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_ARMCLCD is not set # CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_SA1100 is not set -# CONFIG_FB_E1355 is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_ATY is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G450=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set -# CONFIG_FB_3DFX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set # CONFIG_FB_VIRTUAL is not set -# CONFIG_FBCON_ADVANCED is not set -# CONFIG_FBCON_FONTWIDTH8_ONLY is not set -CONFIG_FBCON_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set # # Sound @@ -642,19 +742,63 @@ CONFIG_FONT_8x16=y # CONFIG_SOUND is not set # +# Misc devices +# + +# # USB support # # CONFIG_USB is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set # # Kernel hacking # +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_INFO is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_NO_PGT_CACHE is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_DC21285_PORT is not set -# CONFIG_DEBUG_CLPS711X_UART2 is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# 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/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 6ad406bd9c6e..44cd347847cb 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -1657,6 +1657,8 @@ __stubs_end: ENTRY(__trap_init) stmfd sp!, {r4 - r6, lr} + mov r0, #0xff000000 + orr r0, r0, #0x00ff0000 @ high vectors position adr r1, .LCvectors @ set up the vectors ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr} stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr} diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 6f7938162e46..894de5af42ab 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -46,32 +46,16 @@ #include <asm/system.h> #include <asm/uaccess.h> -#define FIQ_VECTOR (vectors_base() + 0x1c) - static unsigned long no_fiq_insn; -static inline void unprotect_page_0(void) -{ - modify_domain(DOMAIN_USER, DOMAIN_MANAGER); -} - -static inline void protect_page_0(void) -{ - modify_domain(DOMAIN_USER, DOMAIN_CLIENT); -} - /* Default reacquire function * - we always relinquish FIQ control * - we always reacquire FIQ control */ static int fiq_def_op(void *ref, int relinquish) { - if (!relinquish) { - unprotect_page_0(); - *(unsigned long *)FIQ_VECTOR = no_fiq_insn; - protect_page_0(); - flush_icache_range(FIQ_VECTOR, FIQ_VECTOR + 4); - } + if (!relinquish) + set_fiq_handler(&no_fiq_insn, sizeof(no_fiq_insn)); return 0; } @@ -93,12 +77,10 @@ int show_fiq_list(struct seq_file *p, void *v) void set_fiq_handler(void *start, unsigned int length) { - unprotect_page_0(); - - memcpy((void *)FIQ_VECTOR, start, length); - - protect_page_0(); - flush_icache_range(FIQ_VECTOR, FIQ_VECTOR + length); + memcpy((void *)0xffff001c, start, length); + flush_icache_range(0xffff001c, 0xffff001c + length); + if (!vectors_high()) + flush_icache_range(0x1c, 0x1c + length); } /* @@ -198,6 +180,5 @@ EXPORT_SYMBOL(disable_fiq); void __init init_FIQ(void) { - no_fiq_insn = *(unsigned long *)FIQ_VECTOR; - set_fs(get_fs()); + no_fiq_insn = *(unsigned long *)0xffff001c; } diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 7cbd18e95bb0..154099aefad6 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -51,6 +51,13 @@ asmlinkage int sys_pipe(unsigned long __user *fildes) return error; } +/* + * This is the lowest virtual address we can permit any user space + * mapping to be mapped at. This is particularly important for + * non-high vector CPUs. + */ +#define MIN_MAP_ADDR (PAGE_SIZE) + /* common code for old and new mmaps */ inline long do_mmap2( unsigned long addr, unsigned long len, @@ -62,11 +69,7 @@ inline long do_mmap2( flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - /* - * If we are doing a fixed mapping, and address < PAGE_SIZE, - * then deny it. - */ - if (flags & MAP_FIXED && addr < PAGE_SIZE && vectors_base() == 0) + if (flags & MAP_FIXED && addr < MIN_MAP_ADDR) goto out; error = -EBADF; @@ -119,12 +122,7 @@ sys_arm_mremap(unsigned long addr, unsigned long old_len, { unsigned long ret = -EINVAL; - /* - * If we are doing a fixed mapping, and address < PAGE_SIZE, - * then deny it. - */ - if (flags & MREMAP_FIXED && new_addr < PAGE_SIZE && - vectors_base() == 0) + if (flags & MREMAP_FIXED && new_addr < MIN_MAP_ADDR) goto out; down_write(¤t->mm->mmap_sem); diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index d0f983705e2e..b80f8cee77f3 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -328,20 +328,11 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs) */ asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode) { - unsigned int vectors = vectors_base(); - console_verbose(); printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n", handler[reason], processor_modes[proc_mode]); - /* - * Dump out the vectors and stub routines. Maybe a better solution - * would be to dump them out only if we detect that they are corrupted. - */ - dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40); - dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8); - die("Oops - bad mode", regs, 0); local_irq_disable(); panic("bad mode"); @@ -537,7 +528,7 @@ EXPORT_SYMBOL(__bug); void __readwrite_bug(const char *fn) { - printk("%s called, but not implemented", fn); + printk("%s called, but not implemented\n", fn); BUG(); } EXPORT_SYMBOL(__readwrite_bug); @@ -575,13 +566,9 @@ EXPORT_SYMBOL(abort); void __init trap_init(void) { - extern void __trap_init(unsigned long); - unsigned long base = vectors_base(); - - __trap_init(base); - flush_icache_range(base, base + PAGE_SIZE); - if (base != 0) - printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n", - base); + extern void __trap_init(void); + + __trap_init(); + flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); } diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index c1015d5118e2..107c12abc268 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c @@ -243,7 +243,7 @@ struct clk s3c24xx_dclk1 = { }; struct clk s3c24xx_clkout0 = { - .name = "clkout1", + .name = "clkout0", .id = -1, }; diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index 582a69460cff..8d113d629867 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -11,6 +11,8 @@ #include <linux/string.h> #include <linux/pm.h> #include <linux/device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> #include <asm/irq.h> #include <asm/hardware.h> @@ -18,6 +20,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/mach/flash.h> #include <asm/mach/map.h> #include <asm/mach/serial_sa1100.h> #include <asm/arch/simpad.h> @@ -83,6 +86,45 @@ static struct sa1100_port_fns simpad_port_fns __initdata = { .pm = simpad_uart_pm, }; + +static struct mtd_partition simpad_partitions[] = { + { + .name = "SIMpad boot firmware", + .size = 0x00080000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "SIMpad kernel", + .size = 0x0010000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "SIMpad root jffs2", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct flash_platform_data simpad_flash_data = { + .map_name = "cfi_probe", + .parts = simpad_partitions, + .nr_parts = ARRAY_SIZE(simpad_partitions), +}; + + +static struct resource simpad_flash_resources [] = { + { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_16M -1, + .flags = IORESOURCE_MEM, + }, { + .start = SA1100_CS1_PHYS, + .end = SA1100_CS1_PHYS + SZ_16M -1, + .flags = IORESOURCE_MEM, + } +}; + + + static void __init simpad_map_io(void) { sa1100_map_io(); @@ -113,84 +155,9 @@ static void __init simpad_map_io(void) PCFR = 0; PSDR = 0; - -} - -#ifdef CONFIG_PROC_FS - -static char* name[]={ - "VCC_5V_EN", - "VCC_3V_EN", - "EN1", - "EN0", - "DISPLAY_ON", - "PCMCIA_BUFF_DIS", - "MQ_RESET", - "PCMCIA_RESET", - "DECT_POWER_ON", - "IRDA_SD", - "RS232_ON", - "SD_MEDIAQ", - "LED2_ON", - "IRDA_MODE", - "ENABLE_5V", - "RESET_SIMCARD" -}; - -static int proc_cs3_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - int len, i; - - p += sprintf(p, "Chipselect3 : %x\n", (uint)cs3_shadow); - for (i = 0; i <= 15; i++) { - if(cs3_shadow & (1<<i)) { - p += sprintf(p, "%s\t: TRUE \n",name[i]); - } else - p += sprintf(p, "%s\t: FALSE \n",name[i]); - } - len = (p - page) - off; - if (len < 0) - len = 0; - - *eof = (len <= count) ? 1 : 0; - *start = page + off; - - return len; -} - -static int proc_cs3_write(struct file * file, const char * buffer, - size_t count, loff_t *ppos) -{ - unsigned long newRegValue; - char *endp; - - newRegValue = simple_strtoul(buffer,&endp,0); - set_cs3( newRegValue ); - return (count+endp-buffer); -} - -#endif - -static int __init cs3_init(void) -{ - -#ifdef CONFIG_PROC_FS - struct proc_dir_entry *proc_cs3 = create_proc_entry("CS3", 0, 0); - if (proc_cs3) - { - proc_cs3->read_proc = proc_cs3_read; - proc_cs3->write_proc = (void*)proc_cs3_write; - } -#endif - - - - return 0; + sa11x0_set_flash_data(&simpad_flash_data, simpad_flash_resources, + ARRAY_SIZE(simpad_flash_resources)); } - -arch_initcall(cs3_init); static void simpad_power_off(void) { diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 402dad21a1d4..76dcfc9ba155 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -15,6 +15,7 @@ #include <asm/pgtable.h> #include <asm/shmparam.h> #include <asm/tlbflush.h> +#include <asm/cacheflush.h> #if SHMLBA > 16384 #error FIX ME diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index ebc696090222..9150033e8b25 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -158,7 +158,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm) init_pgd = pgd_offset_k(0); - if (vectors_base() == 0) { + if (!vectors_high()) { /* * This lock is here just to satisfy pmd_alloc and pte_lock */ @@ -317,12 +317,18 @@ static struct mem_types mem_types[] __initdata = { .prot_sect = PMD_TYPE_SECT | PMD_SECT_MINICACHE, .domain = DOMAIN_KERNEL, }, - [MT_VECTORS] = { + [MT_LOW_VECTORS] = { .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_EXEC, .prot_l1 = PMD_TYPE_TABLE, .domain = DOMAIN_USER, }, + [MT_HIGH_VECTORS] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_USER | L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_USER, + }, [MT_MEMORY] = { .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, @@ -357,13 +363,12 @@ static void __init build_mem_type_table(void) } if (cpu_arch <= CPU_ARCH_ARMv5) { - mem_types[MT_DEVICE].prot_l1 |= PMD_BIT4; - mem_types[MT_DEVICE].prot_sect |= PMD_BIT4; - mem_types[MT_CACHECLEAN].prot_sect |= PMD_BIT4; - mem_types[MT_MINICLEAN].prot_sect |= PMD_BIT4; - mem_types[MT_VECTORS].prot_l1 |= PMD_BIT4; - mem_types[MT_MEMORY].prot_sect |= PMD_BIT4; - mem_types[MT_ROM].prot_sect |= PMD_BIT4; + for (i = 0; i < ARRAY_SIZE(mem_types); i++) { + if (mem_types[i].prot_l1) + mem_types[i].prot_l1 |= PMD_BIT4; + if (mem_types[i].prot_sect) + mem_types[i].prot_sect |= PMD_BIT4; + } } /* @@ -387,13 +392,16 @@ static void __init build_mem_type_table(void) cp = &cache_policies[cachepolicy]; if (cpu_arch >= CPU_ARCH_ARMv5) { - mem_types[MT_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; + mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; + mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; } else { - mem_types[MT_VECTORS].prot_pte |= cp->pte; + mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte; + mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte; mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); } - mem_types[MT_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; mem_types[MT_ROM].prot_sect |= cp->pmd; @@ -420,6 +428,8 @@ static void __init build_mem_type_table(void) ecc_mask ? "en" : "dis", cp->policy); } +#define vectors_base() (vectors_high() ? 0xffff0000 : 0) + /* * Create the page directory entries and any necessary * page tables for the mapping specified by `md'. We @@ -587,16 +597,22 @@ void __init memtable_init(struct meminfo *mi) } while (address != 0); /* - * Create a mapping for the machine vectors at virtual address 0 - * or 0xffff0000. We should always try the high mapping. + * Create a mapping for the machine vectors at the high-vectors + * location (0xffff0000). If we aren't using high-vectors, also + * create a mapping at the low-vectors virtual address. */ init_maps->physical = virt_to_phys(init_maps); - init_maps->virtual = vectors_base(); + init_maps->virtual = 0xffff0000; init_maps->length = PAGE_SIZE; - init_maps->type = MT_VECTORS; - + init_maps->type = MT_HIGH_VECTORS; create_mapping(init_maps); + if (!vectors_high()) { + init_maps->virtual = 0; + init_maps->type = MT_LOW_VECTORS; + create_mapping(init_maps); + } + flush_cache_all(); flush_tlb_all(); } diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 166a94e861c9..fa3a5dd42a71 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -201,6 +201,11 @@ __v6_setup: mov r10, #0x1f @ domains 0, 1 = manager mcr p15, 0, r10, c3, c0, 0 @ load domain access register mrc p15, 0, r0, c1, c0, 0 @ read control register +#ifdef CONFIG_VFP + mrc p15, 0, r10, c1, c0, 2 + orr r10, r10, #(3 << 20) + mcr p15, 0, r10, c1, c0, 2 @ Enable full access to VFP +#endif ldr r10, cr1_clear @ get mask for bits to clear bic r0, r0, r10 @ clear bits them ldr r10, cr1_set @ get mask for bits to set diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 8f069cf3d6e9..e9aa2ca0b55d 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c @@ -357,7 +357,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, #endif /* Are we from a system call? */ - if (regs->orig_rax >= 0) { + if ((long)regs->orig_rax >= 0) { /* If so, check system call restarting.. */ switch (regs->rax) { case -ERESTART_RESTARTBLOCK: @@ -442,7 +442,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) no_signal: /* Did we come from a system call? */ - if (regs->orig_rax >= 0) { + if ((long)regs->orig_rax >= 0) { /* Restart the system call - no handlers present */ long res = regs->rax; if (res == -ERESTARTNOHAND || diff --git a/drivers/Kconfig b/drivers/Kconfig index 3270c2a3afc6..42e7ef5b241e 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -54,4 +54,6 @@ source "sound/Kconfig" source "drivers/usb/Kconfig" +source "drivers/mmc/Kconfig" + endmenu diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 6b1b5177d912..21becb1e55c1 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -49,4 +49,15 @@ config MMC_PXA If unsure, say N. +config MMC_WBSD + tristate "Winbond W83L51xD SD/MMC Card Interface support" + depends on MMC + help + This selects the Winbond(R) W83L51xD Secure digital and + Multimedia card Interface. + If you have a machine with a integrated W83L518D or W83L519D + SD/MMC card reader, say Y or M here. + + If unsure, say N. + endmenu diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index def01111da68..89510c2086c7 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -17,5 +17,6 @@ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o # obj-$(CONFIG_MMC_ARMMMCI) += mmci.o obj-$(CONFIG_MMC_PXA) += pxamci.o +obj-$(CONFIG_MMC_WBSD) += wbsd.o mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index 224114eeef4b..97ee26d8acef 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c @@ -122,7 +122,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) unsigned int nob = data->blocks; unsigned int timeout; u32 dcmd; - int i, len; + int i; host->data = data; @@ -375,15 +375,14 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (CLOCKRATE / clk > ios->clock) clk <<= 1; host->clkrt = fls(clk) - 1; + pxa_set_cken(CKEN12_MMC, 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); + } else { + pxamci_stop_clock(host); + pxa_set_cken(CKEN12_MMC, 0); } if (host->power_mode != ios->power_mode) { @@ -505,8 +504,6 @@ static int pxamci_probe(struct device *dev) if (host->pdata && host->pdata->init) host->pdata->init(dev, pxamci_detect_irq, mmc); - pxa_set_cken(CKEN12_MMC, 1); - mmc_add_host(mmc); return 0; @@ -545,8 +542,6 @@ static int pxamci_remove(struct device *dev) END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, host->base + MMC_I_MASK); - pxa_set_cken(CKEN12_MMC, 0); - DRCMRRXMMC = 0; DRCMRTXMMC = 0; @@ -555,8 +550,6 @@ static int pxamci_remove(struct device *dev) iounmap(host->base); dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); - pxa_set_cken(CKEN12_MMC, 0); - release_resource(host->res); mmc_free_host(mmc); diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c new file mode 100644 index 000000000000..0871134d3976 --- /dev/null +++ b/drivers/mmc/wbsd.c @@ -0,0 +1,1596 @@ +/* + * linux/drivers/mmc/wbsd.c + * + * Copyright (C) 2004 Pierre Ossman, 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 <linux/config.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/blkdev.h> + +#include <linux/mmc/host.h> +#include <linux/mmc/protocol.h> + +#include <asm/io.h> +#include <asm/dma.h> + +#include "wbsd.h" + +#define DRIVER_NAME "wbsd" +#define DRIVER_VERSION "1.0" + +#ifdef CONFIG_MMC_DEBUG +#define DBG(x...) \ + printk(KERN_DEBUG DRIVER_NAME ": " x) +#define DBGF(f, x...) \ + printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__, ##x) +#else +#define DBG(x...) do { } while (0) +#define DBGF(x...) do { } while (0) +#endif + +static unsigned int io = 0x248; +static unsigned int irq = 6; +static int dma = 2; + +#ifdef CONFIG_MMC_DEBUG +void DBG_REG(int reg, u8 value) +{ + int i; + + printk(KERN_DEBUG "wbsd: Register %d: 0x%02X %3d '%c' ", + reg, (int)value, (int)value, (value < 0x20)?'.':value); + + for (i = 7;i >= 0;i--) + { + if (value & (1 << i)) + printk("x"); + else + printk("."); + } + + printk("\n"); +} +#else +#define DBG_REG(r, v) do {} while (0) +#endif + +/* + * Basic functions + */ + +static inline void wbsd_unlock_config(struct wbsd_host* host) +{ + outb(host->unlock_code, host->config); + outb(host->unlock_code, host->config); +} + +static inline void wbsd_lock_config(struct wbsd_host* host) +{ + outb(LOCK_CODE, host->config); +} + +static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) +{ + outb(reg, host->config); + outb(value, host->config + 1); +} + +static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg) +{ + outb(reg, host->config); + return inb(host->config + 1); +} + +static inline void wbsd_write_index(struct wbsd_host* host, u8 index, u8 value) +{ + outb(index, host->base + WBSD_IDXR); + outb(value, host->base + WBSD_DATAR); +} + +static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index) +{ + outb(index, host->base + WBSD_IDXR); + return inb(host->base + WBSD_DATAR); +} + +/* + * Common routines + */ + +static void wbsd_init_device(struct wbsd_host* host) +{ + u8 setup, ier; + + /* + * Reset chip (SD/MMC part) and fifo. + */ + setup = wbsd_read_index(host, WBSD_IDX_SETUP); + setup |= WBSD_FIFO_RESET | WBSD_SOFT_RESET; + wbsd_write_index(host, WBSD_IDX_SETUP, setup); + + /* + * Read back default clock. + */ + host->clk = wbsd_read_index(host, WBSD_IDX_CLK); + + /* + * Power down port. + */ + outb(WBSD_POWER_N, host->base + WBSD_CSR); + + /* + * Set maximum timeout. + */ + wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F); + + /* + * Enable interesting interrupts. + */ + ier = 0; + ier |= WBSD_EINT_CARD; + ier |= WBSD_EINT_FIFO_THRE; + ier |= WBSD_EINT_CCRC; + ier |= WBSD_EINT_TIMEOUT; + ier |= WBSD_EINT_CRC; + ier |= WBSD_EINT_TC; + + outb(ier, host->base + WBSD_EIR); + + /* + * Clear interrupts. + */ + inb(host->base + WBSD_ISR); +} + +static void wbsd_reset(struct wbsd_host* host) +{ + u8 setup; + + printk(KERN_ERR DRIVER_NAME ": Resetting chip\n"); + + /* + * Soft reset of chip (SD/MMC part). + */ + setup = wbsd_read_index(host, WBSD_IDX_SETUP); + setup |= WBSD_SOFT_RESET; + wbsd_write_index(host, WBSD_IDX_SETUP, setup); +} + +static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq) +{ + unsigned long dmaflags; + + DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode); + + if (host->dma >= 0) + { + /* + * Release ISA DMA controller. + */ + dmaflags = claim_dma_lock(); + disable_dma(host->dma); + clear_dma_ff(host->dma); + release_dma_lock(dmaflags); + + /* + * Disable DMA on host. + */ + wbsd_write_index(host, WBSD_IDX_DMA, 0); + } + + host->mrq = NULL; + + /* + * MMC layer might call back into the driver so first unlock. + */ + spin_unlock(&host->lock); + mmc_request_done(host->mmc, mrq); + spin_lock(&host->lock); +} + +/* + * Scatter/gather functions + */ + +static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data) +{ + struct request* req = data->req; + + /* + * Get info. about SG list from data structure. + */ + host->cur_sg = data->sg; + host->num_sg = data->sg_len; + + host->offset = 0; + host->remain = host->cur_sg->length; +} + +static inline int wbsd_next_sg(struct wbsd_host* host) +{ + /* + * Skip to next SG entry. + */ + host->cur_sg++; + host->num_sg--; + + /* + * Any entries left? + */ + if (host->num_sg > 0) + { + host->offset = 0; + host->remain = host->cur_sg->length; + } + + return host->num_sg; +} + +static inline char* wbsd_kmap_sg(struct wbsd_host* host) +{ + return kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) + + host->cur_sg->offset; +} + +static inline void wbsd_kunmap_sg(struct wbsd_host* host) +{ + kunmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ); +} + +static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data) +{ + unsigned int len, i, size; + struct scatterlist* sg; + char* dmabuf = host->dma_buffer; + char* sgbuf; + + size = host->size; + + sg = data->sg; + len = data->sg_len; + + /* + * Just loop through all entries. Size might not + * be the entire list though so make sure that + * we do not transfer too much. + */ + for (i = 0;i < len;i++) + { + sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; + if (size < sg[i].length) + memcpy(dmabuf, sgbuf, size); + else + memcpy(dmabuf, sgbuf, sg[i].length); + kunmap_atomic(sg[i].page, KM_BIO_SRC_IRQ); + dmabuf += sg[i].length; + + if (size < sg[i].length) + size = 0; + else + size -= sg[i].length; + + if (size == 0) + break; + } + + /* + * Check that we didn't get a request to transfer + * more data than can fit into the SG list. + */ + + BUG_ON(size != 0); + + host->size -= size; +} + +static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data) +{ + unsigned int len, i, size; + struct scatterlist* sg; + char* dmabuf = host->dma_buffer; + char* sgbuf; + + size = host->size; + + sg = data->sg; + len = data->sg_len; + + /* + * Just loop through all entries. Size might not + * be the entire list though so make sure that + * we do not transfer too much. + */ + for (i = 0;i < len;i++) + { + sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; + if (size < sg[i].length) + memcpy(sgbuf, dmabuf, size); + else + memcpy(sgbuf, dmabuf, sg[i].length); + kunmap_atomic(sg[i].page, KM_BIO_SRC_IRQ); + dmabuf += sg[i].length; + + if (size < sg[i].length) + size = 0; + else + size -= sg[i].length; + + if (size == 0) + break; + } + + /* + * Check that we didn't get a request to transfer + * more data than can fit into the SG list. + */ + + BUG_ON(size != 0); + + host->size -= size; +} + +/* + * Command handling + */ + +static inline void wbsd_get_short_reply(struct wbsd_host* host, + struct mmc_command* cmd) +{ + /* + * Correct response type? + */ + if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) + { + cmd->error = MMC_ERR_INVALID; + return; + } + + cmd->resp[0] = + wbsd_read_index(host, WBSD_IDX_RESP12) << 24; + cmd->resp[0] |= + wbsd_read_index(host, WBSD_IDX_RESP13) << 16; + cmd->resp[0] |= + wbsd_read_index(host, WBSD_IDX_RESP14) << 8; + cmd->resp[0] |= + wbsd_read_index(host, WBSD_IDX_RESP15) << 0; + cmd->resp[1] = + wbsd_read_index(host, WBSD_IDX_RESP16) << 24; +} + +static inline void wbsd_get_long_reply(struct wbsd_host* host, + struct mmc_command* cmd) +{ + int i; + + /* + * Correct response type? + */ + if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) + { + cmd->error = MMC_ERR_INVALID; + return; + } + + for (i = 0;i < 4;i++) + { + cmd->resp[i] = + wbsd_read_index(host, WBSD_IDX_RESP1 + i * 4) << 24; + cmd->resp[i] |= + wbsd_read_index(host, WBSD_IDX_RESP2 + i * 4) << 16; + cmd->resp[i] |= + wbsd_read_index(host, WBSD_IDX_RESP3 + i * 4) << 8; + cmd->resp[i] |= + wbsd_read_index(host, WBSD_IDX_RESP4 + i * 4) << 0; + } +} + +static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs); + +static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) +{ + int i; + u8 status, eir, isr; + + DBGF("Sending cmd (%x)\n", cmd->opcode); + + /* + * Disable interrupts as the interrupt routine + * will destroy the contents of ISR. + */ + eir = inb(host->base + WBSD_EIR); + outb(0, host->base + WBSD_EIR); + + /* + * Send the command (CRC calculated by host). + */ + outb(cmd->opcode, host->base + WBSD_CMDR); + for (i = 3;i >= 0;i--) + outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR); + + cmd->error = MMC_ERR_NONE; + + /* + * Wait for the request to complete. + */ + do { + status = wbsd_read_index(host, WBSD_IDX_STATUS); + } while (status & WBSD_CARDTRAFFIC); + + /* + * Do we expect a reply? + */ + if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) + { + /* + * Read back status. + */ + isr = inb(host->base + WBSD_ISR); + + /* Card removed? */ + if (isr & WBSD_INT_CARD) + cmd->error = MMC_ERR_TIMEOUT; + /* Timeout? */ + else if (isr & WBSD_INT_TIMEOUT) + cmd->error = MMC_ERR_TIMEOUT; + /* CRC? */ + else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC)) + cmd->error = MMC_ERR_BADCRC; + /* All ok */ + else + { + if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) + wbsd_get_short_reply(host, cmd); + else + wbsd_get_long_reply(host, cmd); + } + } + + /* + * Restore interrupt mask to previous value. + */ + outb(eir, host->base + WBSD_EIR); + + /* + * Call the interrupt routine to jump start + * interrupts. + */ + wbsd_irq(0, host, NULL); + + DBGF("Sent cmd (%x), res %d\n", cmd->opcode, cmd->error); +} + +/* + * Data functions + */ + +static void wbsd_empty_fifo(struct wbsd_host* host) +{ + struct mmc_data* data = host->mrq->cmd->data; + char* buffer; + + /* + * Handle excessive data. + */ + if (data->bytes_xfered == host->size) + return; + + buffer = wbsd_kmap_sg(host) + host->offset; + + /* + * Drain the fifo. This has a tendency to loop longer + * than the FIFO length (usually one block). + */ + while (!(inb(host->base + WBSD_FSR) & WBSD_FIFO_EMPTY)) + { + *buffer = inb(host->base + WBSD_DFR); + buffer++; + host->offset++; + host->remain--; + + data->bytes_xfered++; + + /* + * Transfer done? + */ + if (data->bytes_xfered == host->size) + { + wbsd_kunmap_sg(host); + return; + } + + /* + * End of scatter list entry? + */ + if (host->remain == 0) + { + wbsd_kunmap_sg(host); + + /* + * Get next entry. Check if last. + */ + if (!wbsd_next_sg(host)) + { + /* + * We should never reach this point. + * It means that we're trying to + * transfer more blocks than can fit + * into the scatter list. + */ + BUG_ON(1); + + host->size = data->bytes_xfered; + + return; + } + + buffer = wbsd_kmap_sg(host); + } + } + + wbsd_kunmap_sg(host); +} + +static void wbsd_fill_fifo(struct wbsd_host* host) +{ + struct mmc_data* data = host->mrq->cmd->data; + char* buffer; + + /* + * Check that we aren't being called after the + * entire buffer has been transfered. + */ + if (data->bytes_xfered == host->size) + return; + + buffer = wbsd_kmap_sg(host) + host->offset; + + /* + * Fill the fifo. This has a tendency to loop longer + * than the FIFO length (usually one block). + */ + while (!(inb(host->base + WBSD_FSR) & WBSD_FIFO_FULL)) + { + outb(*buffer, host->base + WBSD_DFR); + buffer++; + host->offset++; + host->remain--; + + data->bytes_xfered++; + + /* + * Transfer done? + */ + if (data->bytes_xfered == host->size) + { + wbsd_kunmap_sg(host); + return; + } + + /* + * End of scatter list entry? + */ + if (host->remain == 0) + { + wbsd_kunmap_sg(host); + + /* + * Get next entry. Check if last. + */ + if (!wbsd_next_sg(host)) + { + /* + * We should never reach this point. + * It means that we're trying to + * transfer more blocks than can fit + * into the scatter list. + */ + BUG_ON(1); + + host->size = data->bytes_xfered; + + return; + } + + buffer = wbsd_kmap_sg(host); + } + } + + wbsd_kunmap_sg(host); +} + +static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) +{ + u16 blksize; + u8 setup; + unsigned long dmaflags; + + DBGF("blksz %04x blks %04x flags %08x\n", + 1 << data->blksz_bits, data->blocks, data->flags); + DBGF("tsac %d ms nsac %d clk\n", + data->timeout_ns / 1000000, data->timeout_clks); + + /* + * Calculate size. + */ + host->size = data->blocks << data->blksz_bits; + + /* + * Check timeout values for overflow. + * (Yes, some cards cause this value to overflow). + */ + if (data->timeout_ns > 127000000) + wbsd_write_index(host, WBSD_IDX_TAAC, 127); + else + wbsd_write_index(host, WBSD_IDX_TAAC, data->timeout_ns/1000000); + + if (data->timeout_clks > 255) + wbsd_write_index(host, WBSD_IDX_NSAC, 255); + else + wbsd_write_index(host, WBSD_IDX_NSAC, data->timeout_clks); + + /* + * Inform the chip of how large blocks will be + * sent. It needs this to determine when to + * calculate CRC. + * + * Space for CRC must be included in the size. + */ + blksize = (1 << data->blksz_bits) + 2; + + wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); + wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); + + /* + * Clear the FIFO. This is needed even for DMA + * transfers since the chip still uses the FIFO + * internally. + */ + setup = wbsd_read_index(host, WBSD_IDX_SETUP); + setup |= WBSD_FIFO_RESET; + wbsd_write_index(host, WBSD_IDX_SETUP, setup); + + /* + * DMA transfer? + */ + if (host->dma >= 0) + { + /* + * The buffer for DMA is only 64 kB. + */ + BUG_ON(host->size > 0x10000); + if (host->size > 0x10000) + { + data->error = MMC_ERR_INVALID; + return; + } + + /* + * Transfer data from the SG list to + * the DMA buffer. + */ + if (data->flags & MMC_DATA_WRITE) + wbsd_sg_to_dma(host, data); + + /* + * Initialise the ISA DMA controller. + */ + dmaflags = claim_dma_lock(); + disable_dma(host->dma); + clear_dma_ff(host->dma); + if (data->flags & MMC_DATA_READ) + set_dma_mode(host->dma, DMA_MODE_READ); + else + set_dma_mode(host->dma, DMA_MODE_WRITE); + set_dma_addr(host->dma, host->dma_addr); + set_dma_count(host->dma, host->size); + + enable_dma(host->dma); + release_dma_lock(dmaflags); + + /* + * Enable DMA on the host. + */ + wbsd_write_index(host, WBSD_IDX_DMA, + WBSD_DMA_SINGLE | WBSD_DMA_ENABLE); + } + else + { + /* + * This flag is used to keep printk + * output to a minimum. + */ + host->firsterr = 1; + + /* + * Initialise the SG list. + */ + wbsd_init_sg(host, data); + + /* + * Turn off DMA. + */ + wbsd_write_index(host, WBSD_IDX_DMA, 0); + + /* + * Set up FIFO threshold levels (and fill + * buffer if doing a write). + */ + if (data->flags & MMC_DATA_READ) + { + wbsd_write_index(host, WBSD_IDX_FIFOEN, + WBSD_FIFOEN_FULL | 8); + } + else + { + wbsd_write_index(host, WBSD_IDX_FIFOEN, + WBSD_FIFOEN_EMPTY | 8); + wbsd_fill_fifo(host); + } + } + + data->error = MMC_ERR_NONE; +} + +static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) +{ + unsigned long dmaflags; + int count; + + WARN_ON(host->mrq == NULL); + + /* + * Send a stop command if needed. + */ + if (data->stop) + wbsd_send_command(host, data->stop); + + /* + * DMA transfer? + */ + if (host->dma >= 0) + { + /* + * Disable DMA on the host. + */ + wbsd_write_index(host, WBSD_IDX_DMA, 0); + + /* + * Turn of ISA DMA controller. + */ + dmaflags = claim_dma_lock(); + disable_dma(host->dma); + clear_dma_ff(host->dma); + count = get_dma_residue(host->dma); + release_dma_lock(dmaflags); + + /* + * Any leftover data? + */ + if (count) + { + printk(KERN_ERR DRIVER_NAME ": Incomplete DMA " + "transfer. %d bytes left.\n", count); + + data->error = MMC_ERR_FAILED; + } + else + { + /* + * Transfer data from DMA buffer to + * SG list. + */ + if (data->flags & MMC_DATA_READ) + wbsd_dma_to_sg(host, data); + + data->bytes_xfered = host->size; + } + } + + DBGF("Ending data transfer (%d bytes)\n", data->bytes_xfered); + + wbsd_request_end(host, host->mrq); +} + +/* + * MMC Callbacks + */ + +static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) +{ + struct wbsd_host* host = mmc_priv(mmc); + struct mmc_command* cmd; + + /* + * Disable tasklets to avoid a deadlock. + */ + spin_lock_bh(&host->lock); + + BUG_ON(host->mrq != NULL); + + cmd = mrq->cmd; + + host->mrq = mrq; + + /* + * If there is no card in the slot then + * timeout immediatly. + */ + if (!(inb(host->base + WBSD_CSR) & WBSD_CARDPRESENT)) + { + cmd->error = MMC_ERR_TIMEOUT; + goto done; + } + + /* + * Does the request include data? + */ + if (cmd->data) + { + wbsd_prepare_data(host, cmd->data); + + if (cmd->data->error != MMC_ERR_NONE) + goto done; + } + + wbsd_send_command(host, cmd); + + /* + * If this is a data transfer the request + * will be finished after the data has + * transfered. + */ + if (cmd->data && (cmd->error == MMC_ERR_NONE)) + { + spin_unlock_bh(&host->lock); + + return; + } + +done: + wbsd_request_end(host, mrq); + + spin_unlock_bh(&host->lock); +} + +static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) +{ + struct wbsd_host* host = mmc_priv(mmc); + u8 clk, setup, pwr; + + DBGF("clock %uHz busmode %u powermode %u Vdd %u\n", + ios->clock, ios->bus_mode, ios->power_mode, ios->vdd); + + spin_lock_bh(&host->lock); + + /* + * Reset the chip on each power off. + * Should clear out any weird states. + */ + if (ios->power_mode == MMC_POWER_OFF) + wbsd_init_device(host); + + if (ios->clock >= 24000000) + clk = WBSD_CLK_24M; + else if (ios->clock >= 16000000) + clk = WBSD_CLK_16M; + else if (ios->clock >= 12000000) + clk = WBSD_CLK_12M; + else + clk = WBSD_CLK_375K; + + /* + * Only write to the clock register when + * there is an actual change. + */ + if (clk != host->clk) + { + wbsd_write_index(host, WBSD_IDX_CLK, clk); + host->clk = clk; + } + + if (ios->power_mode != MMC_POWER_OFF) + { + /* + * Power up card. + */ + pwr = inb(host->base + WBSD_CSR); + pwr &= ~WBSD_POWER_N; + outb(pwr, host->base + WBSD_CSR); + + /* + * This behaviour is stolen from the + * Windows driver. Don't know why, but + * it is needed. + */ + setup = wbsd_read_index(host, WBSD_IDX_SETUP); + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) + setup |= WBSD_DAT3_H; + else + setup &= ~WBSD_DAT3_H; + wbsd_write_index(host, WBSD_IDX_SETUP, setup); + + mdelay(1); + } + + spin_unlock_bh(&host->lock); +} + +/* + * Tasklets + */ + +inline static struct mmc_data* wbsd_get_data(struct wbsd_host* host) +{ + WARN_ON(!host->mrq); + if (!host->mrq) + return NULL; + + WARN_ON(!host->mrq->cmd); + if (!host->mrq->cmd) + return NULL; + + WARN_ON(!host->mrq->cmd->data); + if (!host->mrq->cmd->data) + return NULL; + + return host->mrq->cmd->data; +} + +static void wbsd_tasklet_card(unsigned long param) +{ + struct wbsd_host* host = (struct wbsd_host*)param; + u8 csr; + + spin_lock(&host->lock); + + csr = inb(host->base + WBSD_CSR); + WARN_ON(csr == 0xff); + + if (csr & WBSD_CARDPRESENT) + DBG("Card inserted\n"); + else + { + DBG("Card removed\n"); + + if (host->mrq) + { + printk(KERN_ERR DRIVER_NAME + ": Card removed during transfer!\n"); + wbsd_reset(host); + + host->mrq->cmd->error = MMC_ERR_FAILED; + tasklet_schedule(&host->finish_tasklet); + } + } + + /* + * Unlock first since we might get a call back. + */ + spin_unlock(&host->lock); + + mmc_detect_change(host->mmc); +} + +static void wbsd_tasklet_fifo(unsigned long param) +{ + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; + + spin_lock(&host->lock); + + if (!host->mrq) + goto end; + + data = wbsd_get_data(host); + if (!data) + goto end; + + if (data->flags & MMC_DATA_WRITE) + wbsd_fill_fifo(host); + else + wbsd_empty_fifo(host); + + /* + * Done? + */ + if (host->size == data->bytes_xfered) + { + wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); + tasklet_schedule(&host->finish_tasklet); + } + +end: + spin_unlock(&host->lock); +} + +static void wbsd_tasklet_crc(unsigned long param) +{ + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; + + spin_lock(&host->lock); + + WARN_ON(!host->mrq); + if (!host->mrq) + goto end; + + data = wbsd_get_data(host); + if (!data) + goto end; + + DBGF("CRC error\n"); + + data->error = MMC_ERR_BADCRC; + + tasklet_schedule(&host->finish_tasklet); + +end: + spin_unlock(&host->lock); +} + +static void wbsd_tasklet_timeout(unsigned long param) +{ + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; + + spin_lock(&host->lock); + + WARN_ON(!host->mrq); + if (!host->mrq) + goto end; + + data = wbsd_get_data(host); + if (!data) + goto end; + + DBGF("Timeout\n"); + + data->error = MMC_ERR_TIMEOUT; + + tasklet_schedule(&host->finish_tasklet); + +end: + spin_unlock(&host->lock); +} + +static void wbsd_tasklet_finish(unsigned long param) +{ + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; + + spin_lock(&host->lock); + + WARN_ON(!host->mrq); + if (!host->mrq) + goto end; + + data = wbsd_get_data(host); + if (!data) + goto end; + + wbsd_finish_data(host, data); + +end: + spin_unlock(&host->lock); +} + +static void wbsd_tasklet_block(unsigned long param) +{ + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; + + spin_lock(&host->lock); + + if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != + WBSD_CRC_OK) + { + data = wbsd_get_data(host); + if (!data) + goto end; + + DBGF("CRC error\n"); + + data->error = MMC_ERR_BADCRC; + + tasklet_schedule(&host->finish_tasklet); + } + +end: + spin_unlock(&host->lock); +} + +/* + * Interrupt handling + */ + +static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct wbsd_host* host = dev_id; + int isr; + + isr = inb(host->base + WBSD_ISR); + + /* + * Was it actually our hardware that caused the interrupt? + */ + if (isr == 0xff || isr == 0x00) + return IRQ_NONE; + + /* + * Schedule tasklets as needed. + */ + if (isr & WBSD_INT_CARD) + tasklet_schedule(&host->card_tasklet); + if (isr & WBSD_INT_FIFO_THRE) + tasklet_hi_schedule(&host->fifo_tasklet); + if (isr & WBSD_INT_CRC) + tasklet_hi_schedule(&host->crc_tasklet); + if (isr & WBSD_INT_TIMEOUT) + tasklet_hi_schedule(&host->timeout_tasklet); + if (isr & WBSD_INT_BUSYEND) + tasklet_hi_schedule(&host->block_tasklet); + if (isr & WBSD_INT_TC) + tasklet_schedule(&host->finish_tasklet); + + return IRQ_HANDLED; +} + +/* + * Support functions for probe + */ + +static int wbsd_scan(struct wbsd_host* host) +{ + int i, j, k; + int id; + + /* + * Iterate through all ports, all codes to + * find hardware that is in our known list. + */ + for (i = 0;i < sizeof(config_ports)/sizeof(int);i++) + { + if (!request_region(config_ports[i], 2, DRIVER_NAME)) + continue; + + for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++) + { + id = 0xFFFF; + + outb(unlock_codes[j], config_ports[i]); + outb(unlock_codes[j], config_ports[i]); + + outb(WBSD_CONF_ID_HI, config_ports[i]); + id = inb(config_ports[i] + 1) << 8; + + outb(WBSD_CONF_ID_LO, config_ports[i]); + id |= inb(config_ports[i] + 1); + + for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++) + { + if (id == valid_ids[k]) + { + host->chip_id = id; + host->config = config_ports[i]; + host->unlock_code = unlock_codes[i]; + + return 0; + } + } + + if (id != 0xFFFF) + { + DBG("Unknown hardware (id %x) found at %x\n", + id, config_ports[i]); + } + + outb(LOCK_CODE, config_ports[i]); + } + + release_region(config_ports[i], 2); + } + + return -ENODEV; +} + +static int wbsd_request_regions(struct wbsd_host* host) +{ + if (io & 0x7) + return -EINVAL; + + if (!request_region(io, 8, DRIVER_NAME)) + return -EIO; + + host->base = io; + + return 0; +} + +static void wbsd_release_regions(struct wbsd_host* host) +{ + if (host->base) + release_region(host->base, 8); + + if (host->config) + release_region(host->config, 2); +} + +static void wbsd_init_dma(struct wbsd_host* host) +{ + host->dma = -1; + + if (dma < 0) + return; + + if (request_dma(dma, DRIVER_NAME)) + goto err; + + /* + * We need to allocate a special buffer in + * order for ISA to be able to DMA to it. + */ + host->dma_buffer = kmalloc(65536, + GFP_NOIO | GFP_DMA | __GFP_REPEAT | __GFP_NOWARN); + if (!host->dma_buffer) + goto free; + + /* + * Translate the address to a physical address. + */ + host->dma_addr = isa_virt_to_bus(host->dma_buffer); + + /* + * ISA DMA must be aligned on a 64k basis. + */ + if ((host->dma_addr & 0xffff) != 0) + goto kfree; + /* + * ISA cannot access memory above 16 MB. + */ + else if (host->dma_addr >= 0x1000000) + goto kfree; + + host->dma = dma; + + return; + +kfree: + /* + * If we've gotten here then there is some kind of alignment bug + */ + BUG_ON(1); + + kfree(host->dma_buffer); + host->dma_buffer = NULL; + +free: + free_dma(dma); + +err: + printk(KERN_WARNING DRIVER_NAME ": Unable to allocate DMA %d. " + "Falling back on FIFO.\n", dma); +} + +static struct mmc_host_ops wbsd_ops = { + .request = wbsd_request, + .set_ios = wbsd_set_ios, +}; + +/* + * Device probe + */ + +static int wbsd_probe(struct device* dev) +{ + struct wbsd_host* host = NULL; + struct mmc_host* mmc = NULL; + int ret; + + /* + * Allocate MMC structure. + */ + mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev); + if (!mmc) + return -ENOMEM; + + host = mmc_priv(mmc); + host->mmc = mmc; + + /* + * Scan for hardware. + */ + ret = wbsd_scan(host); + if (ret) + goto freemmc; + + /* + * Reset the chip. + */ + wbsd_write_config(host, WBSD_CONF_SWRST, 1); + wbsd_write_config(host, WBSD_CONF_SWRST, 0); + + /* + * Allocate I/O ports. + */ + ret = wbsd_request_regions(host); + if (ret) + goto release; + + /* + * Set host parameters. + */ + mmc->ops = &wbsd_ops; + mmc->f_min = 375000; + mmc->f_max = 24000000; + mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; + + spin_lock_init(&host->lock); + + /* + * Select SD/MMC function. + */ + wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); + + /* + * Set up card detection. + */ + wbsd_write_config(host, WBSD_CONF_PINS, 0x02); + + /* + * Configure I/O port. + */ + wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8); + wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff); + + /* + * Allocate interrupt. + */ + ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host); + if (ret) + goto release; + + host->irq = irq; + + /* + * Set up tasklets. + */ + tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host); + tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host); + tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host); + tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); + tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); + tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); + + /* + * Configure interrupt. + */ + wbsd_write_config(host, WBSD_CONF_IRQ, host->irq); + + /* + * Allocate DMA. + */ + wbsd_init_dma(host); + + /* + * If all went well, then configure DMA. + */ + if (host->dma >= 0) + wbsd_write_config(host, WBSD_CONF_DRQ, host->dma); + + /* + * Maximum number of segments. Worst case is one sector per segment + * so this will be 64kB/512. + */ + mmc->max_hw_segs = NR_SG; + mmc->max_phys_segs = NR_SG; + + /* + * Maximum number of sectors in one transfer. Also limited by 64kB + * buffer. + */ + mmc->max_sectors = 128; + + /* + * Maximum segment size. Could be one segment with the maximum number + * of segments. + */ + mmc->max_seg_size = mmc->max_sectors * 512; + + /* + * Enable chip. + */ + wbsd_write_config(host, WBSD_CONF_ENABLE, 1); + + /* + * Power up chip. + */ + wbsd_write_config(host, WBSD_CONF_POWER, 0x20); + + /* + * Power Management stuff. No idea how this works. + * Not tested. + */ +#ifdef CONFIG_PM + wbsd_write_config(host, WBSD_CONF_PME, 0xA0); +#endif + + /* + * Reset the chip into a known state. + */ + wbsd_init_device(host); + + dev_set_drvdata(dev, mmc); + + /* + * Add host to MMC layer. + */ + mmc_add_host(mmc); + + printk(KERN_INFO "%s: W83L51xD id %x at 0x%x irq %d dma %d\n", + mmc->host_name, (int)host->chip_id, (int)host->base, + (int)host->irq, (int)host->dma); + + return 0; + +release: + wbsd_release_regions(host); + +freemmc: + mmc_free_host(mmc); + + return ret; +} + +/* + * Device remove + */ + +static int wbsd_remove(struct device* dev) +{ + struct mmc_host* mmc = dev_get_drvdata(dev); + struct wbsd_host* host; + + if (!mmc) + return 0; + + host = mmc_priv(mmc); + + /* + * Unregister host with MMC layer. + */ + mmc_remove_host(mmc); + + /* + * Power down the SD/MMC function. + */ + wbsd_unlock_config(host); + wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); + wbsd_write_config(host, WBSD_CONF_ENABLE, 0); + wbsd_lock_config(host); + + /* + * Free resources. + */ + if (host->dma_buffer) + kfree(host->dma_buffer); + + if (host->dma >= 0) + free_dma(host->dma); + + free_irq(host->irq, host); + + tasklet_kill(&host->card_tasklet); + tasklet_kill(&host->fifo_tasklet); + tasklet_kill(&host->crc_tasklet); + tasklet_kill(&host->timeout_tasklet); + tasklet_kill(&host->finish_tasklet); + tasklet_kill(&host->block_tasklet); + + wbsd_release_regions(host); + + mmc_free_host(mmc); + + return 0; +} + +/* + * Power management + */ + +#ifdef CONFIG_PM +static int wbsd_suspend(struct device *dev, u32 state, u32 level) +{ + DBGF("Not yet supported\n"); + + return 0; +} + +static int wbsd_resume(struct device *dev, u32 level) +{ + DBGF("Not yet supported\n"); + + return 0; +} +#else +#define wbsd_suspend NULL +#define wbsd_resume NULL +#endif + +static void wbsd_release(struct device *dev) +{ +} + +static struct platform_device wbsd_device = { + .name = DRIVER_NAME, + .id = -1, + .dev = { + .release = wbsd_release, + }, +}; + +static struct device_driver wbsd_driver = { + .name = DRIVER_NAME, + .bus = &platform_bus_type, + .probe = wbsd_probe, + .remove = wbsd_remove, + + .suspend = wbsd_suspend, + .resume = wbsd_resume, +}; + +/* + * Module loading/unloading + */ + +static int __init wbsd_drv_init(void) +{ + int result; + + printk(KERN_INFO DRIVER_NAME + ": Winbond W83L51xD SD/MMC card interface driver, " + DRIVER_VERSION "\n"); + printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); + + result = driver_register(&wbsd_driver); + if (result < 0) + return result; + + result = platform_device_register(&wbsd_device); + if (result < 0) + return result; + + return 0; +} + +static void __exit wbsd_drv_exit(void) +{ + platform_device_unregister(&wbsd_device); + + driver_unregister(&wbsd_driver); + + DBG("unloaded\n"); +} + +module_init(wbsd_drv_init); +module_exit(wbsd_drv_exit); +module_param(io, uint, 0444); +module_param(irq, uint, 0444); +module_param(dma, int, 0444); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver"); + +MODULE_PARM_DESC(io, "I/O base to allocate. Must be 8 byte aligned. (default 0x248)"); +MODULE_PARM_DESC(irq, "IRQ to allocate. (default 6)"); +MODULE_PARM_DESC(dma, "DMA channel to allocate. -1 for no DMA. (default 2)"); diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h new file mode 100644 index 000000000000..51652c34197e --- /dev/null +++ b/drivers/mmc/wbsd.h @@ -0,0 +1,177 @@ +/* + * linux/drivers/mmc/wbsd.h + * + * Copyright (C) 2004 Pierre Ossman, 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. + */ + +const int config_ports[] = { 0x2E, 0x4E }; +const int unlock_codes[] = { 0x83, 0x87 }; + +const int valid_ids[] = { + 0x7112, + }; + +#define LOCK_CODE 0xAA + +#define WBSD_CONF_SWRST 0x02 +#define WBSD_CONF_DEVICE 0x07 +#define WBSD_CONF_ID_HI 0x20 +#define WBSD_CONF_ID_LO 0x21 +#define WBSD_CONF_POWER 0x22 +#define WBSD_CONF_PME 0x23 +#define WBSD_CONF_PMES 0x24 + +#define WBSD_CONF_ENABLE 0x30 +#define WBSD_CONF_PORT_HI 0x60 +#define WBSD_CONF_PORT_LO 0x61 +#define WBSD_CONF_IRQ 0x70 +#define WBSD_CONF_DRQ 0x74 + +#define WBSD_CONF_PINS 0xF0 + +#define DEVICE_SD 0x03 + +#define WBSD_CMDR 0x00 +#define WBSD_DFR 0x01 +#define WBSD_EIR 0x02 +#define WBSD_ISR 0x03 +#define WBSD_FSR 0x04 +#define WBSD_IDXR 0x05 +#define WBSD_DATAR 0x06 +#define WBSD_CSR 0x07 + +#define WBSD_EINT_CARD 0x40 +#define WBSD_EINT_FIFO_THRE 0x20 +#define WBSD_EINT_CCRC 0x10 +#define WBSD_EINT_TIMEOUT 0x08 +#define WBSD_EINT_PROGEND 0x04 +#define WBSD_EINT_CRC 0x02 +#define WBSD_EINT_TC 0x01 + +#define WBSD_INT_PENDING 0x80 +#define WBSD_INT_CARD 0x40 +#define WBSD_INT_FIFO_THRE 0x20 +#define WBSD_INT_CRC 0x10 +#define WBSD_INT_TIMEOUT 0x08 +#define WBSD_INT_PROGEND 0x04 +#define WBSD_INT_BUSYEND 0x02 +#define WBSD_INT_TC 0x01 + +#define WBSD_FIFO_EMPTY 0x80 +#define WBSD_FIFO_FULL 0x40 +#define WBSD_FIFO_EMTHRE 0x20 +#define WBSD_FIFO_FUTHRE 0x10 +#define WBSD_FIFO_SZMASK 0x0F + +#define WBSD_MSLED 0x20 +#define WBSD_POWER_N 0x10 +#define WBSD_WRPT 0x04 +#define WBSD_CARDPRESENT 0x01 + +#define WBSD_IDX_CLK 0x01 +#define WBSD_IDX_PBSMSB 0x02 +#define WBSD_IDX_TAAC 0x03 +#define WBSD_IDX_NSAC 0x04 +#define WBSD_IDX_PBSLSB 0x05 +#define WBSD_IDX_SETUP 0x06 +#define WBSD_IDX_DMA 0x07 +#define WBSD_IDX_FIFOEN 0x08 +#define WBSD_IDX_STATUS 0x10 +#define WBSD_IDX_RSPLEN 0x1E +#define WBSD_IDX_RESP0 0x1F +#define WBSD_IDX_RESP1 0x20 +#define WBSD_IDX_RESP2 0x21 +#define WBSD_IDX_RESP3 0x22 +#define WBSD_IDX_RESP4 0x23 +#define WBSD_IDX_RESP5 0x24 +#define WBSD_IDX_RESP6 0x25 +#define WBSD_IDX_RESP7 0x26 +#define WBSD_IDX_RESP8 0x27 +#define WBSD_IDX_RESP9 0x28 +#define WBSD_IDX_RESP10 0x29 +#define WBSD_IDX_RESP11 0x2A +#define WBSD_IDX_RESP12 0x2B +#define WBSD_IDX_RESP13 0x2C +#define WBSD_IDX_RESP14 0x2D +#define WBSD_IDX_RESP15 0x2E +#define WBSD_IDX_RESP16 0x2F +#define WBSD_IDX_CRCSTATUS 0x30 +#define WBSD_IDX_ISR 0x3F + +#define WBSD_CLK_375K 0x00 +#define WBSD_CLK_12M 0x01 +#define WBSD_CLK_16M 0x02 +#define WBSD_CLK_24M 0x03 + +#define WBSD_DAT3_H 0x08 +#define WBSD_FIFO_RESET 0x04 +#define WBSD_SOFT_RESET 0x02 +#define WBSD_INC_INDEX 0x01 + +#define WBSD_DMA_SINGLE 0x02 +#define WBSD_DMA_ENABLE 0x01 + +#define WBSD_FIFOEN_EMPTY 0x20 +#define WBSD_FIFOEN_FULL 0x10 +#define WBSD_FIFO_THREMASK 0x0F + +#define WBSD_BUSY 0x20 +#define WBSD_CARDTRAFFIC 0x04 +#define WBSD_SENDCMD 0x02 +#define WBSD_RECVRES 0x01 + +#define WBSD_RSP_SHORT 0x00 +#define WBSD_RSP_LONG 0x01 + +#define WBSD_CRC_MASK 0x1F +#define WBSD_CRC_OK 0x05 /* S010E (00101) */ +#define WBSD_CRC_FAIL 0x0B /* S101E (01011) */ + + +/* 64kB / 512 */ +#define NR_SG 128 + +struct wbsd_host +{ + struct mmc_host* mmc; /* MMC structure */ + + spinlock_t lock; /* Mutex */ + + struct mmc_request* mrq; /* Current request */ + + struct scatterlist sg[NR_SG]; /* SG list */ + struct scatterlist* cur_sg; /* Current SG entry */ + unsigned int num_sg; /* Number of entries left */ + + unsigned int offset; /* Offset into current entry */ + unsigned int remain; /* Data left in curren entry */ + + int size; /* Total size of transfer */ + + char* dma_buffer; /* ISA DMA buffer */ + dma_addr_t dma_addr; /* Physical address for same */ + + int firsterr; /* See fifo functions */ + + u8 clk; /* Current clock speed */ + + int config; /* Config port */ + u8 unlock_code; /* Code to unlock config */ + + int chip_id; /* ID of controller */ + + int base; /* I/O port base */ + int irq; /* Interrupt */ + int dma; /* DMA channel */ + + struct tasklet_struct card_tasklet; /* Tasklet structures */ + struct tasklet_struct fifo_tasklet; + struct tasklet_struct crc_tasklet; + struct tasklet_struct timeout_tasklet; + struct tasklet_struct finish_tasklet; + struct tasklet_struct block_tasklet; +}; diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 3ed8b2c68fc9..127fb89250ce 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -663,10 +663,9 @@ static void __devexit aac_remove_one(struct pci_dev *pdev) kfree(aac->fibs); + list_del(&aac->entry); scsi_host_put(shost); pci_disable_device(pdev); - - list_del(&aac->entry); } static struct pci_driver aac_pci_driver = { diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index eda703d736b9..1a5c910429c8 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1140,6 +1140,10 @@ static struct scsi_host_template imm_template = { .use_clustering = ENABLE_CLUSTERING, .can_queue = 1, .slave_alloc = imm_adjust_queue, + .unchecked_isa_dma = 1, /* imm cannot deal with highmem, so + * this is an easy trick to ensure + * all io pages for this host reside + * in low memory */ }; /*************************************************************************** diff --git a/drivers/scsi/megaraid/megaraid_ioctl.h b/drivers/scsi/megaraid/megaraid_ioctl.h index bebc8e1915ea..4bf0430dd5b3 100644 --- a/drivers/scsi/megaraid/megaraid_ioctl.h +++ b/drivers/scsi/megaraid/megaraid_ioctl.h @@ -142,7 +142,7 @@ typedef struct uioc { caddr_t buf_vaddr; dma_addr_t buf_paddr; - uint8_t pool_index; + int8_t pool_index; uint8_t free_buf; uint8_t timedout; diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index ee2b1ff5c039..301ebef9f173 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_mm.c - * Version : v2.20.2.2 (Nov 04 2004) + * Version : v2.20.2.3 (Dec 09 2004) * * Common management module */ @@ -614,23 +614,27 @@ mraid_mm_dealloc_kioc(mraid_mmadp_t *adp, uioc_t *kioc) mm_dmapool_t *pool; unsigned long flags; - pool = &adp->dma_pool_list[kioc->pool_index]; + if (kioc->pool_index != -1) { + pool = &adp->dma_pool_list[kioc->pool_index]; - /* This routine may be called in non-isr context also */ - spin_lock_irqsave(&pool->lock, flags); - - /* - * While attaching the dma buffer, if we didn't get the required - * buffer from the pool, we would have allocated it at the run time - * and set the free_buf flag. We must free that buffer. Otherwise, - * just mark that the buffer is not in use - */ - if (kioc->free_buf == 1) - pci_pool_free(pool->handle, kioc->buf_vaddr, kioc->buf_paddr); - else - pool->in_use = 0; + /* This routine may be called in non-isr context also */ + spin_lock_irqsave(&pool->lock, flags); - spin_unlock_irqrestore(&pool->lock, flags); + /* + * While attaching the dma buffer, if we didn't get the + * required buffer from the pool, we would have allocated + * it at the run time and set the free_buf flag. We must + * free that buffer. Otherwise, just mark that the buffer is + * not in use + */ + if (kioc->free_buf == 1) + pci_pool_free(pool->handle, kioc->buf_vaddr, + kioc->buf_paddr); + else + pool->in_use = 0; + + spin_unlock_irqrestore(&pool->lock, flags); + } /* Return the kioc to the free pool */ spin_lock_irqsave(&adp->kioc_pool_lock, flags); diff --git a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h index 173550854cb8..28f1fb4952af 100644 --- a/drivers/scsi/megaraid/megaraid_mm.h +++ b/drivers/scsi/megaraid/megaraid_mm.h @@ -29,10 +29,9 @@ #include "megaraid_ioctl.h" -#define LSI_COMMON_MOD_VERSION "2.20.2.2" +#define LSI_COMMON_MOD_VERSION "2.20.2.3" #define LSI_COMMON_MOD_EXT_VERSION \ - "(Release Date: Thu Nov 4 17:46:29 EST 2004)" - + "(Release Date: Thu Dec 9 19:02:14 EST 2004)" #define LSI_DBGLVL dbglevel diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c index 26d6d384355e..87d0cea8d664 100644 --- a/drivers/scsi/qla2xxx/qla_rscn.c +++ b/drivers/scsi/qla2xxx/qla_rscn.c @@ -47,8 +47,6 @@ /* Local Prototypes. */ static inline uint32_t qla2x00_to_handle(uint16_t, uint16_t, uint16_t); static inline uint16_t qla2x00_handle_to_idx(uint32_t); -static inline uint16_t qla2x00_handle_to_iter(uint32_t); -static inline uint16_t qla2x00_handle_to_type(uint32_t); static inline uint32_t qla2x00_iodesc_to_handle(struct io_descriptor *); static inline struct io_descriptor *qla2x00_handle_to_iodesc(scsi_qla_host_t *, uint32_t); @@ -130,30 +128,6 @@ qla2x00_handle_to_idx(uint32_t handle) } /** - * qla2x00_handle_to_type() - Retrive the descriptor type for a given handle. - * @handle: descriptor handle - * - * Returns the descriptor type specified by the @handle. - */ -static inline uint16_t -qla2x00_handle_to_type(uint32_t handle) -{ - return ((uint16_t)(((handle) >> HDL_TYPE_SHIFT) & HDL_TYPE_MASK)); -} - -/** - * qla2x00_handle_to_iter() - Retrive the rolling signature for a given handle. - * @handle: descriptor handle - * - * Returns the signature specified by the @handle. - */ -static inline uint16_t -qla2x00_handle_to_iter(uint32_t handle) -{ - return ((uint16_t)(((handle) >> HDL_ITER_SHIFT) & HDL_ITER_MASK)); -} - -/** * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle. * @iodesc: io descriptor * diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 31fcbafa0cba..0d10f106701d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -198,8 +198,8 @@ static struct scsi_disk *scsi_disk_get(struct gendisk *disk) static void scsi_disk_put(struct scsi_disk *sdkp) { down(&sd_ref_sem); - scsi_device_put(sdkp->device); kref_put(&sdkp->kref, scsi_disk_release); + scsi_device_put(sdkp->device); up(&sd_ref_sem); } diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index da06adf48834..dc9d740da8b0 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -156,8 +156,8 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk) static inline void scsi_cd_put(struct scsi_cd *cd) { down(&sr_ref_sem); - scsi_device_put(cd->device); kref_put(&cd->kref, sr_kref_release); + scsi_device_put(cd->device); up(&sr_ref_sem); } diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h index 2a75545a2d04..0dbac30ed127 100644 --- a/include/asm-arm/mach/map.h +++ b/include/asm-arm/mach/map.h @@ -21,9 +21,10 @@ struct meminfo; #define MT_DEVICE 0 #define MT_CACHECLEAN 1 #define MT_MINICLEAN 2 -#define MT_VECTORS 3 -#define MT_MEMORY 4 -#define MT_ROM 5 +#define MT_LOW_VECTORS 3 +#define MT_HIGH_VECTORS 4 +#define MT_MEMORY 5 +#define MT_ROM 6 extern void create_memmap_holes(struct meminfo *); extern void memtable_init(struct meminfo *); diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 53cd8d3a08f2..77d0dcf0b713 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -128,9 +128,9 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ extern unsigned int user_debug; #if __LINUX_ARM_ARCH__ >= 4 -#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0) +#define vectors_high() (cr_alignment & CR_V) #else -#define vectors_base() (0) +#define vectors_high() (0) #endif #define mb() __asm__ __volatile__ ("" : : : "memory") diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index fd9e0535bad5..a0f598569886 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3029,7 +3029,7 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_opt *tp, int estab) if(tp->snd_wscale > 14) { if(net_ratelimit()) printk(KERN_INFO "tcp_parse_options: Illegal window " - "scaling value %d >14 received.", + "scaling value %d >14 received.\n", tp->snd_wscale); tp->snd_wscale = 14; } diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 79b2a4001149..a6de2b46a0d1 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -418,6 +418,7 @@ bad_ret: int tcf_action_copy_stats (struct sk_buff *skb,struct tc_action *a) { + int err; struct gnet_dump d; struct tcf_act_hdr *h = a->priv; @@ -428,7 +429,14 @@ int tcf_action_copy_stats (struct sk_buff *skb,struct tc_action *a) if (NULL == h) goto errout; - if (gnet_stats_start_copy(skb, TCA_ACT_STATS, h->stats_lock, &d) < 0) + if (a->type == TCA_OLD_COMPAT) + err = gnet_stats_start_copy_compat(skb, TCA_ACT_STATS, + TCA_STATS, TCA_XSTATS, h->stats_lock, &d); + else + err = gnet_stats_start_copy(skb, TCA_ACT_STATS, + h->stats_lock, &d); + + if (err < 0) goto errout; if (NULL != a->ops && NULL != a->ops->get_stats) diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 709cf821252a..c520afb5b045 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -160,7 +160,8 @@ static int tcindex_init(struct tcf_proto *tp) } -static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) +static int +__tcindex_delete(struct tcf_proto *tp, unsigned long arg, int lock) { struct tcindex_data *p = PRIV(tp); struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg; @@ -182,9 +183,11 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) found: f = *walk; - tcf_tree_lock(tp); + if (lock) + tcf_tree_lock(tp); *walk = f->next; - tcf_tree_unlock(tp); + if (lock) + tcf_tree_unlock(tp); } tcf_unbind_filter(tp, &r->res); #ifdef CONFIG_NET_CLS_POLICE @@ -195,6 +198,10 @@ found: return 0; } +static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) +{ + return __tcindex_delete(tp, arg, 1); +} /* * There are no parameters for tcindex_init, so we overload tcindex_change @@ -384,7 +391,7 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker) static int tcindex_destroy_element(struct tcf_proto *tp, unsigned long arg, struct tcf_walker *walker) { - return tcindex_delete(tp,arg); + return __tcindex_delete(tp, arg, 0); } |
