[oe] [PATCH v2 1/3] topas910: Add BSP patch against 2.6.32.9 and make it default.
Matthias Günther
matgnt at gmail.com
Mon Apr 26 22:41:37 UTC 2010
---
recipes/linux/linux-2.6.32/topas910/defconfig | 1359 +
.../topas910/linux-2.6.32.9_topas910.patch |52973 ++++++++++++++++++++
recipes/linux/linux_2.6.26.bb | 2 +-
recipes/linux/linux_2.6.32.bb | 6 +-
4 files changed, 54338 insertions(+), 2 deletions(-)
create mode 100644 recipes/linux/linux-2.6.32/topas910/defconfig
create mode 100644 recipes/linux/linux-2.6.32/topas910/linux-2.6.32.9_topas910.patch
diff --git a/recipes/linux/linux-2.6.32/topas910/defconfig b/recipes/linux/linux-2.6.32/topas910/defconfig
new file mode 100644
index 0000000..b9f3d4c
--- /dev/null
+++ b/recipes/linux/linux-2.6.32/topas910/defconfig
@@ -0,0 +1,1359 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Thu Dec 3 11:39:59 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_SLOW_WORK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+CONFIG_ARCH_TMPA910=y
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_CPU_TMPA910=y
+# CONFIG_CPU_TMPA900 is not set
+CONFIG_MACH_TOPAS910=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="mem=63M mtdparts=physmap-flash.0:384k(bootloader)ro,5120k(kernel),-(root) root=/dev/mtdblock2 rdinit=/init"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA 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_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+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=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_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# 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 is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_COMPAT=y
+CONFIG_MTD_PHYSMAP_START=0x20000000
+CONFIG_MTD_PHYSMAP_LEN=0x02000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM 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
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_TMPA910=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON 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_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_DEBUGLEVEL=0
+# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+CONFIG_TOUCHSCREEN_TMPA910=y
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_TMPA910=y
+CONFIG_SERIAL_TMPA910_CONSOLE=y
+CONFIG_SERIAL_TMPA910_CONSOLE_PREFERED=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_TMPA910=y
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 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
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_TMPA910=y
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_TMPA910=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_MINI_4x6=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_ARM=y
+# CONFIG_SND_TMPA910_WM8976 is not set
+CONFIG_SND_TMPA910_PCM1773=y
+CONFIG_SND_SPI=y
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+CONFIG_USB_GADGET_TMPA910=y
+CONFIG_USB_TMPA910=y
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL 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_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_USB_G_PRINTER=m
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# 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_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# 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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL 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_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/recipes/linux/linux-2.6.32/topas910/linux-2.6.32.9_topas910.patch b/recipes/linux/linux-2.6.32/topas910/linux-2.6.32.9_topas910.patch
new file mode 100644
index 0000000..feccfe9
--- /dev/null
+++ b/recipes/linux/linux-2.6.32/topas910/linux-2.6.32.9_topas910.patch
@@ -0,0 +1,52973 @@
+diff --git a/Documentation/Changes b/Documentation/Changes
+index f08b313..6d0f1ef 100644
+--- a/Documentation/Changes
++++ b/Documentation/Changes
+@@ -49,8 +49,6 @@ o oprofile 0.9 # oprofiled --version
+ o udev 081 # udevinfo -V
+ o grub 0.93 # grub --version
+ o mcelog 0.6
+-o iptables 1.4.1 # iptables -V
+-
+
+ Kernel compilation
+ ==================
+diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
+index 50075df..ab8300f 100644
+--- a/Documentation/DocBook/Makefile
++++ b/Documentation/DocBook/Makefile
+@@ -32,10 +32,10 @@ PS_METHOD = $(prefer-db2x)
+
+ ###
+ # The targets that may be used.
+-PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs xmldoclinks
++PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs media
+
+ BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
+-xmldocs: $(BOOKS) xmldoclinks
++xmldocs: $(BOOKS)
+ sgmldocs: xmldocs
+
+ PS := $(patsubst %.xml, %.ps, $(BOOKS))
+@@ -45,24 +45,15 @@ PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
+ pdfdocs: $(PDF)
+
+ HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
+-htmldocs: $(HTML)
++htmldocs: media $(HTML)
+ $(call build_main_index)
+- $(call build_images)
+
+ MAN := $(patsubst %.xml, %.9, $(BOOKS))
+ mandocs: $(MAN)
+
+-build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
+- cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/
+-
+-xmldoclinks:
+-ifneq ($(objtree),$(srctree))
+- for dep in dvb media-entities.tmpl media-indices.tmpl v4l; do \
+- rm -f $(objtree)/Documentation/DocBook/$$dep \
+- && ln -s $(srctree)/Documentation/DocBook/$$dep $(objtree)/Documentation/DocBook/ \
+- || exit; \
+- done
+-endif
++media:
++ mkdir -p $(srctree)/Documentation/DocBook/media/
++ cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(srctree)/Documentation/DocBook/media/
+
+ installmandocs: mandocs
+ mkdir -p /usr/local/man/man9/
+diff --git a/Documentation/dontdiff b/Documentation/dontdiff
+index e1efc40..0dda0c8 100644
+--- a/Documentation/dontdiff
++++ b/Documentation/dontdiff
+@@ -121,7 +121,6 @@ logo_*.c
+ logo_*_clut224.c
+ logo_*_mono.c
+ lxdialog
+-mach-types
+ mach-types.h
+ machtypes.h
+ map
+diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
+index e1def17..6d94e06 100644
+--- a/Documentation/filesystems/ext4.txt
++++ b/Documentation/filesystems/ext4.txt
+@@ -153,8 +153,8 @@ journal_dev=devnum When the external journal device's major/minor numbers
+ identified through its new major/minor numbers encoded
+ in devnum.
+
+-norecovery Don't load the journal on mounting. Note that
+-noload if the filesystem was not unmounted cleanly,
++noload Don't load the journal on mounting. Note that
++ if the filesystem was not unmounted cleanly,
+ skipping the journal replay will lead to the
+ filesystem containing inconsistencies that can
+ lead to any number of problems.
+@@ -196,7 +196,7 @@ nobarrier This also requires an IO stack which can support
+ also be used to enable or disable barriers, for
+ consistency with other ext4 mount options.
+
+-inode_readahead_blks=n This tuning parameter controls the maximum
++inode_readahead=n This tuning parameter controls the maximum
+ number of inode table blocks that ext4's inode
+ table readahead algorithm will pre-read into
+ the buffer cache. The default value is 32 blocks.
+@@ -353,12 +353,6 @@ noauto_da_alloc replacing existing files via patterns such as
+ system crashes before the delayed allocation
+ blocks are forced to disk.
+
+-discard Controls whether ext4 should issue discard/TRIM
+-nodiscard(*) commands to the underlying block device when
+- blocks are freed. This is useful for SSD devices
+- and sparse/thinly-provisioned LUNs, but it is off
+- by default until sufficient testing has been done.
+-
+ Data Mode
+ =========
+ There are 3 different data modes:
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index 5bc4eaa..9107b38 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -2645,8 +2645,6 @@ and is between 256 and 4096 characters. It is defined in the file
+ to a common usb-storage quirk flag as follows:
+ a = SANE_SENSE (collect more than 18 bytes
+ of sense data);
+- b = BAD_SENSE (don't collect more than 18
+- bytes of sense data);
+ c = FIX_CAPACITY (decrease the reported
+ device capacity by one sector);
+ h = CAPACITY_HEURISTICS (decrease the
+diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
+index db3a706..5a4bc8c 100644
+--- a/Documentation/kvm/api.txt
++++ b/Documentation/kvm/api.txt
+@@ -593,42 +593,6 @@ struct kvm_irqchip {
+ } chip;
+ };
+
+-4.27 KVM_GET_CLOCK
+-
+-Capability: KVM_CAP_ADJUST_CLOCK
+-Architectures: x86
+-Type: vm ioctl
+-Parameters: struct kvm_clock_data (out)
+-Returns: 0 on success, -1 on error
+-
+-Gets the current timestamp of kvmclock as seen by the current guest. In
+-conjunction with KVM_SET_CLOCK, it is used to ensure monotonicity on scenarios
+-such as migration.
+-
+-struct kvm_clock_data {
+- __u64 clock; /* kvmclock current value */
+- __u32 flags;
+- __u32 pad[9];
+-};
+-
+-4.28 KVM_SET_CLOCK
+-
+-Capability: KVM_CAP_ADJUST_CLOCK
+-Architectures: x86
+-Type: vm ioctl
+-Parameters: struct kvm_clock_data (in)
+-Returns: 0 on success, -1 on error
+-
+-Sets the current timestamp of kvmclock to the valued specific in its parameter.
+-In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
+-such as migration.
+-
+-struct kvm_clock_data {
+- __u64 clock; /* kvmclock current value */
+- __u32 flags;
+- __u32 pad[9];
+-};
+-
+ 5. The kvm_run structure
+
+ Application code obtains a pointer to the kvm_run structure by
+diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c
+index 10abd37..ddd00f6 100644
+--- a/Documentation/spi/spidev_test.c
++++ b/Documentation/spi/spidev_test.c
+@@ -161,9 +161,11 @@ int main(int argc, char *argv[])
+
+ parse_opts(argc, argv);
+
++ printf("open <%s>\n", device);
++
+ fd = open(device, O_RDWR);
+ if (fd < 0)
+- pabort("can't open device");
++ pabort("can't open device <%s>");
+
+ /*
+ * spi mode
+diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
+index 94e255a..2620d60 100644
+--- a/Documentation/video4linux/CARDLIST.saa7134
++++ b/Documentation/video4linux/CARDLIST.saa7134
+@@ -172,4 +172,3 @@
+ 171 -> Beholder BeholdTV X7 [5ace:7595]
+ 172 -> RoverMedia TV Link Pro FM [19d1:0138]
+ 173 -> Zolid Hybrid TV Tuner PCI [1131:2004]
+-174 -> Asus Europa Hybrid OEM [1043:4847]
+diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
+index 90e85a8..3f61825 100644
+--- a/Documentation/video4linux/gspca.txt
++++ b/Documentation/video4linux/gspca.txt
+@@ -37,7 +37,6 @@ ov519 041e:405f Creative Live! VISTA VF0330
+ ov519 041e:4060 Creative Live! VISTA VF0350
+ ov519 041e:4061 Creative Live! VISTA VF0400
+ ov519 041e:4064 Creative Live! VISTA VF0420
+-ov519 041e:4067 Creative Live! Cam Video IM (VF0350)
+ ov519 041e:4068 Creative Live! VISTA VF0470
+ spca561 0458:7004 Genius VideoCAM Express V2
+ sunplus 0458:7006 Genius Dsc 1.3 Smart
+diff --git a/MAINTAINERS b/MAINTAINERS
+index c57d396..4f96ac8 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -5594,11 +5594,9 @@ S: Maintained
+ F: drivers/net/wireless/rndis_wlan.c
+
+ USB XHCI DRIVER
+-M: Sarah Sharp <sarah.a.sharp at linux.intel.com>
++M: Sarah Sharp <sarah.a.sharp at intel.com>
+ L: linux-usb at vger.kernel.org
+ S: Supported
+-F: drivers/usb/host/xhci*
+-F: drivers/usb/host/pci-quirks*
+
+ USB ZC0301 DRIVER
+ M: Luca Risolia <luca.risolia at studio.unibo.it>
+diff --git a/Makefile b/Makefile
+index ec932b2..f5cdb72 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 32
+-EXTRAVERSION = .9
++EXTRAVERSION =
+ NAME = Man-Eating Seals of Antiquity
+
+ # *DOCUMENTATION*
+diff --git a/README b/README
+index 737838f..632f7c5 100644
+--- a/README
++++ b/README
+@@ -372,4 +372,3 @@ IF SOMETHING GOES WRONG:
+
+ gdb'ing a non-running kernel currently fails because gdb (wrongly)
+ disregards the starting offset for which the kernel is compiled.
+-
+diff --git a/README.kc b/README.kc
+new file mode 100644
+index 0000000..8491afe
+--- /dev/null
++++ b/README.kc
+@@ -0,0 +1,7 @@
++kernel concepts Linux kernel development
++
++Log:
++git remote add linus git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
++
++Merge upstream:
++git pull linus refs/tags/v2.6.30
+diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
+index 62619f2..9a3334a 100644
+--- a/arch/alpha/kernel/osf_sys.c
++++ b/arch/alpha/kernel/osf_sys.c
+@@ -178,18 +178,25 @@ SYSCALL_DEFINE6(osf_mmap, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, off)
+ {
+- unsigned long ret = -EINVAL;
++ struct file *file = NULL;
++ unsigned long ret = -EBADF;
+
+ #if 0
+ if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
+ printk("%s: unimplemented OSF mmap flags %04lx\n",
+ current->comm, flags);
+ #endif
+- if ((off + PAGE_ALIGN(len)) < off)
+- goto out;
+- if (off & ~PAGE_MASK)
+- goto out;
+- ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ down_write(¤t->mm->mmap_sem);
++ ret = do_mmap(file, addr, len, prot, flags, off);
++ up_write(¤t->mm->mmap_sem);
++ if (file)
++ fput(file);
+ out:
+ return ret;
+ }
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 1c4119c..508a718 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -344,6 +344,26 @@ config ARCH_H720X
+ help
+ This enables support for systems based on the Hynix HMS720x
+
++config ARCH_IMX
++ bool "IMX"
++ select CPU_ARM920T
++ select GENERIC_GPIO
++ select GENERIC_TIME
++ select GENERIC_CLOCKEVENTS
++ help
++ Support for Motorola's i.MX family of processors (MX1, MXL).
++
++config ARCH_TMPA910
++ bool "Toshiba TX09 / TMPA9xx based"
++ select CPU_ARM926T
++ select GENERIC_GPIO
++ select ARCH_REQUIRE_GPIOLIB
++ select GENERIC_CLOCKEVENTS
++ select GENERIC_CLOCKEVENTS_BUILD
++ help
++ This enables support for Toshiba TX09 series TMPA9xx / TMPA9xxCR based
++ devices.
++
+ config ARCH_NOMADIK
+ bool "STMicroelectronics Nomadik"
+ select ARM_AMBA
+@@ -802,6 +822,8 @@ source "arch/arm/mach-u300/Kconfig"
+
+ source "arch/arm/mach-w90x900/Kconfig"
+
++source "arch/arm/mach-tmpa910/Kconfig"
++
+ source "arch/arm/mach-bcmring/Kconfig"
+
+ # Definitions to make life easier
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index a73caaf..ae9defb 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -126,6 +126,7 @@ machine-$(CONFIG_ARCH_EBSA110) := ebsa110
+ machine-$(CONFIG_ARCH_EP93XX) := ep93xx
+ machine-$(CONFIG_ARCH_GEMINI) := gemini
+ machine-$(CONFIG_ARCH_H720X) := h720x
++machine-$(CONFIG_ARCH_IMX) := imx
+ machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
+ machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
+ machine-$(CONFIG_ARCH_IOP32X) := iop32x
+@@ -165,6 +166,7 @@ machine-$(CONFIG_ARCH_SA1100) := sa1100
+ machine-$(CONFIG_ARCH_SHARK) := shark
+ machine-$(CONFIG_ARCH_STMP378X) := stmp378x
+ machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
++machine-$(CONFIG_ARCH_TMPA910) := tmpa910
+ machine-$(CONFIG_ARCH_U300) := u300
+ machine-$(CONFIG_ARCH_VERSATILE) := versatile
+ machine-$(CONFIG_ARCH_W90X900) := w90x900
+diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
+index ce39dc5..db539a7 100644
+--- a/arch/arm/boot/compressed/Makefile
++++ b/arch/arm/boot/compressed/Makefile
+@@ -36,6 +36,10 @@ ifeq ($(CONFIG_CPU_XSCALE),y)
+ OBJS += head-xscale.o
+ endif
+
++ifeq ($(CONFIG_ARCH_TMPA910),y)
++OBJS += head-tmpa910.o
++endif
++
+ ifeq ($(CONFIG_PXA_SHARPSL),y)
+ OBJS += head-sharpsl.o
+ endif
+diff --git a/arch/arm/boot/compressed/head-tmpa910.S b/arch/arm/boot/compressed/head-tmpa910.S
+new file mode 100644
+index 0000000..aae9972
+--- /dev/null
++++ b/arch/arm/boot/compressed/head-tmpa910.S
+@@ -0,0 +1,32 @@
++/*
++ * The head file for Toshiba TMPA910
++ * by Yin, Fengwei (fengwei.yin at gmail.com)
++ * TMPA910 sepific. This is merged int head.S by the linker.
++ */
++
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++#include <asm/mach-types.h>
++
++ .section ".start", "ax"
++tmpa910_start:
++ @ Preserve r8/r7 i.e. kernel entry values
++
++ @ Data cache might be active.
++ @ Be sure to flush kernel binary out of the cache,
++ @ whatever state it is, before it is turned off.
++ @ This is done by fetching through currently executed
++ @ memory to be sure we hit the same cache.
++ bic r2, pc, #0x1f
++ add r3, r2, #0x10000 @ 64 kb is quite enough...
++1: ldr r0, [r2], #32
++ teq r2, r3
++ bne 1b
++ mcr p15, 0, r0, c7, c10, 4 @ drain WB
++ mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
++
++ @ disabling MMU and caches
++ mrc p15, 0, r0, c1, c0, 0 @ read control reg
++ bic r0, r0, #0x05 @ clear DC, MMU
++ bic r0, r0, #0x1000 @ clear Icache
++ mcr p15, 0, r0, c1, c0, 0
+diff --git a/arch/arm/configs/tonga_defconfig b/arch/arm/configs/tonga_defconfig
+new file mode 100644
+index 0000000..b06d038
+--- /dev/null
++++ b/arch/arm/configs/tonga_defconfig
+@@ -0,0 +1,1373 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.32
++# Fri Mar 12 17:46:36 2010
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_CONSTRUCTORS=y
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_RCU=y
++# CONFIG_TREE_PREEMPT_RCU is not set
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_FANOUT=32
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++# CONFIG_SYSFS_DEPRECATED_V2 is not set
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++
++#
++# Kernel Performance Events And Counters
++#
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++
++#
++# GCOV-based kernel profiling
++#
++CONFIG_SLOW_WORK=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_BLOCK=y
++# CONFIG_LBDAF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_FREEZER is not set
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_STMP3XXX is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++CONFIG_ARCH_TMPA910=y
++# CONFIG_ARCH_NOMADIK is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5PC1XX is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_BCMRING is not set
++# CONFIG_CPU_TMPA910 is not set
++CONFIG_CPU_TMPA900=y
++# CONFIG_DISPLAY_GLYN_640_480 is not set
++# CONFIG_MACH_TOPASA900 is not set
++CONFIG_MACH_TONGA=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_LEGACY=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++CONFIG_ARM_L1_CACHE_SHIFT=5
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE="mem=63M mtdparts=physmap-flash.0:384k(bootloader)ro,5120k(kernel),-(root) root=/dev/mtdblock2 rdinit=/init"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++CONFIG_CPU_IDLE=y
++CONFIG_CPU_IDLE_GOV_LADDER=y
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++CONFIG_NET_IPIP=y
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA 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_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++CONFIG_MTD_JEDECPROBE=y
++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=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_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++CONFIG_MTD_CFI_AMDSTD=y
++# 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 is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_IMPA7 is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM 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
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++CONFIG_MTD_NAND_TMPA910=y
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
++# UBI - Unsorted block images
++#
++CONFIG_MTD_UBI=y
++CONFIG_MTD_UBI_WL_THRESHOLD=4096
++CONFIG_MTD_UBI_BEB_RESERVE=1
++CONFIG_MTD_UBI_GLUEBI=y
++
++#
++# UBI debugging options
++#
++# CONFIG_MTD_UBI_DEBUG is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON 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_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_MISC_DEVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=y
++# CONFIG_BLK_DEV_SR_VENDOR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++CONFIG_DM9000=y
++CONFIG_DM9000_DEBUGLEVEL=0
++# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_B44 is not set
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851 is not set
++# CONFIG_KS8851_MLL is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++CONFIG_WLAN=y
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=y
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++CONFIG_INPUT_MOUSE=y
++# CONFIG_MOUSE_PS2 is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_MOUSE_SYNAPTICS_I2C is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_ADS7846 is not set
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
++# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
++# CONFIG_TOUCHSCREEN_EETI is not set
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
++# CONFIG_TOUCHSCREEN_MCS5000 is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_INEXIO is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++CONFIG_TOUCHSCREEN_TMPA910=y
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
++# CONFIG_TOUCHSCREEN_TSC2007 is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_DEVKMEM=y
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_MAX3100 is not set
++CONFIG_SERIAL_TMPA910=y
++CONFIG_SERIAL_TMPA910_CONSOLE=y
++CONFIG_SERIAL_TMPA910_CONSOLE_PREFERED=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_COMPAT=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_TMPA910=y
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_TSL2550 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
++CONFIG_SPI=y
++# CONFIG_SPI_DEBUG is not set
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++CONFIG_SPI_TMPA910=y
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=y
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_DEBUG_GPIO is not set
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++
++#
++# AC97 GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_MC13783 is not set
++# CONFIG_AB3100_CORE is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++CONFIG_FB_TMPA910=y
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++CONFIG_LCD_CLASS_DEVICE=y
++# CONFIG_LCD_LMS283GF05 is not set
++# CONFIG_LCD_LTV350QV is not set
++# CONFIG_LCD_ILI9320 is not set
++# CONFIG_LCD_TDO24M is not set
++# CONFIG_LCD_VGG2432A4 is not set
++# CONFIG_LCD_PLATFORM is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_GENERIC=y
++
++#
++# Display device support
++#
++CONFIG_DISPLAY_SUPPORT=y
++
++#
++# Display hardware drivers
++#
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++CONFIG_FONT_MINI_4x6=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_LOGO_LINUX_CLUT224=y
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SOUND_OSS_CORE_PRECLAIM=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++CONFIG_SND_DRIVERS=y
++# 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
++CONFIG_SND_ARM=y
++CONFIG_SND_TMPA910_WM8976=y
++# CONFIG_SND_TMPA910_PCM1773 is not set
++CONFIG_SND_SPI=y
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HIDRAW is not set
++# CONFIG_HID_PID is not set
++
++#
++# Special HID drivers
++#
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++# CONFIG_USB is not set
++
++#
++# Enable Host or Gadget support to see Inventra options
++#
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++# CONFIG_USB_GADGET is not set
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++
++#
++# TI VLYNQ
++#
++# CONFIG_STAGING is not set
++
++#
++# 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_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++# CONFIG_FUSE_FS is not set
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++CONFIG_MISC_FILESYSTEMS=y
++# 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_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_UBIFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
++CONFIG_NFS_V4=y
++# CONFIG_NFS_V4_1 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_ACL_SUPPORT=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++CONFIG_SUNRPC_GSS=y
++CONFIG_RPCSEC_GSS_KRB5=y
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++CONFIG_CIFS=m
++# CONFIG_CIFS_STATS is not set
++CONFIG_CIFS_WEAK_PW_HASH=y
++CONFIG_CIFS_XATTR=y
++CONFIG_CIFS_POSIX=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_EXPERIMENTAL 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_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=y
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++# CONFIG_ENABLE_MUST_CHECK is not set
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
++CONFIG_DETECT_HUNG_TASK=y
++# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
++CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_DEBUG_KMEMLEAK is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_DEBUG_NOTIFIERS is not set
++# CONFIG_DEBUG_CREDENTIALS is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++# CONFIG_PAGE_POISONING is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++CONFIG_SAMPLES=y
++# CONFIG_SAMPLE_KOBJECT is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_ARM_UNWIND is not set
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_GHASH is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=y
++CONFIG_CRC32=y
++CONFIG_CRC7=y
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+diff --git a/arch/arm/configs/topas910_defconfig b/arch/arm/configs/topas910_defconfig
+new file mode 100644
+index 0000000..b9f3d4c
+--- /dev/null
++++ b/arch/arm/configs/topas910_defconfig
+@@ -0,0 +1,1359 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.32
++# Thu Dec 3 11:39:59 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_CONSTRUCTORS=y
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_RCU=y
++# CONFIG_TREE_PREEMPT_RCU is not set
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_FANOUT=32
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++
++#
++# Kernel Performance Events And Counters
++#
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++
++#
++# GCOV-based kernel profiling
++#
++CONFIG_SLOW_WORK=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_STMP3XXX is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++CONFIG_ARCH_TMPA910=y
++# CONFIG_ARCH_NOMADIK is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5PC1XX is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_BCMRING is not set
++CONFIG_CPU_TMPA910=y
++# CONFIG_CPU_TMPA900 is not set
++CONFIG_MACH_TOPAS910=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_LEGACY=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++CONFIG_ARM_L1_CACHE_SHIFT=5
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_HZ=100
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE="mem=63M mtdparts=physmap-flash.0:384k(bootloader)ro,5120k(kernel),-(root) root=/dev/mtdblock2 rdinit=/init"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++CONFIG_CPU_IDLE=y
++CONFIG_CPU_IDLE_GOV_LADDER=y
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++CONFIG_APM_EMULATION=y
++# CONFIG_PM_RUNTIME is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++CONFIG_NET_IPIP=y
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA 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_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++CONFIG_MTD_JEDECPROBE=y
++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=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_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++CONFIG_MTD_CFI_AMDSTD=y
++# 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 is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_COMPAT=y
++CONFIG_MTD_PHYSMAP_START=0x20000000
++CONFIG_MTD_PHYSMAP_LEN=0x02000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_IMPA7 is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM 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
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++CONFIG_MTD_NAND_TMPA910=y
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON 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_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_MISC_DEVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=y
++# CONFIG_BLK_DEV_SR_VENDOR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++CONFIG_DM9000=y
++CONFIG_DM9000_DEBUGLEVEL=0
++# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_B44 is not set
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851 is not set
++# CONFIG_KS8851_MLL is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_WLAN is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=y
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++CONFIG_INPUT_MOUSE=y
++# CONFIG_MOUSE_PS2 is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_MOUSE_SYNAPTICS_I2C is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_ADS7846 is not set
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
++# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
++# CONFIG_TOUCHSCREEN_EETI is not set
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
++# CONFIG_TOUCHSCREEN_MCS5000 is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_INEXIO is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++CONFIG_TOUCHSCREEN_TMPA910=y
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
++# CONFIG_TOUCHSCREEN_TSC2007 is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_DEVKMEM=y
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_MAX3100 is not set
++CONFIG_SERIAL_TMPA910=y
++CONFIG_SERIAL_TMPA910_CONSOLE=y
++CONFIG_SERIAL_TMPA910_CONSOLE_PREFERED=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_COMPAT=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_TMPA910=y
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_TSL2550 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
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++CONFIG_SPI_TMPA910=y
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=y
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++
++#
++# AC97 GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_MC13783 is not set
++# CONFIG_AB3100_CORE is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++CONFIG_FB_TMPA910=y
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++CONFIG_LCD_CLASS_DEVICE=y
++# CONFIG_LCD_LMS283GF05 is not set
++# CONFIG_LCD_LTV350QV is not set
++# CONFIG_LCD_ILI9320 is not set
++# CONFIG_LCD_TDO24M is not set
++# CONFIG_LCD_VGG2432A4 is not set
++# CONFIG_LCD_PLATFORM is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_GENERIC=y
++
++#
++# Display device support
++#
++CONFIG_DISPLAY_SUPPORT=y
++
++#
++# Display hardware drivers
++#
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++CONFIG_FONT_MINI_4x6=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_LOGO_LINUX_CLUT224=y
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SOUND_OSS_CORE_PRECLAIM=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++CONFIG_SND_ARM=y
++# CONFIG_SND_TMPA910_WM8976 is not set
++CONFIG_SND_TMPA910_PCM1773=y
++CONFIG_SND_SPI=y
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HIDRAW is not set
++# CONFIG_HID_PID is not set
++
++#
++# Special HID drivers
++#
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++# CONFIG_USB is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG_FILES=y
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++CONFIG_USB_GADGET_TMPA910=y
++CONFIG_USB_TMPA910=y
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_R8A66597 is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C_HSOTG is not set
++# CONFIG_USB_GADGET_IMX is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LANGWELL 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_AUDIO is not set
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++CONFIG_USB_GADGETFS=m
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++CONFIG_USB_G_PRINTER=m
++CONFIG_USB_CDC_COMPOSITE=m
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++
++#
++# TI VLYNQ
++#
++# CONFIG_STAGING is not set
++
++#
++# 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_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++# CONFIG_FUSE_FS is not set
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++CONFIG_MISC_FILESYSTEMS=y
++# 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_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
++CONFIG_NFS_V4=y
++# CONFIG_NFS_V4_1 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_ACL_SUPPORT=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++CONFIG_SUNRPC_GSS=y
++CONFIG_RPCSEC_GSS_KRB5=y
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++CONFIG_CIFS=m
++# CONFIG_CIFS_STATS is not set
++CONFIG_CIFS_WEAK_PW_HASH=y
++CONFIG_CIFS_XATTR=y
++CONFIG_CIFS_POSIX=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_EXPERIMENTAL 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_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=y
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++# CONFIG_ENABLE_MUST_CHECK is not set
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_ARM_UNWIND is not set
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_GHASH is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=y
++CONFIG_CRC32=y
++CONFIG_CRC7=y
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+diff --git a/arch/arm/configs/topasa900_defconfig b/arch/arm/configs/topasa900_defconfig
+new file mode 100644
+index 0000000..a642018
+--- /dev/null
++++ b/arch/arm/configs/topasa900_defconfig
+@@ -0,0 +1,1366 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.32
++# Thu Jan 14 16:58:28 2010
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_CONSTRUCTORS=y
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_POSIX_MQUEUE_SYSCTL=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_RCU=y
++# CONFIG_TREE_PREEMPT_RCU is not set
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_FANOUT=32
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_CGROUPS is not set
++# CONFIG_SYSFS_DEPRECATED_V2 is not set
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_NET_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++
++#
++# Kernel Performance Events And Counters
++#
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_COMPAT_BRK=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++
++#
++# GCOV-based kernel profiling
++#
++CONFIG_SLOW_WORK=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_BLOCK=y
++# CONFIG_LBDAF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_FREEZER is not set
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_STMP3XXX is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++CONFIG_ARCH_TMPA910=y
++# CONFIG_ARCH_NOMADIK is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5PC1XX is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_BCMRING is not set
++# CONFIG_CPU_TMPA910 is not set
++CONFIG_CPU_TMPA900=y
++CONFIG_MACH_TOPASA900=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_LEGACY=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++CONFIG_ARM_L1_CACHE_SHIFT=5
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_HAVE_MLOCK=y
++CONFIG_HAVE_MLOCKED_PAGE_BIT=y
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE="mem=63M mtdparts=physmap-flash.0:384k(bootloader)ro,5120k(kernel),-(root) root=/dev/mtdblock2 rdinit=/init"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++CONFIG_CPU_IDLE=y
++CONFIG_CPU_IDLE_GOV_LADDER=y
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++CONFIG_NET_IPIP=y
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA 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_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_TESTS is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++CONFIG_MTD_JEDECPROBE=y
++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=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_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++CONFIG_MTD_CFI_AMDSTD=y
++# 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 is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_COMPAT=y
++CONFIG_MTD_PHYSMAP_START=0x20000000
++CONFIG_MTD_PHYSMAP_LEN=0x02000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_IMPA7 is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SST25L is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM 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
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++CONFIG_MTD_NAND_TMPA910=y
++# CONFIG_MTD_ONENAND is not set
++
++#
++# LPDDR flash memory drivers
++#
++# CONFIG_MTD_LPDDR is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON 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_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_MISC_DEVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=y
++# CONFIG_BLK_DEV_SR_VENDOR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++CONFIG_DM9000=y
++CONFIG_DM9000_DEBUGLEVEL=0
++# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
++# CONFIG_ENC28J60 is not set
++# CONFIG_ETHOC is not set
++# CONFIG_SMC911X is not set
++# CONFIG_SMSC911X is not set
++# CONFIG_DNET is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
++# CONFIG_B44 is not set
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851 is not set
++# CONFIG_KS8851_MLL is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++CONFIG_WLAN=y
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=y
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++CONFIG_INPUT_MOUSE=y
++# CONFIG_MOUSE_PS2 is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_MOUSE_SYNAPTICS_I2C is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_ADS7846 is not set
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
++# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
++# CONFIG_TOUCHSCREEN_EETI is not set
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
++# CONFIG_TOUCHSCREEN_MCS5000 is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_INEXIO is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++CONFIG_TOUCHSCREEN_TMPA910=y
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
++# CONFIG_TOUCHSCREEN_TSC2007 is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_DEVKMEM=y
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_MAX3100 is not set
++CONFIG_SERIAL_TMPA910=y
++CONFIG_SERIAL_TMPA910_CONSOLE=y
++CONFIG_SERIAL_TMPA910_CONSOLE_PREFERED=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_COMPAT=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_TMPA910=y
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_TSL2550 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
++CONFIG_SPI=y
++# CONFIG_SPI_DEBUG is not set
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++CONFIG_SPI_TMPA910=y
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_SPIDEV=y
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++# CONFIG_DEBUG_GPIO is not set
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++
++#
++# AC97 GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X is not set
++# CONFIG_MFD_WM8350_I2C is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_MC13783 is not set
++# CONFIG_AB3100_CORE is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++CONFIG_FB_TMPA910=y
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_FB_BROADSHEET is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++CONFIG_LCD_CLASS_DEVICE=y
++# CONFIG_LCD_LMS283GF05 is not set
++# CONFIG_LCD_LTV350QV is not set
++# CONFIG_LCD_ILI9320 is not set
++# CONFIG_LCD_TDO24M is not set
++# CONFIG_LCD_VGG2432A4 is not set
++# CONFIG_LCD_PLATFORM is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_GENERIC=y
++
++#
++# Display device support
++#
++CONFIG_DISPLAY_SUPPORT=y
++
++#
++# Display hardware drivers
++#
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++CONFIG_FONT_MINI_4x6=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_LOGO_LINUX_CLUT224=y
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SOUND_OSS_CORE_PRECLAIM=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++CONFIG_SND_DRIVERS=y
++# 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
++CONFIG_SND_ARM=y
++CONFIG_SND_TMPA910_WM8976=y
++# CONFIG_SND_TMPA910_PCM1773 is not set
++CONFIG_SND_SPI=y
++# CONFIG_SND_SOC is not set
++# CONFIG_SOUND_PRIME is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HIDRAW is not set
++# CONFIG_HID_PID is not set
++
++#
++# Special HID drivers
++#
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++# CONFIG_USB is not set
++
++#
++# Enable Host or Gadget support to see Inventra options
++#
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++# CONFIG_USB_GADGET is not set
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++
++#
++# TI VLYNQ
++#
++# CONFIG_STAGING is not set
++
++#
++# 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_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++# CONFIG_FUSE_FS is not set
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++CONFIG_MISC_FILESYSTEMS=y
++# 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_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
++CONFIG_NFS_V4=y
++# CONFIG_NFS_V4_1 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_ACL_SUPPORT=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++CONFIG_SUNRPC_GSS=y
++CONFIG_RPCSEC_GSS_KRB5=y
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++CONFIG_CIFS=m
++# CONFIG_CIFS_STATS is not set
++CONFIG_CIFS_WEAK_PW_HASH=y
++CONFIG_CIFS_XATTR=y
++CONFIG_CIFS_POSIX=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_EXPERIMENTAL 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_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=y
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++# CONFIG_ENABLE_MUST_CHECK is not set
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
++CONFIG_DETECT_HUNG_TASK=y
++# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
++CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_DEBUG_KMEMLEAK is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_DEBUG_NOTIFIERS is not set
++# CONFIG_DEBUG_CREDENTIALS is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++# CONFIG_PAGE_POISONING is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++CONFIG_SAMPLES=y
++# CONFIG_SAMPLE_KOBJECT is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_ARM_UNWIND is not set
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_GHASH is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_FIND_LAST_BIT=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=y
++CONFIG_CRC32=y
++CONFIG_CRC7=y
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
+diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/asm/mman.h
+index 41f99c5..8eebf89 100644
+--- a/arch/arm/include/asm/mman.h
++++ b/arch/arm/include/asm/mman.h
+@@ -1,4 +1 @@
+ #include <asm-generic/mman.h>
+-
+-#define arch_mmap_check(addr, len, flags) \
+- (((flags) & MAP_FIXED && (addr) < FIRST_USER_ADDRESS) ? -EINVAL : 0)
+diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
+index 4f07168..fafce1b 100644
+--- a/arch/arm/kernel/calls.S
++++ b/arch/arm/kernel/calls.S
+@@ -172,7 +172,7 @@
+ /* 160 */ CALL(sys_sched_get_priority_min)
+ CALL(sys_sched_rr_get_interval)
+ CALL(sys_nanosleep)
+- CALL(sys_mremap)
++ CALL(sys_arm_mremap)
+ CALL(sys_setresuid16)
+ /* 165 */ CALL(sys_getresuid16)
+ CALL(sys_ni_syscall) /* vm86 */
+diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
+index 2c1db77..f0fe95b 100644
+--- a/arch/arm/kernel/entry-common.S
++++ b/arch/arm/kernel/entry-common.S
+@@ -416,12 +416,12 @@ sys_mmap2:
+ tst r5, #PGOFF_MASK
+ moveq r5, r5, lsr #PAGE_SHIFT - 12
+ streq r5, [sp, #4]
+- beq sys_mmap_pgoff
++ beq do_mmap2
+ mov r0, #-EINVAL
+ mov pc, lr
+ #else
+ str r5, [sp, #4]
+- b sys_mmap_pgoff
++ b do_mmap2
+ #endif
+ ENDPROC(sys_mmap2)
+
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+index 38ccbe1..edfcbe2 100644
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -74,6 +74,7 @@
+ * crap here - that's what the boot loader (or in extreme, well justified
+ * circumstances, zImage) is for.
+ */
++
+ .section ".text.head", "ax"
+ ENTRY(stext)
+ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
+@@ -102,6 +103,7 @@ ENTRY(stext)
+ THUMB( add r12, r10, #PROCINFO_INITFUNC )
+ THUMB( mov pc, r12 )
+ ENDPROC(stext)
++PB_ADDR: .word (0xf08013FC)
+
+ #if defined(CONFIG_SMP)
+ ENTRY(secondary_startup)
+diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
+index 0d96d01..cc8d459 100644
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -100,7 +100,7 @@ void arm_machine_restart(char mode, const char *cmd)
+ /*
+ * Now call the architecture specific reboot code.
+ */
+- arch_reset(mode, cmd);
++ arch_reset(mode);
+
+ /*
+ * Whoops - the architecture was unable to reboot.
+diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
+index ae4027b..78ecaac 100644
+--- a/arch/arm/kernel/sys_arm.c
++++ b/arch/arm/kernel/sys_arm.c
+@@ -28,6 +28,41 @@
+ #include <linux/ipc.h>
+ #include <linux/uaccess.h>
+
++extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
++ unsigned long new_len, unsigned long flags,
++ unsigned long new_addr);
++
++/* common code for old and new mmaps */
++inline long do_mmap2(
++ unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ int error = -EINVAL;
++ struct file * file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ if (flags & MAP_FIXED && addr < FIRST_USER_ADDRESS)
++ goto out;
++
++ error = -EBADF;
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ struct mmap_arg_struct {
+ unsigned long addr;
+ unsigned long len;
+@@ -49,11 +84,29 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+
++asmlinkage unsigned long
++sys_arm_mremap(unsigned long addr, unsigned long old_len,
++ unsigned long new_len, unsigned long flags,
++ unsigned long new_addr)
++{
++ unsigned long ret = -EINVAL;
++
++ if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS)
++ goto out;
++
++ down_write(¤t->mm->mmap_sem);
++ ret = do_mremap(addr, old_len, new_len, flags, new_addr);
++ up_write(¤t->mm->mmap_sem);
++
++out:
++ return ret;
++}
++
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls.
+diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
+index 36e4fb4..0976049 100644
+--- a/arch/arm/mach-davinci/dm646x.c
++++ b/arch/arm/mach-davinci/dm646x.c
+@@ -789,14 +789,7 @@ static struct davinci_id dm646x_ids[] = {
+ .part_no = 0xb770,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM6467,
+- .name = "dm6467_rev1.x",
+- },
+- {
+- .variant = 0x1,
+- .part_no = 0xb770,
+- .manufacturer = 0x017,
+- .cpu_id = DAVINCI_CPU_ID_DM6467,
+- .name = "dm6467_rev3.x",
++ .name = "dm6467",
+ },
+ };
+
+diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
+index 86a8732..aec7f42 100644
+--- a/arch/arm/mach-pxa/em-x270.c
++++ b/arch/arm/mach-pxa/em-x270.c
+@@ -497,15 +497,16 @@ static int em_x270_usb_hub_init(void)
+ goto err_free_vbus_gpio;
+
+ /* USB Hub power-on and reset */
+- gpio_direction_output(usb_hub_reset, 1);
+- gpio_direction_output(GPIO9_USB_VBUS_EN, 0);
++ gpio_direction_output(usb_hub_reset, 0);
+ regulator_enable(em_x270_usb_ldo);
+- gpio_set_value(usb_hub_reset, 0);
+ gpio_set_value(usb_hub_reset, 1);
++ gpio_set_value(usb_hub_reset, 0);
+ regulator_disable(em_x270_usb_ldo);
+ regulator_enable(em_x270_usb_ldo);
+- gpio_set_value(usb_hub_reset, 0);
+- gpio_set_value(GPIO9_USB_VBUS_EN, 1);
++ gpio_set_value(usb_hub_reset, 1);
++
++ /* enable VBUS */
++ gpio_direction_output(GPIO9_USB_VBUS_EN, 1);
+
+ return 0;
+
+diff --git a/arch/arm/mach-tmpa910/Kconfig b/arch/arm/mach-tmpa910/Kconfig
+new file mode 100644
+index 0000000..6aafab1
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/Kconfig
+@@ -0,0 +1,34 @@
++if ARCH_TMPA910
++
++choice
++
++ prompt "Select TX09 Variant"
++
++config CPU_TMPA910
++ depends on ARCH_TMPA910
++ bool "TMPA910 SoC"
++
++config CPU_TMPA900
++ depends on ARCH_TMPA910
++ bool "TMPA900 SoC"
++
++endchoice
++
++
++config MACH_TOPAS910
++ bool "Toshiba Topas910 TMPA910 development board"
++ depends on CPU_TMPA910
++
++config DISPLAY_GLYN_640_480
++ bool "Use Glyn VGA display instead of the regular QVGA."
++ depends on ARCH_TMPA910
++
++config MACH_TOPASA900
++ bool "Toshiba TopasA900 TMPA900 development board"
++ depends on CPU_TMPA900
++
++config MACH_TONGA
++ bool "Glyn ARM9 / Tonga board"
++ depends on CPU_TMPA900
++
++endif
+diff --git a/arch/arm/mach-tmpa910/Makefile b/arch/arm/mach-tmpa910/Makefile
+new file mode 100644
+index 0000000..2a4fe7a
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/Makefile
+@@ -0,0 +1,13 @@
++#
++# Makefile for the linux kernel.
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++# Object file lists.
++
++obj-y += irq.o time.o gpio.o led-topas910.o dma.o
++obj-$(CONFIG_MACH_TOPAS910) += topas910.o
++obj-$(CONFIG_MACH_TOPASA900) += topasa900.o
++obj-$(CONFIG_MACH_TONGA) += tonga.o
+diff --git a/arch/arm/mach-tmpa910/Makefile.boot b/arch/arm/mach-tmpa910/Makefile.boot
+new file mode 100644
+index 0000000..0e62bb5
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/Makefile.boot
+@@ -0,0 +1,2 @@
++zreladdr-y := 0x40008000
++params_phys-y := 0x40000100
+diff --git a/arch/arm/mach-tmpa910/dma.c b/arch/arm/mach-tmpa910/dma.c
+new file mode 100644
+index 0000000..ccf7ee3
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/dma.c
+@@ -0,0 +1,245 @@
++/*
++ * linux/arch/arm/mach-tmpa/dma.c
++ *
++ * tmpa910 DMA registration and IRQ dispatching
++ * based on arch/arm/mach-imx/dma.c
++ * Copyright (C) Yin, Fengwei (fengwei.yin at gmail.com)
++ *
++ * 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.
++ *
++ */
++
++#undef DEBUG
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/errno.h>
++
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/dma.h>
++#include <mach/tmpa910_regs.h>
++#include <mach/dma.h>
++
++struct tmpa910_dma_channel tmpa910_dma_channels[TMPA910_DMA_CHANNELS];
++
++/**
++ * tmpa910_dma_enable - function to start TMPA910 DMA channel operation
++ */
++void tmpa910_dma_enable(int dma_ch)
++{
++ struct tmpa910_dma_channel *dma = &tmpa910_dma_channels[dma_ch];
++ unsigned long flags;
++
++ pr_debug("tmpa910 dma%d: tmpa910_dma_enable\n", dma_ch);
++
++ if (!dma->name) {
++ printk(KERN_CRIT "%s: called for not allocated channel %d\n",
++ __FUNCTION__, dma_ch);
++ return;
++ }
++
++ local_irq_save(flags);
++ DMA_CONFIG(dma_ch) = DMA_CONFIG(dma_ch) | DMA_CONFIG_EN;
++ local_irq_restore(flags);
++}
++
++/**
++ * tmpa910_dma_disable - disable TMPA910 DMA channel operatin
++ */
++void tmpa910_dma_disable(int dma_ch)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++ DMA_CONFIG(dma_ch) = DMA_CONFIG(dma_ch) & ~DMA_CONFIG_EN;
++ local_irq_restore(flags);
++}
++
++long tmpa910_dma_get_size(int dma_ch)
++{
++ long size = DMA_CONTROL(dma_ch) & 0x0FFF;
++ long width;
++ width = (size >> 18) & 0x0007;
++ switch(width)
++ {
++ case 0:
++ size *= 1;
++ break;
++ case 1:
++ size *= 2;
++ break;
++ case 2:
++ size *= 4;
++ break;
++ }
++ return size;
++}
++
++/**
++ * tmpa910_dma_request - request/allocate specified channel number
++ */
++int tmpa910_dma_request(const char *name,
++ int prio,
++ void (*irq_handler)(int, void *),
++ void (*err_handler)(int, void *),
++ void *data)
++{
++ unsigned long flags;
++ int i, found = 0;
++
++ /* basic sanity checks */
++ if (!name)
++ return -EINVAL;
++
++ local_irq_save(flags);
++
++ for (i = prio; i > 0; i--) {
++ if (tmpa910_dma_channels[i].name == NULL) {
++ found = 1;
++ break;
++ }
++ }
++
++ if (!found) {
++ for (i = prio; i < TMPA910_DMA_CHANNELS; i ++) {
++ if (tmpa910_dma_channels[i].name == NULL) {
++ found = 1;
++ break;
++ }
++ }
++ }
++
++ if (!found) {
++ local_irq_restore(flags);
++ return -ENODEV;
++ }
++
++ if (tmpa910_dma_channels[i].name != NULL) {
++ local_irq_restore(flags);
++ return -ENODEV;
++ }
++ tmpa910_dma_channels[i].name = name;
++ tmpa910_dma_channels[i].err_handler = err_handler;
++ tmpa910_dma_channels[i].irq_handler = irq_handler;
++ tmpa910_dma_channels[i].data = data;
++
++ local_irq_restore(flags);
++ return i;
++}
++
++/**
++ * tmpa910_dma_free - release previously acquired channel
++ */
++void tmpa910_dma_free(int dma_ch)
++{
++ unsigned long flags;
++ struct tmpa910_dma_channel *dma = &tmpa910_dma_channels[dma_ch];
++
++ if (!dma->name) {
++ printk(KERN_CRIT
++ "%s: trying to free channel %d which is already freed\n",
++ __FUNCTION__, dma_ch);
++ return;
++ }
++
++ local_irq_save(flags);
++ /* Disable interrupts */
++ DMA_CONFIG(dma_ch) &= ~DMA_CONFIG_EN;
++ dma->name = NULL;
++ dma->err_handler = NULL;
++ dma->irq_handler = NULL;
++ local_irq_restore(flags);
++}
++
++static irqreturn_t dma_err_handler(int irq, void *dev_id)
++{
++ struct tmpa910_dma_channel *channel;
++ unsigned int err_status = DMA_ERR_STATUS;
++ int i;
++
++ DMA_ERR_CLEAR = err_status;
++
++ for (i = 0; i < TMPA910_DMA_CHANNELS; i++) {
++ if(!(err_status & (1 << i)))
++ continue;
++
++ channel = &tmpa910_dma_channels[i];
++ if (channel->name && channel->err_handler) {
++ channel->err_handler(i, channel->data);
++ continue;
++ } else {
++ printk(KERN_WARNING "spurous DMA IRQ: %d\n", i);
++ tmpa910_dma_disable(i);
++ }
++ }
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t dma_irq_handler(int irq, void *dev_id)
++{
++ struct tmpa910_dma_channel *channel;
++ unsigned int tc_status = DMA_TC_STATUS;
++ int i;
++
++ DMA_TC_CLEAR = tc_status;
++
++ for (i = 0; i < TMPA910_DMA_CHANNELS; i++) {
++ if(!(tc_status & (1 << i)))
++ continue;
++
++ channel = &tmpa910_dma_channels[i];
++ if (channel->name && channel->irq_handler) {
++ channel->irq_handler(i, channel->data);
++ continue;
++ } else {
++ printk(KERN_WARNING "spurous DMA IRQ: %d\n", i);
++ tmpa910_dma_disable(i);
++ }
++ }
++ return IRQ_HANDLED;
++}
++
++static int __init tmpa910_dma_init(void)
++{
++ int ret;
++ int i;
++
++ /* Initialize DMA module */
++ DMA_CONFIGURE = 0x0001; /* DMA1/2: little endian, Active DMA */
++ DMA_ERR_CLEAR = 0xff; /* Clear DMA error interrupt */
++ DMA_TC_CLEAR = 0xff; /* Clear DMA TC interrupt */
++
++
++ ret = request_irq(DMA_END_INT, dma_irq_handler, 0, "DMA", NULL);
++ if (ret) {
++ printk(KERN_CRIT "Wow! Can't register IRQ for DMA\n");
++ return ret;
++ }
++
++ ret = request_irq(DMA_ERR_INT, dma_err_handler, 0, "DMA", NULL);
++ if (ret) {
++ printk(KERN_CRIT "Wow! Can't register ERRIRQ for DMA\n");
++ free_irq(DMA_END_INT, NULL);
++ return ret;
++ }
++
++ for (i = 0; i < TMPA910_DMA_CHANNELS; i++) {
++ tmpa910_dma_channels[i].name = NULL;
++ tmpa910_dma_channels[i].dma_num = i;
++ }
++
++ return ret;
++}
++
++arch_initcall(tmpa910_dma_init);
++
++EXPORT_SYMBOL(tmpa910_dma_enable);
++EXPORT_SYMBOL(tmpa910_dma_disable);
++EXPORT_SYMBOL(tmpa910_dma_get_size);
++EXPORT_SYMBOL(tmpa910_dma_request);
++EXPORT_SYMBOL(tmpa910_dma_free);
+diff --git a/arch/arm/mach-tmpa910/gpio.c b/arch/arm/mach-tmpa910/gpio.c
+new file mode 100644
+index 0000000..7885d31
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/gpio.c
+@@ -0,0 +1,533 @@
++/*
++ * linux/arch/arm/mach-tmpa910/gpio.c
++ *
++ * Generic TMPA910 / TMPA910CR / TMPA910CRAXBG GPIO handling
++ *
++ * Copyright (c) 2009 Florian Boor <florian.boor at kernelconcepts.de>
++ *
++ * Based on mach-ep93xx/gpio.c
++ * Copyright (c) 2008 Ryan Mallon <ryan at bluewatersys.com>
++ *
++ * 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.
++ *
++ * GPIO functions implementation
++ *
++ * The GPIO ports are are organized in 16 ports of 8bit each, even if the
++ * are all 32bit. Not all ports allow all functions / directions.
++ * The same applies to interrupts.
++ *
++ * TODO: Allow sharing beween GPIO and non-GPIO IRQs
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/seq_file.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++
++#include <mach/tmpa910_regs.h>
++#include <mach/gpio.h>
++#include <asm/gpio.h>
++#include <mach/irqs.h>
++
++
++struct tmpa910_gpio_chip {
++ struct gpio_chip chip;
++
++ unsigned int data_reg; /* Associated data register for GPIO bank */
++ unsigned int data_dir_reg; /* Register for pin direction setting */
++
++ unsigned int input_mask; /* Bits that are allowed to be input */
++ unsigned int output_mask; /* Bits that are allowed to be output */
++ unsigned int irq_mask; /* Bits that can trigger an interrupt */
++};
++
++#define to_tmpa910_gpio_chip(c) container_of(c, struct tmpa910_gpio_chip, chip)
++
++
++static int tmpa910_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
++{
++ struct tmpa910_gpio_chip *tmpa910_chip = to_tmpa910_gpio_chip(chip);
++ unsigned long flags;
++ u8 v;
++
++ if (!(tmpa910_chip->input_mask & (1 << offset)))
++ return -EINVAL;
++
++ local_irq_save(flags);
++ v = __raw_readb(tmpa910_chip->data_dir_reg);
++ v &= ~(1 << offset);
++ __raw_writeb(v, tmpa910_chip->data_dir_reg);
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++static int tmpa910_gpio_direction_output(struct gpio_chip *chip,
++ unsigned offset, int val)
++{
++ struct tmpa910_gpio_chip *tmpa910_chip = to_tmpa910_gpio_chip(chip);
++ unsigned long flags;
++ u8 v;
++
++ if (!(tmpa910_chip->output_mask & (1 << offset)))
++ return -EINVAL;
++
++ local_irq_save(flags);
++
++ /* Set the value */
++ v = __raw_readb(tmpa910_chip->data_reg);
++ if (val)
++ v |= (1 << offset);
++ else
++ v &= ~(1 << offset);
++ __raw_writeb(v, tmpa910_chip->data_reg);
++
++ /* check if it can generate an interrupt, disable int in this case. */
++ if (tmpa910_chip->irq_mask & (1 << offset)) {
++ v = __raw_readb(tmpa910_chip->data_reg + 0x414);
++ v &= ~(1 << offset);
++ __raw_writeb(v, tmpa910_chip->data_reg + 0x414);
++ }
++
++ /* Set the direction */
++ v = __raw_readb(tmpa910_chip->data_dir_reg);
++ v |= (1 << offset);
++ __raw_writeb(v, tmpa910_chip->data_dir_reg);
++
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++static int tmpa910_gpio_get(struct gpio_chip *chip, unsigned offset)
++{
++ struct tmpa910_gpio_chip *tmpa910_chip = to_tmpa910_gpio_chip(chip);
++
++ return !!(__raw_readb(tmpa910_chip->data_reg) & (1 << offset));
++}
++
++static void tmpa910_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
++{
++ struct tmpa910_gpio_chip *tmpa910_chip = to_tmpa910_gpio_chip(chip);
++ unsigned long flags;
++ u8 v;
++
++ /* TODO: We could use the clever address based writing function here. */
++ local_irq_save(flags);
++ v = __raw_readb(tmpa910_chip->data_reg);
++ if (val)
++ v |= (1 << offset);
++ else
++ v &= ~(1 << offset);
++ __raw_writeb(v, tmpa910_chip->data_reg);
++ local_irq_restore(flags);
++}
++
++static void tmpa910_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
++{
++ struct tmpa910_gpio_chip *tmpa910_chip = to_tmpa910_gpio_chip(chip);
++ u8 data_reg, data_dir_reg;
++ int i;
++
++ data_reg = __raw_readb(tmpa910_chip->data_reg);
++ data_dir_reg = __raw_readb(tmpa910_chip->data_dir_reg);
++
++ for (i = 0; i < chip->ngpio; i++)
++ seq_printf(s, "GPIO %s%d: %s %s\n", chip->label, i,
++ (data_reg & (1 << i)) ? "set" : "clear",
++ (data_dir_reg & (1 << i)) ? "out" : "in");
++}
++
++
++/*
++ * GPIO Interrupts
++ */
++
++struct tmpa910_gpio_irq {
++ unsigned int gpio;
++ unsigned int port;
++ unsigned int bit;
++};
++
++
++/* Nothing is obvious here. We need to know quite a lot. */
++static struct tmpa910_gpio_irq irq_gpio_desc[TMPA910_NUM_GPIO_IRQS] = {
++ { 0, PORTA, 0 },
++ { 1, PORTA, 1 },
++ { 2, PORTA, 2 },
++ { 3, PORTA, 3 },
++ { 4, PORTA, 4 },
++ { 5, PORTA, 5 },
++ { 6, PORTA, 6 },
++ { 7, PORTA, 7 },
++ { 21, PORTC, 5 },
++ { 23, PORTC, 7 },
++ { 30, PORTD, 6 },
++ { 31, PORTD, 7 },
++ { 47, PORTF, 7 },
++ { 108, PORTN, 4 },
++ { 109, PORTN, 5 },
++ { 110, PORTN, 6 },
++ { 111, PORTN, 7 },
++ { 112, PORTP, 0 },
++ { 113, PORTP, 1 },
++ { 114, PORTP, 2 },
++ { 115, PORTP, 3 },
++ { 116, PORTP, 4 },
++ { 117, PORTP, 5 },
++ { 118, PORTP, 6 },
++ { 119, PORTP, 7 },
++ { 122, PORTR, 2 },
++};
++
++#define GPIO_NUM_FOR_GPIO_IRQ(_x) (irq_gpio_desc[_x].gpio)
++
++inline int __tmpa910_gpio_to_irq(unsigned gpio) {
++ int i;
++
++ for (i = 0; i < TMPA910_NUM_GPIO_IRQS; i++)
++ if (irq_gpio_desc[i].gpio == gpio)
++ return (i + TMPA910_NUM_IRQS);
++
++ BUG(); /* not found */
++ return -1;
++}
++
++inline int __tmpa910_irq_to_gpio(unsigned irq) {
++ return GPIO_NUM_FOR_GPIO_IRQ(irq - TMPA910_NUM_IRQS);
++}
++
++/*
++ * Interrupt handlers
++ * The matching GPIO is easy to find: Port base GPIO number + bit offset.
++ */
++static void tmpa910_gpioa_irq_handler(unsigned int irq, struct irq_desc *desc)
++{
++ unsigned char status;
++ int i;
++
++ desc->chip->ack(irq);
++ status = __raw_readb(TMPA910_GPIO_REG_MIS(PORTA));
++ while (status) {
++ for (i = 0; i < 8; i++) {
++ if (status & (1 << i)) {
++ int gpio_irq = gpio_to_irq(0 + i);
++ generic_handle_irq(gpio_irq);
++ }
++ }
++ status = __raw_readb(TMPA910_GPIO_REG_MIS(PORTA));
++ }
++ desc->chip->unmask(irq);
++}
++
++static void tmpa910_gpioc_irq_handler(unsigned int irq, struct irq_desc *desc)
++{
++ unsigned char status;
++
++ desc->chip->ack(irq);
++ status = __raw_readb(TMPA910_GPIO_REG_MIS(PORTC));
++ if (status & (1 << 5)) {
++ int gpio_irq = gpio_to_irq(16 + 5);
++ generic_handle_irq(gpio_irq);
++ }
++ if (status & (1 << 7)) {
++ int gpio_irq = gpio_to_irq(16 + 7);
++ generic_handle_irq(gpio_irq);
++ }
++ desc->chip->unmask(irq);
++}
++
++static void tmpa910_gpiod_irq_handler(unsigned int irq, struct irq_desc *desc)
++{
++ unsigned char status;
++ int i;
++
++ desc->chip->ack(irq);
++ status = __raw_readb(TMPA910_GPIO_REG_MIS(PORTD));
++ for (i = 6; i < 8; i++) {
++ if (status & (1 << i)) {
++ int gpio_irq = gpio_to_irq(24 + i);
++ generic_handle_irq(gpio_irq);
++ }
++ }
++ desc->chip->unmask(irq);
++}
++
++
++static void tmpa910_gpiof_irq_handler(unsigned int irq, struct irq_desc *desc)
++{
++ unsigned char status;
++
++ desc->chip->ack(irq);
++ status = __raw_readb(TMPA910_GPIO_REG_MIS(PORTF));
++ if (status & (1 << 7)) {
++ int gpio_irq = gpio_to_irq(40 + 7);
++ generic_handle_irq(gpio_irq);
++ }
++ desc->chip->unmask(irq);
++}
++
++
++static void tmpa910_gpion_irq_handler(unsigned int irq, struct irq_desc *desc)
++{
++ unsigned char status;
++ int i;
++
++ desc->chip->ack(irq);
++ status = __raw_readb(TMPA910_GPIO_REG_MIS(PORTN));
++ for (i = 4; i < 8; i++) {
++ if (status & (1 << i)) {
++ int gpio_irq = gpio_to_irq(104 + i);
++ generic_handle_irq(gpio_irq);
++ }
++ }
++ desc->chip->unmask(irq);
++}
++
++static void tmpa910_gpiop_irq_handler(unsigned int irq, struct irq_desc *desc)
++{
++ unsigned char status;
++ int i;
++
++ desc->chip->ack(irq);
++ status = __raw_readb(TMPA910_GPIO_REG_MIS(PORTP));
++ for (i = 0; i < 8; i++) {
++ if (status & (1 << i)) {
++ int gpio_irq = gpio_to_irq(112 + i);
++ generic_handle_irq(gpio_irq);
++ }
++ }
++ desc->chip->unmask(irq);
++}
++
++static void tmpa910_gpior_irq_handler(unsigned int irq, struct irq_desc *desc)
++{
++ unsigned char status;
++
++ desc->chip->mask(irq);
++ desc->chip->ack(irq);
++ status = __raw_readb(TMPA910_GPIO_REG_MIS(PORTR));
++ if (status & (1 << 2)) {
++ int gpio_irq = gpio_to_irq(120 + 2);
++ generic_handle_irq(gpio_irq);
++ }
++ desc->chip->unmask(irq);
++}
++
++
++static void tmpa910_gpio_irq_ack(unsigned int irq)
++{
++ unsigned int gpio_irq = irq - TMPA910_NUM_IRQS;
++ struct tmpa910_gpio_irq girq;
++
++ BUG_ON((irq < TMPA910_NUM_IRQS) || (gpio_irq >= TMPA910_NUM_GPIO_IRQS));
++
++ girq = irq_gpio_desc[gpio_irq];
++
++ __raw_writeb(1 << girq.bit, TMPA910_GPIO_REG_IC(girq.port));
++}
++
++static void tmpa910_gpio_irq_mask(unsigned int irq)
++{
++ unsigned int gpio_irq = irq - TMPA910_NUM_IRQS;
++ struct tmpa910_gpio_irq girq;
++ unsigned char reg;
++
++ BUG_ON((irq < TMPA910_NUM_IRQS) || (gpio_irq >= TMPA910_NUM_GPIO_IRQS));
++
++ girq = irq_gpio_desc[gpio_irq];
++ reg = __raw_readb(TMPA910_GPIO_REG_IE(girq.port));
++ reg &= ~(1 << girq.bit);
++ __raw_writeb(reg, TMPA910_GPIO_REG_IE(girq.port));
++}
++
++static void tmpa910_gpio_irq_unmask(unsigned int irq)
++{
++ unsigned int gpio_irq = irq - TMPA910_NUM_IRQS;
++ struct tmpa910_gpio_irq girq;
++ unsigned char reg;
++
++ BUG_ON((irq < TMPA910_NUM_IRQS) || (gpio_irq >= TMPA910_NUM_GPIO_IRQS));
++
++ girq = irq_gpio_desc[gpio_irq];
++ reg = __raw_readb(TMPA910_GPIO_REG_IE(girq.port));
++ reg |= (1 << girq.bit);
++ __raw_writeb(reg, TMPA910_GPIO_REG_IE(girq.port));
++}
++
++
++static int tmpa910_gpio_irq_type(unsigned int irq, unsigned int type)
++{
++ struct irq_desc *desc = irq_desc + irq;
++ const int gpio = irq_to_gpio(irq);
++ struct tmpa910_gpio_irq girq;
++ unsigned int gpio_irq = irq - TMPA910_NUM_IRQS;
++ unsigned char reg_level_sel;
++ unsigned char reg_dir_sel;
++ unsigned char reg_edge_both;
++ unsigned char reg_raise_high;
++ unsigned char reg_enable;
++ unsigned char port_mask;
++ unsigned long flags;
++
++ BUG_ON((irq < TMPA910_NUM_IRQS) || (gpio_irq >= TMPA910_NUM_GPIO_IRQS));
++
++ girq = irq_gpio_desc[gpio_irq];
++ reg_level_sel = __raw_readb(TMPA910_GPIO_REG_IS(girq.port));
++ reg_edge_both = __raw_readb(TMPA910_GPIO_REG_IBE(girq.port));
++ reg_raise_high = __raw_readb(TMPA910_GPIO_REG_IEV(girq.port));
++
++ port_mask = (1 << girq.bit);
++
++ /* we following the prodcedure mentioned in section 3.9.3 of the data sheet */
++
++ local_irq_save(flags);
++ reg_dir_sel = __raw_readb(TMPA910_GPIO_REG_DIR(girq.port));
++ reg_dir_sel &= ~(1 << girq.bit);
++ __raw_writeb(reg_dir_sel, TMPA910_GPIO_REG_DIR(girq.port));
++ local_irq_restore(flags);
++
++ tmpa910_gpio_irq_mask(irq); /* disable interrupt */
++
++ switch (type) {
++ case IRQ_TYPE_EDGE_RISING:
++ reg_level_sel &= ~port_mask;
++ reg_edge_both &= ~port_mask;
++ reg_raise_high |= port_mask;
++ desc->handle_irq = handle_edge_irq;
++ break;
++ case IRQ_TYPE_EDGE_FALLING:
++ reg_level_sel &= ~port_mask;
++ reg_edge_both &= ~port_mask;
++ reg_raise_high &= ~port_mask;
++ desc->handle_irq = handle_edge_irq;
++ break;
++ case IRQ_TYPE_LEVEL_HIGH:
++ reg_level_sel |= ~port_mask;
++ reg_edge_both &= ~port_mask;
++ reg_raise_high |= port_mask;
++ desc->handle_irq = handle_level_irq;
++ break;
++ case IRQ_TYPE_LEVEL_LOW:
++ reg_level_sel |= ~port_mask;
++ reg_edge_both &= ~port_mask;
++ reg_raise_high &= ~port_mask;
++ desc->handle_irq = handle_level_irq;
++ break;
++ case IRQ_TYPE_EDGE_BOTH:
++ reg_level_sel &= ~port_mask;
++ reg_edge_both |= port_mask;
++ desc->handle_irq = handle_edge_irq;
++ break;
++ default:
++ pr_err("tmpa910: failed to set irq type %d for gpio %d\n",
++ type, gpio);
++ return -EINVAL;
++ }
++
++ /* apply settings */
++ __raw_writeb(reg_level_sel, TMPA910_GPIO_REG_IS(girq.port));
++ __raw_writeb(reg_edge_both, TMPA910_GPIO_REG_IBE(girq.port));
++ __raw_writeb(reg_raise_high, TMPA910_GPIO_REG_IEV(girq.port));
++
++ tmpa910_gpio_irq_ack(irq); /* clear interrupt state */
++
++ desc->status &= ~IRQ_TYPE_SENSE_MASK;
++ desc->status |= type & IRQ_TYPE_SENSE_MASK;
++
++ reg_enable = __raw_readb(TMPA910_GPIO_REG_IE(girq.port));
++ reg_enable |= port_mask;
++ __raw_writeb(reg_enable, TMPA910_GPIO_REG_IE(girq.port));
++
++ return 0;
++}
++
++static struct irq_chip tmpa910_gpio_irq_chip = {
++ .name = "GPIO",
++ .ack = tmpa910_gpio_irq_ack,
++ .mask = tmpa910_gpio_irq_mask,
++ .unmask = tmpa910_gpio_irq_unmask,
++ .set_type = tmpa910_gpio_irq_type,
++};
++
++
++#define TMPA910_GPIO_BANK(name, port_base, base_gpio, im, om, irqm) \
++ { \
++ .chip = { \
++ .label = name, \
++ .direction_input = tmpa910_gpio_direction_input, \
++ .direction_output = tmpa910_gpio_direction_output, \
++ .get = tmpa910_gpio_get, \
++ .set = tmpa910_gpio_set, \
++ .dbg_show = tmpa910_gpio_dbg_show, \
++ .base = base_gpio, \
++ .ngpio = 8, \
++ }, \
++ .data_reg = TMPA910_GPIO_REG(port_base, PORT_OFS_DATA), \
++ .data_dir_reg = TMPA910_GPIO_REG(port_base, PORT_OFS_DIR),\
++ .input_mask = im, \
++ .output_mask = om,\
++ .irq_mask = irqm, \
++ }
++
++static struct tmpa910_gpio_chip tmpa910_gpio_banks[] = {
++ TMPA910_GPIO_BANK("A", PORTA, 0, 0xFF, 0x00, 0xFF), /* 8 interrupts */
++ TMPA910_GPIO_BANK("B", PORTB, 8, 0x00, 0xFF, 0x00),
++ TMPA910_GPIO_BANK("C", PORTC, 16, 0xE0, 0xFF, 0xA0), /* 2 interrupts */
++ TMPA910_GPIO_BANK("D", PORTD, 24, 0xFF, 0x00, 0xC0), /* 2 interrupts */
++#ifndef CONFIG_CPU_TMPA900
++ TMPA910_GPIO_BANK("E", PORTE, 32, 0xFF, 0x00, 0x00),
++#endif
++ TMPA910_GPIO_BANK("F", PORTF, 40, 0xCF, 0xC0, 0x80), /* 1 interrupt */
++ TMPA910_GPIO_BANK("G", PORTG, 48, 0xFF, 0xFF, 0x00),
++#ifndef CONFIG_CPU_TMPA900
++ TMPA910_GPIO_BANK("H", PORTH, 56, 0xFF, 0xFF, 0x00),
++#endif
++ TMPA910_GPIO_BANK("J", PORTJ, 72, 0x00, 0xFF, 0x00),
++ TMPA910_GPIO_BANK("K", PORTK, 80, 0x00, 0xFF, 0x00),
++ TMPA910_GPIO_BANK("L", PORTL, 88, 0x1F, 0x1F, 0x00),
++ TMPA910_GPIO_BANK("M", PORTM, 96, 0x0F, 0x0F, 0x00),
++ TMPA910_GPIO_BANK("N", PORTN, 104, 0xFF, 0xFF, 0xF0), /* 4 interrupts */
++ TMPA910_GPIO_BANK("P", PORTP, 112, 0xFF, 0xFF, 0xFF), /* 8 interrupts */
++ TMPA910_GPIO_BANK("R", PORTR, 120, 0x04, 0x07, 0x04), /* 1 interrupt */
++ TMPA910_GPIO_BANK("T", PORTT, 128, 0xFF, 0xFF, 0x00),
++};
++
++static int __init tmpa910_gpio_init(void)
++{
++ int i;
++ int gpio_irq;
++
++ /* Register GPIO banks */
++ for (i = 0; i < ARRAY_SIZE(tmpa910_gpio_banks); i++)
++ BUG_ON(gpiochip_add(&tmpa910_gpio_banks[i].chip) < 0);
++
++ /* Now the interrupts */
++ for (i = 0; i < TMPA910_NUM_GPIO_IRQS; i++) {
++ gpio_irq = gpio_to_irq(0) + i;
++ set_irq_chip(gpio_irq, &tmpa910_gpio_irq_chip);
++ set_irq_handler(gpio_irq, handle_level_irq);
++ set_irq_flags(gpio_irq, IRQF_VALID);
++ }
++
++ /* Finally install the interrrupt handlers we need for the GPIOs */
++ set_irq_chained_handler(INTR_VECT_GPIOA, tmpa910_gpioa_irq_handler);
++ set_irq_chained_handler(INTR_VECT_GPIOC, tmpa910_gpioc_irq_handler);
++#if !defined(CONFIG_TOUCHSCREEN_TMPA910) && !defined(CONFIG_TOUCHSCREEN_TMPA910_MODULE)
++ set_irq_chained_handler(INTR_VECT_GPIOD, tmpa910_gpiod_irq_handler);
++#endif
++ set_irq_chained_handler(INTR_VECT_GPIOF, tmpa910_gpiof_irq_handler);
++ set_irq_chained_handler(INTR_VECT_GPION, tmpa910_gpion_irq_handler);
++#if !defined(CONFIG_USB_ISP1362_HCD) && !defined(CONFIG_USB_ISP1362_HCD_MODULE)
++ set_irq_chained_handler(INTR_VECT_GPIOP, tmpa910_gpiop_irq_handler);
++#endif
++ set_irq_chained_handler(INTR_VECT_GPIOR, tmpa910_gpior_irq_handler);
++
++ return 0;
++}
++
++arch_initcall(tmpa910_gpio_init);
+diff --git a/arch/arm/mach-tmpa910/include/mach/adc.h b/arch/arm/mach-tmpa910/include/mach/adc.h
+new file mode 100644
+index 0000000..b1ea893
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/adc.h
+@@ -0,0 +1,62 @@
++/*
++ * Header file for TMPA910 TS Controller
++ *
++ * Data structure and register user interface
++ *
++ * Copyright (C) 2008 bplam GmbH
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __TMPA910_ADC_H__
++#define __TMPA910_ADC_H__
++
++
++struct tmpa910_adc
++{
++ uint32_t adreg0l; // 0x0000 a/d conversion result lower-order register 0
++ uint32_t adreg0h; // 0x0004 a/d conversion result higher-order register 0
++ uint32_t adreg1l; // 0x0008 a/d conversion result lower-order register 1
++ uint32_t adreg1h; // 0x000c a/d conversion result higher-order register 1
++ uint32_t adreg2l; // 0x0010 a/d conversion result lower-order register 2
++ uint32_t adreg2h; // 0x0014 a/d conversion result higher-order register 2
++ uint32_t adreg3l; // 0x0018 a/d conversion result lower-order register 3
++ uint32_t adreg3h; // 0x001c a/d conversion result higher-order register 3
++ uint32_t adreg4l; // 0x0020 a/d conversion result lower-order register 4
++ uint32_t adreg4h; // 0x0024 a/d conversion result higher-order register 4
++ uint32_t adreg5l; // 0x0028 a/d conversion result lower-order register 5
++ uint32_t adreg5h; // 0x002c a/d conversion result higher-order register 5
++ uint32_t rsd1; // 0x0030 reserved
++ uint32_t rsd2; // 0x0034 reserved
++ uint32_t rsd3; // 0x0038 reserved
++ uint32_t rsd4; // 0x003c reserved
++ uint32_t adregspl; // 0x0040 top-priority a/d conversion result lower-order register
++ uint32_t adregsph; // 0x0044 top-priority a/d conversion result higher-order register
++ uint32_t adcomregl; // 0x0048 a/d conversion result comparison lower-order register
++ uint32_t adcomregh; // 0x004c a/d conversion result comparison lower-order register
++ uint32_t admod0; // 0x0050 a/d mode control register 0
++ uint32_t admod1; // 0x0054 a/d mode control register 1
++ uint32_t admod2; // 0x0058 a/d mode control register 2
++ uint32_t admod3; // 0x005c a/d mode control register 3
++ uint32_t admod4; // 0x0060 a/d mode control register 4
++ uint32_t rsd5; // 0x0064 reserved
++ uint32_t rsd6; // 0x0068 reserved
++ uint32_t rsd7; // 0x006c reserved
++ uint32_t adclk; // 0x0070 a/d conversion clock setting register
++ uint32_t adie; // 0x0074 a/d interrupt enable register
++ uint32_t adis; // 0x0078 a/d interrupt status register
++ uint32_t adic; // 0x007c a/d interrupt clear register
++};
++
++#endif /* __TMPA910_ADC_H__ */
+diff --git a/arch/arm/mach-tmpa910/include/mach/debug-macro.S b/arch/arm/mach-tmpa910/include/mach/debug-macro.S
+new file mode 100644
+index 0000000..d8772bc
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/debug-macro.S
+@@ -0,0 +1,56 @@
++/* linux/include/asm-arm/arch-tmpa910/debug-macro.S
++ *
++ * Debugging macro include header
++ *
++ * Copyright (C) 1994-1999 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.
++ *
++*/
++
++#include "hardware.h"
++#define UART0DR 0x00
++#define UART0FR 0x18
++#define FR_TXFE 0x40
++#define FR_BUSY 0x08
++
++ .macro addruart,rx
++ mrc p15, 0, \rx, c1, c0
++ tst \rx, #1 @ MMU enabled?
++ moveq \rx, #0xf2000000 @ physical
++ movne \rx, #io_p2v(0xf2000000) @ virtual
++ .endm
++
++ .macro senduart,rd,rx
++ strb \rd, [\rx, #UART0DR]
++ .endm
++
++ .macro busyuart,rd,rx
++1002: ldrb \rd, [\rx, #UART0FR]
++ and \rd, \rd, #FR_TXFE
++ teq \rd, #FR_TXFE
++ bne 1002b
++ .endm
++
++ .macro waituart,rd,rx
++1001: ldrb \rd, [\rx, #UART0FR]
++ and \rd, \rd, #FR_BUSY
++ teq \rd, #0
++ bne 1001b
++ .endm
++
++/*
++ .macro addruart,rx
++ .endm
++
++ .macro senduart,rd,rx
++ .endm
++
++ .macro waituart,rd,rx
++ .endm
++
++ .macro busyuart,rd,rx
++ .endm
++*/
+diff --git a/arch/arm/mach-tmpa910/include/mach/dma.h b/arch/arm/mach-tmpa910/include/mach/dma.h
+new file mode 100644
+index 0000000..aff2bd8
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/dma.h
+@@ -0,0 +1,65 @@
++/*
++ * linux/include/asm-arm/arch-tmpa910/dma.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 __ASM_ARCH_TMPA910_DMA_H
++#define __ASM_ARCH_TMPA910_DMA_H
++
++#define TMPA910_DMA_CHANNELS 8
++
++enum {
++ DMA_UART0_TX = 0,
++ DMA_UART0_RX = 1,
++ DMA_NANDC0 = 4,
++ DMA_CMSI = 5,
++ I2S0 = 10,
++ I2S1 = 11,
++ LCDDA = 14,
++};
++
++/*
++ * Descriptor structure for TMPA910 DMA engine
++ */
++typedef struct tmpa910_dma_desc {
++ volatile u32 src_addr; /* DMA Channel source address */
++ volatile u32 dest_addr; /* DMA Channel dest address */
++ volatile u32 dma_lli; /* DMA linked list item */
++ volatile u32 control; /* DMA channel control */
++ volatile u32 config; /* DMA channel configuration */
++} tmpa910_dma_desc;
++
++typedef enum {
++ DMA_PRIO_HIGH = 1,
++ DMA_PRIO_MEDIUM = 4,
++ DMA_PRIO_LOW = 8,
++} tmpa910_dma_prio;
++
++struct tmpa910_dma_channel {
++ const char *name;
++ void (*irq_handler)(int, void *);
++ void (*err_handler)(int, void *);
++ void *data;
++ int dma_num;
++};
++
++void tmpa910_dma_enable(int dma_ch);
++void tmpa910_dma_disable(int dma_ch);
++long tmpa910_dma_get_size(int dma_ch);
++
++
++/*
++ * DMA registration
++ */
++
++int tmpa910_dma_request (const char *name,
++ int prio,
++ void (*irq_handler)(int, void *),
++ void (*err_handler)(int, void *),
++ void *data);
++
++void tmpa910_dma_free (int dma_ch);
++
++#endif /* _ASM_ARCH_DMA_H */
++
+diff --git a/arch/arm/mach-tmpa910/include/mach/entry-macro.S b/arch/arm/mach-tmpa910/include/mach/entry-macro.S
+new file mode 100644
+index 0000000..fa6af71
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/entry-macro.S
+@@ -0,0 +1,49 @@
++/*
++ * include/asm-arm/arch-tmpa910/entry-macro.S
++ *
++ * Low-level IRQ helper macros for TMPA910 platforms
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++#include <mach/hardware.h>
++
++
++ .macro get_irqnr_preamble, base, tmp
++ .endm
++
++ .macro arch_ret_to_user, tmp1, tmp2
++ .endm
++
++
++ .macro disable_fiq
++ .endm
++
++ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
++ ldr \irqstat, =IO_ADDRESS(0xf4000000) @ int ctrl
++
++ ldr \base, =0 @ invalid interrupt
++ ldr \tmp, [\irqstat, #0x000] @ 0xf00 <- vic addr
++ cmp \tmp, \base
++ beq 1002f
++
++ ldr \irqnr, [\irqstat, #0xf00] @ 0xf00 <- vic addr
++
++ # hack it here?
++ #str \irqnr, [\irqstat, #0xf00] @ 0xf00 <- vic addr
++
++ ldr \irqstat, =1 @ dummy compare
++ ldr \base, =32 @ invalid interrupt
++ cmp \irqnr, \base
++ bne 1001f
++1002:
++ ldr \irqstat, =0
++1001:
++ tst \irqstat, #1 @ to make the condition code = TRUE
++ .endm
++
++ .macro irq_prio_table
++ .endm
++
++
+diff --git a/arch/arm/mach-tmpa910/include/mach/gpio.h b/arch/arm/mach-tmpa910/include/mach/gpio.h
+new file mode 100644
+index 0000000..871d56c
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/gpio.h
+@@ -0,0 +1,27 @@
++#ifndef __ASM_ARCH_GPIO_H
++#define __ASM_ARCH_GPIO_H
++/*
++ * arch/arm/mach-tmpa910/include/mach/gpio.h
++ */
++
++#define ARCH_NR_GPIOS 136
++
++#include <asm-generic/gpio.h>
++#include <mach/irqs.h>
++
++#define gpio_get_value __gpio_get_value
++#define gpio_set_value __gpio_set_value
++#define gpio_cansleep __gpio_cansleep
++
++/*
++ * Map GPIO A0..A7 (0..7) to irq 64..71,
++ * B0..B7 (7..15) to irq 72..79, and
++ * F0..F7 (16..24) to irq 80..87.
++ */
++
++#define gpio_to_irq __tmpa910_gpio_to_irq
++#define irq_to_gpio __tmpa910_irq_to_gpio
++extern int __tmpa910_irq_to_gpio(unsigned irq);
++extern int __tmpa910_gpio_to_irq(unsigned gpio);
++
++#endif
+diff --git a/arch/arm/mach-tmpa910/include/mach/hardware.h b/arch/arm/mach-tmpa910/include/mach/hardware.h
+new file mode 100644
+index 0000000..1e509cb
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/hardware.h
+@@ -0,0 +1,57 @@
++/*
++ * arch/arm/mach-tmpa910/include/mach/hardware.h
++ *
++ * Based on arch-mx2ads/hardware.h, which is:
++ * Copyright (C) 2004 Metrowerks Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __ASM_ARCH_HARDWARE_H
++#define __ASM_ARCH_HARDWARE_H
++
++#ifndef __ASSEMBLY__
++#include <asm/types.h>
++#endif
++
++
++#define CLK32 32768
++
++
++// The phys IO [0xf000 0000 -> 0xf400 0000]
++// Let's do a simple 1:1 mapping
++#define TMPA910_IO_VIRT_BASE 0xf0000000
++#define TMPA910_IO_PHYS_BASE 0xf0000000
++
++#define TMPA910_IO_SIZE 0x04400000
++
++#ifndef __ASSEMBLY__
++
++#define _in32(__ofs) ( * ( (volatile unsigned long *) (__ofs) ) )
++#define _out32(__ofs,__val) { (* ( (volatile unsigned long *) (__ofs)) ) = __val; }
++
++#endif
++
++#define __REG(x) (*((volatile u32 *)io_p2v(x)))
++#define __PREG(x) (io_v2p((u32)&(x)))
++
++/* For assembler the C-type using macros are not useful */
++#define IO_ADDRESS(x) ((x))
++
++
++#define io_p2v(x) ( (x) )
++#define io_v2p(x) ( (x) )
++
++
++#endif
+diff --git a/arch/arm/mach-tmpa910/include/mach/io.h b/arch/arm/mach-tmpa910/include/mach/io.h
+new file mode 100644
+index 0000000..6dafefc
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/io.h
+@@ -0,0 +1,30 @@
++/*
++ * linux/include/asm-arm/arch-imxads/io.h
++ *
++ * Copyright (C) 1999 ARM Limited
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __ASM_ARM_ARCH_IO_H
++#define __ASM_ARM_ARCH_IO_H
++
++#include <mach/hardware.h>
++
++#define IO_SPACE_LIMIT 0xffffffff
++
++#define __io(a) ((void __iomem *)(a))
++#define __mem_pci(a) (a)
++
++#endif
+diff --git a/arch/arm/mach-tmpa910/include/mach/irqs.h b/arch/arm/mach-tmpa910/include/mach/irqs.h
+new file mode 100644
+index 0000000..93287f1
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/irqs.h
+@@ -0,0 +1,136 @@
++/*
++ * include/asm-arm/arch-topas910/irqs.h
++ *
++ * Copyright (C) 2004 Metrowerks Corp.
++ *
++ * based on arch-mx1ads/irqs.h, which is:
++ * Copyright (C) 1999 ARM Limited
++ * Copyright (C) 2000 Deep Blue Solutions Ltd.
++ * Copyright (C) 2006 Jochen Karrer
++ * Copyright (C) 2008 bplan GmbH
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef __ARM_IRQS_H__
++#define __ARM_IRQS_H__
++
++/* ------------------------------------------------------------
++ * Interrupts
++ * ------------------------------------------------------------
++ */
++
++#define NR_IRQS (MAXIRQNUM + 1 + TMPA910_NUM_GPIO_IRQS)
++#define NR_FIQS (MAXFIQNUM + 1)
++
++/*
++ * Topas910 IRQ Vectors
++ * TODO: Move to a board specific file.
++ */
++#define TOPAS910_INT_DM9000 INT_GPIO_INTH
++
++
++#define TMPA910_NUM_IRQS 32
++
++/*
++ * Chip internal -> not of the board
++ */
++#define INTR_VECT_WDT 0
++#define INTR_VECT_RTC 1
++#define INTR_VECT_TIMER01 2
++#define INTR_VECT_TIMER23 3
++#define INTR_VECT_TIMER45 4
++#define INTR_VECT_GPIOD 5
++#define INTR_VECT_I2C_CH0 6
++#define INTR_VECT_I2C_CH1 7
++#define INTR_VECT_ADC 8
++
++#define INTR_VECT_UART_CH0 10
++#define INTR_VECT_UART_CH1 11
++#define INTR_VECT_SSP_CH0 12
++#define INTR_VECT_SSP_CH1 13
++#define INTR_VECT_NDFC 14
++#define INTR_VECT_CMSIF 15
++#define INTR_VECT_DMA_ERROR 16
++#define INTR_VECT_DMA_END 17
++#define INTR_VECT_LCDC 18
++
++#define INTR_VECT_LCDDA 20
++#define INTR_VECT_USB 21
++#define INTR_VECT_SDHC 22
++#define INTR_VECT_I2S 23
++
++#define INTR_VECT_GPIOR 26
++#define INTR_VECT_GPIOP 27
++#define INTR_VECT_GPION 28
++#define INTR_VECT_GPIOF 29
++#define INTR_VECT_GPIOC 30
++#define INTR_VECT_GPIOA 31
++
++#define MAXIRQNUM 31
++#define MAXFIQNUM 31
++
++#define DMA_ERR_INT INTR_VECT_DMA_ERROR
++#define DMA_END_INT INTR_VECT_DMA_END
++#define I2S_INT INTR_VECT_I2S
++#define USB_INT INTR_VECT_USB
++
++/*
++ * GPIO Interrupts
++ */
++
++#define TMPA910_NUM_GPIO_IRQS 26
++
++/* Port A */
++#define INT_GPIO_KI0 32
++#define INT_GPIO_KI1 33
++#define INT_GPIO_KI2 34
++#define INT_GPIO_KI3 35
++#define INT_GPIO_KI4 36
++#define INT_GPIO_KI5 37
++#define INT_GPIO_KI6 38
++#define INT_GPIO_KI7 39
++
++/* Port C */
++#define INT_GPIO_INT8 40
++#define INT_GPIO_INT9 41
++
++/* Port D */
++#define INT_GPIO_INTA 42
++#define INT_GPIO_INTB 43
++
++/* Port F */
++#define INT_GPIO_INTC 44
++
++/* Port N */
++#define INT_GPIO_INTD 45
++#define INT_GPIO_INTE 46
++#define INT_GPIO_INTF 47
++#define INT_GPIO_INTG 48
++
++/* Port P */
++#define INT_GPIO_INT0 49
++#define INT_GPIO_INT1 50
++#define INT_GPIO_INT2 51
++#define INT_GPIO_INT3 52
++#define INT_GPIO_INT4 53
++#define INT_GPIO_INT5 54
++#define INT_GPIO_INT6 55
++#define INT_GPIO_INT7 56
++
++/* Port R */
++#define INT_GPIO_INTH 57
++
++#endif
+diff --git a/arch/arm/mach-tmpa910/include/mach/memory.h b/arch/arm/mach-tmpa910/include/mach/memory.h
+new file mode 100644
+index 0000000..13105bd
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/memory.h
+@@ -0,0 +1,44 @@
++/*
++ * linux/include/asm-arm/arch-topas910/memory.h
++ *
++ * Copyright (C) 1999 ARM Limited
++ * Copyright (C) 2002 Shane Nay (shane at minirl.com)
++ * Copyright (C) 2006 Jochen Karrer (jk06 at jkarrer.de)
++ * Copyright (C) 2008 bplan GmbH
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __ASM_ARCH_MEMORY_H
++#define __ASM_ARCH_MEMORY_H
++
++#define FB_SIZE UL(2048*1024)
++#define FB_OFFSET PHYS_OFFSET + MEM_SIZE
++
++#define PHYS_OFFSET UL(0x40000000)
++#define MEM_SIZE ( UL(0x04000000) - FB_SIZE)
++/*
++ * Virtual view <-> DMA view memory address translations
++ * virt_to_bus: Used to translate the virtual address to an
++ * address suitable to be passed to set_dma_addr
++ * bus_to_virt: Used to convert an address for DMA operations
++ * to an address that the kernel can use.
++ */
++#define __virt_to_bus__is_a_macro
++#define __virt_to_bus(x) (x - PAGE_OFFSET + PHYS_OFFSET)
++#define __bus_to_virt__is_a_macro
++#define __bus_to_virt(x) (x - PHYS_OFFSET + PAGE_OFFSET)
++
++#endif
++
+diff --git a/arch/arm/mach-tmpa910/include/mach/system.h b/arch/arm/mach-tmpa910/include/mach/system.h
+new file mode 100644
+index 0000000..f8d1024
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/system.h
+@@ -0,0 +1,56 @@
++/*
++ * arch/arm/mach-tmpa910/include/mach/system.h
++ *
++ * Copyright (C) 1999 ARM Limited
++ * Copyright (C) 2000 Deep Blue Solutions Ltd
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __ASM_ARCH_SYSTEM_H
++#define __ASM_ARCH_SYSTEM_H
++
++#include <asm/io.h>
++
++static void
++arch_idle(void)
++{
++ /*
++ * This should do all the clock switching
++ * and wait for interrupt tricks
++ */
++ cpu_do_idle();
++}
++
++static inline void
++arch_reset(char mode)
++{
++ uint8_t *wdt_base;
++
++ printk("Issue reset\n");
++
++ wdt_base = (char *) (0xf0010000);
++
++ if (wdt_base==NULL )
++ {
++ wdt_base = (uint8_t *) 0xf0010000;
++ }
++
++ outl( 0x1, (uint32_t *) (wdt_base + 0));
++ outl( 0x3, (uint32_t *) (wdt_base + 8));
++
++ /* Bye ! */
++}
++
++#endif
+diff --git a/arch/arm/mach-tmpa910/include/mach/timex.h b/arch/arm/mach-tmpa910/include/mach/timex.h
+new file mode 100644
+index 0000000..d9fe3bb
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/timex.h
+@@ -0,0 +1,26 @@
++/*
++ * linux/include/asm-arm/imx/timex.h
++ *
++ * Copyright (C) 1999 ARM Limited
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef __ASM_ARCH_TIMEX_H
++#define __ASM_ARCH_TIMEX_H
++#include <mach/hardware.h>
++#define CLOCK_TICK_RATE (CLK32)
++
++#endif
+diff --git a/arch/arm/mach-tmpa910/include/mach/tmpa910_regs.h b/arch/arm/mach-tmpa910/include/mach/tmpa910_regs.h
+new file mode 100644
+index 0000000..8af57c7
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/tmpa910_regs.h
+@@ -0,0 +1,502 @@
++/*
++ * Copyright (C) 2008 bplan GmbH. All rights reserved.
++ * Copyright (C) 2009 Florian Boor <florian.boor at kernelconcepts.de>
++ *
++ * 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
++ *
++ * TMPA910 register header
++ */
++
++#ifndef __TMPA910_REGS__
++#define __TMPA910_REGS__
++
++/* GPIO Ports */
++
++#define PORT_BASE 0xF0800000
++#define PORTA 0x0000
++#define PORTB 0x1000
++#define PORTC 0x2000
++#define PORTD 0x3000
++#ifndef CONFIG_CPU_TMPA900
++#define PORTE 0x4000
++#endif
++#define PORTF 0x5000
++#define PORTG 0x6000
++#ifndef CONFIG_CPU_TMPA900
++#define PORTH 0x7000
++#endif
++#define PORTJ 0x8000
++#define PORTK 0x9000
++#define PORTL 0xA000
++#define PORTM 0xB000
++#define PORTN 0xC000
++#define PORTP 0xD000
++#define PORTR 0xE000
++#define PORTT 0xF000
++
++/* TMPA900 */
++#ifdef CONFIG_CPU_TMPA900
++#define PORTU 0x4000
++#define PORTV 0x7000
++#endif
++
++
++#define PORT_OFS_DATA 0x03FC /* 0x000 - 0x3FC, data register masked from 0x00 to 0xFF << 2 */
++#define PORT_OFS_DIR 0x0400 /* direction register */
++#define PORT_OFS_FR1 0x0424 /* function register 1 */
++#define PORT_OFS_FF2 0x0428 /* function register 2 */
++#define PORT_OFS_IS 0x0804 /* interrupt sensitivity */
++#define PORT_OFS_IBE 0x0808 /* interrupt both edge register */
++#define PORT_OFS_IEV 0x080C /* interrupt event register */
++#define PORT_OFS_IE 0x0810 /* interrupt enable register*/
++#define PORT_OFS_RIS 0x0814 /* raw interrupt status register */
++#define PORT_OFS_MIS 0x0818 /* masked interrupt status */
++#define PORT_OFS_IC 0x081C /* interrupt clear register */
++#define PORT_OFS_ODE 0x0C00 /* open drain output */
++
++#define TMPA910_GPIO_REG(x,y) (PORT_BASE | (x) | (y)) /* base addr + port offset + register offset */
++
++#define TMPA910_GPIO_REG_DATA(x) (PORT_BASE | PORT_OFS_DATA | (x))
++#define TMPA910_GPIO_REG_DIR(x) (PORT_BASE | PORT_OFS_DIR | (x))
++#define TMPA910_GPIO_REG_IS(x) (PORT_BASE | PORT_OFS_IS | (x))
++#define TMPA910_GPIO_REG_IBE(x) (PORT_BASE | PORT_OFS_IBE | (x))
++#define TMPA910_GPIO_REG_IEV(x) (PORT_BASE | PORT_OFS_IEV | (x))
++#define TMPA910_GPIO_REG_IE(x) (PORT_BASE | PORT_OFS_IE | (x))
++#define TMPA910_GPIO_REG_MIS(x) (PORT_BASE | PORT_OFS_MIS | (x))
++#define TMPA910_GPIO_REG_IC(x) (PORT_BASE | PORT_OFS_IC | (x))
++
++#define TMPA910_CFG_PORT_GPIO(x) (__REG(PORT_BASE | (x) | PORT_OFS_FR1) = 0)
++#define TMPA910_PORT_FR1(x) __REG(PORT_BASE | (x) | PORT_OFS_FR1)
++#define TMPA910_PORT_T_FR1 TMPA910_PORT_FR1(PORTT)
++
++
++/******* redundent stuff */
++#define PORTB_BASE (PORT_BASE + 0x1000)
++
++#define PORTB_GPIODATA (PORTB_BASE + PORT_OFS_DATA)
++
++
++#define PORTF_BASE 0xF0805000
++#define PORTF_GPIOFDIR (PORTF_BASE + 0x0400)
++#define PORTF_GPIOFFR (PORTF_BASE + 0x0424)
++#define PORTF_GPIOFODE (PORTF_BASE + 0x0c00)
++
++
++/********/
++#define PORTD_BASE 0xF0803000
++#define PORTD_GPIOFR1 (PORTD_BASE + 0x0424)
++#define PORTD_GPIOFR2 (PORTD_BASE + 0x0428)
++#define PORTD_GPIOIE (PORTD_BASE + 0x0810)
++#define PORTD_GPIOIC (PORTD_BASE + 0x081C)
++#define PORTD_GPIOMIS (PORTD_BASE + 0x0818)
++/********/
++#define PORTE_BASE 0xF0804000
++#define PORTE_GPIOEFR (PORTE_BASE + 0x0424)
++
++/********/
++#define PORTG_BASE 0xF0806000
++#define PORTG_GPIOFR (PORTG_BASE + 0x0424)
++
++
++/* GPIO registers */
++#define IO_1_GPIO_BASE (0xF0800000)
++#define IO_1_BASE (IO_1_GPIO_BASE)
++#define GPIO_A_BASE (IO_1_GPIO_BASE + PORTA)
++#define GPIO_B_BASE (IO_1_GPIO_BASE + PORTB)
++#define GPIO_C_BASE (IO_1_GPIO_BASE + PORTC)
++#define GPIO_D_BASE (IO_1_GPIO_BASE + PORTD)
++#ifndef CONFIG_CPU_TMPA900
++#define GPIO_E_BASE (IO_1_GPIO_BASE + PORTE)
++#endif
++#define GPIO_F_BASE (IO_1_GPIO_BASE + PORTF)
++#define GPIO_G_BASE (IO_1_GPIO_BASE + PORTG)
++#ifndef CONFIG_CPU_TMPA900
++#define GPIO_H_BASE (IO_1_GPIO_BASE + PORTH)
++#endif
++#define GPIO_J_BASE (IO_1_GPIO_BASE + PORTJ)
++#define GPIO_K_BASE (IO_1_GPIO_BASE + PORTK)
++#define GPIO_L_BASE (IO_1_GPIO_BASE + PORTL)
++#define GPIO_M_BASE (IO_1_GPIO_BASE + PORTM)
++#define GPIO_N_BASE (IO_1_GPIO_BASE + PORTN)
++#define GPIO_P_BASE (IO_1_GPIO_BASE + PORTP)
++#define GPIO_R_BASE (IO_1_GPIO_BASE + PORTR)
++#define GPIO_T_BASE (IO_1_GPIO_BASE + PORTT)
++
++#ifdef CONFIG_CPU_TMPA900
++#define GPIO_U_BASE (IO_1_GPIO_BASE + PORTU)
++#define GPIO_V_BASE (IO_1_GPIO_BASE + PORTV)
++#endif
++
++#define GPIOADATA __REG(GPIO_A_BASE + 0x3FC)
++#define GPIOADIR __REG(GPIO_A_BASE + 0x400)
++#define GPIOAFR1 __REG(GPIO_A_BASE + 0x424)
++#define GPIOAFR2 __REG(GPIO_A_BASE + 0x428)
++#define GPIOAIS __REG(GPIO_A_BASE + 0x804)
++#define GPIOAIBE __REG(GPIO_A_BASE + 0x808)
++#define GPIOAIEV __REG(GPIO_A_BASE + 0x80C)
++#define GPIOAIE __REG(GPIO_A_BASE + 0x810)
++#define GPIOARIS __REG(GPIO_A_BASE + 0x814)
++#define GPIOAMIS __REG(GPIO_A_BASE + 0x818)
++#define GPIOAIC __REG(GPIO_A_BASE + 0x81C)
++
++#define GPIOBDATA __REG(GPIO_B_BASE + 0x3FC)
++#define GPIOBDIR __REG(GPIO_B_BASE + 0x400)
++#define GPIOBFR1 __REG(GPIO_B_BASE + 0x424)
++#define GPIOBFR2 __REG(GPIO_B_BASE + 0x428)
++#define GPIOBODE __REG(GPIO_B_BASE + 0xC00)
++
++#define GPIOCDATA __REG(GPIO_C_BASE + 0x3FC)
++#define GPIOCDIR __REG(GPIO_C_BASE + 0x400)
++#define GPIOCFR1 __REG(GPIO_C_BASE + 0x424)
++#define GPIOCFR2 __REG(GPIO_C_BASE + 0x428)
++#define GPIOCIS __REG(GPIO_C_BASE + 0x804)
++#define GPIOCIBE __REG(GPIO_C_BASE + 0x808)
++#define GPIOCIEV __REG(GPIO_C_BASE + 0x80C)
++#define GPIOCIE __REG(GPIO_C_BASE + 0x810)
++#define GPIOCRIS __REG(GPIO_C_BASE + 0x814)
++#define GPIOCMIS __REG(GPIO_C_BASE + 0x818)
++#define GPIOCIC __REG(GPIO_C_BASE + 0x81C)
++#define GPIOCODE __REG(GPIO_C_BASE + 0xC00)
++
++#define GPIODDATA __REG(GPIO_D_BASE + 0x3FC)
++#define GPIODDIR __REG(GPIO_D_BASE + 0x400)
++#define GPIODFR1 __REG(GPIO_D_BASE + 0x424)
++#define GPIODFR2 __REG(GPIO_D_BASE + 0x428)
++#define GPIODIS __REG(GPIO_D_BASE + 0x804)
++#define GPIODIBE __REG(GPIO_D_BASE + 0x808)
++#define GPIODIEV __REG(GPIO_D_BASE + 0x80C)
++#define GPIODIE __REG(GPIO_D_BASE + 0x810)
++#define GPIODRIS __REG(GPIO_D_BASE + 0x814)
++#define GPIODMIS __REG(GPIO_D_BASE + 0x818)
++#define GPIODIC __REG(GPIO_D_BASE + 0x81C)
++
++#ifndef CONFIG_CPU_TMPA900
++#define GPIOEDATA __REG(GPIO_E_BASE + 0x3FC)
++#define GPIOEDIR __REG(GPIO_E_BASE + 0x400)
++#define GPIOEFR1 __REG(GPIO_E_BASE + 0x424)
++#define GPIOEFR2 __REG(GPIO_E_BASE + 0x428)
++#endif
++
++#define GPIOFDATA __REG(GPIO_F_BASE + 0x000)
++#define GPIOFDIR __REG(GPIO_F_BASE + 0x400)
++#define GPIOFFR1 __REG(GPIO_F_BASE + 0x424)
++#define GPIOFFR2 __REG(GPIO_F_BASE + 0x428)
++#define GPIOFIS __REG(GPIO_F_BASE + 0x804)
++#define GPIOFIBE __REG(GPIO_F_BASE + 0x808)
++#define GPIOFIEV __REG(GPIO_F_BASE + 0x80C)
++#define GPIOFIE __REG(GPIO_F_BASE + 0x810)
++#define GPIOFRIS __REG(GPIO_F_BASE + 0x814)
++#define GPIOFMIS __REG(GPIO_F_BASE + 0x818)
++#define GPIOFIC __REG(GPIO_F_BASE + 0x81C)
++#define GPIOFODE __REG(GPIO_F_BASE + 0xC00)
++
++#define GPIOGDATA __REG(GPIO_G_BASE + 0x3FC)
++#define GPIOGDIR __REG(GPIO_G_BASE + 0x400)
++#define GPIOGFR1 __REG(GPIO_G_BASE + 0x424)
++#define GPIOGFR2 __REG(GPIO_G_BASE + 0x428)
++
++#ifndef CONFIG_CPU_TMPA900
++#define GPIOHDATA __REG(GPIO_H_BASE + 0x3FC)
++#define GPIOHDIR __REG(GPIO_H_BASE + 0x400)
++#define GPIOHFR1 __REG(GPIO_H_BASE + 0x424)
++#define GPIOHFR2 __REG(GPIO_H_BASE + 0x428)
++#endif
++
++#define GPIOJDATA __REG(GPIO_J_BASE + 0x3FC)
++#define GPIOJDIR __REG(GPIO_J_BASE + 0x400)
++#define GPIOJFR1 __REG(GPIO_J_BASE + 0x424)
++#define GPIOJFR2 __REG(GPIO_J_BASE + 0x428)
++
++#define GPIOKDATA __REG(GPIO_K_BASE + 0x3FC)
++#define GPIOKDIR __REG(GPIO_K_BASE + 0x400)
++#define GPIOKFR1 __REG(GPIO_K_BASE + 0x424)
++#define GPIOKFR2 __REG(GPIO_K_BASE + 0x428)
++
++#define GPIOLDATA __REG(GPIO_L_BASE + 0x3FC)
++#define GPIOLDIR __REG(GPIO_L_BASE + 0x400)
++#define GPIOLFR1 __REG(GPIO_L_BASE + 0x424)
++#define GPIOLFR2 __REG(GPIO_L_BASE + 0x428)
++
++#define GPIOMDATA __REG(GPIO_M_BASE + 0x3FC)
++#define GPIOMDIR __REG(GPIO_M_BASE + 0x400)
++#define GPIOMFR1 __REG(GPIO_M_BASE + 0x424)
++#define GPIOMFR2 __REG(GPIO_M_BASE + 0x428)
++
++#define GPIONDATA __REG(GPIO_N_BASE + 0x3FC)
++#define GPIONDIR __REG(GPIO_N_BASE + 0x400)
++#define GPIONFR1 __REG(GPIO_N_BASE + 0x424)
++#define GPIONFR2 __REG(GPIO_N_BASE + 0x428)
++#define GPIONIS __REG(GPIO_N_BASE + 0x804)
++#define GPIONIBE __REG(GPIO_N_BASE + 0x808)
++#define GPIONIEV __REG(GPIO_N_BASE + 0x80C)
++#define GPIONIE __REG(GPIO_N_BASE + 0x810)
++#define GPIONRIS __REG(GPIO_N_BASE + 0x814)
++#define GPIONMIS __REG(GPIO_N_BASE + 0x818)
++#define GPIONIC __REG(GPIO_N_BASE + 0x81C)
++
++#define GPIOPDATA __REG(GPIO_P_BASE + 0x3FC)
++#define GPIOPDIR __REG(GPIO_P_BASE + 0x400)
++#define GPIOPFR1 __REG(GPIO_P_BASE + 0x424)
++#define GPIOPFR2 __REG(GPIO_P_BASE + 0x428)
++#define GPIOPIS __REG(GPIO_P_BASE + 0x804)
++#define GPIOPIBE __REG(GPIO_P_BASE + 0x808)
++#define GPIOPIEV __REG(GPIO_P_BASE + 0x80C)
++#define GPIOPIE __REG(GPIO_P_BASE + 0x810)
++#define GPIOPRIS __REG(GPIO_P_BASE + 0x814)
++#define GPIOPMIS __REG(GPIO_P_BASE + 0x818)
++#define GPIOPIC __REG(GPIO_P_BASE + 0x81C)
++
++#define GPIORDATA __REG(GPIO_R_BASE + 0x3FC)
++#define GPIORDIR __REG(GPIO_R_BASE + 0x400)
++#define GPIORFR1 __REG(GPIO_R_BASE + 0x424)
++#define GPIORFR2 __REG(GPIO_R_BASE + 0x428)
++#define GPIORIS __REG(GPIO_R_BASE + 0x804)
++#define GPIORIBE __REG(GPIO_R_BASE + 0x808)
++#define GPIORIEV __REG(GPIO_R_BASE + 0x80C)
++#define GPIORIE __REG(GPIO_R_BASE + 0x810)
++#define GPIORRIS __REG(GPIO_R_BASE + 0x814)
++#define GPIORMIS __REG(GPIO_R_BASE + 0x818)
++#define GPIORIC __REG(GPIO_R_BASE + 0x81C)
++
++#define GPIOTDATA __REG(GPIO_T_BASE + 0x3FC)
++#define GPIOTDIR __REG(GPIO_T_BASE + 0x400)
++#define GPIOTFR1 __REG(GPIO_T_BASE + 0x424)
++#define GPIOTFR2 __REG(GPIO_T_BASE + 0x428)
++
++/* Port U and V TMPA900 only */
++#ifdef CONFIG_CPU_TMPA900
++#define GPIOUFR1 __REG(GPIO_U_BASE + 0x424)
++#define GPIOUFR2 __REG(GPIO_U_BASE + 0x428)
++
++#define GPIOVFR1 __REG(GPIO_V_BASE + 0x424)
++#define GPIOVFR2 __REG(GPIO_V_BASE + 0x428)
++#endif
++
++/* Timer */
++#define TMPA910_TIMER0 0xf0040000
++
++/* LCD Controller */
++#define LCDC_BASE 0xf4200000
++
++
++/* I2C Ports */
++#define I2C0_BASE 0xF0070000
++
++
++/* Camera sensor controller */
++#define CMOSCAM_BASE 0xF2020000
++
++/* DMA */
++#define DMAC_BASE 0xF4100000
++#define DMACIntTCStatus __REG(DMAC_BASE | 0x004)
++#define DMACIntTCClear __REG(DMAC_BASE | 0x008)
++#define DMACConfiguration __REG(DMAC_BASE | 0x030)
++#define DMACC5SrcAddr __REG(DMAC_BASE | 0x1a0)
++#define DMACC5DestAddr __REG(DMAC_BASE | 0x1a4)
++#define DMACC5Control __REG(DMAC_BASE | 0x1ac)
++#define DMACC5Configuration __REG(DMAC_BASE | 0x1b0)
++
++/* Memory controller MPMC0 */
++#define SMC_MPMC0_BASE 0xf4301000
++#define SMC_MEMC_STATUS_3 __REG(SMC_MPMC0_BASE + 0x000)
++#define SMC_MEMIF_CFG_3 __REG(SMC_MPMC0_BASE + 0x004)
++#define SMC_DIRECT_CMD_3 __REG(SMC_MPMC0_BASE + 0x010)
++#define SMC_SET_CYCLES_3 __REG(SMC_MPMC0_BASE + 0x014)
++#define SMC_SET_OPMODE_3 __REG(SMC_MPMC0_BASE + 0x018)
++#define SMC_SRAM_CYCLES_0_3 __REG(SMC_MPMC0_BASE + 0x100)
++#define SMC_SRAM_CYCLES_1_3 __REG(SMC_MPMC0_BASE + 0x120)
++#define SMC_SRAM_CYCLES_2_3 __REG(SMC_MPMC0_BASE + 0x140)
++#define SMC_SRAM_CYCLES_3_3 __REG(SMC_MPMC0_BASE + 0x160)
++#define SMC_OPMODE0_0_3 __REG(SMC_MPMC0_BASE + 0x104)
++#define SMC_OPMODE0_1_3 __REG(SMC_MPMC0_BASE + 0x124)
++#define SMC_OPMODE0_2_3 __REG(SMC_MPMC0_BASE + 0x144)
++#define SMC_OPMODE0_3_3 __REG(SMC_MPMC0_BASE + 0x164)
++
++/* Memory controller MPMC1 */
++#define SMC_MPMC1_BASE 0xf4311000
++#define SMC_MEMC_STATUS_5 __REG(SMC_MPMC1_BASE + 0x000)
++#define SMC_MEMIF_CFG_5 __REG(SMC_MPMC1_BASE + 0x004)
++#define SMC_DIRECT_CMD_5 __REG(SMC_MPMC1_BASE + 0x010)
++#define SMC_SET_CYCLES_5 __REG(SMC_MPMC1_BASE + 0x014)
++#define SMC_SET_OPMODE_5 __REG(SMC_MPMC1_BASE + 0x018)
++#define SMC_SRAM_CYCLES_0_5 __REG(SMC_MPMC1_BASE + 0x100)
++#define SMC_SRAM_CYCLES_1_5 __REG(SMC_MPMC1_BASE + 0x120)
++#define SMC_SRAM_CYCLES_2_5 __REG(SMC_MPMC1_BASE + 0x140)
++#define SMC_SRAM_CYCLES_3_5 __REG(SMC_MPMC1_BASE + 0x160)
++#define SMC_OPMODE0_0_5 __REG(SMC_MPMC1_BASE + 0x104)
++#define SMC_OPMODE0_1_5 __REG(SMC_MPMC1_BASE + 0x124)
++#define SMC_OPMODE0_2_5 __REG(SMC_MPMC1_BASE + 0x144)
++#define SMC_OPMODE0_3_5 __REG(SMC_MPMC1_BASE + 0x164)
++
++/* I2S Interface */
++#define I2S_BASE 0xF2040000
++#define I2STCON __REG(I2S_BASE + 0x000)
++#define I2STSLVON __REG(I2S_BASE + 0x004)
++#define I2STFCLR __REG(I2S_BASE + 0x008)
++#define I2STMS __REG(I2S_BASE + 0x00C)
++#define I2STMCON __REG(I2S_BASE + 0x010)
++#define I2STMSTP __REG(I2S_BASE + 0x014)
++#define I2STDMA1 __REG(I2S_BASE + 0x018)
++#define I2SRCON __REG(I2S_BASE + 0x020)
++#define I2SRSLVON __REG(I2S_BASE + 0x024)
++#define I2SFRFCLR __REG(I2S_BASE + 0x028)
++#define I2SRMS __REG(I2S_BASE + 0x02C)
++#define I2SRMCON __REG(I2S_BASE + 0x030)
++#define I2SRMSTP __REG(I2S_BASE + 0x034)
++#define I2SRDMA1 __REG(I2S_BASE + 0x038)
++#define I2SCOMMON __REG(I2S_BASE + 0x044)
++#define I2STST __REG(I2S_BASE + 0x048)
++#define I2SRST __REG(I2S_BASE + 0x04C)
++#define I2SINT __REG(I2S_BASE + 0x050)
++#define I2SINTMSK __REG(I2S_BASE + 0x054)
++#define I2STDAT __REG(I2S_BASE + 0x1000)
++#define I2SRDAT __REG(I2S_BASE + 0x2000)
++#define I2STDAT_ADR (I2S_BASE + 0x1000)
++#define I2SRDAT_ADR (I2S_BASE + 0x2000)
++
++
++/* System Control / PLL */
++#define PLL_BASE_ADDRESS 0xF0050000
++#define SYSCR0 __REG__(PLL_BASE_ADDRESS + 0x000)
++#define SYSCR1 __REG__(PLL_BASE_ADDRESS + 0x004)
++#define SYSCR2 __REG__(PLL_BASE_ADDRESS + 0x008)
++#define SYSCR3 __REG__(PLL_BASE_ADDRESS + 0x00C)
++#define SYSCR4 __REG__(PLL_BASE_ADDRESS + 0x010)
++#define SYSCR5 __REG__(PLL_BASE_ADDRESS + 0x014)
++#define SYSCR6 __REG__(PLL_BASE_ADDRESS + 0x018)
++#define SYSCR7 __REG__(PLL_BASE_ADDRESS + 0x01C)
++#define CLKCR5 __REG__(PLL_BASE_ADDRESS + 0x054)
++
++/* NAND Flash Controller */
++#define NANDF_BASE 0xF2010000
++
++#define NDFMCR0 __REG(NANDF_BASE | 0x0000) /* NAND-Flash Control Register 0 */
++#define NDFMCR1 __REG(NANDF_BASE | 0x0004) /* NAND-Flash Control Register 1 */
++#define NDFMCR2 __REG(NANDF_BASE | 0x0008) /* NAND-Flash Control Register 2 */
++#define NDFINTC __REG(NANDF_BASE | 0x000C) /* NAND-Flash Interrupt Control Register */
++#define NDFDTR __REG(NANDF_BASE | 0x0010) /* NAND-Flash Data Register */
++#define NDECCRD0 __REG(NANDF_BASE | 0x0020) /* NAND-Flash ECC Read Register 0 */
++#define NDECCRD1 __REG(NANDF_BASE | 0x0024) /* NAND-Flash ECC Read Register 1 */
++#define NDECCRD2 __REG(NANDF_BASE | 0x0028) /* NAND-Flash ECC Read Register 2 */
++#define NDRSCA0 __REG(NANDF_BASE | 0x0030) /* NAND-Flash Reed-Solomon Calculation Result Address Register 0 */
++#define NDRSCD0 __REG(NANDF_BASE | 0x0034) /* NAND-Flash Reed-Solomon Calculation Result Data Register 0 */
++#define NDRSCA1 __REG(NANDF_BASE | 0x0038) /* NAND-Flash Reed-Solomon Calculation Result Address Register 1 */
++#define NDRSCD1 __REG(NANDF_BASE | 0x003C) /* NAND-Flash Reed-Solomon Calculation Result Data Register 1 */
++#define NDRSCA2 __REG(NANDF_BASE | 0x0040) /* NAND-Flash Reed-Solomon Calculation Result Address Register 2 */
++#define NDRSCD2 __REG(NANDF_BASE | 0x0044) /* NAND-Flash Reed-Solomon Calculation Result Data Register 2 */
++#define NDRSCA3 __REG(NANDF_BASE | 0x0048) /* NAND-Flash Reed-Solomon Calculation Result Address Register 3 */
++#define NDRSCD3 __REG(NANDF_BASE | 0x004C) /* NAND-Flash Reed-Solomon Calculation Result Data Register 3 */
++
++#define NDFDTR_PHY NANDF_BASE + 0x10
++
++
++#define NDFMCR0_ECCRST (0x1 << 0)
++#define NDFMCR0_BUSY (0x1 << 1)
++#define NDFMCR0_ECCE (0x1 << 2)
++#define NDFMCR0_CE1 (0x1 << 3)
++#define NDFMCR0_CE0 (0x1 << 4)
++#define NDFMCR0_CLE (0x1 << 5)
++#define NDFMCR0_ALE (0x1 << 6)
++#define NDFMCR0_WE (0x1 << 7)
++#define NDFMCR0_RSEDN (0x1 << 10)
++
++#define NDFMCR1_ECCS (0x1 << 1)
++#define NDFMCR1_SELAL (0x1 << 9)
++#define NDFMCR1_ALS (0x1 << 8)
++
++#define NAND_DMAC_STATUS (0x1 << 5)
++#define NAND_DMAC_CLEAR (0x1 << 5)
++
++
++
++/* LCDDA (LCD Data Process Accelerator) */
++#define LCDDA_BASE 0xF2050000
++#define LCDDA_LDACR0 __REG(LCDDA_BASE + 0x00)
++#define LCDDA_LDACR1 __REG(LCDDA_BASE + 0x34)
++
++
++/* Interrupt Controller */
++#define INTR_BASE 0xF4000000
++
++/* Touchscreen Controller */
++#define TS_BASE 0xf00601f0
++#define TOUCHSCREEN_BASE 0xF00601F0
++
++/* ADC */
++#define ADC_BASE 0xf0080000
++
++/* SDRAM */
++#define SRAM_BASE 0xF8002000
++#define SRAM_SIZE 0x0000C000
++
++/* DMA registers */
++#define DMA_BASE (0xF4100000)
++#define DMA_INT_STATUS __REG(DMA_BASE)
++#define DMA_TC_STATUS __REG(DMA_BASE + 0x0004)
++#define DMA_TC_CLEAR __REG(DMA_BASE + 0x0008)
++#define DMA_ERR_STATUS __REG(DMA_BASE + 0x000c)
++#define DMA_ERR_CLEAR __REG(DMA_BASE + 0x0010)
++#define DMA_RAW_TC_STATUS __REG(DMA_BASE + 0x0014)
++#define DMA_RAW_ERR_STATUS __REG(DMA_BASE + 0x0018)
++#define DMA_ENABLED_CHN __REG(DMA_BASE + 0x001c)
++#define DMA_CONFIGURE __REG(DMA_BASE + 0x0030)
++
++#define DMA_SRC_ADDR(x) __REG(DMA_BASE + 0x100 + ((x) << 5))
++#define DMA_DEST_ADDR(x) __REG(DMA_BASE + 0x100 + ((x) << 5) + 0x04)
++#define DMA_LLI(x) __REG(DMA_BASE + 0x100 + ((x) << 5) + 0x08)
++#define DMA_CONTROL(x) __REG(DMA_BASE + 0x100 + ((x) << 5) + 0x0c)
++#define DMA_CONFIG(x) __REG(DMA_BASE + 0x100 + ((x) << 5) + 0x10)
++
++#define DMA_CONFIG_EN (1 << 0)
++
++
++/* I2C_1 : 0xf0071000 */
++#define I2C1_BASE (0xF0071000)
++#define I2C1CR1 __REG(I2C1_BASE + 0x00)
++#define I2C1DBR __REG(I2C1_BASE + 0x04)
++#define I2C1AR __REG(I2C1_BASE + 0x08)
++#define I2C1CR2 __REG(I2C1_BASE + 0x0c)
++#define I2C1SR __REG(I2C1_BASE + 0x0c)
++#define I2C1PRS __REG(I2C1_BASE + 0x10)
++#define I2C1IE __REG(I2C1_BASE + 0x14)
++#define I2C1IR __REG(I2C1_BASE + 0x18)
++
++/* I2S : 0xf2040000 */
++#define I2S_BASE 0xF2040000
++#define I2STCON __REG(I2S_BASE + 0x000)
++#define I2STSLVON __REG(I2S_BASE + 0x004)
++#define I2STFCLR __REG(I2S_BASE + 0x008)
++#define I2STMS __REG(I2S_BASE + 0x00C)
++#define I2STMCON __REG(I2S_BASE + 0x010)
++#define I2STMSTP __REG(I2S_BASE + 0x014)
++#define I2STDMA1 __REG(I2S_BASE + 0x018)
++#define I2SRCON __REG(I2S_BASE + 0x020)
++#define I2SRSLVON __REG(I2S_BASE + 0x024)
++#define I2SFRFCLR __REG(I2S_BASE + 0x028)
++#define I2SRMS __REG(I2S_BASE + 0x02C)
++#define I2SRMCON __REG(I2S_BASE + 0x030)
++#define I2SRMSTP __REG(I2S_BASE + 0x034)
++#define I2SRDMA1 __REG(I2S_BASE + 0x038)
++#define I2SCOMMON __REG(I2S_BASE + 0x044)
++#define I2STST __REG(I2S_BASE + 0x048)
++#define I2SRST __REG(I2S_BASE + 0x04C)
++#define I2SINT __REG(I2S_BASE + 0x050)
++#define I2SINTMSK __REG(I2S_BASE + 0x054)
++#define I2STDAT __REG(I2S_BASE + 0x1000)
++#define I2SRDAT __REG(I2S_BASE + 0x2000)
++#define I2STDAT_ADR (I2S_BASE + 0x1000)
++#define I2SRDAT_ADR (I2S_BASE + 0x2000)
++
++#endif /* __TMPA910_REGS__ */
+diff --git a/arch/arm/mach-tmpa910/include/mach/ts.h b/arch/arm/mach-tmpa910/include/mach/ts.h
+new file mode 100644
+index 0000000..e5d5676
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/ts.h
+@@ -0,0 +1,61 @@
++/*
++ * Header file for TMPA910 TS Controller
++ *
++ * Data structure and register user interface
++ *
++ * Copyright (C) 2008 bplam GmbH
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __TMPA910_TS_H__
++#define __TMPA910_TS_H__
++
++
++/******/
++/******/
++struct tmpa910_ts_platforminfo {
++ int fuzz;
++#define TMPA910_TS_DEFAULT_FUZZ 4
++
++ int rate;
++#define TMPA910_TS_DEFAULT_RATE 25
++
++ int skip_count;
++#define TMPA910_TS_DEFAULT_SKIP_COUNT 1
++};
++
++/******/
++/******/
++/*
++ * Controller register
++*/
++
++#define TMPA910_TS_CR0_TSI7 (1<<7) // TSI7 R/W 0y0 pull-down resistor(refer to Explanation)
++#define TMPA910_TS_CR0_INGE (1<<6) // INGE R/W 0y0 Input gate control of Port PD6, PD7
++#define TMPA910_TS_CR0_PTST (1<<5) // PTST R 0y0 Detection condition
++#define TMPA910_TS_CR0_TWIEN (1<<4) // TWIEN R/W 0y0 INTA interrupt control
++#define TMPA910_TS_CR0_PYEN (1<<3) // PYEN R/W 0y0 SPY
++#define TMPA910_TS_CR0_PXEN (1<<2) // PXEN R/W 0y0 SPX
++#define TMPA910_TS_CR0_MYEN (1<<1) // MYEN R/W 0y0 SMY
++#define TMPA910_TS_CR0_MXEN (1<<0) // MXEN[0] MXEN R/W 0y0 SMX
++
++
++struct tmpa910_ts
++{
++ uint32_t tsicr0; // 0x01f0 tsi control register0
++ uint32_t tsicr1; // 0x01f4 tsi control register1
++};
++
++#endif /* __TMPA910_TS_H__ */
+diff --git a/arch/arm/mach-tmpa910/include/mach/uncompress.h b/arch/arm/mach-tmpa910/include/mach/uncompress.h
+new file mode 100644
+index 0000000..e204732
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/uncompress.h
+@@ -0,0 +1,72 @@
++/*
++ * linux/include/asm-arm/arch-tmpa910/uncompress.h
++ *
++ * Copyright (C) 2004 Metrowerks Corp.
++ *
++ * Based on linux/include/asm-arm/arch-mx1ads/uncompress.h, which is:
++ * Copyright (C) 1999 ARM Limited
++ * Copyright (C) Shane Nay (shane at minirl.com)
++ *
++ * 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
++ */
++
++
++static void flush(void)
++{
++
++}
++
++#define _in32(__ofs) ( * ( (volatile unsigned long *) (__ofs) ) )
++#define _out32(__ofs,__val) { (* ( (volatile unsigned long *) (__ofs)) ) = __val; }
++
++
++#define _UART0DR 0x000
++#define _UART0RSR 0x004
++#define _UART0ECR 0x004
++#define _UART0FR 0x018
++#define _UART0ILPR 0x020
++#define _UART0IBRD 0x024
++#define _UART0FBRD 0x028
++#define _UART0LCR_H 0x02C
++#define _UART0CR 0x030
++#define _UART0IFLS 0x034
++#define _UART0IMSC 0x038
++#define _UART0RIS 0x03C
++#define _UART0MIS 0x040
++#define _UART0ICR 0x044
++#define _UART0DMACR 0x048
++
++#define __reg(x) (*((volatile u32 *)(x)))
++#define UART0FR __reg(0xf2000000+_UART0FR)
++#define UART0DR __reg(0xf2000000+_UART0DR)
++
++#define UART_FR_TXFE (1 << 7)
++
++static void putc(int c)
++{
++ while ((UART0FR & UART_FR_TXFE) == 0);
++ UART0DR = (unsigned long)(c & 0xff);
++}
++
++static void puthex(unsigned long x)
++{
++// _out32(0xf08013FC, x);
++}
++
++/*
++ * nothing to setup and wdog currently not used
++ */
++#define arch_decomp_setup()
++#define arch_decomp_wdog()
+diff --git a/arch/arm/mach-tmpa910/include/mach/vmalloc.h b/arch/arm/mach-tmpa910/include/mach/vmalloc.h
+new file mode 100644
+index 0000000..de81a90
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/include/mach/vmalloc.h
+@@ -0,0 +1,22 @@
++/*
++ * linux/include/asm-arm/arch-topas910/vmalloc.h
++ *
++ * Copyright (C) 2000 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, 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
++ */
++//#define VMALLOC_OFFSET (8*1024*1024)
++//#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
++#define VMALLOC_END (PAGE_OFFSET + 0x20000000)
+diff --git a/arch/arm/mach-tmpa910/irq.c b/arch/arm/mach-tmpa910/irq.c
+new file mode 100644
+index 0000000..b88348a
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/irq.c
+@@ -0,0 +1,127 @@
++/*
++ * arch/arm/mach-tmpa910/irq.c
++ *
++ * Copyright (C) 2008 bplan GmbH
++ * Copyright (C) 2009 Florian Boor <florian.boor at kernelconcepts.de>
++ *
++ * Based on mach-mx1ads/irq.c, which is:
++ * Copyright (C) 1999 ARM Limited
++ * Copyright (C) 2002 Shane Nay (shane at minirl.com)
++ * 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
++ *
++ * TMPA910 main interrupt handling
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++
++#include <asm/irq.h>
++#include <asm/io.h>
++
++#include <asm/mach/irq.h>
++#include <mach/gpio.h>
++#include <mach/tmpa910_regs.h>
++
++
++struct hw_ictl
++{
++ uint32_t vicirqstatus; // 0x0000
++ uint32_t vicfiqstatus; // 0x0004
++ uint32_t vicrawintr; // 0x0008
++ uint32_t vicintselect; // 0x000c
++ uint32_t vicintenable; // 0x0010
++ uint32_t vicintenclear; // 0x0014
++ uint32_t vicsoftint; // 0x0018
++ uint32_t vicsoftintclear; // 0x001c
++ uint32_t vicprotection; // 0x0020
++ uint32_t vicswprioritymask; // 0x0024
++ uint32_t rsd[54]; // 0x0028 - 0x00fC
++ uint32_t vicvectaddr[32]; // 0x0100 - 0x017c
++ uint32_t rsd2[32]; // 0x0180 - 0x01fc
++ uint32_t vicvectpriority[32]; // 0x0200 - 0x027c
++ uint32_t rsd3[32 + 0xc00/4]; // 0x0280 - 0x0dfc
++ uint32_t vicaddress; // 0x0f00
++};
++
++
++static void tmpa910_ena_irq(unsigned int irq) {
++
++ volatile struct hw_ictl *hw_ictl = (volatile struct hw_ictl *) INTR_BASE;
++
++ hw_ictl->vicintenable = 1 << irq;
++}
++
++
++static void tmpa910_dis_irq(unsigned int irq) {
++
++ volatile struct hw_ictl *hw_ictl = (volatile struct hw_ictl *) INTR_BASE;
++
++ hw_ictl->vicintenclear = 1 << irq;
++}
++
++
++static void tmpa910_ack_irq(unsigned int irq) {
++
++ volatile struct hw_ictl *hw_ictl = (volatile struct hw_ictl *) INTR_BASE;
++
++ hw_ictl->vicintenclear = 1 << irq;
++ hw_ictl->vicaddress = 0x12345678;
++}
++
++
++static void tmpa910_end_irq(unsigned int irq) {
++
++ volatile struct hw_ictl *hw_ictl = (volatile struct hw_ictl *) INTR_BASE;
++
++ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
++ hw_ictl->vicintenable = 1 << irq;
++ }
++}
++
++
++static struct irq_chip tmpa910_chip = {
++ .typename = "tmpa910",
++
++ .ack = tmpa910_ack_irq,
++ .end = tmpa910_end_irq,
++
++ .mask = tmpa910_dis_irq,
++ .unmask = tmpa910_ena_irq,
++};
++
++
++void __init tmpa910_init_irq(void)
++{
++ volatile struct hw_ictl *hw_ictl = (volatile struct hw_ictl *) INTR_BASE;
++ int i;
++
++ /* Every interrupt to the IRQ execpetion */
++ hw_ictl->vicintselect = 0;
++
++ /* make sure every pri unmasked */
++ hw_ictl->vicswprioritymask = 0xffffffff;
++
++ /* this help to obtain the interrupt vector in the service call */
++ for(i=0; i < 32; i++)
++ hw_ictl->vicvectaddr[i] = i;
++
++ for (i = 0; i < TMPA910_NUM_IRQS; i++) {
++ set_irq_chip(i, &tmpa910_chip);
++ set_irq_handler(i, handle_level_irq);
++ set_irq_flags(i, IRQF_VALID );
++ }
++}
++
+diff --git a/arch/arm/mach-tmpa910/led-topas910.c b/arch/arm/mach-tmpa910/led-topas910.c
+new file mode 100644
+index 0000000..239e8df
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/led-topas910.c
+@@ -0,0 +1,194 @@
++/*
++ * arch/arm/mach-tmpa910/led-topas910.c
++ *
++ * Copyright (C) 2009 Florian Boor <florian.boor at kernelconcepts.de>
++ *
++ * 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
++ *
++ * Toshiba Topas 910, LED driver, mainly for GPIO testing
++ *
++ */
++
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++
++#include <asm/system.h>
++#include <mach/hardware.h>
++
++#include <mach/gpio.h>
++
++#include <asm/mach/arch.h>
++#include <mach/hardware.h>
++#include <mach/tmpa910_regs.h>
++
++#include "topas910.h"
++
++#define GPIO_LED_SEG_A 8
++#define GPIO_LED_SEG_B 9
++#define GPIO_LED_SEG_C 10
++#define GPIO_LED_SEG_D 11
++#define GPIO_LED_SEG_E 12
++#define GPIO_LED_SEG_F 13
++#define GPIO_LED_SEG_G 14
++#define GPIO_LED_SEG_DP 15
++
++/* Pattern for digits from 0 to 9, "L.", clear, all on */
++static const unsigned char pattern[] = {0x3F, 0x06/*1*/, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0xB8, 0x00, 0xFF};
++static unsigned int num_pattern = ARRAY_SIZE(pattern);
++static int saved_state;
++
++
++static void segments_set(int value)
++{
++ int i;
++
++ if (value >= num_pattern)
++ return;
++
++ if (value < 0)
++ return;
++
++ for (i=0; i<8; i++)
++ gpio_set_value(GPIO_LED_SEG_A + i, (pattern[value] & (1 << i)) ? 0 : 1);
++}
++
++static int segments_get(void)
++{
++ int i, p = 0;
++
++ for (i=0; i<8; i++)
++ p |= (gpio_get_value(GPIO_LED_SEG_A + i) ? 0 : (1 << i));
++
++ for (i=0; i<num_pattern; i++)
++ if (p == pattern[i])
++ return i;
++
++ return -1;
++}
++
++ssize_t led_segment_show(struct device *pdev, struct device_attribute *attr, char *buf)
++{
++ return snprintf(buf, PAGE_SIZE, "%i\n", segments_get());
++}
++
++
++ssize_t led_segment_store(struct device *pdev, struct device_attribute *attr, const char *buf, size_t count)
++{
++ if (count) {
++ int i = simple_strtol(buf, NULL, 10);
++
++ segments_set(i);
++ }
++ return count;
++}
++
++DEVICE_ATTR(led_segment, 0644, led_segment_show, led_segment_store);
++
++
++static int __init topas_led_probe(struct platform_device *pdev)
++{
++ int ret = 0;
++
++ platform_set_drvdata(pdev, NULL);
++
++ /* Yes we could have this easier, but I need a customer for the GPIO implementation */
++ ret += gpio_request(GPIO_LED_SEG_A, "LED_SEG_A");
++ ret += gpio_request(GPIO_LED_SEG_B, "LED_SEG_B");
++ ret += gpio_request(GPIO_LED_SEG_C, "LED_SEG_C");
++ ret += gpio_request(GPIO_LED_SEG_D, "LED_SEG_D");
++ ret += gpio_request(GPIO_LED_SEG_E, "LED_SEG_E");
++ ret += gpio_request(GPIO_LED_SEG_F, "LED_SEG_F");
++ ret += gpio_request(GPIO_LED_SEG_G, "LED_SEG_G");
++ ret += gpio_request(GPIO_LED_SEG_DP, "LED_SEG_DP");
++
++ if (ret < 0) {
++ printk(KERN_ERR "Topas910 LED: Unable to get GPIO for LEDs %i\n", ret);
++ return -1;
++ }
++
++
++ /* Clear state, bootloader leaves it undefined */
++ segments_set(10);
++
++ ret = device_create_file(&pdev->dev, &dev_attr_led_segment);
++
++ return 0;
++}
++
++static int __devexit topas_led_remove(struct platform_device *pdev)
++{
++ gpio_free(GPIO_LED_SEG_A);
++ gpio_free(GPIO_LED_SEG_B);
++ gpio_free(GPIO_LED_SEG_C);
++ gpio_free(GPIO_LED_SEG_D);
++ gpio_free(GPIO_LED_SEG_E);
++ gpio_free(GPIO_LED_SEG_F);
++ gpio_free(GPIO_LED_SEG_G);
++ gpio_free(GPIO_LED_SEG_DP);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++
++static int topas_led_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ saved_state = segments_get();
++ segments_set(11); /* all led off */
++
++ return 0;
++}
++
++static int topas_led_resume(struct platform_device *pdev)
++{
++ segments_set(saved_state);
++
++ return 0;
++}
++#else
++
++#define topas_led_suspend NULL
++#define topas_led_resume NULL
++
++#endif
++
++static struct platform_driver topas_led_driver = {
++ .probe = topas_led_probe,
++ .remove = __devexit_p(topas_led_remove),
++ .suspend = topas_led_suspend,
++ .resume = topas_led_resume,
++ .driver = {
++ .name = "led-topas",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init topas_led_init(void)
++{
++ return platform_driver_register(&topas_led_driver);
++}
++
++static void __exit topas_led_exit(void)
++{
++ platform_driver_unregister(&topas_led_driver);
++}
++
++module_init(topas_led_init);
++module_exit(topas_led_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Florian Boor <florian.boor at kernelconcepts.de>");
++MODULE_DESCRIPTION("LED driver for TOPAS 910");
+diff --git a/arch/arm/mach-tmpa910/time.c b/arch/arm/mach-tmpa910/time.c
+new file mode 100644
+index 0000000..e0b1927
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/time.c
+@@ -0,0 +1,285 @@
++/*
++ * arch/arm/mach-tmpa910/time.c
++ *
++ * Copyright (C) 2000-2001 Deep Blue Solutions
++ * Copyright (C) 2002 Shane Nay (shane at minirl.com)
++ * Copyright (C) 2006 Jochen Karrer (jk06 at jkarrer.de)
++ * Copyright (C) 2008 bplan GmbH
++ *
++ * 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/autoconf.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/time.h>
++
++#include <linux/clocksource.h>
++#include <linux/clockchips.h>
++
++#include <linux/tick.h>
++
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <asm/leds.h>
++#include <asm/irq.h>
++#include <asm/mach/time.h>
++
++#include <mach/tmpa910_regs.h>
++
++/*********/
++
++struct hw_timer {
++ uint32_t TimerLoad; // 0x0000
++ uint32_t TimerValue; // 0x0004
++ uint32_t TimerControl; // 0x0008
++ uint32_t TimerIntClr; // 0x000C
++ uint32_t TimerRIS; // 0x0010
++ uint32_t TimerMIS; // 0x0014
++ uint32_t TimerBGLoad; // 0x0018
++ uint32_t TimerMode; // 0x001C
++ uint32_t Rsvd[32]; // 0x0020 -> 0x9C
++ uint32_t TimerCompare1; // 0x00A0 Timer0 Compare value
++ uint32_t TimerCmpIntClr1; // 0x00C0 Timer0 Compare Interrupt clear
++ uint32_t TimerCmpEn; // 0x00E0 Timer0 Compare Enable
++ uint32_t TimerCmpRIS; // 0x00E4 Timer0 Compare raw interrupt status
++ uint32_t TimerCmpMIS; // 0x00E8 Timer0 Compare masked int status
++ uint32_t TimerBGCmp; // 0x00EC Background compare value for Timer0
++};
++
++#define TIMxEN (1<<7)
++#define TIMxMOD (1<<6)
++#define TIMxINTE (1<<5)
++#define TIMxSIZE_16B (1<<1)
++#define TIMxOSCTL_NORESTART (1<<0)
++
++#define TIMxPRS_1 (0x0<<2)
++#define TIMxPRS_16 (0x1<<2)
++#define TIMxPRS_256 (0x2<<2)
++
++/*
++ * TimerControl
++ * [7] TIM0EN R/W 0y0 Timer 0 enable bit
++ * 0: Disable
++ * 1: Enable
++ * [6] TIM0MOD R/W 0y0 Timer 0 mode setting
++ * 0: Free-running mode
++ * 1: Periodic timer mode
++ * [5] TIM0INTE R/W 0y0 Timer 0 interrupt control
++ * 0: Disable inerrupts
++ * 1: Enable interrupts
++ * - -
++ * [4] Undefined Read undefined. Write as zero.
++ * [3:2] TIM0PRS R/W 0y00 Timer 0 prescaler setting
++ * 00: No division
++ * 01: Divide by 16
++ * 10: Divide by 256
++ * 11: Setting prohibited
++ * [1] TIM0SIZE R/W 0y0 8-bit/16-bit counter select for Timer 0
++ * 0: 8-bit counter
++ * 1: 16-bit counter
++ * [0] TIM0OSCTL R/W 0y0 One-shot/wrapping mode select for Timer 0
++ * 0: Wrapping mode
++ * 1: One-shot mode
++*/
++
++#define GPT_COUNT 6
++
++/* system timer reference clock, in Hz */
++#define REFCLK (32768)
++
++/* timer counter value, to get an interrupt every HZ */
++#define TIMER_RELOAD (REFCLK/HZ)
++
++/* conversion from timer counter values to microseconds */
++#define TICKS2USECS(x) ((x) * 1000000 / REFCLK)
++
++
++/*********/
++/*********/
++static irqreturn_t topas910_timer_interrupt(int irq, void *dev_id)
++{
++ volatile struct hw_timer *hw_timer =
++ (volatile struct hw_timer *)TMPA910_TIMER0;
++
++ struct clock_event_device *c = dev_id;
++
++ //NPRINTK("-> irq=%d, c =%p, TimerMIS=0x%x, TimerRIS=0x%x, TimerControl=0x%x\n",
++ // irq, c, hw_timer->TimerMIS, hw_timer->TimerRIS, hw_timer->TimerControl);
++
++ c->event_handler(c);
++
++ /* clear the interrupt */
++ if (hw_timer->TimerMIS)
++ hw_timer->TimerIntClr = -1;
++
++ return IRQ_HANDLED;
++}
++
++/*********/
++/*********/
++static void
++tmpa910_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
++{
++ unsigned long irqflags;
++ uint32_t TimerControl;
++ volatile struct hw_timer *hw_timer =
++ (volatile struct hw_timer *)TMPA910_TIMER0;
++
++ TimerControl = 0;
++
++ raw_local_irq_save(irqflags);
++
++
++ switch (mode) {
++
++ case CLOCK_EVT_MODE_UNUSED:
++ case CLOCK_EVT_MODE_SHUTDOWN:
++ /* initializing, released, or preparing for suspend */
++ break;
++
++ case CLOCK_EVT_MODE_RESUME:
++ break;
++
++ case CLOCK_EVT_MODE_ONESHOT:
++ TimerControl |=TIMxOSCTL_NORESTART;
++
++ case CLOCK_EVT_MODE_PERIODIC:
++
++
++ hw_timer->TimerLoad = TIMER_RELOAD;
++ hw_timer->TimerValue = 0;
++
++ // Default to 16 bits timers
++ TimerControl |= TIMxEN | TIMxSIZE_16B;
++
++ TimerControl |= TIMxMOD;
++ TimerControl |= TIMxINTE;
++
++ break;
++ }
++
++ hw_timer->TimerControl = TimerControl;
++
++ raw_local_irq_restore(irqflags);
++
++}
++
++/*********/
++static int
++tmpa910_set_next_event(unsigned long delta, struct clock_event_device *dev)
++{
++ volatile struct hw_timer *hw_timer =
++ (volatile struct hw_timer *)TMPA910_TIMER0;
++ unsigned long flags;
++
++ uint32_t TimerControl;
++
++ //NPRINTK("-> delta=%ld. dev=%p\n", delta, dev);
++
++ raw_local_irq_save(flags);
++
++ hw_timer->TimerLoad = delta;
++ hw_timer->TimerValue = 0;
++
++ // Default to 16 bits timers
++ TimerControl = TIMxEN | TIMxSIZE_16B;
++
++ TimerControl |= TIMxMOD;
++ TimerControl |= TIMxINTE;
++
++ hw_timer->TimerControl = TimerControl;
++
++ raw_local_irq_restore(flags);
++
++ //NPRINTK("-> hTimerControl=%pm val=0x%x\n", hw_timer->TimerControl, hw_timer->TimerValue);
++
++ return (signed)0;
++}
++
++/*********/
++/*********/
++static cycle_t tmpa910_readcycle(void)
++{
++ volatile struct hw_timer *hw_timer =
++ (volatile struct hw_timer *)TMPA910_TIMER0;
++
++ unsigned long ticks = 10;
++
++ ticks = hw_timer->TimerValue;
++
++ //NPRINTK("ticks=%ld\n", ticks);
++
++ return (cycle_t) ticks;
++}
++
++/*********/
++/*********/
++static struct clock_event_device clockevent_tmpa910 = {
++ .name = "tmpa910_timer",
++ .features = 0,
++ .shift = 32,
++ .set_mode = tmpa910_set_mode,
++ .set_next_event = tmpa910_set_next_event,
++ .rating = 200,
++};
++
++static struct irqaction topas910_timer_irq = {
++ .name = "TMPA910/TOPAS910 Timer Tick",
++ .flags = IRQF_DISABLED | IRQF_TIMER,
++ .handler = topas910_timer_interrupt,
++ .dev_id = &clockevent_tmpa910,
++};
++
++static struct clocksource cksrc_tmpa910 = {
++ .name = "tmpa910",
++ .rating = 450,
++ .read = tmpa910_readcycle,
++};
++
++static int tmpa910_clockevent_init(int clock_tick_rate)
++{
++
++ cksrc_tmpa910.mask = CLOCKSOURCE_MASK(32);
++ cksrc_tmpa910.shift = 20;
++ cksrc_tmpa910.mult =
++ clocksource_hz2mult(clock_tick_rate, cksrc_tmpa910.shift);
++
++ clockevent_tmpa910.mult =
++ div_sc(clock_tick_rate, NSEC_PER_SEC, clockevent_tmpa910.shift);
++ clockevent_tmpa910.max_delta_ns =
++ clockevent_delta2ns(0xfffffffe, &clockevent_tmpa910);
++ clockevent_tmpa910.min_delta_ns =
++ clockevent_delta2ns(0xf, &clockevent_tmpa910);
++
++ clockevent_tmpa910.features = CLOCK_EVT_FEAT_PERIODIC;
++
++ clockevent_tmpa910.cpumask = cpumask_of(0);
++
++ clocksource_register(&cksrc_tmpa910);
++ clockevents_register_device(&clockevent_tmpa910);
++
++ return 0;
++}
++
++static void topas910_timer_init(void)
++{
++ volatile struct hw_timer *hw_timer =
++ (volatile struct hw_timer *)TMPA910_TIMER0;
++
++ hw_timer->TimerControl = 0;
++
++ setup_irq(INTR_VECT_TIMER01, &topas910_timer_irq);
++
++ tmpa910_clockevent_init(REFCLK);
++}
++
++struct sys_timer topas910_timer = {
++ .init = topas910_timer_init,
++};
++
+diff --git a/arch/arm/mach-tmpa910/tonga.c b/arch/arm/mach-tmpa910/tonga.c
+new file mode 100644
+index 0000000..ebfd70e
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/tonga.c
+@@ -0,0 +1,590 @@
++/*
++ * arch/arm/mach-tmpa910/tonga.c
++ *
++ * Copyright (C) 2010 Florian Boor <florian.boor at kernelconcepts.de>
++ * Based on tonga.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 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
++ *
++ * Glyn ARM9 / Tonga machine definition, multi purpose Toshiba TMPA900 based SoM
++ *
++ */
++
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/mmc_spi.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++
++#include <asm/system.h>
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++
++#include <asm/mach/map.h>
++#include <asm/mach-types.h>
++
++#include <video/tmpa910_fb.h>
++#include <mach/gpio.h>
++
++#include <asm/mach/arch.h>
++#include <mach/hardware.h>
++#include <mach/ts.h>
++#include <mach/tmpa910_regs.h>
++#include <asm/serial.h>
++#include <asm/dma.h>
++
++
++#ifdef CONFIG_SPI_TMPA910
++#include <linux/spi/spi.h>
++#endif
++
++#include "topas910.h"
++
++#define CONFIG_SPI_CHANNEL0
++
++
++/* I/O Mapping related, might want to be moved to a CPU specific file */
++
++static struct map_desc tmpa900_io_desc[] __initdata = {
++ {
++ .virtual = TMPA910_IO_VIRT_BASE,
++ .pfn = __phys_to_pfn(TMPA910_IO_PHYS_BASE),
++ .length = TMPA910_IO_SIZE,
++ .type = MT_DEVICE,
++ }
++};
++
++
++void __init tonga_map_io(void)
++{
++ iotable_init(tmpa900_io_desc, ARRAY_SIZE(tmpa900_io_desc));
++}
++
++
++static void dummy_release(struct device *dev)
++{
++ /* normally not freed */
++}
++
++static u64 topas910_dmamask = 0xffffffffUL;
++
++/* Ethernet */
++
++static struct resource dm9000_resources[] = {
++ [0] = {
++ .start = 0x60000002,
++ .end = 0x60000003,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 0x60001002,
++ .end = 0x60001003,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = TOPAS910_INT_DM9000,
++ .end = TOPAS910_INT_DM9000,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
++ },
++};
++
++
++static struct platform_device topas910_dm9000_device = {
++ .name = "dm9000",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(dm9000_resources),
++ .resource = dm9000_resources,
++ .dev = {
++ .release = dummy_release,
++ .coherent_dma_mask = 0xffffffff,
++ },
++};
++
++
++/*
++ * Serial UART
++ */
++
++static struct resource tmpa910_resource_uart0[] = {
++ {
++ .start = 0xf2000000,
++ .end = 0xf2000000 + 0x100,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = 10,
++ .end = 10,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++
++struct platform_device tmpa910_device_uart0 = {
++ .name = "tmpa910-uart",
++ .id = 0,
++ .resource = tmpa910_resource_uart0,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_uart0),
++};
++
++
++/*
++ * DMA
++*/
++static struct resource tmpa910_resource_dmac[] = {
++ {
++ .start = DMAC_BASE,
++ .end = DMAC_BASE+0x200,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_DMA_END,
++ .end = INTR_VECT_DMA_END,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }, {
++ .start = INTR_VECT_DMA_ERROR,
++ .end = INTR_VECT_DMA_ERROR,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++struct platform_device tmpa910_device_dmac = {
++ .name = "tmpa910-dmac",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL
++ },
++ .resource = tmpa910_resource_dmac,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_dmac),
++};
++
++
++static struct resource tmpa910_resource_i2c[] = {
++ {
++ .start = I2C0_BASE,
++ .end = I2C0_BASE+0x1F,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = I2C1_BASE,
++ .end = I2C1_BASE+0x1F,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_I2C_CH0,
++ .end = INTR_VECT_I2C_CH0,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }, {
++ .start = INTR_VECT_I2C_CH1,
++ .end = INTR_VECT_I2C_CH1,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++struct platform_device tmpa910_device_i2c = {
++ .name = "tmpa910-i2c",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = tmpa910_resource_i2c,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_i2c),
++};
++
++
++#ifdef CONFIG_SPI_CHANNEL0
++static struct resource tmpa910_resource_spi0[] = {
++ {
++ .start = 0xF2002000,
++ .end = 0xF2002000+0x27,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_SSP_CH0,
++ .end = INTR_VECT_SSP_CH0,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++#endif
++
++#ifdef CONFIG_SPI_CHANNEL1
++static struct resource tmpa910_resource_spi1[] = {
++ {
++ .start = 0xF2003000,
++ .end = 0xF2003000+0x27,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_SSP_CH1,
++ .end = INTR_VECT_SSP_CH1,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++#endif
++
++#ifdef CONFIG_SPI_CHANNEL0
++struct platform_device tmpa910_device_spi0 = {
++ .name = "tmpa910-spi",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL,
++ },
++ .resource = tmpa910_resource_spi0,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_spi0),
++};
++#endif
++
++#ifdef CONFIG_SPI_CHANNEL1
++struct platform_device tmpa910_device_spi1 = {
++ .name = "tmpa910-spi",
++ .id = 1,
++ .dev = {
++ .platform_data = NULL,
++ },
++ .resource = tmpa910_resource_spi1,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_spi1),
++};
++#endif
++
++
++
++/*
++ * Touchscreen
++ */
++
++static struct resource tmpa910_resource_ts[] = {
++ {
++ .start = TS_BASE,
++ .end = TS_BASE + 0x40,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = ADC_BASE,
++ .end = ADC_BASE + 0x100,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_GPIOD,
++ .end = INTR_VECT_GPIOD,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }, {
++ .start = INTR_VECT_ADC,
++ .end = INTR_VECT_ADC,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++struct platform_device tmpa910_device_ts = {
++ .name = "tmpa910_ts",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL
++ },
++ .resource = tmpa910_resource_ts,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_ts),
++};
++
++
++/* LCD controller device */
++
++static struct resource tmpa910_resource_lcdc[] = {
++ {
++ .start = LCDC_BASE,
++ .end = LCDC_BASE + 0x400,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = FB_OFFSET,
++ .end = FB_OFFSET+FB_SIZE,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_LCDC,
++ .end = INTR_VECT_LCDC,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++
++static struct tmpa910_lcdc_platforminfo topas910_v1_lcdc_platforminfo;
++
++
++struct platform_device tmpa910_device_lcdc= {
++ .name = "tmpa910_lcdc",
++ .id = 0,
++ .resource = tmpa910_resource_lcdc,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_lcdc),
++};
++
++
++
++/*
++ * NAND Flash Controller
++ */
++
++#ifdef CONFIG_MTD_NAND_TMPA910
++static struct resource tmpa910_nand_resources[] = {
++ [0] = {
++ .start = NANDF_BASE ,
++ .end = NANDF_BASE + 0x200,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device tmpa910_nand_device = {
++ .name = "tmpa910-nand",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa910_nand_resources),
++ .resource = tmpa910_nand_resources,
++};
++
++#endif
++
++
++static struct platform_device tmpa910_i2s_device = {
++ .name = "WM8976-I2S",
++ .id = -1,
++};
++
++
++#ifdef CONFIG_MMC_SPI
++static struct spi_board_info spi_board_info[] =
++{
++{
++ .modalias = "mmc_spi",
++ .platform_data = NULL,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 1000000,
++ .bus_num = 0,
++
++}
++};
++#elif defined(CONFIG_SPI_SPIDEV)
++static struct spi_board_info spi_board_info[] = {
++{
++ .modalias = "spidev",
++ .platform_data = NULL,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 0,
++},
++{
++ .modalias = "spidev",
++ .platform_data = NULL,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 1,
++}
++};
++
++#endif
++
++
++#define RTC_BASE 0xF0030000
++
++static struct resource tmpa910_resource_rtc[] = {
++ {
++ .start = RTC_BASE,
++ .end = RTC_BASE + 0x3ff,
++ .flags = IORESOURCE_MEM
++ },{
++ .start = INTR_VECT_RTC,
++ .end = INTR_VECT_RTC,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH
++ }
++};
++
++static struct platform_device tmpa910_device_rtc = {
++ .name = "tmpa910_rtc",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_rtc),
++ .resource = tmpa910_resource_rtc
++ }
++;
++
++
++#ifdef CONFIG_USB_OHCI_HCD_TMPA900
++static struct resource tmpa900_ohci_resources[] = {
++ [0] = {
++ .start = 0xf4500000,
++ .end = 0xf4500000 + 0x100,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 0xF8008000,
++ .end = 0xF8009fff,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = 27,
++ .end = 27,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ },
++};
++
++static struct platform_device tmpa900_ohci_device = {
++ .name = "tmpa900-usb",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa900_ohci_resources),
++ .resource = tmpa900_ohci_resources,
++ .dev = {
++ .release = dummy_release, // not needed
++ .coherent_dma_mask = 0xffffffff,
++ },
++};
++
++#endif /* CONFIG_USB_OHCI_HCD_TMPA900 */
++
++
++#ifdef CONFIG_USB_GADGET_TMPA910
++/* USB Device Controller */
++static struct resource tmpa910_udc_resource[] = {
++ [0] = {
++ .start = 0xf4400000,
++ .end = 0xf44003ff,
++ .flags = IORESOURCE_MEM
++ },
++ [1] = {
++ .start = USB_INT,
++ .end = USB_INT,
++ .flags = IORESOURCE_IRQ
++ }
++};
++
++static struct platform_device tmpa910_udc_device = {
++ .name = "tmpa910-usb",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa910_udc_resource),
++ .resource = tmpa910_udc_resource,
++ .dev = {
++ .platform_data = NULL,
++ }
++};
++#endif
++
++
++static struct platform_device *devices[] __initdata = {
++ &tmpa910_device_dmac,
++ &tmpa910_device_ts,
++ &topas910_dm9000_device,
++ &tmpa910_device_uart0,
++#ifdef CONFIG_MTD_NAND_TMPA910
++ &tmpa910_nand_device,
++#endif
++ &tmpa910_device_lcdc,
++ &tmpa910_device_i2c,
++#ifdef CONFIG_USB_GADGET_TMPA910
++ &tmpa910_udc_device,
++#endif
++#ifdef CONFIG_USB_OHCI_HCD_TMPA900
++ &tmpa900_ohci_device,
++#endif
++ &tmpa910_i2s_device,
++#ifdef CONFIG_SPI_CHANNEL0
++ &tmpa910_device_spi0,
++#endif
++#ifdef CONFIG_SPI_CHANNEL1
++ &tmpa910_device_spi1,
++#endif
++ &tmpa910_device_rtc
++};
++
++
++static void __init setup_lcdc_device(void)
++{
++ uint32_t *LCDReg;
++ int width = 320;
++ int height = 240;
++
++ topas910_v1_lcdc_platforminfo.width = width;
++ topas910_v1_lcdc_platforminfo.height = height;
++ topas910_v1_lcdc_platforminfo.depth = 32;
++ topas910_v1_lcdc_platforminfo.pitch = width*4;
++
++ LCDReg = topas910_v1_lcdc_platforminfo.LCDReg;
++ LCDReg[LCDREG_TIMING0_H] = ( ((height/16)-1) << 2) // pixel per line
++ | ( (8-1) << 8 ) // tHSW. Horizontal sync pulse
++ | ( (8-1) << 16 ) // tHFP, Horizontal front porch
++ | ( (8-1) << 24 ); // tHBP, Horizontal back porch
++
++ LCDReg[LCDREG_TIMING1_V] = (2 << 24) // tVBP
++ | (2 << 16) // tVFP
++ | ((2-1) << 10) // tVSP
++ | (width-1);
++
++ LCDReg[LCDREG_TIMING2_CLK] = ((width-1)<<16) | 0x0000e | 1<<13 | 0<<12 | 0<<11;
++ LCDReg[LCDREG_TIMING3_LEC] = 0;
++ LCDReg[LCDREG_LCDCONTROL] = (0x5<<1) | (1<<5) | (1<<11);
++ tmpa910_device_lcdc.dev.platform_data = &topas910_v1_lcdc_platforminfo;
++}
++
++
++void __init tonga_init_irq(void) {
++ tmpa910_init_irq();
++}
++
++
++/* tonga device initialisation */
++
++static void __init tonga_init(void)
++{
++
++ /* Memory controller - for DM9000 */
++ SMC_SET_CYCLES_3 = 0x0004AFAA;
++ SMC_SET_OPMODE_3 = 0x00000002;
++ SMC_DIRECT_CMD_3 = 0x00C00000;
++
++ /* DMA setup */
++ platform_bus.coherent_dma_mask = 0xffffffff;
++ platform_bus.dma_mask=&topas910_dmamask;
++
++ /* Pin configuration */
++ TMPA910_CFG_PORT_GPIO(PORTA); /* Keypad */
++ TMPA910_CFG_PORT_GPIO(PORTB); /* 7 segment LED */
++ TMPA910_CFG_PORT_GPIO(PORTG); /* SDIO0, for SPI MMC */
++ TMPA910_CFG_PORT_GPIO(PORTP); /* GPIO routed to CM605 left */
++ TMPA910_PORT_T_FR1 = 0x00F0; /* Enable USB function pin */
++
++ /* Configure LCD interface */
++ setup_lcdc_device();
++
++ /* NAND Controller */
++ NDFMCR0 = 0x00000010; // NDCE0n pin = 0, ECC-disable
++ NDFMCR1 = 0x00000000; // ECC = Hamming
++ NDFMCR2 = 0x00003343; // NDWEn L = 3clks,H =3clks,
++ // NDREn L = 4clks,H = 3clks
++ NDFINTC = 0x00000000; // ALL Interrupt Disable
++
++ /* Add devices */
++ platform_add_devices(devices, ARRAY_SIZE(devices));
++
++#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_MMC_SPI)
++ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
++#endif
++}
++
++
++MACHINE_START(TONGA, "Tonga")
++ /* Maintainer: Florian Boor <florian.boor at kernelconcepts.de> */
++ .phys_io = TMPA910_IO_PHYS_BASE,
++ .boot_params = 0,
++ .io_pg_offst = (io_p2v(TMPA910_IO_PHYS_BASE) >> 18) & 0xfffc,
++ .map_io = tonga_map_io,
++ .init_irq = tonga_init_irq,
++ .timer = &topas910_timer,
++ .init_machine = tonga_init,
++MACHINE_END
++
+diff --git a/arch/arm/mach-tmpa910/topas910.c b/arch/arm/mach-tmpa910/topas910.c
+new file mode 100644
+index 0000000..7204b95
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/topas910.c
+@@ -0,0 +1,702 @@
++/*
++ * arch/arm/mach-tmpa910/topas910.c -- Topas 910 machine
++ *
++ * Copyright (C) 2008 bplan GmbH. All rights reserved.
++ * Copyright (C) 2009 Florian Boor <florian.boor at kernelconcepts.de>
++ *
++ * 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
++ *
++ * Toshiba Topas 910 machine, reference design for the TMPA910CRAXBG SoC
++ *
++ * TODO: MMC, ADC, power manager
++ * TODO: separate SoC and board code
++ */
++
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/mmc_spi.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++
++#include <asm/system.h>
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++
++#include <asm/mach/map.h>
++#include <asm/mach-types.h>
++
++#include <video/tmpa910_fb.h>
++#include <mach/gpio.h>
++
++#include <asm/mach/arch.h>
++#include <mach/hardware.h>
++#include <mach/ts.h>
++#include <mach/tmpa910_regs.h>
++#include <asm/serial.h>
++#include <asm/dma.h>
++
++#if defined(CONFIG_USB_ISP1362_HCD)
++#include <linux/usb/isp1362.h>
++#endif
++
++#ifdef CONFIG_SPI_TMPA910
++#include <linux/spi/spi.h>
++#endif
++
++#ifdef CONFIG_SPI_AT25
++#include <linux/spi/eeprom.h>
++#endif
++
++#include "topas910.h"
++
++#define CONFIG_SPI_CHANNEL0
++
++
++/* I/O Mapping related, might want to be moved to a CPU specific file */
++
++static struct map_desc tmpa910_io_desc[] __initdata = {
++ {
++ .virtual = TMPA910_IO_VIRT_BASE,
++ .pfn = __phys_to_pfn(TMPA910_IO_PHYS_BASE),
++ .length = TMPA910_IO_SIZE,
++ .type = MT_DEVICE,
++ }
++};
++
++
++void __init topas910_map_io(void)
++{
++ iotable_init(tmpa910_io_desc, ARRAY_SIZE(tmpa910_io_desc));
++}
++
++
++static void dummy_release(struct device *dev)
++{
++ /* normally not freed */
++}
++
++static u64 topas910_dmamask = 0xffffffffUL;
++
++
++
++/* Ethernet */
++
++static struct resource dm9000_resources[] = {
++ [0] = {
++ .start = 0x60000002,
++ .end = 0x60000003,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 0x60001002,
++ .end = 0x60001003,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = TOPAS910_INT_DM9000,
++ .end = TOPAS910_INT_DM9000,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
++ },
++};
++
++
++static struct platform_device topas910_dm9000_device = {
++ .name = "dm9000",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(dm9000_resources),
++ .resource = dm9000_resources,
++ .dev = {
++ .release = dummy_release,
++ .coherent_dma_mask = 0xffffffff,
++ },
++};
++
++
++/*
++ * Serial UART
++ */
++
++static struct resource tmpa910_resource_uart0[] = {
++ {
++ .start = 0xf2000000,
++ .end = 0xf2000000 + 0x100,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = 10,
++ .end = 10,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++
++struct platform_device tmpa910_device_uart0 = {
++ .name = "tmpa910-uart",
++ .id = 0,
++ .resource = tmpa910_resource_uart0,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_uart0),
++};
++
++
++/*
++ * DMA
++*/
++static struct resource tmpa910_resource_dmac[] = {
++ {
++ .start = DMAC_BASE,
++ .end = DMAC_BASE+0x200,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_DMA_END,
++ .end = INTR_VECT_DMA_END,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }, {
++ .start = INTR_VECT_DMA_ERROR,
++ .end = INTR_VECT_DMA_ERROR,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++struct platform_device tmpa910_device_dmac = {
++ .name = "tmpa910-dmac",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL
++ },
++ .resource = tmpa910_resource_dmac,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_dmac),
++};
++
++
++static struct resource tmpa910_resource_i2c[] = {
++ {
++ .start = I2C0_BASE,
++ .end = I2C0_BASE+0x1F,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = I2C1_BASE,
++ .end = I2C1_BASE+0x1F,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_I2C_CH0,
++ .end = INTR_VECT_I2C_CH0,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }, {
++ .start = INTR_VECT_I2C_CH1,
++ .end = INTR_VECT_I2C_CH1,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++struct platform_device tmpa910_device_i2c = {
++ .name = "tmpa910-i2c",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = tmpa910_resource_i2c,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_i2c),
++};
++
++
++
++
++
++
++#ifdef CONFIG_SPI_CHANNEL0
++static struct resource tmpa910_resource_spi0[] = {
++ {
++ .start = 0xF2002000,
++ .end = 0xF2002000+0x27,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_SSP_CH0,
++ .end = INTR_VECT_SSP_CH0,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++#endif
++
++#ifdef CONFIG_SPI_CHANNEL1
++static struct resource tmpa910_resource_spi1[] = {
++ {
++ .start = 0xF2003000,
++ .end = 0xF2003000+0x27,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_SSP_CH1,
++ .end = INTR_VECT_SSP_CH1,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++#endif
++
++#ifdef CONFIG_SPI_CHANNEL0
++struct platform_device tmpa910_device_spi0 = {
++ .name = "tmpa910-spi",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL,
++ },
++ .resource = tmpa910_resource_spi0,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_spi0),
++};
++#endif
++
++#ifdef CONFIG_SPI_CHANNEL1
++struct platform_device tmpa910_device_spi1 = {
++ .name = "tmpa910-spi",
++ .id = 1,
++ .dev = {
++ .platform_data = NULL,
++ },
++ .resource = tmpa910_resource_spi1,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_spi1),
++};
++#endif
++
++
++
++/*
++ * Touchscreen
++ */
++
++static struct resource tmpa910_resource_ts[] = {
++ {
++ .start = TS_BASE,
++ .end = TS_BASE + 0x40,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = ADC_BASE,
++ .end = ADC_BASE + 0x100,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_GPIOD,
++ .end = INTR_VECT_GPIOD,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }, {
++ .start = INTR_VECT_ADC,
++ .end = INTR_VECT_ADC,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++struct platform_device tmpa910_device_ts = {
++ .name = "tmpa910_ts",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL
++ },
++ .resource = tmpa910_resource_ts,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_ts),
++};
++
++
++/* LCD controller device */
++
++static struct resource tmpa910_resource_lcdc[] = {
++ {
++ .start = LCDC_BASE,
++ .end = LCDC_BASE + 0x400,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = FB_OFFSET,
++ .end = FB_OFFSET+FB_SIZE,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_LCDC,
++ .end = INTR_VECT_LCDC,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++
++static struct tmpa910_lcdc_platforminfo topas910_v1_lcdc_platforminfo;
++
++
++struct platform_device tmpa910_device_lcdc= {
++ .name = "tmpa910_lcdc",
++ .id = 0,
++ .resource = tmpa910_resource_lcdc,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_lcdc),
++};
++
++
++/*
++ * 7 segment LED display
++ */
++
++static struct platform_device topas910_led_device = {
++ .name = "led-topas",
++ .id = -1,
++};
++
++
++/*
++ * Joystick
++ */
++
++static struct gpio_keys_button topas910_buttons[] = {
++ {
++ .code = KEY_LEFT,
++ .gpio = 0,
++ .active_low = 0,
++ .desc = "Joystick left",
++ .type = EV_KEY,
++ .wakeup = 0,
++ },
++ {
++ .code = KEY_DOWN,
++ .gpio = 1,
++ .active_low = 0,
++ .desc = "Joystick down",
++ .type = EV_KEY,
++ .wakeup = 0,
++ },
++ {
++ .code = KEY_UP,
++ .gpio = 2,
++ .active_low = 0,
++ .desc = "Joystick up",
++ .type = EV_KEY,
++ .wakeup = 0,
++ },
++ {
++ .code = KEY_RIGHT,
++ .gpio = 3,
++ .active_low = 0,
++ .desc = "Joystick right",
++ .type = EV_KEY,
++ .wakeup = 0,
++ },
++ {
++ .code = KEY_ENTER,
++ .gpio = 4,
++ .active_low = 0,
++ .desc = "Joystick center",
++ .type = EV_KEY,
++ .wakeup = 1,
++ },
++};
++
++static struct gpio_keys_platform_data topas910_keys_data = {
++ .buttons = topas910_buttons,
++ .nbuttons = ARRAY_SIZE(topas910_buttons),
++};
++
++static struct platform_device topas910_keys_device = {
++ .name = "gpio-keys",
++ .id = -1,
++ .dev = {
++ .platform_data = &topas910_keys_data,
++ },
++};
++
++
++/*
++ * NAND Flash Controller
++ */
++
++#ifdef CONFIG_MTD_NAND_TMPA910
++static struct resource tmpa910_nand_resources[] = {
++ [0] = {
++ .start = NANDF_BASE ,
++ .end = NANDF_BASE + 0xFFF,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device tmpa910_nand_device = {
++ .name = "tmpa910-nand",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa910_nand_resources),
++ .resource = tmpa910_nand_resources,
++};
++
++#endif
++
++
++static struct platform_device tmpa910_i2s_device = {
++ .name = "WM8976-I2S",
++ .id = -1,
++};
++
++
++#ifdef CONFIG_MMC_SPI
++static struct spi_board_info spi_board_info[] =
++{
++{
++ .modalias = "mmc_spi",
++ .platform_data = NULL,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 1000000,
++ .bus_num = 0,
++
++}
++};
++
++#elif defined(CONFIG_SPI_AT25)
++static struct spi_eeprom spi_eeprom_info = {
++ .page_size = 256,
++ .name = "AT25F512",
++ .flags = EE_ADDR3|EE_READONLY
++};
++
++static struct spi_board_info spi_board_info[] = {
++{
++ .modalias = "at25",
++ .platform_data = &spi_eeprom_info,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 0,
++},
++{
++ .modalias = "at25",
++ .platform_data = &spi_eeprom_info,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 1,
++}
++};
++#elif defined(CONFIG_SPI_SPIDEV)
++static struct spi_board_info spi_board_info[] = {
++{
++ .modalias = "spidev",
++ .platform_data = NULL,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 0,
++},
++{
++ .modalias = "spidev",
++ .platform_data = NULL,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 1,
++}
++};
++
++#endif
++
++
++#define RTC_BASE 0xF0030000
++
++static struct resource tmpa910_resource_rtc[] = {
++ {
++ .start = RTC_BASE,
++ .end = RTC_BASE + 0x3ff,
++ .flags = IORESOURCE_MEM
++ },{
++ .start = INTR_VECT_RTC,
++ .end = INTR_VECT_RTC,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH
++ }
++};
++
++static struct platform_device tmpa910_device_rtc = {
++ .name = "tmpa910_rtc",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_rtc),
++ .resource = tmpa910_resource_rtc
++ }
++;
++
++#ifdef CONFIG_USB_GADGET_TMPA910
++/* USB Device Controller */
++static struct resource tmpa910_udc_resource[] = {
++ [0] = {
++ .start = 0xf4400000,
++ .end = 0xf44003ff,
++ .flags = IORESOURCE_MEM
++ },
++ [1] = {
++ .start = USB_INT,
++ .end = USB_INT,
++ .flags = IORESOURCE_IRQ
++ }
++};
++
++static struct platform_device tmpa910_udc_device = {
++ .name = "tmpa910-usb",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa910_udc_resource),
++ .resource = tmpa910_udc_resource,
++ .dev = {
++ .platform_data = NULL,
++ }
++};
++
++#endif
++
++
++static struct platform_device *devices[] __initdata = {
++ &tmpa910_device_dmac,
++ &tmpa910_device_ts,
++ &topas910_led_device,
++ &topas910_dm9000_device,
++ &tmpa910_device_uart0,
++ &topas910_keys_device,
++ &tmpa910_device_lcdc,
++ &tmpa910_device_i2c,
++#ifdef CONFIG_USB_GADGET_TMPA910
++ &tmpa910_udc_device,
++#endif
++#ifdef CONFIG_MTD_NAND_TMPA910
++ &tmpa910_nand_device,
++#endif
++ &tmpa910_i2s_device,
++#ifdef CONFIG_SPI_CHANNEL0
++ &tmpa910_device_spi0,
++#endif
++#ifdef CONFIG_SPI_CHANNEL1
++ &tmpa910_device_spi1,
++#endif
++
++ &tmpa910_device_rtc
++};
++
++
++static void __init _setup_lcdc_device(void)
++{
++ uint32_t *LCDReg;
++
++ LCDReg = topas910_v1_lcdc_platforminfo.LCDReg;
++#ifdef CONFIG_DISPLAY_GLYN_640_480
++ int width = 640;
++ int height = 480;
++
++ topas910_v1_lcdc_platforminfo.width = width;
++ topas910_v1_lcdc_platforminfo.height = height;
++ topas910_v1_lcdc_platforminfo.depth = 32;
++ topas910_v1_lcdc_platforminfo.pitch = width * 4; /* line length */
++ LCDReg[0] =
++ ( ((width/16)-1) << 2) // pixel per line
++ | ( (48) << 8 ) // tHSW. Horizontal sync pulse
++ | ( (53) << 16 ) // tHFP, Horizontal front porch
++ | ( (155) << 24 ) // tHBP, Horizontal back porch
++ ;
++
++ LCDReg[1] =
++ (35 << 24) // tVBP
++ | (8 << 16) // tVFP
++ | (2 << 10) // tVSP
++ | (height-1);
++
++ LCDReg[2] = ((width-1)<<16) | (4 & 0x1f) | (((16-2)>>5) << 27) | 1<<13 | 1<<12 | 0<<11;
++ LCDReg[3] = 0;
++ LCDReg[4] = (0x5<<1) | (1<<5) | (1<<11);
++#else
++ int width = 320;
++ int height = 240;
++
++ topas910_v1_lcdc_platforminfo.width = width;
++ topas910_v1_lcdc_platforminfo.height = height;
++ topas910_v1_lcdc_platforminfo.depth = 32;
++ topas910_v1_lcdc_platforminfo.pitch = width*4;
++
++ LCDReg[0] =
++ ( ((width/16)-1) << 2) // pixel per line
++ | ( (8-1) << 8 ) // tHSW. Horizontal sync pulse
++ | ( (8-1) << 16 ) // tHFP, Horizontal front porch
++ | ( (8-1) << 24 ) // tHBP, Horizontal back porch
++ ;
++
++ LCDReg[1] =
++ (2 << 24) // tVBP
++ | (2 << 16) // tVFP
++ | ((2-1) << 10) // tVSP
++ | (height-1);
++
++ LCDReg[2] = ((width-1)<<16) | 0x0000e | 1<<13 | 0<<12 | 0<<11;
++ LCDReg[3] = 0;
++ LCDReg[4] = (0x5<<1) | (1<<5) | (1<<11);
++#endif
++ tmpa910_device_lcdc.dev.platform_data = &topas910_v1_lcdc_platforminfo;
++}
++
++
++void __init topas910_init_irq(void) {
++ tmpa910_init_irq();
++}
++
++
++/* Topas910 device initialisation */
++
++static void __init topas910_init(void)
++{
++ /* Memory controller - for DM9000 */
++ SMC_SET_CYCLES_3 = 0x0004AFAA;
++ SMC_SET_OPMODE_3 = 0x00000002;
++ SMC_DIRECT_CMD_3 = 0x00C00000;
++ __REG(0xf00a0050) = 0x01;
++
++ /* DMA setup */
++ platform_bus.coherent_dma_mask = 0xffffffff;
++ platform_bus.dma_mask=&topas910_dmamask;
++
++ /* Pin configuration */
++ TMPA910_CFG_PORT_GPIO(PORTA); /* Keypad */
++ TMPA910_CFG_PORT_GPIO(PORTB); /* 7 segment LED */
++ TMPA910_CFG_PORT_GPIO(PORTG); /* SDIO0, for SPI MMC */
++ TMPA910_CFG_PORT_GPIO(PORTP); /* GPIO routed to CM605 left */
++ TMPA910_PORT_T_FR1 = 0x00F0; /* Enable USB function pin */
++
++ /* Configure LCD interface */
++ _setup_lcdc_device();
++
++ /* NAND Controller */
++ NDFMCR0 = 0x00000010; // NDCE0n pin = 0, ECC-disable
++ NDFMCR1 = 0x00000000; // ECC = Hamming
++ NDFMCR2 = 0x00003343; // NDWEn L = 3clks,H =3clks,
++ // NDREn L = 4clks,H = 3clks
++ NDFINTC = 0x00000000; // ALL Interrupt Disable
++
++#ifdef CONFIG_USB_ISP1362_HCD
++ // Force configuration on the ISP expansion port interrupt line
++#warning _configure_isp1362_expansion_irq();
++#endif
++
++ /* Add devices */
++ platform_add_devices(devices, ARRAY_SIZE(devices));
++
++#if defined(CONFIG_SPI_AT25) || defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_MMC_SPI)
++ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
++#endif
++}
++
++
++MACHINE_START(TOPAS910, "Toshiba Topas910")
++ /* Maintainer: Florian Boor <florian.boor at kernelconcepts.de> */
++ .phys_io = TMPA910_IO_PHYS_BASE,
++ .boot_params = 0,
++ .io_pg_offst = (io_p2v(TMPA910_IO_PHYS_BASE) >> 18) & 0xfffc,
++ .map_io = topas910_map_io,
++ .init_irq = topas910_init_irq,
++ .timer = &topas910_timer,
++ .init_machine = topas910_init,
++MACHINE_END
+diff --git a/arch/arm/mach-tmpa910/topas910.h b/arch/arm/mach-tmpa910/topas910.h
+new file mode 100644
+index 0000000..6f50013
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/topas910.h
+@@ -0,0 +1,17 @@
++/*
++ * arch/arm/mach-topas910/topas910.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 __TOPAS910_H__
++#define __TOPAS910_H__
++
++extern void __init tmpa910_init_irq(void);
++
++struct sys_timer;
++extern struct sys_timer topas910_timer;
++
++#endif
+diff --git a/arch/arm/mach-tmpa910/topasa900.c b/arch/arm/mach-tmpa910/topasa900.c
+new file mode 100644
+index 0000000..7a9d365
+--- /dev/null
++++ b/arch/arm/mach-tmpa910/topasa900.c
+@@ -0,0 +1,697 @@
++/*
++ * arch/arm/mach-tmpa910/topasa900.c
++ *
++ * Copyright (C) 2008 bplan GmbH. All rights reserved.
++ * Copyright (C) 2009 Florian Boor <florian.boor at kernelconcepts.de>
++ *
++ * 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
++ *
++ * Toshiba Topas A900 machine, reference design for the TMPA900 SoC
++ *
++ * TODO: MMC, ADC, power manager
++ * TODO: separate SoC and board code
++ */
++
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/mmc_spi.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++
++#include <asm/system.h>
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++
++#include <asm/mach/map.h>
++#include <asm/mach-types.h>
++
++#include <video/tmpa910_fb.h>
++#include <mach/gpio.h>
++
++#include <asm/mach/arch.h>
++#include <mach/hardware.h>
++#include <mach/ts.h>
++#include <mach/tmpa910_regs.h>
++#include <asm/serial.h>
++#include <asm/dma.h>
++
++#if defined(CONFIG_USB_ISP1362_HCD)
++#include <linux/usb/isp1362.h>
++#endif
++
++#ifdef CONFIG_SPI_TMPA910
++#include <linux/spi/spi.h>
++#endif
++
++#ifdef CONFIG_SPI_AT25
++#include <linux/spi/eeprom.h>
++#endif
++
++#include "topas910.h"
++
++#define CONFIG_SPI_CHANNEL0
++
++
++/* I/O Mapping related, might want to be moved to a CPU specific file */
++
++static struct map_desc tmpa900_io_desc[] __initdata = {
++ {
++ .virtual = TMPA910_IO_VIRT_BASE,
++ .pfn = __phys_to_pfn(TMPA910_IO_PHYS_BASE),
++ .length = TMPA910_IO_SIZE,
++ .type = MT_DEVICE,
++ }
++};
++
++
++void __init topasa900_map_io(void)
++{
++ iotable_init(tmpa900_io_desc, ARRAY_SIZE(tmpa900_io_desc));
++}
++
++
++static void dummy_release(struct device *dev)
++{
++ /* normally not freed */
++}
++
++static u64 topas910_dmamask = 0xffffffffUL;
++
++/* Ethernet */
++
++static struct resource dm9000_resources[] = {
++ [0] = {
++ .start = 0x60000002,
++ .end = 0x60000003,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 0x60001002,
++ .end = 0x60001003,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = TOPAS910_INT_DM9000,
++ .end = TOPAS910_INT_DM9000,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
++ },
++};
++
++
++static struct platform_device topas910_dm9000_device = {
++ .name = "dm9000",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(dm9000_resources),
++ .resource = dm9000_resources,
++ .dev = {
++ .release = dummy_release,
++ .coherent_dma_mask = 0xffffffff,
++ },
++};
++
++
++/*
++ * Serial UART
++ */
++
++static struct resource tmpa910_resource_uart0[] = {
++ {
++ .start = 0xf2000000,
++ .end = 0xf2000000 + 0x100,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = 10,
++ .end = 10,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++
++struct platform_device tmpa910_device_uart0 = {
++ .name = "tmpa910-uart",
++ .id = 0,
++ .resource = tmpa910_resource_uart0,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_uart0),
++};
++
++
++/*
++ * DMA
++*/
++static struct resource tmpa910_resource_dmac[] = {
++ {
++ .start = DMAC_BASE,
++ .end = DMAC_BASE+0x200,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_DMA_END,
++ .end = INTR_VECT_DMA_END,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }, {
++ .start = INTR_VECT_DMA_ERROR,
++ .end = INTR_VECT_DMA_ERROR,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++struct platform_device tmpa910_device_dmac = {
++ .name = "tmpa910-dmac",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL
++ },
++ .resource = tmpa910_resource_dmac,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_dmac),
++};
++
++
++static struct resource tmpa910_resource_i2c[] = {
++ {
++ .start = I2C0_BASE,
++ .end = I2C0_BASE+0x1F,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = I2C1_BASE,
++ .end = I2C1_BASE+0x1F,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_I2C_CH0,
++ .end = INTR_VECT_I2C_CH0,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }, {
++ .start = INTR_VECT_I2C_CH1,
++ .end = INTR_VECT_I2C_CH1,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++struct platform_device tmpa910_device_i2c = {
++ .name = "tmpa910-i2c",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = tmpa910_resource_i2c,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_i2c),
++};
++
++
++#ifdef CONFIG_SPI_CHANNEL0
++static struct resource tmpa910_resource_spi0[] = {
++ {
++ .start = 0xF2002000,
++ .end = 0xF2002000+0x27,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_SSP_CH0,
++ .end = INTR_VECT_SSP_CH0,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++#endif
++
++#ifdef CONFIG_SPI_CHANNEL1
++static struct resource tmpa910_resource_spi1[] = {
++ {
++ .start = 0xF2003000,
++ .end = 0xF2003000+0x27,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_SSP_CH1,
++ .end = INTR_VECT_SSP_CH1,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++#endif
++
++#ifdef CONFIG_SPI_CHANNEL0
++struct platform_device tmpa910_device_spi0 = {
++ .name = "tmpa910-spi",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL,
++ },
++ .resource = tmpa910_resource_spi0,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_spi0),
++};
++#endif
++
++#ifdef CONFIG_SPI_CHANNEL1
++struct platform_device tmpa910_device_spi1 = {
++ .name = "tmpa910-spi",
++ .id = 1,
++ .dev = {
++ .platform_data = NULL,
++ },
++ .resource = tmpa910_resource_spi1,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_spi1),
++};
++#endif
++
++
++
++/*
++ * Touchscreen
++ */
++
++static struct resource tmpa910_resource_ts[] = {
++ {
++ .start = TS_BASE,
++ .end = TS_BASE + 0x40,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = ADC_BASE,
++ .end = ADC_BASE + 0x100,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_GPIOD,
++ .end = INTR_VECT_GPIOD,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }, {
++ .start = INTR_VECT_ADC,
++ .end = INTR_VECT_ADC,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++struct platform_device tmpa910_device_ts = {
++ .name = "tmpa910_ts",
++ .id = 0,
++ .dev = {
++ .platform_data = NULL
++ },
++ .resource = tmpa910_resource_ts,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_ts),
++};
++
++
++/* LCD controller device */
++
++static struct resource tmpa910_resource_lcdc[] = {
++ {
++ .start = LCDC_BASE,
++ .end = LCDC_BASE + 0x400,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = FB_OFFSET,
++ .end = FB_OFFSET+FB_SIZE,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = INTR_VECT_LCDC,
++ .end = INTR_VECT_LCDC,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ }
++};
++
++
++static struct tmpa910_lcdc_platforminfo topas910_v1_lcdc_platforminfo;
++
++
++struct platform_device tmpa910_device_lcdc= {
++ .name = "tmpa910_lcdc",
++ .id = 0,
++ .resource = tmpa910_resource_lcdc,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_lcdc),
++};
++
++
++/*
++ * 7 segment LED display
++ */
++
++static struct platform_device topas910_led_device = {
++ .name = "led-topas",
++ .id = -1,
++};
++
++
++/*
++ * Joystick
++ */
++
++static struct gpio_keys_button topas910_buttons[] = {
++ {
++ .code = KEY_LEFT,
++ .gpio = 0,
++ .active_low = 0,
++ .desc = "Joystick left",
++ .type = EV_KEY,
++ .wakeup = 0,
++ },
++ {
++ .code = KEY_DOWN,
++ .gpio = 1,
++ .active_low = 0,
++ .desc = "Joystick down",
++ .type = EV_KEY,
++ .wakeup = 0,
++ },
++ {
++ .code = KEY_UP,
++ .gpio = 2,
++ .active_low = 0,
++ .desc = "Joystick up",
++ .type = EV_KEY,
++ .wakeup = 0,
++ },
++ {
++ .code = KEY_RIGHT,
++ .gpio = 3,
++ .active_low = 0,
++ .desc = "Joystick right",
++ .type = EV_KEY,
++ .wakeup = 0,
++ },
++ {
++ .code = KEY_ENTER,
++ .gpio = 4,
++ .active_low = 0,
++ .desc = "Joystick center",
++ .type = EV_KEY,
++ .wakeup = 1,
++ },
++};
++
++static struct gpio_keys_platform_data topas910_keys_data = {
++ .buttons = topas910_buttons,
++ .nbuttons = ARRAY_SIZE(topas910_buttons),
++};
++
++static struct platform_device topas910_keys_device = {
++ .name = "gpio-keys",
++ .id = -1,
++ .dev = {
++ .platform_data = &topas910_keys_data,
++ },
++};
++
++
++/*
++ * NAND Flash Controller
++ */
++
++#ifdef CONFIG_MTD_NAND_TMPA910
++static struct resource tmpa910_nand_resources[] = {
++ [0] = {
++ .start = NANDF_BASE ,
++ .end = NANDF_BASE + 0x200,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device tmpa910_nand_device = {
++ .name = "tmpa910-nand",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa910_nand_resources),
++ .resource = tmpa910_nand_resources,
++};
++
++#endif
++
++
++static struct platform_device tmpa910_i2s_device = {
++ .name = "WM8976-I2S",
++ .id = -1,
++};
++
++
++#ifdef CONFIG_MMC_SPI
++static struct spi_board_info spi_board_info[] =
++{
++{
++ .modalias = "mmc_spi",
++ .platform_data = NULL,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 1000000,
++ .bus_num = 0,
++
++}
++};
++
++#elif defined(CONFIG_SPI_AT25)
++static struct spi_eeprom spi_eeprom_info = {
++ .page_size = 256,
++ .name = "AT25F512",
++ .flags = EE_ADDR3|EE_READONLY
++};
++
++static struct spi_board_info spi_board_info[] = {
++{
++ .modalias = "at25",
++ .platform_data = &spi_eeprom_info,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 0,
++},
++{
++ .modalias = "at25",
++ .platform_data = &spi_eeprom_info,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 1,
++}
++};
++#elif defined(CONFIG_SPI_SPIDEV)
++static struct spi_board_info spi_board_info[] = {
++{
++ .modalias = "spidev",
++ .platform_data = NULL,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 0,
++},
++{
++ .modalias = "spidev",
++ .platform_data = NULL,
++ .mode = SPI_MODE_0,
++ .chip_select = 0,
++ .max_speed_hz = 20000000,
++ .bus_num = 1,
++}
++};
++
++#endif
++
++
++#define RTC_BASE 0xF0030000
++
++static struct resource tmpa910_resource_rtc[] = {
++ {
++ .start = RTC_BASE,
++ .end = RTC_BASE + 0x3ff,
++ .flags = IORESOURCE_MEM
++ },{
++ .start = INTR_VECT_RTC,
++ .end = INTR_VECT_RTC,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH
++ }
++};
++
++static struct platform_device tmpa910_device_rtc = {
++ .name = "tmpa910_rtc",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa910_resource_rtc),
++ .resource = tmpa910_resource_rtc
++ }
++;
++
++
++#ifdef CONFIG_USB_OHCI_HCD_TMPA900
++static struct resource tmpa900_ohci_resources[] = {
++ [0] = {
++ .start = 0xf4500000,
++ .end = 0xf4500000 + 0x100,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = 0xF8008000,
++ .end = 0xF8009fff,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = 27,
++ .end = 27,
++ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
++ },
++};
++
++static struct platform_device tmpa900_ohci_device = {
++ .name = "tmpa900-usb",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa900_ohci_resources),
++ .resource = tmpa900_ohci_resources,
++ .dev = {
++ .release = dummy_release, // not needed
++ .coherent_dma_mask = 0xffffffff,
++ },
++};
++
++#endif /* CONFIG_USB_OHCI_HCD_TMPA900 */
++
++
++#ifdef CONFIG_USB_GADGET_TMPA910
++/* USB Device Controller */
++static struct resource tmpa910_udc_resource[] = {
++ [0] = {
++ .start = 0xf4400000,
++ .end = 0xf44003ff,
++ .flags = IORESOURCE_MEM
++ },
++ [1] = {
++ .start = USB_INT,
++ .end = USB_INT,
++ .flags = IORESOURCE_IRQ
++ }
++};
++
++static struct platform_device tmpa910_udc_device = {
++ .name = "tmpa910-usb",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(tmpa910_udc_resource),
++ .resource = tmpa910_udc_resource,
++ .dev = {
++ .platform_data = NULL,
++ }
++};
++#endif
++
++
++static struct platform_device *devices[] __initdata = {
++ &tmpa910_device_dmac,
++ &tmpa910_device_ts,
++ &topas910_led_device,
++ &topas910_dm9000_device,
++ &tmpa910_device_uart0,
++#ifdef CONFIG_MTD_NAND_TMPA910
++ &tmpa910_nand_device,
++#endif
++ &topas910_keys_device,
++ &tmpa910_device_lcdc,
++ &tmpa910_device_i2c,
++#ifdef CONFIG_USB_GADGET_TMPA910
++ &tmpa910_udc_device,
++#endif
++#ifdef CONFIG_USB_OHCI_HCD_TMPA900
++ &tmpa900_ohci_device,
++#endif
++ &tmpa910_i2s_device,
++#ifdef CONFIG_SPI_CHANNEL0
++ &tmpa910_device_spi0,
++#endif
++#ifdef CONFIG_SPI_CHANNEL1
++ &tmpa910_device_spi1,
++#endif
++ &tmpa910_device_rtc
++};
++
++
++static void __init setup_lcdc_device(void)
++{
++ uint32_t *LCDReg;
++ int width = 320;
++ int height = 240;
++
++ topas910_v1_lcdc_platforminfo.width = width;
++ topas910_v1_lcdc_platforminfo.height = height;
++ topas910_v1_lcdc_platforminfo.depth = 32;
++ topas910_v1_lcdc_platforminfo.pitch = width*4;
++
++ LCDReg = topas910_v1_lcdc_platforminfo.LCDReg;
++ LCDReg[LCDREG_TIMING0_H] = ( ((height/16)-1) << 2) // pixel per line
++ | ( (8-1) << 8 ) // tHSW. Horizontal sync pulse
++ | ( (8-1) << 16 ) // tHFP, Horizontal front porch
++ | ( (8-1) << 24 ); // tHBP, Horizontal back porch
++
++ LCDReg[LCDREG_TIMING1_V] = (2 << 24) // tVBP
++ | (2 << 16) // tVFP
++ | ((2-1) << 10) // tVSP
++ | (width-1);
++
++ LCDReg[LCDREG_TIMING2_CLK] = ((width-1)<<16) | 0x0000e | 1<<13 | 0<<12 | 0<<11;
++ LCDReg[LCDREG_TIMING3_LEC] = 0;
++ LCDReg[LCDREG_LCDCONTROL] = (0x5<<1) | (1<<5) | (1<<11);
++ tmpa910_device_lcdc.dev.platform_data = &topas910_v1_lcdc_platforminfo;
++}
++
++
++void __init topasa900_init_irq(void) {
++ tmpa910_init_irq();
++}
++
++
++/* TopasA900 device initialisation */
++
++static void __init topasa900_init(void)
++{
++
++ /* Memory controller - for DM9000 */
++ SMC_SET_CYCLES_3 = 0x0004AFAA;
++ SMC_SET_OPMODE_3 = 0x00000002;
++ SMC_DIRECT_CMD_3 = 0x00C00000;
++
++ /* DMA setup */
++ platform_bus.coherent_dma_mask = 0xffffffff;
++ platform_bus.dma_mask=&topas910_dmamask;
++
++ /* Pin configuration */
++ TMPA910_CFG_PORT_GPIO(PORTA); /* Keypad */
++ TMPA910_CFG_PORT_GPIO(PORTB); /* 7 segment LED */
++ TMPA910_CFG_PORT_GPIO(PORTG); /* SDIO0, for SPI MMC */
++ TMPA910_CFG_PORT_GPIO(PORTP); /* GPIO routed to CM605 left */
++ TMPA910_PORT_T_FR1 = 0x00F0; /* Enable USB function pin */
++
++ /* Configure LCD interface */
++ setup_lcdc_device();
++
++ /* NAND Controller */
++ NDFMCR0 = 0x00000010; // NDCE0n pin = 0, ECC-disable
++ NDFMCR1 = 0x00000000; // ECC = Hamming
++ NDFMCR2 = 0x00003343; // NDWEn L = 3clks,H =3clks,
++ // NDREn L = 4clks,H = 3clks
++ NDFINTC = 0x00000000; // ALL Interrupt Disable
++
++ /* Add devices */
++ platform_add_devices(devices, ARRAY_SIZE(devices));
++
++#if defined(CONFIG_SPI_AT25) || defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_MMC_SPI)
++ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
++#endif
++}
++
++
++MACHINE_START(TOPASA900, "Toshiba TopasA900")
++ /* Maintainer: Florian Boor <florian.boor at kernelconcepts.de> */
++ .phys_io = TMPA910_IO_PHYS_BASE,
++ .boot_params = 0,
++ .io_pg_offst = (io_p2v(TMPA910_IO_PHYS_BASE) >> 18) & 0xfffc,
++ .map_io = topasa900_map_io,
++ .init_irq = topasa900_init_irq,
++ .timer = &topas910_timer,
++ .init_machine = topasa900_init,
++MACHINE_END
++
+diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
+index f5abc51..2b79964 100644
+--- a/arch/arm/mm/mmap.c
++++ b/arch/arm/mm/mmap.c
+@@ -54,8 +54,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ * We enforce the MAP_FIXED case.
+ */
+ if (flags & MAP_FIXED) {
+- if (aliasing && flags & MAP_SHARED &&
+- (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
++ if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1))
+ return -EINVAL;
+ return addr;
+ }
+diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
+index 07b976d..55a3609 100644
+--- a/arch/arm/tools/mach-types
++++ b/arch/arm/tools/mach-types
+@@ -12,7 +12,7 @@
+ #
+ # http://www.arm.linux.org.uk/developer/machines/?action=new
+ #
+-# Last update: Wed Nov 25 22:14:58 2009
++# Last update: Fri Mar 12 15:35:36 2010
+ #
+ # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
+ #
+@@ -1319,7 +1319,7 @@ mistral MACH_MISTRAL MISTRAL 1315
+ msm MACH_MSM MSM 1316
+ ct5910 MACH_CT5910 CT5910 1317
+ ct5912 MACH_CT5912 CT5912 1318
+-hynet_ine MACH_HYNET_INE HYNET_INE 1319
++argonst_foundation MACH_HYNET_INE HYNET_INE 1319
+ hynet_app MACH_HYNET_APP HYNET_APP 1320
+ msm7200 MACH_MSM7200 MSM7200 1321
+ msm7600 MACH_MSM7600 MSM7600 1322
+@@ -1776,6 +1776,7 @@ cybook3 MACH_CYBOOK3 CYBOOK3 1784
+ wdg002 MACH_WDG002 WDG002 1785
+ sg560adsl MACH_SG560ADSL SG560ADSL 1786
+ nextio_n2800_ica MACH_NEXTIO_N2800_ICA NEXTIO_N2800_ICA 1787
++dove_db MACH_DOVE_DB DOVE_DB 1788
+ marvell_newdb MACH_MARVELL_NEWDB MARVELL_NEWDB 1789
+ vandihud MACH_VANDIHUD VANDIHUD 1790
+ magx_e8 MACH_MAGX_E8 MAGX_E8 1791
+@@ -2256,7 +2257,7 @@ oratisalog MACH_ORATISALOG ORATISALOG 2268
+ oratismadi MACH_ORATISMADI ORATISMADI 2269
+ oratisot16 MACH_ORATISOT16 ORATISOT16 2270
+ oratisdesk MACH_ORATISDESK ORATISDESK 2271
+-v2_ca9 MACH_V2P_CA9 V2P_CA9 2272
++vexpress MACH_VEXPRESS VEXPRESS 2272
+ sintexo MACH_SINTEXO SINTEXO 2273
+ cm3389 MACH_CM3389 CM3389 2274
+ omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275
+@@ -2373,7 +2374,7 @@ sch_m490 MACH_SCH_M490 SCH_M490 2386
+ rbl01 MACH_RBL01 RBL01 2387
+ omnifi MACH_OMNIFI OMNIFI 2388
+ otavalo MACH_OTAVALO OTAVALO 2389
+-sienna MACH_SIENNA SIENNA 2390
++siena MACH_SIENNA SIENNA 2390
+ htc_excalibur_s620 MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620 2391
+ htc_opal MACH_HTC_OPAL HTC_OPAL 2392
+ touchbook MACH_TOUCHBOOK TOUCHBOOK 2393
+@@ -2535,4 +2536,197 @@ davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548
+ c3ax03 MACH_C3AX03 C3AX03 2549
+ mxt_td60 MACH_MXT_TD60 MXT_TD60 2550
+ esyx MACH_ESYX ESYX 2551
++dove_db2 MACH_DOVE_DB2 DOVE_DB2 2552
+ bulldog MACH_BULLDOG BULLDOG 2553
++derell_me2000 MACH_DERELL_ME2000 DERELL_ME2000 2554
++bcmring_base MACH_BCMRING_BASE BCMRING_BASE 2555
++bcmring_evm MACH_BCMRING_EVM BCMRING_EVM 2556
++bcmring_evm_jazz MACH_BCMRING_EVM_JAZZ BCMRING_EVM_JAZZ 2557
++bcmring_sp MACH_BCMRING_SP BCMRING_SP 2558
++bcmring_sv MACH_BCMRING_SV BCMRING_SV 2559
++bcmring_sv_jazz MACH_BCMRING_SV_JAZZ BCMRING_SV_JAZZ 2560
++bcmring_tablet MACH_BCMRING_TABLET BCMRING_TABLET 2561
++bcmring_vp MACH_BCMRING_VP BCMRING_VP 2562
++bcmring_evm_seikor MACH_BCMRING_EVM_SEIKOR BCMRING_EVM_SEIKOR 2563
++bcmring_sp_wqvga MACH_BCMRING_SP_WQVGA BCMRING_SP_WQVGA 2564
++bcmring_custom MACH_BCMRING_CUSTOM BCMRING_CUSTOM 2565
++acer_s200 MACH_ACER_S200 ACER_S200 2566
++bt270 MACH_BT270 BT270 2567
++iseo MACH_ISEO ISEO 2568
++cezanne MACH_CEZANNE CEZANNE 2569
++lucca MACH_LUCCA LUCCA 2570
++supersmart MACH_SUPERSMART SUPERSMART 2571
++arm11_board MACH_CS_MISANO CS_MISANO 2572
++magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 2573
++emxx MACH_EMXX EMXX 2574
++outlaw MACH_OUTLAW OUTLAW 2575
++riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576
++riot_vox MACH_RIOT_VOX RIOT_VOX 2577
++riot_x37 MACH_RIOT_X37 RIOT_X37 2578
++mega25mx MACH_MEGA25MX MEGA25MX 2579
++benzina2 MACH_BENZINA2 BENZINA2 2580
++ignite MACH_IGNITE IGNITE 2581
++foggia MACH_FOGGIA FOGGIA 2582
++arezzo MACH_AREZZO AREZZO 2583
++leica_skywalker MACH_LEICA_SKYWALKER LEICA_SKYWALKER 2584
++jacinto2_jamr MACH_JACINTO2_JAMR JACINTO2_JAMR 2585
++gts_nova MACH_GTS_NOVA GTS_NOVA 2586
++p3600 MACH_P3600 P3600 2587
++dlt2 MACH_DLT2 DLT2 2588
++df3120 MACH_DF3120 DF3120 2589
++ecucore_9g20 MACH_ECUCORE_9G20 ECUCORE_9G20 2590
++nautel_lpc3240 MACH_NAUTEL_LPC3240 NAUTEL_LPC3240 2591
++glacier MACH_GLACIER GLACIER 2592
++phrazer_bulldog MACH_PHRAZER_BULLDOG PHRAZER_BULLDOG 2593
++omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_BULLDOG 2594
++pca101 MACH_PCA101 PCA101 2595
++buzzc MACH_BUZZC BUZZC 2596
++sasie2 MACH_SASIE2 SASIE2 2597
++davinci_cio MACH_DAVINCI_CIO DAVINCI_CIO 2598
++smartmeter_dl MACH_SMARTMETER_DL SMARTMETER_DL 2599
++wzl6410 MACH_WZL6410 WZL6410 2600
++wzl6410m MACH_WZL6410M WZL6410M 2601
++wzl6410f MACH_WZL6410F WZL6410F 2602
++wzl6410i MACH_WZL6410I WZL6410I 2603
++spacecom1 MACH_SPACECOM1 SPACECOM1 2604
++pingu920 MACH_PINGU920 PINGU920 2605
++bravoc MACH_BRAVOC BRAVOC 2606
++cybo2440 MACH_CYBO2440 CYBO2440 2607
++vdssw MACH_VDSSW VDSSW 2608
++romulus MACH_ROMULUS ROMULUS 2609
++omap_magic MACH_OMAP_MAGIC OMAP_MAGIC 2610
++eltd100 MACH_ELTD100 ELTD100 2611
++capc7117 MACH_CAPC7117 CAPC7117 2612
++swan MACH_SWAN SWAN 2613
++veu MACH_VEU VEU 2614
++rm2 MACH_RM2 RM2 2615
++tt2100 MACH_TT2100 TT2100 2616
++venice MACH_VENICE VENICE 2617
++pc7323 MACH_PC7323 PC7323 2618
++masp MACH_MASP MASP 2619
++fujitsu_tvstbsoc0 MACH_FUJITSU_TVSTBSOC FUJITSU_TVSTBSOC 2620
++fujitsu_tvstbsoc1 MACH_FUJITSU_TVSTBSOC1 FUJITSU_TVSTBSOC1 2621
++lexikon MACH_LEXIKON LEXIKON 2622
++mini2440v2 MACH_MINI2440V2 MINI2440V2 2623
++icontrol MACH_ICONTROL ICONTROL 2624
++sheevad MACH_SHEEVAD SHEEVAD 2625
++qsd8x50a_st1_1 MACH_QSD8X50A_ST1_1 QSD8X50A_ST1_1 2626
++qsd8x50a_st1_5 MACH_QSD8X50A_ST1_5 QSD8X50A_ST1_5 2627
++bee MACH_BEE BEE 2628
++mx23evk MACH_MX23EVK MX23EVK 2629
++ap4evb MACH_AP4EVB AP4EVB 2630
++stockholm MACH_STOCKHOLM STOCKHOLM 2631
++lpc_h3131 MACH_LPC_H3131 LPC_H3131 2632
++stingray MACH_STINGRAY STINGRAY 2633
++kraken MACH_KRAKEN KRAKEN 2634
++gw2388 MACH_GW2388 GW2388 2635
++jadecpu MACH_JADECPU JADECPU 2636
++carlisle MACH_CARLISLE CARLISLE 2637
++lux_sf9 MACH_LUX_SFT9 LUX_SFT9 2638
++nemid_tb MACH_NEMID_TB NEMID_TB 2639
++terrier MACH_TERRIER TERRIER 2640
++turbot MACH_TURBOT TURBOT 2641
++sanddab MACH_SANDDAB SANDDAB 2642
++mx35_cicada MACH_MX35_CICADA MX35_CICADA 2643
++ghi2703d MACH_GHI2703D GHI2703D 2644
++lux_sfx9 MACH_LUX_SFX9 LUX_SFX9 2645
++lux_sf9g MACH_LUX_SF9G LUX_SF9G 2646
++lux_edk9 MACH_LUX_EDK9 LUX_EDK9 2647
++hw90240 MACH_HW90240 HW90240 2648
++dm365_leopard MACH_DM365_LEOPARD DM365_LEOPARD 2649
++mityomapl138 MACH_MITYOMAPL138 MITYOMAPL138 2650
++scat110 MACH_SCAT110 SCAT110 2651
++acer_a1 MACH_ACER_A1 ACER_A1 2652
++cmcontrol MACH_CMCONTROL CMCONTROL 2653
++pelco_lamar MACH_PELCO_LAMAR PELCO_LAMAR 2654
++rfp43 MACH_RFP43 RFP43 2655
++sk86r0301 MACH_SK86R0301 SK86R0301 2656
++ctpxa MACH_CTPXA CTPXA 2657
++epb_arm9_a MACH_EPB_ARM9_A EPB_ARM9_A 2658
++guruplug MACH_GURUPLUG GURUPLUG 2659
++spear310 MACH_SPEAR310 SPEAR310 2660
++spear320 MACH_SPEAR320 SPEAR320 2661
++robotx MACH_ROBOTX ROBOTX 2662
++lsxhl MACH_LSXHL LSXHL 2663
++smartlite MACH_SMARTLITE SMARTLITE 2664
++cws2 MACH_CWS2 CWS2 2665
++m619 MACH_M619 M619 2666
++smartview MACH_SMARTVIEW SMARTVIEW 2667
++lsa_salsa MACH_LSA_SALSA LSA_SALSA 2668
++kizbox MACH_KIZBOX KIZBOX 2669
++htccharmer MACH_HTCCHARMER HTCCHARMER 2670
++guf_neso_lt MACH_GUF_NESO_LT GUF_NESO_LT 2671
++pm9g45 MACH_PM9G45 PM9G45 2672
++htcpanther MACH_HTCPANTHER HTCPANTHER 2673
++htcpanther_cdma MACH_HTCPANTHER_CDMA HTCPANTHER_CDMA 2674
++reb01 MACH_REB01 REB01 2675
++aquila MACH_AQUILA AQUILA 2676
++spark_sls_hw2 MACH_SPARK_SLS_HW2 SPARK_SLS_HW2 2677
++sheeva_esata MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678
++msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
++micro2440 MACH_MICRO2440 MICRO2440 2680
++am2440 MACH_AM2440 AM2440 2681
++tq2440 MACH_TQ2440 TQ2440 2682
++lpc2478oem MACH_LPC2478OEM LPC2478OEM 2683
++ak880x MACH_AK880X AK880X 2684
++cobra3530 MACH_COBRA3530 COBRA3530 2685
++pmppb MACH_PMPPB PMPPB 2686
++u6715 MACH_U6715 U6715 2687
++axar1500_sender MACH_AXAR1500_SENDER AXAR1500_SENDER 2688
++g30_dvb MACH_G30_DVB G30_DVB 2689
++vc088x MACH_VC088X VC088X 2690
++mioa702 MACH_MIOA702 MIOA702 2691
++hpmin MACH_HPMIN HPMIN 2692
++ak880xak MACH_AK880XAK AK880XAK 2693
++arm926tomap850 MACH_ARM926TOMAP850 ARM926TOMAP850 2694
++lkevm MACH_LKEVM LKEVM 2695
++mw6410 MACH_MW6410 MW6410 2696
++terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697
++cpu8000e MACH_CPU8000E CPU8000E 2698
++catania MACH_CATANIA CATANIA 2699
++tokyo MACH_TOKYO TOKYO 2700
++msm7201a_surf MACH_MSM7201A_SURF MSM7201A_SURF 2701
++msm7201a_ffa MACH_MSM7201A_FFA MSM7201A_FFA 2702
++msm7x25_surf MACH_MSM7X25_SURF MSM7X25_SURF 2703
++msm7x25_ffa MACH_MSM7X25_FFA MSM7X25_FFA 2704
++msm7x27_surf MACH_MSM7X27_SURF MSM7X27_SURF 2705
++msm7x27_ffa MACH_MSM7X27_FFA MSM7X27_FFA 2706
++msm7x30_ffa MACH_MSM7X30_FFA MSM7X30_FFA 2707
++qsd8x50_surf MACH_QSD8X50_SURF QSD8X50_SURF 2708
++qsd8x50_comet MACH_QSD8X50_COMET QSD8X50_COMET 2709
++qsd8x50_ffa MACH_QSD8X50_FFA QSD8X50_FFA 2710
++qsd8x50a_surf MACH_QSD8X50A_SURF QSD8X50A_SURF 2711
++qsd8x50a_ffa MACH_QSD8X50A_FFA QSD8X50A_FFA 2712
++adx_xgcp10 MACH_ADX_XGCP10 ADX_XGCP10 2713
++mcgwumts2a MACH_MCGWUMTS2A MCGWUMTS2A 2714
++mobikt MACH_MOBIKT MOBIKT 2715
++mx53_evk MACH_MX53_EVK MX53_EVK 2716
++igep0030 MACH_IGEP0030 IGEP0030 2717
++axell_h40_h50_ctrl MACH_AXELL_H40_H50_CTRL AXELL_H40_H50_CTRL 2718
++dtcommod MACH_DTCOMMOD DTCOMMOD 2719
++gould MACH_GOULD GOULD 2720
++siberia MACH_SIBERIA SIBERIA 2721
++sbc3530 MACH_SBC3530 SBC3530 2722
++qarm MACH_QARM QARM 2723
++mips MACH_MIPS MIPS 2724
++mx27grb MACH_MX27GRB MX27GRB 2725
++sbc8100 MACH_SBC8100 SBC8100 2726
++saarb MACH_SAARB SAARB 2727
++omap3mini MACH_OMAP3MINI OMAP3MINI 2728
++cnmbook7se MACH_CNMBOOK7SE CNMBOOK7SE 2729
++catan MACH_CATAN CATAN 2730
++harmony MACH_HARMONY HARMONY 2731
++tonga MACH_TONGA TONGA 2732
++cybook_orizon MACH_CYBOOK_ORIZON CYBOOK_ORIZON 2733
++htcrhodiumcdma MACH_HTCRHODIUMCDMA HTCRHODIUMCDMA 2734
++epc_g45 MACH_EPC_G45 EPC_G45 2735
++epc_lpc3250 MACH_EPC_LPC3250 EPC_LPC3250 2736
++mxc91341evb MACH_MXC91341EVB MXC91341EVB 2737
++rtw1000 MACH_RTW1000 RTW1000 2738
++bobcat MACH_BOBCAT BOBCAT 2739
++trizeps6 MACH_TRIZEPS6 TRIZEPS6 2740
++msm7x30_fluid MACH_MSM7X30_FLUID MSM7X30_FLUID 2741
++nedap9263 MACH_NEDAP9263 NEDAP9263 2742
++netgear_ms2110 MACH_NETGEAR_MS2110 NETGEAR_MS2110 2743
++bmx MACH_BMX BMX 2744
++netstream MACH_NETSTREAM NETSTREAM 2745
+diff --git a/arch/avr32/include/asm/syscalls.h b/arch/avr32/include/asm/syscalls.h
+index 66a1972..483d666 100644
+--- a/arch/avr32/include/asm/syscalls.h
++++ b/arch/avr32/include/asm/syscalls.h
+@@ -29,6 +29,10 @@ asmlinkage int sys_sigaltstack(const stack_t __user *, stack_t __user *,
+ struct pt_regs *);
+ asmlinkage int sys_rt_sigreturn(struct pt_regs *);
+
++/* kernel/sys_avr32.c */
++asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
++ unsigned long, unsigned long, off_t);
++
+ /* mm/cache.c */
+ asmlinkage int sys_cacheflush(int, void __user *, size_t);
+
+diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c
+index 459349b..5d2daea 100644
+--- a/arch/avr32/kernel/sys_avr32.c
++++ b/arch/avr32/kernel/sys_avr32.c
+@@ -5,8 +5,39 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
++#include <linux/errno.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/mm.h>
+ #include <linux/unistd.h>
+
++#include <asm/mman.h>
++#include <asm/uaccess.h>
++#include <asm/syscalls.h>
++
++asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, off_t offset)
++{
++ int error = -EBADF;
++ struct file *file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ return error;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, offset);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++ return error;
++}
++
+ int kernel_execve(const char *file, char **argv, char **envp)
+ {
+ register long scno asm("r8") = __NR_execve;
+diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S
+index 0447a3e..f7244cd 100644
+--- a/arch/avr32/kernel/syscall-stubs.S
++++ b/arch/avr32/kernel/syscall-stubs.S
+@@ -61,7 +61,7 @@ __sys_execve:
+ __sys_mmap2:
+ pushm lr
+ st.w --sp, ARG6
+- call sys_mmap_pgoff
++ call sys_mmap2
+ sub sp, -4
+ popm pc
+
+diff --git a/arch/blackfin/include/asm/page.h b/arch/blackfin/include/asm/page.h
+index 1d04e40..944a07c 100644
+--- a/arch/blackfin/include/asm/page.h
++++ b/arch/blackfin/include/asm/page.h
+@@ -10,9 +10,4 @@
+ #include <asm-generic/page.h>
+ #define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+
+-#define VM_DATA_DEFAULT_FLAGS \
+- (VM_READ | VM_WRITE | \
+- ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
+- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+-
+ #endif
+diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
+index 2e7f8e1..afcef12 100644
+--- a/arch/blackfin/kernel/sys_bfin.c
++++ b/arch/blackfin/kernel/sys_bfin.c
+@@ -22,6 +22,39 @@
+ #include <asm/cacheflush.h>
+ #include <asm/dma.h>
+
++/* common code for old and new mmaps */
++static inline long
++do_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ int error = -EBADF;
++ struct file *file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++ out:
++ return error;
++}
++
++asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ return do_mmap2(addr, len, prot, flags, fd, pgoff);
++}
++
+ asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags)
+ {
+ return sram_alloc_with_lsl(size, flags);
+diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
+index 1d8f00a..94a0375 100644
+--- a/arch/blackfin/mach-common/entry.S
++++ b/arch/blackfin/mach-common/entry.S
+@@ -1422,7 +1422,7 @@ ENTRY(_sys_call_table)
+ .long _sys_ni_syscall /* streams2 */
+ .long _sys_vfork /* 190 */
+ .long _sys_getrlimit
+- .long _sys_mmap_pgoff
++ .long _sys_mmap2
+ .long _sys_truncate64
+ .long _sys_ftruncate64
+ .long _sys_stat64 /* 195 */
+diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c
+index c2bbb1a..2ad962c 100644
+--- a/arch/cris/kernel/sys_cris.c
++++ b/arch/cris/kernel/sys_cris.c
+@@ -26,6 +26,31 @@
+ #include <asm/uaccess.h>
+ #include <asm/segment.h>
+
++/* common code for old and new mmaps */
++static inline long
++do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
++ unsigned long flags, unsigned long fd, unsigned long pgoff)
++{
++ int error = -EBADF;
++ struct file * file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ asmlinkage unsigned long old_mmap(unsigned long __user *args)
+ {
+ unsigned long buffer[6];
+@@ -38,7 +63,7 @@ asmlinkage unsigned long old_mmap(unsigned long __user *args)
+ if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */
+ goto out;
+
+- err = sys_mmap_pgoff(buffer[0], buffer[1], buffer[2], buffer[3],
++ err = do_mmap2(buffer[0], buffer[1], buffer[2], buffer[3],
+ buffer[4], buffer[5] >> PAGE_SHIFT);
+ out:
+ return err;
+@@ -48,8 +73,7 @@ asmlinkage long
+ sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, unsigned long fd, unsigned long pgoff)
+ {
+- /* bug(?): 8Kb pages here */
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
++ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+ }
+
+ /*
+diff --git a/arch/frv/include/asm/page.h b/arch/frv/include/asm/page.h
+index 8c97068..25c6a50 100644
+--- a/arch/frv/include/asm/page.h
++++ b/arch/frv/include/asm/page.h
+@@ -63,10 +63,12 @@ extern unsigned long max_pfn;
+ #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+
+
++#ifdef CONFIG_MMU
+ #define VM_DATA_DEFAULT_FLAGS \
+ (VM_READ | VM_WRITE | \
+ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
++#endif
+
+ #endif /* __ASSEMBLY__ */
+
+diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c
+index 1d3d4c9..2b6b528 100644
+--- a/arch/frv/kernel/sys_frv.c
++++ b/arch/frv/kernel/sys_frv.c
+@@ -31,6 +31,9 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+ {
++ int error = -EBADF;
++ struct file * file = NULL;
++
+ /* As with sparc32, make sure the shift for mmap2 is constant
+ (12), no matter what PAGE_SIZE we have.... */
+
+@@ -38,10 +41,69 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ trying to map something we can't */
+ if (pgoff & ((1 << (PAGE_SHIFT - 12)) - 1))
+ return -EINVAL;
++ pgoff >>= PAGE_SHIFT - 12;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
++#if 0 /* DAVIDM - do we want this */
++struct mmap_arg_struct64 {
++ __u32 addr;
++ __u32 len;
++ __u32 prot;
++ __u32 flags;
++ __u64 offset; /* 64 bits */
++ __u32 fd;
++};
++
++asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
++{
++ int error = -EFAULT;
++ struct file * file = NULL;
++ struct mmap_arg_struct64 a;
++ unsigned long pgoff;
++
++ if (copy_from_user(&a, arg, sizeof(a)))
++ return -EFAULT;
++
++ if ((long)a.offset & ~PAGE_MASK)
++ return -EINVAL;
++
++ pgoff = a.offset >> PAGE_SHIFT;
++ if ((a.offset >> PAGE_SHIFT) != pgoff)
++ return -EINVAL;
++
++ if (!(a.flags & MAP_ANONYMOUS)) {
++ error = -EBADF;
++ file = fget(a.fd);
++ if (!file)
++ goto out;
++ }
++ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+- return sys_mmap_pgoff(addr, len, prot, flags, fd,
+- pgoff >> (PAGE_SHIFT - 12));
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++ if (file)
++ fput(file);
++out:
++ return error;
+ }
++#endif
+
+ /*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
+index b5969db..8cb5d73 100644
+--- a/arch/h8300/kernel/sys_h8300.c
++++ b/arch/h8300/kernel/sys_h8300.c
+@@ -26,6 +26,39 @@
+ #include <asm/traps.h>
+ #include <asm/unistd.h>
+
++/* common code for old and new mmaps */
++static inline long do_mmap2(
++ unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ int error = -EBADF;
++ struct file * file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
++asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ return do_mmap2(addr, len, prot, flags, fd, pgoff);
++}
++
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+@@ -54,11 +87,57 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+- a.offset >> PAGE_SHIFT);
++ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++out:
++ return error;
++}
++
++#if 0 /* DAVIDM - do we want this */
++struct mmap_arg_struct64 {
++ __u32 addr;
++ __u32 len;
++ __u32 prot;
++ __u32 flags;
++ __u64 offset; /* 64 bits */
++ __u32 fd;
++};
++
++asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
++{
++ int error = -EFAULT;
++ struct file * file = NULL;
++ struct mmap_arg_struct64 a;
++ unsigned long pgoff;
++
++ if (copy_from_user(&a, arg, sizeof(a)))
++ return -EFAULT;
++
++ if ((long)a.offset & ~PAGE_MASK)
++ return -EINVAL;
++
++ pgoff = a.offset >> PAGE_SHIFT;
++ if ((a.offset >> PAGE_SHIFT) != pgoff)
++ return -EINVAL;
++
++ if (!(a.flags & MAP_ANONYMOUS)) {
++ error = -EBADF;
++ file = fget(a.fd);
++ if (!file)
++ goto out;
++ }
++ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++ if (file)
++ fput(file);
+ out:
+ return error;
+ }
++#endif
+
+ struct sel_arg_struct {
+ unsigned long n;
+diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S
+index 2d69881..4eb67fa 100644
+--- a/arch/h8300/kernel/syscalls.S
++++ b/arch/h8300/kernel/syscalls.S
+@@ -206,7 +206,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
+ .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
+ .long SYMBOL_NAME(sys_vfork) /* 190 */
+ .long SYMBOL_NAME(sys_getrlimit)
+- .long SYMBOL_NAME(sys_mmap_pgoff)
++ .long SYMBOL_NAME(sys_mmap2)
+ .long SYMBOL_NAME(sys_truncate64)
+ .long SYMBOL_NAME(sys_ftruncate64)
+ .long SYMBOL_NAME(sys_stat64) /* 195 */
+diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
+index e031ee8..625ed8f 100644
+--- a/arch/ia64/ia32/sys_ia32.c
++++ b/arch/ia64/ia32/sys_ia32.c
+@@ -858,9 +858,6 @@ ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot
+
+ prot = get_prot32(prot);
+
+- if (flags & MAP_HUGETLB)
+- return -ENOMEM;
+-
+ #if PAGE_SHIFT > IA32_PAGE_SHIFT
+ mutex_lock(&ia32_mmap_mutex);
+ {
+diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
+index cc8335e..0d9d16e 100644
+--- a/arch/ia64/include/asm/io.h
++++ b/arch/ia64/include/asm/io.h
+@@ -424,8 +424,6 @@ __writeq (unsigned long val, volatile void __iomem *addr)
+ extern void __iomem * ioremap(unsigned long offset, unsigned long size);
+ extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
+ extern void iounmap (volatile void __iomem *addr);
+-extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
+-extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
+
+ /*
+ * String version of IO memory access ops:
+diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
+index 609d500..92ed83f 100644
+--- a/arch/ia64/kernel/sys_ia64.c
++++ b/arch/ia64/kernel/sys_ia64.c
+@@ -100,7 +100,51 @@ sys_getpagesize (void)
+ asmlinkage unsigned long
+ ia64_brk (unsigned long brk)
+ {
+- unsigned long retval = sys_brk(brk);
++ unsigned long rlim, retval, newbrk, oldbrk;
++ struct mm_struct *mm = current->mm;
++
++ /*
++ * Most of this replicates the code in sys_brk() except for an additional safety
++ * check and the clearing of r8. However, we can't call sys_brk() because we need
++ * to acquire the mmap_sem before we can do the test...
++ */
++ down_write(&mm->mmap_sem);
++
++ if (brk < mm->end_code)
++ goto out;
++ newbrk = PAGE_ALIGN(brk);
++ oldbrk = PAGE_ALIGN(mm->brk);
++ if (oldbrk == newbrk)
++ goto set_brk;
++
++ /* Always allow shrinking brk. */
++ if (brk <= mm->brk) {
++ if (!do_munmap(mm, newbrk, oldbrk-newbrk))
++ goto set_brk;
++ goto out;
++ }
++
++ /* Check against unimplemented/unmapped addresses: */
++ if ((newbrk - oldbrk) > RGN_MAP_LIMIT || REGION_OFFSET(newbrk) > RGN_MAP_LIMIT)
++ goto out;
++
++ /* Check against rlimit.. */
++ rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
++ if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
++ goto out;
++
++ /* Check against existing mmap mappings. */
++ if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
++ goto out;
++
++ /* Ok, looks good - let it rip. */
++ if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
++ goto out;
++set_brk:
++ mm->brk = brk;
++out:
++ retval = mm->brk;
++ up_write(&mm->mmap_sem);
+ force_successful_syscall_return();
+ return retval;
+ }
+@@ -141,6 +185,39 @@ int ia64_mmap_check(unsigned long addr, unsigned long len,
+ return 0;
+ }
+
++static inline unsigned long
++do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff)
++{
++ struct file *file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ return -EBADF;
++
++ if (!file->f_op || !file->f_op->mmap) {
++ addr = -ENODEV;
++ goto out;
++ }
++ }
++
++ /* Careful about overflows.. */
++ len = PAGE_ALIGN(len);
++ if (!len || len > TASK_SIZE) {
++ addr = -EINVAL;
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++out: if (file)
++ fput(file);
++ return addr;
++}
++
+ /*
+ * mmap2() is like mmap() except that the offset is expressed in units
+ * of PAGE_SIZE (instead of bytes). This allows to mmap2() (pieces
+@@ -149,7 +226,7 @@ int ia64_mmap_check(unsigned long addr, unsigned long len,
+ asmlinkage unsigned long
+ sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
+ {
+- addr = sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
++ addr = do_mmap2(addr, len, prot, flags, fd, pgoff);
+ if (!IS_ERR((void *) addr))
+ force_successful_syscall_return();
+ return addr;
+@@ -161,7 +238,7 @@ sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, lo
+ if (offset_in_page(off) != 0)
+ return -EINVAL;
+
+- addr = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
++ addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+ if (!IS_ERR((void *) addr))
+ force_successful_syscall_return();
+ return addr;
+diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c
+index 3dccdd8..2a14062 100644
+--- a/arch/ia64/mm/ioremap.c
++++ b/arch/ia64/mm/ioremap.c
+@@ -22,12 +22,6 @@ __ioremap (unsigned long phys_addr)
+ }
+
+ void __iomem *
+-early_ioremap (unsigned long phys_addr, unsigned long size)
+-{
+- return __ioremap(phys_addr);
+-}
+-
+-void __iomem *
+ ioremap (unsigned long phys_addr, unsigned long size)
+ {
+ void __iomem *addr;
+@@ -108,11 +102,6 @@ ioremap_nocache (unsigned long phys_addr, unsigned long size)
+ EXPORT_SYMBOL(ioremap_nocache);
+
+ void
+-early_iounmap (volatile void __iomem *addr, unsigned long size)
+-{
+-}
+-
+-void
+ iounmap (volatile void __iomem *addr)
+ {
+ if (REGION_NUMBER(addr) == RGN_GATE)
+diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
+index d3c865c..305ac85 100644
+--- a/arch/m32r/kernel/sys_m32r.c
++++ b/arch/m32r/kernel/sys_m32r.c
+@@ -76,6 +76,30 @@ asmlinkage int sys_tas(int __user *addr)
+ return oldval;
+ }
+
++asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ int error = -EBADF;
++ struct file *file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ /*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+diff --git a/arch/m32r/kernel/syscall_table.S b/arch/m32r/kernel/syscall_table.S
+index 60536e2..aa3bf4c 100644
+--- a/arch/m32r/kernel/syscall_table.S
++++ b/arch/m32r/kernel/syscall_table.S
+@@ -191,7 +191,7 @@ ENTRY(sys_call_table)
+ .long sys_ni_syscall /* streams2 */
+ .long sys_vfork /* 190 */
+ .long sys_getrlimit
+- .long sys_mmap_pgoff
++ .long sys_mmap2
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
+index 218f441..7deb402 100644
+--- a/arch/m68k/kernel/sys_m68k.c
++++ b/arch/m68k/kernel/sys_m68k.c
+@@ -29,16 +29,37 @@
+ #include <asm/page.h>
+ #include <asm/unistd.h>
+
++/* common code for old and new mmaps */
++static inline long do_mmap2(
++ unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ int error = -EBADF;
++ struct file * file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+ {
+- /*
+- * This is wrong for sun3 - there PAGE_SIZE is 8Kb,
+- * so we need to shift the argument down by 1; m68k mmap64(3)
+- * (in libc) expects the last argument of mmap2 in 4Kb units.
+- */
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
++ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+ }
+
+ /*
+@@ -69,11 +90,57 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+- a.offset >> PAGE_SHIFT);
++ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++out:
++ return error;
++}
++
++#if 0
++struct mmap_arg_struct64 {
++ __u32 addr;
++ __u32 len;
++ __u32 prot;
++ __u32 flags;
++ __u64 offset; /* 64 bits */
++ __u32 fd;
++};
++
++asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
++{
++ int error = -EFAULT;
++ struct file * file = NULL;
++ struct mmap_arg_struct64 a;
++ unsigned long pgoff;
++
++ if (copy_from_user(&a, arg, sizeof(a)))
++ return -EFAULT;
++
++ if ((long)a.offset & ~PAGE_MASK)
++ return -EINVAL;
++
++ pgoff = a.offset >> PAGE_SHIFT;
++ if ((a.offset >> PAGE_SHIFT) != pgoff)
++ return -EINVAL;
++
++ if (!(a.flags & MAP_ANONYMOUS)) {
++ error = -EBADF;
++ file = fget(a.fd);
++ if (!file)
++ goto out;
++ }
++ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++ if (file)
++ fput(file);
+ out:
+ return error;
+ }
++#endif
+
+ struct sel_arg_struct {
+ unsigned long n;
+diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
+index b67cbc7..efdd090 100644
+--- a/arch/m68knommu/kernel/sys_m68k.c
++++ b/arch/m68knommu/kernel/sys_m68k.c
+@@ -27,6 +27,39 @@
+ #include <asm/cacheflush.h>
+ #include <asm/unistd.h>
+
++/* common code for old and new mmaps */
++static inline long do_mmap2(
++ unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ int error = -EBADF;
++ struct file * file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
++asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ return do_mmap2(addr, len, prot, flags, fd, pgoff);
++}
++
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+@@ -55,8 +88,9 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+- a.offset >> PAGE_SHIFT);
++ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
+index 486837e..23535cc 100644
+--- a/arch/m68knommu/kernel/syscalltable.S
++++ b/arch/m68knommu/kernel/syscalltable.S
+@@ -210,7 +210,7 @@ ENTRY(sys_call_table)
+ .long sys_ni_syscall /* streams2 */
+ .long sys_vfork /* 190 */
+ .long sys_getrlimit
+- .long sys_mmap_pgoff
++ .long sys_mmap2
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
+index 9f3c205..07cabed 100644
+--- a/arch/microblaze/kernel/sys_microblaze.c
++++ b/arch/microblaze/kernel/sys_microblaze.c
+@@ -62,14 +62,46 @@ out:
+ return error;
+ }
+
++asmlinkage long
++sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ struct file *file = NULL;
++ int ret = -EBADF;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file) {
++ printk(KERN_INFO "no fd in mmap\r\n");
++ goto out;
++ }
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++ if (file)
++ fput(file);
++out:
++ return ret;
++}
++
+ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t pgoff)
+ {
+- if (pgoff & ~PAGE_MASK)
+- return -EINVAL;
++ int err = -EINVAL;
++
++ if (pgoff & ~PAGE_MASK) {
++ printk(KERN_INFO "no pagemask in mmap\r\n");
++ goto out;
++ }
+
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
++ err = sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
++out:
++ return err;
+ }
+
+ /*
+diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
+index eb50ce5..ecec191 100644
+--- a/arch/microblaze/kernel/syscall_table.S
++++ b/arch/microblaze/kernel/syscall_table.S
+@@ -196,7 +196,7 @@ ENTRY(sys_call_table)
+ .long sys_ni_syscall /* reserved for streams2 */
+ .long sys_vfork /* 190 */
+ .long sys_getrlimit
+- .long sys_mmap_pgoff /* mmap2 */
++ .long sys_mmap2 /* mmap2 */
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
+index ea4a746..b77fefa 100644
+--- a/arch/mips/kernel/linux32.c
++++ b/arch/mips/kernel/linux32.c
+@@ -67,13 +67,28 @@ SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, pgoff)
+ {
++ struct file * file = NULL;
+ unsigned long error;
+
+ error = -EINVAL;
+ if (pgoff & (~PAGE_MASK >> 12))
+ goto out;
+- error = sys_mmap_pgoff(addr, len, prot, flags, fd,
+- pgoff >> (PAGE_SHIFT-12));
++ pgoff >>= PAGE_SHIFT-12;
++
++ if (!(flags & MAP_ANONYMOUS)) {
++ error = -EBADF;
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++ if (file)
++ fput(file);
++
+ out:
+ return error;
+ }
+diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
+index 3f7f466..fe0d798 100644
+--- a/arch/mips/kernel/syscall.c
++++ b/arch/mips/kernel/syscall.c
+@@ -93,8 +93,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ * We do not accept a shared mapping if it would violate
+ * cache aliasing constraints.
+ */
+- if ((flags & MAP_SHARED) &&
+- ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
++ if ((flags & MAP_SHARED) && (addr & shm_align_mask))
+ return -EINVAL;
+ return addr;
+ }
+@@ -130,6 +129,31 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ }
+ }
+
++/* common code for old and new mmaps */
++static inline unsigned long
++do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
++ unsigned long flags, unsigned long fd, unsigned long pgoff)
++{
++ unsigned long error = -EBADF;
++ struct file * file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long,
+ fd, off_t, offset)
+@@ -140,7 +164,7 @@ SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
+ if (offset & ~PAGE_MASK)
+ goto out;
+
+- result = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++ result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+
+ out:
+ return result;
+@@ -153,7 +177,7 @@ SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len,
+ if (pgoff & (~PAGE_MASK >> 12))
+ return -EINVAL;
+
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
++ return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
+ }
+
+ save_static_function(sys_fork);
+diff --git a/arch/mn10300/include/asm/mman.h b/arch/mn10300/include/asm/mman.h
+index db5c53d..8eebf89 100644
+--- a/arch/mn10300/include/asm/mman.h
++++ b/arch/mn10300/include/asm/mman.h
+@@ -1,6 +1 @@
+ #include <asm-generic/mman.h>
+-
+-#define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */
+-
+-#define arch_mmap_check(addr, len, flags) \
+- (((flags) & MAP_FIXED && (addr) < MIN_MAP_ADDR) ? -EINVAL : 0)
+diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
+index c9ee6c0..a94e7ea 100644
+--- a/arch/mn10300/kernel/entry.S
++++ b/arch/mn10300/kernel/entry.S
+@@ -578,7 +578,7 @@ ENTRY(sys_call_table)
+ .long sys_ni_syscall /* reserved for streams2 */
+ .long sys_vfork /* 190 */
+ .long sys_getrlimit
+- .long sys_mmap_pgoff
++ .long sys_mmap2
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c
+index 17cc6ce..8ca5af0 100644
+--- a/arch/mn10300/kernel/sys_mn10300.c
++++ b/arch/mn10300/kernel/sys_mn10300.c
+@@ -23,13 +23,47 @@
+
+ #include <asm/uaccess.h>
+
++#define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */
++
++/*
++ * memory mapping syscall
++ */
++asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ struct file *file = NULL;
++ long error = -EINVAL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ if (flags & MAP_FIXED && addr < MIN_MAP_ADDR)
++ goto out;
++
++ error = -EBADF;
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ asmlinkage long old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long offset)
+ {
+ if (offset & ~PAGE_MASK)
+ return -EINVAL;
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++ return sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+ }
+
+ struct sel_arg_struct {
+diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
+index 9147391..71b3195 100644
+--- a/arch/parisc/kernel/sys_parisc.c
++++ b/arch/parisc/kernel/sys_parisc.c
+@@ -110,14 +110,37 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ return addr;
+ }
+
++static unsigned long do_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags, unsigned long fd,
++ unsigned long pgoff)
++{
++ struct file * file = NULL;
++ unsigned long error = -EBADF;
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file != NULL)
++ fput(file);
++out:
++ return error;
++}
++
+ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags, unsigned long fd,
+ unsigned long pgoff)
+ {
+ /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
+ we have. */
+- return sys_mmap_pgoff(addr, len, prot, flags, fd,
+- pgoff >> (PAGE_SHIFT - 12));
++ return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
+ }
+
+ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+@@ -125,8 +148,7 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+ unsigned long offset)
+ {
+ if (!(offset & ~PAGE_MASK)) {
+- return sys_mmap_pgoff(addr, len, prot, flags, fd,
+- offset >> PAGE_SHIFT);
++ return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+ } else {
+ return -EINVAL;
+ }
+diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
+index 5698502..014a624 100644
+--- a/arch/powerpc/include/asm/elf.h
++++ b/arch/powerpc/include/asm/elf.h
+@@ -236,10 +236,14 @@ typedef elf_vrregset_t elf_fpxregset_t;
+ #ifdef __powerpc64__
+ # define SET_PERSONALITY(ex) \
+ do { \
++ unsigned long new_flags = 0; \
+ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+- set_thread_flag(TIF_32BIT); \
++ new_flags = _TIF_32BIT; \
++ if ((current_thread_info()->flags & _TIF_32BIT) \
++ != new_flags) \
++ set_thread_flag(TIF_ABI_PENDING); \
+ else \
+- clear_thread_flag(TIF_32BIT); \
++ clear_thread_flag(TIF_ABI_PENDING); \
+ if (personality(current->personality) != PER_LINUX32) \
+ set_personality(PER_LINUX | \
+ (current->personality & (~PER_MASK))); \
+diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
+index 0192a4e..0845488 100644
+--- a/arch/powerpc/include/asm/module.h
++++ b/arch/powerpc/include/asm/module.h
+@@ -87,10 +87,5 @@ struct exception_table_entry;
+ void sort_ex_table(struct exception_table_entry *start,
+ struct exception_table_entry *finish);
+
+-#ifdef CONFIG_MODVERSIONS
+-#define ARCH_RELOCATES_KCRCTAB
+-
+-extern const unsigned long reloc_start[];
+-#endif
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_POWERPC_MODULE_H */
+diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
+index aa9d383..c8b3292 100644
+--- a/arch/powerpc/include/asm/thread_info.h
++++ b/arch/powerpc/include/asm/thread_info.h
+@@ -111,6 +111,7 @@ static inline struct thread_info *current_thread_info(void)
+ #define TIF_NOTIFY_RESUME 13 /* callback before returning to user */
+ #define TIF_FREEZE 14 /* Freezing for suspend */
+ #define TIF_RUNLATCH 15 /* Is the runlatch enabled? */
++#define TIF_ABI_PENDING 16 /* 32/64 bit switch needed */
+
+ /* as above, but as bit values */
+ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
+@@ -128,6 +129,7 @@ static inline struct thread_info *current_thread_info(void)
+ #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
+ #define _TIF_FREEZE (1<<TIF_FREEZE)
+ #define _TIF_RUNLATCH (1<<TIF_RUNLATCH)
++#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
+ #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
+
+ #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
+index f0c624f..a5b632e 100644
+--- a/arch/powerpc/kernel/align.c
++++ b/arch/powerpc/kernel/align.c
+@@ -642,14 +642,10 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
+ */
+ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
+ unsigned int areg, struct pt_regs *regs,
+- unsigned int flags, unsigned int length,
+- unsigned int elsize)
++ unsigned int flags, unsigned int length)
+ {
+ char *ptr;
+- unsigned long *lptr;
+ int ret = 0;
+- int sw = 0;
+- int i, j;
+
+ flush_vsx_to_thread(current);
+
+@@ -658,35 +654,19 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
+ else
+ ptr = (char *) ¤t->thread.vr[reg - 32];
+
+- lptr = (unsigned long *) ptr;
+-
+- if (flags & SW)
+- sw = elsize-1;
+-
+- for (j = 0; j < length; j += elsize) {
+- for (i = 0; i < elsize; ++i) {
+- if (flags & ST)
+- ret |= __put_user(ptr[i^sw], addr + i);
+- else
+- ret |= __get_user(ptr[i^sw], addr + i);
++ if (flags & ST)
++ ret = __copy_to_user(addr, ptr, length);
++ else {
++ if (flags & SPLT){
++ ret = __copy_from_user(ptr, addr, length);
++ ptr += length;
+ }
+- ptr += elsize;
+- addr += elsize;
++ ret |= __copy_from_user(ptr, addr, length);
+ }
+-
+- if (!ret) {
+- if (flags & U)
+- regs->gpr[areg] = regs->dar;
+-
+- /* Splat load copies the same data to top and bottom 8 bytes */
+- if (flags & SPLT)
+- lptr[1] = lptr[0];
+- /* For 8 byte loads, zero the top 8 bytes */
+- else if (!(flags & ST) && (8 == length))
+- lptr[1] = 0;
+- } else
++ if (flags & U)
++ regs->gpr[areg] = regs->dar;
++ if (ret)
+ return -EFAULT;
+-
+ return 1;
+ }
+ #endif
+@@ -787,25 +767,16 @@ int fix_alignment(struct pt_regs *regs)
+
+ #ifdef CONFIG_VSX
+ if ((instruction & 0xfc00003e) == 0x7c000018) {
+- unsigned int elsize;
+-
+- /* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */
++ /* Additional register addressing bit (64 VSX vs 32 FPR/GPR */
+ reg |= (instruction & 0x1) << 5;
+ /* Simple inline decoder instead of a table */
+- /* VSX has only 8 and 16 byte memory accesses */
+- nb = 8;
+ if (instruction & 0x200)
+ nb = 16;
+-
+- /* Vector stores in little-endian mode swap individual
+- elements, so process them separately */
+- elsize = 4;
+- if (instruction & 0x80)
+- elsize = 8;
+-
++ else if (instruction & 0x080)
++ nb = 8;
++ else
++ nb = 4;
+ flags = 0;
+- if (regs->msr & MSR_LE)
+- flags |= SW;
+ if (instruction & 0x100)
+ flags |= ST;
+ if (instruction & 0x040)
+@@ -816,7 +787,7 @@ int fix_alignment(struct pt_regs *regs)
+ nb = 8;
+ }
+ PPC_WARN_EMULATED(vsx);
+- return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize);
++ return emulate_vsx(addr, reg, areg, regs, flags, nb);
+ }
+ #endif
+ /* A size of 0 indicates an instruction we don't support, with
+diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
+index cadbed6..e8dfdbd 100644
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -1107,12 +1107,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ struct dev_archdata *sd = &dev->dev.archdata;
+
+- /* Cardbus can call us to add new devices to a bus, so ignore
+- * those who are already fully discovered
+- */
+- if (dev->is_added)
+- continue;
+-
+ /* Setup OF node pointer in archdata */
+ sd->of_node = pci_device_to_OF_node(dev);
+
+@@ -1153,13 +1147,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+ }
+ EXPORT_SYMBOL(pcibios_fixup_bus);
+
+-void __devinit pci_fixup_cardbus(struct pci_bus *bus)
+-{
+- /* Now fixup devices on that bus */
+- pcibios_setup_bus_devices(bus);
+-}
+-
+-
+ static int skip_isa_ioresource_align(struct pci_dev *dev)
+ {
+ if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
+diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
+index 7b816da..c930ac3 100644
+--- a/arch/powerpc/kernel/process.c
++++ b/arch/powerpc/kernel/process.c
+@@ -554,6 +554,18 @@ void exit_thread(void)
+
+ void flush_thread(void)
+ {
++#ifdef CONFIG_PPC64
++ struct thread_info *t = current_thread_info();
++
++ if (test_ti_thread_flag(t, TIF_ABI_PENDING)) {
++ clear_ti_thread_flag(t, TIF_ABI_PENDING);
++ if (test_ti_thread_flag(t, TIF_32BIT))
++ clear_ti_thread_flag(t, TIF_32BIT);
++ else
++ set_ti_thread_flag(t, TIF_32BIT);
++ }
++#endif
++
+ discard_lazy_cpu_state();
+
+ if (current->thread.dabr) {
+diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
+index 3370e62..c04832c 100644
+--- a/arch/powerpc/kernel/syscalls.c
++++ b/arch/powerpc/kernel/syscalls.c
+@@ -140,6 +140,7 @@ static inline unsigned long do_mmap2(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long off, int shift)
+ {
++ struct file * file = NULL;
+ unsigned long ret = -EINVAL;
+
+ if (!arch_validate_prot(prot))
+@@ -150,8 +151,20 @@ static inline unsigned long do_mmap2(unsigned long addr, size_t len,
+ goto out;
+ off >>= shift;
+ }
++
++ ret = -EBADF;
++ if (!(flags & MAP_ANONYMOUS)) {
++ if (!(file = fget(fd)))
++ goto out;
++ }
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+- ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off);
++ down_write(¤t->mm->mmap_sem);
++ ret = do_mmap_pgoff(file, addr, len, prot, flags, off);
++ up_write(¤t->mm->mmap_sem);
++ if (file)
++ fput(file);
+ out:
+ return ret;
+ }
+diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
+index fe46048..67b6916 100644
+--- a/arch/powerpc/kernel/vector.S
++++ b/arch/powerpc/kernel/vector.S
+@@ -58,7 +58,7 @@ _GLOBAL(load_up_altivec)
+ * all 1's
+ */
+ mfspr r4,SPRN_VRSAVE
+- cmpwi 0,r4,0
++ cmpdi 0,r4,0
+ bne+ 1f
+ li r4,-1
+ mtspr SPRN_VRSAVE,r4
+diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
+index dcd01c8..27735a7 100644
+--- a/arch/powerpc/kernel/vmlinux.lds.S
++++ b/arch/powerpc/kernel/vmlinux.lds.S
+@@ -38,9 +38,6 @@ jiffies = jiffies_64 + 4;
+ #endif
+ SECTIONS
+ {
+- . = 0;
+- reloc_start = .;
+-
+ . = KERNELBASE;
+
+ /*
+diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
+index e82749b..ae88b14 100644
+--- a/arch/powerpc/sysdev/fsl_pci.c
++++ b/arch/powerpc/sysdev/fsl_pci.c
+@@ -392,22 +392,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header);
+ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header);
+ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
+ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1011E, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1011, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013E, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020E, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022E, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010, quirk_fsl_pcie_header);
+ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020E, quirk_fsl_pcie_header);
+ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040E, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080E, quirk_fsl_pcie_header);
+-DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080, quirk_fsl_pcie_header);
+ #endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */
+
+ #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
+diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h
+index 82b32a1..3dfcaeb 100644
+--- a/arch/s390/include/asm/kvm.h
++++ b/arch/s390/include/asm/kvm.h
+@@ -1,5 +1,6 @@
+ #ifndef __LINUX_KVM_S390_H
+ #define __LINUX_KVM_S390_H
++
+ /*
+ * asm-s390/kvm.h - KVM s390 specific structures and definitions
+ *
+@@ -14,8 +15,6 @@
+ */
+ #include <linux/types.h>
+
+-#define __KVM_S390
+-
+ /* for KVM_GET_REGS and KVM_SET_REGS */
+ struct kvm_regs {
+ /* general purpose regs for s390 */
+diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
+index 9c746c0..0debcec 100644
+--- a/arch/s390/kernel/compat_linux.c
++++ b/arch/s390/kernel/compat_linux.c
+@@ -683,6 +683,38 @@ struct mmap_arg_struct_emu31 {
+ u32 offset;
+ };
+
++/* common code for old and new mmaps */
++static inline long do_mmap2(
++ unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ struct file * file = NULL;
++ unsigned long error = -EBADF;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) {
++ /* Result is out of bounds. */
++ do_munmap(current->mm, addr, len);
++ error = -ENOMEM;
++ }
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
++
+ asmlinkage unsigned long
+ old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
+ {
+@@ -696,8 +728,7 @@ old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+- a.offset >> PAGE_SHIFT);
++ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+@@ -710,7 +741,7 @@ sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ goto out;
+- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
++ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
+ out:
+ return error;
+ }
+diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
+index e8ef21c..48215d1 100644
+--- a/arch/s390/kernel/entry.S
++++ b/arch/s390/kernel/entry.S
+@@ -571,7 +571,6 @@ pgm_svcper:
+ mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
+ oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+ TRACE_IRQS_ON
+- lm %r2,%r6,SP_R2(%r15) # load svc arguments
+ stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
+ b BASED(sysc_do_svc)
+
+diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
+index f33658f..9aff1d4 100644
+--- a/arch/s390/kernel/entry64.S
++++ b/arch/s390/kernel/entry64.S
+@@ -549,7 +549,6 @@ pgm_svcper:
+ mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
+ oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+ TRACE_IRQS_ON
+- lmg %r2,%r6,SP_R2(%r15) # load svc arguments
+ stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
+ j sysc_do_svc
+
+diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
+index d984a2a..6a25080 100644
+--- a/arch/s390/kernel/head64.S
++++ b/arch/s390/kernel/head64.S
+@@ -83,8 +83,6 @@ startup_continue:
+ slr %r0,%r0 # set cpuid to zero
+ sigp %r1,%r0,0x12 # switch to esame mode
+ sam64 # switch to 64 bit mode
+- llgfr %r13,%r13 # clear high-order half of base reg
+- lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half
+ lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
+ lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
+ # move IPL device to lowcore
+@@ -129,7 +127,6 @@ startup_continue:
+ .L4malign:.quad 0xffffffffffc00000
+ .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
+ .Lnop: .long 0x07000700
+-.Lzero64:.fill 16,4,0x0
+ #ifdef CONFIG_ZFCPDUMP
+ .Lcurrent_cpu:
+ .long 0x0
+diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
+index 86a74c9..e9d94f6 100644
+--- a/arch/s390/kernel/sys_s390.c
++++ b/arch/s390/kernel/sys_s390.c
+@@ -32,6 +32,32 @@
+ #include <asm/uaccess.h>
+ #include "entry.h"
+
++/* common code for old and new mmaps */
++static inline long do_mmap2(
++ unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ long error = -EBADF;
++ struct file * file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux for S/390 isn't able to handle more than 5
+@@ -55,7 +81,7 @@ SYSCALL_DEFINE1(mmap2, struct mmap_arg_struct __user *, arg)
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ goto out;
+- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
++ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
+ out:
+ return error;
+ }
+@@ -72,7 +98,7 @@ SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct __user *, arg)
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
++ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+ out:
+ return error;
+ }
+diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
+index b400964..ba9d8a7 100644
+--- a/arch/s390/kvm/intercept.c
++++ b/arch/s390/kvm/intercept.c
+@@ -213,7 +213,7 @@ static int handle_instruction_and_prog(struct kvm_vcpu *vcpu)
+ return rc2;
+ }
+
+-static const intercept_handler_t intercept_funcs[] = {
++static const intercept_handler_t intercept_funcs[0x48 >> 2] = {
+ [0x00 >> 2] = handle_noop,
+ [0x04 >> 2] = handle_instruction,
+ [0x08 >> 2] = handle_prog,
+@@ -230,7 +230,7 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
+ intercept_handler_t func;
+ u8 code = vcpu->arch.sie_block->icptcode;
+
+- if (code & 3 || (code >> 2) >= ARRAY_SIZE(intercept_funcs))
++ if (code & 3 || code > 0x48)
+ return -ENOTSUPP;
+ func = intercept_funcs[code >> 2];
+ if (func)
+diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
+index ca2d312..07ced89 100644
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -116,16 +116,10 @@ long kvm_arch_dev_ioctl(struct file *filp,
+
+ int kvm_dev_ioctl_check_extension(long ext)
+ {
+- int r;
+-
+ switch (ext) {
+- case KVM_CAP_S390_PSW:
+- r = 1;
+- break;
+ default:
+- r = 0;
++ return 0;
+ }
+- return r;
+ }
+
+ /* Section: vm related */
+@@ -425,10 +419,8 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
+ vcpu_load(vcpu);
+ if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
+ rc = -EBUSY;
+- else {
+- vcpu->run->psw_mask = psw.mask;
+- vcpu->run->psw_addr = psw.addr;
+- }
++ else
++ vcpu->arch.sie_block->gpsw = psw;
+ vcpu_put(vcpu);
+ return rc;
+ }
+@@ -516,6 +508,9 @@ rerun_vcpu:
+
+ switch (kvm_run->exit_reason) {
+ case KVM_EXIT_S390_SIEIC:
++ vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask;
++ vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
++ break;
+ case KVM_EXIT_UNKNOWN:
+ case KVM_EXIT_INTR:
+ case KVM_EXIT_S390_RESET:
+@@ -524,9 +519,6 @@ rerun_vcpu:
+ BUG();
+ }
+
+- vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
+- vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
+-
+ might_fault();
+
+ do {
+@@ -546,6 +538,8 @@ rerun_vcpu:
+ /* intercept cannot be handled in-kernel, prepare kvm-run */
+ kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
+ kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
++ kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask;
++ kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr;
+ kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
+ kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
+ rc = 0;
+@@ -557,9 +551,6 @@ rerun_vcpu:
+ rc = 0;
+ }
+
+- kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
+- kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
+-
+ if (vcpu->sigset_active)
+ sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+
+diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
+index 15ee111..40c8c67 100644
+--- a/arch/s390/kvm/sigp.c
++++ b/arch/s390/kvm/sigp.c
+@@ -188,9 +188,9 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
+
+ /* make sure that the new value is valid memory */
+ address = address & 0x7fffe000u;
+- if ((copy_from_user(&tmp, (void __user *)
+- (address + vcpu->arch.sie_block->gmsor) , 1)) ||
+- (copy_from_user(&tmp, (void __user *)(address +
++ if ((copy_from_guest(vcpu, &tmp,
++ (u64) (address + vcpu->arch.sie_block->gmsor) , 1)) ||
++ (copy_from_guest(vcpu, &tmp, (u64) (address +
+ vcpu->arch.sie_block->gmsor + PAGE_SIZE), 1))) {
+ *reg |= SIGP_STAT_INVALID_PARAMETER;
+ return 1; /* invalid parameter */
+diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c
+index 856ed68..0012494 100644
+--- a/arch/score/kernel/sys_score.c
++++ b/arch/score/kernel/sys_score.c
+@@ -36,16 +36,34 @@ asmlinkage long
+ sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, unsigned long fd, unsigned long pgoff)
+ {
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
++ int error = -EBADF;
++ struct file *file = NULL;
++
++ if (pgoff & (~PAGE_MASK >> 12))
++ return -EINVAL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ return error;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++
++ return error;
+ }
+
+ asmlinkage long
+ sys_mmap(unsigned long addr, unsigned long len, unsigned long prot,
+- unsigned long flags, unsigned long fd, off_t offset)
++ unsigned long flags, unsigned long fd, off_t pgoff)
+ {
+- if (unlikely(offset & ~PAGE_MASK))
+- return -EINVAL;
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++ return sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
+ }
+
+ asmlinkage long
+diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h
+index ba64e7f..c0d359c 100644
+--- a/arch/sh/include/asm/pgtable_32.h
++++ b/arch/sh/include/asm/pgtable_32.h
+@@ -344,8 +344,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
+ #define pte_special(pte) ((pte).pte_low & _PAGE_SPECIAL)
+
+ #ifdef CONFIG_X2TLB
+-#define pte_write(pte) \
+- ((pte).pte_high & (_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE))
++#define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE)
+ #else
+ #define pte_write(pte) ((pte).pte_low & _PAGE_RW)
+ #endif
+@@ -359,7 +358,7 @@ static inline pte_t pte_##fn(pte_t pte) { pte.pte_##h op; return pte; }
+ * individually toggled (and user permissions are entirely decoupled from
+ * kernel permissions), we attempt to couple them a bit more sanely here.
+ */
+-PTE_BIT_FUNC(high, wrprotect, &= ~(_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE));
++PTE_BIT_FUNC(high, wrprotect, &= ~_PAGE_EXT_USER_WRITE);
+ PTE_BIT_FUNC(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE);
+ PTE_BIT_FUNC(high, mkhuge, |= _PAGE_SZHUGE);
+ #else
+diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
+index 44aa119..1192398 100644
+--- a/arch/sh/kernel/process_64.c
++++ b/arch/sh/kernel/process_64.c
+@@ -367,7 +367,7 @@ void exit_thread(void)
+ void flush_thread(void)
+ {
+
+- /* Called by fs/exec.c (setup_new_exec) to remove traces of a
++ /* Called by fs/exec.c (flush_old_exec) to remove traces of a
+ * previously running executable. */
+ #ifdef CONFIG_SH_FPU
+ if (last_task_used_math == current) {
+diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
+index 71399cd..8aa5d1c 100644
+--- a/arch/sh/kernel/sys_sh.c
++++ b/arch/sh/kernel/sys_sh.c
+@@ -28,13 +28,37 @@
+ #include <asm/cacheflush.h>
+ #include <asm/cachectl.h>
+
++static inline long
++do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
++ unsigned long flags, int fd, unsigned long pgoff)
++{
++ int error = -EBADF;
++ struct file *file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ asmlinkage int old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ int fd, unsigned long off)
+ {
+ if (off & ~PAGE_MASK)
+ return -EINVAL;
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
++ return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
+ }
+
+ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+@@ -50,7 +74,7 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+
+ pgoff >>= PAGE_SHIFT - 12;
+
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
++ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+ }
+
+ /*
+diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
+index afeb710..d2984fa 100644
+--- a/arch/sh/mm/mmap.c
++++ b/arch/sh/mm/mmap.c
+@@ -54,8 +54,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ /* We do not accept a shared mapping if it would violate
+ * cache aliasing constraints.
+ */
+- if ((flags & MAP_SHARED) &&
+- ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
++ if ((flags & MAP_SHARED) && (addr & shm_align_mask))
+ return -EINVAL;
+ return addr;
+ }
+diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
+index 113225b..dfe272d 100644
+--- a/arch/sparc/Makefile
++++ b/arch/sparc/Makefile
+@@ -27,7 +27,6 @@ AS := $(AS) -32
+ LDFLAGS := -m elf32_sparc
+ CHECKFLAGS += -D__sparc__
+ export BITS := 32
+-UTS_MACHINE := sparc
+
+ #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
+ KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
+@@ -47,7 +46,6 @@ CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64
+
+ LDFLAGS := -m elf64_sparc
+ export BITS := 64
+-UTS_MACHINE := sparc64
+
+ KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \
+ -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \
+diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
+index 9968085..d42e393 100644
+--- a/arch/sparc/include/asm/elf_64.h
++++ b/arch/sparc/include/asm/elf_64.h
+@@ -196,10 +196,17 @@ static inline unsigned int sparc64_elf_hwcap(void)
+ #define ELF_PLATFORM (NULL)
+
+ #define SET_PERSONALITY(ex) \
+-do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+- set_thread_flag(TIF_32BIT); \
++do { unsigned long new_flags = current_thread_info()->flags; \
++ new_flags &= _TIF_32BIT; \
++ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
++ new_flags |= _TIF_32BIT; \
+ else \
+- clear_thread_flag(TIF_32BIT); \
++ new_flags &= ~_TIF_32BIT; \
++ if ((current_thread_info()->flags & _TIF_32BIT) \
++ != new_flags) \
++ set_thread_flag(TIF_ABI_PENDING); \
++ else \
++ clear_thread_flag(TIF_ABI_PENDING); \
+ /* flush_thread will update pgd cache */ \
+ if (personality(current->personality) != PER_LINUX32) \
+ set_personality(PER_LINUX | \
+diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
+index f78ad9a..1b45a7b 100644
+--- a/arch/sparc/include/asm/thread_info_64.h
++++ b/arch/sparc/include/asm/thread_info_64.h
+@@ -227,11 +227,12 @@ register struct thread_info *current_thread_info_reg asm("g6");
+ /* flag bit 8 is available */
+ #define TIF_SECCOMP 9 /* secure computing */
+ #define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */
++/* flag bit 11 is available */
+ /* NOTE: Thread flags >= 12 should be ones we have no interest
+ * in using in assembly, else we can't use the mask as
+ * an immediate value in instructions such as andcc.
+ */
+-/* flag bit 12 is available */
++#define TIF_ABI_PENDING 12
+ #define TIF_MEMDIE 13
+ #define TIF_POLLING_NRFLAG 14
+ #define TIF_FREEZE 15 /* is freezing for suspend */
+@@ -245,6 +246,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
+ #define _TIF_32BIT (1<<TIF_32BIT)
+ #define _TIF_SECCOMP (1<<TIF_SECCOMP)
+ #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
++#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
+ #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+ #define _TIF_FREEZE (1<<TIF_FREEZE)
+
+diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
+index e0ba898..cb3c72c 100644
+--- a/arch/sparc/kernel/ldc.c
++++ b/arch/sparc/kernel/ldc.c
+@@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name)
+ snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
+
+ err = request_irq(lp->cfg.rx_irq, ldc_rx,
+- IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
++ IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
+ lp->rx_irq_name, lp);
+ if (err)
+ return err;
+
+ err = request_irq(lp->cfg.tx_irq, ldc_tx,
+- IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
++ IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
+ lp->tx_irq_name, lp);
+ if (err) {
+ free_irq(lp->cfg.rx_irq, lp);
+diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
+index 4771274..b129611 100644
+--- a/arch/sparc/kernel/nmi.c
++++ b/arch/sparc/kernel/nmi.c
+@@ -96,6 +96,7 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
+ int cpu = smp_processor_id();
+
+ clear_softint(1 << irq);
++ pcr_ops->write(PCR_PIC_PRIV);
+
+ local_cpu_data().__nmi_count++;
+
+@@ -104,8 +105,6 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
+ if (notify_die(DIE_NMI, "nmi", regs, 0,
+ pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
+ touched = 1;
+- else
+- pcr_ops->write(PCR_PIC_PRIV);
+
+ sum = kstat_irqs_cpu(0, cpu);
+ if (__get_cpu_var(nmi_touch)) {
+diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
+index 0a6f2d1..881947e 100644
+--- a/arch/sparc/kernel/of_device_64.c
++++ b/arch/sparc/kernel/of_device_64.c
+@@ -104,19 +104,9 @@ static int of_bus_pci_map(u32 *addr, const u32 *range,
+ int i;
+
+ /* Check address type match */
+- if (!((addr[0] ^ range[0]) & 0x03000000))
+- goto type_match;
+-
+- /* Special exception, we can map a 64-bit address into
+- * a 32-bit range.
+- */
+- if ((addr[0] & 0x03000000) == 0x03000000 &&
+- (range[0] & 0x03000000) == 0x02000000)
+- goto type_match;
+-
+- return -EINVAL;
++ if ((addr[0] ^ range[0]) & 0x03000000)
++ return -EINVAL;
+
+-type_match:
+ if (of_out_of_range(addr + 1, range + 1, range + na + pna,
+ na - 1, ns))
+ return -EINVAL;
+diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
+index 198fb4e..fa5936e 100644
+--- a/arch/sparc/kernel/perf_event.c
++++ b/arch/sparc/kernel/perf_event.c
+@@ -986,17 +986,6 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
+ data.addr = 0;
+
+ cpuc = &__get_cpu_var(cpu_hw_events);
+-
+- /* If the PMU has the TOE IRQ enable bits, we need to do a
+- * dummy write to the %pcr to clear the overflow bits and thus
+- * the interrupt.
+- *
+- * Do this before we peek at the counters to determine
+- * overflow so we don't lose any events.
+- */
+- if (sparc_pmu->irq_bit)
+- pcr_ops->write(cpuc->pcr);
+-
+ for (idx = 0; idx < MAX_HWEVENTS; idx++) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
+index c3f1cce..18d6785 100644
+--- a/arch/sparc/kernel/process_64.c
++++ b/arch/sparc/kernel/process_64.c
+@@ -365,6 +365,14 @@ void flush_thread(void)
+ struct thread_info *t = current_thread_info();
+ struct mm_struct *mm;
+
++ if (test_ti_thread_flag(t, TIF_ABI_PENDING)) {
++ clear_ti_thread_flag(t, TIF_ABI_PENDING);
++ if (test_ti_thread_flag(t, TIF_32BIT))
++ clear_ti_thread_flag(t, TIF_32BIT);
++ else
++ set_ti_thread_flag(t, TIF_32BIT);
++ }
++
+ mm = t->task->mm;
+ if (mm)
+ tsb_context_switch(mm);
+diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
+index 3a82e65..03035c8 100644
+--- a/arch/sparc/kernel/sys_sparc_32.c
++++ b/arch/sparc/kernel/sys_sparc_32.c
+@@ -45,8 +45,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ /* We do not accept a shared mapping if it would violate
+ * cache aliasing constraints.
+ */
+- if ((flags & MAP_SHARED) &&
+- ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
++ if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
+ return -EINVAL;
+ return addr;
+ }
+@@ -80,6 +79,15 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ }
+ }
+
++asmlinkage unsigned long sparc_brk(unsigned long brk)
++{
++ if(ARCH_SUN4C) {
++ if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000))
++ return current->mm->brk;
++ }
++ return sys_brk(brk);
++}
++
+ /*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+@@ -226,6 +234,31 @@ int sparc_mmap_check(unsigned long addr, unsigned long len)
+ }
+
+ /* Linux version of mmap */
++static unsigned long do_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags, unsigned long fd,
++ unsigned long pgoff)
++{
++ struct file * file = NULL;
++ unsigned long retval = -EBADF;
++
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ len = PAGE_ALIGN(len);
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ down_write(¤t->mm->mmap_sem);
++ retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return retval;
++}
+
+ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags, unsigned long fd,
+@@ -233,16 +266,14 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
+ {
+ /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
+ we have. */
+- return sys_mmap_pgoff(addr, len, prot, flags, fd,
+- pgoff >> (PAGE_SHIFT - 12));
++ return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
+ }
+
+ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags, unsigned long fd,
+ unsigned long off)
+ {
+- /* no alignment check? */
+- return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
++ return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+ }
+
+ long sparc_remap_file_pages(unsigned long start, unsigned long size,
+@@ -256,6 +287,27 @@ long sparc_remap_file_pages(unsigned long start, unsigned long size,
+ (pgoff >> (PAGE_SHIFT - 12)), flags);
+ }
+
++extern unsigned long do_mremap(unsigned long addr,
++ unsigned long old_len, unsigned long new_len,
++ unsigned long flags, unsigned long new_addr);
++
++asmlinkage unsigned long sparc_mremap(unsigned long addr,
++ unsigned long old_len, unsigned long new_len,
++ unsigned long flags, unsigned long new_addr)
++{
++ unsigned long ret = -EINVAL;
++
++ if (unlikely(sparc_mmap_check(addr, old_len)))
++ goto out;
++ if (unlikely(sparc_mmap_check(new_addr, new_len)))
++ goto out;
++ down_write(¤t->mm->mmap_sem);
++ ret = do_mremap(addr, old_len, new_len, flags, new_addr);
++ up_write(¤t->mm->mmap_sem);
++out:
++ return ret;
++}
++
+ /* we come to here via sys_nis_syscall so it can setup the regs argument */
+ asmlinkage unsigned long
+ c_sys_nis_syscall (struct pt_regs *regs)
+diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
+index cfa0e19..e2d1024 100644
+--- a/arch/sparc/kernel/sys_sparc_64.c
++++ b/arch/sparc/kernel/sys_sparc_64.c
+@@ -317,14 +317,10 @@ bottomup:
+ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+ {
+ unsigned long align_goal, addr = -ENOMEM;
+- unsigned long (*get_area)(struct file *, unsigned long,
+- unsigned long, unsigned long, unsigned long);
+-
+- get_area = current->mm->get_unmapped_area;
+
+ if (flags & MAP_FIXED) {
+ /* Ok, don't mess with it. */
+- return get_area(NULL, orig_addr, len, pgoff, flags);
++ return get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
+ }
+ flags &= ~MAP_SHARED;
+
+@@ -337,7 +333,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
+ align_goal = (64UL * 1024);
+
+ do {
+- addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
++ addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
+ if (!(addr & ~PAGE_MASK)) {
+ addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
+ break;
+@@ -355,7 +351,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
+ * be obtained.
+ */
+ if (addr & ~PAGE_MASK)
+- addr = get_area(NULL, orig_addr, len, pgoff, flags);
++ addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
+
+ return addr;
+ }
+@@ -403,6 +399,18 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ }
+ }
+
++SYSCALL_DEFINE1(sparc_brk, unsigned long, brk)
++{
++ /* People could try to be nasty and use ta 0x6d in 32bit programs */
++ if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32)
++ return current->mm->brk;
++
++ if (unlikely(straddles_64bit_va_hole(current->mm->brk, brk)))
++ return current->mm->brk;
++
++ return sys_brk(brk);
++}
++
+ /*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+@@ -560,13 +568,23 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, off)
+ {
+- unsigned long retval = -EINVAL;
++ struct file * file = NULL;
++ unsigned long retval = -EBADF;
+
+- if ((off + PAGE_ALIGN(len)) < off)
+- goto out;
+- if (off & ~PAGE_MASK)
+- goto out;
+- retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ len = PAGE_ALIGN(len);
++
++ down_write(¤t->mm->mmap_sem);
++ retval = do_mmap(file, addr, len, prot, flags, off);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
+ out:
+ return retval;
+ }
+@@ -596,6 +614,12 @@ SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len,
+
+ if (test_thread_flag(TIF_32BIT))
+ goto out;
++ if (unlikely(new_len >= VA_EXCLUDE_START))
++ goto out;
++ if (unlikely(sparc_mmap_check(addr, old_len)))
++ goto out;
++ if (unlikely(sparc_mmap_check(new_addr, new_len)))
++ goto out;
+
+ down_write(¤t->mm->mmap_sem);
+ ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h
+index d2f999a..a63c5d2 100644
+--- a/arch/sparc/kernel/systbls.h
++++ b/arch/sparc/kernel/systbls.h
+@@ -9,6 +9,7 @@
+ struct new_utsname;
+
+ extern asmlinkage unsigned long sys_getpagesize(void);
++extern asmlinkage unsigned long sparc_brk(unsigned long brk);
+ extern asmlinkage long sparc_pipe(struct pt_regs *regs);
+ extern asmlinkage long sys_ipc(unsigned int call, int first,
+ unsigned long second,
+diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
+index 14f950a..0f1658d 100644
+--- a/arch/sparc/kernel/systbls_32.S
++++ b/arch/sparc/kernel/systbls_32.S
+@@ -19,7 +19,7 @@ sys_call_table:
+ /*0*/ .long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write
+ /*5*/ .long sys_open, sys_close, sys_wait4, sys_creat, sys_link
+ /*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod
+-/*15*/ .long sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys_lseek
++/*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek
+ /*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
+ /*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause
+ /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice
+@@ -67,7 +67,7 @@ sys_call_table:
+ /*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
+ /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
+ /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
+-/*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
++/*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
+ /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
+ /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
+ /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
+diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
+index f63c871..009825f 100644
+--- a/arch/sparc/kernel/systbls_64.S
++++ b/arch/sparc/kernel/systbls_64.S
+@@ -21,7 +21,7 @@ sys_call_table32:
+ /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write
+ /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link
+ /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod
+-/*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys32_perfctr, sys32_lseek
++/*15*/ .word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek
+ /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
+ /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause
+ /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
+@@ -96,7 +96,7 @@ sys_call_table:
+ /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
+ /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link
+ /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod
+-/*15*/ .word sys_chmod, sys_lchown, sys_brk, sys_perfctr, sys_lseek
++/*15*/ .word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek
+ /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
+ /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall
+ /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
+diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S
+index 24b8b12..7ce9c65 100644
+--- a/arch/sparc/lib/mcount.S
++++ b/arch/sparc/lib/mcount.S
+@@ -64,9 +64,8 @@ mcount:
+ 2: sethi %hi(softirq_stack), %g3
+ or %g3, %lo(softirq_stack), %g3
+ ldx [%g3 + %g1], %g7
+- sub %g7, STACK_BIAS, %g7
+ cmp %sp, %g7
+- bleu,pt %xcc, 3f
++ bleu,pt %xcc, 2f
+ sethi %hi(THREAD_SIZE), %g3
+ add %g7, %g3, %g7
+ cmp %sp, %g7
+@@ -76,7 +75,7 @@ mcount:
+ * again, we are already trying to output the stack overflow
+ * message.
+ */
+-3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough
++ sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough
+ or %g7, %lo(ovstack), %g7
+ add %g7, OVSTACKSIZE, %g3
+ sub %g3, STACK_BIAS + 192, %g3
+diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
+index cccab85..a4625c7 100644
+--- a/arch/um/kernel/syscall.c
++++ b/arch/um/kernel/syscall.c
+@@ -8,7 +8,6 @@
+ #include "linux/mm.h"
+ #include "linux/sched.h"
+ #include "linux/utsname.h"
+-#include "linux/syscalls.h"
+ #include "asm/current.h"
+ #include "asm/mman.h"
+ #include "asm/uaccess.h"
+@@ -38,6 +37,31 @@ long sys_vfork(void)
+ return ret;
+ }
+
++/* common code for old and new mmaps */
++long sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ long error = -EBADF;
++ struct file * file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++ out:
++ return error;
++}
++
+ long old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long offset)
+@@ -46,7 +70,7 @@ long old_mmap(unsigned long addr, unsigned long len,
+ if (offset & ~PAGE_MASK)
+ goto out;
+
+- err = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++ err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+ out:
+ return err;
+ }
+diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/um/sys-i386/shared/sysdep/syscalls.h
+index e778767..9056981 100644
+--- a/arch/um/sys-i386/shared/sysdep/syscalls.h
++++ b/arch/um/sys-i386/shared/sysdep/syscalls.h
+@@ -20,3 +20,7 @@ extern syscall_handler_t *sys_call_table[];
+ #define EXECUTE_SYSCALL(syscall, regs) \
+ ((long (*)(struct syscall_args)) \
+ (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs))
++
++extern long sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff);
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 4fdb669..72ace95 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -984,6 +984,12 @@ config X86_CPUID
+ with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
+ /dev/cpu/31/cpuid.
+
++config X86_CPU_DEBUG
++ tristate "/sys/kernel/debug/x86/cpu/* - CPU Debug support"
++ ---help---
++ If you select this option, this will provide various x86 CPUs
++ information through debugfs.
++
+ choice
+ prompt "High Memory Support"
+ default HIGHMEM4G if !X86_NUMAQ
+diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
+index f2824fb..2649840 100644
+--- a/arch/x86/Kconfig.cpu
++++ b/arch/x86/Kconfig.cpu
+@@ -400,7 +400,7 @@ config X86_TSC
+
+ config X86_CMPXCHG64
+ def_bool y
+- depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM
++ depends on !M386 && !M486
+
+ # this should be set for all -march=.. options where the compiler
+ # generates cmov.
+diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
+index 1937226..30e9a26 100644
+--- a/arch/x86/Makefile_32.cpu
++++ b/arch/x86/Makefile_32.cpu
+@@ -46,13 +46,6 @@ cflags-$(CONFIG_MGEODEGX1) += -march=pentium-mmx
+ # cpu entries
+ cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686))
+
+-# Work around the pentium-mmx code generator madness of gcc4.4.x which
+-# does stack alignment by generating horrible code _before_ the mcount
+-# prologue (push %ebp, mov %esp, %ebp) which breaks the function graph
+-# tracer assumptions. For i686, generic, core2 this is set by the
+-# compiler anyway
+-cflags-$(CONFIG_FUNCTION_GRAPH_TRACER) += $(call cc-option,-maccumulate-outgoing-args)
+-
+ # Bug fix for binutils: this option is required in order to keep
+ # binutils from generating NOPL instructions against our will.
+ ifneq ($(CONFIG_X86_P6_NOP),y)
+diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
+index f9f4724..2a4d073 100644
+--- a/arch/x86/ia32/ia32_aout.c
++++ b/arch/x86/ia32/ia32_aout.c
+@@ -308,16 +308,15 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+ if (retval)
+ return retval;
+
+- /* OK, This is the point of no return */
+- set_personality(PER_LINUX);
+- set_thread_flag(TIF_IA32);
+-
+- setup_new_exec(bprm);
+-
+ regs->cs = __USER32_CS;
+ regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
+ regs->r13 = regs->r14 = regs->r15 = 0;
+
++ /* OK, This is the point of no return */
++ set_personality(PER_LINUX);
++ set_thread_flag(TIF_IA32);
++ clear_thread_flag(TIF_ABI_PENDING);
++
+ current->mm->end_code = ex.a_text +
+ (current->mm->start_code = N_TXTADDR(ex));
+ current->mm->end_data = ex.a_data +
+diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
+index 5294d84..581b056 100644
+--- a/arch/x86/ia32/ia32entry.S
++++ b/arch/x86/ia32/ia32entry.S
+@@ -696,7 +696,7 @@ ia32_sys_call_table:
+ .quad quiet_ni_syscall /* streams2 */
+ .quad stub32_vfork /* 190 */
+ .quad compat_sys_getrlimit
+- .quad sys_mmap_pgoff
++ .quad sys32_mmap2
+ .quad sys32_truncate64
+ .quad sys32_ftruncate64
+ .quad sys32_stat64 /* 195 */
+diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
+index 016218c..9f55271 100644
+--- a/arch/x86/ia32/sys_ia32.c
++++ b/arch/x86/ia32/sys_ia32.c
+@@ -155,6 +155,9 @@ struct mmap_arg_struct {
+ asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg)
+ {
+ struct mmap_arg_struct a;
++ struct file *file = NULL;
++ unsigned long retval;
++ struct mm_struct *mm ;
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ return -EFAULT;
+@@ -162,8 +165,22 @@ asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg)
+ if (a.offset & ~PAGE_MASK)
+ return -EINVAL;
+
+- return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
++ if (!(a.flags & MAP_ANONYMOUS)) {
++ file = fget(a.fd);
++ if (!file)
++ return -EBADF;
++ }
++
++ mm = current->mm;
++ down_write(&mm->mmap_sem);
++ retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags,
+ a.offset>>PAGE_SHIFT);
++ if (file)
++ fput(file);
++
++ up_write(&mm->mmap_sem);
++
++ return retval;
+ }
+
+ asmlinkage long sys32_mprotect(unsigned long start, size_t len,
+@@ -522,6 +539,30 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd,
+ return ret;
+ }
+
++asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ struct mm_struct *mm = current->mm;
++ unsigned long error;
++ struct file *file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ return -EBADF;
++ }
++
++ down_write(&mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(&mm->mmap_sem);
++
++ if (file)
++ fput(file);
++ return error;
++}
++
+ asmlinkage long sys32_olduname(struct oldold_utsname __user *name)
+ {
+ char *arch = "x86_64";
+diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h
+index 18aa3f8..4b18089 100644
+--- a/arch/x86/include/asm/amd_iommu.h
++++ b/arch/x86/include/asm/amd_iommu.h
+@@ -32,7 +32,6 @@ extern void amd_iommu_flush_all_domains(void);
+ extern void amd_iommu_flush_all_devices(void);
+ extern void amd_iommu_shutdown(void);
+ extern void amd_iommu_apply_erratum_63(u16 devid);
+-extern void amd_iommu_init_api(void);
+ #else
+ static inline int amd_iommu_init(void) { return -ENODEV; }
+ static inline void amd_iommu_detect(void) { }
+diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
+new file mode 100644
+index 0000000..d96c1ee
+--- /dev/null
++++ b/arch/x86/include/asm/cpu_debug.h
+@@ -0,0 +1,127 @@
++#ifndef _ASM_X86_CPU_DEBUG_H
++#define _ASM_X86_CPU_DEBUG_H
++
++/*
++ * CPU x86 architecture debug
++ *
++ * Copyright(C) 2009 Jaswinder Singh Rajput
++ */
++
++/* Register flags */
++enum cpu_debug_bit {
++/* Model Specific Registers (MSRs) */
++ CPU_MC_BIT, /* Machine Check */
++ CPU_MONITOR_BIT, /* Monitor */
++ CPU_TIME_BIT, /* Time */
++ CPU_PMC_BIT, /* Performance Monitor */
++ CPU_PLATFORM_BIT, /* Platform */
++ CPU_APIC_BIT, /* APIC */
++ CPU_POWERON_BIT, /* Power-on */
++ CPU_CONTROL_BIT, /* Control */
++ CPU_FEATURES_BIT, /* Features control */
++ CPU_LBRANCH_BIT, /* Last Branch */
++ CPU_BIOS_BIT, /* BIOS */
++ CPU_FREQ_BIT, /* Frequency */
++ CPU_MTTR_BIT, /* MTRR */
++ CPU_PERF_BIT, /* Performance */
++ CPU_CACHE_BIT, /* Cache */
++ CPU_SYSENTER_BIT, /* Sysenter */
++ CPU_THERM_BIT, /* Thermal */
++ CPU_MISC_BIT, /* Miscellaneous */
++ CPU_DEBUG_BIT, /* Debug */
++ CPU_PAT_BIT, /* PAT */
++ CPU_VMX_BIT, /* VMX */
++ CPU_CALL_BIT, /* System Call */
++ CPU_BASE_BIT, /* BASE Address */
++ CPU_VER_BIT, /* Version ID */
++ CPU_CONF_BIT, /* Configuration */
++ CPU_SMM_BIT, /* System mgmt mode */
++ CPU_SVM_BIT, /*Secure Virtual Machine*/
++ CPU_OSVM_BIT, /* OS-Visible Workaround*/
++/* Standard Registers */
++ CPU_TSS_BIT, /* Task Stack Segment */
++ CPU_CR_BIT, /* Control Registers */
++ CPU_DT_BIT, /* Descriptor Table */
++/* End of Registers flags */
++ CPU_REG_ALL_BIT, /* Select all Registers */
++};
++
++#define CPU_REG_ALL (~0) /* Select all Registers */
++
++#define CPU_MC (1 << CPU_MC_BIT)
++#define CPU_MONITOR (1 << CPU_MONITOR_BIT)
++#define CPU_TIME (1 << CPU_TIME_BIT)
++#define CPU_PMC (1 << CPU_PMC_BIT)
++#define CPU_PLATFORM (1 << CPU_PLATFORM_BIT)
++#define CPU_APIC (1 << CPU_APIC_BIT)
++#define CPU_POWERON (1 << CPU_POWERON_BIT)
++#define CPU_CONTROL (1 << CPU_CONTROL_BIT)
++#define CPU_FEATURES (1 << CPU_FEATURES_BIT)
++#define CPU_LBRANCH (1 << CPU_LBRANCH_BIT)
++#define CPU_BIOS (1 << CPU_BIOS_BIT)
++#define CPU_FREQ (1 << CPU_FREQ_BIT)
++#define CPU_MTRR (1 << CPU_MTTR_BIT)
++#define CPU_PERF (1 << CPU_PERF_BIT)
++#define CPU_CACHE (1 << CPU_CACHE_BIT)
++#define CPU_SYSENTER (1 << CPU_SYSENTER_BIT)
++#define CPU_THERM (1 << CPU_THERM_BIT)
++#define CPU_MISC (1 << CPU_MISC_BIT)
++#define CPU_DEBUG (1 << CPU_DEBUG_BIT)
++#define CPU_PAT (1 << CPU_PAT_BIT)
++#define CPU_VMX (1 << CPU_VMX_BIT)
++#define CPU_CALL (1 << CPU_CALL_BIT)
++#define CPU_BASE (1 << CPU_BASE_BIT)
++#define CPU_VER (1 << CPU_VER_BIT)
++#define CPU_CONF (1 << CPU_CONF_BIT)
++#define CPU_SMM (1 << CPU_SMM_BIT)
++#define CPU_SVM (1 << CPU_SVM_BIT)
++#define CPU_OSVM (1 << CPU_OSVM_BIT)
++#define CPU_TSS (1 << CPU_TSS_BIT)
++#define CPU_CR (1 << CPU_CR_BIT)
++#define CPU_DT (1 << CPU_DT_BIT)
++
++/* Register file flags */
++enum cpu_file_bit {
++ CPU_INDEX_BIT, /* index */
++ CPU_VALUE_BIT, /* value */
++};
++
++#define CPU_FILE_VALUE (1 << CPU_VALUE_BIT)
++
++#define MAX_CPU_FILES 512
++
++struct cpu_private {
++ unsigned cpu;
++ unsigned type;
++ unsigned reg;
++ unsigned file;
++};
++
++struct cpu_debug_base {
++ char *name; /* Register name */
++ unsigned flag; /* Register flag */
++ unsigned write; /* Register write flag */
++};
++
++/*
++ * Currently it looks similar to cpu_debug_base but once we add more files
++ * cpu_file_base will go in different direction
++ */
++struct cpu_file_base {
++ char *name; /* Register file name */
++ unsigned flag; /* Register file flag */
++ unsigned write; /* Register write flag */
++};
++
++struct cpu_cpuX_base {
++ struct dentry *dentry; /* Register dentry */
++ int init; /* Register index file */
++};
++
++struct cpu_debug_range {
++ unsigned min; /* Register range min */
++ unsigned max; /* Register range max */
++ unsigned flag; /* Supported flags */
++};
++
++#endif /* _ASM_X86_CPU_DEBUG_H */
+diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
+index 8ac9d9a..456a304 100644
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -197,8 +197,14 @@ do { \
+ set_fs(USER_DS); \
+ } while (0)
+
+-void set_personality_ia32(void);
+-#define COMPAT_SET_PERSONALITY(ex) set_personality_ia32()
++#define COMPAT_SET_PERSONALITY(ex) \
++do { \
++ if (test_thread_flag(TIF_IA32)) \
++ clear_thread_flag(TIF_ABI_PENDING); \
++ else \
++ set_thread_flag(TIF_ABI_PENDING); \
++ current->personality |= force_personality32; \
++} while (0)
+
+ #define COMPAT_ELF_PLATFORM ("i686")
+
+diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h
+index 3251e23..1c22cb0 100644
+--- a/arch/x86/include/asm/hpet.h
++++ b/arch/x86/include/asm/hpet.h
+@@ -66,7 +66,6 @@
+ extern unsigned long hpet_address;
+ extern unsigned long force_hpet_address;
+ extern int hpet_force_user;
+-extern u8 hpet_msi_disable;
+ extern int is_hpet_enabled(void);
+ extern int hpet_enable(void);
+ extern void hpet_disable(void);
+diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
+index 6e90a04..5b21f0e 100644
+--- a/arch/x86/include/asm/irq_vectors.h
++++ b/arch/x86/include/asm/irq_vectors.h
+@@ -113,7 +113,7 @@
+ */
+ #define LOCAL_PENDING_VECTOR 0xec
+
+-#define UV_BAU_MESSAGE 0xea
++#define UV_BAU_MESSAGE 0xec
+
+ /*
+ * Self IPI vector for machine checks
+diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
+index 7c18e12..b7ed2c4 100644
+--- a/arch/x86/include/asm/kvm_emulate.h
++++ b/arch/x86/include/asm/kvm_emulate.h
+@@ -129,7 +129,7 @@ struct decode_cache {
+ u8 seg_override;
+ unsigned int d;
+ unsigned long regs[NR_VCPU_REGS];
+- unsigned long eip, eip_orig;
++ unsigned long eip;
+ /* modrm */
+ u8 modrm;
+ u8 modrm_mod;
+diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
+index d759a1f..d838922 100644
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -412,7 +412,6 @@ struct kvm_arch{
+ unsigned long irq_sources_bitmap;
+ unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
+ u64 vm_init_tsc;
+- s64 kvmclock_offset;
+ };
+
+ struct kvm_vm_stat {
+diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
+index a479023..f1363b7 100644
+--- a/arch/x86/include/asm/mce.h
++++ b/arch/x86/include/asm/mce.h
+@@ -214,11 +214,5 @@ void intel_init_thermal(struct cpuinfo_x86 *c);
+
+ void mce_log_therm_throt_event(__u64 status);
+
+-#ifdef CONFIG_X86_THERMAL_VECTOR
+-extern void mcheck_intel_therm_init(void);
+-#else
+-static inline void mcheck_intel_therm_init(void) { }
+-#endif
+-
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_X86_MCE_H */
+diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
+index 0e3e728..7e2b6ba 100644
+--- a/arch/x86/include/asm/msr.h
++++ b/arch/x86/include/asm/msr.h
+@@ -27,18 +27,6 @@ struct msr {
+ };
+ };
+
+-struct msr_info {
+- u32 msr_no;
+- struct msr reg;
+- struct msr *msrs;
+- int err;
+-};
+-
+-struct msr_regs_info {
+- u32 *regs;
+- int err;
+-};
+-
+ static inline unsigned long long native_read_tscp(unsigned int *aux)
+ {
+ unsigned long low, high;
+@@ -256,14 +244,11 @@ do { \
+
+ #define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
+
+-struct msr *msrs_alloc(void);
+-void msrs_free(struct msr *msrs);
+-
+ #ifdef CONFIG_SMP
+ int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
+ int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
+-void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
+-void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
++void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
++void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
+ int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
+ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
+ int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
+index 13b1885..c978648 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -180,7 +180,7 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
+ {
+ /* ecx is often an input as well as an output. */
+- asm volatile("cpuid"
++ asm("cpuid"
+ : "=a" (*eax),
+ "=b" (*ebx),
+ "=c" (*ecx),
+diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
+index 77c1184..72a6dcd 100644
+--- a/arch/x86/include/asm/sys_ia32.h
++++ b/arch/x86/include/asm/sys_ia32.h
+@@ -62,6 +62,9 @@ asmlinkage long sys32_pwrite(unsigned int, char __user *, u32, u32, u32);
+ asmlinkage long sys32_personality(unsigned long);
+ asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
+
++asmlinkage long sys32_mmap2(unsigned long, unsigned long, unsigned long,
++ unsigned long, unsigned long, unsigned long);
++
+ struct oldold_utsname;
+ struct old_utsname;
+ asmlinkage long sys32_olduname(struct oldold_utsname __user *);
+diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
+index 1bb6e39..372b76e 100644
+--- a/arch/x86/include/asm/syscalls.h
++++ b/arch/x86/include/asm/syscalls.h
+@@ -55,6 +55,8 @@ struct sel_arg_struct;
+ struct oldold_utsname;
+ struct old_utsname;
+
++asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
++ unsigned long, unsigned long, unsigned long);
+ asmlinkage int old_mmap(struct mmap_arg_struct __user *);
+ asmlinkage int old_select(struct sel_arg_struct __user *);
+ asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
+diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
+index 19c3ce4..d27d0a2 100644
+--- a/arch/x86/include/asm/thread_info.h
++++ b/arch/x86/include/asm/thread_info.h
+@@ -86,6 +86,7 @@ struct thread_info {
+ #define TIF_NOTSC 16 /* TSC is not accessible in userland */
+ #define TIF_IA32 17 /* 32bit process */
+ #define TIF_FORK 18 /* ret_from_fork */
++#define TIF_ABI_PENDING 19
+ #define TIF_MEMDIE 20
+ #define TIF_DEBUG 21 /* uses debug registers */
+ #define TIF_IO_BITMAP 22 /* uses I/O bitmap */
+@@ -109,6 +110,7 @@ struct thread_info {
+ #define _TIF_NOTSC (1 << TIF_NOTSC)
+ #define _TIF_IA32 (1 << TIF_IA32)
+ #define _TIF_FORK (1 << TIF_FORK)
++#define _TIF_ABI_PENDING (1 << TIF_ABI_PENDING)
+ #define _TIF_DEBUG (1 << TIF_DEBUG)
+ #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP)
+ #define _TIF_FREEZE (1 << TIF_FREEZE)
+diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
+index e90a8a9..d1414af 100644
+--- a/arch/x86/include/asm/uv/uv_hub.h
++++ b/arch/x86/include/asm/uv/uv_hub.h
+@@ -31,20 +31,20 @@
+ * contiguous (although various IO spaces may punch holes in
+ * it)..
+ *
+- * N - Number of bits in the node portion of a socket physical
+- * address.
++ * N - Number of bits in the node portion of a socket physical
++ * address.
+ *
+- * NASID - network ID of a router, Mbrick or Cbrick. Nasid values of
+- * routers always have low bit of 1, C/MBricks have low bit
+- * equal to 0. Most addressing macros that target UV hub chips
+- * right shift the NASID by 1 to exclude the always-zero bit.
+- * NASIDs contain up to 15 bits.
++ * NASID - network ID of a router, Mbrick or Cbrick. Nasid values of
++ * routers always have low bit of 1, C/MBricks have low bit
++ * equal to 0. Most addressing macros that target UV hub chips
++ * right shift the NASID by 1 to exclude the always-zero bit.
++ * NASIDs contain up to 15 bits.
+ *
+ * GNODE - NASID right shifted by 1 bit. Most mmrs contain gnodes instead
+ * of nasids.
+ *
+- * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant
+- * of the nasid for socket usage.
++ * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant
++ * of the nasid for socket usage.
+ *
+ *
+ * NumaLink Global Physical Address Format:
+@@ -71,12 +71,12 @@
+ *
+ *
+ * APICID format
+- * NOTE!!!!!! This is the current format of the APICID. However, code
+- * should assume that this will change in the future. Use functions
+- * in this file for all APICID bit manipulations and conversion.
++ * NOTE!!!!!! This is the current format of the APICID. However, code
++ * should assume that this will change in the future. Use functions
++ * in this file for all APICID bit manipulations and conversion.
+ *
+- * 1111110000000000
+- * 5432109876543210
++ * 1111110000000000
++ * 5432109876543210
+ * pppppppppplc0cch
+ * sssssssssss
+ *
+@@ -89,9 +89,9 @@
+ * Note: Processor only supports 12 bits in the APICID register. The ACPI
+ * tables hold all 16 bits. Software needs to be aware of this.
+ *
+- * Unless otherwise specified, all references to APICID refer to
+- * the FULL value contained in ACPI tables, not the subset in the
+- * processor APICID register.
++ * Unless otherwise specified, all references to APICID refer to
++ * the FULL value contained in ACPI tables, not the subset in the
++ * processor APICID register.
+ */
+
+
+@@ -151,16 +151,16 @@ struct uv_hub_info_s {
+ };
+
+ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
+-#define uv_hub_info (&__get_cpu_var(__uv_hub_info))
++#define uv_hub_info (&__get_cpu_var(__uv_hub_info))
+ #define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu))
+
+ /*
+ * Local & Global MMR space macros.
+- * Note: macros are intended to be used ONLY by inline functions
+- * in this file - not by other kernel code.
+- * n - NASID (full 15-bit global nasid)
+- * g - GNODE (full 15-bit global nasid, right shifted 1)
+- * p - PNODE (local part of nsids, right shifted 1)
++ * Note: macros are intended to be used ONLY by inline functions
++ * in this file - not by other kernel code.
++ * n - NASID (full 15-bit global nasid)
++ * g - GNODE (full 15-bit global nasid, right shifted 1)
++ * p - PNODE (local part of nsids, right shifted 1)
+ */
+ #define UV_NASID_TO_PNODE(n) (((n) >> 1) & uv_hub_info->pnode_mask)
+ #define UV_PNODE_TO_GNODE(p) ((p) |uv_hub_info->gnode_extra)
+@@ -213,8 +213,8 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
+ /*
+ * Macros for converting between kernel virtual addresses, socket local physical
+ * addresses, and UV global physical addresses.
+- * Note: use the standard __pa() & __va() macros for converting
+- * between socket virtual and socket physical addresses.
++ * Note: use the standard __pa() & __va() macros for converting
++ * between socket virtual and socket physical addresses.
+ */
+
+ /* socket phys RAM --> UV global physical address */
+@@ -265,18 +265,21 @@ static inline int uv_apicid_to_pnode(int apicid)
+ * Access global MMRs using the low memory MMR32 space. This region supports
+ * faster MMR access but not all MMRs are accessible in this space.
+ */
+-static inline unsigned long *uv_global_mmr32_address(int pnode, unsigned long offset)
++static inline unsigned long *uv_global_mmr32_address(int pnode,
++ unsigned long offset)
+ {
+ return __va(UV_GLOBAL_MMR32_BASE |
+ UV_GLOBAL_MMR32_PNODE_BITS(pnode) | offset);
+ }
+
+-static inline void uv_write_global_mmr32(int pnode, unsigned long offset, unsigned long val)
++static inline void uv_write_global_mmr32(int pnode, unsigned long offset,
++ unsigned long val)
+ {
+ writeq(val, uv_global_mmr32_address(pnode, offset));
+ }
+
+-static inline unsigned long uv_read_global_mmr32(int pnode, unsigned long offset)
++static inline unsigned long uv_read_global_mmr32(int pnode,
++ unsigned long offset)
+ {
+ return readq(uv_global_mmr32_address(pnode, offset));
+ }
+@@ -285,32 +288,25 @@ static inline unsigned long uv_read_global_mmr32(int pnode, unsigned long offset
+ * Access Global MMR space using the MMR space located at the top of physical
+ * memory.
+ */
+-static inline unsigned long *uv_global_mmr64_address(int pnode, unsigned long offset)
++static inline unsigned long *uv_global_mmr64_address(int pnode,
++ unsigned long offset)
+ {
+ return __va(UV_GLOBAL_MMR64_BASE |
+ UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset);
+ }
+
+-static inline void uv_write_global_mmr64(int pnode, unsigned long offset, unsigned long val)
++static inline void uv_write_global_mmr64(int pnode, unsigned long offset,
++ unsigned long val)
+ {
+ writeq(val, uv_global_mmr64_address(pnode, offset));
+ }
+
+-static inline unsigned long uv_read_global_mmr64(int pnode, unsigned long offset)
++static inline unsigned long uv_read_global_mmr64(int pnode,
++ unsigned long offset)
+ {
+ return readq(uv_global_mmr64_address(pnode, offset));
+ }
+
+-static inline void uv_write_global_mmr8(int pnode, unsigned long offset, unsigned char val)
+-{
+- writeb(val, uv_global_mmr64_address(pnode, offset));
+-}
+-
+-static inline unsigned char uv_read_global_mmr8(int pnode, unsigned long offset)
+-{
+- return readb(uv_global_mmr64_address(pnode, offset));
+-}
+-
+ /*
+ * Access hub local MMRs. Faster than using global space but only local MMRs
+ * are accessible.
+@@ -430,17 +426,11 @@ static inline void uv_set_scir_bits(unsigned char value)
+ }
+ }
+
+-static inline unsigned long uv_scir_offset(int apicid)
+-{
+- return SCIR_LOCAL_MMR_BASE | (apicid & 0x3f);
+-}
+-
+ static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
+ {
+ if (uv_cpu_hub_info(cpu)->scir.state != value) {
+- uv_write_global_mmr8(uv_cpu_to_pnode(cpu),
+- uv_cpu_hub_info(cpu)->scir.offset, value);
+ uv_cpu_hub_info(cpu)->scir.state = value;
++ uv_write_local_mmr8(uv_cpu_hub_info(cpu)->scir.offset, value);
+ }
+ }
+
+diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
+index 2e837f5..59cdfa4 100644
+--- a/arch/x86/kernel/acpi/cstate.c
++++ b/arch/x86/kernel/acpi/cstate.c
+@@ -48,7 +48,7 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
+ * P4, Core and beyond CPUs
+ */
+ if (c->x86_vendor == X86_VENDOR_INTEL &&
+- (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f)))
++ (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 14)))
+ flags->bm_control = 0;
+ }
+ EXPORT_SYMBOL(acpi_processor_power_init_bm_check);
+diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
+index 23fc9fe..0285521 100644
+--- a/arch/x86/kernel/amd_iommu.c
++++ b/arch/x86/kernel/amd_iommu.c
+@@ -540,7 +540,7 @@ static void flush_all_devices_for_iommu(struct amd_iommu *iommu)
+ static void flush_devices_by_domain(struct protection_domain *domain)
+ {
+ struct amd_iommu *iommu;
+- unsigned long i;
++ int i;
+
+ for (i = 0; i <= amd_iommu_last_bdf; ++i) {
+ if ((domain == NULL && amd_iommu_pd_table[i] == NULL) ||
+@@ -1230,10 +1230,9 @@ static void __detach_device(struct protection_domain *domain, u16 devid)
+
+ /*
+ * If we run in passthrough mode the device must be assigned to the
+- * passthrough domain if it is detached from any other domain.
+- * Make sure we can deassign from the pt_domain itself.
++ * passthrough domain if it is detached from any other domain
+ */
+- if (iommu_pass_through && domain != pt_domain) {
++ if (iommu_pass_through) {
+ struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
+ __attach_device(iommu, pt_domain, devid);
+ }
+@@ -2048,10 +2047,10 @@ static void prealloc_protection_domains(void)
+ struct pci_dev *dev = NULL;
+ struct dma_ops_domain *dma_dom;
+ struct amd_iommu *iommu;
+- u16 devid, __devid;
++ u16 devid;
+
+ while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+- __devid = devid = calc_devid(dev->bus->number, dev->devfn);
++ devid = calc_devid(dev->bus->number, dev->devfn);
+ if (devid > amd_iommu_last_bdf)
+ continue;
+ devid = amd_iommu_alias_table[devid];
+@@ -2066,10 +2065,6 @@ static void prealloc_protection_domains(void)
+ init_unity_mappings_for_device(dma_dom, devid);
+ dma_dom->target_dev = devid;
+
+- attach_device(iommu, &dma_dom->domain, devid);
+- if (__devid != devid)
+- attach_device(iommu, &dma_dom->domain, __devid);
+-
+ list_add_tail(&dma_dom->list, &iommu_pd_list);
+ }
+ }
+@@ -2084,11 +2079,6 @@ static struct dma_map_ops amd_iommu_dma_ops = {
+ .dma_supported = amd_iommu_dma_supported,
+ };
+
+-void __init amd_iommu_init_api(void)
+-{
+- register_iommu(&amd_iommu_ops);
+-}
+-
+ /*
+ * The function which clues the AMD IOMMU driver into dma_ops.
+ */
+@@ -2130,6 +2120,8 @@ int __init amd_iommu_init_dma_ops(void)
+ /* Make the driver finally visible to the drivers */
+ dma_ops = &amd_iommu_dma_ops;
+
++ register_iommu(&amd_iommu_ops);
++
+ bus_register_notifier(&pci_bus_type, &device_nb);
+
+ amd_iommu_stats_init();
+diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
+index 362ab88..c20001e 100644
+--- a/arch/x86/kernel/amd_iommu_init.c
++++ b/arch/x86/kernel/amd_iommu_init.c
+@@ -136,11 +136,6 @@ LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the
+ system */
+
+ /*
+- * Set to true if ACPI table parsing and hardware intialization went properly
+- */
+-static bool amd_iommu_initialized;
+-
+-/*
+ * Pointer to the device table which is shared by all AMD IOMMUs
+ * it is indexed by the PCI device id or the HT unit id and contains
+ * information about the domain the device belongs to as well as the
+@@ -918,8 +913,6 @@ static int __init init_iommu_all(struct acpi_table_header *table)
+ }
+ WARN_ON(p != end);
+
+- amd_iommu_initialized = true;
+-
+ return 0;
+ }
+
+@@ -932,7 +925,7 @@ static int __init init_iommu_all(struct acpi_table_header *table)
+ *
+ ****************************************************************************/
+
+-static int iommu_setup_msi(struct amd_iommu *iommu)
++static int __init iommu_setup_msi(struct amd_iommu *iommu)
+ {
+ int r;
+
+@@ -1270,9 +1263,6 @@ int __init amd_iommu_init(void)
+ if (acpi_table_parse("IVRS", init_iommu_all) != 0)
+ goto free;
+
+- if (!amd_iommu_initialized)
+- goto free;
+-
+ if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
+ goto free;
+
+@@ -1288,12 +1278,9 @@ int __init amd_iommu_init(void)
+ ret = amd_iommu_init_passthrough();
+ else
+ ret = amd_iommu_init_dma_ops();
+-
+ if (ret)
+ goto free;
+
+- amd_iommu_init_api();
+-
+ enable_iommus();
+
+ if (iommu_pass_through)
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index c86dbcf..894aa97 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -246,7 +246,7 @@ static int modern_apic(void)
+ */
+ static void native_apic_write_dummy(u32 reg, u32 v)
+ {
+- WARN_ON_ONCE(cpu_has_apic && !disable_apic);
++ WARN_ON_ONCE((cpu_has_apic || !disable_apic));
+ }
+
+ static u32 native_apic_read_dummy(u32 reg)
+diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c
+index 873f81f..d0c99ab 100644
+--- a/arch/x86/kernel/apic/apic_flat_64.c
++++ b/arch/x86/kernel/apic/apic_flat_64.c
+@@ -240,11 +240,6 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+ printk(KERN_DEBUG "system APIC only can use physical flat");
+ return 1;
+ }
+-
+- if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "EXA", 3)) {
+- printk(KERN_DEBUG "IBM Summit detected, will use apic physical");
+- return 1;
+- }
+ #endif
+
+ return 0;
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index c107e83..dc69f28 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -3157,7 +3157,6 @@ unsigned int create_irq_nr(unsigned int irq_want, int node)
+ continue;
+
+ desc_new = move_irq_desc(desc_new, node);
+- cfg_new = desc_new->chip_data;
+
+ if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
+ irq = new;
+diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
+index 9ee87cf..326c254 100644
+--- a/arch/x86/kernel/apic/x2apic_uv_x.c
++++ b/arch/x86/kernel/apic/x2apic_uv_x.c
+@@ -364,13 +364,13 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
+
+ enum map_type {map_wb, map_uc};
+
+-static __init void map_high(char *id, unsigned long base, int pshift,
+- int bshift, int max_pnode, enum map_type map_type)
++static __init void map_high(char *id, unsigned long base, int shift,
++ int max_pnode, enum map_type map_type)
+ {
+ unsigned long bytes, paddr;
+
+- paddr = base << pshift;
+- bytes = (1UL << bshift) * (max_pnode + 1);
++ paddr = base << shift;
++ bytes = (1UL << shift) * (max_pnode + 1);
+ printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr,
+ paddr + bytes);
+ if (map_type == map_uc)
+@@ -386,7 +386,7 @@ static __init void map_gru_high(int max_pnode)
+
+ gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR);
+ if (gru.s.enable)
+- map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb);
++ map_high("GRU", gru.s.base, shift, max_pnode, map_wb);
+ }
+
+ static __init void map_mmr_high(int max_pnode)
+@@ -396,7 +396,7 @@ static __init void map_mmr_high(int max_pnode)
+
+ mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR);
+ if (mmr.s.enable)
+- map_high("MMR", mmr.s.base, shift, shift, max_pnode, map_uc);
++ map_high("MMR", mmr.s.base, shift, max_pnode, map_uc);
+ }
+
+ static __init void map_mmioh_high(int max_pnode)
+@@ -406,8 +406,7 @@ static __init void map_mmioh_high(int max_pnode)
+
+ mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR);
+ if (mmioh.s.enable)
+- map_high("MMIOH", mmioh.s.base, shift, mmioh.s.m_io,
+- max_pnode, map_uc);
++ map_high("MMIOH", mmioh.s.base, shift, max_pnode, map_uc);
+ }
+
+ static __init void uv_rtc_init(void)
+@@ -608,10 +607,8 @@ void __init uv_system_init(void)
+ uv_rtc_init();
+
+ for_each_present_cpu(cpu) {
+- int apicid = per_cpu(x86_cpu_to_apicid, cpu);
+-
+ nid = cpu_to_node(cpu);
+- pnode = uv_apicid_to_pnode(apicid);
++ pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu));
+ blade = boot_pnode_to_blade(pnode);
+ lcpu = uv_blade_info[blade].nr_possible_cpus;
+ uv_blade_info[blade].nr_possible_cpus++;
+@@ -632,13 +629,15 @@ void __init uv_system_init(void)
+ uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
+ uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
+ uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
+- uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
++ uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu;
+ uv_node_to_blade[nid] = blade;
+ uv_cpu_to_blade[cpu] = blade;
+ max_pnode = max(pnode, max_pnode);
+
+- printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n",
+- cpu, apicid, pnode, nid, lcpu, blade);
++ printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, "
++ "lcpu %d, blade %d\n",
++ cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid,
++ lcpu, blade);
+ }
+
+ /* Add blade/pnode info for nodes without cpus */
+diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
+index ff502cc..68537e9 100644
+--- a/arch/x86/kernel/cpu/Makefile
++++ b/arch/x86/kernel/cpu/Makefile
+@@ -18,6 +18,8 @@ obj-y += vmware.o hypervisor.o sched.o
+ obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o
+ obj-$(CONFIG_X86_64) += bugs_64.o
+
++obj-$(CONFIG_X86_CPU_DEBUG) += cpu_debug.o
++
+ obj-$(CONFIG_CPU_SUP_INTEL) += intel.o
+ obj-$(CONFIG_CPU_SUP_AMD) += amd.o
+ obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o
+diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
+new file mode 100644
+index 0000000..dca325c
+--- /dev/null
++++ b/arch/x86/kernel/cpu/cpu_debug.c
+@@ -0,0 +1,688 @@
++/*
++ * CPU x86 architecture debug code
++ *
++ * Copyright(C) 2009 Jaswinder Singh Rajput
++ *
++ * For licencing details see kernel-base/COPYING
++ */
++
++#include <linux/interrupt.h>
++#include <linux/compiler.h>
++#include <linux/seq_file.h>
++#include <linux/debugfs.h>
++#include <linux/kprobes.h>
++#include <linux/uaccess.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/percpu.h>
++#include <linux/signal.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/smp.h>
++
++#include <asm/cpu_debug.h>
++#include <asm/paravirt.h>
++#include <asm/system.h>
++#include <asm/traps.h>
++#include <asm/apic.h>
++#include <asm/desc.h>
++
++static DEFINE_PER_CPU(struct cpu_cpuX_base [CPU_REG_ALL_BIT], cpu_arr);
++static DEFINE_PER_CPU(struct cpu_private * [MAX_CPU_FILES], priv_arr);
++static DEFINE_PER_CPU(int, cpu_priv_count);
++
++static DEFINE_MUTEX(cpu_debug_lock);
++
++static struct dentry *cpu_debugfs_dir;
++
++static struct cpu_debug_base cpu_base[] = {
++ { "mc", CPU_MC, 0 },
++ { "monitor", CPU_MONITOR, 0 },
++ { "time", CPU_TIME, 0 },
++ { "pmc", CPU_PMC, 1 },
++ { "platform", CPU_PLATFORM, 0 },
++ { "apic", CPU_APIC, 0 },
++ { "poweron", CPU_POWERON, 0 },
++ { "control", CPU_CONTROL, 0 },
++ { "features", CPU_FEATURES, 0 },
++ { "lastbranch", CPU_LBRANCH, 0 },
++ { "bios", CPU_BIOS, 0 },
++ { "freq", CPU_FREQ, 0 },
++ { "mtrr", CPU_MTRR, 0 },
++ { "perf", CPU_PERF, 0 },
++ { "cache", CPU_CACHE, 0 },
++ { "sysenter", CPU_SYSENTER, 0 },
++ { "therm", CPU_THERM, 0 },
++ { "misc", CPU_MISC, 0 },
++ { "debug", CPU_DEBUG, 0 },
++ { "pat", CPU_PAT, 0 },
++ { "vmx", CPU_VMX, 0 },
++ { "call", CPU_CALL, 0 },
++ { "base", CPU_BASE, 0 },
++ { "ver", CPU_VER, 0 },
++ { "conf", CPU_CONF, 0 },
++ { "smm", CPU_SMM, 0 },
++ { "svm", CPU_SVM, 0 },
++ { "osvm", CPU_OSVM, 0 },
++ { "tss", CPU_TSS, 0 },
++ { "cr", CPU_CR, 0 },
++ { "dt", CPU_DT, 0 },
++ { "registers", CPU_REG_ALL, 0 },
++};
++
++static struct cpu_file_base cpu_file[] = {
++ { "index", CPU_REG_ALL, 0 },
++ { "value", CPU_REG_ALL, 1 },
++};
++
++/* CPU Registers Range */
++static struct cpu_debug_range cpu_reg_range[] = {
++ { 0x00000000, 0x00000001, CPU_MC, },
++ { 0x00000006, 0x00000007, CPU_MONITOR, },
++ { 0x00000010, 0x00000010, CPU_TIME, },
++ { 0x00000011, 0x00000013, CPU_PMC, },
++ { 0x00000017, 0x00000017, CPU_PLATFORM, },
++ { 0x0000001B, 0x0000001B, CPU_APIC, },
++ { 0x0000002A, 0x0000002B, CPU_POWERON, },
++ { 0x0000002C, 0x0000002C, CPU_FREQ, },
++ { 0x0000003A, 0x0000003A, CPU_CONTROL, },
++ { 0x00000040, 0x00000047, CPU_LBRANCH, },
++ { 0x00000060, 0x00000067, CPU_LBRANCH, },
++ { 0x00000079, 0x00000079, CPU_BIOS, },
++ { 0x00000088, 0x0000008A, CPU_CACHE, },
++ { 0x0000008B, 0x0000008B, CPU_BIOS, },
++ { 0x0000009B, 0x0000009B, CPU_MONITOR, },
++ { 0x000000C1, 0x000000C4, CPU_PMC, },
++ { 0x000000CD, 0x000000CD, CPU_FREQ, },
++ { 0x000000E7, 0x000000E8, CPU_PERF, },
++ { 0x000000FE, 0x000000FE, CPU_MTRR, },
++
++ { 0x00000116, 0x0000011E, CPU_CACHE, },
++ { 0x00000174, 0x00000176, CPU_SYSENTER, },
++ { 0x00000179, 0x0000017B, CPU_MC, },
++ { 0x00000186, 0x00000189, CPU_PMC, },
++ { 0x00000198, 0x00000199, CPU_PERF, },
++ { 0x0000019A, 0x0000019A, CPU_TIME, },
++ { 0x0000019B, 0x0000019D, CPU_THERM, },
++ { 0x000001A0, 0x000001A0, CPU_MISC, },
++ { 0x000001C9, 0x000001C9, CPU_LBRANCH, },
++ { 0x000001D7, 0x000001D8, CPU_LBRANCH, },
++ { 0x000001D9, 0x000001D9, CPU_DEBUG, },
++ { 0x000001DA, 0x000001E0, CPU_LBRANCH, },
++
++ { 0x00000200, 0x0000020F, CPU_MTRR, },
++ { 0x00000250, 0x00000250, CPU_MTRR, },
++ { 0x00000258, 0x00000259, CPU_MTRR, },
++ { 0x00000268, 0x0000026F, CPU_MTRR, },
++ { 0x00000277, 0x00000277, CPU_PAT, },
++ { 0x000002FF, 0x000002FF, CPU_MTRR, },
++
++ { 0x00000300, 0x00000311, CPU_PMC, },
++ { 0x00000345, 0x00000345, CPU_PMC, },
++ { 0x00000360, 0x00000371, CPU_PMC, },
++ { 0x0000038D, 0x00000390, CPU_PMC, },
++ { 0x000003A0, 0x000003BE, CPU_PMC, },
++ { 0x000003C0, 0x000003CD, CPU_PMC, },
++ { 0x000003E0, 0x000003E1, CPU_PMC, },
++ { 0x000003F0, 0x000003F2, CPU_PMC, },
++
++ { 0x00000400, 0x00000417, CPU_MC, },
++ { 0x00000480, 0x0000048B, CPU_VMX, },
++
++ { 0x00000600, 0x00000600, CPU_DEBUG, },
++ { 0x00000680, 0x0000068F, CPU_LBRANCH, },
++ { 0x000006C0, 0x000006CF, CPU_LBRANCH, },
++
++ { 0x000107CC, 0x000107D3, CPU_PMC, },
++
++ { 0xC0000080, 0xC0000080, CPU_FEATURES, },
++ { 0xC0000081, 0xC0000084, CPU_CALL, },
++ { 0xC0000100, 0xC0000102, CPU_BASE, },
++ { 0xC0000103, 0xC0000103, CPU_TIME, },
++
++ { 0xC0010000, 0xC0010007, CPU_PMC, },
++ { 0xC0010010, 0xC0010010, CPU_CONF, },
++ { 0xC0010015, 0xC0010015, CPU_CONF, },
++ { 0xC0010016, 0xC001001A, CPU_MTRR, },
++ { 0xC001001D, 0xC001001D, CPU_MTRR, },
++ { 0xC001001F, 0xC001001F, CPU_CONF, },
++ { 0xC0010030, 0xC0010035, CPU_BIOS, },
++ { 0xC0010044, 0xC0010048, CPU_MC, },
++ { 0xC0010050, 0xC0010056, CPU_SMM, },
++ { 0xC0010058, 0xC0010058, CPU_CONF, },
++ { 0xC0010060, 0xC0010060, CPU_CACHE, },
++ { 0xC0010061, 0xC0010068, CPU_SMM, },
++ { 0xC0010069, 0xC001006B, CPU_SMM, },
++ { 0xC0010070, 0xC0010071, CPU_SMM, },
++ { 0xC0010111, 0xC0010113, CPU_SMM, },
++ { 0xC0010114, 0xC0010118, CPU_SVM, },
++ { 0xC0010140, 0xC0010141, CPU_OSVM, },
++ { 0xC0011022, 0xC0011023, CPU_CONF, },
++};
++
++static int is_typeflag_valid(unsigned cpu, unsigned flag)
++{
++ int i;
++
++ /* Standard Registers should be always valid */
++ if (flag >= CPU_TSS)
++ return 1;
++
++ for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
++ if (cpu_reg_range[i].flag == flag)
++ return 1;
++ }
++
++ /* Invalid */
++ return 0;
++}
++
++static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max,
++ int index, unsigned flag)
++{
++ if (cpu_reg_range[index].flag == flag) {
++ *min = cpu_reg_range[index].min;
++ *max = cpu_reg_range[index].max;
++ } else
++ *max = 0;
++
++ return *max;
++}
++
++/* This function can also be called with seq = NULL for printk */
++static void print_cpu_data(struct seq_file *seq, unsigned type,
++ u32 low, u32 high)
++{
++ struct cpu_private *priv;
++ u64 val = high;
++
++ if (seq) {
++ priv = seq->private;
++ if (priv->file) {
++ val = (val << 32) | low;
++ seq_printf(seq, "0x%llx\n", val);
++ } else
++ seq_printf(seq, " %08x: %08x_%08x\n",
++ type, high, low);
++ } else
++ printk(KERN_INFO " %08x: %08x_%08x\n", type, high, low);
++}
++
++/* This function can also be called with seq = NULL for printk */
++static void print_msr(struct seq_file *seq, unsigned cpu, unsigned flag)
++{
++ unsigned msr, msr_min, msr_max;
++ struct cpu_private *priv;
++ u32 low, high;
++ int i;
++
++ if (seq) {
++ priv = seq->private;
++ if (priv->file) {
++ if (!rdmsr_safe_on_cpu(priv->cpu, priv->reg,
++ &low, &high))
++ print_cpu_data(seq, priv->reg, low, high);
++ return;
++ }
++ }
++
++ for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
++ if (!get_cpu_range(cpu, &msr_min, &msr_max, i, flag))
++ continue;
++
++ for (msr = msr_min; msr <= msr_max; msr++) {
++ if (rdmsr_safe_on_cpu(cpu, msr, &low, &high))
++ continue;
++ print_cpu_data(seq, msr, low, high);
++ }
++ }
++}
++
++static void print_tss(void *arg)
++{
++ struct pt_regs *regs = task_pt_regs(current);
++ struct seq_file *seq = arg;
++ unsigned int seg;
++
++ seq_printf(seq, " RAX\t: %016lx\n", regs->ax);
++ seq_printf(seq, " RBX\t: %016lx\n", regs->bx);
++ seq_printf(seq, " RCX\t: %016lx\n", regs->cx);
++ seq_printf(seq, " RDX\t: %016lx\n", regs->dx);
++
++ seq_printf(seq, " RSI\t: %016lx\n", regs->si);
++ seq_printf(seq, " RDI\t: %016lx\n", regs->di);
++ seq_printf(seq, " RBP\t: %016lx\n", regs->bp);
++ seq_printf(seq, " ESP\t: %016lx\n", regs->sp);
++
++#ifdef CONFIG_X86_64
++ seq_printf(seq, " R08\t: %016lx\n", regs->r8);
++ seq_printf(seq, " R09\t: %016lx\n", regs->r9);
++ seq_printf(seq, " R10\t: %016lx\n", regs->r10);
++ seq_printf(seq, " R11\t: %016lx\n", regs->r11);
++ seq_printf(seq, " R12\t: %016lx\n", regs->r12);
++ seq_printf(seq, " R13\t: %016lx\n", regs->r13);
++ seq_printf(seq, " R14\t: %016lx\n", regs->r14);
++ seq_printf(seq, " R15\t: %016lx\n", regs->r15);
++#endif
++
++ asm("movl %%cs,%0" : "=r" (seg));
++ seq_printf(seq, " CS\t: %04x\n", seg);
++ asm("movl %%ds,%0" : "=r" (seg));
++ seq_printf(seq, " DS\t: %04x\n", seg);
++ seq_printf(seq, " SS\t: %04lx\n", regs->ss & 0xffff);
++ asm("movl %%es,%0" : "=r" (seg));
++ seq_printf(seq, " ES\t: %04x\n", seg);
++ asm("movl %%fs,%0" : "=r" (seg));
++ seq_printf(seq, " FS\t: %04x\n", seg);
++ asm("movl %%gs,%0" : "=r" (seg));
++ seq_printf(seq, " GS\t: %04x\n", seg);
++
++ seq_printf(seq, " EFLAGS\t: %016lx\n", regs->flags);
++
++ seq_printf(seq, " EIP\t: %016lx\n", regs->ip);
++}
++
++static void print_cr(void *arg)
++{
++ struct seq_file *seq = arg;
++
++ seq_printf(seq, " cr0\t: %016lx\n", read_cr0());
++ seq_printf(seq, " cr2\t: %016lx\n", read_cr2());
++ seq_printf(seq, " cr3\t: %016lx\n", read_cr3());
++ seq_printf(seq, " cr4\t: %016lx\n", read_cr4_safe());
++#ifdef CONFIG_X86_64
++ seq_printf(seq, " cr8\t: %016lx\n", read_cr8());
++#endif
++}
++
++static void print_desc_ptr(char *str, struct seq_file *seq, struct desc_ptr dt)
++{
++ seq_printf(seq, " %s\t: %016llx\n", str, (u64)(dt.address | dt.size));
++}
++
++static void print_dt(void *seq)
++{
++ struct desc_ptr dt;
++ unsigned long ldt;
++
++ /* IDT */
++ store_idt((struct desc_ptr *)&dt);
++ print_desc_ptr("IDT", seq, dt);
++
++ /* GDT */
++ store_gdt((struct desc_ptr *)&dt);
++ print_desc_ptr("GDT", seq, dt);
++
++ /* LDT */
++ store_ldt(ldt);
++ seq_printf(seq, " LDT\t: %016lx\n", ldt);
++
++ /* TR */
++ store_tr(ldt);
++ seq_printf(seq, " TR\t: %016lx\n", ldt);
++}
++
++static void print_dr(void *arg)
++{
++ struct seq_file *seq = arg;
++ unsigned long dr;
++ int i;
++
++ for (i = 0; i < 8; i++) {
++ /* Ignore db4, db5 */
++ if ((i == 4) || (i == 5))
++ continue;
++ get_debugreg(dr, i);
++ seq_printf(seq, " dr%d\t: %016lx\n", i, dr);
++ }
++
++ seq_printf(seq, "\n MSR\t:\n");
++}
++
++static void print_apic(void *arg)
++{
++ struct seq_file *seq = arg;
++
++#ifdef CONFIG_X86_LOCAL_APIC
++ seq_printf(seq, " LAPIC\t:\n");
++ seq_printf(seq, " ID\t\t: %08x\n", apic_read(APIC_ID) >> 24);
++ seq_printf(seq, " LVR\t\t: %08x\n", apic_read(APIC_LVR));
++ seq_printf(seq, " TASKPRI\t: %08x\n", apic_read(APIC_TASKPRI));
++ seq_printf(seq, " ARBPRI\t\t: %08x\n", apic_read(APIC_ARBPRI));
++ seq_printf(seq, " PROCPRI\t: %08x\n", apic_read(APIC_PROCPRI));
++ seq_printf(seq, " LDR\t\t: %08x\n", apic_read(APIC_LDR));
++ seq_printf(seq, " DFR\t\t: %08x\n", apic_read(APIC_DFR));
++ seq_printf(seq, " SPIV\t\t: %08x\n", apic_read(APIC_SPIV));
++ seq_printf(seq, " ISR\t\t: %08x\n", apic_read(APIC_ISR));
++ seq_printf(seq, " ESR\t\t: %08x\n", apic_read(APIC_ESR));
++ seq_printf(seq, " ICR\t\t: %08x\n", apic_read(APIC_ICR));
++ seq_printf(seq, " ICR2\t\t: %08x\n", apic_read(APIC_ICR2));
++ seq_printf(seq, " LVTT\t\t: %08x\n", apic_read(APIC_LVTT));
++ seq_printf(seq, " LVTTHMR\t: %08x\n", apic_read(APIC_LVTTHMR));
++ seq_printf(seq, " LVTPC\t\t: %08x\n", apic_read(APIC_LVTPC));
++ seq_printf(seq, " LVT0\t\t: %08x\n", apic_read(APIC_LVT0));
++ seq_printf(seq, " LVT1\t\t: %08x\n", apic_read(APIC_LVT1));
++ seq_printf(seq, " LVTERR\t\t: %08x\n", apic_read(APIC_LVTERR));
++ seq_printf(seq, " TMICT\t\t: %08x\n", apic_read(APIC_TMICT));
++ seq_printf(seq, " TMCCT\t\t: %08x\n", apic_read(APIC_TMCCT));
++ seq_printf(seq, " TDCR\t\t: %08x\n", apic_read(APIC_TDCR));
++ if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
++ unsigned int i, v, maxeilvt;
++
++ v = apic_read(APIC_EFEAT);
++ maxeilvt = (v >> 16) & 0xff;
++ seq_printf(seq, " EFEAT\t\t: %08x\n", v);
++ seq_printf(seq, " ECTRL\t\t: %08x\n", apic_read(APIC_ECTRL));
++
++ for (i = 0; i < maxeilvt; i++) {
++ v = apic_read(APIC_EILVTn(i));
++ seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v);
++ }
++ }
++#endif /* CONFIG_X86_LOCAL_APIC */
++ seq_printf(seq, "\n MSR\t:\n");
++}
++
++static int cpu_seq_show(struct seq_file *seq, void *v)
++{
++ struct cpu_private *priv = seq->private;
++
++ if (priv == NULL)
++ return -EINVAL;
++
++ switch (cpu_base[priv->type].flag) {
++ case CPU_TSS:
++ smp_call_function_single(priv->cpu, print_tss, seq, 1);
++ break;
++ case CPU_CR:
++ smp_call_function_single(priv->cpu, print_cr, seq, 1);
++ break;
++ case CPU_DT:
++ smp_call_function_single(priv->cpu, print_dt, seq, 1);
++ break;
++ case CPU_DEBUG:
++ if (priv->file == CPU_INDEX_BIT)
++ smp_call_function_single(priv->cpu, print_dr, seq, 1);
++ print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
++ break;
++ case CPU_APIC:
++ if (priv->file == CPU_INDEX_BIT)
++ smp_call_function_single(priv->cpu, print_apic, seq, 1);
++ print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
++ break;
++
++ default:
++ print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
++ break;
++ }
++ seq_printf(seq, "\n");
++
++ return 0;
++}
++
++static void *cpu_seq_start(struct seq_file *seq, loff_t *pos)
++{
++ if (*pos == 0) /* One time is enough ;-) */
++ return seq;
++
++ return NULL;
++}
++
++static void *cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++ (*pos)++;
++
++ return cpu_seq_start(seq, pos);
++}
++
++static void cpu_seq_stop(struct seq_file *seq, void *v)
++{
++}
++
++static const struct seq_operations cpu_seq_ops = {
++ .start = cpu_seq_start,
++ .next = cpu_seq_next,
++ .stop = cpu_seq_stop,
++ .show = cpu_seq_show,
++};
++
++static int cpu_seq_open(struct inode *inode, struct file *file)
++{
++ struct cpu_private *priv = inode->i_private;
++ struct seq_file *seq;
++ int err;
++
++ err = seq_open(file, &cpu_seq_ops);
++ if (!err) {
++ seq = file->private_data;
++ seq->private = priv;
++ }
++
++ return err;
++}
++
++static int write_msr(struct cpu_private *priv, u64 val)
++{
++ u32 low, high;
++
++ high = (val >> 32) & 0xffffffff;
++ low = val & 0xffffffff;
++
++ if (!wrmsr_safe_on_cpu(priv->cpu, priv->reg, low, high))
++ return 0;
++
++ return -EPERM;
++}
++
++static int write_cpu_register(struct cpu_private *priv, const char *buf)
++{
++ int ret = -EPERM;
++ u64 val;
++
++ ret = strict_strtoull(buf, 0, &val);
++ if (ret < 0)
++ return ret;
++
++ /* Supporting only MSRs */
++ if (priv->type < CPU_TSS_BIT)
++ return write_msr(priv, val);
++
++ return ret;
++}
++
++static ssize_t cpu_write(struct file *file, const char __user *ubuf,
++ size_t count, loff_t *off)
++{
++ struct seq_file *seq = file->private_data;
++ struct cpu_private *priv = seq->private;
++ char buf[19];
++
++ if ((priv == NULL) || (count >= sizeof(buf)))
++ return -EINVAL;
++
++ if (copy_from_user(&buf, ubuf, count))
++ return -EFAULT;
++
++ buf[count] = 0;
++
++ if ((cpu_base[priv->type].write) && (cpu_file[priv->file].write))
++ if (!write_cpu_register(priv, buf))
++ return count;
++
++ return -EACCES;
++}
++
++static const struct file_operations cpu_fops = {
++ .owner = THIS_MODULE,
++ .open = cpu_seq_open,
++ .read = seq_read,
++ .write = cpu_write,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++
++static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
++ unsigned file, struct dentry *dentry)
++{
++ struct cpu_private *priv = NULL;
++
++ /* Already intialized */
++ if (file == CPU_INDEX_BIT)
++ if (per_cpu(cpu_arr[type].init, cpu))
++ return 0;
++
++ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++ if (priv == NULL)
++ return -ENOMEM;
++
++ priv->cpu = cpu;
++ priv->type = type;
++ priv->reg = reg;
++ priv->file = file;
++ mutex_lock(&cpu_debug_lock);
++ per_cpu(priv_arr[type], cpu) = priv;
++ per_cpu(cpu_priv_count, cpu)++;
++ mutex_unlock(&cpu_debug_lock);
++
++ if (file)
++ debugfs_create_file(cpu_file[file].name, S_IRUGO,
++ dentry, (void *)priv, &cpu_fops);
++ else {
++ debugfs_create_file(cpu_base[type].name, S_IRUGO,
++ per_cpu(cpu_arr[type].dentry, cpu),
++ (void *)priv, &cpu_fops);
++ mutex_lock(&cpu_debug_lock);
++ per_cpu(cpu_arr[type].init, cpu) = 1;
++ mutex_unlock(&cpu_debug_lock);
++ }
++
++ return 0;
++}
++
++static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg,
++ struct dentry *dentry)
++{
++ unsigned file;
++ int err = 0;
++
++ for (file = 0; file < ARRAY_SIZE(cpu_file); file++) {
++ err = cpu_create_file(cpu, type, reg, file, dentry);
++ if (err)
++ return err;
++ }
++
++ return err;
++}
++
++static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
++{
++ struct dentry *cpu_dentry = NULL;
++ unsigned reg, reg_min, reg_max;
++ int i, err = 0;
++ char reg_dir[12];
++ u32 low, high;
++
++ for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
++ if (!get_cpu_range(cpu, ®_min, ®_max, i,
++ cpu_base[type].flag))
++ continue;
++
++ for (reg = reg_min; reg <= reg_max; reg++) {
++ if (rdmsr_safe_on_cpu(cpu, reg, &low, &high))
++ continue;
++
++ sprintf(reg_dir, "0x%x", reg);
++ cpu_dentry = debugfs_create_dir(reg_dir, dentry);
++ err = cpu_init_regfiles(cpu, type, reg, cpu_dentry);
++ if (err)
++ return err;
++ }
++ }
++
++ return err;
++}
++
++static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
++{
++ struct dentry *cpu_dentry = NULL;
++ unsigned type;
++ int err = 0;
++
++ for (type = 0; type < ARRAY_SIZE(cpu_base) - 1; type++) {
++ if (!is_typeflag_valid(cpu, cpu_base[type].flag))
++ continue;
++ cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
++ per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
++
++ if (type < CPU_TSS_BIT)
++ err = cpu_init_msr(cpu, type, cpu_dentry);
++ else
++ err = cpu_create_file(cpu, type, 0, CPU_INDEX_BIT,
++ cpu_dentry);
++ if (err)
++ return err;
++ }
++
++ return err;
++}
++
++static int cpu_init_cpu(void)
++{
++ struct dentry *cpu_dentry = NULL;
++ struct cpuinfo_x86 *cpui;
++ char cpu_dir[12];
++ unsigned cpu;
++ int err = 0;
++
++ for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
++ cpui = &cpu_data(cpu);
++ if (!cpu_has(cpui, X86_FEATURE_MSR))
++ continue;
++
++ sprintf(cpu_dir, "cpu%d", cpu);
++ cpu_dentry = debugfs_create_dir(cpu_dir, cpu_debugfs_dir);
++ err = cpu_init_allreg(cpu, cpu_dentry);
++
++ pr_info("cpu%d(%d) debug files %d\n",
++ cpu, nr_cpu_ids, per_cpu(cpu_priv_count, cpu));
++ if (per_cpu(cpu_priv_count, cpu) > MAX_CPU_FILES) {
++ pr_err("Register files count %d exceeds limit %d\n",
++ per_cpu(cpu_priv_count, cpu), MAX_CPU_FILES);
++ per_cpu(cpu_priv_count, cpu) = MAX_CPU_FILES;
++ err = -ENFILE;
++ }
++ if (err)
++ return err;
++ }
++
++ return err;
++}
++
++static int __init cpu_debug_init(void)
++{
++ cpu_debugfs_dir = debugfs_create_dir("cpu", arch_debugfs_dir);
++
++ return cpu_init_cpu();
++}
++
++static void __exit cpu_debug_exit(void)
++{
++ int i, cpu;
++
++ if (cpu_debugfs_dir)
++ debugfs_remove_recursive(cpu_debugfs_dir);
++
++ for (cpu = 0; cpu < nr_cpu_ids; cpu++)
++ for (i = 0; i < per_cpu(cpu_priv_count, cpu); i++)
++ kfree(per_cpu(priv_arr[i], cpu));
++}
++
++module_init(cpu_debug_init);
++module_exit(cpu_debug_exit);
++
++MODULE_AUTHOR("Jaswinder Singh Rajput");
++MODULE_DESCRIPTION("CPU Debug module");
++MODULE_LICENSE("GPL");
+diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+index ab1cd30..3f12dab 100644
+--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
++++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+@@ -1351,7 +1351,6 @@ static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol)
+
+ kfree(data->powernow_table);
+ kfree(data);
+- per_cpu(powernow_data, pol->cpu) = NULL;
+
+ return 0;
+ }
+@@ -1371,7 +1370,7 @@ static unsigned int powernowk8_get(unsigned int cpu)
+ int err;
+
+ if (!data)
+- return 0;
++ return -EINVAL;
+
+ smp_call_function_single(cpu, query_values_on_cpu, &err, true);
+ if (err)
+diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
+index a2a03cf..40e1835 100644
+--- a/arch/x86/kernel/cpu/intel.c
++++ b/arch/x86/kernel/cpu/intel.c
+@@ -70,6 +70,7 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
+ if (c->x86_power & (1 << 8)) {
+ set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+ set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
++ set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
+ sched_clock_stable = 1;
+ }
+
+diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
+index 8178d03..804c40e 100644
+--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
++++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
+@@ -94,7 +94,7 @@ static const struct _cache_table __cpuinitconst cache_table[] =
+ { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */
+ { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */
+ { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */
+- { 0xd7, LVL_3, 2048 }, /* 8-way set assoc, 64 byte line size */
++ { 0xd7, LVL_3, 2038 }, /* 8-way set assoc, 64 byte line size */
+ { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
+ { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */
+ { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
+@@ -102,9 +102,6 @@ static const struct _cache_table __cpuinitconst cache_table[] =
+ { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */
+ { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
+ { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
+- { 0xea, LVL_3, 12288 }, /* 24-way set assoc, 64 byte line size */
+- { 0xeb, LVL_3, 18432 }, /* 24-way set assoc, 64 byte line size */
+- { 0xec, LVL_3, 24576 }, /* 24-way set assoc, 64 byte line size */
+ { 0x00, 0, 0}
+ };
+
+diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
+index 0f16a2b..721a77c 100644
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -1374,14 +1374,13 @@ static void mce_init_timer(void)
+ struct timer_list *t = &__get_cpu_var(mce_timer);
+ int *n = &__get_cpu_var(mce_next_interval);
+
+- setup_timer(t, mcheck_timer, smp_processor_id());
+-
+ if (mce_ignore_ce)
+ return;
+
+ *n = check_interval * HZ;
+ if (!*n)
+ return;
++ setup_timer(t, mcheck_timer, smp_processor_id());
+ t->expires = round_jiffies(jiffies + *n);
+ add_timer_on(t, smp_processor_id());
+ }
+@@ -1992,11 +1991,9 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+ break;
+ case CPU_DOWN_FAILED:
+ case CPU_DOWN_FAILED_FROZEN:
+- if (!mce_ignore_ce && check_interval) {
+- t->expires = round_jiffies(jiffies +
++ t->expires = round_jiffies(jiffies +
+ __get_cpu_var(mce_next_interval));
+- add_timer_on(t, cpu);
+- }
++ add_timer_on(t, cpu);
+ smp_call_function_single(cpu, mce_reenable_cpu, &action, 1);
+ break;
+ case CPU_POST_DEAD:
+diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
+index 687638e..b3a1dba 100644
+--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
++++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
+@@ -49,8 +49,6 @@ static DEFINE_PER_CPU(struct thermal_state, thermal_state);
+
+ static atomic_t therm_throt_en = ATOMIC_INIT(0);
+
+-static u32 lvtthmr_init __read_mostly;
+-
+ #ifdef CONFIG_SYSFS
+ #define define_therm_throt_sysdev_one_ro(_name) \
+ static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL)
+@@ -256,27 +254,14 @@ asmlinkage void smp_thermal_interrupt(struct pt_regs *regs)
+ ack_APIC_irq();
+ }
+
+-void __init mcheck_intel_therm_init(void)
+-{
+- /*
+- * This function is only called on boot CPU. Save the init thermal
+- * LVT value on BSP and use that value to restore APs' thermal LVT
+- * entry BIOS programmed later
+- */
+- if (cpu_has(&boot_cpu_data, X86_FEATURE_ACPI) &&
+- cpu_has(&boot_cpu_data, X86_FEATURE_ACC))
+- lvtthmr_init = apic_read(APIC_LVTTHMR);
+-}
+-
+ void intel_init_thermal(struct cpuinfo_x86 *c)
+ {
+ unsigned int cpu = smp_processor_id();
+ int tm2 = 0;
+ u32 l, h;
+
+- /* Thermal monitoring depends on APIC, ACPI and clock modulation */
+- if (!cpu_has_apic || !cpu_has(c, X86_FEATURE_ACPI) ||
+- !cpu_has(c, X86_FEATURE_ACC))
++ /* Thermal monitoring depends on ACPI and clock modulation*/
++ if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC))
+ return;
+
+ /*
+@@ -285,20 +270,7 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
+ * since it might be delivered via SMI already:
+ */
+ rdmsr(MSR_IA32_MISC_ENABLE, l, h);
+-
+- /*
+- * The initial value of thermal LVT entries on all APs always reads
+- * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI
+- * sequence to them and LVT registers are reset to 0s except for
+- * the mask bits which are set to 1s when APs receive INIT IPI.
+- * Always restore the value that BIOS has programmed on AP based on
+- * BSP's info we saved since BIOS is always setting the same value
+- * for all threads/cores
+- */
+- apic_write(APIC_LVTTHMR, lvtthmr_init);
+-
+- h = lvtthmr_init;
+-
++ h = apic_read(APIC_LVTTHMR);
+ if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
+ printk(KERN_DEBUG
+ "CPU%d: Thermal monitoring handled by SMI\n", cpu);
+diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
+index 898df97..fab786f 100644
+--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
++++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
+@@ -712,7 +712,7 @@ static void probe_nmi_watchdog(void)
+ switch (boot_cpu_data.x86_vendor) {
+ case X86_VENDOR_AMD:
+ if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 &&
+- boot_cpu_data.x86 != 16 && boot_cpu_data.x86 != 17)
++ boot_cpu_data.x86 != 16)
+ return;
+ wd_ops = &k7_wd_ops;
+ break;
+diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
+index 0c91110..6a52d4b 100644
+--- a/arch/x86/kernel/cpuid.c
++++ b/arch/x86/kernel/cpuid.c
+@@ -192,8 +192,7 @@ static int __init cpuid_init(void)
+ int i, err = 0;
+ i = 0;
+
+- if (__register_chrdev(CPUID_MAJOR, 0, NR_CPUS,
+- "cpu/cpuid", &cpuid_fops)) {
++ if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
+ printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
+ CPUID_MAJOR);
+ err = -EBUSY;
+@@ -222,7 +221,7 @@ out_class:
+ }
+ class_destroy(cpuid_class);
+ out_chrdev:
+- __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
++ unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+ out:
+ return err;
+ }
+@@ -234,7 +233,7 @@ static void __exit cpuid_exit(void)
+ for_each_online_cpu(cpu)
+ cpuid_device_destroy(cpu);
+ class_destroy(cpuid_class);
+- __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
++ unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+ unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
+ }
+
+diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
+index 5877873..dedc2bd 100644
+--- a/arch/x86/kernel/hpet.c
++++ b/arch/x86/kernel/hpet.c
+@@ -33,8 +33,6 @@
+ * HPET address is set in acpi/boot.c, when an ACPI entry exists
+ */
+ unsigned long hpet_address;
+-u8 hpet_msi_disable;
+-
+ #ifdef CONFIG_PCI_MSI
+ static unsigned long hpet_num_timers;
+ #endif
+@@ -586,9 +584,6 @@ static void hpet_msi_capability_lookup(unsigned int start_timer)
+ unsigned int num_timers_used = 0;
+ int i;
+
+- if (hpet_msi_disable)
+- return;
+-
+ id = hpet_readl(HPET_ID);
+
+ num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
+@@ -916,9 +911,6 @@ static __init int hpet_late_init(void)
+ hpet_reserve_platform_timers(hpet_readl(HPET_ID));
+ hpet_print_config();
+
+- if (hpet_msi_disable)
+- return 0;
+-
+ for_each_online_cpu(cpu) {
+ hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);
+ }
+diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
+index 5eaeb5e..6a3cefc 100644
+--- a/arch/x86/kernel/msr.c
++++ b/arch/x86/kernel/msr.c
+@@ -251,7 +251,7 @@ static int __init msr_init(void)
+ int i, err = 0;
+ i = 0;
+
+- if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) {
++ if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
+ printk(KERN_ERR "msr: unable to get major %d for msr\n",
+ MSR_MAJOR);
+ err = -EBUSY;
+@@ -279,7 +279,7 @@ out_class:
+ msr_device_destroy(i);
+ class_destroy(msr_class);
+ out_chrdev:
+- __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
++ unregister_chrdev(MSR_MAJOR, "cpu/msr");
+ out:
+ return err;
+ }
+@@ -290,7 +290,7 @@ static void __exit msr_exit(void)
+ for_each_online_cpu(cpu)
+ msr_device_destroy(cpu);
+ class_destroy(msr_class);
+- __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
++ unregister_chrdev(MSR_MAJOR, "cpu/msr");
+ unregister_hotcpu_notifier(&msr_class_cpu_notifier);
+ }
+
+diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
+index e6ec8a2..971a3be 100644
+--- a/arch/x86/kernel/pci-calgary_64.c
++++ b/arch/x86/kernel/pci-calgary_64.c
+@@ -318,15 +318,13 @@ static inline struct iommu_table *find_iommu_table(struct device *dev)
+
+ pdev = to_pci_dev(dev);
+
+- /* search up the device tree for an iommu */
+ pbus = pdev->bus;
+- do {
+- tbl = pci_iommu(pbus);
+- if (tbl && tbl->it_busno == pbus->number)
+- break;
+- tbl = NULL;
++
++ /* is the device behind a bridge? Look for the root bus */
++ while (pbus->parent)
+ pbus = pbus->parent;
+- } while (pbus);
++
++ tbl = pci_iommu(pbus);
+
+ BUG_ON(tbl && (tbl->it_busno != pbus->number));
+
+diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
+index 6ac3931..a6e804d 100644
+--- a/arch/x86/kernel/pci-dma.c
++++ b/arch/x86/kernel/pci-dma.c
+@@ -214,7 +214,7 @@ static __init int iommu_setup(char *p)
+ if (!strncmp(p, "allowdac", 8))
+ forbid_dac = 0;
+ if (!strncmp(p, "nodac", 5))
+- forbid_dac = 1;
++ forbid_dac = -1;
+ if (!strncmp(p, "usedac", 6)) {
+ forbid_dac = -1;
+ return 1;
+diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
+index fcc0b5c..a7f1b64 100644
+--- a/arch/x86/kernel/pci-gart_64.c
++++ b/arch/x86/kernel/pci-gart_64.c
+@@ -856,7 +856,7 @@ void __init gart_parse_options(char *p)
+ #endif
+ if (isdigit(*p) && get_option(&p, &arg))
+ iommu_size = arg;
+- if (!strncmp(p, "fullflush", 9))
++ if (!strncmp(p, "fullflush", 8))
+ iommu_fullflush = 1;
+ if (!strncmp(p, "nofullflush", 11))
+ iommu_fullflush = 0;
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index f010ab4..5284cd2 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -91,6 +91,18 @@ void flush_thread(void)
+ {
+ struct task_struct *tsk = current;
+
++#ifdef CONFIG_X86_64
++ if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) {
++ clear_tsk_thread_flag(tsk, TIF_ABI_PENDING);
++ if (test_tsk_thread_flag(tsk, TIF_IA32)) {
++ clear_tsk_thread_flag(tsk, TIF_IA32);
++ } else {
++ set_tsk_thread_flag(tsk, TIF_IA32);
++ current_thread_info()->status |= TS_COMPAT;
++ }
++ }
++#endif
++
+ clear_tsk_thread_flag(tsk, TIF_DEBUG);
+
+ tsk->thread.debugreg0 = 0;
+diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
+index f9ce04f..eb62cbc 100644
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -540,17 +540,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp,
+ return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
+ }
+
+-void set_personality_ia32(void)
+-{
+- /* inherit personality from parent */
+-
+- /* Make sure to be in 32bit mode */
+- set_thread_flag(TIF_IA32);
+-
+- /* Prepare the first "return" to user space */
+- current_thread_info()->status |= TS_COMPAT;
+-}
+-
+ unsigned long get_wchan(struct task_struct *p)
+ {
+ unsigned long stack;
+diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
+index c06acdd..7b058a2 100644
+--- a/arch/x86/kernel/ptrace.c
++++ b/arch/x86/kernel/ptrace.c
+@@ -408,14 +408,14 @@ static int genregs_get(struct task_struct *target,
+ {
+ if (kbuf) {
+ unsigned long *k = kbuf;
+- while (count >= sizeof(*k)) {
++ while (count > 0) {
+ *k++ = getreg(target, pos);
+ count -= sizeof(*k);
+ pos += sizeof(*k);
+ }
+ } else {
+ unsigned long __user *u = ubuf;
+- while (count >= sizeof(*u)) {
++ while (count > 0) {
+ if (__put_user(getreg(target, pos), u++))
+ return -EFAULT;
+ count -= sizeof(*u);
+@@ -434,14 +434,14 @@ static int genregs_set(struct task_struct *target,
+ int ret = 0;
+ if (kbuf) {
+ const unsigned long *k = kbuf;
+- while (count >= sizeof(*k) && !ret) {
++ while (count > 0 && !ret) {
+ ret = putreg(target, pos, *k++);
+ count -= sizeof(*k);
+ pos += sizeof(*k);
+ }
+ } else {
+ const unsigned long __user *u = ubuf;
+- while (count >= sizeof(*u) && !ret) {
++ while (count > 0 && !ret) {
+ unsigned long word;
+ ret = __get_user(word, u++);
+ if (ret)
+@@ -1219,14 +1219,14 @@ static int genregs32_get(struct task_struct *target,
+ {
+ if (kbuf) {
+ compat_ulong_t *k = kbuf;
+- while (count >= sizeof(*k)) {
++ while (count > 0) {
+ getreg32(target, pos, k++);
+ count -= sizeof(*k);
+ pos += sizeof(*k);
+ }
+ } else {
+ compat_ulong_t __user *u = ubuf;
+- while (count >= sizeof(*u)) {
++ while (count > 0) {
+ compat_ulong_t word;
+ getreg32(target, pos, &word);
+ if (__put_user(word, u++))
+@@ -1247,14 +1247,14 @@ static int genregs32_set(struct task_struct *target,
+ int ret = 0;
+ if (kbuf) {
+ const compat_ulong_t *k = kbuf;
+- while (count >= sizeof(*k) && !ret) {
++ while (count > 0 && !ret) {
+ ret = putreg32(target, pos, *k++);
+ count -= sizeof(*k);
+ pos += sizeof(*k);
+ }
+ } else {
+ const compat_ulong_t __user *u = ubuf;
+- while (count >= sizeof(*u) && !ret) {
++ while (count > 0 && !ret) {
+ compat_ulong_t word;
+ ret = __get_user(word, u++);
+ if (ret)
+diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
+index 0040164..6c3b2c6 100644
+--- a/arch/x86/kernel/quirks.c
++++ b/arch/x86/kernel/quirks.c
+@@ -491,19 +491,6 @@ void force_hpet_resume(void)
+ break;
+ }
+ }
+-
+-/*
+- * HPET MSI on some boards (ATI SB700/SB800) has side effect on
+- * floppy DMA. Disable HPET MSI on such platforms.
+- */
+-static void force_disable_hpet_msi(struct pci_dev *unused)
+-{
+- hpet_msi_disable = 1;
+-}
+-
+-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
+- force_disable_hpet_msi);
+-
+ #endif
+
+ #if defined(CONFIG_PCI) && defined(CONFIG_NUMA)
+diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
+index bff34d6..f930787 100644
+--- a/arch/x86/kernel/reboot.c
++++ b/arch/x86/kernel/reboot.c
+@@ -203,15 +203,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "0T656F"),
+ },
+ },
+- { /* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G*/
+- .callback = set_bios_reboot,
+- .ident = "Dell OptiPlex 760",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 760"),
+- DMI_MATCH(DMI_BOARD_NAME, "0G919G"),
+- },
+- },
+ { /* Handle problems with rebooting on Dell 2400's */
+ .callback = set_bios_reboot,
+ .ident = "Dell PowerEdge 2400",
+@@ -268,14 +259,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"),
+ },
+ },
+- { /* Handle problems with rebooting on ASUS P4S800 */
+- .callback = set_bios_reboot,
+- .ident = "ASUS P4S800",
+- .matches = {
+- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+- DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
+- },
+- },
+ { }
+ };
+
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 8425f7e..2a34f9c 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -109,7 +109,6 @@
+ #ifdef CONFIG_X86_64
+ #include <asm/numa_64.h>
+ #endif
+-#include <asm/mce.h>
+
+ /*
+ * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
+@@ -667,27 +666,19 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix/MSC"),
+ },
+ },
++ {
+ /*
+- * AMI BIOS with low memory corruption was found on Intel DG45ID and
+- * DG45FC boards.
+- * It has a different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
++ * AMI BIOS with low memory corruption was found on Intel DG45ID board.
++ * It hase different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
+ * match only DMI_BOARD_NAME and see if there is more bad products
+ * with this vendor.
+ */
+- {
+ .callback = dmi_low_memory_corruption,
+ .ident = "AMI BIOS",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "DG45ID"),
+ },
+ },
+- {
+- .callback = dmi_low_memory_corruption,
+- .ident = "AMI BIOS",
+- .matches = {
+- DMI_MATCH(DMI_BOARD_NAME, "DG45FC"),
+- },
+- },
+ #endif
+ {}
+ };
+@@ -1040,8 +1031,6 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+ #endif
+ x86_init.oem.banner();
+-
+- mcheck_intel_therm_init();
+ }
+
+ #ifdef CONFIG_X86_32
+diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
+index dee1ff7..1884a8d 100644
+--- a/arch/x86/kernel/sys_i386_32.c
++++ b/arch/x86/kernel/sys_i386_32.c
+@@ -24,6 +24,31 @@
+
+ #include <asm/syscalls.h>
+
++asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ int error = -EBADF;
++ struct file *file = NULL;
++ struct mm_struct *mm = current->mm;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(&mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(&mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ /*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/i386 didn't use to be able to handle more than
+@@ -52,7 +77,7 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+- err = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags,
++ err = sys_mmap2(a.addr, a.len, a.prot, a.flags,
+ a.fd, a.offset >> PAGE_SHIFT);
+ out:
+ return err;
+diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
+index 8aa2057..45e00eb 100644
+--- a/arch/x86/kernel/sys_x86_64.c
++++ b/arch/x86/kernel/sys_x86_64.c
+@@ -23,11 +23,26 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
+ unsigned long, fd, unsigned long, off)
+ {
+ long error;
++ struct file *file;
++
+ error = -EINVAL;
+ if (off & ~PAGE_MASK)
+ goto out;
+
+- error = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
++ error = -EBADF;
++ file = NULL;
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
+ out:
+ return error;
+ }
+diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
+index 76d70a4..0157cd2 100644
+--- a/arch/x86/kernel/syscall_table_32.S
++++ b/arch/x86/kernel/syscall_table_32.S
+@@ -191,7 +191,7 @@ ENTRY(sys_call_table)
+ .long sys_ni_syscall /* reserved for streams2 */
+ .long ptregs_vfork /* 190 */
+ .long sys_getrlimit
+- .long sys_mmap_pgoff
++ .long sys_mmap2
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
+index 364d015..1740c85 100644
+--- a/arch/x86/kernel/tlb_uv.c
++++ b/arch/x86/kernel/tlb_uv.c
+@@ -817,8 +817,10 @@ static int __init uv_init_blade(int blade)
+ */
+ apicid = blade_to_first_apicid(blade);
+ pa = uv_read_global_mmr64(pnode, UVH_BAU_DATA_CONFIG);
+- uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
++ if ((pa & 0xff) != UV_BAU_MESSAGE) {
++ uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
+ ((apicid << 32) | UV_BAU_MESSAGE));
++ }
+ return 0;
+ }
+
+diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
+index 597683a..cd982f4 100644
+--- a/arch/x86/kernel/tsc.c
++++ b/arch/x86/kernel/tsc.c
+@@ -763,7 +763,6 @@ void mark_tsc_unstable(char *reason)
+ {
+ if (!tsc_unstable) {
+ tsc_unstable = 1;
+- sched_clock_stable = 0;
+ printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
+ /* Change only the rating, when not registered */
+ if (clocksource_tsc.mult)
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index e02dbb6..1be5cd6 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -613,9 +613,6 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
+ {
+ int rc = 0;
+
+- /* x86 instructions are limited to 15 bytes. */
+- if (eip + size - ctxt->decode.eip_orig > 15)
+- return X86EMUL_UNHANDLEABLE;
+ eip += ctxt->cs_base;
+ while (size--) {
+ rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++);
+@@ -874,7 +871,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+ /* Shadow copy of register state. Committed on successful emulation. */
+
+ memset(c, 0, sizeof(struct decode_cache));
+- c->eip = c->eip_orig = kvm_rip_read(ctxt->vcpu);
++ c->eip = kvm_rip_read(ctxt->vcpu);
+ ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
+ memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
+
+diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
+index 88ad162..144e7f6 100644
+--- a/arch/x86/kvm/i8254.c
++++ b/arch/x86/kvm/i8254.c
+@@ -465,9 +465,6 @@ static int pit_ioport_read(struct kvm_io_device *this,
+ return -EOPNOTSUPP;
+
+ addr &= KVM_PIT_CHANNEL_MASK;
+- if (addr == 3)
+- return 0;
+-
+ s = &pit_state->channels[addr];
+
+ mutex_lock(&pit_state->lock);
+diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
+index 8dfeaaa..23c2176 100644
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -374,12 +374,6 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
+ if (unlikely(!apic_enabled(apic)))
+ break;
+
+- if (trig_mode) {
+- apic_debug("level trig mode for vector %d", vector);
+- apic_set_vector(vector, apic->regs + APIC_TMR);
+- } else
+- apic_clear_vector(vector, apic->regs + APIC_TMR);
+-
+ result = !apic_test_and_set_irr(vector, apic);
+ trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode,
+ trig_mode, vector, !result);
+@@ -390,6 +384,11 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
+ break;
+ }
+
++ if (trig_mode) {
++ apic_debug("level trig mode for vector %d", vector);
++ apic_set_vector(vector, apic->regs + APIC_TMR);
++ } else
++ apic_clear_vector(vector, apic->regs + APIC_TMR);
+ kvm_vcpu_kick(vcpu);
+ break;
+
+@@ -1157,7 +1156,6 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
+ hrtimer_cancel(&apic->lapic_timer.timer);
+ update_divide_count(apic);
+ start_apic_timer(apic);
+- apic->irr_pending = true;
+ }
+
+ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
+diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
+index 3a01519..818b92a 100644
+--- a/arch/x86/kvm/mmu.c
++++ b/arch/x86/kvm/mmu.c
+@@ -477,7 +477,7 @@ static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
+
+ addr = gfn_to_hva(kvm, gfn);
+ if (kvm_is_error_hva(addr))
+- return PT_PAGE_TABLE_LEVEL;
++ return page_size;
+
+ down_read(¤t->mm->mmap_sem);
+ vma = find_vma(current->mm, addr);
+@@ -515,9 +515,11 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
+ if (host_level == PT_PAGE_TABLE_LEVEL)
+ return host_level;
+
+- for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level)
++ for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level) {
++
+ if (has_wrprotected_page(vcpu->kvm, large_gfn, level))
+ break;
++ }
+
+ return level - 1;
+ }
+diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
+index 5fa3325..72558f8 100644
+--- a/arch/x86/kvm/paging_tmpl.h
++++ b/arch/x86/kvm/paging_tmpl.h
+@@ -150,9 +150,7 @@ walk:
+ walker->table_gfn[walker->level - 1] = table_gfn;
+ walker->pte_gpa[walker->level - 1] = pte_gpa;
+
+- if (kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte)))
+- goto not_present;
+-
++ kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte));
+ trace_kvm_mmu_paging_element(pte, walker->level);
+
+ if (!is_present_gpte(pte))
+@@ -457,6 +455,8 @@ out_unlock:
+ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
+ {
+ struct kvm_shadow_walk_iterator iterator;
++ pt_element_t gpte;
++ gpa_t pte_gpa = -1;
+ int level;
+ u64 *sptep;
+ int need_flush = 0;
+@@ -471,6 +471,10 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
+ if (level == PT_PAGE_TABLE_LEVEL ||
+ ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) ||
+ ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) {
++ struct kvm_mmu_page *sp = page_header(__pa(sptep));
++
++ pte_gpa = (sp->gfn << PAGE_SHIFT);
++ pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t);
+
+ if (is_shadow_present_pte(*sptep)) {
+ rmap_remove(vcpu->kvm, sptep);
+@@ -489,6 +493,18 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
+ if (need_flush)
+ kvm_flush_remote_tlbs(vcpu->kvm);
+ spin_unlock(&vcpu->kvm->mmu_lock);
++
++ if (pte_gpa == -1)
++ return;
++ if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte,
++ sizeof(pt_element_t)))
++ return;
++ if (is_present_gpte(gpte) && (gpte & PT_ACCESSED_MASK)) {
++ if (mmu_topup_memory_caches(vcpu))
++ return;
++ kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte,
++ sizeof(pt_element_t), 0);
++ }
+ }
+
+ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index e78d990..ae07d26 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -484,19 +484,16 @@ static inline u32 bit(int bitno)
+ * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
+ *
+ * This list is modified at module load time to reflect the
+- * capabilities of the host cpu. This capabilities test skips MSRs that are
+- * kvm-specific. Those are put in the beginning of the list.
++ * capabilities of the host cpu.
+ */
+-
+-#define KVM_SAVE_MSRS_BEGIN 2
+ static u32 msrs_to_save[] = {
+- MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
+ MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
+ MSR_K6_STAR,
+ #ifdef CONFIG_X86_64
+ MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
+ #endif
+- MSR_IA32_TSC, MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
++ MSR_IA32_TSC, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
++ MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
+ };
+
+ static unsigned num_msrs_to_save;
+@@ -583,7 +580,7 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
+ {
+ static int version;
+ struct pvclock_wall_clock wc;
+- struct timespec boot;
++ struct timespec now, sys, boot;
+
+ if (!wall_clock)
+ return;
+@@ -598,7 +595,9 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
+ * wall clock specified here. guest system time equals host
+ * system time for us, thus we must fill in host boot time here.
+ */
+- getboottime(&boot);
++ now = current_kernel_time();
++ ktime_get_ts(&sys);
++ boot = ns_to_timespec(timespec_to_ns(&now) - timespec_to_ns(&sys));
+
+ wc.sec = boot.tv_sec;
+ wc.nsec = boot.tv_nsec;
+@@ -673,14 +672,12 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
+ local_irq_save(flags);
+ kvm_get_msr(v, MSR_IA32_TSC, &vcpu->hv_clock.tsc_timestamp);
+ ktime_get_ts(&ts);
+- monotonic_to_bootbased(&ts);
+ local_irq_restore(flags);
+
+ /* With all the info we got, fill in the values */
+
+ vcpu->hv_clock.system_time = ts.tv_nsec +
+- (NSEC_PER_SEC * (u64)ts.tv_sec) + v->kvm->arch.kvmclock_offset;
+-
++ (NSEC_PER_SEC * (u64)ts.tv_sec);
+ /*
+ * The interface expects us to write an even number signaling that the
+ * update is finished. Since the guest won't see the intermediate
+@@ -1227,7 +1224,6 @@ int kvm_dev_ioctl_check_extension(long ext)
+ case KVM_CAP_PIT2:
+ case KVM_CAP_PIT_STATE2:
+ case KVM_CAP_SET_IDENTITY_MAP_ADDR:
+- case KVM_CAP_ADJUST_CLOCK:
+ r = 1;
+ break;
+ case KVM_CAP_COALESCED_MMIO:
+@@ -2425,44 +2421,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
+ r = 0;
+ break;
+ }
+- case KVM_SET_CLOCK: {
+- struct timespec now;
+- struct kvm_clock_data user_ns;
+- u64 now_ns;
+- s64 delta;
+-
+- r = -EFAULT;
+- if (copy_from_user(&user_ns, argp, sizeof(user_ns)))
+- goto out;
+-
+- r = -EINVAL;
+- if (user_ns.flags)
+- goto out;
+-
+- r = 0;
+- ktime_get_ts(&now);
+- now_ns = timespec_to_ns(&now);
+- delta = user_ns.clock - now_ns;
+- kvm->arch.kvmclock_offset = delta;
+- break;
+- }
+- case KVM_GET_CLOCK: {
+- struct timespec now;
+- struct kvm_clock_data user_ns;
+- u64 now_ns;
+-
+- ktime_get_ts(&now);
+- now_ns = timespec_to_ns(&now);
+- user_ns.clock = kvm->arch.kvmclock_offset + now_ns;
+- user_ns.flags = 0;
+-
+- r = -EFAULT;
+- if (copy_to_user(argp, &user_ns, sizeof(user_ns)))
+- goto out;
+- r = 0;
+- break;
+- }
+-
+ default:
+ ;
+ }
+@@ -2475,8 +2433,7 @@ static void kvm_init_msr_list(void)
+ u32 dummy[2];
+ unsigned i, j;
+
+- /* skip the first msrs in the list. KVM-specific */
+- for (i = j = KVM_SAVE_MSRS_BEGIN; i < ARRAY_SIZE(msrs_to_save); i++) {
++ for (i = j = 0; i < ARRAY_SIZE(msrs_to_save); i++) {
+ if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0)
+ continue;
+ if (j < i)
+@@ -4805,13 +4762,12 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
+ GFP_KERNEL);
+ if (!vcpu->arch.mce_banks) {
+ r = -ENOMEM;
+- goto fail_free_lapic;
++ goto fail_mmu_destroy;
+ }
+ vcpu->arch.mcg_cap = KVM_MAX_MCE_BANKS;
+
+ return 0;
+-fail_free_lapic:
+- kvm_free_lapic(vcpu);
++
+ fail_mmu_destroy:
+ kvm_mmu_destroy(vcpu);
+ fail_free_pio_data:
+@@ -4822,7 +4778,6 @@ fail:
+
+ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
+ {
+- kfree(vcpu->arch.mce_banks);
+ kvm_free_lapic(vcpu);
+ down_read(&vcpu->kvm->slots_lock);
+ kvm_mmu_destroy(vcpu);
+diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
+index c2b6f39..85f5db9 100644
+--- a/arch/x86/lib/Makefile
++++ b/arch/x86/lib/Makefile
+@@ -2,14 +2,14 @@
+ # Makefile for x86 specific library files.
+ #
+
+-obj-$(CONFIG_SMP) += msr-smp.o
++obj-$(CONFIG_SMP) := msr.o
+
+ lib-y := delay.o
+ lib-y += thunk_$(BITS).o
+ lib-y += usercopy_$(BITS).o getuser.o putuser.o
+ lib-y += memcpy_$(BITS).o
+
+-obj-y += msr.o msr-reg.o msr-reg-export.o
++obj-y += msr-reg.o msr-reg-export.o
+
+ ifeq ($(CONFIG_X86_32),y)
+ obj-y += atomic64_32.o
+diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c
+deleted file mode 100644
+index a6b1b86..0000000
+--- a/arch/x86/lib/msr-smp.c
++++ /dev/null
+@@ -1,204 +0,0 @@
+-#include <linux/module.h>
+-#include <linux/preempt.h>
+-#include <linux/smp.h>
+-#include <asm/msr.h>
+-
+-static void __rdmsr_on_cpu(void *info)
+-{
+- struct msr_info *rv = info;
+- struct msr *reg;
+- int this_cpu = raw_smp_processor_id();
+-
+- if (rv->msrs)
+- reg = per_cpu_ptr(rv->msrs, this_cpu);
+- else
+- reg = &rv->reg;
+-
+- rdmsr(rv->msr_no, reg->l, reg->h);
+-}
+-
+-static void __wrmsr_on_cpu(void *info)
+-{
+- struct msr_info *rv = info;
+- struct msr *reg;
+- int this_cpu = raw_smp_processor_id();
+-
+- if (rv->msrs)
+- reg = per_cpu_ptr(rv->msrs, this_cpu);
+- else
+- reg = &rv->reg;
+-
+- wrmsr(rv->msr_no, reg->l, reg->h);
+-}
+-
+-int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+-{
+- int err;
+- struct msr_info rv;
+-
+- memset(&rv, 0, sizeof(rv));
+-
+- rv.msr_no = msr_no;
+- err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
+- *l = rv.reg.l;
+- *h = rv.reg.h;
+-
+- return err;
+-}
+-EXPORT_SYMBOL(rdmsr_on_cpu);
+-
+-int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+-{
+- int err;
+- struct msr_info rv;
+-
+- memset(&rv, 0, sizeof(rv));
+-
+- rv.msr_no = msr_no;
+- rv.reg.l = l;
+- rv.reg.h = h;
+- err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
+-
+- return err;
+-}
+-EXPORT_SYMBOL(wrmsr_on_cpu);
+-
+-static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
+- struct msr *msrs,
+- void (*msr_func) (void *info))
+-{
+- struct msr_info rv;
+- int this_cpu;
+-
+- memset(&rv, 0, sizeof(rv));
+-
+- rv.msrs = msrs;
+- rv.msr_no = msr_no;
+-
+- this_cpu = get_cpu();
+-
+- if (cpumask_test_cpu(this_cpu, mask))
+- msr_func(&rv);
+-
+- smp_call_function_many(mask, msr_func, &rv, 1);
+- put_cpu();
+-}
+-
+-/* rdmsr on a bunch of CPUs
+- *
+- * @mask: which CPUs
+- * @msr_no: which MSR
+- * @msrs: array of MSR values
+- *
+- */
+-void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+-{
+- __rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
+-}
+-EXPORT_SYMBOL(rdmsr_on_cpus);
+-
+-/*
+- * wrmsr on a bunch of CPUs
+- *
+- * @mask: which CPUs
+- * @msr_no: which MSR
+- * @msrs: array of MSR values
+- *
+- */
+-void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+-{
+- __rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
+-}
+-EXPORT_SYMBOL(wrmsr_on_cpus);
+-
+-/* These "safe" variants are slower and should be used when the target MSR
+- may not actually exist. */
+-static void __rdmsr_safe_on_cpu(void *info)
+-{
+- struct msr_info *rv = info;
+-
+- rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
+-}
+-
+-static void __wrmsr_safe_on_cpu(void *info)
+-{
+- struct msr_info *rv = info;
+-
+- rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
+-}
+-
+-int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+-{
+- int err;
+- struct msr_info rv;
+-
+- memset(&rv, 0, sizeof(rv));
+-
+- rv.msr_no = msr_no;
+- err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
+- *l = rv.reg.l;
+- *h = rv.reg.h;
+-
+- return err ? err : rv.err;
+-}
+-EXPORT_SYMBOL(rdmsr_safe_on_cpu);
+-
+-int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+-{
+- int err;
+- struct msr_info rv;
+-
+- memset(&rv, 0, sizeof(rv));
+-
+- rv.msr_no = msr_no;
+- rv.reg.l = l;
+- rv.reg.h = h;
+- err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
+-
+- return err ? err : rv.err;
+-}
+-EXPORT_SYMBOL(wrmsr_safe_on_cpu);
+-
+-/*
+- * These variants are significantly slower, but allows control over
+- * the entire 32-bit GPR set.
+- */
+-static void __rdmsr_safe_regs_on_cpu(void *info)
+-{
+- struct msr_regs_info *rv = info;
+-
+- rv->err = rdmsr_safe_regs(rv->regs);
+-}
+-
+-static void __wrmsr_safe_regs_on_cpu(void *info)
+-{
+- struct msr_regs_info *rv = info;
+-
+- rv->err = wrmsr_safe_regs(rv->regs);
+-}
+-
+-int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+-{
+- int err;
+- struct msr_regs_info rv;
+-
+- rv.regs = regs;
+- rv.err = -EIO;
+- err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
+-
+- return err ? err : rv.err;
+-}
+-EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
+-
+-int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+-{
+- int err;
+- struct msr_regs_info rv;
+-
+- rv.regs = regs;
+- rv.err = -EIO;
+- err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
+-
+- return err ? err : rv.err;
+-}
+-EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
+diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
+index 8f8eebd..33a1e3c 100644
+--- a/arch/x86/lib/msr.c
++++ b/arch/x86/lib/msr.c
+@@ -1,23 +1,226 @@
+ #include <linux/module.h>
+ #include <linux/preempt.h>
++#include <linux/smp.h>
+ #include <asm/msr.h>
+
+-struct msr *msrs_alloc(void)
++struct msr_info {
++ u32 msr_no;
++ struct msr reg;
++ struct msr *msrs;
++ int off;
++ int err;
++};
++
++static void __rdmsr_on_cpu(void *info)
++{
++ struct msr_info *rv = info;
++ struct msr *reg;
++ int this_cpu = raw_smp_processor_id();
++
++ if (rv->msrs)
++ reg = &rv->msrs[this_cpu - rv->off];
++ else
++ reg = &rv->reg;
++
++ rdmsr(rv->msr_no, reg->l, reg->h);
++}
++
++static void __wrmsr_on_cpu(void *info)
++{
++ struct msr_info *rv = info;
++ struct msr *reg;
++ int this_cpu = raw_smp_processor_id();
++
++ if (rv->msrs)
++ reg = &rv->msrs[this_cpu - rv->off];
++ else
++ reg = &rv->reg;
++
++ wrmsr(rv->msr_no, reg->l, reg->h);
++}
++
++int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
++{
++ int err;
++ struct msr_info rv;
++
++ memset(&rv, 0, sizeof(rv));
++
++ rv.msr_no = msr_no;
++ err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
++ *l = rv.reg.l;
++ *h = rv.reg.h;
++
++ return err;
++}
++EXPORT_SYMBOL(rdmsr_on_cpu);
++
++int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
++{
++ int err;
++ struct msr_info rv;
++
++ memset(&rv, 0, sizeof(rv));
++
++ rv.msr_no = msr_no;
++ rv.reg.l = l;
++ rv.reg.h = h;
++ err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
++
++ return err;
++}
++EXPORT_SYMBOL(wrmsr_on_cpu);
++
++/* rdmsr on a bunch of CPUs
++ *
++ * @mask: which CPUs
++ * @msr_no: which MSR
++ * @msrs: array of MSR values
++ *
++ */
++void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs)
++{
++ struct msr_info rv;
++ int this_cpu;
++
++ memset(&rv, 0, sizeof(rv));
++
++ rv.off = cpumask_first(mask);
++ rv.msrs = msrs;
++ rv.msr_no = msr_no;
++
++ this_cpu = get_cpu();
++
++ if (cpumask_test_cpu(this_cpu, mask))
++ __rdmsr_on_cpu(&rv);
++
++ smp_call_function_many(mask, __rdmsr_on_cpu, &rv, 1);
++ put_cpu();
++}
++EXPORT_SYMBOL(rdmsr_on_cpus);
++
++/*
++ * wrmsr on a bunch of CPUs
++ *
++ * @mask: which CPUs
++ * @msr_no: which MSR
++ * @msrs: array of MSR values
++ *
++ */
++void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs)
++{
++ struct msr_info rv;
++ int this_cpu;
++
++ memset(&rv, 0, sizeof(rv));
++
++ rv.off = cpumask_first(mask);
++ rv.msrs = msrs;
++ rv.msr_no = msr_no;
++
++ this_cpu = get_cpu();
++
++ if (cpumask_test_cpu(this_cpu, mask))
++ __wrmsr_on_cpu(&rv);
++
++ smp_call_function_many(mask, __wrmsr_on_cpu, &rv, 1);
++ put_cpu();
++}
++EXPORT_SYMBOL(wrmsr_on_cpus);
++
++/* These "safe" variants are slower and should be used when the target MSR
++ may not actually exist. */
++static void __rdmsr_safe_on_cpu(void *info)
++{
++ struct msr_info *rv = info;
++
++ rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
++}
++
++static void __wrmsr_safe_on_cpu(void *info)
++{
++ struct msr_info *rv = info;
++
++ rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
++}
++
++int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+ {
+- struct msr *msrs = NULL;
++ int err;
++ struct msr_info rv;
+
+- msrs = alloc_percpu(struct msr);
+- if (!msrs) {
+- pr_warning("%s: error allocating msrs\n", __func__);
+- return NULL;
+- }
++ memset(&rv, 0, sizeof(rv));
+
+- return msrs;
++ rv.msr_no = msr_no;
++ err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
++ *l = rv.reg.l;
++ *h = rv.reg.h;
++
++ return err ? err : rv.err;
+ }
+-EXPORT_SYMBOL(msrs_alloc);
++EXPORT_SYMBOL(rdmsr_safe_on_cpu);
+
+-void msrs_free(struct msr *msrs)
++int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+ {
+- free_percpu(msrs);
++ int err;
++ struct msr_info rv;
++
++ memset(&rv, 0, sizeof(rv));
++
++ rv.msr_no = msr_no;
++ rv.reg.l = l;
++ rv.reg.h = h;
++ err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
++
++ return err ? err : rv.err;
++}
++EXPORT_SYMBOL(wrmsr_safe_on_cpu);
++
++/*
++ * These variants are significantly slower, but allows control over
++ * the entire 32-bit GPR set.
++ */
++struct msr_regs_info {
++ u32 *regs;
++ int err;
++};
++
++static void __rdmsr_safe_regs_on_cpu(void *info)
++{
++ struct msr_regs_info *rv = info;
++
++ rv->err = rdmsr_safe_regs(rv->regs);
++}
++
++static void __wrmsr_safe_regs_on_cpu(void *info)
++{
++ struct msr_regs_info *rv = info;
++
++ rv->err = wrmsr_safe_regs(rv->regs);
++}
++
++int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
++{
++ int err;
++ struct msr_regs_info rv;
++
++ rv.regs = regs;
++ rv.err = -EIO;
++ err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
++
++ return err ? err : rv.err;
++}
++EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
++
++int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
++{
++ int err;
++ struct msr_regs_info rv;
++
++ rv.regs = regs;
++ rv.err = -EIO;
++ err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
++
++ return err ? err : rv.err;
+ }
+-EXPORT_SYMBOL(msrs_free);
++EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
+diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
+index 3871c60..dbb5381 100644
+--- a/arch/x86/mm/srat_64.c
++++ b/arch/x86/mm/srat_64.c
+@@ -229,11 +229,9 @@ update_nodes_add(int node, unsigned long start, unsigned long end)
+ printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n");
+ }
+
+- if (changed) {
+- node_set(node, cpu_nodes_parsed);
++ if (changed)
+ printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n",
+ nd->start, nd->end);
+- }
+ }
+
+ /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
+diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
+index 3347f69..cb88b1a 100644
+--- a/arch/x86/oprofile/nmi_int.c
++++ b/arch/x86/oprofile/nmi_int.c
+@@ -222,7 +222,7 @@ static void nmi_cpu_switch(void *dummy)
+
+ /* move to next set */
+ si += model->num_counters;
+- if ((si >= model->num_virt_counters) || (counter_config[si].count == 0))
++ if ((si > model->num_virt_counters) || (counter_config[si].count == 0))
+ per_cpu(switch_index, cpu) = 0;
+ else
+ per_cpu(switch_index, cpu) = si;
+@@ -598,7 +598,6 @@ static int __init ppro_init(char **cpu_type)
+ case 15: case 23:
+ *cpu_type = "i386/core_2";
+ break;
+- case 0x2e:
+ case 26:
+ spec = &op_arch_perfmon_spec;
+ *cpu_type = "i386/core_i7";
+diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
+index a672f12..b22d13b 100644
+--- a/arch/x86/pci/i386.c
++++ b/arch/x86/pci/i386.c
+@@ -282,15 +282,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ return -EINVAL;
+
+ prot = pgprot_val(vma->vm_page_prot);
+-
+- /*
+- * Return error if pat is not enabled and write_combine is requested.
+- * Caller can followup with UC MINUS request and add a WC mtrr if there
+- * is a free mtrr slot.
+- */
+- if (!pat_enabled && write_combine)
+- return -EINVAL;
+-
+ if (pat_enabled && write_combine)
+ prot |= _PAGE_CACHE_WC;
+ else if (pat_enabled || boot_cpu_data.x86 > 3)
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index 79f9738..dfbf70e 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -138,23 +138,24 @@ static void xen_vcpu_setup(int cpu)
+ */
+ void xen_vcpu_restore(void)
+ {
+- int cpu;
++ if (have_vcpu_info_placement) {
++ int cpu;
+
+- for_each_online_cpu(cpu) {
+- bool other_cpu = (cpu != smp_processor_id());
++ for_each_online_cpu(cpu) {
++ bool other_cpu = (cpu != smp_processor_id());
+
+- if (other_cpu &&
+- HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL))
+- BUG();
+-
+- xen_setup_runstate_info(cpu);
++ if (other_cpu &&
++ HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL))
++ BUG();
+
+- if (have_vcpu_info_placement)
+ xen_vcpu_setup(cpu);
+
+- if (other_cpu &&
+- HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL))
+- BUG();
++ if (other_cpu &&
++ HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL))
++ BUG();
++ }
++
++ BUG_ON(!have_vcpu_info_placement);
+ }
+ }
+
+@@ -1181,8 +1182,6 @@ asmlinkage void __init xen_start_kernel(void)
+
+ xen_raw_console_write("about to get started...\n");
+
+- xen_setup_runstate_info(0);
+-
+ /* Start the world */
+ #ifdef CONFIG_X86_32
+ i386_start_kernel();
+diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
+index bf4cd6b..3bf7b1d 100644
+--- a/arch/x86/xen/mmu.c
++++ b/arch/x86/xen/mmu.c
+@@ -185,7 +185,7 @@ static inline unsigned p2m_index(unsigned long pfn)
+ }
+
+ /* Build the parallel p2m_top_mfn structures */
+-void xen_build_mfn_list_list(void)
++static void __init xen_build_mfn_list_list(void)
+ {
+ unsigned pfn, idx;
+
+diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
+index 360f8d8..fe03eee 100644
+--- a/arch/x86/xen/smp.c
++++ b/arch/x86/xen/smp.c
+@@ -295,7 +295,6 @@ static int __cpuinit xen_cpu_up(unsigned int cpu)
+ (unsigned long)task_stack_page(idle) -
+ KERNEL_STACK_OFFSET + THREAD_SIZE;
+ #endif
+- xen_setup_runstate_info(cpu);
+ xen_setup_timer(cpu);
+ xen_init_lock_cpu(cpu);
+
+diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
+index 987267f..95be7b4 100644
+--- a/arch/x86/xen/suspend.c
++++ b/arch/x86/xen/suspend.c
+@@ -1,5 +1,4 @@
+ #include <linux/types.h>
+-#include <linux/clockchips.h>
+
+ #include <xen/interface/xen.h>
+ #include <xen/grant_table.h>
+@@ -28,8 +27,6 @@ void xen_pre_suspend(void)
+
+ void xen_post_suspend(int suspend_cancelled)
+ {
+- xen_build_mfn_list_list();
+-
+ xen_setup_shared_info();
+
+ if (suspend_cancelled) {
+@@ -47,19 +44,7 @@ void xen_post_suspend(int suspend_cancelled)
+
+ }
+
+-static void xen_vcpu_notify_restore(void *data)
+-{
+- unsigned long reason = (unsigned long)data;
+-
+- /* Boot processor notified via generic timekeeping_resume() */
+- if ( smp_processor_id() == 0)
+- return;
+-
+- clockevents_notify(reason, NULL);
+-}
+-
+ void xen_arch_resume(void)
+ {
+- smp_call_function(xen_vcpu_notify_restore,
+- (void *)CLOCK_EVT_NOTIFY_RESUME, 1);
++ /* nothing */
+ }
+diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
+index 9d1f853..0a5aa44 100644
+--- a/arch/x86/xen/time.c
++++ b/arch/x86/xen/time.c
+@@ -100,7 +100,7 @@ bool xen_vcpu_stolen(int vcpu)
+ return per_cpu(runstate, vcpu).state == RUNSTATE_runnable;
+ }
+
+-void xen_setup_runstate_info(int cpu)
++static void setup_runstate_info(int cpu)
+ {
+ struct vcpu_register_runstate_memory_area area;
+
+@@ -434,7 +434,7 @@ void xen_setup_timer(int cpu)
+ name = "<timer kasprintf failed>";
+
+ irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
+- IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER,
++ IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
+ name, NULL);
+
+ evt = &per_cpu(xen_clock_events, cpu);
+@@ -442,6 +442,8 @@ void xen_setup_timer(int cpu)
+
+ evt->cpumask = cpumask_of(cpu);
+ evt->irq = irq;
++
++ setup_runstate_info(cpu);
+ }
+
+ void xen_teardown_timer(int cpu)
+@@ -492,7 +494,6 @@ __init void xen_time_init(void)
+
+ setup_force_cpu_cap(X86_FEATURE_TSC);
+
+- xen_setup_runstate_info(cpu);
+ xen_setup_timer(cpu);
+ xen_setup_cpu_clockevents();
+ }
+diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
+index 53adefd..02f496a 100644
+--- a/arch/x86/xen/xen-asm_64.S
++++ b/arch/x86/xen/xen-asm_64.S
+@@ -96,7 +96,7 @@ ENTRY(xen_sysret32)
+ pushq $__USER32_CS
+ pushq %rcx
+
+- pushq $0
++ pushq $VGCF_in_syscall
+ 1: jmp hypercall_iret
+ ENDPATCH(xen_sysret32)
+ RELOC(xen_sysret32, 1b+1)
+@@ -151,7 +151,7 @@ ENTRY(xen_syscall32_target)
+ ENTRY(xen_sysenter_target)
+ lea 16(%rsp), %rsp /* strip %rcx, %r11 */
+ mov $-ENOSYS, %rax
+- pushq $0
++ pushq $VGCF_in_syscall
+ jmp hypercall_iret
+ ENDPROC(xen_syscall32_target)
+ ENDPROC(xen_sysenter_target)
+diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
+index f9153a3..355fa6b 100644
+--- a/arch/x86/xen/xen-ops.h
++++ b/arch/x86/xen/xen-ops.h
+@@ -25,7 +25,6 @@ extern struct shared_info *HYPERVISOR_shared_info;
+
+ void xen_setup_mfn_list_list(void);
+ void xen_setup_shared_info(void);
+-void xen_build_mfn_list_list(void);
+ void xen_setup_machphys_mapping(void);
+ pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
+ void xen_ident_map_ISA(void);
+@@ -42,7 +41,6 @@ void __init xen_build_dynamic_phys_to_machine(void);
+
+ void xen_init_irq_ops(void);
+ void xen_setup_timer(int cpu);
+-void xen_setup_runstate_info(int cpu);
+ void xen_teardown_timer(int cpu);
+ cycle_t xen_clocksource_read(void);
+ void xen_setup_cpu_clockevents(void);
+diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h
+index 4352dbe..05cebf8 100644
+--- a/arch/xtensa/include/asm/syscall.h
++++ b/arch/xtensa/include/asm/syscall.h
+@@ -13,6 +13,8 @@ struct sigaction;
+ asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*);
+ asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*);
+ asmlinkage long xtensa_pipe(int __user *);
++asmlinkage long xtensa_mmap2(unsigned long, unsigned long, unsigned long,
++ unsigned long, unsigned long, unsigned long);
+ asmlinkage long xtensa_ptrace(long, long, long, long);
+ asmlinkage long xtensa_sigreturn(struct pt_regs*);
+ asmlinkage long xtensa_rt_sigreturn(struct pt_regs*);
+diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h
+index 9a5c354..c092c8f 100644
+--- a/arch/xtensa/include/asm/unistd.h
++++ b/arch/xtensa/include/asm/unistd.h
+@@ -189,7 +189,7 @@ __SYSCALL( 79, sys_fremovexattr, 2)
+ /* File Map / Shared Memory Operations */
+
+ #define __NR_mmap2 80
+-__SYSCALL( 80, sys_mmap_pgoff, 6)
++__SYSCALL( 80, xtensa_mmap2, 6)
+ #define __NR_munmap 81
+ __SYSCALL( 81, sys_munmap, 2)
+ #define __NR_mprotect 82
+diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c
+index 1e67bab..ac15ecb 100644
+--- a/arch/xtensa/kernel/syscall.c
++++ b/arch/xtensa/kernel/syscall.c
+@@ -57,6 +57,31 @@ asmlinkage long xtensa_pipe(int __user *userfds)
+ return error;
+ }
+
++
++asmlinkage long xtensa_mmap2(unsigned long addr, unsigned long len,
++ unsigned long prot, unsigned long flags,
++ unsigned long fd, unsigned long pgoff)
++{
++ int error = -EBADF;
++ struct file * file = NULL;
++
++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++ if (!(flags & MAP_ANONYMOUS)) {
++ file = fget(fd);
++ if (!file)
++ goto out;
++ }
++
++ down_write(¤t->mm->mmap_sem);
++ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++ up_write(¤t->mm->mmap_sem);
++
++ if (file)
++ fput(file);
++out:
++ return error;
++}
++
+ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg)
+ {
+ unsigned long ret;
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index d5aa886..66d4aa8 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -560,28 +560,6 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ EXPORT_SYMBOL(blk_stack_limits);
+
+ /**
+- * bdev_stack_limits - adjust queue limits for stacked drivers
+- * @t: the stacking driver limits (top device)
+- * @bdev: the component block_device (bottom)
+- * @start: first data sector within component device
+- *
+- * Description:
+- * Merges queue limits for a top device and a block_device. Returns
+- * 0 if alignment didn't change. Returns -1 if adding the bottom
+- * device caused misalignment.
+- */
+-int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev,
+- sector_t start)
+-{
+- struct request_queue *bq = bdev_get_queue(bdev);
+-
+- start += get_start_sect(bdev);
+-
+- return blk_stack_limits(t, &bq->limits, start << 9);
+-}
+-EXPORT_SYMBOL(bdev_stack_limits);
+-
+-/**
+ * disk_stack_limits - adjust queue limits for stacked drivers
+ * @disk: MD/DM gendisk (top)
+ * @bdev: the underlying block device (bottom)
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 6ee53c7..019f345 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -100,7 +100,7 @@ obj-y += firmware/
+ obj-$(CONFIG_CRYPTO) += crypto/
+ obj-$(CONFIG_SUPERH) += sh/
+ obj-$(CONFIG_GENERIC_TIME) += clocksource/
+-obj-$(CONFIG_DMA_ENGINE) += dma/
++obj-$(CONFIG_DMADEVICES) += dma/
+ obj-$(CONFIG_DCA) += dca/
+ obj-$(CONFIG_HID) += hid/
+ obj-$(CONFIG_PPC_PS3) += ps3/
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index 49f6ede..7411915 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -344,167 +344,6 @@ bool acpi_bus_can_wakeup(acpi_handle handle)
+
+ EXPORT_SYMBOL(acpi_bus_can_wakeup);
+
+-static void acpi_print_osc_error(acpi_handle handle,
+- struct acpi_osc_context *context, char *error)
+-{
+- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER};
+- int i;
+-
+- if (ACPI_FAILURE(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))
+- printk(KERN_DEBUG "%s\n", error);
+- else {
+- printk(KERN_DEBUG "%s:%s\n", (char *)buffer.pointer, error);
+- kfree(buffer.pointer);
+- }
+- printk(KERN_DEBUG"_OSC request data:");
+- for (i = 0; i < context->cap.length; i += sizeof(u32))
+- printk("%x ", *((u32 *)(context->cap.pointer + i)));
+- printk("\n");
+-}
+-
+-static u8 hex_val(unsigned char c)
+-{
+- return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
+-}
+-
+-static acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
+-{
+- int i;
+- static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21,
+- 24, 26, 28, 30, 32, 34};
+-
+- if (strlen(str) != 36)
+- return AE_BAD_PARAMETER;
+- for (i = 0; i < 36; i++) {
+- if (i == 8 || i == 13 || i == 18 || i == 23) {
+- if (str[i] != '-')
+- return AE_BAD_PARAMETER;
+- } else if (!isxdigit(str[i]))
+- return AE_BAD_PARAMETER;
+- }
+- for (i = 0; i < 16; i++) {
+- uuid[i] = hex_val(str[opc_map_to_uuid[i]]) << 4;
+- uuid[i] |= hex_val(str[opc_map_to_uuid[i] + 1]);
+- }
+- return AE_OK;
+-}
+-
+-acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
+-{
+- acpi_status status;
+- struct acpi_object_list input;
+- union acpi_object in_params[4];
+- union acpi_object *out_obj;
+- u8 uuid[16];
+- u32 errors;
+- struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+-
+- if (!context)
+- return AE_ERROR;
+- if (ACPI_FAILURE(acpi_str_to_uuid(context->uuid_str, uuid)))
+- return AE_ERROR;
+- context->ret.length = ACPI_ALLOCATE_BUFFER;
+- context->ret.pointer = NULL;
+-
+- /* Setting up input parameters */
+- input.count = 4;
+- input.pointer = in_params;
+- in_params[0].type = ACPI_TYPE_BUFFER;
+- in_params[0].buffer.length = 16;
+- in_params[0].buffer.pointer = uuid;
+- in_params[1].type = ACPI_TYPE_INTEGER;
+- in_params[1].integer.value = context->rev;
+- in_params[2].type = ACPI_TYPE_INTEGER;
+- in_params[2].integer.value = context->cap.length/sizeof(u32);
+- in_params[3].type = ACPI_TYPE_BUFFER;
+- in_params[3].buffer.length = context->cap.length;
+- in_params[3].buffer.pointer = context->cap.pointer;
+-
+- status = acpi_evaluate_object(handle, "_OSC", &input, &output);
+- if (ACPI_FAILURE(status))
+- return status;
+-
+- if (!output.length)
+- return AE_NULL_OBJECT;
+-
+- out_obj = output.pointer;
+- if (out_obj->type != ACPI_TYPE_BUFFER
+- || out_obj->buffer.length != context->cap.length) {
+- acpi_print_osc_error(handle, context,
+- "_OSC evaluation returned wrong type");
+- status = AE_TYPE;
+- goto out_kfree;
+- }
+- /* Need to ignore the bit0 in result code */
+- errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+- if (errors) {
+- if (errors & OSC_REQUEST_ERROR)
+- acpi_print_osc_error(handle, context,
+- "_OSC request failed");
+- if (errors & OSC_INVALID_UUID_ERROR)
+- acpi_print_osc_error(handle, context,
+- "_OSC invalid UUID");
+- if (errors & OSC_INVALID_REVISION_ERROR)
+- acpi_print_osc_error(handle, context,
+- "_OSC invalid revision");
+- if (errors & OSC_CAPABILITIES_MASK_ERROR) {
+- if (((u32 *)context->cap.pointer)[OSC_QUERY_TYPE]
+- & OSC_QUERY_ENABLE)
+- goto out_success;
+- status = AE_SUPPORT;
+- goto out_kfree;
+- }
+- status = AE_ERROR;
+- goto out_kfree;
+- }
+-out_success:
+- context->ret.length = out_obj->buffer.length;
+- context->ret.pointer = kmalloc(context->ret.length, GFP_KERNEL);
+- if (!context->ret.pointer) {
+- status = AE_NO_MEMORY;
+- goto out_kfree;
+- }
+- memcpy(context->ret.pointer, out_obj->buffer.pointer,
+- context->ret.length);
+- status = AE_OK;
+-
+-out_kfree:
+- kfree(output.pointer);
+- if (status != AE_OK)
+- context->ret.pointer = NULL;
+- return status;
+-}
+-EXPORT_SYMBOL(acpi_run_osc);
+-
+-static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
+-static void acpi_bus_osc_support(void)
+-{
+- u32 capbuf[2];
+- struct acpi_osc_context context = {
+- .uuid_str = sb_uuid_str,
+- .rev = 1,
+- .cap.length = 8,
+- .cap.pointer = capbuf,
+- };
+- acpi_handle handle;
+-
+- capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+- capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
+-#if defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) ||\
+- defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE)
+- capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT;
+-#endif
+-
+-#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+- capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT;
+-#endif
+- if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
+- return;
+- if (ACPI_SUCCESS(acpi_run_osc(handle, &context)))
+- kfree(context.ret.pointer);
+- /* do we need to check the returned cap? Sounds no */
+-}
+-
+ /* --------------------------------------------------------------------------
+ Event Management
+ -------------------------------------------------------------------------- */
+@@ -895,8 +734,6 @@ static int __init acpi_bus_init(void)
+ status = acpi_ec_ecdt_probe();
+ /* Ignore result. Not having an ECDT is not fatal. */
+
+- acpi_bus_osc_support();
+-
+ status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 8a95e83..0c9c6a9 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -282,13 +282,6 @@ static int acpi_lid_send_state(struct acpi_device *device)
+ if (ret == NOTIFY_DONE)
+ ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
+ device);
+- if (ret == NOTIFY_DONE || ret == NOTIFY_OK) {
+- /*
+- * It is also regarded as success if the notifier_chain
+- * returns NOTIFY_OK or NOTIFY_DONE.
+- */
+- ret = 0;
+- }
+ return ret;
+ }
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index f1670e0..baef28c 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -201,13 +201,14 @@ unlock:
+ spin_unlock_irqrestore(&ec->curr_lock, flags);
+ }
+
+-static int acpi_ec_sync_query(struct acpi_ec *ec);
++static void acpi_ec_gpe_query(void *ec_cxt);
+
+-static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
++static int ec_check_sci(struct acpi_ec *ec, u8 state)
+ {
+ if (state & ACPI_EC_FLAG_SCI) {
+ if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
+- return acpi_ec_sync_query(ec);
++ return acpi_os_execute(OSL_EC_BURST_HANDLER,
++ acpi_ec_gpe_query, ec);
+ }
+ return 0;
+ }
+@@ -248,6 +249,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
+ {
+ unsigned long tmp;
+ int ret = 0;
++ pr_debug(PREFIX "transaction start\n");
++ /* disable GPE during transaction if storm is detected */
++ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
++ acpi_disable_gpe(NULL, ec->gpe);
++ }
+ if (EC_FLAGS_MSI)
+ udelay(ACPI_EC_MSI_UDELAY);
+ /* start transaction */
+@@ -259,9 +265,20 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
+ clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+ spin_unlock_irqrestore(&ec->curr_lock, tmp);
+ ret = ec_poll(ec);
++ pr_debug(PREFIX "transaction end\n");
+ spin_lock_irqsave(&ec->curr_lock, tmp);
+ ec->curr = NULL;
+ spin_unlock_irqrestore(&ec->curr_lock, tmp);
++ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
++ /* check if we received SCI during transaction */
++ ec_check_sci(ec, acpi_ec_read_status(ec));
++ /* it is safe to enable GPE outside of transaction */
++ acpi_enable_gpe(NULL, ec->gpe);
++ } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
++ pr_info(PREFIX "GPE storm detected, "
++ "transactions will use polling mode\n");
++ set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
++ }
+ return ret;
+ }
+
+@@ -304,26 +321,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
+ status = -ETIME;
+ goto end;
+ }
+- pr_debug(PREFIX "transaction start\n");
+- /* disable GPE during transaction if storm is detected */
+- if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+- acpi_disable_gpe(NULL, ec->gpe);
+- }
+-
+ status = acpi_ec_transaction_unlocked(ec, t);
+-
+- /* check if we received SCI during transaction */
+- ec_check_sci_sync(ec, acpi_ec_read_status(ec));
+- if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+- msleep(1);
+- /* it is safe to enable GPE outside of transaction */
+- acpi_enable_gpe(NULL, ec->gpe);
+- } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+- pr_info(PREFIX "GPE storm detected, "
+- "transactions will use polling mode\n");
+- set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
+- }
+- pr_debug(PREFIX "transaction end\n");
+ end:
+ if (ec->global_lock)
+ acpi_release_global_lock(glk);
+@@ -445,7 +443,7 @@ int ec_transaction(u8 command,
+
+ EXPORT_SYMBOL(ec_transaction);
+
+-static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
++static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
+ {
+ int result;
+ u8 d;
+@@ -454,16 +452,20 @@ static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
+ .wlen = 0, .rlen = 1};
+ if (!ec || !data)
+ return -EINVAL;
++
+ /*
+ * Query the EC to find out which _Qxx method we need to evaluate.
+ * Note that successful completion of the query causes the ACPI_EC_SCI
+ * bit to be cleared (and thus clearing the interrupt source).
+ */
+- result = acpi_ec_transaction_unlocked(ec, &t);
++
++ result = acpi_ec_transaction(ec, &t);
+ if (result)
+ return result;
++
+ if (!d)
+ return -ENODATA;
++
+ *data = d;
+ return 0;
+ }
+@@ -507,78 +509,43 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
+
+ EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
+
+-static void acpi_ec_run(void *cxt)
+-{
+- struct acpi_ec_query_handler *handler = cxt;
+- if (!handler)
+- return;
+- pr_debug(PREFIX "start query execution\n");
+- if (handler->func)
+- handler->func(handler->data);
+- else if (handler->handle)
+- acpi_evaluate_object(handler->handle, NULL, NULL, NULL);
+- pr_debug(PREFIX "stop query execution\n");
+- kfree(handler);
+-}
+-
+-static int acpi_ec_sync_query(struct acpi_ec *ec)
++static void acpi_ec_gpe_query(void *ec_cxt)
+ {
++ struct acpi_ec *ec = ec_cxt;
+ u8 value = 0;
+- int status;
+- struct acpi_ec_query_handler *handler, *copy;
+- if ((status = acpi_ec_query_unlocked(ec, &value)))
+- return status;
++ struct acpi_ec_query_handler *handler, copy;
++
++ if (!ec || acpi_ec_query(ec, &value))
++ return;
++ mutex_lock(&ec->lock);
+ list_for_each_entry(handler, &ec->list, node) {
+ if (value == handler->query_bit) {
+ /* have custom handler for this bit */
+- copy = kmalloc(sizeof(*handler), GFP_KERNEL);
+- if (!copy)
+- return -ENOMEM;
+- memcpy(copy, handler, sizeof(*copy));
+- pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value);
+- return acpi_os_execute(OSL_GPE_HANDLER,
+- acpi_ec_run, copy);
++ memcpy(©, handler, sizeof(copy));
++ mutex_unlock(&ec->lock);
++ if (copy.func) {
++ copy.func(copy.data);
++ } else if (copy.handle) {
++ acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
++ }
++ return;
+ }
+ }
+- return 0;
+-}
+-
+-static void acpi_ec_gpe_query(void *ec_cxt)
+-{
+- struct acpi_ec *ec = ec_cxt;
+- if (!ec)
+- return;
+- mutex_lock(&ec->lock);
+- acpi_ec_sync_query(ec);
+ mutex_unlock(&ec->lock);
+ }
+
+-static void acpi_ec_gpe_query(void *ec_cxt);
+-
+-static int ec_check_sci(struct acpi_ec *ec, u8 state)
+-{
+- if (state & ACPI_EC_FLAG_SCI) {
+- if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
+- pr_debug(PREFIX "push gpe query to the queue\n");
+- return acpi_os_execute(OSL_NOTIFY_HANDLER,
+- acpi_ec_gpe_query, ec);
+- }
+- }
+- return 0;
+-}
+-
+ static u32 acpi_ec_gpe_handler(void *data)
+ {
+ struct acpi_ec *ec = data;
++ u8 status;
+
+ pr_debug(PREFIX "~~~> interrupt\n");
++ status = acpi_ec_read_status(ec);
+
+- advance_transaction(ec, acpi_ec_read_status(ec));
+- if (ec_transaction_done(ec) &&
+- (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
++ advance_transaction(ec, status);
++ if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
+ wake_up(&ec->wait);
+- ec_check_sci(ec, acpi_ec_read_status(ec));
+- }
++ ec_check_sci(ec, status);
+ return ACPI_INTERRUPT_HANDLED;
+ }
+
+@@ -949,7 +916,6 @@ static int ec_validate_ecdt(const struct dmi_system_id *id)
+ /* MSI EC needs special treatment, enable it */
+ static int ec_flag_msi(const struct dmi_system_id *id)
+ {
+- printk(KERN_DEBUG PREFIX "Detected MSI hardware, enabling workarounds.\n");
+ EC_FLAGS_MSI = 1;
+ EC_FLAGS_VALIDATE_ECDT = 1;
+ return 0;
+@@ -962,13 +928,8 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL},
+ {
+ ec_flag_msi, "MSI hardware", {
+- DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star")}, NULL},
+- {
+- ec_flag_msi, "MSI hardware", {
+- DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star")}, NULL},
+- {
+- ec_flag_msi, "MSI hardware", {
+- DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
++ DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"),
++ DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL},
+ {
+ ec_validate_ecdt, "ASUS hardware", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+index d9f78f6..bbd066e 100644
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -110,14 +110,6 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
+ DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+ DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
+ (void *)2},
+- { set_max_cstate, "Pavilion zv5000", {
+- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+- DMI_MATCH(DMI_PRODUCT_NAME,"Pavilion zv5000 (DS502A#ABA)")},
+- (void *)1},
+- { set_max_cstate, "Asus L8400B", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+- DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},
+- (void *)1},
+ {},
+ };
+
+@@ -307,17 +299,6 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
+ pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency;
+ pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency;
+
+- /*
+- * FADT specified C2 latency must be less than or equal to
+- * 100 microseconds.
+- */
+- if (acpi_gbl_FADT.C2latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
+- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+- "C2 latency too large [%d]\n", acpi_gbl_FADT.C2latency));
+- /* invalidate C2 */
+- pr->power.states[ACPI_STATE_C2].address = 0;
+- }
+-
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "lvl2[0x%08x] lvl3[0x%08x]\n",
+ pr->power.states[ACPI_STATE_C2].address,
+@@ -514,6 +495,16 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
+ return;
+
+ /*
++ * C2 latency must be less than or equal to 100
++ * microseconds.
++ */
++ else if (cx->latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
++ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
++ "latency too large [%d]\n", cx->latency));
++ return;
++ }
++
++ /*
+ * Otherwise we've met all of our C2 requirements.
+ * Normalize the C2 latency to expidite policy
+ */
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index 0b09703..14a7481 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -1357,9 +1357,6 @@ int acpi_bus_start(struct acpi_device *device)
+ {
+ struct acpi_bus_ops ops;
+
+- if (!device)
+- return -EINVAL;
+-
+ memset(&ops, 0, sizeof(ops));
+ ops.acpi_op_start = 1;
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index 9b37502..a3241a1 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -113,7 +113,6 @@ enum {
+ board_ahci_mcp65 = 6,
+ board_ahci_nopmp = 7,
+ board_ahci_yesncq = 8,
+- board_ahci_nosntf = 9,
+
+ /* global controller registers */
+ HOST_CAP = 0x00, /* host capabilities */
+@@ -236,7 +235,6 @@ enum {
+ AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */
+ AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = (1 << 11), /* treat SRST timeout as
+ link offline */
+- AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */
+
+ /* ap->flags bits */
+
+@@ -510,7 +508,7 @@ static const struct ata_port_info ahci_port_info[] = {
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_ops,
+ },
+- [board_ahci_yesncq] =
++ /* board_ahci_yesncq */
+ {
+ AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ),
+ .flags = AHCI_FLAG_COMMON,
+@@ -518,14 +516,6 @@ static const struct ata_port_info ahci_port_info[] = {
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_ops,
+ },
+- [board_ahci_nosntf] =
+- {
+- AHCI_HFLAGS (AHCI_HFLAG_NO_SNTF),
+- .flags = AHCI_FLAG_COMMON,
+- .pio_mask = ATA_PIO4,
+- .udma_mask = ATA_UDMA6,
+- .port_ops = &ahci_ops,
+- },
+ };
+
+ static const struct pci_device_id ahci_pci_tbl[] = {
+@@ -541,7 +531,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
+ { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
+ { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
+- { PCI_VDEVICE(INTEL, 0x2822), board_ahci_nosntf }, /* ICH8 */
++ { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */
+ { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
+ { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
+ { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
+@@ -859,12 +849,6 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
+ cap &= ~HOST_CAP_PMP;
+ }
+
+- if ((cap & HOST_CAP_SNTF) && (hpriv->flags & AHCI_HFLAG_NO_SNTF)) {
+- dev_printk(KERN_INFO, &pdev->dev,
+- "controller can't do SNTF, turning off CAP_SNTF\n");
+- cap &= ~HOST_CAP_SNTF;
+- }
+-
+ if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 &&
+ port_map != 1) {
+ dev_printk(KERN_INFO, &pdev->dev,
+@@ -2868,21 +2852,6 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
+ },
+ .driver_data = "F.23", /* cutoff BIOS version */
+ },
+- /*
+- * Acer eMachines G725 has the same problem. BIOS
+- * V1.03 is known to be broken. V3.04 is known to
+- * work. Inbetween, there are V1.06, V2.06 and V3.03
+- * that we don't have much idea about. For now,
+- * blacklist anything older than V3.04.
+- */
+- {
+- .ident = "G725",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "eMachines"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"),
+- },
+- .driver_data = "V3.04", /* cutoff BIOS version */
+- },
+ { } /* terminate list */
+ };
+ const struct dmi_system_id *dmi = dmi_first_match(sysids);
+diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
+index 0c6155f..9ac4e37 100644
+--- a/drivers/ata/ata_piix.c
++++ b/drivers/ata/ata_piix.c
+@@ -869,10 +869,10 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
+ (timings[pio][1] << 8);
+ }
+
+- if (ap->udma_mask)
++ if (ap->udma_mask) {
+ udma_enable &= ~(1 << devid);
+-
+- pci_write_config_word(dev, master_port, master_data);
++ pci_write_config_word(dev, master_port, master_data);
++ }
+ }
+ /* Don't scribble on 0x48 if the controller does not support UDMA */
+ if (ap->udma_mask)
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 91fed3c..dc72690 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -3790,45 +3790,21 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params,
+ int sata_link_resume(struct ata_link *link, const unsigned long *params,
+ unsigned long deadline)
+ {
+- int tries = ATA_LINK_RESUME_TRIES;
+ u32 scontrol, serror;
+ int rc;
+
+ if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
+ return rc;
+
+- /*
+- * Writes to SControl sometimes get ignored under certain
+- * controllers (ata_piix SIDPR). Make sure DET actually is
+- * cleared.
+- */
+- do {
+- scontrol = (scontrol & 0x0f0) | 0x300;
+- if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol)))
+- return rc;
+- /*
+- * Some PHYs react badly if SStatus is pounded
+- * immediately after resuming. Delay 200ms before
+- * debouncing.
+- */
+- msleep(200);
++ scontrol = (scontrol & 0x0f0) | 0x300;
+
+- /* is SControl restored correctly? */
+- if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
+- return rc;
+- } while ((scontrol & 0xf0f) != 0x300 && --tries);
+-
+- if ((scontrol & 0xf0f) != 0x300) {
+- ata_link_printk(link, KERN_ERR,
+- "failed to resume link (SControl %X)\n",
+- scontrol);
+- return 0;
+- }
++ if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol)))
++ return rc;
+
+- if (tries < ATA_LINK_RESUME_TRIES)
+- ata_link_printk(link, KERN_WARNING,
+- "link resume succeeded after %d retries\n",
+- ATA_LINK_RESUME_TRIES - tries);
++ /* Some PHYs react badly if SStatus is pounded immediately
++ * after resuming. Delay 200ms before debouncing.
++ */
++ msleep(200);
+
+ if ((rc = sata_link_debounce(link, params, deadline)))
+ return rc;
+diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
+index 7d8d3c3..bba2ae5 100644
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -2019,9 +2019,8 @@ static void ata_eh_link_autopsy(struct ata_link *link)
+ qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
+
+ /* determine whether the command is worth retrying */
+- if (qc->flags & ATA_QCFLAG_IO ||
+- (!(qc->err_mask & AC_ERR_INVALID) &&
+- qc->err_mask != AC_ERR_DEV))
++ if (!(qc->err_mask & AC_ERR_INVALID) &&
++ ((qc->flags & ATA_QCFLAG_IO) || qc->err_mask != AC_ERR_DEV))
+ qc->flags |= ATA_QCFLAG_RETRY;
+
+ /* accumulate error info */
+diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
+index 2ae15c3..bbbb1fa 100644
+--- a/drivers/ata/libata-sff.c
++++ b/drivers/ata/libata-sff.c
+@@ -893,9 +893,6 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
+ do_write);
+ }
+
+- if (!do_write)
+- flush_dcache_page(page);
+-
+ qc->curbytes += qc->sect_size;
+ qc->cursg_ofs += qc->sect_size;
+
+diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
+index f0bad9b..f98dffe 100644
+--- a/drivers/ata/pata_cmd64x.c
++++ b/drivers/ata/pata_cmd64x.c
+@@ -219,7 +219,7 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+ regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
+ /* Merge the control bits */
+ regU |= 1 << adev->devno; /* UDMA on */
+- if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */
++ if (adev->dma_mode > 2) /* 15nS timing */
+ regU |= 4 << adev->devno;
+ } else {
+ regU &= ~ (1 << adev->devno); /* UDMA off */
+diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
+index ec07c53..d0a7df2 100644
+--- a/drivers/ata/pata_hpt37x.c
++++ b/drivers/ata/pata_hpt37x.c
+@@ -24,7 +24,7 @@
+ #include <linux/libata.h>
+
+ #define DRV_NAME "pata_hpt37x"
+-#define DRV_VERSION "0.6.14"
++#define DRV_VERSION "0.6.12"
+
+ struct hpt_clock {
+ u8 xfer_speed;
+@@ -404,8 +404,9 @@ static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev)
+
+ pci_read_config_dword(pdev, addr1, ®);
+ mode = hpt37x_find_mode(ap, adev->pio_mode);
+- mode &= 0xCFC3FFFF; /* Leave DMA bits alone */
+- reg &= ~0xCFC3FFFF; /* Strip timing bits */
++ mode &= ~0x8000000; /* No FIFO in PIO */
++ mode &= ~0x30070000; /* Leave config bits alone */
++ reg &= 0x30070000; /* Strip timing bits */
+ pci_write_config_dword(pdev, addr1, reg | mode);
+ }
+
+@@ -422,7 +423,8 @@ static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+ {
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u32 addr1, addr2;
+- u32 reg, mode, mask;
++ u32 reg;
++ u32 mode;
+ u8 fast;
+
+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
+@@ -434,12 +436,11 @@ static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+ fast |= 0x01;
+ pci_write_config_byte(pdev, addr2, fast);
+
+- mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
+-
+ pci_read_config_dword(pdev, addr1, ®);
+ mode = hpt37x_find_mode(ap, adev->dma_mode);
+- mode &= mask;
+- reg &= ~mask;
++ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */
++ mode &= ~0xC0000000; /* Leave config bits alone */
++ reg &= 0xC0000000; /* Strip timing bits */
+ pci_write_config_dword(pdev, addr1, reg | mode);
+ }
+
+@@ -507,8 +508,9 @@ static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ mode = hpt37x_find_mode(ap, adev->pio_mode);
+
+ printk("Find mode for %d reports %X\n", adev->pio_mode, mode);
+- mode &= 0xCFC3FFFF; /* Leave DMA bits alone */
+- reg &= ~0xCFC3FFFF; /* Strip timing bits */
++ mode &= ~0x80000000; /* No FIFO in PIO */
++ mode &= ~0x30070000; /* Leave config bits alone */
++ reg &= 0x30070000; /* Strip timing bits */
+ pci_write_config_dword(pdev, addr1, reg | mode);
+ }
+
+@@ -525,7 +527,8 @@ static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+ {
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u32 addr1, addr2;
+- u32 reg, mode, mask;
++ u32 reg;
++ u32 mode;
+ u8 fast;
+
+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
+@@ -536,13 +539,12 @@ static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+ fast &= ~0x07;
+ pci_write_config_byte(pdev, addr2, fast);
+
+- mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
+-
+ pci_read_config_dword(pdev, addr1, ®);
+ mode = hpt37x_find_mode(ap, adev->dma_mode);
+ printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode);
+- mode &= mask;
+- reg &= ~mask;
++ mode &= ~0xC0000000; /* Leave config bits alone */
++ mode |= 0x80000000; /* FIFO in MWDMA or UDMA */
++ reg &= 0xC0000000; /* Strip timing bits */
+ pci_write_config_dword(pdev, addr1, reg | mode);
+ }
+
+diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
+index d16e87e..3d59fe0 100644
+--- a/drivers/ata/pata_hpt3x2n.c
++++ b/drivers/ata/pata_hpt3x2n.c
+@@ -8,7 +8,7 @@
+ * Copyright (C) 1999-2003 Andre Hedrick <andre at linux-ide.org>
+ * Portions Copyright (C) 2001 Sun Microsystems, Inc.
+ * Portions Copyright (C) 2003 Red Hat Inc
+- * Portions Copyright (C) 2005-2009 MontaVista Software, Inc.
++ * Portions Copyright (C) 2005-2007 MontaVista Software, Inc.
+ *
+ *
+ * TODO
+@@ -25,7 +25,7 @@
+ #include <linux/libata.h>
+
+ #define DRV_NAME "pata_hpt3x2n"
+-#define DRV_VERSION "0.3.8"
++#define DRV_VERSION "0.3.4"
+
+ enum {
+ HPT_PCI_FAST = (1 << 31),
+@@ -185,8 +185,9 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev)
+
+ pci_read_config_dword(pdev, addr1, ®);
+ mode = hpt3x2n_find_mode(ap, adev->pio_mode);
+- mode &= 0xCFC3FFFF; /* Leave DMA bits alone */
+- reg &= ~0xCFC3FFFF; /* Strip timing bits */
++ mode &= ~0x8000000; /* No FIFO in PIO */
++ mode &= ~0x30070000; /* Leave config bits alone */
++ reg &= 0x30070000; /* Strip timing bits */
+ pci_write_config_dword(pdev, addr1, reg | mode);
+ }
+
+@@ -203,7 +204,8 @@ static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+ {
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u32 addr1, addr2;
+- u32 reg, mode, mask;
++ u32 reg;
++ u32 mode;
+ u8 fast;
+
+ addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
+@@ -214,12 +216,11 @@ static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+ fast &= ~0x07;
+ pci_write_config_byte(pdev, addr2, fast);
+
+- mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
+-
+ pci_read_config_dword(pdev, addr1, ®);
+ mode = hpt3x2n_find_mode(ap, adev->dma_mode);
+- mode &= mask;
+- reg &= ~mask;
++ mode |= 0x8000000; /* FIFO in MWDMA or UDMA */
++ mode &= ~0xC0000000; /* Leave config bits alone */
++ reg &= 0xC0000000; /* Strip timing bits */
+ pci_write_config_dword(pdev, addr1, reg | mode);
+ }
+
+@@ -262,7 +263,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc)
+
+ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
+ {
+- void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8;
++ void __iomem *bmdma = ap->ioaddr.bmdma_addr;
+
+ /* Tristate the bus */
+ iowrite8(0x80, bmdma+0x73);
+@@ -272,9 +273,9 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
+ iowrite8(source, bmdma+0x7B);
+ iowrite8(0xC0, bmdma+0x79);
+
+- /* Reset state machines, avoid enabling the disabled channels */
+- iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70);
+- iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74);
++ /* Reset state machines */
++ iowrite8(0x37, bmdma+0x70);
++ iowrite8(0x37, bmdma+0x74);
+
+ /* Complete reset */
+ iowrite8(0x00, bmdma+0x79);
+@@ -284,10 +285,21 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
+ iowrite8(0x00, bmdma+0x77);
+ }
+
++/* Check if our partner interface is busy */
++
++static int hpt3x2n_pair_idle(struct ata_port *ap)
++{
++ struct ata_host *host = ap->host;
++ struct ata_port *pair = host->ports[ap->port_no ^ 1];
++
++ if (pair->hsm_task_state == HSM_ST_IDLE)
++ return 1;
++ return 0;
++}
++
+ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
+ {
+ long flags = (long)ap->host->private_data;
+-
+ /* See if we should use the DPLL */
+ if (writing)
+ return USE_DPLL; /* Needed for write */
+@@ -296,35 +308,20 @@ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
+ return 0;
+ }
+
+-static int hpt3x2n_qc_defer(struct ata_queued_cmd *qc)
+-{
+- struct ata_port *ap = qc->ap;
+- struct ata_port *alt = ap->host->ports[ap->port_no ^ 1];
+- int rc, flags = (long)ap->host->private_data;
+- int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
+-
+- /* First apply the usual rules */
+- rc = ata_std_qc_defer(qc);
+- if (rc != 0)
+- return rc;
+-
+- if ((flags & USE_DPLL) != dpll && alt->qc_active)
+- return ATA_DEFER_PORT;
+- return 0;
+-}
+-
+ static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc)
+ {
++ struct ata_taskfile *tf = &qc->tf;
+ struct ata_port *ap = qc->ap;
+ int flags = (long)ap->host->private_data;
+- int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
+-
+- if ((flags & USE_DPLL) != dpll) {
+- flags &= ~USE_DPLL;
+- flags |= dpll;
+- ap->host->private_data = (void *)(long)flags;
+
+- hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23);
++ if (hpt3x2n_pair_idle(ap)) {
++ int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE));
++ if ((flags & USE_DPLL) != dpll) {
++ if (dpll == 1)
++ hpt3x2n_set_clock(ap, 0x21);
++ else
++ hpt3x2n_set_clock(ap, 0x23);
++ }
+ }
+ return ata_sff_qc_issue(qc);
+ }
+@@ -341,8 +338,6 @@ static struct ata_port_operations hpt3x2n_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+
+ .bmdma_stop = hpt3x2n_bmdma_stop,
+-
+- .qc_defer = hpt3x2n_qc_defer,
+ .qc_issue = hpt3x2n_qc_issue,
+
+ .cable_detect = hpt3x2n_cable_detect,
+@@ -460,7 +455,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+ unsigned int f_low, f_high;
+ int adjust;
+ unsigned long iobase = pci_resource_start(dev, 4);
+- void *hpriv = (void *)USE_DPLL;
++ void *hpriv = NULL;
+ int rc;
+
+ rc = pcim_enable_device(dev);
+@@ -548,7 +543,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+ /* Set our private data up. We only need a few flags so we use
+ it directly */
+ if (pci_mhz > 60) {
+- hpriv = (void *)(PCI66 | USE_DPLL);
++ hpriv = (void *)PCI66;
+ /*
+ * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in
+ * the MISC. register to stretch the UltraDMA Tss timing.
+diff --git a/drivers/base/class.c b/drivers/base/class.c
+index 6e2c3b0..161746d 100644
+--- a/drivers/base/class.c
++++ b/drivers/base/class.c
+@@ -59,8 +59,6 @@ static void class_release(struct kobject *kobj)
+ else
+ pr_debug("class '%s' does not have a release() function, "
+ "be careful\n", class->name);
+-
+- kfree(cp);
+ }
+
+ static struct sysfs_ops class_sysfs_ops = {
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index 1093179..6bee6af 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -56,14 +56,7 @@ static inline int device_is_not_partition(struct device *dev)
+ */
+ const char *dev_driver_string(const struct device *dev)
+ {
+- struct device_driver *drv;
+-
+- /* dev->driver can change to NULL underneath us because of unbinding,
+- * so be careful about accessing it. dev->bus and dev->class should
+- * never change once they are set, so they don't need special care.
+- */
+- drv = ACCESS_ONCE(dev->driver);
+- return drv ? drv->name :
++ return dev->driver ? dev->driver->name :
+ (dev->bus ? dev->bus->name :
+ (dev->class ? dev->class->name : ""));
+ }
+diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
+index 33faaa2..a1cb5af 100644
+--- a/drivers/base/devtmpfs.c
++++ b/drivers/base/devtmpfs.c
+@@ -353,7 +353,6 @@ int __init devtmpfs_init(void)
+ {
+ int err;
+ struct vfsmount *mnt;
+- char options[] = "mode=0755";
+
+ err = register_filesystem(&dev_fs_type);
+ if (err) {
+@@ -362,7 +361,7 @@ int __init devtmpfs_init(void)
+ return err;
+ }
+
+- mnt = kern_mount_data(&dev_fs_type, options);
++ mnt = kern_mount(&dev_fs_type);
+ if (IS_ERR(mnt)) {
+ err = PTR_ERR(mnt);
+ printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 0a4b75f..846d89e 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -777,7 +777,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
+ }
+
+ if (parent) {
+- spin_lock_nested(&parent->power.lock, SINGLE_DEPTH_NESTING);
++ spin_lock(&parent->power.lock);
+
+ /*
+ * It is invalid to put an active child under a parent that is
+diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
+index ca9c548..92b1263 100644
+--- a/drivers/block/cciss.c
++++ b/drivers/block/cciss.c
+@@ -339,9 +339,6 @@ static int cciss_seq_show(struct seq_file *seq, void *v)
+ if (*pos > h->highest_lun)
+ return 0;
+
+- if (drv == NULL) /* it's possible for h->drv[] to have holes. */
+- return 0;
+-
+ if (drv->heads == 0)
+ return 0;
+
+diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
+index 68b5957..2ddf03a 100644
+--- a/drivers/block/pktcdvd.c
++++ b/drivers/block/pktcdvd.c
+@@ -322,7 +322,7 @@ static void pkt_sysfs_dev_remove(struct pktcdvd_device *pd)
+ pkt_kobj_remove(pd->kobj_stat);
+ pkt_kobj_remove(pd->kobj_wqueue);
+ if (class_pktcdvd)
+- device_unregister(pd->dev);
++ device_destroy(class_pktcdvd, pd->pkt_dev);
+ }
+
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 1be7631..44bc8bb 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -307,7 +307,6 @@ static void btusb_bulk_complete(struct urb *urb)
+ return;
+
+ usb_anchor_urb(urb, &data->bulk_anchor);
+- usb_mark_last_busy(data->udev);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
+index 4dcfef0..3cb56a0 100644
+--- a/drivers/char/agp/intel-agp.c
++++ b/drivers/char/agp/intel-agp.c
+@@ -178,7 +178,6 @@ static struct _intel_private {
+ * popup and for the GTT.
+ */
+ int gtt_entries; /* i830+ */
+- int gtt_total_size;
+ union {
+ void __iomem *i9xx_flush_page;
+ void *i8xx_flush_page;
+@@ -1154,7 +1153,7 @@ static int intel_i915_configure(void)
+ readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
+
+ if (agp_bridge->driver->needs_scratch_page) {
+- for (i = intel_private.gtt_entries; i < intel_private.gtt_total_size; i++) {
++ for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+ writel(agp_bridge->scratch_page, intel_private.gtt+i);
+ }
+ readl(intel_private.gtt+i-1); /* PCI Posting. */
+@@ -1309,8 +1308,6 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
+ if (!intel_private.gtt)
+ return -ENOMEM;
+
+- intel_private.gtt_total_size = gtt_map_size / 4;
+-
+ temp &= 0xfff80000;
+
+ intel_private.registers = ioremap(temp, 128 * 4096);
+@@ -1398,8 +1395,6 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
+ if (!intel_private.gtt)
+ return -ENOMEM;
+
+- intel_private.gtt_total_size = gtt_size / 4;
+-
+ intel_private.registers = ioremap(temp, 128 * 4096);
+ if (!intel_private.registers) {
+ iounmap(intel_private.gtt);
+diff --git a/drivers/char/mem.c b/drivers/char/mem.c
+index aef3fb4..a074fce 100644
+--- a/drivers/char/mem.c
++++ b/drivers/char/mem.c
+@@ -35,19 +35,6 @@
+ # include <linux/efi.h>
+ #endif
+
+-static inline unsigned long size_inside_page(unsigned long start,
+- unsigned long size)
+-{
+- unsigned long sz;
+-
+- if (-start & (PAGE_SIZE - 1))
+- sz = -start & (PAGE_SIZE - 1);
+- else
+- sz = PAGE_SIZE;
+-
+- return min_t(unsigned long, sz, size);
+-}
+-
+ /*
+ * Architectures vary in how they handle caching for addresses
+ * outside of main memory.
+@@ -421,7 +408,6 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
+ unsigned long p = *ppos;
+ ssize_t low_count, read, sz;
+ char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
+- int err = 0;
+
+ read = 0;
+ if (p < (unsigned long) high_memory) {
+@@ -444,7 +430,15 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
+ }
+ #endif
+ while (low_count > 0) {
+- sz = size_inside_page(p, low_count);
++ /*
++ * Handle first page in case it's not aligned
++ */
++ if (-p & (PAGE_SIZE - 1))
++ sz = -p & (PAGE_SIZE - 1);
++ else
++ sz = PAGE_SIZE;
++
++ sz = min_t(unsigned long, sz, low_count);
+
+ /*
+ * On ia64 if a page has been mapped somewhere as
+@@ -468,18 +462,16 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
+ if (!kbuf)
+ return -ENOMEM;
+ while (count > 0) {
+- int len = size_inside_page(p, count);
++ int len = count;
+
+- if (!is_vmalloc_or_module_addr((void *)p)) {
+- err = -ENXIO;
+- break;
+- }
++ if (len > PAGE_SIZE)
++ len = PAGE_SIZE;
+ len = vread(kbuf, (char *)p, len);
+ if (!len)
+ break;
+ if (copy_to_user(buf, kbuf, len)) {
+- err = -EFAULT;
+- break;
++ free_page((unsigned long)kbuf);
++ return -EFAULT;
+ }
+ count -= len;
+ buf += len;
+@@ -488,8 +480,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
+ }
+ free_page((unsigned long)kbuf);
+ }
+- *ppos = p;
+- return read ? read : err;
++ *ppos = p;
++ return read;
+ }
+
+
+@@ -518,8 +510,15 @@ do_write_kmem(void *p, unsigned long realp, const char __user * buf,
+
+ while (count > 0) {
+ char *ptr;
++ /*
++ * Handle first page in case it's not aligned
++ */
++ if (-realp & (PAGE_SIZE - 1))
++ sz = -realp & (PAGE_SIZE - 1);
++ else
++ sz = PAGE_SIZE;
+
+- sz = size_inside_page(realp, count);
++ sz = min_t(unsigned long, sz, count);
+
+ /*
+ * On ia64 if a page has been mapped somewhere as
+@@ -558,7 +557,6 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
+ ssize_t virtr = 0;
+ ssize_t written;
+ char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
+- int err = 0;
+
+ if (p < (unsigned long) high_memory) {
+
+@@ -580,20 +578,20 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
+ if (!kbuf)
+ return wrote ? wrote : -ENOMEM;
+ while (count > 0) {
+- int len = size_inside_page(p, count);
++ int len = count;
+
+- if (!is_vmalloc_or_module_addr((void *)p)) {
+- err = -ENXIO;
+- break;
+- }
++ if (len > PAGE_SIZE)
++ len = PAGE_SIZE;
+ if (len) {
+ written = copy_from_user(kbuf, buf, len);
+ if (written) {
+- err = -EFAULT;
+- break;
++ if (wrote + virtr)
++ break;
++ free_page((unsigned long)kbuf);
++ return -EFAULT;
+ }
+ }
+- vwrite(kbuf, (char *)p, len);
++ len = vwrite(kbuf, (char *)p, len);
+ count -= len;
+ buf += len;
+ virtr += len;
+@@ -602,8 +600,8 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
+ free_page((unsigned long)kbuf);
+ }
+
+- *ppos = p;
+- return virtr + wrote ? : err;
++ *ppos = p;
++ return virtr + wrote;
+ }
+ #endif
+
+diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
+index dc52f75..d3400b2 100644
+--- a/drivers/char/nozomi.c
++++ b/drivers/char/nozomi.c
+@@ -1629,10 +1629,10 @@ static void ntty_close(struct tty_struct *tty, struct file *file)
+
+ dc->open_ttys--;
+ port->count--;
++ tty_port_tty_set(port, NULL);
+
+ if (port->count == 0) {
+ DBG1("close: %d", nport->token_dl);
+- tty_port_tty_set(port, NULL);
+ spin_lock_irqsave(&dc->spin_mutex, flags);
+ dc->last_ier &= ~(nport->token_dl);
+ writew(dc->last_ier, dc->reg_ier);
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 908ac1f..04b505e 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1051,6 +1051,12 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+ /* like a named pipe */
+ }
+
++ /*
++ * If we gave the user some bytes, update the access time.
++ */
++ if (count)
++ file_accessed(file);
++
+ return (count ? count : retval);
+ }
+
+@@ -1101,6 +1107,7 @@ static ssize_t random_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+ {
+ size_t ret;
++ struct inode *inode = file->f_path.dentry->d_inode;
+
+ ret = write_pool(&blocking_pool, buffer, count);
+ if (ret)
+@@ -1109,6 +1116,8 @@ static ssize_t random_write(struct file *file, const char __user *buffer,
+ if (ret)
+ return ret;
+
++ inode->i_mtime = current_fs_time(inode->i_sb);
++ mark_inode_dirty(inode);
+ return (ssize_t)count;
+ }
+
+diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
+index f584407..ecba494 100644
+--- a/drivers/char/tpm/tpm_infineon.c
++++ b/drivers/char/tpm/tpm_infineon.c
+@@ -39,12 +39,12 @@
+ struct tpm_inf_dev {
+ int iotype;
+
+- void __iomem *mem_base; /* MMIO ioremap'd addr */
+- unsigned long map_base; /* phys MMIO base */
+- unsigned long map_size; /* MMIO region size */
+- unsigned int index_off; /* index register offset */
++ void __iomem *mem_base; /* MMIO ioremap'd addr */
++ unsigned long map_base; /* phys MMIO base */
++ unsigned long map_size; /* MMIO region size */
++ unsigned int index_off; /* index register offset */
+
+- unsigned int data_regs; /* Data registers */
++ unsigned int data_regs; /* Data registers */
+ unsigned int data_size;
+
+ unsigned int config_port; /* IO Port config index reg */
+@@ -406,14 +406,14 @@ static const struct tpm_vendor_specific tpm_inf = {
+ .miscdev = {.fops = &inf_ops,},
+ };
+
+-static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
++static const struct pnp_device_id tpm_pnp_tbl[] = {
+ /* Infineon TPMs */
+ {"IFX0101", 0},
+ {"IFX0102", 0},
+ {"", 0}
+ };
+
+-MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
++MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
+
+ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
+ const struct pnp_device_id *dev_id)
+@@ -430,7 +430,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
+ if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
+ !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
+
+- tpm_dev.iotype = TPM_INF_IO_PORT;
++ tpm_dev.iotype = TPM_INF_IO_PORT;
+
+ tpm_dev.config_port = pnp_port_start(dev, 0);
+ tpm_dev.config_size = pnp_port_len(dev, 0);
+@@ -459,9 +459,9 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
+ goto err_last;
+ }
+ } else if (pnp_mem_valid(dev, 0) &&
+- !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
++ !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
+
+- tpm_dev.iotype = TPM_INF_IO_MEM;
++ tpm_dev.iotype = TPM_INF_IO_MEM;
+
+ tpm_dev.map_base = pnp_mem_start(dev, 0);
+ tpm_dev.map_size = pnp_mem_len(dev, 0);
+@@ -563,11 +563,11 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
+ "product id 0x%02x%02x"
+ "%s\n",
+ tpm_dev.iotype == TPM_INF_IO_PORT ?
+- tpm_dev.config_port :
+- tpm_dev.map_base + tpm_dev.index_off,
++ tpm_dev.config_port :
++ tpm_dev.map_base + tpm_dev.index_off,
+ tpm_dev.iotype == TPM_INF_IO_PORT ?
+- tpm_dev.data_regs :
+- tpm_dev.map_base + tpm_dev.data_regs,
++ tpm_dev.data_regs :
++ tpm_dev.map_base + tpm_dev.data_regs,
+ version[0], version[1],
+ vendorid[0], vendorid[1],
+ productid[0], productid[1], chipname);
+@@ -607,55 +607,20 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
+ iounmap(tpm_dev.mem_base);
+ release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
+ }
+- tpm_dev_vendor_release(chip);
+ tpm_remove_hardware(chip->dev);
+ }
+ }
+
+-static int tpm_inf_pnp_suspend(struct pnp_dev *dev, pm_message_t pm_state)
+-{
+- struct tpm_chip *chip = pnp_get_drvdata(dev);
+- int rc;
+- if (chip) {
+- u8 savestate[] = {
+- 0, 193, /* TPM_TAG_RQU_COMMAND */
+- 0, 0, 0, 10, /* blob length (in bytes) */
+- 0, 0, 0, 152 /* TPM_ORD_SaveState */
+- };
+- dev_info(&dev->dev, "saving TPM state\n");
+- rc = tpm_inf_send(chip, savestate, sizeof(savestate));
+- if (rc < 0) {
+- dev_err(&dev->dev, "error while saving TPM state\n");
+- return rc;
+- }
+- }
+- return 0;
+-}
+-
+-static int tpm_inf_pnp_resume(struct pnp_dev *dev)
+-{
+- /* Re-configure TPM after suspending */
+- tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
+- tpm_config_out(IOLIMH, TPM_INF_ADDR);
+- tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
+- tpm_config_out(IOLIML, TPM_INF_ADDR);
+- tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
+- /* activate register */
+- tpm_config_out(TPM_DAR, TPM_INF_ADDR);
+- tpm_config_out(0x01, TPM_INF_DATA);
+- tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
+- /* disable RESET, LP and IRQC */
+- tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
+- return tpm_pm_resume(&dev->dev);
+-}
+-
+ static struct pnp_driver tpm_inf_pnp_driver = {
+ .name = "tpm_inf_pnp",
+- .id_table = tpm_inf_pnp_tbl,
++ .driver = {
++ .owner = THIS_MODULE,
++ .suspend = tpm_pm_suspend,
++ .resume = tpm_pm_resume,
++ },
++ .id_table = tpm_pnp_tbl,
+ .probe = tpm_inf_pnp_probe,
+- .suspend = tpm_inf_pnp_suspend,
+- .resume = tpm_inf_pnp_resume,
+- .remove = __devexit_p(tpm_inf_pnp_remove)
++ .remove = __devexit_p(tpm_inf_pnp_remove),
+ };
+
+ static int __init init_inf(void)
+@@ -673,5 +638,5 @@ module_exit(cleanup_inf);
+
+ MODULE_AUTHOR("Marcel Selhorst <m.selhorst at sirrix.com>");
+ MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
+-MODULE_VERSION("1.9.2");
++MODULE_VERSION("1.9");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
+index 05cab2c..59499ee 100644
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -1930,10 +1930,8 @@ static int tty_fasync(int fd, struct file *filp, int on)
+ pid = task_pid(current);
+ type = PIDTYPE_PID;
+ }
+- get_pid(pid);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ retval = __f_setown(filp, pid, type, 0);
+- put_pid(pid);
+ if (retval)
+ goto out;
+ } else {
+diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
+index 537c29a..f060246 100644
+--- a/drivers/connector/connector.c
++++ b/drivers/connector/connector.c
+@@ -36,6 +36,17 @@ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Evgeniy Polyakov <zbr at ioremap.net>");
+ MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
+
++static u32 cn_idx = CN_IDX_CONNECTOR;
++static u32 cn_val = CN_VAL_CONNECTOR;
++
++module_param(cn_idx, uint, 0);
++module_param(cn_val, uint, 0);
++MODULE_PARM_DESC(cn_idx, "Connector's main device idx.");
++MODULE_PARM_DESC(cn_val, "Connector's main device val.");
++
++static DEFINE_MUTEX(notify_lock);
++static LIST_HEAD(notify_list);
++
+ static struct cn_dev cdev;
+
+ static int cn_already_initialized;
+@@ -199,6 +210,54 @@ static void cn_rx_skb(struct sk_buff *__skb)
+ }
+
+ /*
++ * Notification routing.
++ *
++ * Gets id and checks if there are notification request for it's idx
++ * and val. If there are such requests notify the listeners with the
++ * given notify event.
++ *
++ */
++static void cn_notify(struct cb_id *id, u32 notify_event)
++{
++ struct cn_ctl_entry *ent;
++
++ mutex_lock(¬ify_lock);
++ list_for_each_entry(ent, ¬ify_list, notify_entry) {
++ int i;
++ struct cn_notify_req *req;
++ struct cn_ctl_msg *ctl = ent->msg;
++ int idx_found, val_found;
++
++ idx_found = val_found = 0;
++
++ req = (struct cn_notify_req *)ctl->data;
++ for (i = 0; i < ctl->idx_notify_num; ++i, ++req) {
++ if (id->idx >= req->first &&
++ id->idx < req->first + req->range) {
++ idx_found = 1;
++ break;
++ }
++ }
++
++ for (i = 0; i < ctl->val_notify_num; ++i, ++req) {
++ if (id->val >= req->first &&
++ id->val < req->first + req->range) {
++ val_found = 1;
++ break;
++ }
++ }
++
++ if (idx_found && val_found) {
++ struct cn_msg m = { .ack = notify_event, };
++
++ memcpy(&m.id, id, sizeof(m.id));
++ cn_netlink_send(&m, ctl->group, GFP_KERNEL);
++ }
++ }
++ mutex_unlock(¬ify_lock);
++}
++
++/*
+ * Callback add routing - adds callback with given ID and name.
+ * If there is registered callback with the same ID it will not be added.
+ *
+@@ -217,6 +276,8 @@ int cn_add_callback(struct cb_id *id, char *name,
+ if (err)
+ return err;
+
++ cn_notify(id, 0);
++
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(cn_add_callback);
+@@ -234,9 +295,111 @@ void cn_del_callback(struct cb_id *id)
+ struct cn_dev *dev = &cdev;
+
+ cn_queue_del_callback(dev->cbdev, id);
++ cn_notify(id, 1);
+ }
+ EXPORT_SYMBOL_GPL(cn_del_callback);
+
++/*
++ * Checks two connector's control messages to be the same.
++ * Returns 1 if they are the same or if the first one is corrupted.
++ */
++static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
++{
++ int i;
++ struct cn_notify_req *req1, *req2;
++
++ if (m1->idx_notify_num != m2->idx_notify_num)
++ return 0;
++
++ if (m1->val_notify_num != m2->val_notify_num)
++ return 0;
++
++ if (m1->len != m2->len)
++ return 0;
++
++ if ((m1->idx_notify_num + m1->val_notify_num) * sizeof(*req1) !=
++ m1->len)
++ return 1;
++
++ req1 = (struct cn_notify_req *)m1->data;
++ req2 = (struct cn_notify_req *)m2->data;
++
++ for (i = 0; i < m1->idx_notify_num; ++i) {
++ if (req1->first != req2->first || req1->range != req2->range)
++ return 0;
++ req1++;
++ req2++;
++ }
++
++ for (i = 0; i < m1->val_notify_num; ++i) {
++ if (req1->first != req2->first || req1->range != req2->range)
++ return 0;
++ req1++;
++ req2++;
++ }
++
++ return 1;
++}
++
++/*
++ * Main connector device's callback.
++ *
++ * Used for notification of a request's processing.
++ */
++static void cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
++{
++ struct cn_ctl_msg *ctl;
++ struct cn_ctl_entry *ent;
++ u32 size;
++
++ if (msg->len < sizeof(*ctl))
++ return;
++
++ ctl = (struct cn_ctl_msg *)msg->data;
++
++ size = (sizeof(*ctl) + ((ctl->idx_notify_num +
++ ctl->val_notify_num) *
++ sizeof(struct cn_notify_req)));
++
++ if (msg->len != size)
++ return;
++
++ if (ctl->len + sizeof(*ctl) != msg->len)
++ return;
++
++ /*
++ * Remove notification.
++ */
++ if (ctl->group == 0) {
++ struct cn_ctl_entry *n;
++
++ mutex_lock(¬ify_lock);
++ list_for_each_entry_safe(ent, n, ¬ify_list, notify_entry) {
++ if (cn_ctl_msg_equals(ent->msg, ctl)) {
++ list_del(&ent->notify_entry);
++ kfree(ent);
++ }
++ }
++ mutex_unlock(¬ify_lock);
++
++ return;
++ }
++
++ size += sizeof(*ent);
++
++ ent = kzalloc(size, GFP_KERNEL);
++ if (!ent)
++ return;
++
++ ent->msg = (struct cn_ctl_msg *)(ent + 1);
++
++ memcpy(ent->msg, ctl, size - sizeof(*ent));
++
++ mutex_lock(¬ify_lock);
++ list_add(&ent->notify_entry, ¬ify_list);
++ mutex_unlock(¬ify_lock);
++}
++
+ static int cn_proc_show(struct seq_file *m, void *v)
+ {
+ struct cn_queue_dev *dev = cdev.cbdev;
+@@ -274,8 +437,11 @@ static const struct file_operations cn_file_ops = {
+ static int __devinit cn_init(void)
+ {
+ struct cn_dev *dev = &cdev;
++ int err;
+
+ dev->input = cn_rx_skb;
++ dev->id.idx = cn_idx;
++ dev->id.val = cn_val;
+
+ dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
+ CN_NETLINK_USERS + 0xf,
+@@ -291,6 +457,14 @@ static int __devinit cn_init(void)
+
+ cn_already_initialized = 1;
+
++ err = cn_add_callback(&dev->id, "connector", &cn_callback);
++ if (err) {
++ cn_already_initialized = 0;
++ cn_queue_free_dev(dev->cbdev);
++ netlink_kernel_release(dev->nls);
++ return -EINVAL;
++ }
++
+ proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops);
+
+ return 0;
+@@ -304,6 +478,7 @@ static void __devexit cn_fini(void)
+
+ proc_net_remove(&init_net, "connector");
+
++ cn_del_callback(&dev->id);
+ cn_queue_free_dev(dev->cbdev);
+ netlink_kernel_release(dev->nls);
+ }
+diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
+index 73655ae..6810443 100644
+--- a/drivers/cpuidle/governors/menu.c
++++ b/drivers/cpuidle/governors/menu.c
+@@ -18,7 +18,6 @@
+ #include <linux/hrtimer.h>
+ #include <linux/tick.h>
+ #include <linux/sched.h>
+-#include <linux/math64.h>
+
+ #define BUCKETS 12
+ #define RESOLUTION 1024
+@@ -170,12 +169,6 @@ static DEFINE_PER_CPU(struct menu_device, menu_devices);
+
+ static void menu_update(struct cpuidle_device *dev);
+
+-/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */
+-static u64 div_round64(u64 dividend, u32 divisor)
+-{
+- return div_u64(dividend + (divisor / 2), divisor);
+-}
+-
+ /**
+ * menu_select - selects the next idle state to enter
+ * @dev: the CPU
+@@ -216,8 +209,9 @@ static int menu_select(struct cpuidle_device *dev)
+ data->correction_factor[data->bucket] = RESOLUTION * DECAY;
+
+ /* Make sure to round up for half microseconds */
+- data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket],
+- RESOLUTION * DECAY);
++ data->predicted_us = DIV_ROUND_CLOSEST(
++ data->expected_us * data->correction_factor[data->bucket],
++ RESOLUTION * DECAY);
+
+ /*
+ * We want to default to C1 (hlt), not to busy polling
+diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c
+index d3a27e0..0af8057 100644
+--- a/drivers/crypto/padlock-sha.c
++++ b/drivers/crypto/padlock-sha.c
+@@ -57,23 +57,6 @@ static int padlock_sha_update(struct shash_desc *desc,
+ return crypto_shash_update(&dctx->fallback, data, length);
+ }
+
+-static int padlock_sha_export(struct shash_desc *desc, void *out)
+-{
+- struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
+-
+- return crypto_shash_export(&dctx->fallback, out);
+-}
+-
+-static int padlock_sha_import(struct shash_desc *desc, const void *in)
+-{
+- struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
+- struct padlock_sha_ctx *ctx = crypto_shash_ctx(desc->tfm);
+-
+- dctx->fallback.tfm = ctx->fallback;
+- dctx->fallback.flags = desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
+- return crypto_shash_import(&dctx->fallback, in);
+-}
+-
+ static inline void padlock_output_block(uint32_t *src,
+ uint32_t *dst, size_t count)
+ {
+@@ -252,10 +235,7 @@ static struct shash_alg sha1_alg = {
+ .update = padlock_sha_update,
+ .finup = padlock_sha1_finup,
+ .final = padlock_sha1_final,
+- .export = padlock_sha_export,
+- .import = padlock_sha_import,
+ .descsize = sizeof(struct padlock_sha_desc),
+- .statesize = sizeof(struct sha1_state),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-padlock",
+@@ -276,10 +256,7 @@ static struct shash_alg sha256_alg = {
+ .update = padlock_sha_update,
+ .finup = padlock_sha256_finup,
+ .final = padlock_sha256_final,
+- .export = padlock_sha_export,
+- .import = padlock_sha_import,
+ .descsize = sizeof(struct padlock_sha_desc),
+- .statesize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-padlock",
+diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
+index c558fa1..7585c41 100644
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -815,7 +815,7 @@ atc_is_tx_complete(struct dma_chan *chan,
+ dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n",
+ cookie, done ? *done : 0, used ? *used : 0);
+
+- spin_lock_bh(&atchan->lock);
++ spin_lock_bh(atchan->lock);
+
+ last_complete = atchan->completed_cookie;
+ last_used = chan->cookie;
+@@ -830,7 +830,7 @@ atc_is_tx_complete(struct dma_chan *chan,
+ ret = dma_async_is_complete(cookie, last_complete, last_used);
+ }
+
+- spin_unlock_bh(&atchan->lock);
++ spin_unlock_bh(atchan->lock);
+
+ if (done)
+ *done = last_complete;
+diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
+index dcc4ab7..c524d36 100644
+--- a/drivers/dma/ioat/dma.c
++++ b/drivers/dma/ioat/dma.c
+@@ -1032,7 +1032,7 @@ int __devinit ioat_probe(struct ioatdma_device *device)
+ dma->dev = &pdev->dev;
+
+ if (!dma->chancnt) {
+- dev_err(dev, "channel enumeration error\n");
++ dev_err(dev, "zero channels detected\n");
+ goto err_setup_interrupts;
+ }
+
+diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
+index bbc3e78..45edde9 100644
+--- a/drivers/dma/ioat/dma.h
++++ b/drivers/dma/ioat/dma.h
+@@ -60,7 +60,6 @@
+ * @dca: direct cache access context
+ * @intr_quirk: interrupt setup quirk (for ioat_v1 devices)
+ * @enumerate_channels: hw version specific channel enumeration
+- * @reset_hw: hw version specific channel (re)initialization
+ * @cleanup_tasklet: select between the v2 and v3 cleanup routines
+ * @timer_fn: select between the v2 and v3 timer watchdog routines
+ * @self_test: hardware version specific self test for each supported op type
+@@ -79,7 +78,6 @@ struct ioatdma_device {
+ struct dca_provider *dca;
+ void (*intr_quirk)(struct ioatdma_device *device);
+ int (*enumerate_channels)(struct ioatdma_device *device);
+- int (*reset_hw)(struct ioat_chan_common *chan);
+ void (*cleanup_tasklet)(unsigned long data);
+ void (*timer_fn)(unsigned long data);
+ int (*self_test)(struct ioatdma_device *device);
+@@ -266,22 +264,6 @@ static inline void ioat_suspend(struct ioat_chan_common *chan)
+ writeb(IOAT_CHANCMD_SUSPEND, chan->reg_base + IOAT_CHANCMD_OFFSET(ver));
+ }
+
+-static inline void ioat_reset(struct ioat_chan_common *chan)
+-{
+- u8 ver = chan->device->version;
+-
+- writeb(IOAT_CHANCMD_RESET, chan->reg_base + IOAT_CHANCMD_OFFSET(ver));
+-}
+-
+-static inline bool ioat_reset_pending(struct ioat_chan_common *chan)
+-{
+- u8 ver = chan->device->version;
+- u8 cmd;
+-
+- cmd = readb(chan->reg_base + IOAT_CHANCMD_OFFSET(ver));
+- return (cmd & IOAT_CHANCMD_RESET) == IOAT_CHANCMD_RESET;
+-}
+-
+ static inline void ioat_set_chainaddr(struct ioat_dma_chan *ioat, u64 addr)
+ {
+ struct ioat_chan_common *chan = &ioat->base;
+diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
+index 5cc37af..8f1f7f0 100644
+--- a/drivers/dma/ioat/dma_v2.c
++++ b/drivers/dma/ioat/dma_v2.c
+@@ -239,50 +239,20 @@ void __ioat2_restart_chan(struct ioat2_dma_chan *ioat)
+ __ioat2_start_null_desc(ioat);
+ }
+
+-int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo)
++static void ioat2_restart_channel(struct ioat2_dma_chan *ioat)
+ {
+- unsigned long end = jiffies + tmo;
+- int err = 0;
++ struct ioat_chan_common *chan = &ioat->base;
++ unsigned long phys_complete;
+ u32 status;
+
+ status = ioat_chansts(chan);
+ if (is_ioat_active(status) || is_ioat_idle(status))
+ ioat_suspend(chan);
+ while (is_ioat_active(status) || is_ioat_idle(status)) {
+- if (tmo && time_after(jiffies, end)) {
+- err = -ETIMEDOUT;
+- break;
+- }
+ status = ioat_chansts(chan);
+ cpu_relax();
+ }
+
+- return err;
+-}
+-
+-int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo)
+-{
+- unsigned long end = jiffies + tmo;
+- int err = 0;
+-
+- ioat_reset(chan);
+- while (ioat_reset_pending(chan)) {
+- if (end && time_after(jiffies, end)) {
+- err = -ETIMEDOUT;
+- break;
+- }
+- cpu_relax();
+- }
+-
+- return err;
+-}
+-
+-static void ioat2_restart_channel(struct ioat2_dma_chan *ioat)
+-{
+- struct ioat_chan_common *chan = &ioat->base;
+- unsigned long phys_complete;
+-
+- ioat2_quiesce(chan, 0);
+ if (ioat_cleanup_preamble(chan, &phys_complete))
+ __cleanup(ioat, phys_complete);
+
+@@ -348,19 +318,6 @@ void ioat2_timer_event(unsigned long data)
+ spin_unlock_bh(&chan->cleanup_lock);
+ }
+
+-static int ioat2_reset_hw(struct ioat_chan_common *chan)
+-{
+- /* throw away whatever the channel was doing and get it initialized */
+- u32 chanerr;
+-
+- ioat2_quiesce(chan, msecs_to_jiffies(100));
+-
+- chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+- writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET);
+-
+- return ioat2_reset_sync(chan, msecs_to_jiffies(200));
+-}
+-
+ /**
+ * ioat2_enumerate_channels - find and initialize the device's channels
+ * @device: the device to be enumerated
+@@ -403,10 +360,6 @@ int ioat2_enumerate_channels(struct ioatdma_device *device)
+ (unsigned long) ioat);
+ ioat->xfercap_log = xfercap_log;
+ spin_lock_init(&ioat->ring_lock);
+- if (device->reset_hw(&ioat->base)) {
+- i = 0;
+- break;
+- }
+ }
+ dma->chancnt = i;
+ return i;
+@@ -514,6 +467,7 @@ int ioat2_alloc_chan_resources(struct dma_chan *c)
+ struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
+ struct ioat_chan_common *chan = &ioat->base;
+ struct ioat_ring_ent **ring;
++ u32 chanerr;
+ int order;
+
+ /* have we already been set up? */
+@@ -523,6 +477,12 @@ int ioat2_alloc_chan_resources(struct dma_chan *c)
+ /* Setup register to interrupt and write completion status on error */
+ writew(IOAT_CHANCTRL_RUN, chan->reg_base + IOAT_CHANCTRL_OFFSET);
+
++ chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
++ if (chanerr) {
++ dev_err(to_dev(chan), "CHANERR = %x, clearing\n", chanerr);
++ writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET);
++ }
++
+ /* allocate a completion writeback area */
+ /* doing 2 32bit writes to mmio since 1 64b write doesn't work */
+ chan->completion = pci_pool_alloc(chan->device->completion_pool,
+@@ -786,7 +746,13 @@ void ioat2_free_chan_resources(struct dma_chan *c)
+ tasklet_disable(&chan->cleanup_task);
+ del_timer_sync(&chan->timer);
+ device->cleanup_tasklet((unsigned long) ioat);
+- device->reset_hw(chan);
++
++ /* Delay 100ms after reset to allow internal DMA logic to quiesce
++ * before removing DMA descriptor resources.
++ */
++ writeb(IOAT_CHANCMD_RESET,
++ chan->reg_base + IOAT_CHANCMD_OFFSET(chan->device->version));
++ mdelay(100);
+
+ spin_lock_bh(&ioat->ring_lock);
+ descs = ioat2_ring_space(ioat);
+@@ -873,7 +839,6 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca)
+ int err;
+
+ device->enumerate_channels = ioat2_enumerate_channels;
+- device->reset_hw = ioat2_reset_hw;
+ device->cleanup_tasklet = ioat2_cleanup_tasklet;
+ device->timer_fn = ioat2_timer_event;
+ device->self_test = ioat_dma_self_test;
+diff --git a/drivers/dma/ioat/dma_v2.h b/drivers/dma/ioat/dma_v2.h
+index 3afad8d..1d849ef 100644
+--- a/drivers/dma/ioat/dma_v2.h
++++ b/drivers/dma/ioat/dma_v2.h
+@@ -185,8 +185,6 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order);
+ void __ioat2_issue_pending(struct ioat2_dma_chan *ioat);
+ void ioat2_cleanup_tasklet(unsigned long data);
+ void ioat2_timer_event(unsigned long data);
+-int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo);
+-int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo);
+ extern struct kobj_type ioat2_ktype;
+ extern struct kmem_cache *ioat2_cache;
+ #endif /* IOATDMA_V2_H */
+diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
+index 9908c9e..42f6f10 100644
+--- a/drivers/dma/ioat/dma_v3.c
++++ b/drivers/dma/ioat/dma_v3.c
+@@ -650,11 +650,9 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result,
+
+ num_descs = ioat2_xferlen_to_descs(ioat, len);
+ /* we need 2x the number of descriptors to cover greater than 3
+- * sources (we need 1 extra source in the q-only continuation
+- * case and 3 extra sources in the p+q continuation case.
++ * sources
+ */
+- if (src_cnt + dmaf_p_disabled_continue(flags) > 3 ||
+- (dmaf_continue(flags) && !dmaf_p_disabled_continue(flags))) {
++ if (src_cnt > 3 || flags & DMA_PREP_CONTINUE) {
+ with_ext = 1;
+ num_descs *= 2;
+ } else
+@@ -1130,45 +1128,6 @@ static int __devinit ioat3_dma_self_test(struct ioatdma_device *device)
+ return 0;
+ }
+
+-static int ioat3_reset_hw(struct ioat_chan_common *chan)
+-{
+- /* throw away whatever the channel was doing and get it
+- * initialized, with ioat3 specific workarounds
+- */
+- struct ioatdma_device *device = chan->device;
+- struct pci_dev *pdev = device->pdev;
+- u32 chanerr;
+- u16 dev_id;
+- int err;
+-
+- ioat2_quiesce(chan, msecs_to_jiffies(100));
+-
+- chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+- writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET);
+-
+- /* -= IOAT ver.3 workarounds =- */
+- /* Write CHANERRMSK_INT with 3E07h to mask out the errors
+- * that can cause stability issues for IOAT ver.3, and clear any
+- * pending errors
+- */
+- pci_write_config_dword(pdev, IOAT_PCI_CHANERRMASK_INT_OFFSET, 0x3e07);
+- err = pci_read_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, &chanerr);
+- if (err) {
+- dev_err(&pdev->dev, "channel error register unreachable\n");
+- return err;
+- }
+- pci_write_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, chanerr);
+-
+- /* Clear DMAUNCERRSTS Cfg-Reg Parity Error status bit
+- * (workaround for spurious config parity error after restart)
+- */
+- pci_read_config_word(pdev, IOAT_PCI_DEVICE_ID_OFFSET, &dev_id);
+- if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0)
+- pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10);
+-
+- return ioat2_reset_sync(chan, msecs_to_jiffies(200));
+-}
+-
+ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
+ {
+ struct pci_dev *pdev = device->pdev;
+@@ -1178,10 +1137,10 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
+ struct ioat_chan_common *chan;
+ bool is_raid_device = false;
+ int err;
++ u16 dev_id;
+ u32 cap;
+
+ device->enumerate_channels = ioat2_enumerate_channels;
+- device->reset_hw = ioat3_reset_hw;
+ device->self_test = ioat3_dma_self_test;
+ dma = &device->common;
+ dma->device_prep_dma_memcpy = ioat2_dma_prep_memcpy_lock;
+@@ -1257,6 +1216,19 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
+ dma->device_prep_dma_xor_val = NULL;
+ #endif
+
++ /* -= IOAT ver.3 workarounds =- */
++ /* Write CHANERRMSK_INT with 3E07h to mask out the errors
++ * that can cause stability issues for IOAT ver.3
++ */
++ pci_write_config_dword(pdev, IOAT_PCI_CHANERRMASK_INT_OFFSET, 0x3e07);
++
++ /* Clear DMAUNCERRSTS Cfg-Reg Parity Error status bit
++ * (workaround for spurious config parity error after restart)
++ */
++ pci_read_config_word(pdev, IOAT_PCI_DEVICE_ID_OFFSET, &dev_id);
++ if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0)
++ pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10);
++
+ err = ioat_probe(device);
+ if (err)
+ return err;
+diff --git a/drivers/dma/ioat/registers.h b/drivers/dma/ioat/registers.h
+index e8ae63b..f015ec1 100644
+--- a/drivers/dma/ioat/registers.h
++++ b/drivers/dma/ioat/registers.h
+@@ -27,7 +27,6 @@
+
+ #define IOAT_PCI_DEVICE_ID_OFFSET 0x02
+ #define IOAT_PCI_DMAUNCERRSTS_OFFSET 0x148
+-#define IOAT_PCI_CHANERR_INT_OFFSET 0x180
+ #define IOAT_PCI_CHANERRMASK_INT_OFFSET 0x184
+
+ /* MMIO Device Registers */
+diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
+index 01bc8e2..a38831c 100644
+--- a/drivers/edac/amd64_edac.c
++++ b/drivers/edac/amd64_edac.c
+@@ -13,8 +13,6 @@ module_param(report_gart_errors, int, 0644);
+ static int ecc_enable_override;
+ module_param(ecc_enable_override, int, 0644);
+
+-static struct msr *msrs;
+-
+ /* Lookup table for all possible MC control instances */
+ struct amd64_pvt;
+ static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
+@@ -2620,90 +2618,6 @@ static int amd64_init_csrows(struct mem_ctl_info *mci)
+ return empty;
+ }
+
+-/* get all cores on this DCT */
+-static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
+-{
+- int cpu;
+-
+- for_each_online_cpu(cpu)
+- if (amd_get_nb_id(cpu) == nid)
+- cpumask_set_cpu(cpu, mask);
+-}
+-
+-/* check MCG_CTL on all the cpus on this node */
+-static bool amd64_nb_mce_bank_enabled_on_node(int nid)
+-{
+- cpumask_var_t mask;
+- int cpu, nbe;
+- bool ret = false;
+-
+- if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) {
+- amd64_printk(KERN_WARNING, "%s: error allocating mask\n",
+- __func__);
+- return false;
+- }
+-
+- get_cpus_on_this_dct_cpumask(mask, nid);
+-
+- rdmsr_on_cpus(mask, MSR_IA32_MCG_CTL, msrs);
+-
+- for_each_cpu(cpu, mask) {
+- struct msr *reg = per_cpu_ptr(msrs, cpu);
+- nbe = reg->l & K8_MSR_MCGCTL_NBE;
+-
+- debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
+- cpu, reg->q,
+- (nbe ? "enabled" : "disabled"));
+-
+- if (!nbe)
+- goto out;
+- }
+- ret = true;
+-
+-out:
+- free_cpumask_var(mask);
+- return ret;
+-}
+-
+-static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
+-{
+- cpumask_var_t cmask;
+- int cpu;
+-
+- if (!zalloc_cpumask_var(&cmask, GFP_KERNEL)) {
+- amd64_printk(KERN_WARNING, "%s: error allocating mask\n",
+- __func__);
+- return false;
+- }
+-
+- get_cpus_on_this_dct_cpumask(cmask, pvt->mc_node_id);
+-
+- rdmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
+-
+- for_each_cpu(cpu, cmask) {
+-
+- struct msr *reg = per_cpu_ptr(msrs, cpu);
+-
+- if (on) {
+- if (reg->l & K8_MSR_MCGCTL_NBE)
+- pvt->flags.ecc_report = 1;
+-
+- reg->l |= K8_MSR_MCGCTL_NBE;
+- } else {
+- /*
+- * Turn off ECC reporting only when it was off before
+- */
+- if (!pvt->flags.ecc_report)
+- reg->l &= ~K8_MSR_MCGCTL_NBE;
+- }
+- }
+- wrmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
+-
+- free_cpumask_var(cmask);
+-
+- return 0;
+-}
+-
+ /*
+ * Only if 'ecc_enable_override' is set AND BIOS had ECC disabled, do "we"
+ * enable it.
+@@ -2711,12 +2625,17 @@ static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
+ static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
+ {
+ struct amd64_pvt *pvt = mci->pvt_info;
+- int err = 0;
+- u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
++ const cpumask_t *cpumask = cpumask_of_node(pvt->mc_node_id);
++ int cpu, idx = 0, err = 0;
++ struct msr msrs[cpumask_weight(cpumask)];
++ u32 value;
++ u32 mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
+
+ if (!ecc_enable_override)
+ return;
+
++ memset(msrs, 0, sizeof(msrs));
++
+ amd64_printk(KERN_WARNING,
+ "'ecc_enable_override' parameter is active, "
+ "Enabling AMD ECC hardware now: CAUTION\n");
+@@ -2732,9 +2651,16 @@ static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
+ value |= mask;
+ pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
+
+- if (amd64_toggle_ecc_err_reporting(pvt, ON))
+- amd64_printk(KERN_WARNING, "Error enabling ECC reporting over "
+- "MCGCTL!\n");
++ rdmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
++
++ for_each_cpu(cpu, cpumask) {
++ if (msrs[idx].l & K8_MSR_MCGCTL_NBE)
++ set_bit(idx, &pvt->old_mcgctl);
++
++ msrs[idx].l |= K8_MSR_MCGCTL_NBE;
++ idx++;
++ }
++ wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
+
+ err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
+ if (err)
+@@ -2775,12 +2701,17 @@ static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
+
+ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
+ {
+- int err = 0;
+- u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
++ const cpumask_t *cpumask = cpumask_of_node(pvt->mc_node_id);
++ int cpu, idx = 0, err = 0;
++ struct msr msrs[cpumask_weight(cpumask)];
++ u32 value;
++ u32 mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
+
+ if (!pvt->nbctl_mcgctl_saved)
+ return;
+
++ memset(msrs, 0, sizeof(msrs));
++
+ err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCTL, &value);
+ if (err)
+ debugf0("Reading K8_NBCTL failed\n");
+@@ -2790,9 +2721,66 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
+ /* restore the NB Enable MCGCTL bit */
+ pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
+
+- if (amd64_toggle_ecc_err_reporting(pvt, OFF))
+- amd64_printk(KERN_WARNING, "Error restoring ECC reporting over "
+- "MCGCTL!\n");
++ rdmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
++
++ for_each_cpu(cpu, cpumask) {
++ msrs[idx].l &= ~K8_MSR_MCGCTL_NBE;
++ msrs[idx].l |=
++ test_bit(idx, &pvt->old_mcgctl) << K8_MSR_MCGCTL_NBE;
++ idx++;
++ }
++
++ wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
++}
++
++/* get all cores on this DCT */
++static void get_cpus_on_this_dct_cpumask(cpumask_t *mask, int nid)
++{
++ int cpu;
++
++ for_each_online_cpu(cpu)
++ if (amd_get_nb_id(cpu) == nid)
++ cpumask_set_cpu(cpu, mask);
++}
++
++/* check MCG_CTL on all the cpus on this node */
++static bool amd64_nb_mce_bank_enabled_on_node(int nid)
++{
++ cpumask_t mask;
++ struct msr *msrs;
++ int cpu, nbe, idx = 0;
++ bool ret = false;
++
++ cpumask_clear(&mask);
++
++ get_cpus_on_this_dct_cpumask(&mask, nid);
++
++ msrs = kzalloc(sizeof(struct msr) * cpumask_weight(&mask), GFP_KERNEL);
++ if (!msrs) {
++ amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
++ __func__);
++ return false;
++ }
++
++ rdmsr_on_cpus(&mask, MSR_IA32_MCG_CTL, msrs);
++
++ for_each_cpu(cpu, &mask) {
++ nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE;
++
++ debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
++ cpu, msrs[idx].q,
++ (nbe ? "enabled" : "disabled"));
++
++ if (!nbe)
++ goto out;
++
++ idx++;
++ }
++ ret = true;
++
++out:
++ kfree(msrs);
++ return ret;
+ }
+
+ /*
+@@ -2801,11 +2789,10 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
+ * the memory system completely. A command line option allows to force-enable
+ * hardware ECC later in amd64_enable_ecc_error_reporting().
+ */
+-static const char *ecc_msg =
+- "ECC disabled in the BIOS or no ECC capability, module will not load.\n"
+- " Either enable ECC checking or force module loading by setting "
+- "'ecc_enable_override'.\n"
+- " (Note that use of the override may cause unknown side effects.)\n";
++static const char *ecc_warning =
++ "WARNING: ECC is disabled by BIOS. Module will NOT be loaded.\n"
++ " Either Enable ECC in the BIOS, or set 'ecc_enable_override'.\n"
++ " Also, use of the override can cause unknown side effects.\n";
+
+ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
+ {
+@@ -2820,7 +2807,7 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
+
+ ecc_enabled = !!(value & K8_NBCFG_ECC_ENABLE);
+ if (!ecc_enabled)
+- amd64_printk(KERN_NOTICE, "This node reports that Memory ECC "
++ amd64_printk(KERN_WARNING, "This node reports that Memory ECC "
+ "is currently disabled, set F3x%x[22] (%s).\n",
+ K8_NBCFG, pci_name(pvt->misc_f3_ctl));
+ else
+@@ -2828,17 +2815,18 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
+
+ nb_mce_en = amd64_nb_mce_bank_enabled_on_node(pvt->mc_node_id);
+ if (!nb_mce_en)
+- amd64_printk(KERN_NOTICE, "NB MCE bank disabled, set MSR "
++ amd64_printk(KERN_WARNING, "NB MCE bank disabled, set MSR "
+ "0x%08x[4] on node %d to enable.\n",
+ MSR_IA32_MCG_CTL, pvt->mc_node_id);
+
+ if (!ecc_enabled || !nb_mce_en) {
+ if (!ecc_enable_override) {
+- amd64_printk(KERN_NOTICE, "%s", ecc_msg);
++ amd64_printk(KERN_WARNING, "%s", ecc_warning);
+ return -ENODEV;
+ }
++ } else
++ /* CLEAR the override, since BIOS controlled it */
+ ecc_enable_override = 0;
+- }
+
+ return 0;
+ }
+@@ -2921,6 +2909,7 @@ static int amd64_probe_one_instance(struct pci_dev *dram_f2_ctl,
+ pvt->ext_model = boot_cpu_data.x86_model >> 4;
+ pvt->mc_type_index = mc_type_index;
+ pvt->ops = family_ops(mc_type_index);
++ pvt->old_mcgctl = 0;
+
+ /*
+ * We have the dram_f2_ctl device as an argument, now go reserve its
+@@ -3082,15 +3071,16 @@ static void __devexit amd64_remove_one_instance(struct pci_dev *pdev)
+
+ amd64_free_mc_sibling_devices(pvt);
+
++ kfree(pvt);
++ mci->pvt_info = NULL;
++
++ mci_lookup[pvt->mc_node_id] = NULL;
++
+ /* unregister from EDAC MCE */
+ amd_report_gart_errors(false);
+ amd_unregister_ecc_decoder(amd64_decode_bus_error);
+
+ /* Free the EDAC CORE resources */
+- mci->pvt_info = NULL;
+- mci_lookup[pvt->mc_node_id] = NULL;
+-
+- kfree(pvt);
+ edac_mc_free(mci);
+ }
+
+@@ -3167,29 +3157,23 @@ static void amd64_setup_pci_device(void)
+ static int __init amd64_edac_init(void)
+ {
+ int nb, err = -ENODEV;
+- bool load_ok = false;
+
+ edac_printk(KERN_INFO, EDAC_MOD_STR, EDAC_AMD64_VERSION "\n");
+
+ opstate_init();
+
+ if (cache_k8_northbridges() < 0)
+- goto err_ret;
+-
+- msrs = msrs_alloc();
+- if (!msrs)
+- goto err_ret;
++ return err;
+
+ err = pci_register_driver(&amd64_pci_driver);
+ if (err)
+- goto err_pci;
++ return err;
+
+ /*
+ * At this point, the array 'pvt_lookup[]' contains pointers to alloc'd
+ * amd64_pvt structs. These will be used in the 2nd stage init function
+ * to finish initialization of the MC instances.
+ */
+- err = -ENODEV;
+ for (nb = 0; nb < num_k8_northbridges; nb++) {
+ if (!pvt_lookup[nb])
+ continue;
+@@ -3197,21 +3181,16 @@ static int __init amd64_edac_init(void)
+ err = amd64_init_2nd_stage(pvt_lookup[nb]);
+ if (err)
+ goto err_2nd_stage;
+-
+- load_ok = true;
+ }
+
+- if (load_ok) {
+- amd64_setup_pci_device();
+- return 0;
+- }
++ amd64_setup_pci_device();
++
++ return 0;
+
+ err_2nd_stage:
++ debugf0("2nd stage failed\n");
+ pci_unregister_driver(&amd64_pci_driver);
+-err_pci:
+- msrs_free(msrs);
+- msrs = NULL;
+-err_ret:
++
+ return err;
+ }
+
+@@ -3221,9 +3200,6 @@ static void __exit amd64_edac_exit(void)
+ edac_pci_release_generic_ctl(amd64_ctl_pci);
+
+ pci_unregister_driver(&amd64_pci_driver);
+-
+- msrs_free(msrs);
+- msrs = NULL;
+ }
+
+ module_init(amd64_edac_init);
+diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
+index bba6c94..c6f359a 100644
+--- a/drivers/edac/amd64_edac.h
++++ b/drivers/edac/amd64_edac.h
+@@ -147,8 +147,6 @@
+ #define MAX_CS_COUNT 8
+ #define DRAM_REG_COUNT 8
+
+-#define ON true
+-#define OFF false
+
+ /*
+ * PCI-defined configuration space registers
+@@ -388,7 +386,10 @@ enum {
+ #define K8_NBCAP_DUAL_NODE BIT(1)
+ #define K8_NBCAP_DCT_DUAL BIT(0)
+
+-/* MSRs */
++/*
++ * MSR Regs
++ */
++#define K8_MSR_MCGCTL 0x017b
+ #define K8_MSR_MCGCTL_NBE BIT(4)
+
+ #define K8_MSR_MC4CTL 0x0410
+@@ -486,6 +487,7 @@ struct amd64_pvt {
+ /* Save old hw registers' values before we modified them */
+ u32 nbctl_mcgctl_saved; /* When true, following 2 are valid */
+ u32 old_nbctl;
++ unsigned long old_mcgctl; /* per core on this node */
+
+ /* MC Type Index value: socket F vs Family 10h */
+ u32 mc_type_index;
+@@ -493,7 +495,6 @@ struct amd64_pvt {
+ /* misc settings */
+ struct flags {
+ unsigned long cf8_extcfg:1;
+- unsigned long ecc_report:1;
+ } flags;
+ };
+
+diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c
+index adc10a2..77a9579 100644
+--- a/drivers/edac/i5000_edac.c
++++ b/drivers/edac/i5000_edac.c
+@@ -577,13 +577,7 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
+ debugf0("\tUncorrected bits= 0x%x\n", ue_errors);
+
+ branch = EXTRACT_FBDCHAN_INDX(info->ferr_nf_fbd);
+-
+- /*
+- * According with i5000 datasheet, bit 28 has no significance
+- * for errors M4Err-M12Err and M17Err-M21Err, on FERR_NF_FBD
+- */
+- channel = branch & 2;
+-
++ channel = branch;
+ bank = NREC_BANK(info->nrecmema);
+ rank = NREC_RANK(info->nrecmema);
+ rdwr = NREC_RDWR(info->nrecmema);
+diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
+index ed635ae..e4864e8 100644
+--- a/drivers/firewire/core-card.c
++++ b/drivers/firewire/core-card.c
+@@ -57,9 +57,6 @@ static LIST_HEAD(card_list);
+ static LIST_HEAD(descriptor_list);
+ static int descriptor_count;
+
+-/* ROM header, bus info block, root dir header, capabilities = 7 quadlets */
+-static size_t config_rom_length = 1 + 4 + 1 + 1;
+-
+ #define BIB_CRC(v) ((v) << 0)
+ #define BIB_CRC_LENGTH(v) ((v) << 16)
+ #define BIB_INFO_LENGTH(v) ((v) << 24)
+@@ -75,7 +72,7 @@ static size_t config_rom_length = 1 + 4 + 1 + 1;
+ #define BIB_CMC ((1) << 30)
+ #define BIB_IMC ((1) << 31)
+
+-static u32 *generate_config_rom(struct fw_card *card)
++static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
+ {
+ struct fw_descriptor *desc;
+ static u32 config_rom[256];
+@@ -134,7 +131,7 @@ static u32 *generate_config_rom(struct fw_card *card)
+ for (i = 0; i < j; i += length + 1)
+ length = fw_compute_block_crc(config_rom + i);
+
+- WARN_ON(j != config_rom_length);
++ *config_rom_length = j;
+
+ return config_rom;
+ }
+@@ -143,24 +140,17 @@ static void update_config_roms(void)
+ {
+ struct fw_card *card;
+ u32 *config_rom;
++ size_t length;
+
+ list_for_each_entry (card, &card_list, link) {
+- config_rom = generate_config_rom(card);
+- card->driver->set_config_rom(card, config_rom,
+- config_rom_length);
++ config_rom = generate_config_rom(card, &length);
++ card->driver->set_config_rom(card, config_rom, length);
+ }
+ }
+
+-static size_t required_space(struct fw_descriptor *desc)
+-{
+- /* descriptor + entry into root dir + optional immediate entry */
+- return desc->length + 1 + (desc->immediate > 0 ? 1 : 0);
+-}
+-
+ int fw_core_add_descriptor(struct fw_descriptor *desc)
+ {
+ size_t i;
+- int ret;
+
+ /*
+ * Check descriptor is valid; the length of all blocks in the
+@@ -176,21 +166,15 @@ int fw_core_add_descriptor(struct fw_descriptor *desc)
+
+ mutex_lock(&card_mutex);
+
+- if (config_rom_length + required_space(desc) > 256) {
+- ret = -EBUSY;
+- } else {
+- list_add_tail(&desc->link, &descriptor_list);
+- config_rom_length += required_space(desc);
++ list_add_tail(&desc->link, &descriptor_list);
++ descriptor_count++;
++ if (desc->immediate > 0)
+ descriptor_count++;
+- if (desc->immediate > 0)
+- descriptor_count++;
+- update_config_roms();
+- ret = 0;
+- }
++ update_config_roms();
+
+ mutex_unlock(&card_mutex);
+
+- return ret;
++ return 0;
+ }
+ EXPORT_SYMBOL(fw_core_add_descriptor);
+
+@@ -199,7 +183,6 @@ void fw_core_remove_descriptor(struct fw_descriptor *desc)
+ mutex_lock(&card_mutex);
+
+ list_del(&desc->link);
+- config_rom_length -= required_space(desc);
+ descriptor_count--;
+ if (desc->immediate > 0)
+ descriptor_count--;
+@@ -453,6 +436,7 @@ int fw_card_add(struct fw_card *card,
+ u32 max_receive, u32 link_speed, u64 guid)
+ {
+ u32 *config_rom;
++ size_t length;
+ int ret;
+
+ card->max_receive = max_receive;
+@@ -461,8 +445,8 @@ int fw_card_add(struct fw_card *card,
+
+ mutex_lock(&card_mutex);
+
+- config_rom = generate_config_rom(card);
+- ret = card->driver->enable(card, config_rom, config_rom_length);
++ config_rom = generate_config_rom(card, &length);
++ ret = card->driver->enable(card, config_rom, length);
+ if (ret == 0)
+ list_add_tail(&card->link, &card_list);
+
+diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
+index 720b39b..94260aa 100644
+--- a/drivers/firewire/ohci.c
++++ b/drivers/firewire/ohci.c
+@@ -2209,13 +2209,6 @@ static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
+ page = payload >> PAGE_SHIFT;
+ offset = payload & ~PAGE_MASK;
+ rest = p->payload_length;
+- /*
+- * The controllers I've tested have not worked correctly when
+- * second_req_count is zero. Rather than do something we know won't
+- * work, return an error
+- */
+- if (rest == 0)
+- return -EINVAL;
+
+ /* FIXME: make packet-per-buffer/dual-buffer a context option */
+ while (rest > 0) {
+@@ -2269,7 +2262,7 @@ static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
+ unsigned long payload)
+ {
+ struct iso_context *ctx = container_of(base, struct iso_context, base);
+- struct descriptor *d, *pd;
++ struct descriptor *d = NULL, *pd = NULL;
+ struct fw_iso_packet *p = packet;
+ dma_addr_t d_bus, page_bus;
+ u32 z, header_z, rest;
+@@ -2307,9 +2300,8 @@ static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
+ d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d)));
+
+ rest = payload_per_buffer;
+- pd = d;
+ for (j = 1; j < z; j++) {
+- pd++;
++ pd = d + j;
+ pd->control = cpu_to_le16(DESCRIPTOR_STATUS |
+ DESCRIPTOR_INPUT_MORE);
+
+@@ -2412,7 +2404,6 @@ static void ohci_pmac_off(struct pci_dev *dev)
+
+ #define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT
+ #define PCI_DEVICE_ID_AGERE_FW643 0x5901
+-#define PCI_DEVICE_ID_TI_TSB43AB23 0x8024
+
+ static int __devinit pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+@@ -2478,8 +2469,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
+ #if !defined(CONFIG_X86_32)
+ /* dual-buffer mode is broken with descriptor addresses above 2G */
+ if (dev->vendor == PCI_VENDOR_ID_TI &&
+- (dev->device == PCI_DEVICE_ID_TI_TSB43AB22 ||
+- dev->device == PCI_DEVICE_ID_TI_TSB43AB23))
++ dev->device == PCI_DEVICE_ID_TI_TSB43AB22)
+ ohci->use_dualbuffer = false;
+ #endif
+
+diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
+index 3a2ccb0..938100f 100644
+--- a/drivers/firmware/dmi_scan.c
++++ b/drivers/firmware/dmi_scan.c
+@@ -429,7 +429,7 @@ static bool dmi_matches(const struct dmi_system_id *dmi)
+ for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) {
+ int s = dmi->matches[i].slot;
+ if (s == DMI_NONE)
+- break;
++ continue;
+ if (dmi_ident[s]
+ && strstr(dmi_ident[s], dmi->matches[i].substr))
+ continue;
+@@ -440,15 +440,6 @@ static bool dmi_matches(const struct dmi_system_id *dmi)
+ }
+
+ /**
+- * dmi_is_end_of_table - check for end-of-table marker
+- * @dmi: pointer to the dmi_system_id structure to check
+- */
+-static bool dmi_is_end_of_table(const struct dmi_system_id *dmi)
+-{
+- return dmi->matches[0].slot == DMI_NONE;
+-}
+-
+-/**
+ * dmi_check_system - check system DMI data
+ * @list: array of dmi_system_id structures to match against
+ * All non-null elements of the list must match
+@@ -466,7 +457,7 @@ int dmi_check_system(const struct dmi_system_id *list)
+ int count = 0;
+ const struct dmi_system_id *d;
+
+- for (d = list; !dmi_is_end_of_table(d); d++)
++ for (d = list; d->ident; d++)
+ if (dmi_matches(d)) {
+ count++;
+ if (d->callback && d->callback(d))
+@@ -493,7 +484,7 @@ const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list)
+ {
+ const struct dmi_system_id *d;
+
+- for (d = list; !dmi_is_end_of_table(d); d++)
++ for (d = list; d->ident; d++)
+ if (dmi_matches(d))
+ return d;
+
+diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c
+index a1fce68..628eae3 100644
+--- a/drivers/gpu/drm/ati_pcigart.c
++++ b/drivers/gpu/drm/ati_pcigart.c
+@@ -39,7 +39,8 @@ static int drm_ati_alloc_pcigart_table(struct drm_device *dev,
+ struct drm_ati_pcigart_info *gart_info)
+ {
+ gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size,
+- PAGE_SIZE);
++ PAGE_SIZE,
++ gart_info->table_mask);
+ if (gart_info->table_handle == NULL)
+ return -ENOMEM;
+
+@@ -111,13 +112,6 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
+ DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
+
+- if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) {
+- DRM_ERROR("fail to set dma mask to 0x%Lx\n",
+- gart_info->table_mask);
+- ret = 1;
+- goto done;
+- }
+-
+ ret = drm_ati_alloc_pcigart_table(dev, gart_info);
+ if (ret) {
+ DRM_ERROR("cannot allocate PCI GART page!\n");
+diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
+index 8417cc4..3d09e30 100644
+--- a/drivers/gpu/drm/drm_bufs.c
++++ b/drivers/gpu/drm/drm_bufs.c
+@@ -326,7 +326,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
+ * As we're limiting the address to 2^32-1 (or less),
+ * casting it down to 32 bits is no problem, but we
+ * need to point to a 64bit variable first. */
+- dmah = drm_pci_alloc(dev, map->size, map->size);
++ dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL);
+ if (!dmah) {
+ kfree(map);
+ return -ENOMEM;
+@@ -885,7 +885,7 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request)
+
+ while (entry->buf_count < count) {
+
+- dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000);
++ dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful);
+
+ if (!dmah) {
+ /* Set count correctly so we free the proper amount. */
+diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
+index afed886..bbfd110 100644
+--- a/drivers/gpu/drm/drm_crtc_helper.c
++++ b/drivers/gpu/drm/drm_crtc_helper.c
+@@ -1020,9 +1020,6 @@ bool drm_helper_initial_config(struct drm_device *dev)
+ {
+ int count = 0;
+
+- /* disable all the possible outputs/crtcs before entering KMS mode */
+- drm_helper_disable_unused_functions(dev);
+-
+ drm_fb_helper_parse_command_line(dev);
+
+ count = drm_helper_probe_connector_modes(dev,
+diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
+index 8bf3770..e9dbb48 100644
+--- a/drivers/gpu/drm/drm_gem.c
++++ b/drivers/gpu/drm/drm_gem.c
+@@ -142,6 +142,19 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
+ if (IS_ERR(obj->filp))
+ goto free;
+
++ /* Basically we want to disable the OOM killer and handle ENOMEM
++ * ourselves by sacrificing pages from cached buffers.
++ * XXX shmem_file_[gs]et_gfp_mask()
++ */
++ mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping,
++ GFP_HIGHUSER |
++ __GFP_COLD |
++ __GFP_FS |
++ __GFP_RECLAIMABLE |
++ __GFP_NORETRY |
++ __GFP_NOWARN |
++ __GFP_NOMEMALLOC);
++
+ kref_init(&obj->refcount);
+ kref_init(&obj->handlecount);
+ obj->size = size;
+diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
+index 332d743..0a6f0b3 100644
+--- a/drivers/gpu/drm/drm_irq.c
++++ b/drivers/gpu/drm/drm_irq.c
+@@ -429,21 +429,15 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
+
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ /* Going from 0->1 means we have to enable interrupts again */
+- if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
+- if (!dev->vblank_enabled[crtc]) {
+- ret = dev->driver->enable_vblank(dev, crtc);
+- DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
+- if (ret)
+- atomic_dec(&dev->vblank_refcount[crtc]);
+- else {
+- dev->vblank_enabled[crtc] = 1;
+- drm_update_vblank_count(dev, crtc);
+- }
+- }
+- } else {
+- if (!dev->vblank_enabled[crtc]) {
++ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
++ !dev->vblank_enabled[crtc]) {
++ ret = dev->driver->enable_vblank(dev, crtc);
++ DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
++ if (ret)
+ atomic_dec(&dev->vblank_refcount[crtc]);
+- ret = -EINVAL;
++ else {
++ dev->vblank_enabled[crtc] = 1;
++ drm_update_vblank_count(dev, crtc);
+ }
+ }
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+@@ -470,18 +464,6 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
+ }
+ EXPORT_SYMBOL(drm_vblank_put);
+
+-void drm_vblank_off(struct drm_device *dev, int crtc)
+-{
+- unsigned long irqflags;
+-
+- spin_lock_irqsave(&dev->vbl_lock, irqflags);
+- DRM_WAKEUP(&dev->vbl_queue[crtc]);
+- dev->vblank_enabled[crtc] = 0;
+- dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
+- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+-}
+-EXPORT_SYMBOL(drm_vblank_off);
+-
+ /**
+ * drm_vblank_pre_modeset - account for vblanks across mode sets
+ * @dev: DRM device
+diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
+index e68ebf9..577094f 100644
+--- a/drivers/gpu/drm/drm_pci.c
++++ b/drivers/gpu/drm/drm_pci.c
+@@ -47,7 +47,8 @@
+ /**
+ * \brief Allocate a PCI consistent memory block, for DMA.
+ */
+-drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align)
++drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align,
++ dma_addr_t maxaddr)
+ {
+ drm_dma_handle_t *dmah;
+ #if 1
+@@ -62,6 +63,11 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali
+ if (align > size)
+ return NULL;
+
++ if (pci_set_dma_mask(dev->pdev, maxaddr) != 0) {
++ DRM_ERROR("Setting pci dma mask failed\n");
++ return NULL;
++ }
++
+ dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
+ if (!dmah)
+ return NULL;
+diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
+index 7e859d6..26bf055 100644
+--- a/drivers/gpu/drm/i915/i915_debugfs.c
++++ b/drivers/gpu/drm/i915/i915_debugfs.c
+@@ -288,7 +288,7 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data)
+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
+ obj = obj_priv->obj;
+ if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
+- ret = i915_gem_object_get_pages(obj, 0);
++ ret = i915_gem_object_get_pages(obj);
+ if (ret) {
+ DRM_ERROR("Failed to get pages: %d\n", ret);
+ spin_unlock(&dev_priv->mm.active_list_lock);
+@@ -384,7 +384,37 @@ out:
+ return 0;
+ }
+
++static int i915_registers_info(struct seq_file *m, void *data) {
++ struct drm_info_node *node = (struct drm_info_node *) m->private;
++ struct drm_device *dev = node->minor->dev;
++ drm_i915_private_t *dev_priv = dev->dev_private;
++ uint32_t reg;
++
++#define DUMP_RANGE(start, end) \
++ for (reg=start; reg < end; reg += 4) \
++ seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg));
++
++ DUMP_RANGE(0x00000, 0x00fff); /* VGA registers */
++ DUMP_RANGE(0x02000, 0x02fff); /* instruction, memory, interrupt control registers */
++ DUMP_RANGE(0x03000, 0x031ff); /* FENCE and PPGTT control registers */
++ DUMP_RANGE(0x03200, 0x03fff); /* frame buffer compression registers */
++ DUMP_RANGE(0x05000, 0x05fff); /* I/O control registers */
++ DUMP_RANGE(0x06000, 0x06fff); /* clock control registers */
++ DUMP_RANGE(0x07000, 0x07fff); /* 3D internal debug registers */
++ DUMP_RANGE(0x07400, 0x088ff); /* GPE debug registers */
++ DUMP_RANGE(0x0a000, 0x0afff); /* display palette registers */
++ DUMP_RANGE(0x10000, 0x13fff); /* MMIO MCHBAR */
++ DUMP_RANGE(0x30000, 0x3ffff); /* overlay registers */
++ DUMP_RANGE(0x60000, 0x6ffff); /* display engine pipeline registers */
++ DUMP_RANGE(0x70000, 0x72fff); /* display and cursor registers */
++ DUMP_RANGE(0x73000, 0x73fff); /* performance counters */
++
++ return 0;
++}
++
++
+ static struct drm_info_list i915_debugfs_list[] = {
++ {"i915_regs", i915_registers_info, 0},
+ {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
+ {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
+ {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
+diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
+index eaa1893..e5b138b 100644
+--- a/drivers/gpu/drm/i915/i915_dma.c
++++ b/drivers/gpu/drm/i915/i915_dma.c
+@@ -123,7 +123,7 @@ static int i915_init_phys_hws(struct drm_device *dev)
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ /* Program Hardware Status Page */
+ dev_priv->status_page_dmah =
+- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE);
++ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
+
+ if (!dev_priv->status_page_dmah) {
+ DRM_ERROR("Can not allocate hardware status page\n");
+@@ -1111,8 +1111,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mm_node *compressed_fb, *compressed_llb;
+- unsigned long cfb_base;
+- unsigned long ll_base = 0;
++ unsigned long cfb_base, ll_base;
+
+ /* Leave 1M for line length buffer & misc. */
+ compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0);
+@@ -1252,8 +1251,6 @@ static int i915_load_modeset_init(struct drm_device *dev,
+ if (ret)
+ goto destroy_ringbuffer;
+
+- intel_modeset_init(dev);
+-
+ ret = drm_irq_install(dev);
+ if (ret)
+ goto destroy_ringbuffer;
+@@ -1268,6 +1265,8 @@ static int i915_load_modeset_init(struct drm_device *dev,
+
+ I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
+
++ intel_modeset_init(dev);
++
+ drm_helper_initial_config(dev);
+
+ return 0;
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index f5d49a7..a725f65 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -467,15 +467,6 @@ typedef struct drm_i915_private {
+ struct list_head flushing_list;
+
+ /**
+- * List of objects currently pending a GPU write flush.
+- *
+- * All elements on this list will belong to either the
+- * active_list or flushing_list, last_rendering_seqno can
+- * be used to differentiate between the two elements.
+- */
+- struct list_head gpu_write_list;
+-
+- /**
+ * LRU list of objects which are not in the ringbuffer and
+ * are ready to unbind, but are still in the GTT.
+ *
+@@ -555,7 +546,6 @@ typedef struct drm_i915_private {
+ struct timer_list idle_timer;
+ bool busy;
+ u16 orig_clock;
+- struct drm_connector *int_lvds_connector;
+ } drm_i915_private_t;
+
+ /** driver private structure attached to each drm_gem_object */
+@@ -567,8 +557,6 @@ struct drm_i915_gem_object {
+
+ /** This object's place on the active/flushing/inactive lists */
+ struct list_head list;
+- /** This object's place on GPU write list */
+- struct list_head gpu_write_list;
+
+ /** This object's place on the fenced object LRU */
+ struct list_head fence_list;
+@@ -825,17 +813,15 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
+ int i915_gem_do_init(struct drm_device *dev, unsigned long start,
+ unsigned long end);
+ int i915_gem_idle(struct drm_device *dev);
+-int i915_lp_ring_sync(struct drm_device *dev);
+ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
+ int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
+ int write);
+-int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj);
+ int i915_gem_attach_phys_object(struct drm_device *dev,
+ struct drm_gem_object *obj, int id);
+ void i915_gem_detach_phys_object(struct drm_device *dev,
+ struct drm_gem_object *obj);
+ void i915_gem_free_all_phys_object(struct drm_device *dev);
+-int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
++int i915_gem_object_get_pages(struct drm_gem_object *obj);
+ void i915_gem_object_put_pages(struct drm_gem_object *obj);
+ void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
+
+@@ -971,7 +957,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
+ #define IS_I85X(dev) ((dev)->pci_device == 0x3582)
+ #define IS_I855(dev) ((dev)->pci_device == 0x3582)
+ #define IS_I865G(dev) ((dev)->pci_device == 0x2572)
+-#define IS_I8XX(dev) (IS_I830(dev) || IS_845G(dev) || IS_I85X(dev) || IS_I865G(dev))
+
+ #define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a)
+ #define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
+@@ -1033,12 +1018,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
+ */
+ #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
+ IS_I915GM(dev)))
+-#define SUPPORTS_DIGITAL_OUTPUTS(dev) (IS_I9XX(dev) && !IS_IGD(dev))
+ #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+ #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+ #define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev))
+-#define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \
+- !IS_IGDNG(dev) && !IS_IGD(dev))
+ #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev))
+ /* dsparb controlled by hw only */
+ #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
+index 04da731..abfc27b 100644
+--- a/drivers/gpu/drm/i915/i915_gem.c
++++ b/drivers/gpu/drm/i915/i915_gem.c
+@@ -277,7 +277,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
+
+ mutex_lock(&dev->struct_mutex);
+
+- ret = i915_gem_object_get_pages(obj, 0);
++ ret = i915_gem_object_get_pages(obj);
+ if (ret != 0)
+ goto fail_unlock;
+
+@@ -321,24 +321,40 @@ fail_unlock:
+ return ret;
+ }
+
++static inline gfp_t
++i915_gem_object_get_page_gfp_mask (struct drm_gem_object *obj)
++{
++ return mapping_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping);
++}
++
++static inline void
++i915_gem_object_set_page_gfp_mask (struct drm_gem_object *obj, gfp_t gfp)
++{
++ mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping, gfp);
++}
++
+ static int
+ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj)
+ {
+ int ret;
+
+- ret = i915_gem_object_get_pages(obj, __GFP_NORETRY | __GFP_NOWARN);
++ ret = i915_gem_object_get_pages(obj);
+
+ /* If we've insufficient memory to map in the pages, attempt
+ * to make some space by throwing out some old buffers.
+ */
+ if (ret == -ENOMEM) {
+ struct drm_device *dev = obj->dev;
++ gfp_t gfp;
+
+ ret = i915_gem_evict_something(dev, obj->size);
+ if (ret)
+ return ret;
+
+- ret = i915_gem_object_get_pages(obj, 0);
++ gfp = i915_gem_object_get_page_gfp_mask(obj);
++ i915_gem_object_set_page_gfp_mask(obj, gfp & ~__GFP_NORETRY);
++ ret = i915_gem_object_get_pages(obj);
++ i915_gem_object_set_page_gfp_mask (obj, gfp);
+ }
+
+ return ret;
+@@ -774,7 +790,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
+
+ mutex_lock(&dev->struct_mutex);
+
+- ret = i915_gem_object_get_pages(obj, 0);
++ ret = i915_gem_object_get_pages(obj);
+ if (ret != 0)
+ goto fail_unlock;
+
+@@ -1272,7 +1288,6 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
+ list->hash.key = list->file_offset_node->start;
+ if (drm_ht_insert_item(&mm->offset_hash, &list->hash)) {
+ DRM_ERROR("failed to add to map hash\n");
+- ret = -ENOMEM;
+ goto out_free_mm;
+ }
+
+@@ -1552,8 +1567,6 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
+ else
+ list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
+
+- BUG_ON(!list_empty(&obj_priv->gpu_write_list));
+-
+ obj_priv->last_rendering_seqno = 0;
+ if (obj_priv->active) {
+ obj_priv->active = 0;
+@@ -1624,8 +1637,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
+ struct drm_i915_gem_object *obj_priv, *next;
+
+ list_for_each_entry_safe(obj_priv, next,
+- &dev_priv->mm.gpu_write_list,
+- gpu_write_list) {
++ &dev_priv->mm.flushing_list, list) {
+ struct drm_gem_object *obj = obj_priv->obj;
+
+ if ((obj->write_domain & flush_domains) ==
+@@ -1633,7 +1645,6 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
+ uint32_t old_write_domain = obj->write_domain;
+
+ obj->write_domain = 0;
+- list_del_init(&obj_priv->gpu_write_list);
+ i915_gem_object_move_to_active(obj, seqno);
+
+ trace_i915_gem_object_change_domain(obj,
+@@ -1809,8 +1820,12 @@ i915_gem_retire_work_handler(struct work_struct *work)
+ mutex_unlock(&dev->struct_mutex);
+ }
+
++/**
++ * Waits for a sequence number to be signaled, and cleans up the
++ * request and object lists appropriately for that event.
++ */
+ static int
+-i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
++i915_wait_request(struct drm_device *dev, uint32_t seqno)
+ {
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ u32 ier;
+@@ -1837,15 +1852,10 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
+
+ dev_priv->mm.waiting_gem_seqno = seqno;
+ i915_user_irq_get(dev);
+- if (interruptible)
+- ret = wait_event_interruptible(dev_priv->irq_queue,
+- i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
+- atomic_read(&dev_priv->mm.wedged));
+- else
+- wait_event(dev_priv->irq_queue,
+- i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
+- atomic_read(&dev_priv->mm.wedged));
+-
++ ret = wait_event_interruptible(dev_priv->irq_queue,
++ i915_seqno_passed(i915_get_gem_seqno(dev),
++ seqno) ||
++ atomic_read(&dev_priv->mm.wedged));
+ i915_user_irq_put(dev);
+ dev_priv->mm.waiting_gem_seqno = 0;
+
+@@ -1869,34 +1879,6 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
+ return ret;
+ }
+
+-/**
+- * Waits for a sequence number to be signaled, and cleans up the
+- * request and object lists appropriately for that event.
+- */
+-static int
+-i915_wait_request(struct drm_device *dev, uint32_t seqno)
+-{
+- return i915_do_wait_request(dev, seqno, 1);
+-}
+-
+-/**
+- * Waits for the ring to finish up to the latest request. Usefull for waiting
+- * for flip events, e.g for the overlay support. */
+-int i915_lp_ring_sync(struct drm_device *dev)
+-{
+- uint32_t seqno;
+- int ret;
+-
+- seqno = i915_add_request(dev, NULL, 0);
+-
+- if (seqno == 0)
+- return -ENOMEM;
+-
+- ret = i915_do_wait_request(dev, seqno, 0);
+- BUG_ON(ret == -ERESTARTSYS);
+- return ret;
+-}
+-
+ static void
+ i915_gem_flush(struct drm_device *dev,
+ uint32_t invalidate_domains,
+@@ -1965,7 +1947,7 @@ i915_gem_flush(struct drm_device *dev,
+ #endif
+ BEGIN_LP_RING(2);
+ OUT_RING(cmd);
+- OUT_RING(MI_NOOP);
++ OUT_RING(0); /* noop */
+ ADVANCE_LP_RING();
+ }
+ }
+@@ -2027,6 +2009,9 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
+ /* blow away mappings if mapped through GTT */
+ i915_gem_release_mmap(obj);
+
++ if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
++ i915_gem_clear_fence_reg(obj);
++
+ /* Move the object to the CPU domain to ensure that
+ * any possible CPU writes while it's not in the GTT
+ * are flushed when we go to remap it. This will
+@@ -2042,10 +2027,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
+
+ BUG_ON(obj_priv->active);
+
+- /* release the fence reg _after_ flushing */
+- if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+- i915_gem_clear_fence_reg(obj);
+-
+ if (obj_priv->agp_mem != NULL) {
+ drm_unbind_agp(obj_priv->agp_mem);
+ drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
+@@ -2106,8 +2087,8 @@ static int
+ i915_gem_evict_everything(struct drm_device *dev)
+ {
+ drm_i915_private_t *dev_priv = dev->dev_private;
+- int ret;
+ uint32_t seqno;
++ int ret;
+ bool lists_empty;
+
+ spin_lock(&dev_priv->mm.active_list_lock);
+@@ -2129,8 +2110,6 @@ i915_gem_evict_everything(struct drm_device *dev)
+ if (ret)
+ return ret;
+
+- BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
+-
+ ret = i915_gem_evict_from_inactive_list(dev);
+ if (ret)
+ return ret;
+@@ -2238,8 +2217,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
+ }
+
+ int
+-i915_gem_object_get_pages(struct drm_gem_object *obj,
+- gfp_t gfpmask)
++i915_gem_object_get_pages(struct drm_gem_object *obj)
+ {
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int page_count, i;
+@@ -2265,10 +2243,7 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,
+ inode = obj->filp->f_path.dentry->d_inode;
+ mapping = inode->i_mapping;
+ for (i = 0; i < page_count; i++) {
+- page = read_cache_page_gfp(mapping, i,
+- mapping_gfp_mask (mapping) |
+- __GFP_COLD |
+- gfpmask);
++ page = read_mapping_page(mapping, i, NULL);
+ if (IS_ERR(page)) {
+ ret = PTR_ERR(page);
+ i915_gem_object_put_pages(obj);
+@@ -2591,9 +2566,12 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_mm_node *free_space;
+- gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN;
++ bool retry_alloc = false;
+ int ret;
+
++ if (dev_priv->mm.suspended)
++ return -EBUSY;
++
+ if (obj_priv->madv != I915_MADV_WILLNEED) {
+ DRM_ERROR("Attempting to bind a purgeable object\n");
+ return -EINVAL;
+@@ -2635,7 +2613,15 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
+ DRM_INFO("Binding object of size %zd at 0x%08x\n",
+ obj->size, obj_priv->gtt_offset);
+ #endif
+- ret = i915_gem_object_get_pages(obj, gfpmask);
++ if (retry_alloc) {
++ i915_gem_object_set_page_gfp_mask (obj,
++ i915_gem_object_get_page_gfp_mask (obj) & ~__GFP_NORETRY);
++ }
++ ret = i915_gem_object_get_pages(obj);
++ if (retry_alloc) {
++ i915_gem_object_set_page_gfp_mask (obj,
++ i915_gem_object_get_page_gfp_mask (obj) | __GFP_NORETRY);
++ }
+ if (ret) {
+ drm_mm_put_block(obj_priv->gtt_space);
+ obj_priv->gtt_space = NULL;
+@@ -2645,9 +2631,9 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
+ ret = i915_gem_evict_something(dev, obj->size);
+ if (ret) {
+ /* now try to shrink everyone else */
+- if (gfpmask) {
+- gfpmask = 0;
+- goto search_free;
++ if (! retry_alloc) {
++ retry_alloc = true;
++ goto search_free;
+ }
+
+ return ret;
+@@ -2725,7 +2711,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
+ old_write_domain = obj->write_domain;
+ i915_gem_flush(dev, 0, obj->write_domain);
+ seqno = i915_add_request(dev, NULL, obj->write_domain);
+- BUG_ON(obj->write_domain);
++ obj->write_domain = 0;
+ i915_gem_object_move_to_active(obj, seqno);
+
+ trace_i915_gem_object_change_domain(obj,
+@@ -2825,57 +2811,6 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
+ return 0;
+ }
+
+-/*
+- * Prepare buffer for display plane. Use uninterruptible for possible flush
+- * wait, as in modesetting process we're not supposed to be interrupted.
+- */
+-int
+-i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
+-{
+- struct drm_device *dev = obj->dev;
+- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+- uint32_t old_write_domain, old_read_domains;
+- int ret;
+-
+- /* Not valid to be called on unbound objects. */
+- if (obj_priv->gtt_space == NULL)
+- return -EINVAL;
+-
+- i915_gem_object_flush_gpu_write_domain(obj);
+-
+- /* Wait on any GPU rendering and flushing to occur. */
+- if (obj_priv->active) {
+-#if WATCH_BUF
+- DRM_INFO("%s: object %p wait for seqno %08x\n",
+- __func__, obj, obj_priv->last_rendering_seqno);
+-#endif
+- ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0);
+- if (ret != 0)
+- return ret;
+- }
+-
+- old_write_domain = obj->write_domain;
+- old_read_domains = obj->read_domains;
+-
+- obj->read_domains &= I915_GEM_DOMAIN_GTT;
+-
+- i915_gem_object_flush_cpu_write_domain(obj);
+-
+- /* It should now be out of any other write domains, and we can update
+- * the domain values for our changes.
+- */
+- BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
+- obj->read_domains |= I915_GEM_DOMAIN_GTT;
+- obj->write_domain = I915_GEM_DOMAIN_GTT;
+- obj_priv->dirty = 1;
+-
+- trace_i915_gem_object_change_domain(obj,
+- old_read_domains,
+- old_write_domain);
+-
+- return 0;
+-}
+-
+ /**
+ * Moves a single object to the CPU read, and possibly write domain.
+ *
+@@ -3796,23 +3731,16 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
+ i915_gem_flush(dev,
+ dev->invalidate_domains,
+ dev->flush_domains);
+- if (dev->flush_domains & I915_GEM_GPU_DOMAINS)
++ if (dev->flush_domains)
+ (void)i915_add_request(dev, file_priv,
+ dev->flush_domains);
+ }
+
+ for (i = 0; i < args->buffer_count; i++) {
+ struct drm_gem_object *obj = object_list[i];
+- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ uint32_t old_write_domain = obj->write_domain;
+
+ obj->write_domain = obj->pending_write_domain;
+- if (obj->write_domain)
+- list_move_tail(&obj_priv->gpu_write_list,
+- &dev_priv->mm.gpu_write_list);
+- else
+- list_del_init(&obj_priv->gpu_write_list);
+-
+ trace_i915_gem_object_change_domain(obj,
+ obj->read_domains,
+ old_write_domain);
+@@ -4205,7 +4133,6 @@ int i915_gem_init_object(struct drm_gem_object *obj)
+ obj_priv->obj = obj;
+ obj_priv->fence_reg = I915_FENCE_REG_NONE;
+ INIT_LIST_HEAD(&obj_priv->list);
+- INIT_LIST_HEAD(&obj_priv->gpu_write_list);
+ INIT_LIST_HEAD(&obj_priv->fence_list);
+ obj_priv->madv = I915_MADV_WILLNEED;
+
+@@ -4657,7 +4584,6 @@ i915_gem_load(struct drm_device *dev)
+ spin_lock_init(&dev_priv->mm.active_list_lock);
+ INIT_LIST_HEAD(&dev_priv->mm.active_list);
+ INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
+- INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list);
+ INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
+ INIT_LIST_HEAD(&dev_priv->mm.request_list);
+ INIT_LIST_HEAD(&dev_priv->mm.fence_list);
+@@ -4712,7 +4638,7 @@ int i915_gem_init_phys_object(struct drm_device *dev,
+
+ phys_obj->id = id;
+
+- phys_obj->handle = drm_pci_alloc(dev, size, 0);
++ phys_obj->handle = drm_pci_alloc(dev, size, 0, 0xffffffff);
+ if (!phys_obj->handle) {
+ ret = -ENOMEM;
+ goto kfree_obj;
+@@ -4770,7 +4696,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
+ if (!obj_priv->phys_obj)
+ return;
+
+- ret = i915_gem_object_get_pages(obj, 0);
++ ret = i915_gem_object_get_pages(obj);
+ if (ret)
+ goto out;
+
+@@ -4828,7 +4754,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
+ obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1];
+ obj_priv->phys_obj->cur_obj = obj;
+
+- ret = i915_gem_object_get_pages(obj, 0);
++ ret = i915_gem_object_get_pages(obj);
+ if (ret) {
+ DRM_ERROR("failed to get page list\n");
+ goto out;
+diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
+index 63f28ad..aa7fd82 100644
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -255,6 +255,7 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ int ret = IRQ_NONE;
+ u32 de_iir, gt_iir, de_ier;
++ u32 new_de_iir, new_gt_iir;
+ struct drm_i915_master_private *master_priv;
+
+ /* disable master interrupt before clearing iir */
+@@ -265,31 +266,35 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
+ de_iir = I915_READ(DEIIR);
+ gt_iir = I915_READ(GTIIR);
+
+- if (de_iir == 0 && gt_iir == 0)
+- goto done;
++ for (;;) {
++ if (de_iir == 0 && gt_iir == 0)
++ break;
+
+- ret = IRQ_HANDLED;
++ ret = IRQ_HANDLED;
+
+- if (dev->primary->master) {
+- master_priv = dev->primary->master->driver_priv;
+- if (master_priv->sarea_priv)
+- master_priv->sarea_priv->last_dispatch =
+- READ_BREADCRUMB(dev_priv);
+- }
++ I915_WRITE(DEIIR, de_iir);
++ new_de_iir = I915_READ(DEIIR);
++ I915_WRITE(GTIIR, gt_iir);
++ new_gt_iir = I915_READ(GTIIR);
+
+- if (gt_iir & GT_USER_INTERRUPT) {
+- u32 seqno = i915_get_gem_seqno(dev);
+- dev_priv->mm.irq_gem_seqno = seqno;
+- trace_i915_gem_request_complete(dev, seqno);
+- DRM_WAKEUP(&dev_priv->irq_queue);
+- dev_priv->hangcheck_count = 0;
+- mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
+- }
++ if (dev->primary->master) {
++ master_priv = dev->primary->master->driver_priv;
++ if (master_priv->sarea_priv)
++ master_priv->sarea_priv->last_dispatch =
++ READ_BREADCRUMB(dev_priv);
++ }
++
++ if (gt_iir & GT_USER_INTERRUPT) {
++ u32 seqno = i915_get_gem_seqno(dev);
++ dev_priv->mm.irq_gem_seqno = seqno;
++ trace_i915_gem_request_complete(dev, seqno);
++ DRM_WAKEUP(&dev_priv->irq_queue);
++ }
+
+- I915_WRITE(GTIIR, gt_iir);
+- I915_WRITE(DEIIR, de_iir);
++ de_iir = new_de_iir;
++ gt_iir = new_gt_iir;
++ }
+
+-done:
+ I915_WRITE(DEIER, de_ier);
+ (void)I915_READ(DEIER);
+
+@@ -1044,10 +1049,6 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
+ (void) I915_READ(IER);
+ }
+
+-/*
+- * Must be called after intel_modeset_init or hotplug interrupts won't be
+- * enabled correctly.
+- */
+ int i915_driver_irq_postinstall(struct drm_device *dev)
+ {
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+@@ -1070,23 +1071,19 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
+ if (I915_HAS_HOTPLUG(dev)) {
+ u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
+
+- /* Note HDMI and DP share bits */
+- if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS)
+- hotplug_en |= HDMIB_HOTPLUG_INT_EN;
+- if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS)
+- hotplug_en |= HDMIC_HOTPLUG_INT_EN;
+- if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS)
+- hotplug_en |= HDMID_HOTPLUG_INT_EN;
+- if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS)
+- hotplug_en |= SDVOC_HOTPLUG_INT_EN;
+- if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS)
+- hotplug_en |= SDVOB_HOTPLUG_INT_EN;
+- if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS)
+- hotplug_en |= CRT_HOTPLUG_INT_EN;
+- /* Ignore TV since it's buggy */
+-
++ /* Leave other bits alone */
++ hotplug_en |= HOTPLUG_EN_MASK;
+ I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
+
++ dev_priv->hotplug_supported_mask = CRT_HOTPLUG_INT_STATUS |
++ TV_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS |
++ SDVOB_HOTPLUG_INT_STATUS;
++ if (IS_G4X(dev)) {
++ dev_priv->hotplug_supported_mask |=
++ HDMIB_HOTPLUG_INT_STATUS |
++ HDMIC_HOTPLUG_INT_STATUS |
++ HDMID_HOTPLUG_INT_STATUS;
++ }
+ /* Enable in IER... */
+ enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
+ /* and unmask in IMR */
+diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
+index cc9b49a..1687edf 100644
+--- a/drivers/gpu/drm/i915/i915_reg.h
++++ b/drivers/gpu/drm/i915/i915_reg.h
+@@ -329,7 +329,6 @@
+ #define FBC_CTL_PERIODIC (1<<30)
+ #define FBC_CTL_INTERVAL_SHIFT (16)
+ #define FBC_CTL_UNCOMPRESSIBLE (1<<14)
+-#define FBC_C3_IDLE (1<<13)
+ #define FBC_CTL_STRIDE_SHIFT (5)
+ #define FBC_CTL_FENCENO (1<<0)
+ #define FBC_COMMAND 0x0320c
+@@ -406,13 +405,6 @@
+ # define GPIO_DATA_VAL_IN (1 << 12)
+ # define GPIO_DATA_PULLUP_DISABLE (1 << 13)
+
+-#define GMBUS0 0x5100
+-#define GMBUS1 0x5104
+-#define GMBUS2 0x5108
+-#define GMBUS3 0x510c
+-#define GMBUS4 0x5110
+-#define GMBUS5 0x5120
+-
+ /*
+ * Clock control & power management
+ */
+@@ -871,6 +863,14 @@
+ #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
+ #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */
+ #define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f
++#define HOTPLUG_EN_MASK (HDMIB_HOTPLUG_INT_EN | \
++ HDMIC_HOTPLUG_INT_EN | \
++ HDMID_HOTPLUG_INT_EN | \
++ SDVOB_HOTPLUG_INT_EN | \
++ SDVOC_HOTPLUG_INT_EN | \
++ TV_HOTPLUG_INT_EN | \
++ CRT_HOTPLUG_INT_EN)
++
+
+ #define PORT_HOTPLUG_STAT 0x61114
+ #define HDMIB_HOTPLUG_INT_STATUS (1 << 29)
+@@ -968,8 +968,6 @@
+ #define LVDS_PORT_EN (1 << 31)
+ /* Selects pipe B for LVDS data. Must be set on pre-965. */
+ #define LVDS_PIPEB_SELECT (1 << 30)
+-/* LVDS dithering flag on 965/g4x platform */
+-#define LVDS_ENABLE_DITHER (1 << 25)
+ /* Enable border for unscaled (or aspect-scaled) display */
+ #define LVDS_BORDER_ENABLE (1 << 15)
+ /*
+@@ -1739,8 +1737,6 @@
+
+ /* Display & cursor control */
+
+-/* dithering flag on Ironlake */
+-#define PIPE_ENABLE_DITHER (1 << 4)
+ /* Pipe A */
+ #define PIPEADSL 0x70000
+ #define PIPEACONF 0x70008
+@@ -2161,13 +2157,6 @@
+ #define PCH_GPIOE 0xc5020
+ #define PCH_GPIOF 0xc5024
+
+-#define PCH_GMBUS0 0xc5100
+-#define PCH_GMBUS1 0xc5104
+-#define PCH_GMBUS2 0xc5108
+-#define PCH_GMBUS3 0xc510c
+-#define PCH_GMBUS4 0xc5110
+-#define PCH_GMBUS5 0xc5120
+-
+ #define PCH_DPLL_A 0xc6014
+ #define PCH_DPLL_B 0xc6018
+
+diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
+index 7ad742f..6eec817 100644
+--- a/drivers/gpu/drm/i915/i915_suspend.c
++++ b/drivers/gpu/drm/i915/i915_suspend.c
+@@ -27,7 +27,7 @@
+ #include "drmP.h"
+ #include "drm.h"
+ #include "i915_drm.h"
+-#include "intel_drv.h"
++#include "i915_drv.h"
+
+ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
+ {
+@@ -846,9 +846,6 @@ int i915_restore_state(struct drm_device *dev)
+ for (i = 0; i < 3; i++)
+ I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
+
+- /* I2C state */
+- intel_i2c_reset_gmbus(dev);
+-
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
+index 5e730e6..e505144 100644
+--- a/drivers/gpu/drm/i915/intel_crt.c
++++ b/drivers/gpu/drm/i915/intel_crt.c
+@@ -185,9 +185,6 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
+ adpa = I915_READ(PCH_ADPA);
+
+ adpa &= ~ADPA_CRT_HOTPLUG_MASK;
+- /* disable HPD first */
+- I915_WRITE(PCH_ADPA, adpa);
+- (void)I915_READ(PCH_ADPA);
+
+ adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
+ ADPA_CRT_HOTPLUG_WARMUP_10MS |
+@@ -579,6 +576,4 @@ void intel_crt_init(struct drm_device *dev)
+ drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
+
+ drm_sysfs_connector_add(connector);
+-
+- dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
+ }
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index b00a1aa..099f420 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -988,8 +988,6 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
+
+ /* enable it... */
+ fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC;
+- if (IS_I945GM(dev))
+- fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */
+ fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
+ fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
+ if (obj_priv->tiling_mode != I915_TILING_NONE)
+@@ -1253,7 +1251,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
+ return ret;
+ }
+
+- ret = i915_gem_object_set_to_display_plane(obj);
++ ret = i915_gem_object_set_to_gtt_domain(obj, 1);
+ if (ret != 0) {
+ i915_gem_object_unpin(obj);
+ mutex_unlock(&dev->struct_mutex);
+@@ -1475,10 +1473,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B;
+ u32 temp;
+ int tries = 5, j, n;
+- u32 pipe_bpc;
+-
+- temp = I915_READ(pipeconf_reg);
+- pipe_bpc = temp & PIPE_BPC_MASK;
+
+ /* XXX: When our outputs are all unaware of DPMS modes other than off
+ * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
+@@ -1488,15 +1482,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ DRM_DEBUG("crtc %d dpms on\n", pipe);
+-
+- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+- temp = I915_READ(PCH_LVDS);
+- if ((temp & LVDS_PORT_EN) == 0) {
+- I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
+- POSTING_READ(PCH_LVDS);
+- }
+- }
+-
+ if (HAS_eDP) {
+ /* enable eDP PLL */
+ igdng_enable_pll_edp(crtc);
+@@ -1510,12 +1495,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+
+ /* enable PCH FDI RX PLL, wait warmup plus DMI latency */
+ temp = I915_READ(fdi_rx_reg);
+- /*
+- * make the BPC in FDI Rx be consistent with that in
+- * pipeconf reg.
+- */
+- temp &= ~(0x7 << 16);
+- temp |= (pipe_bpc << 11);
+ I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE |
+ FDI_SEL_PCDCLK |
+ FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */
+@@ -1656,12 +1635,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+
+ /* enable PCH transcoder */
+ temp = I915_READ(transconf_reg);
+- /*
+- * make the BPC in transcoder be consistent with
+- * that in pipeconf reg.
+- */
+- temp &= ~PIPE_BPC_MASK;
+- temp |= pipe_bpc;
+ I915_WRITE(transconf_reg, temp | TRANS_ENABLE);
+ I915_READ(transconf_reg);
+
+@@ -1693,6 +1666,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ case DRM_MODE_DPMS_OFF:
+ DRM_DEBUG("crtc %d dpms off\n", pipe);
+
++ i915_disable_vga(dev);
++
+ /* Disable display plane */
+ temp = I915_READ(dspcntr_reg);
+ if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
+@@ -1702,8 +1677,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ I915_READ(dspbase_reg);
+ }
+
+- i915_disable_vga(dev);
+-
+ /* disable cpu pipe, disable after all planes disabled */
+ temp = I915_READ(pipeconf_reg);
+ if ((temp & PIPEACONF_ENABLE) != 0) {
+@@ -1724,15 +1697,9 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ } else
+ DRM_DEBUG("crtc %d is disabled\n", pipe);
+
+- udelay(100);
+-
+- /* Disable PF */
+- temp = I915_READ(pf_ctl_reg);
+- if ((temp & PF_ENABLE) != 0) {
+- I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
+- I915_READ(pf_ctl_reg);
++ if (HAS_eDP) {
++ igdng_disable_pll_edp(crtc);
+ }
+- I915_WRITE(pf_win_size, 0);
+
+ /* disable CPU FDI tx and PCH FDI rx */
+ temp = I915_READ(fdi_tx_reg);
+@@ -1740,9 +1707,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ I915_READ(fdi_tx_reg);
+
+ temp = I915_READ(fdi_rx_reg);
+- /* BPC in FDI rx is consistent with that in pipeconf */
+- temp &= ~(0x07 << 16);
+- temp |= (pipe_bpc << 11);
+ I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE);
+ I915_READ(fdi_rx_reg);
+
+@@ -1761,13 +1725,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+
+ udelay(100);
+
+- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+- temp = I915_READ(PCH_LVDS);
+- I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN);
+- I915_READ(PCH_LVDS);
+- udelay(100);
+- }
+-
+ /* disable PCH transcoder */
+ temp = I915_READ(transconf_reg);
+ if ((temp & TRANS_ENABLE) != 0) {
+@@ -1786,13 +1743,6 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ }
+ }
+ }
+- temp = I915_READ(transconf_reg);
+- /* BPC in transcoder is consistent with that in pipeconf */
+- temp &= ~PIPE_BPC_MASK;
+- temp |= pipe_bpc;
+- I915_WRITE(transconf_reg, temp);
+- I915_READ(transconf_reg);
+- udelay(100);
+
+ /* disable PCH DPLL */
+ temp = I915_READ(pch_dpll_reg);
+@@ -1801,19 +1751,13 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ I915_READ(pch_dpll_reg);
+ }
+
+- if (HAS_eDP) {
+- igdng_disable_pll_edp(crtc);
+- }
+-
+ temp = I915_READ(fdi_rx_reg);
+- temp &= ~FDI_SEL_PCDCLK;
+- I915_WRITE(fdi_rx_reg, temp);
+- I915_READ(fdi_rx_reg);
+-
+- temp = I915_READ(fdi_rx_reg);
+- temp &= ~FDI_RX_PLL_ENABLE;
+- I915_WRITE(fdi_rx_reg, temp);
+- I915_READ(fdi_rx_reg);
++ if ((temp & FDI_RX_PLL_ENABLE) != 0) {
++ temp &= ~FDI_SEL_PCDCLK;
++ temp &= ~FDI_RX_PLL_ENABLE;
++ I915_WRITE(fdi_rx_reg, temp);
++ I915_READ(fdi_rx_reg);
++ }
+
+ /* Disable CPU FDI TX PLL */
+ temp = I915_READ(fdi_tx_reg);
+@@ -1823,8 +1767,16 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ udelay(100);
+ }
+
++ /* Disable PF */
++ temp = I915_READ(pf_ctl_reg);
++ if ((temp & PF_ENABLE) != 0) {
++ I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
++ I915_READ(pf_ctl_reg);
++ }
++ I915_WRITE(pf_win_size, 0);
++
+ /* Wait for the clocks to turn off. */
+- udelay(100);
++ udelay(150);
+ break;
+ }
+ }
+@@ -1893,7 +1845,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
+ intel_update_watermarks(dev);
+ /* Give the overlay scaler a chance to disable if it's on this pipe */
+ //intel_crtc_dpms_video(crtc, FALSE); TODO
+- drm_vblank_off(dev, pipe);
+
+ if (dev_priv->cfb_plane == plane &&
+ dev_priv->display.disable_fbc)
+@@ -2540,10 +2491,6 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock,
+ sr_entries = roundup(sr_entries / cacheline_size, 1);
+ DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+ I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+- } else {
+- /* Turn off self refresh if both pipes are enabled */
+- I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
+- & ~FW_BLC_SELF_EN);
+ }
+
+ DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n",
+@@ -2562,43 +2509,15 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock,
+ (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
+ }
+
+-static void i965_update_wm(struct drm_device *dev, int planea_clock,
+- int planeb_clock, int sr_hdisplay, int pixel_size)
++static void i965_update_wm(struct drm_device *dev, int unused, int unused2,
++ int unused3, int unused4)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+- unsigned long line_time_us;
+- int sr_clock, sr_entries, srwm = 1;
+-
+- /* Calc sr entries for one plane configs */
+- if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+- /* self-refresh has much higher latency */
+- const static int sr_latency_ns = 12000;
+-
+- sr_clock = planea_clock ? planea_clock : planeb_clock;
+- line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+-
+- /* Use ns/us then divide to preserve precision */
+- sr_entries = (((sr_latency_ns / line_time_us) + 1) *
+- pixel_size * sr_hdisplay) / 1000;
+- sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1);
+- DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+- srwm = I945_FIFO_SIZE - sr_entries;
+- if (srwm < 0)
+- srwm = 1;
+- srwm &= 0x3f;
+- I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+- } else {
+- /* Turn off self refresh if both pipes are enabled */
+- I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
+- & ~FW_BLC_SELF_EN);
+- }
+
+- DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n",
+- srwm);
++ DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n");
+
+ /* 965 has limitations... */
+- I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) |
+- (8 << 0));
++ I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0));
+ I915_WRITE(DSPFW2, (8 << 8) | (8 << 0));
+ }
+
+@@ -2659,10 +2578,6 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
+ if (srwm < 0)
+ srwm = 1;
+ I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
+- } else {
+- /* Turn off self refresh if both pipes are enabled */
+- I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
+- & ~FW_BLC_SELF_EN);
+ }
+
+ DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
+@@ -2939,18 +2854,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
+
+ /* determine panel color depth */
+ temp = I915_READ(pipeconf_reg);
+- temp &= ~PIPE_BPC_MASK;
+- if (is_lvds) {
+- int lvds_reg = I915_READ(PCH_LVDS);
+- /* the BPC will be 6 if it is 18-bit LVDS panel */
+- if ((lvds_reg & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
+- temp |= PIPE_8BPC;
+- else
+- temp |= PIPE_6BPC;
+- } else
+- temp |= PIPE_8BPC;
+- I915_WRITE(pipeconf_reg, temp);
+- I915_READ(pipeconf_reg);
+
+ switch (temp & PIPE_BPC_MASK) {
+ case PIPE_8BPC:
+@@ -3178,20 +3081,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
+ * appropriately here, but we need to look more thoroughly into how
+ * panels behave in the two modes.
+ */
+- /* set the dithering flag */
+- if (IS_I965G(dev)) {
+- if (dev_priv->lvds_dither) {
+- if (IS_IGDNG(dev))
+- pipeconf |= PIPE_ENABLE_DITHER;
+- else
+- lvds |= LVDS_ENABLE_DITHER;
+- } else {
+- if (IS_IGDNG(dev))
+- pipeconf &= ~PIPE_ENABLE_DITHER;
+- else
+- lvds &= ~LVDS_ENABLE_DITHER;
+- }
+- }
++
+ I915_WRITE(lvds_reg, lvds);
+ I915_READ(lvds_reg);
+ }
+@@ -3775,6 +3665,125 @@ static void intel_gpu_idle_timer(unsigned long arg)
+ queue_work(dev_priv->wq, &dev_priv->idle_work);
+ }
+
++void intel_increase_renderclock(struct drm_device *dev, bool schedule)
++{
++ drm_i915_private_t *dev_priv = dev->dev_private;
++
++ if (IS_IGDNG(dev))
++ return;
++
++ if (!dev_priv->render_reclock_avail) {
++ DRM_DEBUG("not reclocking render clock\n");
++ return;
++ }
++
++ /* Restore render clock frequency to original value */
++ if (IS_G4X(dev) || IS_I9XX(dev))
++ pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock);
++ else if (IS_I85X(dev))
++ pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock);
++ DRM_DEBUG("increasing render clock frequency\n");
++
++ /* Schedule downclock */
++ if (schedule)
++ mod_timer(&dev_priv->idle_timer, jiffies +
++ msecs_to_jiffies(GPU_IDLE_TIMEOUT));
++}
++
++void intel_decrease_renderclock(struct drm_device *dev)
++{
++ drm_i915_private_t *dev_priv = dev->dev_private;
++
++ if (IS_IGDNG(dev))
++ return;
++
++ if (!dev_priv->render_reclock_avail) {
++ DRM_DEBUG("not reclocking render clock\n");
++ return;
++ }
++
++ if (IS_G4X(dev)) {
++ u16 gcfgc;
++
++ /* Adjust render clock... */
++ pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
++
++ /* Down to minimum... */
++ gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK;
++ gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ;
++
++ pci_write_config_word(dev->pdev, GCFGC, gcfgc);
++ } else if (IS_I965G(dev)) {
++ u16 gcfgc;
++
++ /* Adjust render clock... */
++ pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
++
++ /* Down to minimum... */
++ gcfgc &= ~I965_GC_RENDER_CLOCK_MASK;
++ gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ;
++
++ pci_write_config_word(dev->pdev, GCFGC, gcfgc);
++ } else if (IS_I945G(dev) || IS_I945GM(dev)) {
++ u16 gcfgc;
++
++ /* Adjust render clock... */
++ pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
++
++ /* Down to minimum... */
++ gcfgc &= ~I945_GC_RENDER_CLOCK_MASK;
++ gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ;
++
++ pci_write_config_word(dev->pdev, GCFGC, gcfgc);
++ } else if (IS_I915G(dev)) {
++ u16 gcfgc;
++
++ /* Adjust render clock... */
++ pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
++
++ /* Down to minimum... */
++ gcfgc &= ~I915_GC_RENDER_CLOCK_MASK;
++ gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ;
++
++ pci_write_config_word(dev->pdev, GCFGC, gcfgc);
++ } else if (IS_I85X(dev)) {
++ u16 hpllcc;
++
++ /* Adjust render clock... */
++ pci_read_config_word(dev->pdev, HPLLCC, &hpllcc);
++
++ /* Up to maximum... */
++ hpllcc &= ~GC_CLOCK_CONTROL_MASK;
++ hpllcc |= GC_CLOCK_133_200;
++
++ pci_write_config_word(dev->pdev, HPLLCC, hpllcc);
++ }
++ DRM_DEBUG("decreasing render clock frequency\n");
++}
++
++/* Note that no increase function is needed for this - increase_renderclock()
++ * will also rewrite these bits
++ */
++void intel_decrease_displayclock(struct drm_device *dev)
++{
++ if (IS_IGDNG(dev))
++ return;
++
++ if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) ||
++ IS_I915GM(dev)) {
++ u16 gcfgc;
++
++ /* Adjust render clock... */
++ pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
++
++ /* Down to minimum... */
++ gcfgc &= ~0xf0;
++ gcfgc |= 0x80;
++
++ pci_write_config_word(dev->pdev, GCFGC, gcfgc);
++ }
++}
++
+ #define CRTC_IDLE_TIMEOUT 1000 /* ms */
+
+ static void intel_crtc_idle_timer(unsigned long arg)
+@@ -3888,6 +3897,12 @@ static void intel_idle_update(struct work_struct *work)
+
+ mutex_lock(&dev->struct_mutex);
+
++ /* GPU isn't processing, downclock it. */
++ if (!dev_priv->busy) {
++ intel_decrease_renderclock(dev);
++ intel_decrease_displayclock(dev);
++ }
++
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ /* Skip inactive CRTCs */
+ if (!crtc->fb)
+@@ -3922,6 +3937,7 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj)
+ return;
+
+ dev_priv->busy = true;
++ intel_increase_renderclock(dev, true);
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ if (!crtc->fb)
+@@ -4102,51 +4118,37 @@ static void intel_setup_outputs(struct drm_device *dev)
+ if (I915_READ(PCH_DP_D) & DP_DETECTED)
+ intel_dp_init(dev, PCH_DP_D);
+
+- } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
++ } else if (IS_I9XX(dev)) {
+ bool found = false;
+
+ if (I915_READ(SDVOB) & SDVO_DETECTED) {
+- DRM_DEBUG_KMS("probing SDVOB\n");
+ found = intel_sdvo_init(dev, SDVOB);
+- if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) {
+- DRM_DEBUG_KMS("probing HDMI on SDVOB\n");
++ if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+ intel_hdmi_init(dev, SDVOB);
+- }
+
+- if (!found && SUPPORTS_INTEGRATED_DP(dev)) {
+- DRM_DEBUG_KMS("probing DP_B\n");
++ if (!found && SUPPORTS_INTEGRATED_DP(dev))
+ intel_dp_init(dev, DP_B);
+- }
+ }
+
+ /* Before G4X SDVOC doesn't have its own detect register */
+
+- if (I915_READ(SDVOB) & SDVO_DETECTED) {
+- DRM_DEBUG_KMS("probing SDVOC\n");
++ if (I915_READ(SDVOB) & SDVO_DETECTED)
+ found = intel_sdvo_init(dev, SDVOC);
+- }
+
+ if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) {
+
+- if (SUPPORTS_INTEGRATED_HDMI(dev)) {
+- DRM_DEBUG_KMS("probing HDMI on SDVOC\n");
++ if (SUPPORTS_INTEGRATED_HDMI(dev))
+ intel_hdmi_init(dev, SDVOC);
+- }
+- if (SUPPORTS_INTEGRATED_DP(dev)) {
+- DRM_DEBUG_KMS("probing DP_C\n");
++ if (SUPPORTS_INTEGRATED_DP(dev))
+ intel_dp_init(dev, DP_C);
+- }
+ }
+
+- if (SUPPORTS_INTEGRATED_DP(dev) &&
+- (I915_READ(DP_D) & DP_DETECTED)) {
+- DRM_DEBUG_KMS("probing DP_D\n");
++ if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED))
+ intel_dp_init(dev, DP_D);
+- }
+- } else if (IS_I8XX(dev))
++ } else
+ intel_dvo_init(dev);
+
+- if (SUPPORTS_TV(dev))
++ if (IS_I9XX(dev) && IS_MOBILE(dev) && !IS_IGDNG(dev))
+ intel_tv_init(dev);
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+@@ -4440,6 +4442,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
+ del_timer_sync(&intel_crtc->idle_timer);
+ }
+
++ intel_increase_renderclock(dev, false);
+ del_timer_sync(&dev_priv->idle_timer);
+
+ mutex_unlock(&dev->struct_mutex);
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index d487771..d834475 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -1254,11 +1254,11 @@ intel_dp_init(struct drm_device *dev, int output_reg)
+ else
+ intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
+
+- if (output_reg == DP_B || output_reg == PCH_DP_B)
++ if (output_reg == DP_B)
+ intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
+- else if (output_reg == DP_C || output_reg == PCH_DP_C)
++ else if (output_reg == DP_C)
+ intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
+- else if (output_reg == DP_D || output_reg == PCH_DP_D)
++ else if (output_reg == DP_D)
+ intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
+
+ if (IS_eDP(intel_output)) {
+@@ -1290,20 +1290,14 @@ intel_dp_init(struct drm_device *dev, int output_reg)
+ break;
+ case DP_B:
+ case PCH_DP_B:
+- dev_priv->hotplug_supported_mask |=
+- HDMIB_HOTPLUG_INT_STATUS;
+ name = "DPDDC-B";
+ break;
+ case DP_C:
+ case PCH_DP_C:
+- dev_priv->hotplug_supported_mask |=
+- HDMIC_HOTPLUG_INT_STATUS;
+ name = "DPDDC-C";
+ break;
+ case DP_D:
+ case PCH_DP_D:
+- dev_priv->hotplug_supported_mask |=
+- HDMID_HOTPLUG_INT_STATUS;
+ name = "DPDDC-D";
+ break;
+ }
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index 6c7c19f..ef61fe9 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -134,8 +134,6 @@ void intel_i2c_destroy(struct i2c_adapter *adapter);
+ int intel_ddc_get_modes(struct intel_output *intel_output);
+ extern bool intel_ddc_probe(struct intel_output *intel_output);
+ void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
+-void intel_i2c_reset_gmbus(struct drm_device *dev);
+-
+ extern void intel_crt_init(struct drm_device *dev);
+ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
+ extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
+diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
+index 1318ac2..2b0fe54 100644
+--- a/drivers/gpu/drm/i915/intel_fb.c
++++ b/drivers/gpu/drm/i915/intel_fb.c
+@@ -148,7 +148,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
+
+ mutex_lock(&dev->struct_mutex);
+
+- ret = i915_gem_object_pin(fbo, 64*1024);
++ ret = i915_gem_object_pin(fbo, PAGE_SIZE);
+ if (ret) {
+ DRM_ERROR("failed to pin fb: %d\n", ret);
+ goto out_unref;
+diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
+index 85760bf..c33451a 100644
+--- a/drivers/gpu/drm/i915/intel_hdmi.c
++++ b/drivers/gpu/drm/i915/intel_hdmi.c
+@@ -254,26 +254,21 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
+ if (sdvox_reg == SDVOB) {
+ intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
+ intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
+- dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
+ } else if (sdvox_reg == SDVOC) {
+ intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
+ intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
+- dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
+ } else if (sdvox_reg == HDMIB) {
+ intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
+ intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
+ "HDMIB");
+- dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
+ } else if (sdvox_reg == HDMIC) {
+ intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
+ intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
+ "HDMIC");
+- dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
+ } else if (sdvox_reg == HDMID) {
+ intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
+ intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
+ "HDMID");
+- dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
+ }
+ if (!intel_output->ddc_bus)
+ goto err_connector;
+diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
+index b94acc4..c7eab72 100644
+--- a/drivers/gpu/drm/i915/intel_i2c.c
++++ b/drivers/gpu/drm/i915/intel_i2c.c
+@@ -118,23 +118,6 @@ static void set_data(void *data, int state_high)
+ udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
+ }
+
+-/* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C
+- * engine, but if the BIOS leaves it enabled, then that can break our use
+- * of the bit-banging I2C interfaces. This is notably the case with the
+- * Mac Mini in EFI mode.
+- */
+-void
+-intel_i2c_reset_gmbus(struct drm_device *dev)
+-{
+- struct drm_i915_private *dev_priv = dev->dev_private;
+-
+- if (IS_IGDNG(dev)) {
+- I915_WRITE(PCH_GMBUS0, 0);
+- } else {
+- I915_WRITE(GMBUS0, 0);
+- }
+-}
+-
+ /**
+ * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
+ * @dev: DRM device
+@@ -185,8 +168,6 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
+ if(i2c_bit_add_bus(&chan->adapter))
+ goto out_free;
+
+- intel_i2c_reset_gmbus(dev);
+-
+ /* JJJ: raise SCL and SDA? */
+ intel_i2c_quirk_set(dev, true);
+ set_data(chan, 1);
+diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
+index 952bb4e..05598ae 100644
+--- a/drivers/gpu/drm/i915/intel_lvds.c
++++ b/drivers/gpu/drm/i915/intel_lvds.c
+@@ -602,33 +602,12 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
+ /* Some lid devices report incorrect lid status, assume they're connected */
+ static const struct dmi_system_id bad_lid_status[] = {
+ {
+- .ident = "Compaq nx9020",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+- DMI_MATCH(DMI_BOARD_NAME, "3084"),
+- },
+- },
+- {
+- .ident = "Samsung SX20S",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
+- DMI_MATCH(DMI_BOARD_NAME, "SX20S"),
+- },
+- },
+- {
+ .ident = "Aspire One",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"),
+ },
+ },
+- {
+- .ident = "PC-81005",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "MALATA"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"),
+- },
+- },
+ { }
+ };
+
+@@ -700,14 +679,7 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
+ struct drm_i915_private *dev_priv =
+ container_of(nb, struct drm_i915_private, lid_notifier);
+ struct drm_device *dev = dev_priv->dev;
+- struct drm_connector *connector = dev_priv->int_lvds_connector;
+
+- /*
+- * check and update the status of LVDS connector after receiving
+- * the LID nofication event.
+- */
+- if (connector)
+- connector->status = connector->funcs->detect(connector);
+ if (!acpi_lid_open()) {
+ dev_priv->modeset_on_lid = 1;
+ return NOTIFY_OK;
+@@ -1113,8 +1085,6 @@ out:
+ DRM_DEBUG("lid notifier registration failed\n");
+ dev_priv->lid_notifier.notifier_call = NULL;
+ }
+- /* keep the LVDS connector */
+- dev_priv->int_lvds_connector = connector;
+ drm_sysfs_connector_add(connector);
+ return;
+
+diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
+index 3f5aaf1..083bec2 100644
+--- a/drivers/gpu/drm/i915/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/intel_sdvo.c
+@@ -472,63 +472,14 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
+ }
+
+ /**
+- * Try to read the response after issuie the DDC switch command. But it
+- * is noted that we must do the action of reading response and issuing DDC
+- * switch command in one I2C transaction. Otherwise when we try to start
+- * another I2C transaction after issuing the DDC bus switch, it will be
+- * switched to the internal SDVO register.
++ * Don't check status code from this as it switches the bus back to the
++ * SDVO chips which defeats the purpose of doing a bus switch in the first
++ * place.
+ */
+ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
+ u8 target)
+ {
+- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+- u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
+- struct i2c_msg msgs[] = {
+- {
+- .addr = sdvo_priv->slave_addr >> 1,
+- .flags = 0,
+- .len = 2,
+- .buf = out_buf,
+- },
+- /* the following two are to read the response */
+- {
+- .addr = sdvo_priv->slave_addr >> 1,
+- .flags = 0,
+- .len = 1,
+- .buf = cmd_buf,
+- },
+- {
+- .addr = sdvo_priv->slave_addr >> 1,
+- .flags = I2C_M_RD,
+- .len = 1,
+- .buf = ret_value,
+- },
+- };
+-
+- intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+- &target, 1);
+- /* write the DDC switch command argument */
+- intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
+-
+- out_buf[0] = SDVO_I2C_OPCODE;
+- out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
+- cmd_buf[0] = SDVO_I2C_CMD_STATUS;
+- cmd_buf[1] = 0;
+- ret_value[0] = 0;
+- ret_value[1] = 0;
+-
+- ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
+- if (ret != 3) {
+- /* failure in I2C transfer */
+- DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
+- return;
+- }
+- if (ret_value[0] != SDVO_CMD_STATUS_SUCCESS) {
+- DRM_DEBUG_KMS("DDC switch command returns response %d\n",
+- ret_value[0]);
+- return;
+- }
+- return;
++ intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
+ }
+
+ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
+@@ -1638,32 +1589,6 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
+ edid = drm_get_edid(&intel_output->base,
+ intel_output->ddc_bus);
+
+- /* This is only applied to SDVO cards with multiple outputs */
+- if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) {
+- uint8_t saved_ddc, temp_ddc;
+- saved_ddc = sdvo_priv->ddc_bus;
+- temp_ddc = sdvo_priv->ddc_bus >> 1;
+- /*
+- * Don't use the 1 as the argument of DDC bus switch to get
+- * the EDID. It is used for SDVO SPD ROM.
+- */
+- while(temp_ddc > 1) {
+- sdvo_priv->ddc_bus = temp_ddc;
+- edid = drm_get_edid(&intel_output->base,
+- intel_output->ddc_bus);
+- if (edid) {
+- /*
+- * When we can get the EDID, maybe it is the
+- * correct DDC bus. Update it.
+- */
+- sdvo_priv->ddc_bus = temp_ddc;
+- break;
+- }
+- temp_ddc >>= 1;
+- }
+- if (edid == NULL)
+- sdvo_priv->ddc_bus = saved_ddc;
+- }
+ /* when there is no edid and no monitor is connected with VGA
+ * port, try to use the CRT ddc to read the EDID for DVI-connector
+ */
+@@ -2743,7 +2668,6 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
+
+ bool intel_sdvo_init(struct drm_device *dev, int output_device)
+ {
+- struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_connector *connector;
+ struct intel_output *intel_output;
+ struct intel_sdvo_priv *sdvo_priv;
+@@ -2790,12 +2714,10 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
+ intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
+ sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
+ "SDVOB/VGA DDC BUS");
+- dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
+ } else {
+ intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+ sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
+ "SDVOC/VGA DDC BUS");
+- dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
+ }
+
+ if (intel_output->ddc_bus == NULL)
+diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
+index ce026f0..9ca9179 100644
+--- a/drivers/gpu/drm/i915/intel_tv.c
++++ b/drivers/gpu/drm/i915/intel_tv.c
+@@ -1213,17 +1213,20 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
+ tv_ctl |= TV_TRILEVEL_SYNC;
+ if (tv_mode->pal_burst)
+ tv_ctl |= TV_PAL_BURST;
+-
+ scctl1 = 0;
+- if (tv_mode->dda1_inc)
++ /* dda1 implies valid video levels */
++ if (tv_mode->dda1_inc) {
+ scctl1 |= TV_SC_DDA1_EN;
++ }
++
+ if (tv_mode->dda2_inc)
+ scctl1 |= TV_SC_DDA2_EN;
++
+ if (tv_mode->dda3_inc)
+ scctl1 |= TV_SC_DDA3_EN;
++
+ scctl1 |= tv_mode->sc_reset;
+- if (video_levels)
+- scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
++ scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
+ scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
+
+ scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
+@@ -1801,8 +1804,6 @@ intel_tv_init(struct drm_device *dev)
+ drm_connector_attach_property(connector,
+ dev->mode_config.tv_bottom_margin_property,
+ tv_priv->margin[TV_MARGIN_BOTTOM]);
+-
+- dev_priv->hotplug_supported_mask |= TV_HOTPLUG_INT_STATUS;
+ out:
+ drm_sysfs_connector_add(connector);
+ }
+diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
+index fed2291..d67c425 100644
+--- a/drivers/gpu/drm/radeon/atom.c
++++ b/drivers/gpu/drm/radeon/atom.c
+@@ -607,7 +607,7 @@ static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg)
+ uint8_t count = U8((*ptr)++);
+ SDEBUG(" count: %d\n", count);
+ if (arg == ATOM_UNIT_MICROSEC)
+- udelay(count);
++ schedule_timeout_uninterruptible(usecs_to_jiffies(count));
+ else
+ schedule_timeout_uninterruptible(msecs_to_jiffies(count));
+ }
+diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
+index 19f93f2..c15287a 100644
+--- a/drivers/gpu/drm/radeon/atombios_crtc.c
++++ b/drivers/gpu/drm/radeon/atombios_crtc.c
+@@ -241,7 +241,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
+ {
+ struct drm_device *dev = crtc->dev;
+ struct radeon_device *rdev = dev->dev_private;
+- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+@@ -249,21 +248,20 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
+ if (ASIC_IS_DCE3(rdev))
+ atombios_enable_crtc_memreq(crtc, 1);
+ atombios_blank_crtc(crtc, 0);
+- if (rdev->family < CHIP_R600)
+- drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
+- radeon_crtc_load_lut(crtc);
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+- if (rdev->family < CHIP_R600)
+- drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
+ atombios_blank_crtc(crtc, 1);
+ if (ASIC_IS_DCE3(rdev))
+ atombios_enable_crtc_memreq(crtc, 0);
+ atombios_enable_crtc(crtc, 0);
+ break;
+ }
++
++ if (mode != DRM_MODE_DPMS_OFF) {
++ radeon_crtc_load_lut(crtc);
++ }
+ }
+
+ static void
+diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
+index 969502a..2ed88a8 100644
+--- a/drivers/gpu/drm/radeon/radeon_atombios.c
++++ b/drivers/gpu/drm/radeon/radeon_atombios.c
+@@ -135,14 +135,6 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
+ }
+ }
+
+- /* HIS X1300 is DVI+VGA, not DVI+DVI */
+- if ((dev->pdev->device == 0x7146) &&
+- (dev->pdev->subsystem_vendor == 0x17af) &&
+- (dev->pdev->subsystem_device == 0x2058)) {
+- if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
+- return false;
+- }
+-
+ /* Funky macbooks */
+ if ((dev->pdev->device == 0x71C5) &&
+ (dev->pdev->subsystem_vendor == 0x106b) &&
+diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+index 22ce4d6..8d0b7aa 100644
+--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
++++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+@@ -292,7 +292,8 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
+ uint32_t mask;
+
+ if (radeon_crtc->crtc_id)
+- mask = (RADEON_CRTC2_DISP_DIS |
++ mask = (RADEON_CRTC2_EN |
++ RADEON_CRTC2_DISP_DIS |
+ RADEON_CRTC2_VSYNC_DIS |
+ RADEON_CRTC2_HSYNC_DIS |
+ RADEON_CRTC2_DISP_REQ_EN_B);
+@@ -304,7 +305,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+ if (radeon_crtc->crtc_id)
+- WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask));
++ WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask);
+ else {
+ WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
+ RADEON_CRTC_DISP_REQ_EN_B));
+@@ -318,7 +319,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
+ case DRM_MODE_DPMS_OFF:
+ drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
+ if (radeon_crtc->crtc_id)
+- WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
++ WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
+ else {
+ WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
+ RADEON_CRTC_DISP_REQ_EN_B));
+diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
+index c8942ca..f8a465d 100644
+--- a/drivers/gpu/drm/radeon/radeon_test.c
++++ b/drivers/gpu/drm/radeon/radeon_test.c
+@@ -42,8 +42,8 @@ void radeon_test_moves(struct radeon_device *rdev)
+ /* Number of tests =
+ * (Total GTT - IB pool - writeback page - ring buffer) / test size
+ */
+- n = ((u32)(rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE -
+- rdev->cp.ring_size)) / size;
++ n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE -
++ rdev->cp.ring_size) / size;
+
+ gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL);
+ if (!gtt_obj) {
+diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
+index 4444f48..5f117cd 100644
+--- a/drivers/gpu/drm/radeon/rs600.c
++++ b/drivers/gpu/drm/radeon/rs600.c
+@@ -301,7 +301,9 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev)
+
+ void rs600_gpu_init(struct radeon_device *rdev)
+ {
++ /* FIXME: HDP same place on rs600 ? */
+ r100_hdp_reset(rdev);
++ /* FIXME: is this correct ? */
+ r420_pipes_init(rdev);
+ /* Wait for mc idle */
+ if (rs600_mc_wait_for_idle(rdev))
+@@ -310,20 +312,9 @@ void rs600_gpu_init(struct radeon_device *rdev)
+
+ void rs600_vram_info(struct radeon_device *rdev)
+ {
++ /* FIXME: to do or is these values sane ? */
+ rdev->mc.vram_is_ddr = true;
+ rdev->mc.vram_width = 128;
+-
+- rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
+- rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
+-
+- rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+- rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+-
+- if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+- rdev->mc.mc_vram_size = rdev->mc.aper_size;
+-
+- if (rdev->mc.real_vram_size > rdev->mc.aper_size)
+- rdev->mc.real_vram_size = rdev->mc.aper_size;
+ }
+
+ void rs600_bandwidth_update(struct radeon_device *rdev)
+diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
+index b12ff76..2754717 100644
+--- a/drivers/gpu/drm/radeon/rs690.c
++++ b/drivers/gpu/drm/radeon/rs690.c
+@@ -131,25 +131,24 @@ void rs690_pm_info(struct radeon_device *rdev)
+
+ void rs690_vram_info(struct radeon_device *rdev)
+ {
++ uint32_t tmp;
+ fixed20_12 a;
+
+ rs400_gart_adjust_size(rdev);
+-
++ /* DDR for all card after R300 & IGP */
+ rdev->mc.vram_is_ddr = true;
+- rdev->mc.vram_width = 128;
+-
++ /* FIXME: is this correct for RS690/RS740 ? */
++ tmp = RREG32(RADEON_MEM_CNTL);
++ if (tmp & R300_MEM_NUM_CHANNELS_MASK) {
++ rdev->mc.vram_width = 128;
++ } else {
++ rdev->mc.vram_width = 64;
++ }
+ rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
+ rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
+
+ rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+-
+- if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+- rdev->mc.mc_vram_size = rdev->mc.aper_size;
+-
+- if (rdev->mc.real_vram_size > rdev->mc.aper_size)
+- rdev->mc.real_vram_size = rdev->mc.aper_size;
+-
+ rs690_pm_info(rdev);
+ /* FIXME: we should enforce default clock in case GPU is not in
+ * default setup
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
+index 5b4d66d..4b96e7a 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -431,13 +431,6 @@ static const struct hid_device_id apple_devices[] = {
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
+- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
+- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+- APPLE_ISO_KEYBOARD },
+- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS),
+- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 9678354..7d05c4b 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1287,9 +1287,6 @@ static const struct hid_device_id hid_blacklist[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
+- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
+- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
+- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index e380e7b..adbef5d 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -88,9 +88,6 @@
+ #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
+ #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
+ #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
+-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239
+-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
+-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
+ #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
+ #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
+ #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241
+diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
+index 5d901f6..03bd703 100644
+--- a/drivers/hid/usbhid/hid-core.c
++++ b/drivers/hid/usbhid/hid-core.c
+@@ -998,8 +998,7 @@ static int usbhid_start(struct hid_device *hid)
+ usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
+ usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
+
+- if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
+- usbhid_init_reports(hid);
++ usbhid_init_reports(hid);
+
+ set_bit(HID_STARTED, &usbhid->iofl);
+
+diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
+index 5713b93..0d9045a 100644
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -280,7 +280,7 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
+ if (idVendor == USB_VENDOR_ID_NCR &&
+ idProduct >= USB_DEVICE_ID_NCR_FIRST &&
+ idProduct <= USB_DEVICE_ID_NCR_LAST)
+- return HID_QUIRK_NO_INIT_REPORTS;
++ return HID_QUIRK_NOGET;
+
+ down_read(&dquirks_rwsem);
+ bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index c1f7ea0..700e93a 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -374,7 +374,7 @@ config SENSORS_GL520SM
+
+ config SENSORS_CORETEMP
+ tristate "Intel Core/Core2/Atom temperature sensor"
+- depends on X86 && PCI && EXPERIMENTAL
++ depends on X86 && EXPERIMENTAL
+ help
+ If you say yes here you get support for the temperature
+ sensor inside your CPU. Most of the family 6 CPUs
+diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c
+index 14f910d..1852f27 100644
+--- a/drivers/hwmon/adt7462.c
++++ b/drivers/hwmon/adt7462.c
+@@ -97,7 +97,7 @@ I2C_CLIENT_INSMOD_1(adt7462);
+ #define ADT7462_PIN24_SHIFT 6
+ #define ADT7462_PIN26_VOLT_INPUT 0x08
+ #define ADT7462_PIN25_VOLT_INPUT 0x20
+-#define ADT7462_PIN28_SHIFT 4 /* cfg3 */
++#define ADT7462_PIN28_SHIFT 6 /* cfg3 */
+ #define ADT7462_PIN28_VOLT 0x5
+
+ #define ADT7462_REG_ALARM1 0xB8
+@@ -182,7 +182,7 @@ I2C_CLIENT_INSMOD_1(adt7462);
+ *
+ * Some, but not all, of these voltages have low/high limits.
+ */
+-#define ADT7462_VOLT_COUNT 13
++#define ADT7462_VOLT_COUNT 12
+
+ #define ADT7462_VENDOR 0x41
+ #define ADT7462_DEVICE 0x62
+diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
+index 2d7bcee..caef39c 100644
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -33,7 +33,6 @@
+ #include <linux/list.h>
+ #include <linux/platform_device.h>
+ #include <linux/cpu.h>
+-#include <linux/pci.h>
+ #include <asm/msr.h>
+ #include <asm/processor.h>
+
+@@ -162,7 +161,6 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
+ int usemsr_ee = 1;
+ int err;
+ u32 eax, edx;
+- struct pci_dev *host_bridge;
+
+ /* Early chips have no MSR for TjMax */
+
+@@ -170,21 +168,11 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
+ usemsr_ee = 0;
+ }
+
+- /* Atom CPUs */
++ /* Atoms seems to have TjMax at 90C */
+
+ if (c->x86_model == 0x1c) {
+ usemsr_ee = 0;
+-
+- host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+-
+- if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL
+- && (host_bridge->device == 0xa000 /* NM10 based nettop */
+- || host_bridge->device == 0xa010)) /* NM10 based netbook */
+- tjmax = 100000;
+- else
+- tjmax = 90000;
+-
+- pci_dev_put(host_bridge);
++ tjmax = 90000;
+ }
+
+ if ((c->x86_model > 0xe) && (usemsr_ee)) {
+diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
+index f600813..da1b1f9 100644
+--- a/drivers/hwmon/fschmd.c
++++ b/drivers/hwmon/fschmd.c
+@@ -767,7 +767,6 @@ leave:
+ static int watchdog_open(struct inode *inode, struct file *filp)
+ {
+ struct fschmd_data *pos, *data = NULL;
+- int watchdog_is_open;
+
+ /* We get called from drivers/char/misc.c with misc_mtx hold, and we
+ call misc_register() from fschmd_probe() with watchdog_data_mutex
+@@ -782,12 +781,10 @@ static int watchdog_open(struct inode *inode, struct file *filp)
+ }
+ }
+ /* Note we can never not have found data, so we don't check for this */
+- watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open);
+- if (!watchdog_is_open)
+- kref_get(&data->kref);
++ kref_get(&data->kref);
+ mutex_unlock(&watchdog_data_mutex);
+
+- if (watchdog_is_open)
++ if (test_and_set_bit(0, &data->watchdog_is_open))
+ return -EBUSY;
+
+ /* Start the watchdog */
+diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
+index 1508e0a..f7e7016 100644
+--- a/drivers/hwmon/lm78.c
++++ b/drivers/hwmon/lm78.c
+@@ -870,16 +870,17 @@ static struct lm78_data *lm78_update_device(struct device *dev)
+ static int __init lm78_isa_found(unsigned short address)
+ {
+ int val, save, found = 0;
+- int port;
+-
+- /* Some boards declare base+0 to base+7 as a PNP device, some base+4
+- * to base+7 and some base+5 to base+6. So we better request each port
+- * individually for the probing phase. */
+- for (port = address; port < address + LM78_EXTENT; port++) {
+- if (!request_region(port, 1, "lm78")) {
+- pr_debug("lm78: Failed to request port 0x%x\n", port);
+- goto release;
+- }
++
++ /* We have to request the region in two parts because some
++ boards declare base+4 to base+7 as a PNP device */
++ if (!request_region(address, 4, "lm78")) {
++ pr_debug("lm78: Failed to request low part of region\n");
++ return 0;
++ }
++ if (!request_region(address + 4, 4, "lm78")) {
++ pr_debug("lm78: Failed to request high part of region\n");
++ release_region(address, 4);
++ return 0;
+ }
+
+ #define REALLY_SLOW_IO
+@@ -943,8 +944,8 @@ static int __init lm78_isa_found(unsigned short address)
+ val & 0x80 ? "LM79" : "LM78", (int)address);
+
+ release:
+- for (port--; port >= address; port--)
+- release_region(port, 1);
++ release_region(address + 4, 4);
++ release_region(address, 4);
+ return found;
+ }
+
+diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
+index 864a371..ebe38b6 100644
+--- a/drivers/hwmon/sht15.c
++++ b/drivers/hwmon/sht15.c
+@@ -305,7 +305,7 @@ static inline int sht15_calc_temp(struct sht15_data *data)
+ int d1 = 0;
+ int i;
+
+- for (i = 1; i < ARRAY_SIZE(temppoints); i++)
++ for (i = 1; i < ARRAY_SIZE(temppoints) - 1; i++)
+ /* Find pointer to interpolate */
+ if (data->supply_uV > temppoints[i - 1].vdd) {
+ d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
+@@ -332,12 +332,12 @@ static inline int sht15_calc_humid(struct sht15_data *data)
+
+ const int c1 = -4;
+ const int c2 = 40500; /* x 10 ^ -6 */
+- const int c3 = -2800; /* x10 ^ -9 */
++ const int c3 = 2800; /* x10 ^ -9 */
+
+ RHlinear = c1*1000
+ + c2 * data->val_humid/1000
+ + (data->val_humid * data->val_humid * c3)/1000000;
+- return (temp - 25000) * (10000 + 80 * data->val_humid)
++ return (temp - 25000) * (10000 + 800 * data->val_humid)
+ / 1000000 + RHlinear;
+ }
+
+diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
+index f0b6883..d27ed1b 100644
+--- a/drivers/hwmon/w83781d.c
++++ b/drivers/hwmon/w83781d.c
+@@ -1818,17 +1818,17 @@ static int __init
+ w83781d_isa_found(unsigned short address)
+ {
+ int val, save, found = 0;
+- int port;
+-
+- /* Some boards declare base+0 to base+7 as a PNP device, some base+4
+- * to base+7 and some base+5 to base+6. So we better request each port
+- * individually for the probing phase. */
+- for (port = address; port < address + W83781D_EXTENT; port++) {
+- if (!request_region(port, 1, "w83781d")) {
+- pr_debug("w83781d: Failed to request port 0x%x\n",
+- port);
+- goto release;
+- }
++
++ /* We have to request the region in two parts because some
++ boards declare base+4 to base+7 as a PNP device */
++ if (!request_region(address, 4, "w83781d")) {
++ pr_debug("w83781d: Failed to request low part of region\n");
++ return 0;
++ }
++ if (!request_region(address + 4, 4, "w83781d")) {
++ pr_debug("w83781d: Failed to request high part of region\n");
++ release_region(address, 4);
++ return 0;
+ }
+
+ #define REALLY_SLOW_IO
+@@ -1902,8 +1902,8 @@ w83781d_isa_found(unsigned short address)
+ val == 0x30 ? "W83782D" : "W83781D", (int)address);
+
+ release:
+- for (port--; port >= address; port--)
+- release_region(port, 1);
++ release_region(address + 4, 4);
++ release_region(address, 4);
+ return found;
+ }
+
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+index e8fe7f1..e9c7a6d 100644
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -7,6 +7,10 @@ menu "I2C Hardware Bus support"
+ comment "PC SMBus host controller drivers"
+ depends on PCI
+
++config I2C_TMPA910
++ tristate "Toshiba TMPA910"
++ depends on ARCH_TMPA910
++
+ config I2C_ALI1535
+ tristate "ALI 1535"
+ depends on PCI
+diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
+index ff937ac..67a2089 100644
+--- a/drivers/i2c/busses/Makefile
++++ b/drivers/i2c/busses/Makefile
+@@ -54,6 +54,7 @@ obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
+ obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
+ obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
+ obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
++obj-$(CONFIG_I2C_TMPA910) += i2c-tmpa910.o
+
+ # External I2C/SMBus adapter drivers
+ obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
+diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c
+index f7346a9..0ed68e2 100644
+--- a/drivers/i2c/busses/i2c-pca-isa.c
++++ b/drivers/i2c/busses/i2c-pca-isa.c
+@@ -75,7 +75,7 @@ static int pca_isa_waitforcompletion(void *pd)
+ unsigned long timeout;
+
+ if (irq > -1) {
+- ret = wait_event_timeout(pca_wait,
++ ret = wait_event_interruptible_timeout(pca_wait,
+ pca_isa_readbyte(pd, I2C_PCA_CON)
+ & I2C_PCA_CON_SI, pca_isa_ops.timeout);
+ } else {
+@@ -96,7 +96,7 @@ static void pca_isa_resetchip(void *pd)
+ }
+
+ static irqreturn_t pca_handler(int this_irq, void *dev_id) {
+- wake_up(&pca_wait);
++ wake_up_interruptible(&pca_wait);
+ return IRQ_HANDLED;
+ }
+
+diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
+index 5b2213d..c4df9d4 100644
+--- a/drivers/i2c/busses/i2c-pca-platform.c
++++ b/drivers/i2c/busses/i2c-pca-platform.c
+@@ -84,7 +84,7 @@ static int i2c_pca_pf_waitforcompletion(void *pd)
+ unsigned long timeout;
+
+ if (i2c->irq) {
+- ret = wait_event_timeout(i2c->wait,
++ ret = wait_event_interruptible_timeout(i2c->wait,
+ i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
+ & I2C_PCA_CON_SI, i2c->adap.timeout);
+ } else {
+@@ -122,7 +122,7 @@ static irqreturn_t i2c_pca_pf_handler(int this_irq, void *dev_id)
+ if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
+ return IRQ_NONE;
+
+- wake_up(&i2c->wait);
++ wake_up_interruptible(&i2c->wait);
+
+ return IRQ_HANDLED;
+ }
+diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c
+index e29b6d5..b1c050f 100644
+--- a/drivers/i2c/busses/i2c-tiny-usb.c
++++ b/drivers/i2c/busses/i2c-tiny-usb.c
+@@ -13,7 +13,6 @@
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/module.h>
+-#include <linux/types.h>
+
+ /* include interfaces to usb layer */
+ #include <linux/usb.h>
+@@ -32,8 +31,8 @@
+ #define CMD_I2C_IO_END (1<<1)
+
+ /* i2c bit delay, default is 10us -> 100kHz */
+-static unsigned short delay = 10;
+-module_param(delay, ushort, 0);
++static int delay = 10;
++module_param(delay, int, 0);
+ MODULE_PARM_DESC(delay, "bit delay in microseconds, "
+ "e.g. 10 for 100kHz (default is 100kHz)");
+
+@@ -110,7 +109,7 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+
+ static u32 usb_func(struct i2c_adapter *adapter)
+ {
+- __le32 func;
++ u32 func;
+
+ /* get functionality from adapter */
+ if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) !=
+@@ -119,7 +118,7 @@ static u32 usb_func(struct i2c_adapter *adapter)
+ return 0;
+ }
+
+- return le32_to_cpu(func);
++ return func;
+ }
+
+ /* This is the actual algorithm we define */
+@@ -217,7 +216,8 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface,
+ "i2c-tiny-usb at bus %03d device %03d",
+ dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
+
+- if (usb_write(&dev->adapter, CMD_SET_DELAY, delay, 0, NULL, 0) != 0) {
++ if (usb_write(&dev->adapter, CMD_SET_DELAY,
++ cpu_to_le16(delay), 0, NULL, 0) != 0) {
+ dev_err(&dev->adapter.dev,
+ "failure setting delay to %dus\n", delay);
+ retval = -EIO;
+diff --git a/drivers/i2c/busses/i2c-tmpa910.c b/drivers/i2c/busses/i2c-tmpa910.c
+new file mode 100644
+index 0000000..4293f41
+--- /dev/null
++++ b/drivers/i2c/busses/i2c-tmpa910.c
+@@ -0,0 +1,660 @@
++/*
++ * drivers/i2c/busses/i2c-tmpa910.c
++ *
++ * Provides I2C support for Toshiba TMPA910
++ *
++ * Copyright © 2009 bplan GmbH
++ *
++ * 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/module.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++
++#include <linux/i2c.h>
++
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++
++
++struct tmpa910_i2c_regs {
++ uint32_t i2c_cr1; // 0x0000 I2C Control Register 1
++ uint32_t i2c_dbr; // 0x0004 I2C Data Buffer Register
++ uint32_t i2c_ar; // 0x0008 I2C (Slave) Address Register
++ uint32_t i2c_cr2; // 0x000C I2C Control Register 2(Write)/Status(Read)
++ uint32_t i2c_prs; // 0x0010 I2C Prescaler Clock Set Register
++ uint32_t i2c_ie; // 0x0014 I2C Interrupt Enable Register
++ uint32_t i2c_ir; // 0x0018 I2C Interrupt Register
++};
++
++#define i2c_sr i2c_cr2 // reading cr2 reads the status
++
++struct tmpa910_i2c_algo_data {
++ struct tmpa910_i2c_regs *regs;
++ int channel;
++
++ int irq;
++ spinlock_t lock;
++};
++
++struct tmpa910_i2c_priv {
++ struct platform_device *pdev;
++ struct i2c_adapter *i2c_adapter[2];
++ struct tmpa910_i2c_algo_data i2c_algo_data[2];
++ unsigned long io_start[2];
++ unsigned long io_lenght[2];
++};
++
++
++#ifdef __DEBUG__
++void tmpa910_i2c_dump_regs(struct tmpa910_i2c_algo_data *algo)
++{
++ volatile struct tmpa910_i2c_regs __iomem *regs = algo->regs;
++
++ printk("I2C controller at %p\n", regs);
++ printk(" I2C%dCR1 (0x%02x) = 0x%02x\n", algo->channel,
++ offsetof(struct tmpa910_i2c_regs, i2c_cr1), regs->i2c_cr1);
++ printk(" I2C%dDBR (0x%02x) = 0xXX\n", algo->channel,
++ offsetof(struct tmpa910_i2c_regs, i2c_dbr));
++ printk(" I2C%dAR (0x%02x) = 0x%02x\n", algo->channel,
++ offsetof(struct tmpa910_i2c_regs, i2c_ar), regs->i2c_ar);
++ printk(" I2C%dSR (0x%02x) = 0x%02x\n", algo->channel,
++ offsetof(struct tmpa910_i2c_regs, i2c_sr), regs->i2c_sr);
++ printk(" I2C%dCR2 (0x%02x) = 0xXX\n", algo->channel,
++ offsetof(struct tmpa910_i2c_regs, i2c_cr2));
++ printk(" I2C%dPRS (0x%02x) = 0x%02x\n", algo->channel,
++ offsetof(struct tmpa910_i2c_regs, i2c_prs), regs->i2c_prs);
++ printk(" I2C%dIE (0x%02x) = 0x%02x\n", algo->channel,
++ offsetof(struct tmpa910_i2c_regs, i2c_ie), regs->i2c_ie);
++ printk(" I2C%dIR (0x%02x) = 0x%02x\n", algo->channel,
++ offsetof(struct tmpa910_i2c_regs, i2c_ir), regs->i2c_ir);
++}
++#else
++void tmpa910_i2c_dump_regs(struct tmpa910_i2c_algo_data *algo)
++{
++}
++#endif
++
++//#define USE_UDELAY
++
++int tmpa910_i2c_wait_status_timeout(struct tmpa910_i2c_algo_data *algo,
++ uint32_t mask, uint32_t val)
++{
++ volatile struct tmpa910_i2c_regs __iomem *regs = algo->regs;
++#ifdef USE_UDELAY
++ volatile int timeout = 1000;
++#else
++ volatile int timeout = 1000 * 1000;
++#endif
++ volatile int sr;
++
++ while (((sr = regs->i2c_sr) & mask) != val) {
++#ifdef USE_UDELAY
++ udelay(10);
++#endif
++ if (timeout-- < 0) {
++ //tmpa910_i2c_dump_regs(algo);
++ return -1;
++ }
++ }
++
++ return 0;
++}
++
++int tmpa910_i2c_wait_free_bus(struct tmpa910_i2c_algo_data *algo)
++{
++ return tmpa910_i2c_wait_status_timeout(algo, (1UL << 5), 0); // bus state == free ?
++}
++
++int tmpa910_i2c_wait_done(struct tmpa910_i2c_algo_data *algo)
++{
++ return tmpa910_i2c_wait_status_timeout(algo, (1UL << 4), 0); // SCL line == low ?
++}
++
++int tmpa910_i2c_start(struct tmpa910_i2c_algo_data *algo, int slave_adr)
++{
++ volatile struct tmpa910_i2c_regs __iomem *regs = algo->regs;
++
++ if (tmpa910_i2c_wait_free_bus(algo) < 0) {
++ printk(KERN_ERR "tmpa9xx i2c bus not free\n");
++ return -EBUSY;
++ }
++
++ regs->i2c_cr1 |= (1UL << 4); // enable acknowledge clock
++
++ regs->i2c_dbr = slave_adr; // send slave address
++
++ regs->i2c_cr2 = (1UL << 7) // select master mode
++ | (1UL << 6) // transmit operation
++ | (1UL << 5) // generate start condition
++ | (1UL << 4) // clear service request
++ | (1UL << 3) // enable I2C operation
++ ;
++
++ if (tmpa910_i2c_wait_done(algo) < 0) {
++ printk(KERN_ERR "done timeout \n");
++ return -ETIMEDOUT;
++ }
++ return 0;
++}
++
++int tmpa910_i2c_stop(struct tmpa910_i2c_algo_data *algo)
++{
++ volatile struct tmpa910_i2c_regs __iomem *regs = algo->regs;
++
++ regs->i2c_cr2 = (1UL << 7) // select master mode
++ | (1UL << 6) // transmit operation
++ | (0UL << 5) // generate stop condition
++ | (1UL << 4) // clear service request
++ | (1UL << 3) // enable I2C operation
++ ;
++
++ if (tmpa910_i2c_wait_free_bus(algo) < 0) {
++ return -EBUSY;
++ }
++
++ return 0;
++}
++
++int tmpa910_i2c_xmit(struct i2c_adapter *adap, struct i2c_msg *msg)
++{
++ struct tmpa910_i2c_algo_data *algo = adap->algo_data;
++ volatile struct tmpa910_i2c_regs __iomem *regs = algo->regs;
++ int ret;
++ unsigned int sr, cr1;
++ int i;
++ u8 *data;
++
++ data = msg->buf;
++
++ if ((ret = tmpa910_i2c_start(algo, (msg->addr << 1))) < 0) {
++ dev_dbg(&adap->dev, "failed to generate start!\n");
++ return ret;
++ }
++
++ sr = regs->i2c_sr;
++
++ if (sr & (1UL << 0)) // check last received bit (should be low for ACK)
++ {
++ dev_dbg(&adap->dev, "no ack!\n");
++ tmpa910_i2c_dump_regs(algo);
++ return -EIO;
++ }
++
++ if ((sr & (1UL << 6)) == 0) // check xmit/rcv selection state (should be xmit)
++ {
++ dev_dbg(&adap->dev, "wrong transfer state!\n");
++ return -EIO;
++ }
++
++ for (i = 0; i < msg->len; i++) {
++ cr1 = regs->i2c_cr1;
++ cr1 &= ~(7UL << 5); // 8bit transfer
++ cr1 |= (1UL << 4); // acknowledge
++
++ if (tmpa910_i2c_wait_done(algo) < 0) {
++ dev_dbg(&adap->dev, "timeout !\n");
++ return -ETIMEDOUT;
++ }
++
++ regs->i2c_cr1 = cr1;
++
++ regs->i2c_dbr = data[i] & 0xFF; // put 8bits into xmit FIFO
++
++ if (tmpa910_i2c_wait_done(algo) < 0) {
++ dev_dbg(&adap->dev, "timeout !\n");
++ return -ETIMEDOUT;
++ }
++
++ }
++
++ if ((ret = tmpa910_i2c_stop(algo)) < 0) {
++ dev_dbg(&adap->dev, "failed to generate stop!\n");
++ return ret;
++ }
++
++ return ret;
++}
++
++int tmpa910_i2c_rcv(struct i2c_adapter *adap, struct i2c_msg *msg)
++{
++ struct tmpa910_i2c_algo_data *algo = adap->algo_data;
++ volatile struct tmpa910_i2c_regs __iomem *regs = algo->regs;
++ int ret;
++ unsigned int sr, cr1;
++ int i, dummy;
++ u8 *data;
++
++
++ data = msg->buf;
++
++ if ((ret = tmpa910_i2c_start(algo, (msg->addr << 1) | 1)) < 0) {
++ printk(KERN_ERR "failed to generate start! ret=%d. addr=0x%x\n", ret,
++ msg->addr);
++ return ret;
++ }
++
++ if (tmpa910_i2c_wait_done(algo) < 0) {
++ printk(KERN_ERR "timeout !\n");
++ return -ETIMEDOUT;
++ }
++
++ sr = regs->i2c_sr;
++
++ if (sr & (1UL << 0)) { // check last received bit (should be low for ACK)
++ printk(KERN_ERR "i2c timeout - no ack !\n");
++ //tmpa910_i2c_dump_regs(algo);
++ return -EIO;
++ }
++
++ if (sr & (1UL << 6)) { // check xmit/rcv selection state (should be rcv)
++ printk(KERN_ERR "wrong transfer state!\n");
++ return -EIO;
++ }
++ // read receive data
++ dummy = regs->i2c_dbr;
++
++ cr1 = regs->i2c_cr1;
++ cr1 &= ~((1UL << 4) | (7UL << 5)); // 8bit transfer, no ACK
++ regs->i2c_cr1 = cr1;
++
++ // write dummy data to set PIN to 1
++ regs->i2c_dbr = 0x00;
++
++ for (i = 0; i < msg->len; i++) {
++
++ ret = tmpa910_i2c_wait_status_timeout(algo, (1UL << 4), (1UL << 4)); // SCL line = free ? ?
++ if (ret < 0) {
++ printk(KERN_ERR "initial SCL line free status failed!\n");
++ break;
++ }
++
++ if (tmpa910_i2c_wait_done(algo) < 0) {
++ printk(KERN_ERR "i2c timeout !\n");
++ return -ETIMEDOUT;
++ }
++
++ data[i] = regs->i2c_dbr;
++
++ // generate NACK, clear ACK
++ cr1 = regs->i2c_cr1;
++ cr1 &= ~((1UL << 4) | (7UL << 5)); // clear no of xfer bits, no ACK
++ cr1 |= (1UL << 5); // xfer bits = 1
++ regs->i2c_cr1 = cr1;
++
++ // write dummy data to issue the ack
++ regs->i2c_dbr = 0;
++
++ // wait until 1bit xfer is complete
++ ret = tmpa910_i2c_wait_status_timeout(algo, (1UL << 4), (1UL << 4)); // SCL line = free ? ?
++ if (ret < 0) {
++ dev_dbg(&adap->dev, "wait 1bit xfer failed!\n");
++ break;
++ }
++ }
++
++ if ((ret = tmpa910_i2c_stop(algo)) < 0) {
++ printk(KERN_ERR "failed to generate stop!\n");
++ return ret;
++ }
++
++ return ret;
++}
++
++int tmpa910_i2c_setup(struct i2c_adapter *adap);
++/*
++ * Generic I2C master transfer entrypoint
++ */
++static int tmpa910_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
++ int num)
++{
++ int i;
++ struct i2c_msg *msg;
++ int err = 0, msgcnt = 0;
++ struct tmpa910_i2c_algo_data *algo = adap->algo_data;
++
++ printk(KERN_DEBUG "tmpa910_i2c_xfer(adap %p,msgs %p,num %d)\n",adap,msgs,num);
++
++
++ if (tmpa910_i2c_wait_free_bus(algo) < 0) {
++ printk(KERN_ERR "bus not free ! Reset!\n");
++ tmpa910_i2c_setup(adap);
++ }
++
++ dev_dbg(&adap->dev, "tmpa910_i2c_xfer: processing %d messages:\n", num);
++
++ for (i = 0; i < num; i++) {
++ msg = &msgs[i];
++
++ printk(KERN_DEBUG " msg %p msg->buf 0x%x msg->len 0x%x msg->flags 0x%x\n",msg,msg->buf,msg->len,msg->flags);
++
++
++ dev_dbg(&adap->dev, " #%d : %sing %d byte%s %s 0x%02x\n",
++ i,
++ msg->flags & I2C_M_RD ? "Read" : "Writ",
++ msg->len,
++ msg->len > 1 ? "s" : "",
++ msg->flags & I2C_M_RD ? "from" : "to", msg->addr);
++
++ if (msg->len == 0)
++ continue;
++
++ if (msg->flags & I2C_M_RD)
++ err = tmpa910_i2c_rcv(adap, msg);
++ else
++ err = tmpa910_i2c_xmit(adap, msg);
++
++ if (err)
++ break;
++
++ //dev_dbg(&adap->dev, "transfer complete\n");
++
++ msgcnt++;
++ };
++
++ if (err == 0)
++ return msgcnt;
++ else
++ return err;
++}
++
++// serial clock rate = PCLK / (Prescaler*(2**(2+sck)+16))
++//
++// 400khz for PCLK = 96MHz
++// 400 = 96*1000 / ( 12 * (2**(2+0) + 16))
++#define PRSCK_400KHZ 12
++#define CR1SCK_400KHZ 0
++// 100khz for PCLK = 96MHz
++// 100 = 96*1000 / ( 30 * (2**(2+2) + 16))
++#define PRSCK_100KHZ 30
++#define CR1SCK_100KHZ 2
++
++int tmpa910_i2c_setup(struct i2c_adapter *adap)
++{
++ struct tmpa910_i2c_algo_data *algo = adap->algo_data;
++ volatile struct tmpa910_i2c_regs __iomem *regs = algo->regs;
++
++ // software reset
++ regs->i2c_cr2 = (1UL << 1) | (0UL << 0);
++ regs->i2c_cr2 = (0UL << 1) | (1UL << 0);
++
++ regs->i2c_ar = 0;
++
++ // setup scalers to 100khz default
++ regs->i2c_prs = PRSCK_100KHZ;
++ regs->i2c_cr1 = CR1SCK_100KHZ;
++
++ // enable i2c operation
++ regs->i2c_cr2 = (1UL << 3);
++
++ //tmpa910_i2c_dump_regs(algo);
++
++ return 0;
++}
++
++int tmpa910_i2c_shutdown(struct i2c_adapter *adap)
++{
++ struct tmpa910_i2c_algo_data *algo = adap->algo_data;
++ volatile struct tmpa910_i2c_regs __iomem *regs = algo->regs;
++
++ if(tmpa910_i2c_wait_free_bus(algo) < 0) {
++ printk(KERN_ERR "bus not free !\n");
++ //return -EBUSY;
++ }
++
++ regs->i2c_prs = 0;
++ regs->i2c_cr1 = 0;
++
++ // disable i2c operation
++ regs->i2c_cr2 = (0UL << 3);
++
++ return 0;
++}
++
++static u32 tmpa910_i2c_func(struct i2c_adapter *adapter)
++{
++ printk(KERN_INFO "tmpa910_i2c_func adapter %p\n",adapter);
++
++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
++}
++
++static struct i2c_algorithm tmpa910_algorithm = {
++ .master_xfer = tmpa910_i2c_xfer,
++ .functionality = tmpa910_i2c_func,
++};
++
++static int __init tmpa910_i2c_probe(struct platform_device *pdev)
++{
++ struct resource *r;
++ int ret = 0;
++ int irq;
++ struct i2c_adapter *adapter;
++ struct tmpa910_i2c_priv *priv;
++
++ printk(KERN_INFO "probe i2c dev!\n");
++
++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (r == NULL) {
++ dev_err(&pdev->dev, "No IO memory resource for I2C0\n");
++ ret = -ENODEV;
++ goto fail;
++ }
++
++ priv = kzalloc(sizeof(struct tmpa910_i2c_priv), GFP_KERNEL);
++ if (priv == 0) {
++ ret = -ENOMEM;
++ goto fail;
++ }
++
++ priv->pdev = pdev;
++ priv->i2c_algo_data[0].irq = NO_IRQ;
++ priv->i2c_algo_data[1].irq = NO_IRQ;
++
++ r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
++ if (r == NULL) {
++ dev_err(&pdev->dev, "failed to request memory resource\n");
++ ret = -EBUSY;
++ goto fail;
++ }
++
++ priv->io_start[0] = r->start;
++ priv->io_lenght[0] = r->end - r->start + 1;
++
++
++ priv->i2c_algo_data[0].regs = ioremap(r->start, r->end - r->start + 1);
++ if (priv->i2c_algo_data[0].regs == NULL) {
++ dev_err(&pdev->dev, "ioremap() failed\n");
++ ret = -ENODEV;
++ goto fail;
++ }
++
++
++ r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ if (r == NULL) {
++ dev_err(&pdev->dev, "No IO memory resource for I2C1\n");
++ ret = -ENODEV;
++ goto fail;
++ }
++
++
++ r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
++ if (r == NULL) {
++ dev_err(&pdev->dev, "failed to request memory resource\n");
++ ret = -EBUSY;
++ goto fail;
++ }
++
++ priv->io_start[1] = r->start;
++ priv->io_lenght[1] = r->end - r->start + 1;
++
++ priv->i2c_algo_data[1].regs = ioremap(r->start, r->end - r->start + 1);
++ if (priv->i2c_algo_data[1].regs == NULL) {
++ dev_err(&pdev->dev, "ioremap() failed\n");
++ ret = -ENODEV;
++ goto fail;
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ dev_err(&pdev->dev, "no IRQ resource defined\n");
++ ret = -ENXIO;
++ goto fail;
++ }
++
++ priv->i2c_algo_data[0].irq = irq;
++
++ irq = platform_get_irq(pdev, 1);
++ if (irq < 0) {
++ dev_err(&pdev->dev, "no IRQ resource defined\n");
++ ret = -ENXIO;
++ goto fail;
++ }
++
++ priv->i2c_algo_data[1].irq = irq;
++
++ adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
++ if (adapter == NULL) {
++ dev_err(&pdev->dev, "can't allocate adapter 0\n");
++ ret = -ENOMEM;
++ goto fail;
++ }
++
++ sprintf(adapter->name, "TMPA910_I2C0");
++ adapter->algo = &tmpa910_algorithm;
++ adapter->algo_data = &priv->i2c_algo_data[0];
++ priv->i2c_algo_data[0].channel = 0;
++ adapter->class = I2C_CLASS_HWMON;
++ adapter->dev.parent = &pdev->dev;
++ adapter->id = 0;
++ adapter->nr = 0;
++ priv->i2c_adapter[0] = adapter;
++
++ platform_set_drvdata(pdev, priv);
++
++ ret = i2c_add_numbered_adapter(priv->i2c_adapter[0]);
++ if (ret) {
++ dev_err(&pdev->dev, "Adapter %s registration failed\n",
++ priv->i2c_adapter[0]->name);
++ goto fail;
++ }
++
++ tmpa910_i2c_setup(adapter);
++
++ adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
++ if (adapter == NULL) {
++ dev_err(&pdev->dev, "can't allocate adapter 1\n");
++ ret = -ENOMEM;
++ goto fail;
++ }
++
++ sprintf(adapter->name, "TMPA910_I2C1");
++ adapter->algo = &tmpa910_algorithm;
++ adapter->algo_data = &priv->i2c_algo_data[1];
++ priv->i2c_algo_data[1].channel = 1;
++ adapter->class = I2C_CLASS_HWMON;
++ adapter->dev.parent = &pdev->dev;
++ adapter->id = 0; // new style drivers don't need those
++ adapter->nr = 1;
++ priv->i2c_adapter[1] = adapter;
++
++ ret = i2c_add_numbered_adapter(priv->i2c_adapter[1]);
++ if (ret) {
++ dev_err(&pdev->dev, "Adapter %s registration failed\n",
++ priv->i2c_adapter[1]->name);
++ goto fail;
++ }
++
++ tmpa910_i2c_setup(adapter);
++
++ printk
++ ("TMPA9x0 I2C: driver ready (ch0: irq=%d IO@%p ch1: irq=%d IO@%p)\n",
++ priv->i2c_algo_data[0].irq, priv->i2c_algo_data[0].regs,
++ priv->i2c_algo_data[1].irq, priv->i2c_algo_data[1].regs);
++
++ return 0;
++ fail:
++ return ret;
++}
++
++static int tmpa910_i2c_remove(struct platform_device *pdev)
++{
++ struct tmpa910_i2c_priv *priv = platform_get_drvdata(pdev);
++ struct i2c_adapter *adap;
++
++ platform_set_drvdata(pdev, NULL);
++
++ if ((adap = priv->i2c_adapter[1]) != NULL) {
++ tmpa910_i2c_shutdown(adap);
++ i2c_del_adapter(adap);
++ iounmap(priv->i2c_algo_data[1].regs);
++
++ release_mem_region(priv->io_start[0], priv->io_lenght[0]);
++
++ kfree(adap);
++ }
++
++ if ((adap = priv->i2c_adapter[0]) != NULL) {
++ tmpa910_i2c_shutdown(adap);
++ i2c_del_adapter(adap);
++ iounmap(priv->i2c_algo_data[0].regs);
++
++ release_mem_region(priv->io_start[1], priv->io_lenght[1]);
++
++ kfree(adap);
++ }
++
++
++ kfree(priv);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++
++static int tmpa910_i2c_suspend(struct platform_device *pdev, pm_message_t msg)
++{
++ return 0;
++}
++
++static int tmpa910_i2c_resume(struct platform_device *pdev)
++{
++ return 0;
++}
++
++#else
++
++#define tmpa910_i2c_suspend NULL
++#define tmpa910_i2c_resume NULL
++#endif
++
++static struct platform_driver tmpa910_i2c_driver = {
++ .probe = tmpa910_i2c_probe,
++ .remove = tmpa910_i2c_remove,
++ .suspend = tmpa910_i2c_suspend,
++ .resume = tmpa910_i2c_resume,
++ .driver = {
++ .name = "tmpa910-i2c",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init tmpa910_i2c_init(void)
++{
++ return platform_driver_register(&tmpa910_i2c_driver);
++}
++
++module_init(tmpa910_i2c_init);
++
++static void __exit tmpa910_i2c_exit(void)
++{
++ platform_driver_unregister(&tmpa910_i2c_driver);
++}
++
++module_exit(tmpa910_i2c_exit);
++
++MODULE_DESCRIPTION("Toshiba TMPA910 I2C Driver");
++MODULE_AUTHOR("bplan GmbH");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
+index 3bf7b0a..2965043 100644
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -801,9 +801,6 @@ int i2c_del_adapter(struct i2c_adapter *adap)
+ adap->dev.parent);
+ #endif
+
+- /* device name is gone after device_unregister */
+- dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
+-
+ /* clean up the sysfs representation */
+ init_completion(&adap->dev_released);
+ device_unregister(&adap->dev);
+@@ -816,6 +813,8 @@ int i2c_del_adapter(struct i2c_adapter *adap)
+ idr_remove(&i2c_adapter_idr, adap->nr);
+ mutex_unlock(&core_lock);
+
++ dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
++
+ /* Clear the device structure in case this adapter is ever going to be
+ added again */
+ memset(&adap->dev, 0, sizeof(adap->dev));
+diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
+index 1ccfb40..9aec78d 100644
+--- a/drivers/ide/slc90e66.c
++++ b/drivers/ide/slc90e66.c
+@@ -91,7 +91,8 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
+
+ if (!(reg48 & u_flag))
+ pci_write_config_word(dev, 0x48, reg48|u_flag);
+- if ((reg4a & a_speed) != u_speed) {
++ /* FIXME: (reg4a & a_speed) ? */
++ if ((reg4a & u_speed) != u_speed) {
+ pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+ pci_read_config_word(dev, 0x4a, ®4a);
+ pci_write_config_word(dev, 0x4a, reg4a|u_speed);
+diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
+index 100da85..b368406 100644
+--- a/drivers/infiniband/hw/ipath/ipath_fs.c
++++ b/drivers/infiniband/hw/ipath/ipath_fs.c
+@@ -346,8 +346,10 @@ static int ipathfs_fill_super(struct super_block *sb, void *data,
+ list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) {
+ spin_unlock_irqrestore(&ipath_devs_lock, flags);
+ ret = create_device_files(sb, dd);
+- if (ret)
++ if (ret) {
++ deactivate_locked_super(sb);
+ goto bail;
++ }
+ spin_lock_irqsave(&ipath_devs_lock, flags);
+ }
+
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+index df3eb8c..2bf5116 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -884,7 +884,6 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour,
+
+ neigh->neighbour = neighbour;
+ neigh->dev = dev;
+- memset(&neigh->dgid.raw, 0, sizeof (union ib_gid));
+ *to_ipoib_neigh(neighbour) = neigh;
+ skb_queue_head_init(&neigh->queue);
+ ipoib_cm_set(neigh, NULL);
+diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c
+index c8f5a9a..33309fe 100644
+--- a/drivers/input/misc/winbond-cir.c
++++ b/drivers/input/misc/winbond-cir.c
+@@ -768,7 +768,7 @@ wbcir_parse_rc6(struct device *dev, struct wbcir_data *data)
+ return;
+ }
+
+- dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X "
++ dev_info(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X "
+ "toggle %u mode %u scan 0x%08X\n",
+ address,
+ command,
+diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
+index fc8823b..f361106 100644
+--- a/drivers/input/mouse/alps.c
++++ b/drivers/input/mouse/alps.c
+@@ -5,7 +5,6 @@
+ * Copyright (c) 2003-2005 Peter Osterlund <petero2 at telia.com>
+ * Copyright (c) 2004 Dmitry Torokhov <dtor at mail.ru>
+ * Copyright (c) 2005 Vojtech Pavlik <vojtech at suse.cz>
+- * Copyright (c) 2009 Sebastian Kapfer <sebastian_kapfer at gmx.net>
+ *
+ * ALPS detection, tap switching and status querying info is taken from
+ * tpconfig utility (by C. Scott Ananian and Bruce Kall).
+@@ -36,8 +35,6 @@
+ #define ALPS_OLDPROTO 0x10
+ #define ALPS_PASS 0x20
+ #define ALPS_FW_BK_2 0x40
+-#define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with
+- 6-byte ALPS packet */
+
+ static const struct alps_model_info alps_model_data[] = {
+ { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
+@@ -58,9 +55,7 @@ static const struct alps_model_info alps_model_data[] = {
+ { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
+ { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
+ { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
+- /* Dell Latitude E5500, E6400, E6500, Precision M4400 */
+- { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
+- ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
++ { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
+ { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 }, /* Dell Vostro 1400 */
+ };
+
+@@ -71,88 +66,20 @@ static const struct alps_model_info alps_model_data[] = {
+ */
+
+ /*
+- * PS/2 packet format
+- *
+- * byte 0: 0 0 YSGN XSGN 1 M R L
+- * byte 1: X7 X6 X5 X4 X3 X2 X1 X0
+- * byte 2: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
+- *
+- * Note that the device never signals overflow condition.
+- *
+- * ALPS absolute Mode - new format
++ * ALPS abolute Mode - new format
+ *
+ * byte 0: 1 ? ? ? 1 ? ? ?
+ * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
+- * byte 2: 0 x10 x9 x8 x7 ? fin ges
++ * byte 2: 0 x10 x9 x8 x7 ? fin ges
+ * byte 3: 0 y9 y8 y7 1 M R L
+ * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
+ * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
+ *
+- * Dualpoint device -- interleaved packet format
+- *
+- * byte 0: 1 1 0 0 1 1 1 1
+- * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
+- * byte 2: 0 x10 x9 x8 x7 0 fin ges
+- * byte 3: 0 0 YSGN XSGN 1 1 1 1
+- * byte 4: X7 X6 X5 X4 X3 X2 X1 X0
+- * byte 5: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
+- * byte 6: 0 y9 y8 y7 1 m r l
+- * byte 7: 0 y6 y5 y4 y3 y2 y1 y0
+- * byte 8: 0 z6 z5 z4 z3 z2 z1 z0
+- *
+- * CAPITALS = stick, miniscules = touchpad
+- *
+ * ?'s can have different meanings on different models,
+ * such as wheel rotation, extra buttons, stick buttons
+ * on a dualpoint, etc.
+ */
+
+-static bool alps_is_valid_first_byte(const struct alps_model_info *model,
+- unsigned char data)
+-{
+- return (data & model->mask0) == model->byte0;
+-}
+-
+-static void alps_report_buttons(struct psmouse *psmouse,
+- struct input_dev *dev1, struct input_dev *dev2,
+- int left, int right, int middle)
+-{
+- struct alps_data *priv = psmouse->private;
+- const struct alps_model_info *model = priv->i;
+-
+- if (model->flags & ALPS_PS2_INTERLEAVED) {
+- struct input_dev *dev;
+-
+- /*
+- * If shared button has already been reported on the
+- * other device (dev2) then this event should be also
+- * sent through that device.
+- */
+- dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
+- input_report_key(dev, BTN_LEFT, left);
+-
+- dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
+- input_report_key(dev, BTN_RIGHT, right);
+-
+- dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
+- input_report_key(dev, BTN_MIDDLE, middle);
+-
+- /*
+- * Sync the _other_ device now, we'll do the first
+- * device later once we report the rest of the events.
+- */
+- input_sync(dev2);
+- } else {
+- /*
+- * For devices with non-interleaved packets we know what
+- * device buttons belong to so we can simply report them.
+- */
+- input_report_key(dev1, BTN_LEFT, left);
+- input_report_key(dev1, BTN_RIGHT, right);
+- input_report_key(dev1, BTN_MIDDLE, middle);
+- }
+-}
+-
+ static void alps_process_packet(struct psmouse *psmouse)
+ {
+ struct alps_data *priv = psmouse->private;
+@@ -162,6 +89,18 @@ static void alps_process_packet(struct psmouse *psmouse)
+ int x, y, z, ges, fin, left, right, middle;
+ int back = 0, forward = 0;
+
++ if ((packet[0] & 0xc8) == 0x08) { /* 3-byte PS/2 packet */
++ input_report_key(dev2, BTN_LEFT, packet[0] & 1);
++ input_report_key(dev2, BTN_RIGHT, packet[0] & 2);
++ input_report_key(dev2, BTN_MIDDLE, packet[0] & 4);
++ input_report_rel(dev2, REL_X,
++ packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
++ input_report_rel(dev2, REL_Y,
++ packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
++ input_sync(dev2);
++ return;
++ }
++
+ if (priv->i->flags & ALPS_OLDPROTO) {
+ left = packet[2] & 0x10;
+ right = packet[2] & 0x08;
+@@ -197,13 +136,18 @@ static void alps_process_packet(struct psmouse *psmouse)
+ input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x));
+ input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
+
+- alps_report_buttons(psmouse, dev2, dev, left, right, middle);
++ input_report_key(dev2, BTN_LEFT, left);
++ input_report_key(dev2, BTN_RIGHT, right);
++ input_report_key(dev2, BTN_MIDDLE, middle);
+
++ input_sync(dev);
+ input_sync(dev2);
+ return;
+ }
+
+- alps_report_buttons(psmouse, dev, dev2, left, right, middle);
++ input_report_key(dev, BTN_LEFT, left);
++ input_report_key(dev, BTN_RIGHT, right);
++ input_report_key(dev, BTN_MIDDLE, middle);
+
+ /* Convert hardware tap to a reasonable Z value */
+ if (ges && !fin) z = 40;
+@@ -244,168 +188,25 @@ static void alps_process_packet(struct psmouse *psmouse)
+ input_sync(dev);
+ }
+
+-static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
+- unsigned char packet[],
+- bool report_buttons)
+-{
+- struct alps_data *priv = psmouse->private;
+- struct input_dev *dev2 = priv->dev2;
+-
+- if (report_buttons)
+- alps_report_buttons(psmouse, dev2, psmouse->dev,
+- packet[0] & 1, packet[0] & 2, packet[0] & 4);
+-
+- input_report_rel(dev2, REL_X,
+- packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
+- input_report_rel(dev2, REL_Y,
+- packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
+-
+- input_sync(dev2);
+-}
+-
+-static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
+-{
+- struct alps_data *priv = psmouse->private;
+-
+- if (psmouse->pktcnt < 6)
+- return PSMOUSE_GOOD_DATA;
+-
+- if (psmouse->pktcnt == 6) {
+- /*
+- * Start a timer to flush the packet if it ends up last
+- * 6-byte packet in the stream. Timer needs to fire
+- * psmouse core times out itself. 20 ms should be enough
+- * to decide if we are getting more data or not.
+- */
+- mod_timer(&priv->timer, jiffies + msecs_to_jiffies(20));
+- return PSMOUSE_GOOD_DATA;
+- }
+-
+- del_timer(&priv->timer);
+-
+- if (psmouse->packet[6] & 0x80) {
+-
+- /*
+- * Highest bit is set - that means we either had
+- * complete ALPS packet and this is start of the
+- * next packet or we got garbage.
+- */
+-
+- if (((psmouse->packet[3] |
+- psmouse->packet[4] |
+- psmouse->packet[5]) & 0x80) ||
+- (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) {
+- dbg("refusing packet %x %x %x %x "
+- "(suspected interleaved ps/2)\n",
+- psmouse->packet[3], psmouse->packet[4],
+- psmouse->packet[5], psmouse->packet[6]);
+- return PSMOUSE_BAD_DATA;
+- }
+-
+- alps_process_packet(psmouse);
+-
+- /* Continue with the next packet */
+- psmouse->packet[0] = psmouse->packet[6];
+- psmouse->pktcnt = 1;
+-
+- } else {
+-
+- /*
+- * High bit is 0 - that means that we indeed got a PS/2
+- * packet in the middle of ALPS packet.
+- *
+- * There is also possibility that we got 6-byte ALPS
+- * packet followed by 3-byte packet from trackpoint. We
+- * can not distinguish between these 2 scenarios but
+- * becase the latter is unlikely to happen in course of
+- * normal operation (user would need to press all
+- * buttons on the pad and start moving trackpoint
+- * without touching the pad surface) we assume former.
+- * Even if we are wrong the wost thing that would happen
+- * the cursor would jump but we should not get protocol
+- * desynchronization.
+- */
+-
+- alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
+- false);
+-
+- /*
+- * Continue with the standard ALPS protocol handling,
+- * but make sure we won't process it as an interleaved
+- * packet again, which may happen if all buttons are
+- * pressed. To avoid this let's reset the 4th bit which
+- * is normally 1.
+- */
+- psmouse->packet[3] = psmouse->packet[6] & 0xf7;
+- psmouse->pktcnt = 4;
+- }
+-
+- return PSMOUSE_GOOD_DATA;
+-}
+-
+-static void alps_flush_packet(unsigned long data)
+-{
+- struct psmouse *psmouse = (struct psmouse *)data;
+-
+- serio_pause_rx(psmouse->ps2dev.serio);
+-
+- if (psmouse->pktcnt == 6) {
+-
+- /*
+- * We did not any more data in reasonable amount of time.
+- * Validate the last 3 bytes and process as a standard
+- * ALPS packet.
+- */
+- if ((psmouse->packet[3] |
+- psmouse->packet[4] |
+- psmouse->packet[5]) & 0x80) {
+- dbg("refusing packet %x %x %x "
+- "(suspected interleaved ps/2)\n",
+- psmouse->packet[3], psmouse->packet[4],
+- psmouse->packet[5]);
+- } else {
+- alps_process_packet(psmouse);
+- }
+- psmouse->pktcnt = 0;
+- }
+-
+- serio_continue_rx(psmouse->ps2dev.serio);
+-}
+-
+ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
+ {
+ struct alps_data *priv = psmouse->private;
+- const struct alps_model_info *model = priv->i;
+
+ if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
+ if (psmouse->pktcnt == 3) {
+- alps_report_bare_ps2_packet(psmouse, psmouse->packet,
+- true);
++ alps_process_packet(psmouse);
+ return PSMOUSE_FULL_PACKET;
+ }
+ return PSMOUSE_GOOD_DATA;
+ }
+
+- /* Check for PS/2 packet stuffed in the middle of ALPS packet. */
+-
+- if ((model->flags & ALPS_PS2_INTERLEAVED) &&
+- psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) {
+- return alps_handle_interleaved_ps2(psmouse);
+- }
+-
+- if (!alps_is_valid_first_byte(model, psmouse->packet[0])) {
+- dbg("refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n",
+- psmouse->packet[0], model->mask0, model->byte0);
++ if ((psmouse->packet[0] & priv->i->mask0) != priv->i->byte0)
+ return PSMOUSE_BAD_DATA;
+- }
+
+ /* Bytes 2 - 6 should have 0 in the highest bit */
+ if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 &&
+- (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
+- dbg("refusing packet[%i] = %x\n",
+- psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]);
++ (psmouse->packet[psmouse->pktcnt - 1] & 0x80))
+ return PSMOUSE_BAD_DATA;
+- }
+
+ if (psmouse->pktcnt == 6) {
+ alps_process_packet(psmouse);
+@@ -644,7 +445,6 @@ static void alps_disconnect(struct psmouse *psmouse)
+ struct alps_data *priv = psmouse->private;
+
+ psmouse_reset(psmouse);
+- del_timer_sync(&priv->timer);
+ input_unregister_device(priv->dev2);
+ kfree(priv);
+ }
+@@ -661,8 +461,6 @@ int alps_init(struct psmouse *psmouse)
+ goto init_fail;
+
+ priv->dev2 = dev2;
+- setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse);
+-
+ psmouse->private = priv;
+
+ if (alps_hw_init(psmouse, &version))
+diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
+index 904ed8b..bc87936 100644
+--- a/drivers/input/mouse/alps.h
++++ b/drivers/input/mouse/alps.h
+@@ -23,7 +23,6 @@ struct alps_data {
+ char phys[32]; /* Phys */
+ const struct alps_model_info *i;/* Info */
+ int prev_fin; /* Finger bit from previous packet */
+- struct timer_list timer;
+ };
+
+ #ifdef CONFIG_MOUSE_PS2_ALPS
+diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
+index 0876d82..07c5379 100644
+--- a/drivers/input/mouse/psmouse-base.c
++++ b/drivers/input/mouse/psmouse-base.c
+@@ -667,6 +667,19 @@ static int psmouse_extensions(struct psmouse *psmouse,
+ max_proto = PSMOUSE_IMEX;
+ }
+
++/*
++ * Try Finger Sensing Pad
++ */
++ if (max_proto > PSMOUSE_IMEX) {
++ if (fsp_detect(psmouse, set_properties) == 0) {
++ if (!set_properties || fsp_init(psmouse) == 0)
++ return PSMOUSE_FSP;
++/*
++ * Init failed, try basic relative protocols
++ */
++ max_proto = PSMOUSE_IMEX;
++ }
++ }
+
+ if (max_proto > PSMOUSE_IMEX) {
+ if (genius_detect(psmouse, set_properties) == 0)
+@@ -683,21 +696,6 @@ static int psmouse_extensions(struct psmouse *psmouse,
+ }
+
+ /*
+- * Try Finger Sensing Pad. We do it here because its probe upsets
+- * Trackpoint devices (causing TP_READ_ID command to time out).
+- */
+- if (max_proto > PSMOUSE_IMEX) {
+- if (fsp_detect(psmouse, set_properties) == 0) {
+- if (!set_properties || fsp_init(psmouse) == 0)
+- return PSMOUSE_FSP;
+-/*
+- * Init failed, try basic relative protocols
+- */
+- max_proto = PSMOUSE_IMEX;
+- }
+- }
+-
+-/*
+ * Reset to defaults in case the device got confused by extended
+ * protocol probes. Note that we follow up with full reset because
+ * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS.
+diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
+index 2a5982e..2bcf1ac 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -67,12 +67,10 @@ static inline void i8042_write_command(int val)
+
+ #include <linux/dmi.h>
+
+-static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
++static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
+ {
+- /*
+- * Arima-Rioworks HDAMB -
+- * AUX LOOP command does not raise AUX IRQ
+- */
++ /* AUX LOOP command does not raise AUX IRQ */
++ .ident = "Arima-Rioworks HDAMB",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
+ DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
+@@ -80,7 +78,7 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
+- /* ASUS G1S */
++ .ident = "ASUS G1S",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_BOARD_NAME, "G1S"),
+@@ -88,7 +86,8 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
+- /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */
++ /* AUX LOOP command does not raise AUX IRQ */
++ .ident = "ASUS P65UP5",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"),
+@@ -96,6 +95,7 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
++ .ident = "Compaq Proliant 8500",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+ DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+@@ -103,6 +103,7 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
++ .ident = "Compaq Proliant DL760",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+ DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+@@ -110,7 +111,7 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
+- /* OQO Model 01 */
++ .ident = "OQO Model 01",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
+@@ -118,7 +119,8 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
+- /* ULI EV4873 - AUX LOOP does not work properly */
++ /* AUX LOOP does not work properly */
++ .ident = "ULI EV4873",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
+@@ -126,7 +128,7 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
+- /* Microsoft Virtual Machine */
++ .ident = "Microsoft Virtual Machine",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
+@@ -134,7 +136,7 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
+- /* Medion MAM 2070 */
++ .ident = "Medion MAM 2070",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
+@@ -142,7 +144,7 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
+- /* Blue FB5601 */
++ .ident = "Blue FB5601",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "blue"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
+@@ -150,7 +152,7 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
+- /* Gigabyte M912 */
++ .ident = "Gigabyte M912",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
+@@ -158,14 +160,7 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ },
+ },
+ {
+- /* Gigabyte M1022M netbook */
+- .matches = {
+- DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."),
+- DMI_MATCH(DMI_BOARD_NAME, "M1022E"),
+- DMI_MATCH(DMI_BOARD_VERSION, "1.02"),
+- },
+- },
+- {
++ .ident = "HP DV9700",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
+@@ -182,72 +177,72 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+ * ... apparently some Toshibas don't like MUX mode either and
+ * die horrible death on reboot.
+ */
+-static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
++static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
+ {
+- /* Fujitsu Lifebook P7010/P7010D */
++ .ident = "Fujitsu Lifebook P7010/P7010D",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
+ },
+ },
+ {
+- /* Fujitsu Lifebook P7010 */
++ .ident = "Fujitsu Lifebook P7010",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
+ },
+ },
+ {
+- /* Fujitsu Lifebook P5020D */
++ .ident = "Fujitsu Lifebook P5020D",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
+ },
+ },
+ {
+- /* Fujitsu Lifebook S2000 */
++ .ident = "Fujitsu Lifebook S2000",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
+ },
+ },
+ {
+- /* Fujitsu Lifebook S6230 */
++ .ident = "Fujitsu Lifebook S6230",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
+ },
+ },
+ {
+- /* Fujitsu T70H */
++ .ident = "Fujitsu T70H",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
+ },
+ },
+ {
+- /* Fujitsu-Siemens Lifebook T3010 */
++ .ident = "Fujitsu-Siemens Lifebook T3010",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
+ },
+ },
+ {
+- /* Fujitsu-Siemens Lifebook E4010 */
++ .ident = "Fujitsu-Siemens Lifebook E4010",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
+ },
+ },
+ {
+- /* Fujitsu-Siemens Amilo Pro 2010 */
++ .ident = "Fujitsu-Siemens Amilo Pro 2010",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
+ },
+ },
+ {
+- /* Fujitsu-Siemens Amilo Pro 2030 */
++ .ident = "Fujitsu-Siemens Amilo Pro 2030",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
+@@ -258,7 +253,7 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
+ * No data is coming from the touchscreen unless KBC
+ * is in legacy mode.
+ */
+- /* Panasonic CF-29 */
++ .ident = "Panasonic CF-29",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
+@@ -266,10 +261,10 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
+ },
+ {
+ /*
+- * HP Pavilion DV4017EA -
+- * errors on MUX ports are reported without raising AUXDATA
++ * Errors on MUX ports are reported without raising AUXDATA
+ * causing "spurious NAK" messages.
+ */
++ .ident = "HP Pavilion DV4017EA",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
+@@ -277,9 +272,9 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
+ },
+ {
+ /*
+- * HP Pavilion ZT1000 -
+- * like DV4017EA does not raise AUXERR for errors on MUX ports.
++ * Like DV4017EA does not raise AUXERR for errors on MUX ports.
+ */
++ .ident = "HP Pavilion ZT1000",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
+@@ -288,41 +283,44 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
+ },
+ {
+ /*
+- * HP Pavilion DV4270ca -
+- * like DV4017EA does not raise AUXERR for errors on MUX ports.
++ * Like DV4017EA does not raise AUXERR for errors on MUX ports.
+ */
++ .ident = "HP Pavilion DV4270ca",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
+ },
+ },
+ {
++ .ident = "Toshiba P10",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
+ },
+ },
+ {
++ .ident = "Toshiba Equium A110",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
+ },
+ },
+ {
++ .ident = "Alienware Sentia",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
+ },
+ },
+ {
+- /* Sharp Actius MM20 */
++ .ident = "Sharp Actius MM20",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
+ },
+ },
+ {
+- /* Sony Vaio FS-115b */
++ .ident = "Sony Vaio FS-115b",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
+@@ -330,72 +328,73 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
+ },
+ {
+ /*
+- * Sony Vaio FZ-240E -
+- * reset and GET ID commands issued via KBD port are
++ * Reset and GET ID commands issued via KBD port are
+ * sometimes being delivered to AUX3.
+ */
++ .ident = "Sony Vaio FZ-240E",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
+ },
+ },
+ {
+- /* Amoi M636/A737 */
++ .ident = "Amoi M636/A737",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
+ },
+ },
+ {
+- /* Lenovo 3000 n100 */
++ .ident = "Lenovo 3000 n100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
+ },
+ },
+ {
++ .ident = "Acer Aspire 1360",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
+ },
+ },
+ {
+- /* Gericom Bellagio */
++ .ident = "Gericom Bellagio",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
+ },
+ },
+ {
+- /* IBM 2656 */
++ .ident = "IBM 2656",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
+ },
+ },
+ {
+- /* Dell XPS M1530 */
++ .ident = "Dell XPS M1530",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
+ },
+ },
+ {
+- /* Compal HEL80I */
++ .ident = "Compal HEL80I",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
+ },
+ },
+ {
+- /* Dell Vostro 1510 */
++ .ident = "Dell Vostro 1510",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
+ },
+ },
+ {
+- /* Acer Aspire 5536 */
++ .ident = "Acer Aspire 5536",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
+@@ -405,65 +404,65 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
+ { }
+ };
+
+-static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
++static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
+ {
+- /* MSI Wind U-100 */
++ .ident = "MSI Wind U-100",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+ DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+ },
+ },
+ {
+- /* LG Electronics X110 */
++ .ident = "LG Electronics X110",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "X110"),
+ DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
+ },
+ },
+ {
+- /* Acer Aspire One 150 */
++ .ident = "Acer Aspire One 150",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+ },
+ },
+ {
+- /* Advent 4211 */
++ .ident = "Advent 4211",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
+ },
+ },
+ {
+- /* Medion Akoya Mini E1210 */
++ .ident = "Medion Akoya Mini E1210",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
+ },
+ },
+ {
+- /* Mivvy M310 */
++ .ident = "Mivvy M310",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
+ },
+ },
+ {
+- /* Dell Vostro 1320 */
++ .ident = "Dell Vostro 1320",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
+ },
+ },
+ {
+- /* Dell Vostro 1520 */
++ .ident = "Dell Vostro 1520",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
+ },
+ },
+ {
+- /* Dell Vostro 1720 */
++ .ident = "Dell Vostro 1720",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
+@@ -473,16 +472,16 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
+ };
+
+ #ifdef CONFIG_PNP
+-static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = {
++static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
+ {
+- /* Intel MBO Desktop D845PESV */
++ .ident = "Intel MBO Desktop D845PESV",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
+ DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+ },
+ },
+ {
+- /* MSI Wind U-100 */
++ .ident = "MSI Wind U-100",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+ DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+@@ -491,23 +490,27 @@ static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = {
+ { }
+ };
+
+-static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
++static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = {
+ {
++ .ident = "Portable",
+ .matches = {
+ DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
+ },
+ },
+ {
++ .ident = "Laptop",
+ .matches = {
+ DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */
+ },
+ },
+ {
++ .ident = "Notebook",
+ .matches = {
+ DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
+ },
+ },
+ {
++ .ident = "Sub-Notebook",
+ .matches = {
+ DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
+ },
+@@ -522,65 +525,58 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
+ * Originally, this was just confined to older laptops, but a few Acer laptops
+ * have turned up in 2007 that also need this again.
+ */
+-static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
+- {
+- /* Acer Aspire 5610 */
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
+- },
+- },
++static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
+ {
+- /* Acer Aspire 5630 */
++ .ident = "Acer Aspire 5630",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
+ },
+ },
+ {
+- /* Acer Aspire 5650 */
++ .ident = "Acer Aspire 5650",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
+ },
+ },
+ {
+- /* Acer Aspire 5680 */
++ .ident = "Acer Aspire 5680",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
+ },
+ },
+ {
+- /* Acer Aspire 5720 */
++ .ident = "Acer Aspire 5720",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
+ },
+ },
+ {
+- /* Acer Aspire 9110 */
++ .ident = "Acer Aspire 9110",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
+ },
+ },
+ {
+- /* Acer TravelMate 660 */
++ .ident = "Acer TravelMate 660",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
+ },
+ },
+ {
+- /* Acer TravelMate 2490 */
++ .ident = "Acer TravelMate 2490",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
+ },
+ },
+ {
+- /* Acer TravelMate 4280 */
++ .ident = "Acer TravelMate 4280",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
+diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
+index 8cc453c..336ca2f 100644
+--- a/drivers/input/touchscreen/Kconfig
++++ b/drivers/input/touchscreen/Kconfig
+@@ -271,6 +271,13 @@ config TOUCHSCREEN_MIGOR
+ To compile this driver as a module, choose M here: the
+ module will be called migor_ts.
+
++config TOUCHSCREEN_TMPA910
++ bool "TMPA910 Touchscreen interface support"
++ depends on ARCH_TMPA910
++ help
++ Say Y here if you have a TMPA910-based board with a touchscreen
++ If unsure, say N.
++
+ config TOUCHSCREEN_TOUCHRIGHT
+ tristate "Touchright serial touchscreen"
+ select SERIO
+diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
+index 15fa62c..a7d8a29 100644
+--- a/drivers/input/touchscreen/Makefile
++++ b/drivers/input/touchscreen/Makefile
+@@ -34,6 +34,7 @@ obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
+ obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o
+ obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
+ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
++obj-$(CONFIG_TOUCHSCREEN_TMPA910) += tmpa910-ts.o
+ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
+ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
+ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
+diff --git a/drivers/input/touchscreen/tmpa910-ts.c b/drivers/input/touchscreen/tmpa910-ts.c
+new file mode 100644
+index 0000000..2832a69
+--- /dev/null
++++ b/drivers/input/touchscreen/tmpa910-ts.c
+@@ -0,0 +1,695 @@
++
++/*
++ * TMPA910 touchscreen driver
++ *
++ * Copyright (c) 2008 bplan GmbH
++ */
++
++/*
++ * 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/errno.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/input.h>
++#include <linux/serio.h>
++#include <linux/init.h>
++#include <linux/workqueue.h>
++
++#include <linux/platform_device.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++
++#include <mach/tmpa910_regs.h>
++#include <mach/ts.h>
++#include <mach/adc.h>
++
++/*******/
++#define DRIVER_DESC "TMPA9x0 touchscreen driver"
++
++MODULE_AUTHOR("bplan GmbH <opensource at bplan-gmbh.de>");
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
++
++/*******/
++
++struct tmpa910_ts_priv
++{
++ struct tmpa910_ts *ts_regs;
++ struct tmpa910_adc *adc_regs;
++ struct input_dev *input_dev;
++ int pen_is_down;
++ int adc_pass;
++ int x;
++ int y;
++ int ts_irq;
++ int adc_irq;
++ int interval;
++ int start_delay;
++ int conv_count;
++ int skip_count;
++ struct workqueue_struct *ts_workq;
++ struct delayed_work scheduled_restart;
++};
++
++/*******/
++
++enum{
++ ADC_PASS_NONE,
++ ADC_PASS_X,
++ ADC_PASS_Y,
++};
++
++#define STARTDELAY_FIRST 5
++#define STARTDELAY_OTHERS 1
++
++static void _start_convertion(struct tmpa910_ts_priv *tmpa910_ts_priv);
++
++/*******/
++/*******/
++static void ts_init(volatile struct tmpa910_ts *ts)
++{
++ ts->tsicr0 = 0x98 & ~TMPA910_TS_CR0_TWIEN ;
++ ts->tsicr1 = 0x95;
++}
++
++
++
++static void ts_end(volatile struct tmpa910_ts *ts)
++{
++ ts->tsicr0 = 0;
++ ts->tsicr1 = 0;
++}
++
++static int ts_pen_is_down(volatile struct tmpa910_ts *ts)
++{
++ return ts->tsicr0 & TMPA910_TS_CR0_PTST ? 1 : 0;
++}
++
++static void _ts_clear_interrupt(void)
++{
++ _out32(PORTD_GPIOIC, _in32(PORTD_GPIOMIS) );
++}
++
++static void _ts_enable_interrupt(volatile struct tmpa910_ts *ts)
++{
++ ts->tsicr0 |= TMPA910_TS_CR0_TWIEN;
++}
++
++static void _ts_disable_interrupt(volatile struct tmpa910_ts *ts)
++{
++ ts->tsicr0 &= ~TMPA910_TS_CR0_TWIEN;
++}
++/*******/
++/*******/
++static void _enable_interrupt(struct tmpa910_ts_priv *tmpa910_ts_priv)
++{
++ struct tmpa910_adc *adc;
++
++ adc = tmpa910_ts_priv->adc_regs;
++
++ _out32(PORTD_GPIOIE, 0xc0);
++ adc->adie = 0x01;
++ _ts_enable_interrupt(tmpa910_ts_priv->ts_regs);
++}
++
++static void _disable_interrupt(struct tmpa910_ts_priv *tmpa910_ts_priv)
++{
++ struct tmpa910_adc *adc;
++
++ adc = tmpa910_ts_priv->adc_regs;
++
++ _out32(PORTD_GPIOIE, 0x00);
++ adc->adie = 0x00;
++
++ _ts_disable_interrupt(tmpa910_ts_priv->ts_regs);
++}
++/*******/
++/*******/
++static void adc_startchannel(struct tmpa910_ts_priv *tmpa910_ts_priv, int chn )
++{
++ volatile struct tmpa910_adc *adc;
++ uint32_t admod1;
++
++ adc = tmpa910_ts_priv->adc_regs;;
++
++ admod1 = adc->admod1;
++ admod1 &= 0xf8;
++ admod1 |= chn & 0x7;
++
++ adc->admod1 = admod1;
++
++ // It seens to be required to obtain aquerate value
++ udelay(tmpa910_ts_priv->start_delay);
++
++ adc->admod0 = 0x1;
++}
++
++/***/
++// X in on AN5
++static int _read_x(volatile struct tmpa910_ts *ts, volatile struct tmpa910_adc *adc )
++{
++ return
++ ( (adc->adreg5l >> 6) & 0x003)
++ | ( (adc->adreg5h << 2) & 0x3FC);
++
++}
++
++// Y in on AN4,
++static int _read_y(volatile struct tmpa910_ts *ts, volatile struct tmpa910_adc *adc )
++{
++ return
++ ( (adc->adreg4l >> 6) & 0x003)
++ | ( (adc->adreg4h << 2) & 0x3FC);
++
++}
++
++/*******/
++/*******/
++static void _update_pendown(struct tmpa910_ts_priv *tmpa910_ts_priv, int pen_is_down)
++{
++ void *input_dev;
++ input_dev = tmpa910_ts_priv->input_dev;
++
++ input_report_key(input_dev, BTN_TOUCH, pen_is_down );
++ input_report_abs(input_dev, ABS_PRESSURE, pen_is_down);
++ input_sync(input_dev);
++
++ tmpa910_ts_priv->pen_is_down = pen_is_down;
++}
++
++static void _update_pos(struct tmpa910_ts_priv *tmpa910_ts_priv)
++{
++ void *input_dev;
++ int skip_count;
++ skip_count = tmpa910_ts_priv->skip_count;
++
++ if ( (skip_count > 0) && (tmpa910_ts_priv->conv_count<skip_count) )
++ {
++ tmpa910_ts_priv->conv_count++;
++ return ;
++ }
++
++ tmpa910_ts_priv->conv_count++;
++
++#if 0
++ // helpful curing development
++ if (ts_pen_is_down(tmpa910_ts_priv->ts_regs) == 0)
++ printk("Warning! Pen not down!\n");
++#endif
++
++ input_dev = tmpa910_ts_priv->input_dev;
++
++ input_report_abs(input_dev, ABS_X, tmpa910_ts_priv->x);
++ input_report_abs(input_dev, ABS_Y, tmpa910_ts_priv->y);
++
++ if (tmpa910_ts_priv->start_delay==STARTDELAY_FIRST)
++ {
++ // for the first time, report the rpeuse as well
++ _update_pendown(tmpa910_ts_priv, 1);
++ tmpa910_ts_priv->start_delay = STARTDELAY_OTHERS;
++ }
++ else
++ {
++ input_sync(input_dev);
++ }
++}
++
++/*******/
++/*******/
++static void _scheduled_restart(struct work_struct *work)
++{
++
++ int pen_is_down;
++ void *input_dev;
++ struct tmpa910_ts_priv *tmpa910_ts_priv = container_of(work, struct tmpa910_ts_priv , scheduled_restart.work);
++
++ input_dev = tmpa910_ts_priv->input_dev;
++
++ pen_is_down = ts_pen_is_down(tmpa910_ts_priv->ts_regs);
++ tmpa910_ts_priv->adc_pass = ADC_PASS_NONE;
++
++ _ts_enable_interrupt(tmpa910_ts_priv->ts_regs);
++
++ if (pen_is_down)
++ {
++ _start_convertion(tmpa910_ts_priv);
++ }
++ else
++ {
++ _update_pendown( tmpa910_ts_priv, pen_is_down);
++ }
++}
++
++static void _start_convertion(struct tmpa910_ts_priv *tmpa910_ts_priv)
++{
++ struct tmpa910_ts *ts;
++ struct tmpa910_adc *adc;
++ int adc_pass;
++ void *input_dev;
++
++ adc = tmpa910_ts_priv->adc_regs;
++ ts = tmpa910_ts_priv->ts_regs;
++
++ if (tmpa910_ts_priv->pen_is_down == 0)
++ {
++ tmpa910_ts_priv->adc_pass = ADC_PASS_NONE;
++
++ // better reamle the ts
++ ts_init(ts);
++ _ts_enable_interrupt(ts);
++
++ return;
++ }
++
++ adc_pass = tmpa910_ts_priv->adc_pass;
++
++ switch(adc_pass)
++ {
++ case ADC_PASS_NONE:
++ // no oconvm start x
++ ts->tsicr0 = 0xc5;
++ adc_startchannel(tmpa910_ts_priv, 5);
++ adc_pass = ADC_PASS_X;
++ break;
++
++ case ADC_PASS_X:
++ // x done, start y
++ ts->tsicr0 = 0xca;
++ adc_startchannel(tmpa910_ts_priv, 4);
++ adc_pass = ADC_PASS_Y;
++ break;
++
++ case ADC_PASS_Y:
++ input_dev = tmpa910_ts_priv->input_dev;
++
++ // Convertion done, report the abs pos and tell input
++ // the pen is down
++ _update_pos(tmpa910_ts_priv);
++
++ // Set status NONE because we are done with this convetion
++ adc_pass = ADC_PASS_NONE;
++
++ // disable, clear interrupts and restrt the ts controller
++ _ts_disable_interrupt(ts);
++ _ts_clear_interrupt();
++ ts_init(ts);
++
++ // Start again pen detection but in a little while
++ queue_delayed_work(tmpa910_ts_priv->ts_workq, &tmpa910_ts_priv->scheduled_restart, tmpa910_ts_priv->interval);
++
++ break;
++
++ }
++
++ tmpa910_ts_priv->adc_pass = adc_pass;
++}
++
++
++/*******/
++/*******/
++static irqreturn_t topas910_ts_interrupt(int irq, void *dev_id)
++{
++ struct tmpa910_ts_priv *tmpa910_ts_priv = (struct tmpa910_ts_priv *)dev_id;
++ struct tmpa910_ts *ts;
++ int pen_is_down;
++
++ ts = tmpa910_ts_priv->ts_regs;
++
++ _ts_clear_interrupt();
++ _ts_disable_interrupt(ts);
++
++ tmpa910_ts_priv->start_delay = STARTDELAY_FIRST;
++ tmpa910_ts_priv->conv_count = 0;
++
++ // so, what happen ?
++ pen_is_down = ts_pen_is_down(ts);
++
++ // report this information to us and to the
++ // input system
++ tmpa910_ts_priv->pen_is_down = pen_is_down;
++
++ // Start the conversion in a little while to give
++ // some time to the hw
++ _start_convertion(tmpa910_ts_priv);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t topas910_adc_interrupt(int irq, void *dev_id)
++{
++ struct tmpa910_ts_priv *tmpa910_ts_priv = (struct tmpa910_ts_priv *)dev_id;
++ struct tmpa910_ts *ts;
++ struct tmpa910_adc *adc;
++ uint32_t onereg;
++
++ adc = tmpa910_ts_priv->adc_regs;
++ ts = tmpa910_ts_priv->ts_regs;
++
++ onereg = adc->admod0;
++ if ( (onereg&0x80) == 0)
++ {
++ printk(KERN_WARNING "Warning! Convertion not finished\n");
++ }
++
++ onereg = adc->adis;
++ if (onereg == 0)
++ {
++ printk(KERN_ERR "Supurious interrupt ? adis=0x%x\n", adc->adis);
++ return IRQ_NONE;
++ }
++
++ adc->adic = onereg;
++
++ switch(tmpa910_ts_priv->adc_pass)
++ {
++ case ADC_PASS_NONE:
++ // strange better renable the ctrl
++ ts_init(ts);
++ _ts_enable_interrupt(ts);
++ break;
++
++ case ADC_PASS_X:
++ // X done, retreive the pos and continue
++ tmpa910_ts_priv->x = _read_x(ts, adc);
++
++ _start_convertion(tmpa910_ts_priv);
++
++ break;
++
++ case ADC_PASS_Y:
++ // Y done, continue the adventure
++ tmpa910_ts_priv->y = _read_y(ts, adc);
++
++ _start_convertion(tmpa910_ts_priv);
++
++ break;
++
++ }
++
++ return IRQ_HANDLED;
++}
++
++static void _free_priv(struct tmpa910_ts_priv *tmpa910_ts_priv)
++{
++ if (tmpa910_ts_priv)
++ {
++ struct tmpa910_adc *adc;
++ struct tmpa910_ts *ts;
++
++ adc = tmpa910_ts_priv->adc_regs;
++ ts = tmpa910_ts_priv->ts_regs;
++
++ if ( ts && adc )
++ _disable_interrupt(tmpa910_ts_priv);
++
++ // NO VRef
++ if (adc)
++ adc->admod1 &= ~0x80;
++
++ if (ts)
++ ts_end(ts);
++
++ if (tmpa910_ts_priv->input_dev)
++ input_free_device(tmpa910_ts_priv->input_dev);
++
++ if (tmpa910_ts_priv->ts_workq)
++ {
++ cancel_delayed_work_sync(&tmpa910_ts_priv->scheduled_restart);
++
++ destroy_workqueue(tmpa910_ts_priv->ts_workq);
++ }
++
++ if (tmpa910_ts_priv->adc_irq != NO_IRQ)
++ free_irq(tmpa910_ts_priv->adc_irq, tmpa910_ts_priv);
++
++ if (tmpa910_ts_priv->ts_irq != NO_IRQ)
++ free_irq(tmpa910_ts_priv->ts_irq, tmpa910_ts_priv);
++
++ kfree(tmpa910_ts_priv);
++ }
++}
++
++static int __init tmpa910_ts_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct tmpa910_ts_priv *tmpa910_ts_priv=NULL;
++ struct input_dev *input_dev = NULL;
++ int err;
++ struct resource *ts_r = NULL;
++ struct resource *adc_r = NULL;
++ int ts_irq;
++ int adc_irq;
++ int ret;
++ int rate;
++ int skip_count;
++ int fuzz;
++ struct tmpa910_adc *adc;
++ struct tmpa910_ts_platforminfo *tmpa910_ts_platforminfo;
++
++ // Ok, first, retrieve some info
++ tmpa910_ts_platforminfo = (struct tmpa910_ts_platforminfo *) dev->platform_data;
++ if (tmpa910_ts_platforminfo) {
++ fuzz = tmpa910_ts_platforminfo->fuzz;
++ rate = tmpa910_ts_platforminfo->rate;
++ skip_count = tmpa910_ts_platforminfo->skip_count;
++ }
++ else {
++ fuzz = TMPA910_TS_DEFAULT_FUZZ;
++ rate = TMPA910_TS_DEFAULT_RATE;
++ skip_count = TMPA910_TS_DEFAULT_SKIP_COUNT;
++ }
++
++ ts_r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!ts_r) {
++ printk(KERN_ERR "resources unusable\n");
++ ret = -ENXIO;
++ return ret;
++ }
++
++ adc_r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ if (!adc_r) {
++ printk(KERN_ERR "resources unusable\n");
++ ret = -ENXIO;
++ return ret;
++ }
++
++ ts_irq = platform_get_irq(pdev, 0);
++ if (ts_irq == NO_IRQ) {
++ printk(KERN_ERR "platform_get_irq 0 failed\n");
++ ret = -ENXIO;
++ return ret;
++ }
++
++ adc_irq = platform_get_irq(pdev, 1);
++ if (adc_irq == NO_IRQ) {
++ printk(KERN_ERR "platform_get_irq 1 failed\n");
++ ret = -ENXIO;
++ return ret;
++ }
++
++ // Now allocate some memory for our private handle
++ tmpa910_ts_priv = kzalloc(sizeof(struct tmpa910_ts_priv), GFP_KERNEL);
++ if (tmpa910_ts_priv==NULL) {
++ err = -ENOMEM;
++ return err;
++ }
++
++ // set the private handle to safe defaults
++ tmpa910_ts_priv->pen_is_down = 0;
++ tmpa910_ts_priv->adc_pass = ADC_PASS_NONE;
++ tmpa910_ts_priv->interval = HZ/rate;
++ tmpa910_ts_priv->adc_irq = NO_IRQ;
++ tmpa910_ts_priv->ts_irq = NO_IRQ;
++ tmpa910_ts_priv->skip_count = skip_count;
++
++ tmpa910_ts_priv->ts_workq = NULL;
++
++ adc = (void *) adc_r->start;
++ tmpa910_ts_priv->adc_regs = adc;
++ tmpa910_ts_priv->ts_regs = (void *) ts_r->start;
++
++ _disable_interrupt(tmpa910_ts_priv);
++
++ // We want an input device
++ input_dev = input_allocate_device();
++ if (!input_dev) {
++ err = -ENOMEM;
++ goto fail;
++ }
++ tmpa910_ts_priv->input_dev = input_dev;
++
++ input_dev->name = DRIVER_DESC;
++ input_dev->phys = (void *) tmpa910_ts_priv->ts_regs;
++ input_dev->id.bustype = BUS_HOST;
++ input_dev->id.vendor = 0;
++ input_dev->id.product = 0;
++ input_dev->id.version = 0x0100;
++ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
++ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
++
++ // Create our work queue
++ tmpa910_ts_priv->ts_workq = create_singlethread_workqueue("tmpa910_ts");
++ if (tmpa910_ts_priv->ts_workq == NULL) {
++ printk(KERN_ERR "Failed to create workqueue\n");
++ err = -ENOMEM;
++ goto fail;
++ }
++
++ INIT_DELAYED_WORK(&tmpa910_ts_priv->scheduled_restart, _scheduled_restart);
++
++ // Our irqs...
++ ret = request_irq(ts_irq, topas910_ts_interrupt, IRQF_SHARED, "ts / ts", tmpa910_ts_priv);
++ if (ret) {
++ printk(KERN_ERR "Fail allocate the interrupt (vector=%d), %i\n", ts_irq, ret );
++ err = -ENOMEM;
++ goto fail;
++ }
++ tmpa910_ts_priv->ts_irq = ts_irq;
++
++ ret = request_irq(adc_irq, topas910_adc_interrupt, IRQF_SHARED, "ts / adc", tmpa910_ts_priv);
++ if (ret) {
++ printk(KERN_ERR "Fail allocate the interrupt (vector=%d)\n", adc_irq );
++ err = -ENOMEM;
++ goto fail;
++ }
++ tmpa910_ts_priv->adc_irq = adc_irq;
++
++
++ // Now setup a bit our input device
++ // TMPA910 ADC is 10bit
++ input_set_abs_params(input_dev, ABS_X, 0, 1024, fuzz, 0);
++ input_set_abs_params(input_dev, ABS_Y, 0, 1024, fuzz, 0);
++
++ // touched or not -> 1 or 0
++ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0);
++ err = input_register_device(tmpa910_ts_priv->input_dev);
++ if (err) {
++ printk(KERN_ERR "input_register_device failed (err=%d)\n", err );
++ goto fail;
++ }
++
++ // Let's start quiet
++ input_report_abs(input_dev, ABS_PRESSURE, 0);
++ input_report_key(input_dev, BTN_TOUCH, 0);
++ input_sync(input_dev);
++
++ printk(KERN_INFO DRIVER_DESC " (fuzz=%d, rate=%d Hz, skip=%d) ready\n",
++ fuzz, rate, tmpa910_ts_priv->skip_count);
++
++ dev_set_drvdata(dev, tmpa910_ts_priv);
++ ts_init(tmpa910_ts_priv->ts_regs);
++
++#if 0
++ // Hum, if I reset the ADC, it does nto work any more at all!
++ tmpa910_ts_priv->adc_regs->admod4 = 0x2;
++ udelay(100);
++ tmpa910_ts_priv->adc_regs->admod4 = 0x1;
++ udelay(100);
++#endif
++
++ // clock un VREF
++ adc->adclk = 0x2;
++ adc->admod1 |= 0x80;
++
++ _enable_interrupt(tmpa910_ts_priv);
++
++ return 0;
++
++
++ fail:
++
++ _free_priv (tmpa910_ts_priv);
++
++ return err;
++
++
++}
++
++static int __exit tmpa910_ts_remove(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct tmpa910_ts_priv *tmpa910_ts_priv;
++
++ tmpa910_ts_priv = (struct tmpa910_ts_priv *) dev_get_drvdata(dev);
++
++ _free_priv(tmpa910_ts_priv);
++
++ dev_set_drvdata(dev, NULL);
++
++ return 0;
++}
++
++
++#ifdef CONFIG_PM
++
++static int tmpa910_ts_suspend(struct platform_device *pdev, pm_message_t mesg)
++{
++ struct device *dev = &pdev->dev;
++ struct tmpa910_ts_priv *tmpa910_ts_priv;
++ struct tmpa910_adc *adc;
++
++ tmpa910_ts_priv = (struct tmpa910_ts_priv *) dev_get_drvdata(dev);
++ adc = tmpa910_ts_priv->adc_regs;
++
++ adc->admod1 &= ~0x80;
++
++ return 0;
++}
++
++static int tmpa910_ts_resume(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct tmpa910_ts_priv *tmpa910_ts_priv;
++ struct tmpa910_adc *adc;
++
++ tmpa910_ts_priv = (struct tmpa910_ts_priv *) dev_get_drvdata(dev);
++ adc = tmpa910_ts_priv->adc_regs;
++
++ adc->admod1 |= 0x80;
++
++ return 0;
++}
++
++#else
++#define tmpa910_ts_suspend NULL
++#define tmpa910_ts_resume NULL
++#endif
++
++static struct platform_driver tmpa910_ts_driver = {
++ .remove = __exit_p(tmpa910_lcdc_remove),
++ .suspend = tmpa910_ts_suspend,
++ .resume = tmpa910_ts_resume,
++
++ .driver = {
++ .name = "tmpa910_ts",
++ .owner = THIS_MODULE,
++ },
++};
++
++/*
++ * The functions for inserting/removing us as a module.
++ */
++
++
++static int __init tmpa910_ts_init(void)
++{
++ return platform_driver_probe(&tmpa910_ts_driver, tmpa910_ts_probe);
++}
++
++static void __exit tmpa910_ts_exit(void)
++{
++ platform_driver_unregister(&tmpa910_ts_driver);
++}
++
++module_init(tmpa910_ts_init);
++module_exit(tmpa910_ts_exit);
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
+index ede4658..951c57b 100644
+--- a/drivers/lguest/segments.c
++++ b/drivers/lguest/segments.c
+@@ -179,10 +179,8 @@ void load_guest_gdt_entry(struct lg_cpu *cpu, u32 num, u32 lo, u32 hi)
+ * We assume the Guest has the same number of GDT entries as the
+ * Host, otherwise we'd have to dynamically allocate the Guest GDT.
+ */
+- if (num >= ARRAY_SIZE(cpu->arch.gdt)) {
++ if (num >= ARRAY_SIZE(cpu->arch.gdt))
+ kill_guest(cpu, "too many gdt entries %i", num);
+- return;
+- }
+
+ /* Set it up, then fix it. */
+ cpu->arch.gdt[num].a = lo;
+diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
+index 386a797..556f0fe 100644
+--- a/drivers/macintosh/therm_adt746x.c
++++ b/drivers/macintosh/therm_adt746x.c
+@@ -79,7 +79,6 @@ struct thermostat {
+ u8 limits[3];
+ int last_speed[2];
+ int last_var[2];
+- int pwm_inv[2];
+ };
+
+ static enum {ADT7460, ADT7467} therm_type;
+@@ -230,23 +229,19 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
+
+ if (speed >= 0) {
+ manual = read_reg(th, MANUAL_MODE[fan]);
+- manual &= ~INVERT_MASK;
+ write_reg(th, MANUAL_MODE[fan],
+- manual | MANUAL_MASK | th->pwm_inv[fan]);
++ (manual|MANUAL_MASK) & (~INVERT_MASK));
+ write_reg(th, FAN_SPD_SET[fan], speed);
+ } else {
+ /* back to automatic */
+ if(therm_type == ADT7460) {
+ manual = read_reg(th,
+ MANUAL_MODE[fan]) & (~MANUAL_MASK);
+- manual &= ~INVERT_MASK;
+- manual |= th->pwm_inv[fan];
++
+ write_reg(th,
+ MANUAL_MODE[fan], manual|REM_CONTROL[fan]);
+ } else {
+ manual = read_reg(th, MANUAL_MODE[fan]);
+- manual &= ~INVERT_MASK;
+- manual |= th->pwm_inv[fan];
+ write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK));
+ }
+ }
+@@ -423,10 +418,6 @@ static int probe_thermostat(struct i2c_client *client,
+
+ thermostat = th;
+
+- /* record invert bit status because fw can corrupt it after suspend */
+- th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
+- th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;
+-
+ /* be sure to really write fan speed the first time */
+ th->last_speed[0] = -2;
+ th->last_speed[1] = -2;
+diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
+index 6c68b9e..961fa0e 100644
+--- a/drivers/macintosh/windfarm_smu_controls.c
++++ b/drivers/macintosh/windfarm_smu_controls.c
+@@ -202,8 +202,6 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
+ fct->ctrl.name = "cpu-front-fan-1";
+ else if (!strcmp(l, "CPU A PUMP"))
+ fct->ctrl.name = "cpu-pump-0";
+- else if (!strcmp(l, "CPU B PUMP"))
+- fct->ctrl.name = "cpu-pump-1";
+ else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") ||
+ !strcmp(l, "EXPANSION SLOTS INTAKE"))
+ fct->ctrl.name = "slots-fan";
+diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
+index a5e5f2f..60e2b32 100644
+--- a/drivers/md/bitmap.c
++++ b/drivers/md/bitmap.c
+@@ -1078,31 +1078,23 @@ static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
+ * out to disk
+ */
+
+-void bitmap_daemon_work(mddev_t *mddev)
++void bitmap_daemon_work(struct bitmap *bitmap)
+ {
+- struct bitmap *bitmap;
+ unsigned long j;
+ unsigned long flags;
+ struct page *page = NULL, *lastpage = NULL;
+ int blocks;
+ void *paddr;
+
+- /* Use a mutex to guard daemon_work against
+- * bitmap_destroy.
+- */
+- mutex_lock(&mddev->bitmap_mutex);
+- bitmap = mddev->bitmap;
+- if (bitmap == NULL) {
+- mutex_unlock(&mddev->bitmap_mutex);
++ if (bitmap == NULL)
+ return;
+- }
+ if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ))
+ goto done;
+
+ bitmap->daemon_lastrun = jiffies;
+ if (bitmap->allclean) {
+ bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
+- goto done;
++ return;
+ }
+ bitmap->allclean = 1;
+
+@@ -1211,7 +1203,6 @@ void bitmap_daemon_work(mddev_t *mddev)
+ done:
+ if (bitmap->allclean == 0)
+ bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ;
+- mutex_unlock(&mddev->bitmap_mutex);
+ }
+
+ static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
+@@ -1550,9 +1541,9 @@ void bitmap_flush(mddev_t *mddev)
+ */
+ sleep = bitmap->daemon_sleep;
+ bitmap->daemon_sleep = 0;
+- bitmap_daemon_work(mddev);
+- bitmap_daemon_work(mddev);
+- bitmap_daemon_work(mddev);
++ bitmap_daemon_work(bitmap);
++ bitmap_daemon_work(bitmap);
++ bitmap_daemon_work(bitmap);
+ bitmap->daemon_sleep = sleep;
+ bitmap_update_sb(bitmap);
+ }
+@@ -1583,7 +1574,6 @@ static void bitmap_free(struct bitmap *bitmap)
+ kfree(bp);
+ kfree(bitmap);
+ }
+-
+ void bitmap_destroy(mddev_t *mddev)
+ {
+ struct bitmap *bitmap = mddev->bitmap;
+@@ -1591,9 +1581,7 @@ void bitmap_destroy(mddev_t *mddev)
+ if (!bitmap) /* there was no bitmap */
+ return;
+
+- mutex_lock(&mddev->bitmap_mutex);
+ mddev->bitmap = NULL; /* disconnect from the md device */
+- mutex_unlock(&mddev->bitmap_mutex);
+ if (mddev->thread)
+ mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
+
+diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h
+index 7e38d13..e989006 100644
+--- a/drivers/md/bitmap.h
++++ b/drivers/md/bitmap.h
+@@ -282,7 +282,7 @@ void bitmap_close_sync(struct bitmap *bitmap);
+ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector);
+
+ void bitmap_unplug(struct bitmap *bitmap);
+-void bitmap_daemon_work(mddev_t *mddev);
++void bitmap_daemon_work(struct bitmap *bitmap);
+ #endif
+
+ #endif
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index 959d6d1..ed10381 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -1,7 +1,7 @@
+ /*
+ * Copyright (C) 2003 Christophe Saout <christophe at saout.de>
+ * Copyright (C) 2004 Clemens Fruhwirth <clemens at endorphin.org>
+- * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved.
++ * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+@@ -71,21 +71,10 @@ struct crypt_iv_operations {
+ int (*ctr)(struct crypt_config *cc, struct dm_target *ti,
+ const char *opts);
+ void (*dtr)(struct crypt_config *cc);
+- int (*init)(struct crypt_config *cc);
+- int (*wipe)(struct crypt_config *cc);
++ const char *(*status)(struct crypt_config *cc);
+ int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector);
+ };
+
+-struct iv_essiv_private {
+- struct crypto_cipher *tfm;
+- struct crypto_hash *hash_tfm;
+- u8 *salt;
+-};
+-
+-struct iv_benbi_private {
+- int shift;
+-};
+-
+ /*
+ * Crypt: maps a linear range of a block device
+ * and encrypts / decrypts at the same time.
+@@ -113,8 +102,8 @@ struct crypt_config {
+ struct crypt_iv_operations *iv_gen_ops;
+ char *iv_mode;
+ union {
+- struct iv_essiv_private essiv;
+- struct iv_benbi_private benbi;
++ struct crypto_cipher *essiv_tfm;
++ int benbi_shift;
+ } iv_gen_private;
+ sector_t iv_offset;
+ unsigned int iv_size;
+@@ -180,114 +169,88 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
+ return 0;
+ }
+
+-/* Initialise ESSIV - compute salt but no local memory allocations */
+-static int crypt_iv_essiv_init(struct crypt_config *cc)
+-{
+- struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
+- struct hash_desc desc;
+- struct scatterlist sg;
+- int err;
+-
+- sg_init_one(&sg, cc->key, cc->key_size);
+- desc.tfm = essiv->hash_tfm;
+- desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+-
+- err = crypto_hash_digest(&desc, &sg, cc->key_size, essiv->salt);
+- if (err)
+- return err;
+-
+- return crypto_cipher_setkey(essiv->tfm, essiv->salt,
+- crypto_hash_digestsize(essiv->hash_tfm));
+-}
+-
+-/* Wipe salt and reset key derived from volume key */
+-static int crypt_iv_essiv_wipe(struct crypt_config *cc)
+-{
+- struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
+- unsigned salt_size = crypto_hash_digestsize(essiv->hash_tfm);
+-
+- memset(essiv->salt, 0, salt_size);
+-
+- return crypto_cipher_setkey(essiv->tfm, essiv->salt, salt_size);
+-}
+-
+-static void crypt_iv_essiv_dtr(struct crypt_config *cc)
+-{
+- struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
+-
+- crypto_free_cipher(essiv->tfm);
+- essiv->tfm = NULL;
+-
+- crypto_free_hash(essiv->hash_tfm);
+- essiv->hash_tfm = NULL;
+-
+- kzfree(essiv->salt);
+- essiv->salt = NULL;
+-}
+-
+ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
+ const char *opts)
+ {
+- struct crypto_cipher *essiv_tfm = NULL;
+- struct crypto_hash *hash_tfm = NULL;
+- u8 *salt = NULL;
++ struct crypto_cipher *essiv_tfm;
++ struct crypto_hash *hash_tfm;
++ struct hash_desc desc;
++ struct scatterlist sg;
++ unsigned int saltsize;
++ u8 *salt;
+ int err;
+
+- if (!opts) {
++ if (opts == NULL) {
+ ti->error = "Digest algorithm missing for ESSIV mode";
+ return -EINVAL;
+ }
+
+- /* Allocate hash algorithm */
++ /* Hash the cipher key with the given hash algorithm */
+ hash_tfm = crypto_alloc_hash(opts, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(hash_tfm)) {
+ ti->error = "Error initializing ESSIV hash";
+- err = PTR_ERR(hash_tfm);
+- goto bad;
++ return PTR_ERR(hash_tfm);
+ }
+
+- salt = kzalloc(crypto_hash_digestsize(hash_tfm), GFP_KERNEL);
+- if (!salt) {
++ saltsize = crypto_hash_digestsize(hash_tfm);
++ salt = kmalloc(saltsize, GFP_KERNEL);
++ if (salt == NULL) {
+ ti->error = "Error kmallocing salt storage in ESSIV";
+- err = -ENOMEM;
+- goto bad;
++ crypto_free_hash(hash_tfm);
++ return -ENOMEM;
+ }
+
+- /* Allocate essiv_tfm */
++ sg_init_one(&sg, cc->key, cc->key_size);
++ desc.tfm = hash_tfm;
++ desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
++ err = crypto_hash_digest(&desc, &sg, cc->key_size, salt);
++ crypto_free_hash(hash_tfm);
++
++ if (err) {
++ ti->error = "Error calculating hash in ESSIV";
++ kfree(salt);
++ return err;
++ }
++
++ /* Setup the essiv_tfm with the given salt */
+ essiv_tfm = crypto_alloc_cipher(cc->cipher, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(essiv_tfm)) {
+ ti->error = "Error allocating crypto tfm for ESSIV";
+- err = PTR_ERR(essiv_tfm);
+- goto bad;
++ kfree(salt);
++ return PTR_ERR(essiv_tfm);
+ }
+ if (crypto_cipher_blocksize(essiv_tfm) !=
+ crypto_ablkcipher_ivsize(cc->tfm)) {
+ ti->error = "Block size of ESSIV cipher does "
+ "not match IV size of block cipher";
+- err = -EINVAL;
+- goto bad;
++ crypto_free_cipher(essiv_tfm);
++ kfree(salt);
++ return -EINVAL;
+ }
++ err = crypto_cipher_setkey(essiv_tfm, salt, saltsize);
++ if (err) {
++ ti->error = "Failed to set key for ESSIV cipher";
++ crypto_free_cipher(essiv_tfm);
++ kfree(salt);
++ return err;
++ }
++ kfree(salt);
+
+- cc->iv_gen_private.essiv.salt = salt;
+- cc->iv_gen_private.essiv.tfm = essiv_tfm;
+- cc->iv_gen_private.essiv.hash_tfm = hash_tfm;
+-
++ cc->iv_gen_private.essiv_tfm = essiv_tfm;
+ return 0;
++}
+
+-bad:
+- if (essiv_tfm && !IS_ERR(essiv_tfm))
+- crypto_free_cipher(essiv_tfm);
+- if (hash_tfm && !IS_ERR(hash_tfm))
+- crypto_free_hash(hash_tfm);
+- kfree(salt);
+- return err;
++static void crypt_iv_essiv_dtr(struct crypt_config *cc)
++{
++ crypto_free_cipher(cc->iv_gen_private.essiv_tfm);
++ cc->iv_gen_private.essiv_tfm = NULL;
+ }
+
+ static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
+ {
+ memset(iv, 0, cc->iv_size);
+ *(u64 *)iv = cpu_to_le64(sector);
+- crypto_cipher_encrypt_one(cc->iv_gen_private.essiv.tfm, iv, iv);
++ crypto_cipher_encrypt_one(cc->iv_gen_private.essiv_tfm, iv, iv);
+ return 0;
+ }
+
+@@ -310,7 +273,7 @@ static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti,
+ return -EINVAL;
+ }
+
+- cc->iv_gen_private.benbi.shift = 9 - log;
++ cc->iv_gen_private.benbi_shift = 9 - log;
+
+ return 0;
+ }
+@@ -325,7 +288,7 @@ static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
+
+ memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */
+
+- val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi.shift) + 1);
++ val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi_shift) + 1);
+ put_unaligned(val, (__be64 *)(iv + cc->iv_size - sizeof(u64)));
+
+ return 0;
+@@ -345,8 +308,6 @@ static struct crypt_iv_operations crypt_iv_plain_ops = {
+ static struct crypt_iv_operations crypt_iv_essiv_ops = {
+ .ctr = crypt_iv_essiv_ctr,
+ .dtr = crypt_iv_essiv_dtr,
+- .init = crypt_iv_essiv_init,
+- .wipe = crypt_iv_essiv_wipe,
+ .generator = crypt_iv_essiv_gen
+ };
+
+@@ -1078,12 +1039,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0)
+ goto bad_ivmode;
+
+- if (cc->iv_gen_ops && cc->iv_gen_ops->init &&
+- cc->iv_gen_ops->init(cc) < 0) {
+- ti->error = "Error initialising IV";
+- goto bad_slab_pool;
+- }
+-
+ cc->iv_size = crypto_ablkcipher_ivsize(tfm);
+ if (cc->iv_size)
+ /* at least a 64 bit sector number should fit in our buffer */
+@@ -1323,7 +1278,6 @@ static void crypt_resume(struct dm_target *ti)
+ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
+ {
+ struct crypt_config *cc = ti->private;
+- int ret = -EINVAL;
+
+ if (argc < 2)
+ goto error;
+@@ -1333,22 +1287,10 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
+ DMWARN("not suspended during key manipulation.");
+ return -EINVAL;
+ }
+- if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) {
+- ret = crypt_set_key(cc, argv[2]);
+- if (ret)
+- return ret;
+- if (cc->iv_gen_ops && cc->iv_gen_ops->init)
+- ret = cc->iv_gen_ops->init(cc);
+- return ret;
+- }
+- if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) {
+- if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) {
+- ret = cc->iv_gen_ops->wipe(cc);
+- if (ret)
+- return ret;
+- }
++ if (argc == 3 && !strnicmp(argv[1], MESG_STR("set")))
++ return crypt_set_key(cc, argv[2]);
++ if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe")))
+ return crypt_wipe_key(cc);
+- }
+ }
+
+ error:
+diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
+index 2052159..7dbe652 100644
+--- a/drivers/md/dm-exception-store.c
++++ b/drivers/md/dm-exception-store.c
+@@ -216,8 +216,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ type = get_type("N");
+ else {
+ ti->error = "Persistent flag is not P or N";
+- r = -EINVAL;
+- goto bad_type;
++ return -EINVAL;
+ }
+
+ if (!type) {
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index d19854c..a679429 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -56,11 +56,6 @@ static void dm_hash_remove_all(int keep_open_devices);
+ */
+ static DECLARE_RWSEM(_hash_lock);
+
+-/*
+- * Protects use of mdptr to obtain hash cell name and uuid from mapped device.
+- */
+-static DEFINE_MUTEX(dm_hash_cells_mutex);
+-
+ static void init_buckets(struct list_head *buckets)
+ {
+ unsigned int i;
+@@ -211,9 +206,7 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi
+ list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
+ }
+ dm_get(md);
+- mutex_lock(&dm_hash_cells_mutex);
+ dm_set_mdptr(md, cell);
+- mutex_unlock(&dm_hash_cells_mutex);
+ up_write(&_hash_lock);
+
+ return 0;
+@@ -231,9 +224,7 @@ static void __hash_remove(struct hash_cell *hc)
+ /* remove from the dev hash */
+ list_del(&hc->uuid_list);
+ list_del(&hc->name_list);
+- mutex_lock(&dm_hash_cells_mutex);
+ dm_set_mdptr(hc->md, NULL);
+- mutex_unlock(&dm_hash_cells_mutex);
+
+ table = dm_get_table(hc->md);
+ if (table) {
+@@ -330,9 +321,7 @@ static int dm_hash_rename(uint32_t cookie, const char *old, const char *new)
+ */
+ list_del(&hc->name_list);
+ old_name = hc->name;
+- mutex_lock(&dm_hash_cells_mutex);
+ hc->name = new_name;
+- mutex_unlock(&dm_hash_cells_mutex);
+ list_add(&hc->name_list, _name_buckets + hash_str(new_name));
+
+ /*
+@@ -1593,7 +1582,8 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid)
+ if (!md)
+ return -ENXIO;
+
+- mutex_lock(&dm_hash_cells_mutex);
++ dm_get(md);
++ down_read(&_hash_lock);
+ hc = dm_get_mdptr(md);
+ if (!hc || hc->md != md) {
+ r = -ENXIO;
+@@ -1606,7 +1596,8 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid)
+ strcpy(uuid, hc->uuid ? : "");
+
+ out:
+- mutex_unlock(&dm_hash_cells_mutex);
++ up_read(&_hash_lock);
++ dm_put(md);
+
+ return r;
+ }
+diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
+index f1c8cae..54abf9e 100644
+--- a/drivers/md/dm-log-userspace-transfer.c
++++ b/drivers/md/dm-log-userspace-transfer.c
+@@ -172,15 +172,11 @@ int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type,
+ {
+ int r = 0;
+ size_t dummy = 0;
+- int overhead_size = sizeof(struct dm_ulog_request) + sizeof(struct cn_msg);
++ int overhead_size =
++ sizeof(struct dm_ulog_request *) + sizeof(struct cn_msg);
+ struct dm_ulog_request *tfr = prealloced_ulog_tfr;
+ struct receiving_pkg pkg;
+
+- /*
+- * Given the space needed to hold the 'struct cn_msg' and
+- * 'struct dm_ulog_request' - do we have enough payload
+- * space remaining?
+- */
+ if (data_size > (DM_ULOG_PREALLOCED_SIZE - overhead_size)) {
+ DMINFO("Size of tfr exceeds preallocated size");
+ return -EINVAL;
+@@ -195,7 +191,7 @@ resend:
+ */
+ mutex_lock(&dm_ulog_lock);
+
+- memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - sizeof(struct cn_msg));
++ memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size);
+ memcpy(tfr->uuid, uuid, DM_UUID_LEN);
+ tfr->luid = luid;
+ tfr->seq = dm_ulog_seq++;
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index 8a4a9c8..3a3ba46 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -553,8 +553,6 @@ static int init_hash_tables(struct dm_snapshot *s)
+ hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
+ hash_size = min(hash_size, max_buckets);
+
+- if (hash_size < 64)
+- hash_size = 64;
+ hash_size = rounddown_pow_of_two(hash_size);
+ if (init_exception_table(&s->complete, hash_size,
+ DM_CHUNK_CONSECUTIVE_BITS))
+@@ -1154,11 +1152,10 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
+ unsigned sz = 0;
+ struct dm_snapshot *snap = ti->private;
+
++ down_write(&snap->lock);
++
+ switch (type) {
+ case STATUSTYPE_INFO:
+-
+- down_write(&snap->lock);
+-
+ if (!snap->valid)
+ DMEMIT("Invalid");
+ else {
+@@ -1174,9 +1171,6 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
+ else
+ DMEMIT("Unknown");
+ }
+-
+- up_write(&snap->lock);
+-
+ break;
+
+ case STATUSTYPE_TABLE:
+@@ -1191,6 +1185,8 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
+ break;
+ }
+
++ up_write(&snap->lock);
++
+ return 0;
+ }
+
+diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
+index bd58703..e0efc1a 100644
+--- a/drivers/md/dm-stripe.c
++++ b/drivers/md/dm-stripe.c
+@@ -110,7 +110,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ }
+
+ stripes = simple_strtoul(argv[0], &end, 10);
+- if (!stripes || *end) {
++ if (*end) {
+ ti->error = "Invalid stripe count";
+ return -EINVAL;
+ }
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index e869128..1a6cb3c 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -499,15 +499,16 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
+ return 0;
+ }
+
+- if (bdev_stack_limits(limits, bdev, start) < 0)
+- DMWARN("%s: adding target device %s caused an alignment inconsistency: "
++ if (blk_stack_limits(limits, &q->limits, start << 9) < 0)
++ DMWARN("%s: target device %s is misaligned: "
+ "physical_block_size=%u, logical_block_size=%u, "
+ "alignment_offset=%u, start=%llu",
+ dm_device_name(ti->table->md), bdevname(bdev, b),
+ q->limits.physical_block_size,
+ q->limits.logical_block_size,
+ q->limits.alignment_offset,
+- (unsigned long long) start << SECTOR_SHIFT);
++ (unsigned long long) start << 9);
++
+
+ /*
+ * Check if merge fn is supported.
+@@ -1024,9 +1025,9 @@ combine_limits:
+ * for the table.
+ */
+ if (blk_stack_limits(limits, &ti_limits, 0) < 0)
+- DMWARN("%s: adding target device "
++ DMWARN("%s: target device "
+ "(start sect %llu len %llu) "
+- "caused an alignment inconsistency",
++ "is misaligned",
+ dm_device_name(table->md),
+ (unsigned long long) ti->begin,
+ (unsigned long long) ti->len);
+@@ -1078,6 +1079,15 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
+ struct queue_limits *limits)
+ {
+ /*
++ * Each target device in the table has a data area that should normally
++ * be aligned such that the DM device's alignment_offset is 0.
++ * FIXME: Propagate alignment_offsets up the stack and warn of
++ * sub-optimal or inconsistent settings.
++ */
++ limits->alignment_offset = 0;
++ limits->misaligned = 0;
++
++ /*
+ * Copy table's limits to the DM device's request_queue
+ */
+ q->limits = *limits;
+diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c
+index c7c555a..6f65883 100644
+--- a/drivers/md/dm-uevent.c
++++ b/drivers/md/dm-uevent.c
+@@ -139,13 +139,14 @@ void dm_send_uevents(struct list_head *events, struct kobject *kobj)
+ list_del_init(&event->elist);
+
+ /*
+- * When a device is being removed this copy fails and we
+- * discard these unsent events.
++ * Need to call dm_copy_name_and_uuid from here for now.
++ * Context of previous var adds and locking used for
++ * hash_cell not compatable.
+ */
+ if (dm_copy_name_and_uuid(event->md, event->name,
+ event->uuid)) {
+- DMINFO("%s: skipping sending uevent for lost device",
+- __func__);
++ DMERR("%s: dm_copy_name_and_uuid() failed",
++ __func__);
+ goto uevent_free;
+ }
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 08f7471..b182f86 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -282,9 +282,7 @@ static void mddev_put(mddev_t *mddev)
+ if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
+ return;
+ if (!mddev->raid_disks && list_empty(&mddev->disks) &&
+- mddev->ctime == 0 && !mddev->hold_active) {
+- /* Array is not configured at all, and not held active,
+- * so destroy it */
++ !mddev->hold_active) {
+ list_del(&mddev->all_mddevs);
+ if (mddev->gendisk) {
+ /* we did a probe so need to clean up.
+@@ -369,7 +367,6 @@ static mddev_t * mddev_find(dev_t unit)
+
+ mutex_init(&new->open_mutex);
+ mutex_init(&new->reconfig_mutex);
+- mutex_init(&new->bitmap_mutex);
+ INIT_LIST_HEAD(&new->disks);
+ INIT_LIST_HEAD(&new->all_mddevs);
+ init_timer(&new->safemode_timer);
+@@ -4173,7 +4170,7 @@ static int do_md_run(mddev_t * mddev)
+ mddev->barriers_work = 1;
+ mddev->ok_start_degraded = start_dirty_degraded;
+
+- if (start_readonly && mddev->ro == 0)
++ if (start_readonly)
+ mddev->ro = 2; /* read-only, but switch on first write */
+
+ err = mddev->pers->run(mddev);
+@@ -5073,10 +5070,6 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
+ mddev->minor_version = info->minor_version;
+ mddev->patch_version = info->patch_version;
+ mddev->persistent = !info->not_persistent;
+- /* ensure mddev_put doesn't delete this now that there
+- * is some minimal configuration.
+- */
+- mddev->ctime = get_seconds();
+ return 0;
+ }
+ mddev->major_version = MD_MAJOR_VERSION;
+@@ -6636,7 +6629,7 @@ void md_check_recovery(mddev_t *mddev)
+
+
+ if (mddev->bitmap)
+- bitmap_daemon_work(mddev);
++ bitmap_daemon_work(mddev->bitmap);
+
+ if (mddev->ro)
+ return;
+diff --git a/drivers/md/md.h b/drivers/md/md.h
+index 87430fe..f184b69 100644
+--- a/drivers/md/md.h
++++ b/drivers/md/md.h
+@@ -289,7 +289,6 @@ struct mddev_s
+ * hot-adding a bitmap. It should
+ * eventually be settable by sysfs.
+ */
+- struct mutex bitmap_mutex;
+
+ struct list_head all_mddevs;
+ };
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index 431b9b2..d29215d 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -5432,11 +5432,11 @@ static int raid5_start_reshape(mddev_t *mddev)
+ !test_bit(Faulty, &rdev->flags)) {
+ if (raid5_add_disk(mddev, rdev) == 0) {
+ char nm[20];
+- if (rdev->raid_disk >= conf->previous_raid_disks) {
++ if (rdev->raid_disk >= conf->previous_raid_disks)
+ set_bit(In_sync, &rdev->flags);
+- added_devices++;
+- } else
++ else
+ rdev->recovery_offset = 0;
++ added_devices++;
+ sprintf(nm, "rd%d", rdev->raid_disk);
+ if (sysfs_create_link(&mddev->kobj,
+ &rdev->kobj, nm))
+@@ -5448,12 +5448,9 @@ static int raid5_start_reshape(mddev_t *mddev)
+ break;
+ }
+
+- /* When a reshape changes the number of devices, ->degraded
+- * is measured against the large of the pre and post number of
+- * devices.*/
+ if (mddev->delta_disks > 0) {
+ spin_lock_irqsave(&conf->device_lock, flags);
+- mddev->degraded += (conf->raid_disks - conf->previous_raid_disks)
++ mddev->degraded = (conf->raid_disks - conf->previous_raid_disks)
+ - added_devices;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+ }
+diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
+index 7eb1bf7..2d02698 100644
+--- a/drivers/media/common/tuners/mxl5007t.c
++++ b/drivers/media/common/tuners/mxl5007t.c
+@@ -196,7 +196,7 @@ static void copy_reg_bits(struct reg_pair_t *reg_pair1,
+ i = j = 0;
+
+ while (reg_pair1[i].reg || reg_pair1[i].val) {
+- while (reg_pair2[j].reg || reg_pair2[j].val) {
++ while (reg_pair2[j].reg || reg_pair2[j].reg) {
+ if (reg_pair1[i].reg != reg_pair2[j].reg) {
+ j++;
+ continue;
+diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
+index 9ddc579..c37790a 100644
+--- a/drivers/media/dvb/dvb-core/dmxdev.c
++++ b/drivers/media/dvb/dvb-core/dmxdev.c
+@@ -761,6 +761,7 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
+ dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
+ dmxdevfilter->type = DMXDEV_TYPE_NONE;
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
++ INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
+ init_timer(&dmxdevfilter->timer);
+
+ dvbdev->users++;
+@@ -886,7 +887,6 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
+ dmxdevfilter->type = DMXDEV_TYPE_PES;
+ memcpy(&dmxdevfilter->params, params,
+ sizeof(struct dmx_pes_filter_params));
+- INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
+
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
+
+diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
+index 6b03dbf..8f88a58 100644
+--- a/drivers/media/dvb/siano/smsusb.c
++++ b/drivers/media/dvb/siano/smsusb.c
+@@ -533,18 +533,8 @@ struct usb_device_id smsusb_id_table[] = {
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0xb910),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+- { USB_DEVICE(0x2040, 0xb980),
+- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+- { USB_DEVICE(0x2040, 0xb990),
+- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0xc000),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+- { USB_DEVICE(0x2040, 0xc010),
+- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+- { USB_DEVICE(0x2040, 0xc080),
+- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+- { USB_DEVICE(0x2040, 0xc090),
+- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { } /* Terminating entry */
+ };
+
+diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
+index e165578..a5c190e 100644
+--- a/drivers/media/video/gspca/ov519.c
++++ b/drivers/media/video/gspca/ov519.c
+@@ -3364,7 +3364,6 @@ static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
+ {USB_DEVICE(0x041e, 0x4064),
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+- {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
+ {USB_DEVICE(0x041e, 0x4068),
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
+diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
+index e0a3b75..cdad3db 100644
+--- a/drivers/media/video/gspca/sn9c20x.c
++++ b/drivers/media/video/gspca/sn9c20x.c
+@@ -2319,7 +2319,7 @@ static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
+ }
+ }
+ if (avg_lum > MAX_AVG_LUM) {
+- if (sd->gain >= 1) {
++ if (sd->gain - 1 >= 0) {
+ sd->gain--;
+ set_gain(gspca_dev);
+ }
+diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
+index 28b4625..aa8f995 100644
+--- a/drivers/media/video/gspca/sunplus.c
++++ b/drivers/media/video/gspca/sunplus.c
+@@ -705,7 +705,7 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
+ rc = spca504B_PollingDataReady(gspca_dev);
+
+ /* Init the cam width height with some values get on init ? */
+- reg_w_riv(dev, 0x31, 0x04, 0);
++ reg_w_riv(dev, 0x31, 0, 0x04);
+ spca504B_WaitCmdStatus(gspca_dev);
+ rc = spca504B_PollingDataReady(gspca_dev);
+ break;
+@@ -807,14 +807,14 @@ static void init_ctl_reg(struct gspca_dev *gspca_dev)
+ default:
+ /* case BRIDGE_SPCA533: */
+ /* case BRIDGE_SPCA504B: */
+- reg_w_riv(dev, 0, 0x21ad, 0x00); /* hue */
+- reg_w_riv(dev, 0, 0x21ac, 0x01); /* sat/hue */
+- reg_w_riv(dev, 0, 0x21a3, 0x00); /* gamma */
++ reg_w_riv(dev, 0, 0x00, 0x21ad); /* hue */
++ reg_w_riv(dev, 0, 0x01, 0x21ac); /* sat/hue */
++ reg_w_riv(dev, 0, 0x00, 0x21a3); /* gamma */
+ break;
+ case BRIDGE_SPCA536:
+- reg_w_riv(dev, 0, 0x20f5, 0x40);
+- reg_w_riv(dev, 0, 0x20f4, 0x01);
+- reg_w_riv(dev, 0, 0x2089, 0x00);
++ reg_w_riv(dev, 0, 0x40, 0x20f5);
++ reg_w_riv(dev, 0, 0x01, 0x20f4);
++ reg_w_riv(dev, 0, 0x00, 0x2089);
+ break;
+ }
+ if (pollreg)
+@@ -888,11 +888,11 @@ static int sd_init(struct gspca_dev *gspca_dev)
+ switch (sd->bridge) {
+ case BRIDGE_SPCA504B:
+ reg_w_riv(dev, 0x1d, 0x00, 0);
+- reg_w_riv(dev, 0, 0x2306, 0x01);
+- reg_w_riv(dev, 0, 0x0d04, 0x00);
+- reg_w_riv(dev, 0, 0x2000, 0x00);
+- reg_w_riv(dev, 0, 0x2301, 0x13);
+- reg_w_riv(dev, 0, 0x2306, 0x00);
++ reg_w_riv(dev, 0, 0x01, 0x2306);
++ reg_w_riv(dev, 0, 0x00, 0x0d04);
++ reg_w_riv(dev, 0, 0x00, 0x2000);
++ reg_w_riv(dev, 0, 0x13, 0x2301);
++ reg_w_riv(dev, 0, 0x00, 0x2306);
+ /* fall thru */
+ case BRIDGE_SPCA533:
+ spca504B_PollingDataReady(gspca_dev);
+@@ -1011,7 +1011,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
+ spca504B_WaitCmdStatus(gspca_dev);
+ break;
+ default:
+- reg_w_riv(dev, 0x31, 0x04, 0);
++ reg_w_riv(dev, 0x31, 0, 0x04);
+ spca504B_WaitCmdStatus(gspca_dev);
+ spca504B_PollingDataReady(gspca_dev);
+ break;
+diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
+index 2bed9e2..0bc2cf5 100644
+--- a/drivers/media/video/ov511.c
++++ b/drivers/media/video/ov511.c
+@@ -5878,7 +5878,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
+ goto error;
+ }
+
+- mutex_unlock(&ov->lock);
++ mutex_lock(&ov->lock);
+
+ return 0;
+
+diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
+index 6781a07..0901322 100644
+--- a/drivers/media/video/saa7134/saa7134-cards.c
++++ b/drivers/media/video/saa7134/saa7134-cards.c
+@@ -5279,30 +5279,6 @@ struct saa7134_board saa7134_boards[] = {
+ .amux = TV,
+ },
+ },
+- [SAA7134_BOARD_ASUS_EUROPA_HYBRID] = {
+- .name = "Asus Europa Hybrid OEM",
+- .audio_clock = 0x00187de7,
+- .tuner_type = TUNER_PHILIPS_TD1316,
+- .radio_type = UNSET,
+- .tuner_addr = 0x61,
+- .radio_addr = ADDR_UNSET,
+- .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
+- .mpeg = SAA7134_MPEG_DVB,
+- .inputs = { {
+- .name = name_tv,
+- .vmux = 3,
+- .amux = TV,
+- .tv = 1,
+- }, {
+- .name = name_comp1,
+- .vmux = 4,
+- .amux = LINE2,
+- }, {
+- .name = name_svideo,
+- .vmux = 8,
+- .amux = LINE2,
+- } },
+- },
+
+ };
+
+@@ -6442,12 +6418,6 @@ struct pci_device_id saa7134_pci_tbl[] = {
+ .subdevice = 0x2004,
+ .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI,
+ }, {
+- .vendor = PCI_VENDOR_ID_PHILIPS,
+- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+- .subvendor = 0x1043,
+- .subdevice = 0x4847,
+- .driver_data = SAA7134_BOARD_ASUS_EUROPA_HYBRID,
+- }, {
+ /* --- boards without eeprom + subsystem ID --- */
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+@@ -7109,7 +7079,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
+ /* break intentionally omitted */
+ case SAA7134_BOARD_VIDEOMATE_DVBT_300:
+ case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
+- case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
+ {
+
+ /* The Philips EUROPA based hybrid boards have the tuner
+diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
+index b8a805c..a26e997 100644
+--- a/drivers/media/video/saa7134/saa7134-dvb.c
++++ b/drivers/media/video/saa7134/saa7134-dvb.c
+@@ -1116,7 +1116,6 @@ static int dvb_init(struct saa7134_dev *dev)
+ break;
+ case SAA7134_BOARD_PHILIPS_EUROPA:
+ case SAA7134_BOARD_VIDEOMATE_DVBT_300:
+- case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
+ &philips_europa_config,
+ &dev->i2c_adap);
+diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
+index 94e1a3b..f8697d4 100644
+--- a/drivers/media/video/saa7134/saa7134.h
++++ b/drivers/media/video/saa7134/saa7134.h
+@@ -297,7 +297,6 @@ struct saa7134_format {
+ #define SAA7134_BOARD_BEHOLD_X7 171
+ #define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
+ #define SAA7134_BOARD_ZOLID_HYBRID_PCI 173
+-#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174
+
+ #define SAA7134_MAXBOARDS 32
+ #define SAA7134_INPUT_MAX 8
+diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
+index 4a293b4..1b89735 100644
+--- a/drivers/media/video/uvc/uvc_ctrl.c
++++ b/drivers/media/video/uvc/uvc_ctrl.c
+@@ -1405,7 +1405,7 @@ uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
+ size = entity->processing.bControlSize;
+
+ for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
+- if (!usb_match_one_id(dev->intf, &blacklist[i].id))
++ if (!usb_match_id(dev->intf, &blacklist[i].id))
+ continue;
+
+ if (blacklist[i].index >= 8 * size ||
+diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
+index b6992b7..610e914 100644
+--- a/drivers/message/fusion/mptbase.c
++++ b/drivers/message/fusion/mptbase.c
+@@ -4330,8 +4330,6 @@ initChainBuffers(MPT_ADAPTER *ioc)
+
+ if (ioc->bus_type == SPI)
+ num_chain *= MPT_SCSI_CAN_QUEUE;
+- else if (ioc->bus_type == SAS)
+- num_chain *= MPT_SAS_CAN_QUEUE;
+ else
+ num_chain *= MPT_FC_CAN_QUEUE;
+
+diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
+index 6cea718..c295786 100644
+--- a/drivers/message/fusion/mptscsih.c
++++ b/drivers/message/fusion/mptscsih.c
+@@ -1720,7 +1720,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
+ dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
+ "Command not in the active list! (sc=%p)\n", ioc->name,
+ SCpnt));
+- retval = SUCCESS;
++ retval = 0;
+ goto out;
+ }
+
+diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
+index ca6b098..ba27c9d 100644
+--- a/drivers/mfd/wm8350-core.c
++++ b/drivers/mfd/wm8350-core.c
+@@ -134,7 +134,8 @@ static inline int is_reg_locked(struct wm8350 *wm8350, u8 reg)
+ wm8350->reg_cache[WM8350_SECURITY] == WM8350_UNLOCK_KEY)
+ return 0;
+
+- if ((reg >= WM8350_GPIO_FUNCTION_SELECT_1 &&
++ if ((reg == WM8350_GPIO_CONFIGURATION_I_O) ||
++ (reg >= WM8350_GPIO_FUNCTION_SELECT_1 &&
+ reg <= WM8350_GPIO_FUNCTION_SELECT_4) ||
+ (reg >= WM8350_BATTERY_CHARGER_CONTROL_1 &&
+ reg <= WM8350_BATTERY_CHARGER_CONTROL_3))
+diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
+index 1eac626..e9eae4a 100644
+--- a/drivers/misc/enclosure.c
++++ b/drivers/misc/enclosure.c
+@@ -391,7 +391,6 @@ static const char *const enclosure_status [] = {
+ [ENCLOSURE_STATUS_NOT_INSTALLED] = "not installed",
+ [ENCLOSURE_STATUS_UNKNOWN] = "unknown",
+ [ENCLOSURE_STATUS_UNAVAILABLE] = "unavailable",
+- [ENCLOSURE_STATUS_MAX] = NULL,
+ };
+
+ static const char *const enclosure_type [] = {
+diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
+index 1f552c6..85f0e8c 100644
+--- a/drivers/mmc/card/block.c
++++ b/drivers/mmc/card/block.c
+@@ -85,14 +85,7 @@ static void mmc_blk_put(struct mmc_blk_data *md)
+ mutex_lock(&open_lock);
+ md->usage--;
+ if (md->usage == 0) {
+- int devmaj = MAJOR(disk_devt(md->disk));
+ int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT;
+-
+- if (!devmaj)
+- devidx = md->disk->first_minor >> MMC_SHIFT;
+-
+- blk_cleanup_queue(md->queue.queue);
+-
+ __clear_bit(devidx, dev_use);
+
+ put_disk(md->disk);
+@@ -620,7 +613,6 @@ static int mmc_blk_probe(struct mmc_card *card)
+ return 0;
+
+ out:
+- mmc_cleanup_queue(&md->queue);
+ mmc_blk_put(md);
+
+ return err;
+diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
+index c5a7a85..49e5823 100644
+--- a/drivers/mmc/card/queue.c
++++ b/drivers/mmc/card/queue.c
+@@ -90,10 +90,9 @@ static void mmc_request(struct request_queue *q)
+ struct request *req;
+
+ if (!mq) {
+- while ((req = blk_fetch_request(q)) != NULL) {
+- req->cmd_flags |= REQ_QUIET;
++ printk(KERN_ERR "MMC: killing requests for dead queue\n");
++ while ((req = blk_fetch_request(q)) != NULL)
+ __blk_end_request_all(req, -EIO);
+- }
+ return;
+ }
+
+@@ -224,18 +223,17 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
+ struct request_queue *q = mq->queue;
+ unsigned long flags;
+
++ /* Mark that we should start throwing out stragglers */
++ spin_lock_irqsave(q->queue_lock, flags);
++ q->queuedata = NULL;
++ spin_unlock_irqrestore(q->queue_lock, flags);
++
+ /* Make sure the queue isn't suspended, as that will deadlock */
+ mmc_queue_resume(mq);
+
+ /* Then terminate our worker thread */
+ kthread_stop(mq->thread);
+
+- /* Empty the queue */
+- spin_lock_irqsave(q->queue_lock, flags);
+- q->queuedata = NULL;
+- blk_start_queue(q);
+- spin_unlock_irqrestore(q->queue_lock, flags);
+-
+ if (mq->bounce_sg)
+ kfree(mq->bounce_sg);
+ mq->bounce_sg = NULL;
+@@ -247,6 +245,8 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
+ kfree(mq->bounce_buf);
+ mq->bounce_buf = NULL;
+
++ blk_cleanup_queue(mq->queue);
++
+ mq->card = NULL;
+ }
+ EXPORT_SYMBOL(mmc_cleanup_queue);
+diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
+index 2fda0b6..9de75ad 100644
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -475,6 +475,12 @@ config MTD_NAND_SOCRATES
+ help
+ Enables support for NAND Flash chips wired onto Socrates board.
+
++config MTD_NAND_TMPA910
++ tristate "Support for TMPA9x0 NAND Controller"
++ depends on MTD_NAND && ARCH_TMPA910
++ help
++ Enables support for NAND flash controller of the Toshiba Topas910 board.
++
+ config MTD_NAND_W90P910
+ tristate "Support for NAND on w90p910 evaluation board."
+ depends on ARCH_W90X900 && MTD_PARTITIONS
+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
+index 6950d3d..f6ef5af 100644
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -40,6 +40,7 @@ obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o
+ obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o
+ obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o
+ obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
++obj-$(CONFIG_MTD_NAND_TMPA910) += tmpa910_nand.o
+ obj-$(CONFIG_MTD_NAND_W90P910) += w90p910_nand.o
+ obj-$(CONFIG_MTD_NAND_NOMADIK) += nomadik_nand.o
+
+diff --git a/drivers/mtd/nand/tmpa910_nand.c b/drivers/mtd/nand/tmpa910_nand.c
+new file mode 100644
+index 0000000..b12023d
+--- /dev/null
++++ b/drivers/mtd/nand/tmpa910_nand.c
+@@ -0,0 +1,890 @@
++/*
++ * drivers/mtd/nand/tmpa910_nand.c
++ *
++ * Copyright (C) 2008 bplan GmbH. All rights reserved. (?)
++ * Copyright (C) 2009 Florian Boor <florian.boor at kernelconcepts.de>
++ *
++ * 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
++ *
++ * TMPA 910 NAND controller driver, unclear origin (BPlan or Toshiba likely)
++ */
++
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++#include <linux/dma-mapping.h>
++#include <linux/interrupt.h>
++
++#include <asm/io.h>
++#include <mach/dma.h>
++#include <mach/tmpa910_regs.h>
++
++#define ECCBUF_SIZE 256
++#define WAIT_TIMEOUT 0xFFFF
++#define DMA_TIMEOUT 0xFFFF
++
++struct tmpa910_nand_timing {
++ unsigned int splw;
++ unsigned int sphw;
++ unsigned int splr;
++ unsigned int sphr;
++};
++
++struct tmpa910_nand_private {
++ struct nand_chip chip;
++ unsigned int chip_select;
++ unsigned int mlc;
++ unsigned int dma;
++ unsigned int softecc;
++ unsigned int column;
++ unsigned int orig_column;
++ unsigned int ecc_pos;
++ unsigned char eccbuf[64];
++ unsigned char *buf;
++ unsigned int phy_buf;
++ unsigned int dma_ch;
++ struct completion dma_completion;
++ struct tmpa910_nand_timing timing;
++};
++
++struct tmpa910_nand_private tmpa910_nand = {
++ .chip_select = 0,
++ .mlc = 0,
++ .timing =
++ {
++ .splw = 0x2,
++ .sphw = 0x2,
++ .splr = 0x2,
++ .sphr = 0x2,
++ },
++};
++
++
++#ifdef CONFIG_MTD_PARTITIONS
++/*
++ * Define static partitions for flash device
++ */
++static int num_partitions = 3;
++
++static struct mtd_partition mtd_parts_builtin[] = {
++ {
++ .name = "bootloader",
++ .offset = 0x00000000,
++ .size = 0x00080000,
++ }, {
++ .name = "kernel",
++ .offset = 0x00080000,
++ .size = 0x00200000,
++ }, {
++ .name = "filesystem",
++ .offset = 0x00280000,
++ .size = 0x08000000 - 0x00280000,
++ },
++};
++
++static const char *part_probes[] = { "cmdlinepart", NULL };
++
++#endif
++
++void tmpa910_nand_dma_read(struct tmpa910_nand_private *priv, unsigned int phy_addr, unsigned short size)
++{
++ //tmpa910_dma_enable(priv->dma_ch);
++ DMA_SRC_ADDR(priv->dma_ch) = NDFDTR_PHY;
++ DMA_DEST_ADDR(priv->dma_ch) = phy_addr;
++ DMA_CONTROL(priv->dma_ch) = 0x88489000 + (size/4);
++ DMA_CONFIG(priv->dma_ch) = 0x9009;
++}
++
++void tmpa910_nand_dma_write(struct tmpa910_nand_private *priv, unsigned int phy_addr, unsigned short size)
++{
++
++ //tmpa910_dma_enable(priv->dma_ch);
++ DMA_SRC_ADDR(priv->dma_ch) = phy_addr; // Source address
++ DMA_DEST_ADDR(priv->dma_ch) = NDFDTR_PHY; // Destination address
++ DMA_CONTROL(priv->dma_ch) = 0x84489000 + (size/4);
++ DMA_CONFIG(priv->dma_ch)= 0x00008901;//FlowCntrl:Memory to peripheral,ITC=1;DMA=EN
++}
++
++static int tmpa910_nand_dev_ready(struct mtd_info *mtd)
++{
++ return !(NDFMCR0 & NDFMCR0_BUSY);
++}
++
++static int tmpa910_nand_als_ready(struct mtd_info *mtd)
++{
++ return !(NDFMCR1 & 0x100);
++}
++
++static void tmpa910_nand_set_cmd(unsigned int cmd)
++{
++ /* Begin command latch cycle */
++ NDFMCR0 |= NDFMCR0_CLE |NDFMCR0_WE;
++ /* Write out the command to the device. */
++ NDFDTR = cmd;
++ /* End command latch cycle */
++ NDFMCR0 &= ~(NDFMCR0_CLE |NDFMCR0_WE);
++}
++
++
++static void tmpa910_nand_set_addr(unsigned int column, unsigned int page_addr,
++ unsigned int buswidth_16, unsigned int third_addr)
++{
++ if (column != -1 || page_addr != -1) {
++ NDFMCR0 |= NDFMCR0_ALE |NDFMCR0_WE;
++
++ /* Serially input address */
++ if (column != -1) {
++ /* Adjust columns for 16 bit buswidth */
++ if (buswidth_16)
++ column >>= 1;
++ NDFDTR = column & 0xff;
++ NDFDTR = column >> 8;
++ }
++ if (page_addr != -1) {
++ NDFDTR = (unsigned char) (page_addr & 0xff);
++ NDFDTR = (unsigned char) ((page_addr >> 8) & 0xff);
++ /* One more address cycle for devices > 128MiB */
++ if (third_addr)
++ NDFDTR = (unsigned char) ((page_addr >> 16) & 0xff);
++ }
++ /* Latch in address */
++ NDFMCR0 &= ~(NDFMCR0_ALE |NDFMCR0_WE);
++ }
++}
++
++static int tmpa910_nand_wait_dma_complete(struct tmpa910_nand_private *priv,
++ unsigned int timeout)
++{
++ int ret;
++
++ ret = wait_for_completion_interruptible_timeout(&priv->dma_completion, timeout);
++ tmpa910_dma_disable(priv->dma_ch);
++
++ return !ret;
++}
++
++static void tmpa910_nand_get_hwecc(unsigned char *ecc_code, unsigned int mlc)
++{
++ unsigned int ecc_val = 0;
++ unsigned char *buf = ecc_code;
++
++ //printf("----Enable HWECCL %x, %x, %x\n ", NDFMCR0, val, NDFMCR1);
++ if (!mlc) {
++ ecc_val = NDECCRD1;
++ *buf++ = (unsigned char)(ecc_val&0xff);
++ *buf++ = (unsigned char)(ecc_val>>8);
++ *buf++ = (unsigned char)(ecc_val>>16);
++ ecc_val = NDECCRD0;
++ *buf++ = (unsigned char)(ecc_val&0xff);
++ *buf++ = (unsigned char)(ecc_val>>8);
++ *buf++ = (unsigned char)(ecc_val>>16);
++ }
++ else
++ {
++ //MLC, Reed solomn ECC data
++ ecc_val = NDECCRD0;
++ *buf++ = (unsigned char)(ecc_val>>8);
++ *buf++ = (unsigned char)(ecc_val&0xff);
++ *buf++ = (unsigned char)(ecc_val>>24);
++ *buf++ = (unsigned char)(ecc_val>>16);
++
++ ecc_val = NDECCRD1;
++ *buf++ = (unsigned char)(ecc_val>>8);
++ *buf++ = (unsigned char)(ecc_val&0xff);
++ *buf++ = (unsigned char)(ecc_val>>24);
++ *buf++ = (unsigned char)(ecc_val>>16);
++
++ ecc_val = NDECCRD2;
++ *buf++ = (unsigned char)(ecc_val>>8);
++ *buf++ = (unsigned char)(ecc_val&0xff);
++ }
++}
++
++static void tmpa910_nand_set_ecctype(unsigned int mlc)
++{
++ if (mlc) {
++ NDFMCR1 |= NDFMCR1_ECCS;
++ }
++ else {
++ NDFMCR1 &= ~NDFMCR1_ECCS;
++ }
++}
++
++static void tmpa910_nand_start_autoload(unsigned int read)
++{
++ unsigned int val;
++
++ val = NDFMCR1;
++ if (read) {
++ /*Set it to be read */
++ val &= ~NDFMCR1_SELAL;
++ }
++ else
++ val |= NDFMCR1_SELAL;
++ /* start autoload */
++ val |= NDFMCR1_ALS;
++ NDFMCR1 = val;
++}
++
++static void tmpa910_nand_start_ecc(unsigned int read)
++{
++ if (read)
++ NDFMCR0 |= NDFMCR0_ECCE | NDFMCR0_ECCRST;
++ else
++ NDFMCR0 |= NDFMCR0_ECCE | NDFMCR0_ECCRST | NDFMCR0_RSEDN;
++}
++
++static void tmpa910_nand_set_rw_mode(unsigned int read)
++{
++ if (read)
++ NDFMCR0 &= ~NDFMCR0_WE;
++ else
++ NDFMCR0 |= NDFMCR0_WE;
++}
++
++static void tmpa910_nand_calculate_softecc(const unsigned char * dat, unsigned char *ecc_code)
++{
++}
++
++static void tmpa910_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
++{
++ register struct nand_chip *this = mtd->priv;
++ int eccsize = this->ecc.size;
++ struct tmpa910_nand_private * priv= (struct tmpa910_nand_private *)this->priv;
++ unsigned char * buf, *eccbuf;
++ unsigned int buswidth_16 = 0, third_addr = 0;
++
++ /* printk("Send command;%x, at column;%x, page;%x\n", command, column, page_addr); */
++ if (mtd->writesize > 512) {
++ /* Emulate NAND_CMD_READOOB */
++ if (command == NAND_CMD_READOOB) {
++ column += mtd->writesize;
++ command = NAND_CMD_READ0;
++ }
++ if (this->chipsize > (128 << 20))
++ third_addr = 1;
++ }
++ else {
++ if (this->chipsize > (32 << 20))
++ third_addr = 1;
++ }
++ if (this->options & NAND_BUSWIDTH_16)
++ buswidth_16 = 1;
++ priv->column = priv->orig_column = column;
++ if (eccsize) {
++ if (priv->mlc)
++ priv->ecc_pos = (column / eccsize) * 10;
++ else
++ priv->ecc_pos = (column / eccsize) * 6;
++ }
++
++ if (command == NAND_CMD_READ0) {
++ column = column & ~(eccsize -1);
++
++ if (priv->dma && !priv->softecc) {
++ if (column < mtd->writesize) {
++ while (column < mtd->writesize) {
++ tmpa910_nand_set_ecctype(priv->mlc);
++ buf = priv->buf + column;
++ if (priv->mlc)
++ eccbuf = priv->eccbuf + (column / eccsize) * 10;
++ else
++ eccbuf = priv->eccbuf + (column / eccsize) * 6;
++ tmpa910_nand_set_cmd(command);
++ tmpa910_nand_dma_read(priv, priv->phy_buf + column, eccsize);
++ tmpa910_nand_start_autoload(1);
++ tmpa910_nand_set_addr(column, page_addr, buswidth_16, third_addr);
++ /* Large page NAND */
++ if (mtd->writesize > 512)
++ tmpa910_nand_set_cmd(NAND_CMD_READSTART);
++ tmpa910_nand_start_ecc(1);
++ tmpa910_nand_set_rw_mode(1);
++ if (tmpa910_nand_wait_dma_complete(priv, DMA_TIMEOUT)) {
++ printk("ERROR: read page :0x%x, column:0x%x time out\n", page_addr, column);
++ return;
++ }
++
++ while(!tmpa910_nand_als_ready(mtd));
++
++ tmpa910_nand_get_hwecc(eccbuf, priv->mlc);
++ if (priv->mlc)
++ eccbuf += 6;
++ else
++ eccbuf += 10;
++ column += eccsize;
++ }
++ //buf += this->eccsize;
++ /*Should not be > this->oobblock */
++ if (column >= mtd->writesize) {
++ buf = priv->buf + column;
++ while (column < (mtd->writesize + mtd->oobsize)) {
++ *buf = NDFDTR;
++ buf++;
++ column++;
++ }
++ }
++ }
++ else {
++ tmpa910_nand_set_cmd(command);
++ tmpa910_nand_set_addr(column, page_addr, buswidth_16, third_addr);
++ if (mtd->writesize > 512)
++ tmpa910_nand_set_cmd(NAND_CMD_READSTART);
++ tmpa910_nand_set_rw_mode(1);
++ while(!tmpa910_nand_dev_ready(mtd));
++ /*buf = priv->buf + column;
++ while (column < (mtd->oobblock + mtd->oobsize)) {
++ *buf = NDFDTR;
++ printf("0x%x,,\t ", *buf);
++ buf++;
++ column++;
++ }*/
++ }
++ }
++ else { /* NO DMA || soft ECC*/
++ tmpa910_nand_set_cmd(command);
++ if (priv->dma)
++ tmpa910_nand_dma_read(priv, priv->phy_buf + column, mtd->writesize + mtd->oobsize - column);
++ tmpa910_nand_set_addr(column, page_addr, buswidth_16, third_addr);
++ /* Large page NAND */
++ if (mtd->writesize > 512)
++ tmpa910_nand_set_cmd(NAND_CMD_READSTART);
++
++ if (priv->dma && tmpa910_nand_wait_dma_complete(priv, DMA_TIMEOUT)) {
++ printk("ERROR: read page :0x%x, column:0x%x time out\n", page_addr, column);
++ return;
++ }
++ /*HWECC start will be set at enable_ecc function */
++
++ while(!tmpa910_nand_dev_ready(mtd));
++ }
++ }
++ else if (command == NAND_CMD_SEQIN) { /* For Write */
++ column = column & ~(eccsize -1);
++ //if (priv->dma && column < this->oobblock) {
++ /*if (!priv->softecc)
++ tmpa910_nand_set_ecctype(priv->mlc); */
++
++ tmpa910_nand_set_cmd(command);
++ tmpa910_nand_set_addr(column, page_addr, buswidth_16, third_addr);
++ }
++ else if (command == NAND_CMD_PAGEPROG || command == NAND_CMD_CACHEDPROG) {
++ if (priv->dma && priv->softecc) {
++ /*nand_base.c can make sure that priv->column is aligned with ecc_step */
++ tmpa910_nand_dma_write(priv, priv->phy_buf + priv->orig_column, mtd->writesize + mtd->oobsize - priv->orig_column);
++ if (tmpa910_nand_wait_dma_complete(priv, DMA_TIMEOUT)) {
++ printk("ERROR: Write page :, column:0x%x time out\n", priv->column);
++ return;
++ }
++
++ while(!tmpa910_nand_als_ready(mtd));
++ }
++ tmpa910_nand_set_cmd(command);
++ tmpa910_nand_set_addr(column, page_addr, buswidth_16, third_addr);
++ }
++ else {
++ tmpa910_nand_set_cmd(command);
++ tmpa910_nand_set_addr(column, page_addr, buswidth_16, third_addr);
++ if (command == NAND_CMD_RESET)
++ while(!tmpa910_nand_dev_ready(mtd));
++ }
++}
++
++
++/* Set WP on deselect, write enable on select */
++static void tmpa910_nand_select_chip(struct mtd_info *mtd, int chip)
++{
++ struct nand_chip *this = mtd->priv;
++ struct tmpa910_nand_private * priv= (struct tmpa910_nand_private *)this->priv;
++ unsigned int val;
++
++ priv->chip_select = chip;
++ if (chip == 0) {
++ val = NDFMCR0;
++ val |= NDFMCR0_CE0; /*Enable chip0 */
++ val &= ~NDFMCR0_CE1; /* Disable chip1 */
++ NDFMCR0 = val;
++ }
++ else if (chip == 1) {
++ val = NDFMCR0;
++ val |= NDFMCR0_CE1; /*Enable chip0 */
++ val &= ~NDFMCR0_CE0; /* Disable chip1 */
++ NDFMCR0 = val;
++ }
++ else {
++ val = NDFMCR0;
++ val &= ~(NDFMCR0_CE1 | NDFMCR0_CE0);
++ NDFMCR0 = val;
++ }
++
++}
++
++static struct nand_ecclayout nand_lp_hw_eccoob = {
++ //.useecc = MTD_NANDECC_AUTOPLACE,
++ .eccbytes = 24,
++ .eccpos = {8, 9, 10, 13, 14, 15, 24, 25,
++ 26, 29, 30, 31, 40, 41, 42, 45,
++ 46, 47, 56, 57, 58, 61, 62, 63},
++ .oobfree = { {0, 8}, {16, 8}, {32, 8}, {48,8}, {11,2}, {27,2}, {43,2}, {59,2}}
++};
++
++static struct nand_ecclayout nand_sp_hw_eccoob = {
++ .eccbytes = 6,
++ .eccpos = {8, 9, 10, 13, 14, 15},
++ .oobfree = { {0, 8},{0,0}}
++};
++
++static void tmpa910_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
++{
++ unsigned i = 0;
++ struct nand_chip *this = mtd->priv;
++ struct tmpa910_nand_private * priv= (struct tmpa910_nand_private *)this->priv;
++
++ if (len > (mtd->writesize + mtd->oobsize - priv->column))
++ len = mtd->writesize + mtd->oobsize- priv->column;
++ if (priv->dma && priv->orig_column < mtd->writesize) {
++ memcpy(buf, priv->buf + priv->column, len);
++ }
++ else {
++ while (i < len)
++ buf[i++] = NDFDTR;
++ }
++ priv->column += len;
++}
++static void tmpa910_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
++{
++ struct nand_chip *this = mtd->priv;
++ int i, eccsize = this->ecc.size;
++ struct tmpa910_nand_private * priv= (struct tmpa910_nand_private *)this->priv;
++
++ if (len > (mtd->writesize + mtd->oobsize - priv->column))
++ len = mtd->writesize + mtd->oobsize - priv->column;
++
++ if (priv->dma && priv->orig_column < mtd->writesize) {
++ memcpy(priv->buf + priv->column, buf, len);
++ if (!priv->softecc) {
++ unsigned char *eccbuf;
++
++ if (priv->mlc)
++ eccbuf = priv->eccbuf + (priv->column / eccsize) * 10;
++ else
++ eccbuf = priv->eccbuf + (priv->column / eccsize) * 6;
++
++ if (priv->column < mtd->writesize) {
++ /* we can be sure that len = ecc_step and priv->column is aligned by ecc_step(512 byte) */
++ tmpa910_nand_dma_write(priv, priv->phy_buf + priv->column, len);
++ tmpa910_nand_start_autoload(0);
++ if (tmpa910_nand_wait_dma_complete(priv, DMA_TIMEOUT)) {
++ printk("ERROR: Write page :, column:0x%x time out\n", priv->column);
++ return;
++ }
++
++ while(!tmpa910_nand_als_ready(mtd));
++
++ //tmpa910_nand_set_rw_mode(1);
++ tmpa910_nand_get_hwecc(eccbuf, priv->mlc);
++ }
++ else {
++ for (i = 0; i < len; i++)
++ NDFDTR = buf[i];
++ }
++ }
++ }
++ else {
++ for (i = 0; i < len; i++)
++ NDFDTR = buf[i];
++ }
++ priv->column += len;
++}
++
++static void tmpa910_nand_enable_hwecc(struct mtd_info *mtd, int mode)
++{
++ struct nand_chip *this = mtd->priv;
++ struct tmpa910_nand_private * priv= (struct tmpa910_nand_private *)this->priv;
++
++ if (mode == NAND_ECC_READ) {
++ /* No DMA || soft ECC*/
++ if (!priv->dma || priv->softecc) {
++ /* Disable WE */
++ tmpa910_nand_set_rw_mode(1);
++
++ if (!priv->softecc) {
++ tmpa910_nand_set_ecctype(priv->mlc);
++ tmpa910_nand_start_ecc(mode == NAND_ECC_READ);
++ }
++ }
++ }
++ else if (mode == NAND_ECC_WRITE) {
++ tmpa910_nand_set_rw_mode(0);
++ if (!priv->softecc) {
++ tmpa910_nand_set_ecctype(priv->mlc);
++ tmpa910_nand_start_ecc(mode == NAND_ECC_READ);
++ }
++ }
++ //printf("Enable HWECCL %x, %x\n ", NDFMCR0, NDFMCR1);
++}
++
++static int tmpa910_nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *dat, unsigned char *ecc_code)
++{
++ struct nand_chip *this = mtd->priv;
++ int eccsize = this->ecc.size;
++ struct tmpa910_nand_private * priv= (struct tmpa910_nand_private *)this->priv;
++ int steps;
++
++ /* No DMA && No read OOB */
++ if (!priv->dma || priv->softecc) {
++ if (priv->softecc) {
++ steps = eccsize / ECCBUF_SIZE;
++ while (steps--) {
++ tmpa910_nand_calculate_softecc(dat, ecc_code);
++ dat += ECCBUF_SIZE;
++ ecc_code += 3;
++ }
++ }
++ else {
++ tmpa910_nand_get_hwecc(ecc_code, priv->mlc);
++ }
++ }
++ else {
++ memcpy(ecc_code, priv->eccbuf + priv->ecc_pos, 6);
++ priv->ecc_pos += 6;
++ }
++ return 0;
++}
++
++#define BIT7 0x80
++#define BIT6 0x40
++#define BIT5 0x20
++#define BIT4 0x10
++#define BIT3 0x08
++#define BIT2 0x04
++#define BIT1 0x02
++#define BIT0 0x01
++#define BIT1BIT0 0x03
++#define BIT23 0x00800000L
++#define MASK_CPS 0x3f
++#define CORRECTABLE 0x00555554L
++
++static int tmpa910_nand_part_correctdata(unsigned char *data, unsigned char *eccdata, unsigned char ecc1, unsigned char ecc2, unsigned char ecc3)
++{
++ /*FIXME should be U31, U16 and U8 */
++ unsigned int l; /* Working to check d */
++ unsigned int d; /* Result of comparison */
++ unsigned short i; /* For counting */
++ unsigned char d1,d2,d3; /* Result of comparison */
++ unsigned char a; /* Working for add */
++ unsigned char add; /* Byte address of cor. DATA */
++ unsigned char b; /* Working for bit */
++ unsigned char bit; /* Bit address of cor. DATA */
++
++ d1=ecc1^eccdata[1]; d2=ecc2^eccdata[0]; /* Compare LP's */
++ d3=ecc3^eccdata[2]; /* Comapre CP's */
++ d=((unsigned int)d1<<16) /* Result of comparison */
++ +((unsigned int)d2<<8)
++ +(unsigned int)d3;
++ if (d==0)
++ return(0); /* If No error, return */
++
++ /* sometimes people do not think about using the ECC, so check
++ * to see if we have an 0xff,0xff,0xff read ECC and then ignore
++ * the error, on the assumption that this is an un-eccd page.
++ */
++ if (eccdata[0] == 0xff && eccdata[1] == 0xff && eccdata[2] == 0xff)
++ return 0;
++
++ if (((d^(d>>1))&CORRECTABLE)==CORRECTABLE) { /* If correctable */
++ l=BIT23;
++ add=0; /* Clear parameter */
++ a=BIT7;
++ for(i=0; i<8; ++i) { /* Checking 8 bit */
++ if ((d&l)!=0)
++ add|=a; /* Make byte address from LP's */
++ l>>=2; a>>=1; /* Right Shift */
++ }
++ bit=0; /* Clear parameter */
++ b=BIT2;
++ for (i = 0; i < 3; ++i) { /* Checking 3 bit */
++ if ((d&l)!=0)
++ bit|=b; /* Make bit address from CP's */
++ l>>=2; b>>=1; /* Right shift */
++ }
++ b=BIT0;
++ data[add]^=(b<<bit); /* Put corrected data */
++ return(1);
++ }
++ i=0; /* Clear count */
++ d&=0x00ffffffL; /* Masking */
++ while (d) { /* If d=0 finish counting */
++ if (d&BIT0)
++ ++i; /* Count number of 1 bit */
++ d>>=1; /* Right shift */
++ }
++ if (i==1) { /* If ECC error */
++ eccdata[1]=ecc1;
++ eccdata[0]=ecc2; /* Put right ECC code */
++ eccdata[2]=ecc3;
++ return(2);
++ }
++ return(3); /* Uncorrectable error */
++}
++
++static int tmpa910_nand_correct_data(struct mtd_info *mtd, u_char *data, u_char *read_ecc, u_char *calc_ecc)
++{
++ struct nand_chip *this = mtd->priv;
++ int eccsize = this->ecc.size;
++ unsigned int size;
++ unsigned char ecc1, ecc2, ecc3; /* FIXME should define as U8 */
++ unsigned int ret, ret_tmp;
++
++ size = eccsize;
++
++ ret_tmp = 0;
++ while (size > 0)
++ {
++ ecc2 = *calc_ecc++;
++ ecc1 = *calc_ecc++;
++ ecc3 = *calc_ecc++;
++ ret = tmpa910_nand_part_correctdata(data, read_ecc, ecc1, ecc2, ecc3);
++ if(ret > ret_tmp) {
++ ret_tmp = ret;
++ }
++
++ size -= ECCBUF_SIZE;
++ data += ECCBUF_SIZE;
++ read_ecc += 3;
++ }
++ return (ret_tmp != 0 && ret_tmp != 1)? -1 : 0;
++}
++
++static void tmpa910_nand_set_timing(struct tmpa910_nand_private *priv)
++{
++#if 1
++ NDFMCR2 = 0x2222;
++#else
++ unsigned timing;
++ timing = (priv->timing.splw << 12) |
++ (priv->timing.sphw << 8) |
++ (priv->timing.splr << 4) |
++ priv->timing.sphr;
++ printk("NAND: setiing NDFMCR2: 0x%04x\n", timing);
++ NDFMCR2 = timing;
++#endif
++}
++
++static void tmpa910_nand_dma_handler(int dma_ch, void *data)
++{
++ struct tmpa910_nand_private * priv;
++
++ priv = (struct tmpa910_nand_private *)data;
++ complete(&priv->dma_completion);
++
++ return;
++}
++
++static void tmpa910_nand_dma_error_handler(int dma_ch, void *data)
++{
++ struct tmpa910_nand_private * priv;
++
++ priv = (struct tmpa910_nand_private *)data;
++ complete(&priv->dma_completion);
++ printk("DMA Error happens at DMA channel %d\n", dma_ch);
++ return;
++}
++
++static int tmpa910_nand_init_priv(struct tmpa910_nand_private *priv)
++{
++ priv->dma = 0;
++ priv->softecc = 0;
++
++// __REG(0xF080E008) = 0x02;
++ //NDFMCR0 =0x95;
++ NDFMCR0 =0x0;
++ NDFMCR1 = 0;
++ tmpa910_nand_set_timing(priv);
++
++ return 0;
++}
++
++static int tmpa910_nand_probe(struct platform_device *pdev)
++{
++ struct tmpa910_nand_private * priv;
++ struct mtd_info *mtd;
++ struct nand_chip *nand;
++ int ret;
++#ifdef CONFIG_MTD_PARTITIONS
++ struct mtd_partition *partitions = NULL;
++ int num_cmdline_parts;
++#endif
++
++ /* We only get one Nand Controller, so we do not modify CFG_NAND_BASE_LIST
++ to get the multiple IO address for the controllers */
++ /* Remeber to set CFG_MAX_NAND_DEVICE in the board config file to be the
++ controller number. Now we only have one controller, so set it to be 1 */
++
++ mtd = (struct mtd_info *)kzalloc(sizeof(struct mtd_info) + sizeof(struct tmpa910_nand_private), GFP_KERNEL);
++ if (mtd == NULL) {
++ printk(KERN_ERR "TMPA910_NAND: not enough mempry");
++ ret = -ENOMEM;
++ goto error;
++ }
++ priv = (struct tmpa910_nand_private *)(mtd + 1);
++ priv->buf = (unsigned char *)dma_alloc_coherent(NULL,2112, &priv->phy_buf, GFP_KERNEL);
++ if (priv->buf == NULL) {
++ ret = -ENOMEM;
++ goto free_mtd;
++ }
++
++ nand = &priv->chip;
++ nand->IO_ADDR_R = (void __iomem *)(&NDFDTR);
++ nand->IO_ADDR_W = (void __iomem *)(&NDFDTR);
++ nand->chip_delay = 0;
++ nand->select_chip = tmpa910_nand_select_chip;
++
++ /* The controller will generate 6 bytes ecc for 512 bytes data*/
++ nand->ecc.calculate = tmpa910_nand_calculate_ecc;
++ nand->ecc.correct = tmpa910_nand_correct_data;
++ nand->ecc.hwctl = tmpa910_nand_enable_hwecc;
++ nand->ecc.mode = NAND_ECC_HW;
++ nand->ecc.size = 512;
++ nand->ecc.bytes = 6;
++
++
++ /* Set address of hardware control function */
++ nand->cmdfunc = tmpa910_nand_command;
++ nand->dev_ready = tmpa910_nand_dev_ready;
++ nand->read_buf = tmpa910_nand_read_buf;
++ nand->write_buf = tmpa910_nand_write_buf;
++
++ mtd->priv = nand;
++ platform_set_drvdata(pdev, mtd);
++
++ ret = tmpa910_nand_init_priv(priv);
++ if (ret) {
++ goto free_dma_buf;
++ }
++ nand->priv = priv;
++
++ init_completion(&priv->dma_completion);
++ priv->dma_ch = tmpa910_dma_request("TMPA910 NAND", 5, tmpa910_nand_dma_handler,
++ tmpa910_nand_dma_error_handler, priv);
++ if (priv->dma_ch < 0) {
++ ret = -ENODEV;
++ goto free_dma_buf;
++ }
++
++ mtd->owner = THIS_MODULE;
++ /* Many callers got this wrong, so check for it for a while... */
++ ret = nand_scan_ident(mtd, 1);
++ if (ret) {
++ goto free_dma_ch;
++ }
++
++ if (mtd->writesize == 2048)
++ nand->ecc.layout = &nand_lp_hw_eccoob;
++ else
++ nand->ecc.layout = &nand_sp_hw_eccoob;
++ ret = nand_scan_tail(mtd);
++ if (ret) {
++ goto free_dma_ch;
++ }
++
++/* Partitions:
++ * If there is support for partitions then use commandline partitions if
++ * available, the defauts otherwise.
++ * If there is no support for partitions then add the whole device.
++ */
++
++#ifdef CONFIG_MTD_PARTITIONS
++
++#ifdef CONFIG_MTD_CMDLINE_PARTS
++ mtd->name = "tmpa910-nand",
++ num_cmdline_parts = parse_mtd_partitions(mtd, part_probes,
++ &partitions, 0);
++ if (num_cmdline_parts)
++ add_mtd_partitions(mtd, partitions, num_cmdline_parts);
++ else
++ add_mtd_partitions(mtd, mtd_parts_builtin, num_partitions);
++#else
++ add_mtd_partitions(mtd, mtd_parts_builtin, num_partitions);
++
++#endif
++
++#else
++ add_mtd_device(mtd);
++#endif
++ return(0);
++
++free_dma_ch:
++ tmpa910_dma_free(priv->dma_ch);
++free_dma_buf:
++ dma_free_coherent(&pdev->dev, 2112, priv->buf, priv->phy_buf);
++free_mtd:
++ kfree(mtd);
++error:
++ return ret;
++}
++
++
++static int tmpa910_nand_remove(struct platform_device *pdev)
++{
++ struct mtd_info *mtd;
++ struct tmpa910_nand_private * priv;
++
++ mtd = platform_get_drvdata(pdev);
++ priv = (struct tmpa910_nand_private *)(mtd->priv);
++ dma_free_coherent(&pdev->dev, 2112, priv->buf, priv->phy_buf);
++
++ kfree(mtd);
++ return 0;
++}
++
++static int tmpa910_nand_suspend(struct platform_device *dev, pm_message_t pm)
++{
++ return 0;
++}
++
++static int tmpa910_nand_resume(struct platform_device *dev)
++{
++ return 0;
++}
++
++static struct platform_driver tmpa910_nand_driver = {
++ .probe = tmpa910_nand_probe,
++ .remove = __devexit_p(tmpa910_nand_remove),
++ .suspend = tmpa910_nand_suspend,
++ .resume = tmpa910_nand_resume,
++ .driver = {
++ .name = "tmpa910-nand",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int tmpa910_nand_init(void)
++{
++ return platform_driver_register(&tmpa910_nand_driver);
++}
++
++static void tmpa910_nand_exit(void)
++{
++ platform_driver_unregister(&tmpa910_nand_driver);
++}
++module_init(tmpa910_nand_init);
++module_exit(tmpa910_nand_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("NAND flash driver for TMPA910");
+diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
+index 111ea41..f237ddb 100644
+--- a/drivers/mtd/ubi/cdev.c
++++ b/drivers/mtd/ubi/cdev.c
+@@ -853,6 +853,7 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
+ break;
+ }
+
++ req.name[req.name_len] = '\0';
+ err = verify_mkvol_req(ubi, &req);
+ if (err)
+ break;
+diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
+index 425bf5a..74fdc40 100644
+--- a/drivers/mtd/ubi/upd.c
++++ b/drivers/mtd/ubi/upd.c
+@@ -147,15 +147,12 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
+ }
+
+ if (bytes == 0) {
+- err = ubi_wl_flush(ubi);
+- if (err)
+- return err;
+-
+ err = clear_update_marker(ubi, vol, 0);
+ if (err)
+ return err;
+- vol->updating = 0;
+- return 0;
++ err = ubi_wl_flush(ubi);
++ if (!err)
++ vol->updating = 0;
+ }
+
+ vol->upd_buf = vmalloc(ubi->leb_size);
+@@ -365,16 +362,16 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,
+
+ ubi_assert(vol->upd_received <= vol->upd_bytes);
+ if (vol->upd_received == vol->upd_bytes) {
+- err = ubi_wl_flush(ubi);
+- if (err)
+- return err;
+ /* The update is finished, clear the update marker */
+ err = clear_update_marker(ubi, vol, vol->upd_bytes);
+ if (err)
+ return err;
+- vol->updating = 0;
+- err = to_write;
+- vfree(vol->upd_buf);
++ err = ubi_wl_flush(ubi);
++ if (err == 0) {
++ vol->updating = 0;
++ err = to_write;
++ vfree(vol->upd_buf);
++ }
+ }
+
+ return err;
+diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
+index 4004402..1afc61e 100644
+--- a/drivers/mtd/ubi/vtbl.c
++++ b/drivers/mtd/ubi/vtbl.c
+@@ -566,7 +566,6 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
+ vol->reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs);
+ vol->alignment = be32_to_cpu(vtbl[i].alignment);
+ vol->data_pad = be32_to_cpu(vtbl[i].data_pad);
+- vol->upd_marker = vtbl[i].upd_marker;
+ vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ?
+ UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME;
+ vol->name_len = be16_to_cpu(vtbl[i].name_len);
+diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h
+index 790e55b..2a1120a 100644
+--- a/drivers/net/atl1c/atl1c.h
++++ b/drivers/net/atl1c/atl1c.h
+@@ -534,9 +534,6 @@ struct atl1c_adapter {
+ #define __AT_TESTING 0x0001
+ #define __AT_RESETTING 0x0002
+ #define __AT_DOWN 0x0003
+- u8 work_event;
+-#define ATL1C_WORK_EVENT_RESET 0x01
+-#define ATL1C_WORK_EVENT_LINK_CHANGE 0x02
+ u32 msg_enable;
+
+ bool have_msi;
+@@ -548,7 +545,8 @@ struct atl1c_adapter {
+ spinlock_t tx_lock;
+ atomic_t irq_sem;
+
+- struct work_struct common_task;
++ struct work_struct reset_task;
++ struct work_struct link_chg_task;
+ struct timer_list watchdog_timer;
+ struct timer_list phy_config_timer;
+
+diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
+index be00ee9..1372e9a 100644
+--- a/drivers/net/atl1c/atl1c_main.c
++++ b/drivers/net/atl1c/atl1c_main.c
+@@ -198,12 +198,27 @@ static void atl1c_phy_config(unsigned long data)
+
+ void atl1c_reinit_locked(struct atl1c_adapter *adapter)
+ {
++
+ WARN_ON(in_interrupt());
+ atl1c_down(adapter);
+ atl1c_up(adapter);
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ }
+
++static void atl1c_reset_task(struct work_struct *work)
++{
++ struct atl1c_adapter *adapter;
++ struct net_device *netdev;
++
++ adapter = container_of(work, struct atl1c_adapter, reset_task);
++ netdev = adapter->netdev;
++
++ netif_device_detach(netdev);
++ atl1c_down(adapter);
++ atl1c_up(adapter);
++ netif_device_attach(netdev);
++}
++
+ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
+ {
+ struct atl1c_hw *hw = &adapter->hw;
+@@ -260,6 +275,18 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
+ }
+ }
+
++/*
++ * atl1c_link_chg_task - deal with link change event Out of interrupt context
++ * @netdev: network interface device structure
++ */
++static void atl1c_link_chg_task(struct work_struct *work)
++{
++ struct atl1c_adapter *adapter;
++
++ adapter = container_of(work, struct atl1c_adapter, link_chg_task);
++ atl1c_check_link_status(adapter);
++}
++
+ static void atl1c_link_chg_event(struct atl1c_adapter *adapter)
+ {
+ struct net_device *netdev = adapter->netdev;
+@@ -284,39 +311,19 @@ static void atl1c_link_chg_event(struct atl1c_adapter *adapter)
+ adapter->link_speed = SPEED_0;
+ }
+ }
+-
+- adapter->work_event |= ATL1C_WORK_EVENT_LINK_CHANGE;
+- schedule_work(&adapter->common_task);
+-}
+-
+-static void atl1c_common_task(struct work_struct *work)
+-{
+- struct atl1c_adapter *adapter;
+- struct net_device *netdev;
+-
+- adapter = container_of(work, struct atl1c_adapter, common_task);
+- netdev = adapter->netdev;
+-
+- if (adapter->work_event & ATL1C_WORK_EVENT_RESET) {
+- netif_device_detach(netdev);
+- atl1c_down(adapter);
+- atl1c_up(adapter);
+- netif_device_attach(netdev);
+- return;
+- }
+-
+- if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE)
+- atl1c_check_link_status(adapter);
+-
+- return;
++ schedule_work(&adapter->link_chg_task);
+ }
+
+-
+ static void atl1c_del_timer(struct atl1c_adapter *adapter)
+ {
+ del_timer_sync(&adapter->phy_config_timer);
+ }
+
++static void atl1c_cancel_work(struct atl1c_adapter *adapter)
++{
++ cancel_work_sync(&adapter->reset_task);
++ cancel_work_sync(&adapter->link_chg_task);
++}
+
+ /*
+ * atl1c_tx_timeout - Respond to a Tx Hang
+@@ -327,8 +334,7 @@ static void atl1c_tx_timeout(struct net_device *netdev)
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ /* Do the reset outside of interrupt context */
+- adapter->work_event |= ATL1C_WORK_EVENT_RESET;
+- schedule_work(&adapter->common_task);
++ schedule_work(&adapter->reset_task);
+ }
+
+ /*
+@@ -1530,8 +1536,7 @@ static irqreturn_t atl1c_intr(int irq, void *data)
+ /* reset MAC */
+ hw->intr_mask &= ~ISR_ERROR;
+ AT_WRITE_REG(hw, REG_IMR, hw->intr_mask);
+- adapter->work_event |= ATL1C_WORK_EVENT_RESET;
+- schedule_work(&adapter->common_task);
++ schedule_work(&adapter->reset_task);
+ break;
+ }
+
+@@ -2195,7 +2200,8 @@ void atl1c_down(struct atl1c_adapter *adapter)
+ struct net_device *netdev = adapter->netdev;
+
+ atl1c_del_timer(adapter);
+- adapter->work_event = 0; /* clear all event */
++ atl1c_cancel_work(adapter);
++
+ /* signal that we're down so the interrupt handler does not
+ * reschedule our watchdog timer */
+ set_bit(__AT_DOWN, &adapter->flags);
+@@ -2595,8 +2601,8 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
+ adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]);
+
+ atl1c_hw_set_mac_addr(&adapter->hw);
+- INIT_WORK(&adapter->common_task, atl1c_common_task);
+- adapter->work_event = 0;
++ INIT_WORK(&adapter->reset_task, atl1c_reset_task);
++ INIT_WORK(&adapter->link_chg_task, atl1c_link_chg_task);
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(&pdev->dev, "register netdevice failed\n");
+diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
+index 1b5facf..955da73 100644
+--- a/drivers/net/atl1e/atl1e_main.c
++++ b/drivers/net/atl1e/atl1e_main.c
+@@ -1666,6 +1666,41 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter,
+ }
+ return 0;
+ }
++
++ if (offload_type & SKB_GSO_TCPV6) {
++ real_len = (((unsigned char *)ipv6_hdr(skb) - skb->data)
++ + ntohs(ipv6_hdr(skb)->payload_len));
++ if (real_len < skb->len)
++ pskb_trim(skb, real_len);
++
++ /* check payload == 0 byte ? */
++ hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
++ if (unlikely(skb->len == hdr_len)) {
++ /* only xsum need */
++ dev_warn(&pdev->dev,
++ "IPV6 tso with zero data??\n");
++ goto check_sum;
++ } else {
++ tcp_hdr(skb)->check = ~csum_ipv6_magic(
++ &ipv6_hdr(skb)->saddr,
++ &ipv6_hdr(skb)->daddr,
++ 0, IPPROTO_TCP, 0);
++ tpd->word3 |= 1 << TPD_IP_VERSION_SHIFT;
++ hdr_len >>= 1;
++ tpd->word3 |= (hdr_len & TPD_V6_IPHLLO_MASK) <<
++ TPD_V6_IPHLLO_SHIFT;
++ tpd->word3 |= ((hdr_len >> 3) &
++ TPD_V6_IPHLHI_MASK) <<
++ TPD_V6_IPHLHI_SHIFT;
++ tpd->word3 |= (tcp_hdrlen(skb) >> 2 &
++ TPD_TCPHDRLEN_MASK) <<
++ TPD_TCPHDRLEN_SHIFT;
++ tpd->word3 |= ((skb_shinfo(skb)->gso_size) &
++ TPD_MSS_MASK) << TPD_MSS_SHIFT;
++ tpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
++ }
++ }
++ return 0;
+ }
+
+ check_sum:
+@@ -2254,6 +2289,7 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ netdev->features |= NETIF_F_LLTX;
+ netdev->features |= NETIF_F_TSO;
++ netdev->features |= NETIF_F_TSO6;
+
+ return 0;
+ }
+diff --git a/drivers/net/b44.c b/drivers/net/b44.c
+index 4869adb..2a91323 100644
+--- a/drivers/net/b44.c
++++ b/drivers/net/b44.c
+@@ -1505,7 +1505,8 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
+ for (k = 0; k< ethaddr_bytes; k++) {
+ ppattern[offset + magicsync +
+ (j * ETH_ALEN) + k] = macaddr[k];
+- set_bit(len++, (unsigned long *) pmask);
++ len++;
++ set_bit(len, (unsigned long *) pmask);
+ }
+ }
+ return len - 1;
+diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
+index d110c1b..ba29dc3 100644
+--- a/drivers/net/bcm63xx_enet.c
++++ b/drivers/net/bcm63xx_enet.c
+@@ -1248,15 +1248,9 @@ static void bcm_enet_get_drvinfo(struct net_device *netdev,
+ drvinfo->n_stats = BCM_ENET_STATS_LEN;
+ }
+
+-static int bcm_enet_get_sset_count(struct net_device *netdev,
+- int string_set)
++static int bcm_enet_get_stats_count(struct net_device *netdev)
+ {
+- switch (string_set) {
+- case ETH_SS_STATS:
+- return BCM_ENET_STATS_LEN;
+- default:
+- return -EINVAL;
+- }
++ return BCM_ENET_STATS_LEN;
+ }
+
+ static void bcm_enet_get_strings(struct net_device *netdev,
+@@ -1482,7 +1476,7 @@ static int bcm_enet_set_pauseparam(struct net_device *dev,
+
+ static struct ethtool_ops bcm_enet_ethtool_ops = {
+ .get_strings = bcm_enet_get_strings,
+- .get_sset_count = bcm_enet_get_sset_count,
++ .get_stats_count = bcm_enet_get_stats_count,
+ .get_ethtool_stats = bcm_enet_get_ethtool_stats,
+ .get_settings = bcm_enet_get_settings,
+ .set_settings = bcm_enet_set_settings,
+diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
+index 511b922..3b79a22 100644
+--- a/drivers/net/benet/be.h
++++ b/drivers/net/benet/be.h
+@@ -35,31 +35,20 @@
+ #define DRV_VER "2.101.205"
+ #define DRV_NAME "be2net"
+ #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
+-#define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC"
+ #define OC_NAME "Emulex OneConnect 10Gbps NIC"
+-#define OC_NAME1 "Emulex OneConnect 10Gbps NIC (be3)"
+ #define DRV_DESC BE_NAME "Driver"
+
+ #define BE_VENDOR_ID 0x19a2
+ #define BE_DEVICE_ID1 0x211
+-#define BE_DEVICE_ID2 0x221
+ #define OC_DEVICE_ID1 0x700
+ #define OC_DEVICE_ID2 0x701
+-#define OC_DEVICE_ID3 0x710
+
+ static inline char *nic_name(struct pci_dev *pdev)
+ {
+- switch (pdev->device) {
+- case OC_DEVICE_ID1:
+- case OC_DEVICE_ID2:
++ if (pdev->device == OC_DEVICE_ID1 || pdev->device == OC_DEVICE_ID2)
+ return OC_NAME;
+- case OC_DEVICE_ID3:
+- return OC_NAME1;
+- case BE_DEVICE_ID2:
+- return BE3_NAME;
+- default:
++ else
+ return BE_NAME;
+- }
+ }
+
+ /* Number of bytes of an RX frame that are copied to skb->data */
+@@ -272,13 +261,8 @@ struct be_adapter {
+ u32 cap;
+ u32 rx_fc; /* Rx flow control */
+ u32 tx_fc; /* Tx flow control */
+- u8 generation; /* BladeEngine ASIC generation */
+ };
+
+-/* BladeEngine Generation numbers */
+-#define BE_GEN2 2
+-#define BE_GEN3 3
+-
+ extern const struct ethtool_ops be_ethtool_ops;
+
+ #define drvr_stats(adapter) (&adapter->stats.drvr_stats)
+diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
+index ad33d55..e5f9676 100644
+--- a/drivers/net/benet/be_cmds.h
++++ b/drivers/net/benet/be_cmds.h
+@@ -154,8 +154,7 @@ struct be_cmd_req_hdr {
+ u8 domain; /* dword 0 */
+ u32 timeout; /* dword 1 */
+ u32 request_length; /* dword 2 */
+- u8 version; /* dword 3 */
+- u8 rsvd[3]; /* dword 3 */
++ u32 rsvd; /* dword 3 */
+ };
+
+ #define RESP_HDR_INFO_OPCODE_SHIFT 0 /* bits 0 - 7 */
+diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
+index ec983cb..876b357 100644
+--- a/drivers/net/benet/be_main.c
++++ b/drivers/net/benet/be_main.c
+@@ -31,10 +31,8 @@ MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
+
+ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
+ { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
+- { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
+ { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
+ { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
+- { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) },
+ { 0 }
+ };
+ MODULE_DEVICE_TABLE(pci, be_dev_ids);
+@@ -1944,7 +1942,6 @@ static void be_unmap_pci_bars(struct be_adapter *adapter)
+ static int be_map_pci_bars(struct be_adapter *adapter)
+ {
+ u8 __iomem *addr;
+- int pcicfg_reg;
+
+ addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2),
+ pci_resource_len(adapter->pdev, 2));
+@@ -1958,13 +1955,8 @@ static int be_map_pci_bars(struct be_adapter *adapter)
+ goto pci_map_err;
+ adapter->db = addr;
+
+- if (adapter->generation == BE_GEN2)
+- pcicfg_reg = 1;
+- else
+- pcicfg_reg = 0;
+-
+- addr = ioremap_nocache(pci_resource_start(adapter->pdev, pcicfg_reg),
+- pci_resource_len(adapter->pdev, pcicfg_reg));
++ addr = ioremap_nocache(pci_resource_start(adapter->pdev, 1),
++ pci_resource_len(adapter->pdev, 1));
+ if (addr == NULL)
+ goto pci_map_err;
+ adapter->pcicfg = addr;
+@@ -2034,7 +2026,6 @@ static int be_stats_init(struct be_adapter *adapter)
+ cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma);
+ if (cmd->va == NULL)
+ return -1;
+- memset(cmd->va, 0, cmd->size);
+ return 0;
+ }
+
+@@ -2108,20 +2099,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ goto rel_reg;
+ }
+ adapter = netdev_priv(netdev);
+-
+- switch (pdev->device) {
+- case BE_DEVICE_ID1:
+- case OC_DEVICE_ID1:
+- adapter->generation = BE_GEN2;
+- break;
+- case BE_DEVICE_ID2:
+- case OC_DEVICE_ID2:
+- adapter->generation = BE_GEN3;
+- break;
+- default:
+- adapter->generation = 0;
+- }
+-
+ adapter->pdev = pdev;
+ pci_set_drvdata(pdev, adapter);
+ adapter->netdev = netdev;
+diff --git a/drivers/net/e100.c b/drivers/net/e100.c
+index 0c53c92..d269a68 100644
+--- a/drivers/net/e100.c
++++ b/drivers/net/e100.c
+@@ -1817,7 +1817,6 @@ static int e100_alloc_cbs(struct nic *nic)
+ &nic->cbs_dma_addr);
+ if (!nic->cbs)
+ return -ENOMEM;
+- memset(nic->cbs, 0, count * sizeof(struct cb));
+
+ for (cb = nic->cbs, i = 0; i < count; cb++, i++) {
+ cb->next = (i + 1 < count) ? cb + 1 : nic->cbs;
+@@ -1826,6 +1825,7 @@ static int e100_alloc_cbs(struct nic *nic)
+ cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb);
+ cb->link = cpu_to_le32(nic->cbs_dma_addr +
+ ((i+1) % count) * sizeof(struct cb));
++ cb->skb = NULL;
+ }
+
+ nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs;
+diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
+index 4a2ee85..42e2b7e 100644
+--- a/drivers/net/e1000/e1000.h
++++ b/drivers/net/e1000/e1000.h
+@@ -326,8 +326,6 @@ struct e1000_adapter {
+ /* for ioport free */
+ int bars;
+ int need_ioport;
+-
+- bool discarding;
+ };
+
+ enum e1000_state_t {
+diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
+index 1a23f16..bcd192c 100644
+--- a/drivers/net/e1000/e1000_main.c
++++ b/drivers/net/e1000/e1000_main.c
+@@ -1698,6 +1698,18 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
+ rctl &= ~E1000_RCTL_SZ_4096;
+ rctl |= E1000_RCTL_BSEX;
+ switch (adapter->rx_buffer_len) {
++ case E1000_RXBUFFER_256:
++ rctl |= E1000_RCTL_SZ_256;
++ rctl &= ~E1000_RCTL_BSEX;
++ break;
++ case E1000_RXBUFFER_512:
++ rctl |= E1000_RCTL_SZ_512;
++ rctl &= ~E1000_RCTL_BSEX;
++ break;
++ case E1000_RXBUFFER_1024:
++ rctl |= E1000_RCTL_SZ_1024;
++ rctl &= ~E1000_RCTL_BSEX;
++ break;
+ case E1000_RXBUFFER_2048:
+ default:
+ rctl |= E1000_RCTL_SZ_2048;
+@@ -3142,7 +3154,13 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
+ * however with the new *_jumbo_rx* routines, jumbo receives will use
+ * fragmented skbs */
+
+- if (max_frame <= E1000_RXBUFFER_2048)
++ if (max_frame <= E1000_RXBUFFER_256)
++ adapter->rx_buffer_len = E1000_RXBUFFER_256;
++ else if (max_frame <= E1000_RXBUFFER_512)
++ adapter->rx_buffer_len = E1000_RXBUFFER_512;
++ else if (max_frame <= E1000_RXBUFFER_1024)
++ adapter->rx_buffer_len = E1000_RXBUFFER_1024;
++ else if (max_frame <= E1000_RXBUFFER_2048)
+ adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+ else
+ #if (PAGE_SIZE >= E1000_RXBUFFER_16384)
+@@ -3809,22 +3827,13 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
+
+ length = le16_to_cpu(rx_desc->length);
+ /* !EOP means multiple descriptors were used to store a single
+- * packet, if thats the case we need to toss it. In fact, we
+- * to toss every packet with the EOP bit clear and the next
+- * frame that _does_ have the EOP bit set, as it is by
+- * definition only a frame fragment
+- */
+- if (unlikely(!(status & E1000_RXD_STAT_EOP)))
+- adapter->discarding = true;
+-
+- if (adapter->discarding) {
++ * packet, also make sure the frame isn't just CRC only */
++ if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) {
+ /* All receives must fit into a single buffer */
+ E1000_DBG("%s: Receive packet consumed multiple"
+ " buffers\n", netdev->name);
+ /* recycle */
+ buffer_info->skb = skb;
+- if (status & E1000_RXD_STAT_EOP)
+- adapter->discarding = false;
+ goto next_desc;
+ }
+
+diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
+index 47db9bd..3e187b0 100644
+--- a/drivers/net/e1000e/e1000.h
++++ b/drivers/net/e1000e/e1000.h
+@@ -417,7 +417,6 @@ struct e1000_info {
+ /* CRC Stripping defines */
+ #define FLAG2_CRC_STRIPPING (1 << 0)
+ #define FLAG2_HAS_PHY_WAKEUP (1 << 1)
+-#define FLAG2_IS_DISCARDING (1 << 2)
+
+ #define E1000_RX_DESC_PS(R, i) \
+ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
+diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
+index 2154530..fad8f9e 100644
+--- a/drivers/net/e1000e/netdev.c
++++ b/drivers/net/e1000e/netdev.c
+@@ -482,24 +482,14 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
+
+ length = le16_to_cpu(rx_desc->length);
+
+- /*
+- * !EOP means multiple descriptors were used to store a single
+- * packet, if that's the case we need to toss it. In fact, we
+- * need to toss every packet with the EOP bit clear and the
+- * next frame that _does_ have the EOP bit set, as it is by
+- * definition only a frame fragment
+- */
+- if (unlikely(!(status & E1000_RXD_STAT_EOP)))
+- adapter->flags2 |= FLAG2_IS_DISCARDING;
+-
+- if (adapter->flags2 & FLAG2_IS_DISCARDING) {
++ /* !EOP means multiple descriptors were used to store a single
++ * packet, also make sure the frame isn't just CRC only */
++ if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) {
+ /* All receives must fit into a single buffer */
+ e_dbg("%s: Receive packet consumed multiple buffers\n",
+ netdev->name);
+ /* recycle */
+ buffer_info->skb = skb;
+- if (status & E1000_RXD_STAT_EOP)
+- adapter->flags2 &= ~FLAG2_IS_DISCARDING;
+ goto next_desc;
+ }
+
+@@ -757,16 +747,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+ PCI_DMA_FROMDEVICE);
+ buffer_info->dma = 0;
+
+- /* see !EOP comment in other rx routine */
+- if (!(staterr & E1000_RXD_STAT_EOP))
+- adapter->flags2 |= FLAG2_IS_DISCARDING;
+-
+- if (adapter->flags2 & FLAG2_IS_DISCARDING) {
++ if (!(staterr & E1000_RXD_STAT_EOP)) {
+ e_dbg("%s: Packet Split buffers didn't pick up the "
+ "full packet\n", netdev->name);
+ dev_kfree_skb_irq(skb);
+- if (staterr & E1000_RXD_STAT_EOP)
+- adapter->flags2 &= ~FLAG2_IS_DISCARDING;
+ goto next_desc;
+ }
+
+@@ -1136,7 +1120,6 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
+
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+- adapter->flags2 &= ~FLAG2_IS_DISCARDING;
+
+ writel(0, adapter->hw.hw_addr + rx_ring->head);
+ writel(0, adapter->hw.hw_addr + rx_ring->tail);
+@@ -2347,6 +2330,18 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
+ rctl &= ~E1000_RCTL_SZ_4096;
+ rctl |= E1000_RCTL_BSEX;
+ switch (adapter->rx_buffer_len) {
++ case 256:
++ rctl |= E1000_RCTL_SZ_256;
++ rctl &= ~E1000_RCTL_BSEX;
++ break;
++ case 512:
++ rctl |= E1000_RCTL_SZ_512;
++ rctl &= ~E1000_RCTL_BSEX;
++ break;
++ case 1024:
++ rctl |= E1000_RCTL_SZ_1024;
++ rctl &= ~E1000_RCTL_BSEX;
++ break;
+ case 2048:
+ default:
+ rctl |= E1000_RCTL_SZ_2048;
+@@ -4326,7 +4321,13 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
+ * fragmented skbs
+ */
+
+- if (max_frame <= 2048)
++ if (max_frame <= 256)
++ adapter->rx_buffer_len = 256;
++ else if (max_frame <= 512)
++ adapter->rx_buffer_len = 512;
++ else if (max_frame <= 1024)
++ adapter->rx_buffer_len = 1024;
++ else if (max_frame <= 2048)
+ adapter->rx_buffer_len = 2048;
+ else
+ adapter->rx_buffer_len = 4096;
+diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
+index 35d896b..a2fc70a 100644
+--- a/drivers/net/qlge/qlge_main.c
++++ b/drivers/net/qlge/qlge_main.c
+@@ -3310,8 +3310,10 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
+
+ /* Initialize the port and set the max framesize. */
+ status = qdev->nic_ops->port_initialize(qdev);
+- if (status)
+- QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
++ if (status) {
++ QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
++ return status;
++ }
+
+ /* Set up the MAC address and frame routing filter. */
+ status = ql_cam_route_initialize(qdev);
+@@ -3712,6 +3714,9 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
+ struct sockaddr *addr = p;
+ int status;
+
++ if (netif_running(ndev))
++ return -EBUSY;
++
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+ memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
+@@ -3863,7 +3868,8 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
+ struct net_device *ndev, int cards_found)
+ {
+ struct ql_adapter *qdev = netdev_priv(ndev);
+- int err = 0;
++ int pos, err = 0;
++ u16 val16;
+
+ memset((void *)qdev, 0, sizeof(*qdev));
+ err = pci_enable_device(pdev);
+@@ -3875,12 +3881,18 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
+ qdev->ndev = ndev;
+ qdev->pdev = pdev;
+ pci_set_drvdata(pdev, ndev);
+-
+- /* Set PCIe read request size */
+- err = pcie_set_readrq(pdev, 4096);
+- if (err) {
+- dev_err(&pdev->dev, "Set readrq failed.\n");
+- goto err_out;
++ pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
++ if (pos <= 0) {
++ dev_err(&pdev->dev, PFX "Cannot find PCI Express capability, "
++ "aborting.\n");
++ return pos;
++ } else {
++ pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16);
++ val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN;
++ val16 |= (PCI_EXP_DEVCTL_CERE |
++ PCI_EXP_DEVCTL_NFERE |
++ PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE);
++ pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, val16);
+ }
+
+ err = pci_request_regions(pdev, DRV_NAME);
+diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
+index 32b1e1f..aec05f2 100644
+--- a/drivers/net/qlge/qlge_mpi.c
++++ b/drivers/net/qlge/qlge_mpi.c
+@@ -446,9 +446,6 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
+ ql_aen_lost(qdev, mbcp);
+ break;
+
+- case AEN_DCBX_CHG:
+- /* Need to support AEN 8110 */
+- break;
+ default:
+ QPRINTK(qdev, DRV, ERR,
+ "Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
+diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
+index d443ad7..489c4de 100644
+--- a/drivers/net/sfc/tx.c
++++ b/drivers/net/sfc/tx.c
+@@ -821,6 +821,8 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
+ tx_queue->efx->type->txd_ring_mask];
+ efx_tsoh_free(tx_queue, buffer);
+ EFX_BUG_ON_PARANOID(buffer->skb);
++ buffer->len = 0;
++ buffer->continuation = true;
+ if (buffer->unmap_len) {
+ unmap_addr = (buffer->dma_addr + buffer->len -
+ buffer->unmap_len);
+@@ -834,8 +836,6 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
+ PCI_DMA_TODEVICE);
+ buffer->unmap_len = 0;
+ }
+- buffer->len = 0;
+- buffer->continuation = true;
+ }
+ }
+
+diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
+index f3600b3..6a10d7b 100644
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -1806,8 +1806,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
+ sky2->tx_cons = idx;
+ smp_mb();
+
+- /* Wake unless it's detached, and called e.g. from sky2_down() */
+- if (tx_avail(sky2) > MAX_SKB_TX_LE + 4 && netif_device_present(dev))
++ if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
+ netif_wake_queue(dev);
+ }
+
+diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
+index e65ee4d..a36e2b5 100644
+--- a/drivers/net/starfire.c
++++ b/drivers/net/starfire.c
+@@ -1063,7 +1063,7 @@ static int netdev_open(struct net_device *dev)
+ if (retval) {
+ printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n",
+ FIRMWARE_RX);
+- goto out_init;
++ return retval;
+ }
+ if (fw_rx->size % 4) {
+ printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n",
+@@ -1108,9 +1108,6 @@ out_tx:
+ release_firmware(fw_tx);
+ out_rx:
+ release_firmware(fw_rx);
+-out_init:
+- if (retval)
+- netdev_close(dev);
+ return retval;
+ }
+
+diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
+index f14d225..b091e20 100644
+--- a/drivers/net/usb/rtl8150.c
++++ b/drivers/net/usb/rtl8150.c
+@@ -324,7 +324,7 @@ static int rtl8150_set_mac_address(struct net_device *netdev, void *p)
+ dbg("%02X:", netdev->dev_addr[i]);
+ dbg("%02X\n", netdev->dev_addr[i]);
+ /* Set the IDR registers. */
+- set_registers(dev, IDR, netdev->addr_len, netdev->dev_addr);
++ set_registers(dev, IDR, sizeof(netdev->dev_addr), netdev->dev_addr);
+ #ifdef EEPROM_WRITE
+ {
+ u8 cr;
+diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
+index f141a4f..e974e58 100644
+--- a/drivers/net/wireless/ath/ar9170/usb.c
++++ b/drivers/net/wireless/ath/ar9170/usb.c
+@@ -68,10 +68,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
+ { USB_DEVICE(0x0cf3, 0x1002) },
+ /* Cace Airpcap NX */
+ { USB_DEVICE(0xcace, 0x0300) },
+- /* D-Link DWA 160 A1 */
++ /* D-Link DWA 160A */
+ { USB_DEVICE(0x07d1, 0x3c10) },
+- /* D-Link DWA 160 A2 */
+- { USB_DEVICE(0x07d1, 0x3a09) },
+ /* Netgear WNDA3100 */
+ { USB_DEVICE(0x0846, 0x9010) },
+ /* Netgear WN111 v2 */
+diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
+index 8a82c75..95a8e23 100644
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -2349,9 +2349,6 @@ ath5k_init(struct ath5k_softc *sc)
+ */
+ ath5k_stop_locked(sc);
+
+- /* Set PHY calibration interval */
+- ah->ah_cal_intval = ath5k_calinterval;
+-
+ /*
+ * The basic interface to setting the hardware in a good
+ * state is ``reset''. On return the hardware is known to
+@@ -2379,6 +2376,10 @@ ath5k_init(struct ath5k_softc *sc)
+
+ /* Set ack to be sent at low bit-rates */
+ ath5k_hw_set_ack_bitrate_high(ah, false);
++
++ /* Set PHY calibration inteval */
++ ah->ah_cal_intval = ath5k_calinterval;
++
+ ret = 0;
+ done:
+ mmiowb();
+diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
+index 9a96550..644962a 100644
+--- a/drivers/net/wireless/ath/ath5k/eeprom.c
++++ b/drivers/net/wireless/ath/ath5k/eeprom.c
+@@ -97,7 +97,6 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ int ret;
+ u16 val;
+- u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX;
+
+ /*
+ * Read values from EEPROM and store them in the capability structure
+@@ -112,44 +111,20 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
+ if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
+ return 0;
+
++#ifdef notyet
+ /*
+ * Validate the checksum of the EEPROM date. There are some
+ * devices with invalid EEPROMs.
+ */
+- AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val);
+- if (val) {
+- eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) <<
+- AR5K_EEPROM_SIZE_ENDLOC_SHIFT;
+- AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val);
+- eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE;
+-
+- /*
+- * Fail safe check to prevent stupid loops due
+- * to busted EEPROMs. XXX: This value is likely too
+- * big still, waiting on a better value.
+- */
+- if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) {
+- ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: "
+- "%d (0x%04x) max expected: %d (0x%04x)\n",
+- eep_max, eep_max,
+- 3 * AR5K_EEPROM_INFO_MAX,
+- 3 * AR5K_EEPROM_INFO_MAX);
+- return -EIO;
+- }
+- }
+-
+- for (cksum = 0, offset = 0; offset < eep_max; offset++) {
++ for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
+ AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
+ cksum ^= val;
+ }
+ if (cksum != AR5K_EEPROM_INFO_CKSUM) {
+- ATH5K_ERR(ah->ah_sc, "Invalid EEPROM "
+- "checksum: 0x%04x eep_max: 0x%04x (%s)\n",
+- cksum, eep_max,
+- eep_max == AR5K_EEPROM_INFO_MAX ?
+- "default size" : "custom size");
++ ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
+ return -EIO;
+ }
++#endif
+
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
+ ee_ant_gain);
+diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
+index 473a483..0123f35 100644
+--- a/drivers/net/wireless/ath/ath5k/eeprom.h
++++ b/drivers/net/wireless/ath/ath5k/eeprom.h
+@@ -37,14 +37,6 @@
+ #define AR5K_EEPROM_RFKILL_POLARITY_S 1
+
+ #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
+-
+-/* FLASH(EEPROM) Defines for AR531X chips */
+-#define AR5K_EEPROM_SIZE_LOWER 0x1b /* size info -- lower */
+-#define AR5K_EEPROM_SIZE_UPPER 0x1c /* size info -- upper */
+-#define AR5K_EEPROM_SIZE_UPPER_MASK 0xfff0
+-#define AR5K_EEPROM_SIZE_UPPER_SHIFT 4
+-#define AR5K_EEPROM_SIZE_ENDLOC_SHIFT 12
+-
+ #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */
+ #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
+ #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
+diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
+index 9d67647..1a039f2 100644
+--- a/drivers/net/wireless/ath/ath5k/phy.c
++++ b/drivers/net/wireless/ath/ath5k/phy.c
+@@ -2954,6 +2954,8 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+ ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
+ return -EINVAL;
+ }
++ if (txpower == 0)
++ txpower = AR5K_TUNE_DEFAULT_TXPOWER;
+
+ /* Reset TX power values */
+ memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
+diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
+index cdb90c5..1d59f10 100644
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -139,7 +139,6 @@ struct ath_buf {
+ dma_addr_t bf_daddr; /* physical addr of desc */
+ dma_addr_t bf_buf_addr; /* physical addr of data buffer */
+ bool bf_stale;
+- bool bf_isnullfunc;
+ u16 bf_flags;
+ struct ath_buf_state bf_state;
+ dma_addr_t bf_dmacontext;
+@@ -525,8 +524,6 @@ struct ath_led {
+ #define SC_OP_BEACON_SYNC BIT(19)
+ #define SC_OP_BTCOEX_ENABLED BIT(20)
+ #define SC_OP_BT_PRIORITY_DETECTED BIT(21)
+-#define SC_OP_NULLFUNC_COMPLETED BIT(22)
+-#define SC_OP_PS_ENABLED BIT(23)
+
+ struct ath_bus_ops {
+ void (*read_cachesize)(struct ath_softc *sc, int *csz);
+diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
+index 0905b38..ca7694c 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -880,11 +880,12 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
+ }
+ }
+
+-static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
++static void ath9k_hw_init_11a_eeprom_fix(struct ath_hw *ah)
+ {
+ u32 i, j;
+
+- if (ah->hw_version.devid == AR9280_DEVID_PCI) {
++ if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
++ test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
+
+ /* EEPROM Fixup */
+ for (i = 0; i < ah->iniModes.ia_rows; i++) {
+@@ -936,11 +937,6 @@ int ath9k_hw_init(struct ath_hw *ah)
+ DPRINTF(ah->ah_sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
+ ah->config.serialize_regmode);
+
+- if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+- ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
+- else
+- ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
+-
+ if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "Mac Chip Rev 0x%02x.%x is not supported by "
+@@ -979,7 +975,7 @@ int ath9k_hw_init(struct ath_hw *ah)
+
+ ath9k_hw_init_mode_gain_regs(ah);
+ ath9k_hw_fill_cap_info(ah);
+- ath9k_hw_init_eeprom_fix(ah);
++ ath9k_hw_init_11a_eeprom_fix(ah);
+
+ r = ath9k_hw_init_macaddr(ah);
+ if (r) {
+@@ -3674,11 +3670,7 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
+ pCap->keycache_size = AR_KEYTABLE_SIZE;
+
+ pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
+-
+- if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+- pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
+- else
+- pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
++ pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
+
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ pCap->num_gpio_pins = AR9285_NUM_GPIO;
+diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
+index ff4383b..b892345 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -218,7 +218,6 @@ struct ath9k_ops_config {
+ #define AR_SPUR_FEEQ_BOUND_HT20 10
+ int spurmode;
+ u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
+- u8 max_txtrig_level;
+ };
+
+ enum ath9k_int {
+@@ -408,7 +407,7 @@ struct ath9k_hw_version {
+ * Using de Bruijin sequence to to look up 1's index in a 32 bit number
+ * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001
+ */
+-#define debruijn32 0x077CB531U
++#define debruijn32 0x077CB531UL
+
+ struct ath_gen_timer_configuration {
+ u32 next_addr;
+diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
+index 110c16d..800bfab 100644
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -70,7 +70,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
+ u32 txcfg, curLevel, newLevel;
+ enum ath9k_int omask;
+
+- if (ah->tx_trig_level >= ah->config.max_txtrig_level)
++ if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
+ return false;
+
+ omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
+@@ -79,7 +79,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
+ curLevel = MS(txcfg, AR_FTRIG);
+ newLevel = curLevel;
+ if (bIncTrigLevel) {
+- if (curLevel < ah->config.max_txtrig_level)
++ if (curLevel < MAX_TX_FIFO_THRESHOLD)
+ newLevel++;
+ } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
+ newLevel--;
+@@ -155,7 +155,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
+ wait = wait_time;
+ while (ath9k_hw_numtxpending(ah, q)) {
+ if ((--wait) == 0) {
+- DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
++ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+ "Failed to stop TX DMA in 100 "
+ "msec after killing last frame\n");
+ break;
+@@ -222,8 +222,6 @@ int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
+ ds->ds_txstat.ts_status = 0;
+ ds->ds_txstat.ts_flags = 0;
+
+- if (ads->ds_txstatus1 & AR_FrmXmitOK)
+- ds->ds_txstat.ts_status |= ATH9K_TX_ACKED;
+ if (ads->ds_txstatus1 & AR_ExcessiveRetries)
+ ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
+ if (ads->ds_txstatus1 & AR_Filtered)
+diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
+index 9720c4d..f56e77d 100644
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -76,10 +76,6 @@
+ #define ATH9K_TXERR_FIFO 0x04
+ #define ATH9K_TXERR_XTXOP 0x08
+ #define ATH9K_TXERR_TIMER_EXPIRED 0x10
+-#define ATH9K_TX_ACKED 0x20
+-#define ATH9K_TXERR_MASK \
+- (ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO | \
+- ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED)
+
+ #define ATH9K_TX_BA 0x01
+ #define ATH9K_TX_PWRMGMT 0x02
+diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
+index 5864eaa..43d2be9 100644
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -2147,9 +2147,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
+ return; /* another wiphy still in use */
+ }
+
+- /* Ensure HW is awake when we try to shut it down. */
+- ath9k_ps_wakeup(sc);
+-
+ if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) {
+ ath9k_hw_btcoex_disable(sc->sc_ah);
+ if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+@@ -2170,9 +2167,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
+ /* disable HAL and put h/w to sleep */
+ ath9k_hw_disable(sc->sc_ah);
+ ath9k_hw_configpcipowersave(sc->sc_ah, 1, 1);
+- ath9k_ps_restore(sc);
+-
+- /* Finally, put the chip in FULL SLEEP mode */
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
+
+ sc->sc_flags |= SC_OP_INVALID;
+@@ -2283,12 +2277,10 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
+ (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+ (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
+- ath9k_ps_wakeup(sc);
+ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+- ath9k_ps_restore(sc);
++ ath_beacon_return(sc, avp);
+ }
+
+- ath_beacon_return(sc, avp);
+ sc->sc_flags &= ~SC_OP_BEACONS;
+
+ for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+@@ -2335,7 +2327,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
+
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ if (conf->flags & IEEE80211_CONF_PS) {
+- sc->sc_flags |= SC_OP_PS_ENABLED;
+ if (!(ah->caps.hw_caps &
+ ATH9K_HW_CAP_AUTOSLEEP)) {
+ if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
+@@ -2343,17 +2334,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
+ ath9k_hw_set_interrupts(sc->sc_ah,
+ sc->imask);
+ }
+- }
+- sc->ps_enabled = true;
+- if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) {
+- sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
+- sc->ps_enabled = true;
+ ath9k_hw_setrxabort(sc->sc_ah, 1);
+ }
++ sc->ps_enabled = true;
+ } else {
+ sc->ps_enabled = false;
+- sc->sc_flags &= ~(SC_OP_PS_ENABLED |
+- SC_OP_NULLFUNC_COMPLETED);
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+ if (!(ah->caps.hw_caps &
+ ATH9K_HW_CAP_AUTOSLEEP)) {
+@@ -2732,21 +2717,15 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
+ case IEEE80211_AMPDU_RX_STOP:
+ break;
+ case IEEE80211_AMPDU_TX_START:
+- ath9k_ps_wakeup(sc);
+ ath_tx_aggr_start(sc, sta, tid, ssn);
+ ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+- ath9k_ps_restore(sc);
+ break;
+ case IEEE80211_AMPDU_TX_STOP:
+- ath9k_ps_wakeup(sc);
+ ath_tx_aggr_stop(sc, sta, tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+- ath9k_ps_restore(sc);
+ break;
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+- ath9k_ps_wakeup(sc);
+ ath_tx_aggr_resume(sc, sta, tid);
+- ath9k_ps_restore(sc);
+ break;
+ default:
+ DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n");
+diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
+index c0d7e65..d83b77f 100644
+--- a/drivers/net/wireless/ath/ath9k/reg.h
++++ b/drivers/net/wireless/ath/ath9k/reg.h
+@@ -969,10 +969,10 @@ enum {
+ #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S 4
+ #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080
+ #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7
+-#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB 0x00000400
+-#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S 10
+ #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB 0x00001000
+ #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S 12
++#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB 0x00001000
++#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S 1
+ #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000
+ #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15
+ #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
+diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
+index 9009bac..42551a4 100644
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -1076,10 +1076,10 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+ if (npend) {
+ int r;
+
+- DPRINTF(sc, ATH_DBG_FATAL, "Unable to stop TxDMA. Reset HAL!\n");
++ DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
+
+ spin_lock_bh(&sc->sc_resetlock);
+- r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
++ r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
+ if (r)
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Unable to reset hardware; reset status %d\n",
+@@ -1563,7 +1563,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
+
+ bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
+
+- if (conf_is_ht(&sc->hw->conf))
++ if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+ bf->bf_state.bf_type |= BUF_HT;
+
+ bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+@@ -1592,13 +1592,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
+ }
+
+ bf->bf_buf_addr = bf->bf_dmacontext;
+-
+- if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
+- bf->bf_isnullfunc = true;
+- sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
+- } else
+- bf->bf_isnullfunc = false;
+-
+ return 0;
+ }
+
+@@ -1648,7 +1641,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+ goto tx_done;
+ }
+
+- if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) {
++ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ /*
+ * Try aggregation if it's a unicast data frame
+ * and the destination is HT capable.
+@@ -1996,15 +1989,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
+ if (ds == txq->axq_gatingds)
+ txq->axq_gatingds = NULL;
+
+- if (bf->bf_isnullfunc &&
+- (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) {
+- if ((sc->sc_flags & SC_OP_PS_ENABLED)) {
+- sc->ps_enabled = true;
+- ath9k_hw_setrxabort(sc->sc_ah, 1);
+- } else
+- sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED;
+- }
+-
+ /*
+ * Remove ath_buf's of the same transmit unit from txq,
+ * however leave the last descriptor back as the holding
+@@ -2020,7 +2004,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
+ if (bf_isaggr(bf))
+ txq->axq_aggr_depth--;
+
+- txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK);
++ txok = (ds->ds_txstat.ts_status == 0);
+ txq->axq_tx_inprogress = false;
+ spin_unlock_bh(&txq->axq_lock);
+
+@@ -2081,9 +2065,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
+
+ if (needreset) {
+ DPRINTF(sc, ATH_DBG_RESET, "tx hung, resetting the chip\n");
+- ath9k_ps_wakeup(sc);
+ ath_reset(sc, false);
+- ath9k_ps_restore(sc);
+ }
+
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
+index 0e6b154..6607162 100644
+--- a/drivers/net/wireless/b43/b43.h
++++ b/drivers/net/wireless/b43/b43.h
+@@ -117,7 +117,6 @@
+ #define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */
+ #define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */
+ #define B43_MMIO_RNG 0x65A
+-#define B43_MMIO_IFSSLOT 0x684 /* Interframe slot time */
+ #define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
+ #define B43_MMIO_IFSCTL_USE_EDCF 0x0004
+ #define B43_MMIO_POWERUP_DELAY 0x6A8
+diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
+index 9ca253e..098dda1 100644
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -628,17 +628,10 @@ static void b43_upload_card_macaddress(struct b43_wldev *dev)
+ static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time)
+ {
+ /* slot_time is in usec. */
+- /* This test used to exit for all but a G PHY. */
+- if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
++ if (dev->phy.type != B43_PHYTYPE_G)
+ return;
+- b43_write16(dev, B43_MMIO_IFSSLOT, 510 + slot_time);
+- /* Shared memory location 0x0010 is the slot time and should be
+- * set to slot_time; however, this register is initially 0 and changing
+- * the value adversely affects the transmit rate for BCM4311
+- * devices. Until this behavior is unterstood, delete this step
+- *
+- * b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);
+- */
++ b43_write16(dev, 0x684, 510 + slot_time);
++ b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);
+ }
+
+ static void b43_short_slot_timing_enable(struct b43_wldev *dev)
+diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
+index 78016ae..ffdce6f 100644
+--- a/drivers/net/wireless/b43/rfkill.c
++++ b/drivers/net/wireless/b43/rfkill.c
+@@ -33,14 +33,8 @@ bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
+ & B43_MMIO_RADIO_HWENABLED_HI_MASK))
+ return 1;
+ } else {
+- /* To prevent CPU fault on PPC, do not read a register
+- * unless the interface is started; however, on resume
+- * for hibernation, this routine is entered early. When
+- * that happens, unconditionally return TRUE.
+- */
+- if (b43_status(dev) < B43_STAT_STARTED)
+- return 1;
+- if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
++ if (b43_status(dev) >= B43_STAT_STARTED &&
++ b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
+ & B43_MMIO_RADIO_HWENABLED_LO_MASK)
+ return 1;
+ }
+diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
+index d579df7..8783022 100644
+--- a/drivers/net/wireless/b43legacy/rfkill.c
++++ b/drivers/net/wireless/b43legacy/rfkill.c
+@@ -34,13 +34,6 @@ bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
+ & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK))
+ return 1;
+ } else {
+- /* To prevent CPU fault on PPC, do not read a register
+- * unless the interface is started; however, on resume
+- * for hibernation, this routine is entered early. When
+- * that happens, unconditionally return TRUE.
+- */
+- if (b43legacy_status(dev) < B43legacy_STAT_STARTED)
+- return 1;
+ if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO)
+ & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK)
+ return 1;
+diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
+index 43102bf..6e2fc0c 100644
+--- a/drivers/net/wireless/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/ipw2x00/ipw2100.c
+@@ -6487,16 +6487,6 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
+ }
+ #endif
+
+-static void ipw2100_shutdown(struct pci_dev *pci_dev)
+-{
+- struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
+-
+- /* Take down the device; powers it off, etc. */
+- ipw2100_down(priv);
+-
+- pci_disable_device(pci_dev);
+-}
+-
+ #define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
+
+ static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
+@@ -6560,7 +6550,6 @@ static struct pci_driver ipw2100_pci_driver = {
+ .suspend = ipw2100_suspend,
+ .resume = ipw2100_resume,
+ #endif
+- .shutdown = ipw2100_shutdown,
+ };
+
+ /**
+diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
+index 9d60f6c..f059b49 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
++++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
+@@ -2895,7 +2895,6 @@ static struct iwl_cfg iwl3945_bg_cfg = {
+ .mod_params = &iwl3945_mod_params,
+ .use_isr_legacy = true,
+ .ht_greenfield_support = false,
+- .broken_powersave = true,
+ };
+
+ static struct iwl_cfg iwl3945_abg_cfg = {
+@@ -2910,7 +2909,6 @@ static struct iwl_cfg iwl3945_abg_cfg = {
+ .mod_params = &iwl3945_mod_params,
+ .use_isr_legacy = true,
+ .ht_greenfield_support = false,
+- .broken_powersave = true,
+ };
+
+ struct pci_device_id iwl3945_hw_card_ids[] = {
+diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
+index 99331ed..6f703a0 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
++++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
+@@ -1337,7 +1337,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
+ iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info);
+
+ /* calculate tx gain adjustment based on power supply voltage */
+- voltage = le16_to_cpu(priv->calib_info->voltage);
++ voltage = priv->calib_info->voltage;
+ init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage);
+ voltage_compensation =
+ iwl4965_get_voltage_compensation(voltage, init_voltage);
+@@ -2087,7 +2087,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
+ struct ieee80211_tx_info *info;
+ struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+ u32 status = le32_to_cpu(tx_resp->u.status);
+- int tid = MAX_TID_COUNT - 1;
++ int tid = MAX_TID_COUNT;
+ int sta_id;
+ int freed;
+ u8 *qc = NULL;
+diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+index bc056e9..4ef6804 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
++++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+@@ -92,15 +92,11 @@
+
+ static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
+ {
+- u16 temperature, voltage;
+- __le16 *temp_calib =
+- (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE);
+-
+- temperature = le16_to_cpu(temp_calib[0]);
+- voltage = le16_to_cpu(temp_calib[1]);
+-
+- /* offset = temp - volt / coeff */
+- return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
++ u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
++ EEPROM_5000_TEMPERATURE);
++ /* offset = temperature - voltage / coef */
++ s32 offset = (s32)(temp_calib[0] - temp_calib[1] / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
++ return offset;
+ }
+
+ /* Fixed (non-configurable) rx data from phy */
+diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
+index 133df70..6e6f516 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
+@@ -460,15 +460,14 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
+ static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
+ {
+ struct iwl_calib_xtal_freq_cmd cmd;
+- __le16 *xtal_calib =
+- (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
++ u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
+
+ cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
+ cmd.hdr.first_group = 0;
+ cmd.hdr.groups_num = 1;
+ cmd.hdr.data_valid = 1;
+- cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
+- cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
++ cmd.cap_pin1 = (u8)xtal_calib[0];
++ cmd.cap_pin2 = (u8)xtal_calib[1];
+ return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
+ (u8 *)&cmd, sizeof(cmd));
+ }
+@@ -1666,7 +1665,6 @@ struct iwl_cfg iwl5300_agn_cfg = {
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = true,
+ .ht_greenfield_support = true,
+- .use_rts_for_ht = true, /* use rts/cts protection */
+ };
+
+ struct iwl_cfg iwl5100_bg_cfg = {
+@@ -1718,7 +1716,6 @@ struct iwl_cfg iwl5100_agn_cfg = {
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
+ .ht_greenfield_support = true,
+- .use_rts_for_ht = true, /* use rts/cts protection */
+ };
+
+ struct iwl_cfg iwl5350_agn_cfg = {
+@@ -1736,7 +1733,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = true,
+ .ht_greenfield_support = true,
+- .use_rts_for_ht = true, /* use rts/cts protection */
+ };
+
+ struct iwl_cfg iwl5150_agn_cfg = {
+@@ -1754,7 +1750,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
+ .ht_greenfield_support = true,
+- .use_rts_for_ht = true, /* use rts/cts protection */
+ };
+
+ MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
+diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+index 0eb2591..81726ee 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+@@ -2808,7 +2808,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
+ repeat_rate--;
+ }
+
+- lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
++ lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_MAX;
+ lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+ lq_cmd->agg_params.agg_time_limit =
+ cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
+index 0cd4ec4..2dc9287 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-core.c
++++ b/drivers/net/wireless/iwlwifi/iwl-core.c
+@@ -2645,7 +2645,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
+ if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
+ priv->staging_rxon.flags = 0;
+
+- iwl_set_rxon_ht(priv, ht_conf);
+ iwl_set_rxon_channel(priv, conf->channel);
+
+ iwl_set_flags_for_band(priv, conf->channel->band);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
+index cea2ee2..028d505 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
++++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
+@@ -703,7 +703,7 @@ extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
+ extern int iwl_queue_space(const struct iwl_queue *q);
+ static inline int iwl_queue_used(const struct iwl_queue *q, int i)
+ {
+- return q->write_ptr >= q->read_ptr ?
++ return q->write_ptr > q->read_ptr ?
+ (i >= q->read_ptr && i < q->write_ptr) :
+ !(i < q->read_ptr && i >= q->write_ptr);
+ }
+@@ -1149,7 +1149,7 @@ struct iwl_priv {
+ u32 last_beacon_time;
+ u64 last_tsf;
+
+- /* eeprom -- this is in the card's little endian byte order */
++ /* eeprom */
+ u8 *eeprom;
+ int nvm_device_type;
+ struct iwl_eeprom_calib_info *calib_info;
+diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+index 18dc3a4..e14c995 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
++++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+@@ -337,7 +337,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
+ return ret;
+ }
+
+-static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_data)
++static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
+ {
+ int ret = 0;
+ u32 r;
+@@ -370,7 +370,7 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat
+ CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
+ IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
+ }
+- *eeprom_data = cpu_to_le16(r >> 16);
++ *eeprom_data = le16_to_cpu((__force __le16)(r >> 16));
+ return 0;
+ }
+
+@@ -379,8 +379,7 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat
+ */
+ static bool iwl_is_otp_empty(struct iwl_priv *priv)
+ {
+- u16 next_link_addr = 0;
+- __le16 link_value;
++ u16 next_link_addr = 0, link_value;
+ bool is_empty = false;
+
+ /* locate the beginning of OTP link list */
+@@ -410,8 +409,7 @@ static bool iwl_is_otp_empty(struct iwl_priv *priv)
+ static int iwl_find_otp_image(struct iwl_priv *priv,
+ u16 *validblockaddr)
+ {
+- u16 next_link_addr = 0, valid_addr;
+- __le16 link_value = 0;
++ u16 next_link_addr = 0, link_value = 0, valid_addr;
+ int usedblocks = 0;
+
+ /* set addressing mode to absolute to traverse the link list */
+@@ -431,7 +429,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
+ * check for more block on the link list
+ */
+ valid_addr = next_link_addr;
+- next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
++ next_link_addr = link_value * sizeof(u16);
+ IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
+ usedblocks, next_link_addr);
+ if (iwl_read_otp_word(priv, next_link_addr, &link_value))
+@@ -465,7 +463,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
+ */
+ int iwl_eeprom_init(struct iwl_priv *priv)
+ {
+- __le16 *e;
++ u16 *e;
+ u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
+ int sz;
+ int ret;
+@@ -484,7 +482,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
+ ret = -ENOMEM;
+ goto alloc_err;
+ }
+- e = (__le16 *)priv->eeprom;
++ e = (u16 *)priv->eeprom;
+
+ ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
+ if (ret < 0) {
+@@ -523,7 +521,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
+ }
+ for (addr = validblockaddr; addr < validblockaddr + sz;
+ addr += sizeof(u16)) {
+- __le16 eeprom_data;
++ u16 eeprom_data;
+
+ ret = iwl_read_otp_word(priv, addr, &eeprom_data);
+ if (ret)
+@@ -547,7 +545,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
+ goto done;
+ }
+ r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+- e[addr / 2] = cpu_to_le16(r >> 16);
++ e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
+ }
+ }
+ ret = 0;
+@@ -711,8 +709,7 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
+ ch_info->ht40_min_power = 0;
+ ch_info->ht40_scan_power = eeprom_ch->max_power_avg;
+ ch_info->ht40_flags = eeprom_ch->flags;
+- if (eeprom_ch->flags & EEPROM_CHANNEL_VALID)
+- ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel;
++ ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel;
+
+ return 0;
+ }
+diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+index fc93f12..80b9e45 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
++++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+@@ -133,7 +133,7 @@ struct iwl_eeprom_channel {
+ *
+ */
+ struct iwl_eeprom_enhanced_txpwr {
+- __le16 common;
++ u16 reserved;
+ s8 chain_a_max;
+ s8 chain_b_max;
+ s8 chain_c_max;
+@@ -347,7 +347,7 @@ struct iwl_eeprom_calib_subband_info {
+ struct iwl_eeprom_calib_info {
+ u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */
+ u8 saturation_power52; /* half-dBm */
+- __le16 voltage; /* signed */
++ s16 voltage; /* signed */
+ struct iwl_eeprom_calib_subband_info
+ band_info[EEPROM_TX_POWER_BANDS];
+ } __attribute__ ((packed));
+diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+index 5f26c93..d00a803 100644
+--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+@@ -562,9 +562,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
+ txq = &priv->txq[txq_id];
+ q = &txq->q;
+
+- if ((iwl_queue_space(q) < q->high_mark))
+- goto drop;
+-
+ spin_lock_irqsave(&priv->lock, flags);
+
+ idx = get_cmd_index(q, q->write_ptr, 0);
+@@ -3857,11 +3854,9 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
+ /* Tell mac80211 our characteristics */
+ hw->flags = IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM |
+- IEEE80211_HW_SPECTRUM_MGMT;
+-
+- if (!priv->cfg->broken_powersave)
+- hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+- IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
++ IEEE80211_HW_SPECTRUM_MGMT |
++ IEEE80211_HW_SUPPORTS_PS |
++ IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_STATION) |
+diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
+index 93c8989..1b02a4e 100644
+--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
++++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
+@@ -258,7 +258,7 @@ struct iwm_priv {
+
+ struct sk_buff_head rx_list;
+ struct list_head rx_tickets;
+- struct list_head rx_packets[IWM_RX_ID_HASH + 1];
++ struct list_head rx_packets[IWM_RX_ID_HASH];
+ struct workqueue_struct *rx_wq;
+ struct work_struct rx_worker;
+
+diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
+index 06d66a1..6c95af3 100644
+--- a/drivers/net/wireless/libertas/scan.c
++++ b/drivers/net/wireless/libertas/scan.c
+@@ -399,8 +399,11 @@ int lbs_scan_networks(struct lbs_private *priv, int full_scan)
+ chan_count = lbs_scan_create_channel_list(priv, chan_list);
+
+ netif_stop_queue(priv->dev);
+- if (priv->mesh_dev)
++ netif_carrier_off(priv->dev);
++ if (priv->mesh_dev) {
+ netif_stop_queue(priv->mesh_dev);
++ netif_carrier_off(priv->mesh_dev);
++ }
+
+ /* Prepare to continue an interrupted scan */
+ lbs_deb_scan("chan_count %d, scan_channel %d\n",
+@@ -464,13 +467,16 @@ out2:
+ priv->scan_channel = 0;
+
+ out:
+- if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len)
+- netif_wake_queue(priv->dev);
+-
+- if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED) &&
+- !priv->tx_pending_len)
+- netif_wake_queue(priv->mesh_dev);
+-
++ if (priv->connect_status == LBS_CONNECTED) {
++ netif_carrier_on(priv->dev);
++ if (!priv->tx_pending_len)
++ netif_wake_queue(priv->dev);
++ }
++ if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) {
++ netif_carrier_on(priv->mesh_dev);
++ if (!priv->tx_pending_len)
++ netif_wake_queue(priv->mesh_dev);
++ }
+ kfree(chan_list);
+
+ lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
+diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
+index 01c738b..be837a0 100644
+--- a/drivers/net/wireless/libertas/wext.c
++++ b/drivers/net/wireless/libertas/wext.c
+@@ -1953,8 +1953,10 @@ static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
+ if (priv->connect_status == LBS_CONNECTED) {
+ memcpy(extra, priv->curbssparams.ssid,
+ priv->curbssparams.ssid_len);
++ extra[priv->curbssparams.ssid_len] = '\0';
+ } else {
+ memset(extra, 0, 32);
++ extra[priv->curbssparams.ssid_len] = '\0';
+ }
+ /*
+ * If none, we may want to get the one that was set
+diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
+index 31ca241..7698fdd 100644
+--- a/drivers/net/wireless/orinoco/wext.c
++++ b/drivers/net/wireless/orinoco/wext.c
+@@ -23,7 +23,7 @@
+ #define MAX_RID_LEN 1024
+
+ /* Helper routine to record keys
+- * It is called under orinoco_lock so it may not sleep */
++ * Do not call from interrupt context */
+ static int orinoco_set_key(struct orinoco_private *priv, int index,
+ enum orinoco_alg alg, const u8 *key, int key_len,
+ const u8 *seq, int seq_len)
+@@ -32,14 +32,14 @@ static int orinoco_set_key(struct orinoco_private *priv, int index,
+ kzfree(priv->keys[index].seq);
+
+ if (key_len) {
+- priv->keys[index].key = kzalloc(key_len, GFP_ATOMIC);
++ priv->keys[index].key = kzalloc(key_len, GFP_KERNEL);
+ if (!priv->keys[index].key)
+ goto nomem;
+ } else
+ priv->keys[index].key = NULL;
+
+ if (seq_len) {
+- priv->keys[index].seq = kzalloc(seq_len, GFP_ATOMIC);
++ priv->keys[index].seq = kzalloc(seq_len, GFP_KERNEL);
+ if (!priv->keys[index].seq)
+ goto free_key;
+ } else
+diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
+index 9a6ceb4..b20e3ea 100644
+--- a/drivers/net/wireless/rt2x00/rt61pci.c
++++ b/drivers/net/wireless/rt2x00/rt61pci.c
+@@ -2538,11 +2538,6 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+ unsigned int i;
+
+ /*
+- * Disable powersaving as default.
+- */
+- rt2x00dev->hw->wiphy->ps_default = false;
+-
+- /*
+ * Initialize all hw fields.
+ */
+ rt2x00dev->hw->flags =
+diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
+index 99406bf..bf9175a 100644
+--- a/drivers/net/wireless/rtl818x/rtl8187.h
++++ b/drivers/net/wireless/rtl818x/rtl8187.h
+@@ -23,7 +23,6 @@
+ #define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */
+ #define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */
+ #define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */
+-#define RTL8187_EEPROM_SELECT_GPIO 0x3B
+
+ #define RTL8187_REQT_READ 0xC0
+ #define RTL8187_REQT_WRITE 0x40
+@@ -32,9 +31,6 @@
+
+ #define RTL8187_MAX_RX 0x9C4
+
+-#define RFKILL_MASK_8187_89_97 0x2
+-#define RFKILL_MASK_8198 0x4
+-
+ struct rtl8187_rx_info {
+ struct urb *urb;
+ struct ieee80211_hw *dev;
+@@ -127,7 +123,6 @@ struct rtl8187_priv {
+ u8 noise;
+ u8 slot_time;
+ u8 aifsn[4];
+- u8 rfkill_mask;
+ struct {
+ __le64 buf;
+ struct sk_buff_head queue;
+diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
+index 9921147..2017ccc 100644
+--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
++++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
+@@ -65,7 +65,6 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
+ /* Sitecom */
+ {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
+ {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
+- {USB_DEVICE(0x0df6, 0x0029), .driver_info = DEVICE_RTL8187B},
+ /* Sphairon Access Systems GmbH */
+ {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187},
+ /* Dick Smith Electronics */
+@@ -1330,7 +1329,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
+ struct ieee80211_channel *channel;
+ const char *chip_name;
+ u16 txpwr, reg;
+- u16 product_id = le16_to_cpu(udev->descriptor.idProduct);
+ int err, i;
+
+ dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops);
+@@ -1490,13 +1488,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
+ (*channel++).hw_value = txpwr & 0xFF;
+ (*channel++).hw_value = txpwr >> 8;
+ }
+- /* Handle the differing rfkill GPIO bit in different models */
+- priv->rfkill_mask = RFKILL_MASK_8187_89_97;
+- if (product_id == 0x8197 || product_id == 0x8198) {
+- eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_SELECT_GPIO, ®);
+- if (reg & 0xFF00)
+- priv->rfkill_mask = RFKILL_MASK_8198;
+- }
+
+ /*
+ * XXX: Once this driver supports anything that requires
+@@ -1525,9 +1516,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
+ mutex_init(&priv->conf_mutex);
+ skb_queue_head_init(&priv->b_tx_status.queue);
+
+- printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
++ printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s\n",
+ wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
+- chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask);
++ chip_name, priv->asic_rev, priv->rf->name);
+
+ #ifdef CONFIG_RTL8187_LEDS
+ eeprom_93cx6_read(&eeprom, 0x3F, ®);
+diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
+index 03555e1..cad8037 100644
+--- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
++++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
+@@ -25,10 +25,10 @@ static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
+ u8 gpio;
+
+ gpio = rtl818x_ioread8(priv, &priv->map->GPIO0);
+- rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask);
++ rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~0x02);
+ gpio = rtl818x_ioread8(priv, &priv->map->GPIO1);
+
+- return gpio & priv->rfkill_mask;
++ return gpio & 0x02;
+ }
+
+ void rtl8187_rfkill_init(struct ieee80211_hw *hw)
+diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
+index 5753036..b952ebc 100644
+--- a/drivers/pci/dmar.c
++++ b/drivers/pci/dmar.c
+@@ -582,8 +582,6 @@ int __init dmar_table_init(void)
+ return 0;
+ }
+
+-static int bios_warned;
+-
+ int __init check_zero_address(void)
+ {
+ struct acpi_table_dmar *dmar;
+@@ -603,9 +601,6 @@ int __init check_zero_address(void)
+ }
+
+ if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
+- void __iomem *addr;
+- u64 cap, ecap;
+-
+ drhd = (void *)entry_header;
+ if (!drhd->address) {
+ /* Promote an attitude of violence to a BIOS engineer today */
+@@ -614,40 +609,17 @@ int __init check_zero_address(void)
+ dmi_get_system_info(DMI_BIOS_VENDOR),
+ dmi_get_system_info(DMI_BIOS_VERSION),
+ dmi_get_system_info(DMI_PRODUCT_VERSION));
+- bios_warned = 1;
+- goto failed;
+- }
+-
+- addr = early_ioremap(drhd->address, VTD_PAGE_SIZE);
+- if (!addr ) {
+- printk("IOMMU: can't validate: %llx\n", drhd->address);
+- goto failed;
+- }
+- cap = dmar_readq(addr + DMAR_CAP_REG);
+- ecap = dmar_readq(addr + DMAR_ECAP_REG);
+- early_iounmap(addr, VTD_PAGE_SIZE);
+- if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) {
+- /* Promote an attitude of violence to a BIOS engineer today */
+- WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
+- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+- drhd->address,
+- dmi_get_system_info(DMI_BIOS_VENDOR),
+- dmi_get_system_info(DMI_BIOS_VERSION),
+- dmi_get_system_info(DMI_PRODUCT_VERSION));
+- bios_warned = 1;
+- goto failed;
++#ifdef CONFIG_DMAR
++ dmar_disabled = 1;
++#endif
++ return 0;
+ }
++ break;
+ }
+
+ entry_header = ((void *)entry_header + entry_header->length);
+ }
+ return 1;
+-
+-failed:
+-#ifdef CONFIG_DMAR
+- dmar_disabled = 1;
+-#endif
+- return 0;
+ }
+
+ void __init detect_intel_iommu(void)
+@@ -692,18 +664,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
+ int agaw = 0;
+ int msagaw = 0;
+
+- if (!drhd->reg_base_addr) {
+- if (!bios_warned) {
+- WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
+- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+- dmi_get_system_info(DMI_BIOS_VENDOR),
+- dmi_get_system_info(DMI_BIOS_VERSION),
+- dmi_get_system_info(DMI_PRODUCT_VERSION));
+- bios_warned = 1;
+- }
+- return -EINVAL;
+- }
+-
+ iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+ if (!iommu)
+ return -ENOMEM;
+@@ -720,16 +680,13 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
+ iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
+
+ if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
+- if (!bios_warned) {
+- /* Promote an attitude of violence to a BIOS engineer today */
+- WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
+- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+- drhd->reg_base_addr,
+- dmi_get_system_info(DMI_BIOS_VENDOR),
+- dmi_get_system_info(DMI_BIOS_VERSION),
+- dmi_get_system_info(DMI_PRODUCT_VERSION));
+- bios_warned = 1;
+- }
++ /* Promote an attitude of violence to a BIOS engineer today */
++ WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
++ "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
++ drhd->reg_base_addr,
++ dmi_get_system_info(DMI_BIOS_VENDOR),
++ dmi_get_system_info(DMI_BIOS_VERSION),
++ dmi_get_system_info(DMI_PRODUCT_VERSION));
+ goto err_unmap;
+ }
+
+diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
+index 2498602..1840a05 100644
+--- a/drivers/pci/intel-iommu.c
++++ b/drivers/pci/intel-iommu.c
+@@ -1523,15 +1523,12 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
+
+ /* Skip top levels of page tables for
+ * iommu which has less agaw than default.
+- * Unnecessary for PT mode.
+ */
+- if (translation != CONTEXT_TT_PASS_THROUGH) {
+- for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
+- pgd = phys_to_virt(dma_pte_addr(pgd));
+- if (!dma_pte_present(pgd)) {
+- spin_unlock_irqrestore(&iommu->lock, flags);
+- return -ENOMEM;
+- }
++ for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
++ pgd = phys_to_virt(dma_pte_addr(pgd));
++ if (!dma_pte_present(pgd)) {
++ spin_unlock_irqrestore(&iommu->lock, flags);
++ return -ENOMEM;
+ }
+ }
+ }
+@@ -1994,16 +1991,6 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
+ "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
+ pci_name(pdev), start, end);
+
+- if (end < start) {
+- WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
+- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+- dmi_get_system_info(DMI_BIOS_VENDOR),
+- dmi_get_system_info(DMI_BIOS_VERSION),
+- dmi_get_system_info(DMI_PRODUCT_VERSION));
+- ret = -EIO;
+- goto error;
+- }
+-
+ if (end >> agaw_to_width(domain->agaw)) {
+ WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
+ "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+@@ -3241,9 +3228,6 @@ static int device_notifier(struct notifier_block *nb,
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct dmar_domain *domain;
+
+- if (iommu_no_mapping(dev))
+- return 0;
+-
+ domain = find_domain(pdev);
+ if (!domain)
+ return 0;
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 6477722..4e4c295 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -2723,11 +2723,6 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev)
+ return 1;
+ }
+
+-void __weak pci_fixup_cardbus(struct pci_bus *bus)
+-{
+-}
+-EXPORT_SYMBOL(pci_fixup_cardbus);
+-
+ static int __init pci_setup(char *str)
+ {
+ while (str) {
+diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
+index 0d91a8a..62d15f6 100644
+--- a/drivers/pci/pcie/aer/aer_inject.c
++++ b/drivers/pci/pcie/aer/aer_inject.c
+@@ -392,14 +392,8 @@ static int aer_inject(struct aer_error_inj *einj)
+ if (ret)
+ goto out_put;
+
+- if (find_aer_device(rpdev, &edev)) {
+- if (!get_service_data(edev)) {
+- printk(KERN_WARNING "AER service is not initialized\n");
+- ret = -EINVAL;
+- goto out_put;
+- }
++ if (find_aer_device(rpdev, &edev))
+ aer_irq(-1, edev);
+- }
+ else
+ ret = -EINVAL;
+ out_put:
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index dd58c6a..cb1a027 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -142,6 +142,7 @@ static void pci_setup_bridge(struct pci_bus *bus)
+ struct pci_dev *bridge = bus->self;
+ struct pci_bus_region region;
+ u32 l, bu, lu, io_upper16;
++ int pref_mem64;
+
+ if (pci_is_enabled(bridge))
+ return;
+@@ -197,6 +198,7 @@ static void pci_setup_bridge(struct pci_bus *bus)
+ pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
+
+ /* Set up PREF base/limit. */
++ pref_mem64 = 0;
+ bu = lu = 0;
+ pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]);
+ if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
+@@ -204,6 +206,7 @@ static void pci_setup_bridge(struct pci_bus *bus)
+ l = (region.start >> 16) & 0xfff0;
+ l |= region.end & 0xfff00000;
+ if (bus->resource[2]->flags & IORESOURCE_MEM_64) {
++ pref_mem64 = 1;
+ bu = upper_32_bits(region.start);
+ lu = upper_32_bits(region.end);
+ width = 16;
+@@ -218,9 +221,11 @@ static void pci_setup_bridge(struct pci_bus *bus)
+ }
+ pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
+
+- /* Set the upper 32 bits of PREF base & limit. */
+- pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
+- pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
++ if (pref_mem64) {
++ /* Set the upper 32 bits of PREF base & limit. */
++ pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
++ pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
++ }
+
+ pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
+ }
+diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
+index 5c26793..db77e1f 100644
+--- a/drivers/pcmcia/cardbus.c
++++ b/drivers/pcmcia/cardbus.c
+@@ -214,7 +214,7 @@ int __ref cb_alloc(struct pcmcia_socket * s)
+ unsigned int max, pass;
+
+ s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
+- pci_fixup_cardbus(bus);
++// pcibios_fixup_bus(bus);
+
+ max = bus->secondary;
+ for (pass = 0; pass < 2; pass++)
+diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
+index 4d922e4..ab64522 100644
+--- a/drivers/platform/x86/acerhdf.c
++++ b/drivers/platform/x86/acerhdf.c
+@@ -52,7 +52,7 @@
+ */
+ #undef START_IN_KERNEL_MODE
+
+-#define DRV_VER "0.5.20"
++#define DRV_VER "0.5.18"
+
+ /*
+ * According to the Atom N270 datasheet,
+@@ -112,14 +112,12 @@ module_param_string(force_product, force_product, 16, 0);
+ MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check");
+
+ /*
+- * cmd_off: to switch the fan completely off
+- * chk_off: to check if the fan is off
++ * cmd_off: to switch the fan completely off / to check if the fan is off
+ * cmd_auto: to set the BIOS in control of the fan. The BIOS regulates then
+ * the fan speed depending on the temperature
+ */
+ struct fancmd {
+ u8 cmd_off;
+- u8 chk_off;
+ u8 cmd_auto;
+ };
+
+@@ -136,41 +134,32 @@ struct bios_settings_t {
+ /* Register addresses and values for different BIOS versions */
+ static const struct bios_settings_t bios_tbl[] = {
+ /* AOA110 */
+- {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x1f, 0x00} },
+- {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x1f, 0x00} },
+- {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+- {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+- {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+- {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+- {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x21, 0x00} },
+- {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x21, 0x00} },
+- {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x21, 0x00} },
++ {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00} },
++ {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00} },
++ {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00} },
++ {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00} },
++ {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00} },
++ {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00} },
++ {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00} },
++ {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} },
++ {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} },
+ /* AOA150 */
+- {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- /* Acer 1410 */
+- {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
++ {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x00} },
++ {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00} },
++ {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} },
++ {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} },
++ {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00} },
++ {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} },
++ {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} },
++ {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} },
+ /* special BIOS / other */
+- {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} },
+- {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- {"Gateway ", "LT31 ", "v1.3103 ", 0x55, 0x58,
+- {0x10, 0x0f, 0x00} },
+- {"Gateway ", "LT31 ", "v1.3201 ", 0x55, 0x58,
+- {0x10, 0x0f, 0x00} },
+- {"Gateway ", "LT31 ", "v1.3302 ", 0x55, 0x58,
+- {0x10, 0x0f, 0x00} },
+- {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} },
+- {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
+- {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} },
+- {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
++ {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} },
++ {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} },
++ {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} },
++ {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} },
++ {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} },
+ /* pewpew-terminator */
+- {"", "", "", 0, 0, {0, 0, 0} }
++ {"", "", "", 0, 0, {0, 0} }
+ };
+
+ static const struct bios_settings_t *bios_cfg __read_mostly;
+@@ -194,7 +183,7 @@ static int acerhdf_get_fanstate(int *state)
+ if (ec_read(bios_cfg->fanreg, &fan))
+ return -EINVAL;
+
+- if (fan != bios_cfg->cmd.chk_off)
++ if (fan != bios_cfg->cmd.cmd_off)
+ *state = ACERHDF_FAN_AUTO;
+ else
+ *state = ACERHDF_FAN_OFF;
+@@ -640,10 +629,9 @@ static void __exit acerhdf_exit(void)
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Peter Feuerer");
+ MODULE_DESCRIPTION("Aspire One temperature and fan driver");
+-MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:");
+-MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:");
+-MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:");
+-MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:");
++MODULE_ALIAS("dmi:*:*Acer*:*:");
++MODULE_ALIAS("dmi:*:*Gateway*:*:");
++MODULE_ALIAS("dmi:*:*Packard Bell*:*:");
+
+ module_init(acerhdf_init);
+ module_exit(acerhdf_exit);
+diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
+index 767cb61..b39d2bb 100644
+--- a/drivers/platform/x86/asus-laptop.c
++++ b/drivers/platform/x86/asus-laptop.c
+@@ -221,7 +221,6 @@ static struct asus_hotk *hotk;
+ */
+ static const struct acpi_device_id asus_device_ids[] = {
+ {"ATK0100", 0},
+- {"ATK0101", 0},
+ {"", 0},
+ };
+ MODULE_DEVICE_TABLE(acpi, asus_device_ids);
+@@ -294,11 +293,6 @@ struct key_entry {
+ enum { KE_KEY, KE_END };
+
+ static struct key_entry asus_keymap[] = {
+- {KE_KEY, 0x02, KEY_SCREENLOCK},
+- {KE_KEY, 0x05, KEY_WLAN},
+- {KE_KEY, 0x08, BTN_TOUCH},
+- {KE_KEY, 0x17, KEY_ZOOM},
+- {KE_KEY, 0x1f, KEY_BATTERY},
+ {KE_KEY, 0x30, KEY_VOLUMEUP},
+ {KE_KEY, 0x31, KEY_VOLUMEDOWN},
+ {KE_KEY, 0x32, KEY_MUTE},
+@@ -318,8 +312,6 @@ static struct key_entry asus_keymap[] = {
+ {KE_KEY, 0x5F, KEY_WLAN},
+ {KE_KEY, 0x60, KEY_SWITCHVIDEOMODE},
+ {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
+- {KE_KEY, 0x62, KEY_SWITCHVIDEOMODE},
+- {KE_KEY, 0x63, KEY_SWITCHVIDEOMODE},
+ {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */
+ {KE_KEY, 0x82, KEY_CAMERA},
+ {KE_KEY, 0x8A, KEY_PROG1},
+@@ -1291,8 +1283,8 @@ static int asus_hotk_add(struct acpi_device *device)
+ hotk->ledd_status = 0xFFF;
+
+ /* Set initial values of light sensor and level */
+- hotk->light_switch = 0; /* Default to light sensor disabled */
+- hotk->light_level = 5; /* level 5 for sensor sensitivity */
++ hotk->light_switch = 1; /* Default to light sensor disabled */
++ hotk->light_level = 0; /* level 5 for sensor sensitivity */
+
+ if (ls_switch_handle)
+ set_light_sens_switch(hotk->light_switch);
+diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
+index 6dec7cc..0f900cc 100644
+--- a/drivers/platform/x86/dell-wmi.c
++++ b/drivers/platform/x86/dell-wmi.c
+@@ -158,13 +158,8 @@ static void dell_wmi_notify(u32 value, void *context)
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ static struct key_entry *key;
+ union acpi_object *obj;
+- acpi_status status;
+
+- status = wmi_get_event_data(value, &response);
+- if (status != AE_OK) {
+- printk(KERN_INFO "dell-wmi: bad event status 0x%x\n", status);
+- return;
+- }
++ wmi_get_event_data(value, &response);
+
+ obj = (union acpi_object *)response.pointer;
+
+@@ -185,7 +180,6 @@ static void dell_wmi_notify(u32 value, void *context)
+ printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
+ buffer[1] & 0xFFFF);
+ }
+- kfree(obj);
+ }
+
+ static int __init dell_wmi_input_setup(void)
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index deb53b5..c284217 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -334,13 +334,8 @@ static void hp_wmi_notify(u32 value, void *context)
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ static struct key_entry *key;
+ union acpi_object *obj;
+- acpi_status status;
+
+- status = wmi_get_event_data(value, &response);
+- if (status != AE_OK) {
+- printk(KERN_INFO "hp-wmi: bad event status 0x%x\n", status);
+- return;
+- }
++ wmi_get_event_data(value, &response);
+
+ obj = (union acpi_object *)response.pointer;
+
+@@ -382,8 +377,6 @@ static void hp_wmi_notify(u32 value, void *context)
+ eventcode);
+ } else
+ printk(KERN_INFO "HP WMI: Unknown response received\n");
+-
+- kfree(obj);
+ }
+
+ static int __init hp_wmi_input_setup(void)
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 1ee734c..a848c7e 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -3866,6 +3866,15 @@ enum {
+
+ #define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
+
++static void bluetooth_suspend(pm_message_t state)
++{
++ /* Try to make sure radio will resume powered off */
++ if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
++ TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
++ vdbg_printk(TPACPI_DBG_RFKILL,
++ "bluetooth power down on resume request failed\n");
++}
++
+ static int bluetooth_get_status(void)
+ {
+ int status;
+@@ -3899,9 +3908,10 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state)
+ #endif
+
+ /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
+- status = TP_ACPI_BLUETOOTH_RESUMECTRL;
+ if (state == TPACPI_RFK_RADIO_ON)
+- status |= TP_ACPI_BLUETOOTH_RADIOSSW;
++ status = TP_ACPI_BLUETOOTH_RADIOSSW;
++ else
++ status = 0;
+
+ if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
+ return -EIO;
+@@ -4040,6 +4050,7 @@ static struct ibm_struct bluetooth_driver_data = {
+ .read = bluetooth_read,
+ .write = bluetooth_write,
+ .exit = bluetooth_exit,
++ .suspend = bluetooth_suspend,
+ .shutdown = bluetooth_shutdown,
+ };
+
+@@ -4057,6 +4068,15 @@ enum {
+
+ #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
+
++static void wan_suspend(pm_message_t state)
++{
++ /* Try to make sure radio will resume powered off */
++ if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
++ TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
++ vdbg_printk(TPACPI_DBG_RFKILL,
++ "WWAN power down on resume request failed\n");
++}
++
+ static int wan_get_status(void)
+ {
+ int status;
+@@ -4089,10 +4109,11 @@ static int wan_set_status(enum tpacpi_rfkill_state state)
+ }
+ #endif
+
+- /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */
+- status = TP_ACPI_WANCARD_RESUMECTRL;
++ /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
+ if (state == TPACPI_RFK_RADIO_ON)
+- status |= TP_ACPI_WANCARD_RADIOSSW;
++ status = TP_ACPI_WANCARD_RADIOSSW;
++ else
++ status = 0;
+
+ if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
+ return -EIO;
+@@ -4230,6 +4251,7 @@ static struct ibm_struct wan_driver_data = {
+ .read = wan_read,
+ .write = wan_write,
+ .exit = wan_exit,
++ .suspend = wan_suspend,
+ .shutdown = wan_shutdown,
+ };
+
+@@ -6101,8 +6123,8 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
+
+ /* Models with Intel Extreme Graphics 2 */
+ TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),
+- TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+- TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
++ TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
++ TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
+
+ /* Models with Intel GMA900 */
+ TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */
+diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
+index 87f4c97..177f8d7 100644
+--- a/drivers/platform/x86/wmi.c
++++ b/drivers/platform/x86/wmi.c
+@@ -510,8 +510,8 @@ EXPORT_SYMBOL_GPL(wmi_remove_notify_handler);
+ /**
+ * wmi_get_event_data - Get WMI data associated with an event
+ *
+- * @event: Event to find
+- * @out: Buffer to hold event data. out->pointer should be freed with kfree()
++ * @event - Event to find
++ * &out - Buffer to hold event data
+ *
+ * Returns extra data associated with an event in WMI.
+ */
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 1836053..efe568d 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -640,7 +640,7 @@ static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
+ static void print_constraints(struct regulator_dev *rdev)
+ {
+ struct regulation_constraints *constraints = rdev->constraints;
+- char buf[80] = "";
++ char buf[80];
+ int count;
+
+ if (rdev->desc->type == REGULATOR_VOLTAGE) {
+diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
+index 43ed81e..768bd0e 100644
+--- a/drivers/regulator/wm8350-regulator.c
++++ b/drivers/regulator/wm8350-regulator.c
+@@ -1504,8 +1504,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
+ led->isink_init.consumer_supplies = &led->isink_consumer;
+ led->isink_init.constraints.min_uA = 0;
+ led->isink_init.constraints.max_uA = pdata->max_uA;
+- led->isink_init.constraints.valid_ops_mask
+- = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS;
++ led->isink_init.constraints.valid_ops_mask = REGULATOR_CHANGE_CURRENT;
+ led->isink_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
+ ret = wm8350_register_regulator(wm8350, isink, &led->isink_init);
+ if (ret != 0) {
+@@ -1518,7 +1517,6 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
+ led->dcdc_init.num_consumer_supplies = 1;
+ led->dcdc_init.consumer_supplies = &led->dcdc_consumer;
+ led->dcdc_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
+- led->dcdc_init.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
+ ret = wm8350_register_regulator(wm8350, dcdc, &led->dcdc_init);
+ if (ret != 0) {
+ platform_device_put(pdev);
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index 3c20dae..b7ba353 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -674,6 +674,20 @@ config RTC_DRV_AT91RM9200
+ Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips
+ this is powered by the backup power supply.
+
++config RTC_DRV_TMPA910
++ tristate "Toshiba TMPA910 RTC"
++ depends on ARCH_TMPA910
++ help
++ Driver for the internal RTC (Realtime Clock) module found on
++ Toshiba TMPA910 chip.
++
++config RTC_DRV_TMPA910
++ tristate "Toshiba TMPA910 RTC"
++ depends on ARCH_TMPA910
++ help
++ Driver for the internal RTC (Realtime Clock) module found on
++ Toshiba TMPA910 chip.
++
+ config RTC_DRV_AT91SAM9
+ tristate "AT91SAM9x/AT91CAP9"
+ depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40)
+diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
+index aa3fbd5..50f1a38 100644
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -78,6 +78,7 @@ obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
+ obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o
+ obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
+ obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
++obj-$(CONFIG_RTC_DRV_TMPA910) += rtc-tmpa910.o
+ obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o
+ obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
+ obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index 473e5f2..f7a4701 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -1099,9 +1099,9 @@ static int cmos_pnp_resume(struct pnp_dev *pnp)
+ #define cmos_pnp_resume NULL
+ #endif
+
+-static void cmos_pnp_shutdown(struct pnp_dev *pnp)
++static void cmos_pnp_shutdown(struct device *pdev)
+ {
+- if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pnp->dev))
++ if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(pdev))
+ return;
+
+ cmos_do_shutdown();
+@@ -1120,12 +1120,15 @@ static struct pnp_driver cmos_pnp_driver = {
+ .id_table = rtc_ids,
+ .probe = cmos_pnp_probe,
+ .remove = __exit_p(cmos_pnp_remove),
+- .shutdown = cmos_pnp_shutdown,
+
+ /* flag ensures resume() gets called, and stops syslog spam */
+ .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
+ .suspend = cmos_pnp_suspend,
+ .resume = cmos_pnp_resume,
++ .driver = {
++ .name = (char *)driver_name,
++ .shutdown = cmos_pnp_shutdown,
++ }
+ };
+
+ #endif /* CONFIG_PNP */
+diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c
+index 812c667..3a7be11 100644
+--- a/drivers/rtc/rtc-fm3130.c
++++ b/drivers/rtc/rtc-fm3130.c
+@@ -376,22 +376,20 @@ static int __devinit fm3130_probe(struct i2c_client *client,
+ }
+
+ /* Disabling calibration mode */
+- if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL) {
++ if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL)
+ i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
+ fm3130->regs[FM3130_RTC_CONTROL] &
+ ~(FM3130_RTC_CONTROL_BIT_CAL));
+ dev_warn(&client->dev, "Disabling calibration mode!\n");
+- }
+
+ /* Disabling read and write modes */
+ if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_WRITE ||
+- fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ) {
++ fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ)
+ i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
+ fm3130->regs[FM3130_RTC_CONTROL] &
+ ~(FM3130_RTC_CONTROL_BIT_READ |
+ FM3130_RTC_CONTROL_BIT_WRITE));
+ dev_warn(&client->dev, "Disabling READ or WRITE mode!\n");
+- }
+
+ /* oscillator off? turn it on, so clock can tick. */
+ if (fm3130->regs[FM3130_CAL_CONTROL] & FM3130_CAL_CONTROL_BIT_nOSCEN)
+diff --git a/drivers/rtc/rtc-tmpa910.c b/drivers/rtc/rtc-tmpa910.c
+new file mode 100644
+index 0000000..c2b9087
+--- /dev/null
++++ b/drivers/rtc/rtc-tmpa910.c
+@@ -0,0 +1,431 @@
++/*
++ * Driver for Toshiba TMPA910 Real Time Clock unit.
++ * derived from rtc_tmpa910.c
++ * Copyright (C) 2003-2006 Yoichi Yuasa <yoichi_yuasa at tripeaks.co.jp>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#include <linux/err.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/rtc.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/delay.h>
++
++
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <mach/tmpa910_regs.h>
++#include <mach/irqs.h>
++
++#define RTC_BASE 0xF0030000
++
++#define RTCDATA (RTC_BASE + 0x0000)
++#define RTCCOMP (RTC_BASE + 0x0004)
++#define RTCPRST (RTC_BASE + 0x0008)
++#define RTCALMINTCR (RTC_BASE + 0x0200)
++#define RTCALMMIS (RTC_BASE + 0x0204)
++
++#define VICINTENABLE 0xF4000010
++
++MODULE_AUTHOR("Michael Hasselberg <mh at open-engineering.de>");
++MODULE_DESCRIPTION("Toshiba TMPA910 RTC driver");
++MODULE_LICENSE("GPL");
++
++/*
++ * This is the initial release of the TMPA910 RTC driver
++ * it currently only supports set / read time and set / read alarm
++ * TODO:
++ * implement RTC_WKLAM_xxx and RTC_PIE_xxx ioctls and functionality
++ * RTC_UIE_xxx is not available on TMPA910
++ *
++ */
++
++static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */
++
++static DEFINE_SPINLOCK(rtc_lock);
++static unsigned long rtc_alarm_value;
++static unsigned int rtc_irq_enabled;
++static int rtc_irq = -1;
++/* static int pie_irq = -1; */
++static void __iomem *rtc_base;
++
++static inline unsigned long read_elapsed_second(void)
++{
++ return _in32(RTCDATA);
++}
++
++static inline void write_elapsed_second(unsigned long sec)
++{
++ spin_lock_irq(&rtc_lock);
++
++ _out32(RTCCOMP, 0);
++ udelay(100);
++ _out32(RTCPRST, sec);
++ udelay(100);
++ while (_in32(RTCDATA) != sec);
++
++ spin_unlock_irq(&rtc_lock);
++}
++
++static void tmpa910_rtc_release(struct device *dev)
++{
++ uint32_t reg;
++//printk("rtc: release\n");
++ spin_lock_irq(&rtc_lock);
++
++ if (rtc_irq_enabled) {
++//printk("rtc: ioctl alarm disable\n");
++ reg = _in32(RTCALMINTCR);
++ reg &= 0x3e;
++ _out32(RTCALMINTCR, reg);
++ disable_irq(rtc_irq);
++ rtc_irq_enabled = 0;
++ }
++
++ spin_unlock_irq(&rtc_lock);
++
++}
++
++static int tmpa910_rtc_read_time(struct device *dev, struct rtc_time *time)
++{
++ unsigned long epoch_sec, elapsed_sec;
++//printk("rtc: read time\n");
++ epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
++ elapsed_sec = read_elapsed_second();
++
++ rtc_time_to_tm(epoch_sec + elapsed_sec, time);
++
++ return 0;
++}
++
++static int tmpa910_rtc_set_time(struct device *dev, struct rtc_time *time)
++{
++ unsigned long epoch_sec, current_sec;
++//printk("rtc: set time\n");
++ epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
++ current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
++ time->tm_hour, time->tm_min, time->tm_sec);
++
++ write_elapsed_second(current_sec - epoch_sec);
++
++ return 0;
++}
++
++static int tmpa910_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
++{
++ struct rtc_time *time = &wkalrm->time;
++//printk("rtc: read alarm\n");
++ spin_lock_irq(&rtc_lock);
++
++ wkalrm->enabled = rtc_irq_enabled;
++
++ spin_unlock_irq(&rtc_lock);
++
++ rtc_time_to_tm(rtc_alarm_value, time);
++
++ return 0;
++}
++
++static int tmpa910_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
++{
++ unsigned long alarm_sec;
++ uint32_t reg;
++
++ struct rtc_time *time = &wkalrm->time;
++//printk("rtc: set alarm 1\n");
++ alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
++ time->tm_hour, time->tm_min, time->tm_sec);
++
++ spin_lock_irq(&rtc_lock);
++
++ rtc_alarm_value = alarm_sec;
++//reg = _in32(RTCDATA);
++//udelay(100);
++//printk("rtc: set alarm 2 rtc: %u, alm: %u\n",reg,alarm_sec);
++ _out32(RTCCOMP, alarm_sec);
++ udelay(100);
++
++ if (wkalrm->enabled) {
++ reg = _in32(RTCALMINTCR);
++ reg |= 0x41;
++ _out32(RTCALMINTCR, reg);
++ enable_irq(rtc_irq);
++ }
++ rtc_irq_enabled = wkalrm->enabled;
++//printk("rtc: enable alarm %u\n", rtc_irq_enabled);
++ spin_unlock_irq(&rtc_lock);
++
++ return 0;
++}
++
++static int tmpa910_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
++{
++ uint32_t reg;
++/*
++ unsigned long count;
++*/
++//printk("rtc: ioctl\n");
++ switch (cmd) {
++ case RTC_AIE_ON:
++//printk("rtc: ioctl RTC_AIE_ON\n");
++ spin_lock_irq(&rtc_lock);
++
++ if (!rtc_irq_enabled) {
++//printk("rtc: ioctl alarm enable\n");
++ enable_irq(rtc_irq);
++//printk("rtc: RTCALMMIS=0x%02x\n",_in32(RTCALMMIS));
++ reg = _in32(RTCALMINTCR);
++//printk("rtc: RTCALMINTCR=0x%02x\n",reg);
++ reg &= 0x3f;
++ reg |= 0x41;
++ _out32(RTCALMINTCR, reg);
++//printk("rtc: RTCALMINTCR=0x%02x\n",reg);
++ reg = _in32(VICINTENABLE);
++//printk("rtc: VICINTENABLE=0x%04x\n",reg);
++ rtc_irq_enabled = 1;
++ }
++ spin_unlock_irq(&rtc_lock);
++ break;
++ case RTC_AIE_OFF:
++//printk("rtc: ioctl RTC_AIE_OFF\n");
++ spin_lock_irq(&rtc_lock);
++
++ if (rtc_irq_enabled) {
++//printk("rtc: ioctl alarm disable\n");
++ reg = _in32(RTCALMINTCR);
++ reg &= 0x3e;
++ _out32(RTCALMINTCR, reg);
++ disable_irq(rtc_irq);
++ rtc_irq_enabled = 0;
++ }
++
++ spin_unlock_irq(&rtc_lock);
++ break;
++#if 0
++ case RTC_PIE_ON:
++ enable_irq(pie_irq);
++ break;
++ case RTC_PIE_OFF:
++ disable_irq(pie_irq);
++ break;
++ case RTC_IRQP_READ:
++ return put_user(periodic_frequency, (unsigned long __user *)arg);
++ break;
++ case RTC_IRQP_SET:
++ if (arg > MAX_PERIODIC_RATE)
++ return -EINVAL;
++
++ periodic_frequency = arg;
++
++ count = RTC_FREQUENCY;
++ do_div(count, arg);
++
++ periodic_count = count;
++
++ spin_lock_irq(&rtc_lock);
++
++ rtc1_write(RTCL1LREG, count);
++ rtc1_write(RTCL1HREG, count >> 16);
++
++ spin_unlock_irq(&rtc_lock);
++ break;
++#endif
++ case RTC_EPOCH_READ:
++ return put_user(epoch, (unsigned long __user *)arg);
++ case RTC_EPOCH_SET:
++ /* Doesn't support before 1900 */
++ if (arg < 1900)
++ return -EINVAL;
++ epoch = arg;
++ break;
++ default:
++ return -ENOIOCTLCMD;
++ }
++
++ return 0;
++}
++
++static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
++{
++ struct platform_device *pdev = (struct platform_device *)dev_id;
++ struct rtc_device *rtc = platform_get_drvdata(pdev);
++ uint32_t reg, reg2;
++//printk("rtc: interrupt\n");
++ reg2 = _in32(RTCALMMIS);
++//printk("rtc: RTCALMMIS=0x%02x\n",reg2);
++ if (reg2 & 0x01) {
++//printk("rtc: interrupt 1\n");
++ reg = _in32(RTCALMINTCR);
++//printk("rtc: RTCALMINTCR=0x%02x\n",reg);
++ reg &= 0x3f;
++ reg |= 0x40;
++ _out32(RTCALMINTCR, reg);
++//printk("rtc: RTCALMINTCR=0x%02x\n",reg);
++ rtc_update_irq(rtc, 1, RTC_AF);
++ }
++ if (reg2 & 0x02) {
++//printk("rtc: interrupt 2\n");
++ reg = _in32(RTCALMINTCR);
++ reg &= 0x3f;
++ reg |= 0x80;
++ _out32(RTCALMINTCR, reg);
++ printk(KERN_INFO "tmpa910_rtc: GLITCH! ALM irq triggered\n");
++ }
++
++ return IRQ_HANDLED;
++}
++
++static const struct rtc_class_ops tmpa910_rtc_ops = {
++ .release = tmpa910_rtc_release,
++ .ioctl = tmpa910_rtc_ioctl,
++ .read_time = tmpa910_rtc_read_time,
++ .set_time = tmpa910_rtc_set_time,
++ .read_alarm = tmpa910_rtc_read_alarm,
++ .set_alarm = tmpa910_rtc_set_alarm,
++};
++
++static int __devinit tmpa910_rtc_probe(struct platform_device *pdev)
++{
++ struct resource *res;
++ struct rtc_device *rtc;
++ int retval;
++ uint32_t reg;
++
++//printk("rtc: rtc_probe start\n");
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res)
++ return -EBUSY;
++
++ rtc_base = ioremap(res->start, res->end - res->start + 1);
++ if (!rtc_base)
++ return -EBUSY;
++
++ rtc = rtc_device_register("tmpa910", &pdev->dev, &tmpa910_rtc_ops, THIS_MODULE);
++ if (IS_ERR(rtc)) {
++ retval = PTR_ERR(rtc);
++ goto err_iounmap_all;
++ }
++
++ spin_lock_irq(&rtc_lock);
++
++ reg = _in32(RTCALMINTCR);
++ reg &= 0x3e;
++ reg |= 0xc0;
++ _out32(RTCALMINTCR, reg);
++ udelay(100);
++ _out32(RTCCOMP, 0);
++ udelay(100);
++ _out32(RTCPRST, 0);
++ udelay(100);
++ while (_in32(RTCDATA) != 0);
++
++ spin_unlock_irq(&rtc_lock);
++
++ rtc_irq = platform_get_irq(pdev, 0);
++ if (rtc_irq < 0 || rtc_irq >= NR_IRQS) {
++ retval = -EBUSY;
++ goto err_device_unregister;
++ }
++
++ retval = request_irq(rtc_irq, elapsedtime_interrupt, 0,
++ "tmpa910-rtc", pdev);
++ if (retval < 0)
++ goto err_device_unregister;
++
++ platform_set_drvdata(pdev, rtc);
++
++ disable_irq(rtc_irq);
++
++ printk(KERN_INFO "rtc: Toshiba TMPA910 Real Time Clock\n");
++
++ return 0;
++
++err_device_unregister:
++ rtc_device_unregister(rtc);
++
++err_iounmap_all:
++ iounmap(rtc_base);
++ rtc_base = NULL;
++
++ return retval;
++}
++
++static int __devexit tmpa910_rtc_remove(struct platform_device *pdev)
++{
++ struct rtc_device *rtc;
++
++ rtc = platform_get_drvdata(pdev);
++ if (rtc)
++ rtc_device_unregister(rtc);
++
++ platform_set_drvdata(pdev, NULL);
++
++ free_irq(rtc_irq, pdev);
++ /* free_irq(pie_irq, pdev); */
++ if (rtc_base)
++ iounmap(rtc_base);
++
++ return 0;
++}
++#ifdef CONFIG_PM
++
++/* RTC Power management control */
++#define tmpa910_rtc_suspend NULL
++#define tmpa910_rtc_resume NULL
++
++#else
++#define tmpa910_rtc_suspend NULL
++#define tmpa910_rtc_resume NULL
++#endif
++
++
++/* work with hotplug and coldplug */
++MODULE_ALIAS("platform:RTC");
++
++static struct platform_driver tmpa910_rtc_platform_driver = {
++ .probe = tmpa910_rtc_probe,
++ .remove = __devexit_p(tmpa910_rtc_remove),
++ .suspend = tmpa910_rtc_suspend,
++ .resume = tmpa910_rtc_resume,
++ .driver = {
++ .name = "tmpa910_rtc",
++ .owner = THIS_MODULE
++ },
++
++};
++
++static int __init tmpa910_rtc_init(void)
++{
++ return platform_driver_register(&tmpa910_rtc_platform_driver);
++}
++
++static void __exit tmpa910_rtc_exit(void)
++{
++ platform_driver_unregister(&tmpa910_rtc_platform_driver);
++}
++
++module_init(tmpa910_rtc_init);
++module_exit(tmpa910_rtc_exit);
++
+diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
+index d0ef15a..aaccc8e 100644
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -994,9 +994,10 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
+ return;
+ cqr = (struct dasd_ccw_req *) intparm;
+ if (cqr->status != DASD_CQR_IN_IO) {
+- DBF_EVENT_DEVID(DBF_DEBUG, cdev,
+- "invalid status in handle_killed_request: "
+- "%02x", cqr->status);
++ DBF_EVENT(DBF_DEBUG,
++ "invalid status in handle_killed_request: "
++ "bus_id %s, status %02x",
++ dev_name(&cdev->dev), cqr->status);
+ return;
+ }
+
+@@ -1004,8 +1005,8 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
+ if (device == NULL ||
+ device != dasd_device_from_cdev_locked(cdev) ||
+ strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
+- DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
+- "invalid device in request");
++ DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
++ "bus_id %s", dev_name(&cdev->dev));
+ return;
+ }
+
+@@ -1044,13 +1045,12 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
+ case -EIO:
+ break;
+ case -ETIMEDOUT:
+- DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: "
+- "request timed out\n", __func__);
++ DBF_EVENT(DBF_WARNING, "%s(%s): request timed out\n",
++ __func__, dev_name(&cdev->dev));
+ break;
+ default:
+- DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: "
+- "unknown error %ld\n", __func__,
+- PTR_ERR(irb));
++ DBF_EVENT(DBF_WARNING, "%s(%s): unknown error %ld\n",
++ __func__, dev_name(&cdev->dev), PTR_ERR(irb));
+ }
+ dasd_handle_killed_request(cdev, intparm);
+ return;
+@@ -1078,8 +1078,8 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
+ device = (struct dasd_device *) cqr->startdev;
+ if (!device ||
+ strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
+- DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
+- "invalid device in request");
++ DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
++ "bus_id %s", dev_name(&cdev->dev));
+ return;
+ }
+
+@@ -2217,9 +2217,9 @@ int dasd_generic_probe(struct ccw_device *cdev,
+ }
+ ret = dasd_add_sysfs_files(cdev);
+ if (ret) {
+- DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s",
+- "dasd_generic_probe: could not add "
+- "sysfs entries");
++ DBF_EVENT(DBF_WARNING,
++ "dasd_generic_probe: could not add sysfs entries "
++ "for %s\n", dev_name(&cdev->dev));
+ return ret;
+ }
+ cdev->handler = &dasd_int_handler;
+diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
+index 8174ec9..4e49b4a 100644
+--- a/drivers/s390/block/dasd_diag.c
++++ b/drivers/s390/block/dasd_diag.c
+@@ -145,15 +145,6 @@ dasd_diag_erp(struct dasd_device *device)
+
+ mdsk_term_io(device);
+ rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
+- if (rc == 4) {
+- if (!(device->features & DASD_FEATURE_READONLY)) {
+- dev_warn(&device->cdev->dev,
+- "The access mode of a DIAG device changed"
+- " to read-only");
+- device->features |= DASD_FEATURE_READONLY;
+- }
+- rc = 0;
+- }
+ if (rc)
+ dev_warn(&device->cdev->dev, "DIAG ERP failed with "
+ "rc=%d\n", rc);
+@@ -442,20 +433,16 @@ dasd_diag_check_device(struct dasd_device *device)
+ for (sb = 512; sb < bsize; sb = sb << 1)
+ block->s2b_shift++;
+ rc = mdsk_init_io(device, block->bp_block, 0, NULL);
+- if (rc && (rc != 4)) {
++ if (rc) {
+ dev_warn(&device->cdev->dev, "DIAG initialization "
+ "failed with rc=%d\n", rc);
+ rc = -EIO;
+ } else {
+- if (rc == 4)
+- device->features |= DASD_FEATURE_READONLY;
+ dev_info(&device->cdev->dev,
+- "New DASD with %ld byte/block, total size %ld KB%s\n",
++ "New DASD with %ld byte/block, total size %ld KB\n",
+ (unsigned long) block->bp_block,
+ (unsigned long) (block->blocks <<
+- block->s2b_shift) >> 1,
+- (rc == 4) ? ", read-only device" : "");
+- rc = 0;
++ block->s2b_shift) >> 1);
+ }
+ out_label:
+ free_page((long) label);
+diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
+index 678bb94..417b97c 100644
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -88,9 +88,9 @@ dasd_eckd_probe (struct ccw_device *cdev)
+ /* set ECKD specific ccw-device options */
+ ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
+ if (ret) {
+- DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s",
+- "dasd_eckd_probe: could not set "
+- "ccw-device options");
++ DBF_EVENT(DBF_WARNING,
++ "dasd_eckd_probe: could not set ccw-device options "
++ "for %s\n", dev_name(&cdev->dev));
+ return ret;
+ }
+ ret = dasd_generic_probe(cdev, &dasd_eckd_discipline);
+@@ -885,15 +885,16 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
+ rc = dasd_eckd_read_conf_lpm(device, &conf_data,
+ &conf_len, lpm);
+ if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
+- DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
++ DBF_EVENT(DBF_WARNING,
+ "Read configuration data returned "
+- "error %d", rc);
++ "error %d for device: %s", rc,
++ dev_name(&device->cdev->dev));
+ return rc;
+ }
+ if (conf_data == NULL) {
+- DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
+- "No configuration data "
+- "retrieved");
++ DBF_EVENT(DBF_WARNING, "No configuration "
++ "data retrieved for device: %s",
++ dev_name(&device->cdev->dev));
+ continue; /* no error */
+ }
+ /* save first valid configuration data */
+@@ -940,8 +941,9 @@ static int dasd_eckd_read_features(struct dasd_device *device)
+ sizeof(struct dasd_rssd_features)),
+ device);
+ if (IS_ERR(cqr)) {
+- DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", "Could not "
+- "allocate initialization request");
++ DBF_EVENT(DBF_WARNING, "Could not allocate initialization "
++ "request for device: %s",
++ dev_name(&device->cdev->dev));
+ return PTR_ERR(cqr);
+ }
+ cqr->startdev = device;
+@@ -1069,8 +1071,10 @@ static int dasd_eckd_validate_server(struct dasd_device *device)
+ /* may be requested feature is not available on server,
+ * therefore just report error and go ahead */
+ private = (struct dasd_eckd_private *) device->private;
+- DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "
+- "returned rc=%d", private->uid.ssid, rc);
++ DBF_EVENT(DBF_WARNING, "PSF-SSC on storage subsystem %s.%s.%04x "
++ "returned rc=%d for device: %s",
++ private->uid.vendor, private->uid.serial,
++ private->uid.ssid, rc, dev_name(&device->cdev->dev));
+ /* RE-Read Configuration Data */
+ return dasd_eckd_read_conf(device);
+ }
+@@ -1119,9 +1123,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
+ if (private->uid.type == UA_BASE_DEVICE) {
+ block = dasd_alloc_block();
+ if (IS_ERR(block)) {
+- DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
+- "could not allocate dasd "
+- "block structure");
++ DBF_EVENT(DBF_WARNING, "could not allocate dasd "
++ "block structure for device: %s",
++ dev_name(&device->cdev->dev));
+ rc = PTR_ERR(block);
+ goto out_err1;
+ }
+@@ -1149,8 +1153,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
+ rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
+ &private->rdc_data, 64);
+ if (rc) {
+- DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+- "Read device characteristic failed, rc=%d", rc);
++ DBF_EVENT(DBF_WARNING,
++ "Read device characteristics failed, rc=%d for "
++ "device: %s", rc, dev_name(&device->cdev->dev));
+ goto out_err3;
+ }
+ /* find the vaild cylinder size */
+@@ -2975,7 +2980,7 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n",
+ req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
+- scsw_cc(&irb->scsw), req ? req->intrc : 0);
++ scsw_cc(&irb->scsw), req->intrc);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " device %s: Failing CCW: %p\n",
+ dev_name(&device->cdev->dev),
+@@ -3248,8 +3253,9 @@ int dasd_eckd_restore_device(struct dasd_device *device)
+ rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
+ &temp_rdc_data, 64);
+ if (rc) {
+- DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+- "Read device characteristic failed, rc=%d", rc);
++ DBF_EVENT(DBF_WARNING,
++ "Read device characteristics failed, rc=%d for "
++ "device: %s", rc, dev_name(&device->cdev->dev));
+ goto out_err;
+ }
+ spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
+index 227b4e9..f245377 100644
+--- a/drivers/s390/block/dasd_fba.c
++++ b/drivers/s390/block/dasd_fba.c
+@@ -141,8 +141,9 @@ dasd_fba_check_characteristics(struct dasd_device *device)
+ }
+ block = dasd_alloc_block();
+ if (IS_ERR(block)) {
+- DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s", "could not allocate "
+- "dasd block structure");
++ DBF_EVENT(DBF_WARNING, "could not allocate dasd block "
++ "structure for device: %s",
++ dev_name(&device->cdev->dev));
+ device->private = NULL;
+ kfree(private);
+ return PTR_ERR(block);
+@@ -154,8 +155,9 @@ dasd_fba_check_characteristics(struct dasd_device *device)
+ rc = dasd_generic_read_dev_chars(device, DASD_FBA_MAGIC,
+ &private->rdc_data, 32);
+ if (rc) {
+- DBF_EVENT_DEVID(DBF_WARNING, cdev, "Read device "
+- "characteristics returned error %d", rc);
++ DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
++ "error %d for device: %s",
++ rc, dev_name(&device->cdev->dev));
+ device->block = NULL;
+ dasd_free_block(block);
+ device->private = NULL;
+diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
+index b19f309..8afd9fa 100644
+--- a/drivers/s390/block/dasd_int.h
++++ b/drivers/s390/block/dasd_int.h
+@@ -108,16 +108,6 @@ do { \
+ d_data); \
+ } while(0)
+
+-#define DBF_EVENT_DEVID(d_level, d_cdev, d_str, d_data...) \
+-do { \
+- struct ccw_dev_id __dev_id; \
+- ccw_device_get_id(d_cdev, &__dev_id); \
+- debug_sprintf_event(dasd_debug_area, \
+- d_level, \
+- "0.%x.%04x " d_str "\n", \
+- __dev_id.ssid, __dev_id.devno, d_data); \
+-} while (0)
+-
+ #define DBF_EXC(d_level, d_str, d_data...)\
+ do { \
+ debug_sprintf_exception(dasd_debug_area, \
+diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
+index a5354b8..f756a1b 100644
+--- a/drivers/s390/block/dasd_ioctl.c
++++ b/drivers/s390/block/dasd_ioctl.c
+@@ -260,7 +260,7 @@ static int dasd_ioctl_information(struct dasd_block *block,
+ struct ccw_dev_id dev_id;
+
+ base = block->base;
+- if (!base->discipline || !base->discipline->fill_info)
++ if (!base->discipline->fill_info)
+ return -EINVAL;
+
+ dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL);
+@@ -303,7 +303,10 @@ static int dasd_ioctl_information(struct dasd_block *block,
+ dasd_info->features |=
+ ((base->features & DASD_FEATURE_READONLY) != 0);
+
+- memcpy(dasd_info->type, base->discipline->name, 4);
++ if (base->discipline)
++ memcpy(dasd_info->type, base->discipline->name, 4);
++ else
++ memcpy(dasd_info->type, "none", 4);
+
+ if (block->request_queue->request_fn) {
+ struct list_head *l;
+diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
+index f9d7d38..654daa3 100644
+--- a/drivers/s390/block/dasd_proc.c
++++ b/drivers/s390/block/dasd_proc.c
+@@ -71,7 +71,7 @@ dasd_devices_show(struct seq_file *m, void *v)
+ /* Print device number. */
+ seq_printf(m, "%s", dev_name(&device->cdev->dev));
+ /* Print discipline string. */
+- if (device->discipline != NULL)
++ if (device != NULL && device->discipline != NULL)
+ seq_printf(m, "(%s)", device->discipline->name);
+ else
+ seq_printf(m, "(none)");
+@@ -91,7 +91,10 @@ dasd_devices_show(struct seq_file *m, void *v)
+ substr = (device->features & DASD_FEATURE_READONLY) ? "(ro)" : " ";
+ seq_printf(m, "%4s: ", substr);
+ /* Print device status information. */
+- switch (device->state) {
++ switch ((device != NULL) ? device->state : -1) {
++ case -1:
++ seq_printf(m, "unknown");
++ break;
+ case DASD_STATE_NEW:
+ seq_printf(m, "new");
+ break;
+diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
+index 55f9973..2490b74 100644
+--- a/drivers/s390/cio/device.c
++++ b/drivers/s390/cio/device.c
+@@ -1292,7 +1292,7 @@ static int io_subchannel_probe(struct subchannel *sch)
+ sch->private = kzalloc(sizeof(struct io_subchannel_private),
+ GFP_KERNEL | GFP_DMA);
+ if (!sch->private)
+- goto out_schedule;
++ goto out_err;
+ /*
+ * First check if a fitting device may be found amongst the
+ * disconnected devices or in the orphanage.
+@@ -1317,7 +1317,7 @@ static int io_subchannel_probe(struct subchannel *sch)
+ }
+ cdev = io_subchannel_create_ccwdev(sch);
+ if (IS_ERR(cdev))
+- goto out_schedule;
++ goto out_err;
+ rc = io_subchannel_recog(cdev, sch);
+ if (rc) {
+ spin_lock_irqsave(sch->lock, flags);
+@@ -1325,7 +1325,9 @@ static int io_subchannel_probe(struct subchannel *sch)
+ spin_unlock_irqrestore(sch->lock, flags);
+ }
+ return 0;
+-
++out_err:
++ kfree(sch->private);
++ sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
+ out_schedule:
+ io_subchannel_schedule_removal(sch);
+ return 0;
+@@ -1339,14 +1341,13 @@ io_subchannel_remove (struct subchannel *sch)
+
+ cdev = sch_get_cdev(sch);
+ if (!cdev)
+- goto out_free;
++ return 0;
+ /* Set ccw device to not operational and drop reference. */
+ spin_lock_irqsave(cdev->ccwlock, flags);
+ sch_set_cdev(sch, NULL);
+ cdev->private->state = DEV_STATE_NOT_OPER;
+ spin_unlock_irqrestore(cdev->ccwlock, flags);
+ ccw_device_unregister(cdev);
+-out_free:
+ kfree(sch->private);
+ sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
+ return 0;
+diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
+index 13b703a..b9613d7 100644
+--- a/drivers/s390/cio/device_fsm.c
++++ b/drivers/s390/cio/device_fsm.c
+@@ -1080,14 +1080,14 @@ void ccw_device_trigger_reprobe(struct ccw_device *cdev)
+ ccw_device_start_id(cdev, 0);
+ }
+
+-static void ccw_device_disabled_irq(struct ccw_device *cdev,
+- enum dev_event dev_event)
++static void
++ccw_device_offline_irq(struct ccw_device *cdev, enum dev_event dev_event)
+ {
+ struct subchannel *sch;
+
+ sch = to_subchannel(cdev->dev.parent);
+ /*
+- * An interrupt in a disabled state means a previous disable was not
++ * An interrupt in state offline means a previous disable was not
+ * successful - should not happen, but we try to disable again.
+ */
+ cio_disable_subchannel(sch);
+@@ -1150,12 +1150,25 @@ ccw_device_nop(struct ccw_device *cdev, enum dev_event dev_event)
+ }
+
+ /*
++ * Bug operation action.
++ */
++static void
++ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event)
++{
++ CIO_MSG_EVENT(0, "Internal state [%i][%i] not handled for device "
++ "0.%x.%04x\n", cdev->private->state, dev_event,
++ cdev->private->dev_id.ssid,
++ cdev->private->dev_id.devno);
++ BUG();
++}
++
++/*
+ * device statemachine
+ */
+ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
+ [DEV_STATE_NOT_OPER] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_nop,
+- [DEV_EVENT_INTERRUPT] = ccw_device_disabled_irq,
++ [DEV_EVENT_INTERRUPT] = ccw_device_bug,
+ [DEV_EVENT_TIMEOUT] = ccw_device_nop,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
+ },
+@@ -1173,7 +1186,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
+ },
+ [DEV_STATE_OFFLINE] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper,
+- [DEV_EVENT_INTERRUPT] = ccw_device_disabled_irq,
++ [DEV_EVENT_INTERRUPT] = ccw_device_offline_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_nop,
+ [DEV_EVENT_VERIFY] = ccw_device_offline_verify,
+ },
+@@ -1230,7 +1243,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
+ [DEV_STATE_DISCONNECTED] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_nop,
+ [DEV_EVENT_INTERRUPT] = ccw_device_start_id,
+- [DEV_EVENT_TIMEOUT] = ccw_device_nop,
++ [DEV_EVENT_TIMEOUT] = ccw_device_bug,
+ [DEV_EVENT_VERIFY] = ccw_device_start_id,
+ },
+ [DEV_STATE_DISCONNECTED_SENSE_ID] = {
+diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
+index 7f1e3ba..f4b0c47 100644
+--- a/drivers/s390/crypto/zcrypt_pcicc.c
++++ b/drivers/s390/crypto/zcrypt_pcicc.c
+@@ -373,8 +373,6 @@ static int convert_type86(struct zcrypt_device *zdev,
+ zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
+ return -EAGAIN;
+ }
+- if (service_rc == 8 && service_rs == 72)
+- return -EINVAL;
+ zdev->online = 0;
+ return -EAGAIN; /* repeat the request on a different device. */
+ }
+diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
+index 1f9e923..5677b40 100644
+--- a/drivers/s390/crypto/zcrypt_pcixcc.c
++++ b/drivers/s390/crypto/zcrypt_pcixcc.c
+@@ -462,8 +462,6 @@ static int convert_type86_ica(struct zcrypt_device *zdev,
+ }
+ if (service_rc == 12 && service_rs == 769)
+ return -EINVAL;
+- if (service_rc == 8 && service_rs == 72)
+- return -EINVAL;
+ zdev->online = 0;
+ return -EAGAIN; /* repeat the request on a different device. */
+ }
+diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
+index 395c04c..c84eadd 100644
+--- a/drivers/s390/net/netiucv.c
++++ b/drivers/s390/net/netiucv.c
+@@ -741,13 +741,13 @@ static void conn_action_txdone(fsm_instance *fi, int event, void *arg)
+ if (single_flag) {
+ if ((skb = skb_dequeue(&conn->commit_queue))) {
+ atomic_dec(&skb->users);
++ dev_kfree_skb_any(skb);
+ if (privptr) {
+ privptr->stats.tx_packets++;
+ privptr->stats.tx_bytes +=
+ (skb->len - NETIUCV_HDRLEN
+- - NETIUCV_HDRLEN);
++ - NETIUCV_HDRLEN);
+ }
+- dev_kfree_skb_any(skb);
+ }
+ }
+ conn->tx_buff->data = conn->tx_buff->head;
+diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
+index bfec4fa..3ee1cbc 100644
+--- a/drivers/scsi/device_handler/scsi_dh.c
++++ b/drivers/scsi/device_handler/scsi_dh.c
+@@ -304,15 +304,18 @@ static int scsi_dh_notifier(struct notifier_block *nb,
+ sdev = to_scsi_device(dev);
+
+ if (action == BUS_NOTIFY_ADD_DEVICE) {
+- err = device_create_file(dev, &scsi_dh_state_attr);
+- /* don't care about err */
+ devinfo = device_handler_match(NULL, sdev);
+- if (devinfo)
+- err = scsi_dh_handler_attach(sdev, devinfo);
++ if (!devinfo)
++ goto out;
++
++ err = scsi_dh_handler_attach(sdev, devinfo);
++ if (!err)
++ err = device_create_file(dev, &scsi_dh_state_attr);
+ } else if (action == BUS_NOTIFY_DEL_DEVICE) {
+ device_remove_file(dev, &scsi_dh_state_attr);
+ scsi_dh_handler_detach(sdev, NULL);
+ }
++out:
+ return err;
+ }
+
+diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
+index 70ab5d0..704b8e0 100644
+--- a/drivers/scsi/fcoe/fcoe.c
++++ b/drivers/scsi/fcoe/fcoe.c
+@@ -137,7 +137,7 @@ static struct scsi_host_template fcoe_shost_template = {
+ .change_queue_depth = fc_change_queue_depth,
+ .change_queue_type = fc_change_queue_type,
+ .this_id = -1,
+- .cmd_per_lun = 3,
++ .cmd_per_lun = 32,
+ .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .sg_tablesize = SG_ALL,
+@@ -160,7 +160,6 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe,
+ {
+ struct fcoe_ctlr *fip = &fcoe->ctlr;
+ struct netdev_hw_addr *ha;
+- struct net_device *real_dev;
+ u8 flogi_maddr[ETH_ALEN];
+
+ fcoe->netdev = netdev;
+@@ -174,12 +173,10 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe,
+
+ /* look for SAN MAC address, if multiple SAN MACs exist, only
+ * use the first one for SPMA */
+- real_dev = (netdev->priv_flags & IFF_802_1Q_VLAN) ?
+- vlan_dev_real_dev(netdev) : netdev;
+ rcu_read_lock();
+- for_each_dev_addr(real_dev, ha) {
++ for_each_dev_addr(netdev, ha) {
+ if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
+- (is_valid_ether_addr(ha->addr))) {
++ (is_valid_ether_addr(fip->ctl_src_addr))) {
+ memcpy(fip->ctl_src_addr, ha->addr, ETH_ALEN);
+ fip->spma = 1;
+ break;
+@@ -667,7 +664,7 @@ static int fcoe_ddp_setup(struct fc_lport *lp, u16 xid,
+ {
+ struct net_device *n = fcoe_netdev(lp);
+
+- if (n->netdev_ops->ndo_fcoe_ddp_setup)
++ if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
+ return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
+
+ return 0;
+@@ -684,7 +681,7 @@ static int fcoe_ddp_done(struct fc_lport *lp, u16 xid)
+ {
+ struct net_device *n = fcoe_netdev(lp);
+
+- if (n->netdev_ops->ndo_fcoe_ddp_done)
++ if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
+ return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
+ return 0;
+ }
+@@ -1634,7 +1631,7 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
+ {
+ struct fcoe_interface *fcoe;
+ struct net_device *netdev;
+- int rc = 0;
++ int rc;
+
+ mutex_lock(&fcoe_config_mutex);
+ #ifdef CONFIG_FCOE_MODULE
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+index 554626e..c968cc3 100644
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -180,20 +180,14 @@ void scsi_remove_host(struct Scsi_Host *shost)
+ EXPORT_SYMBOL(scsi_remove_host);
+
+ /**
+- * scsi_add_host_with_dma - add a scsi host with dma device
++ * scsi_add_host - add a scsi host
+ * @shost: scsi host pointer to add
+ * @dev: a struct device of type scsi class
+- * @dma_dev: dma device for the host
+- *
+- * Note: You rarely need to worry about this unless you're in a
+- * virtualised host environments, so use the simpler scsi_add_host()
+- * function instead.
+ *
+ * Return value:
+ * 0 on success / != 0 for error
+ **/
+-int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
+- struct device *dma_dev)
++int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
+ {
+ struct scsi_host_template *sht = shost->hostt;
+ int error = -EINVAL;
+@@ -213,7 +207,6 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
+
+ if (!shost->shost_gendev.parent)
+ shost->shost_gendev.parent = dev ? dev : &platform_bus;
+- shost->dma_dev = dma_dev;
+
+ error = device_add(&shost->shost_gendev);
+ if (error)
+@@ -269,7 +262,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
+ fail:
+ return error;
+ }
+-EXPORT_SYMBOL(scsi_add_host_with_dma);
++EXPORT_SYMBOL(scsi_add_host);
+
+ static void scsi_host_dev_release(struct device *dev)
+ {
+diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
+index c3ff9a6..76d294f 100644
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -6516,7 +6516,6 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
+ int rc;
+
+ ENTER;
+- ioa_cfg->pdev->state_saved = true;
+ rc = pci_restore_state(ioa_cfg->pdev);
+
+ if (rc != PCIBIOS_SUCCESSFUL) {
+diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
+index d4cb3f9..c48799e 100644
+--- a/drivers/scsi/libfc/fc_disc.c
++++ b/drivers/scsi/libfc/fc_disc.c
+@@ -371,7 +371,7 @@ static void fc_disc_gpn_ft_req(struct fc_disc *disc)
+ disc, lport->e_d_tov))
+ return;
+ err:
+- fc_disc_error(disc, NULL);
++ fc_disc_error(disc, fp);
+ }
+
+ /**
+diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
+index 9298458..5cfa687 100644
+--- a/drivers/scsi/libfc/fc_elsct.c
++++ b/drivers/scsi/libfc/fc_elsct.c
+@@ -53,10 +53,8 @@ static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
+ did = FC_FID_DIR_SERV;
+ }
+
+- if (rc) {
+- fc_frame_free(fp);
++ if (rc)
+ return NULL;
+- }
+
+ fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type,
+ FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
+diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
+index 7a14402..59a4408 100644
+--- a/drivers/scsi/libfc/fc_fcp.c
++++ b/drivers/scsi/libfc/fc_fcp.c
+@@ -302,13 +302,10 @@ static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp)
+ if (!fsp)
+ return;
+
+- if (fsp->xfer_ddp == FC_XID_UNKNOWN)
+- return;
+-
+ lp = fsp->lp;
+- if (lp->tt.ddp_done) {
++ if (fsp->xfer_ddp && lp->tt.ddp_done) {
+ fsp->xfer_len = lp->tt.ddp_done(lp, fsp->xfer_ddp);
+- fsp->xfer_ddp = FC_XID_UNKNOWN;
++ fsp->xfer_ddp = 0;
+ }
+ }
+
+@@ -575,8 +572,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
+ tlen -= sg_bytes;
+ remaining -= sg_bytes;
+
+- if ((skb_shinfo(fp_skb(fp))->nr_frags < FC_FRAME_SG_LEN) &&
+- (tlen))
++ if (tlen)
+ continue;
+
+ /*
+@@ -1052,6 +1048,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
+
+ seq = lp->tt.exch_seq_send(lp, fp, resp, fc_fcp_pkt_destroy, fsp, 0);
+ if (!seq) {
++ fc_frame_free(fp);
+ rc = -1;
+ goto unlock;
+ }
+@@ -1316,6 +1313,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
+ fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */
+ return;
+ }
++ fc_frame_free(fp);
+ retry:
+ if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
+ fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
+@@ -1563,9 +1561,10 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
+
+ seq = lp->tt.exch_seq_send(lp, fp, fc_fcp_srr_resp, NULL,
+ fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
+- if (!seq)
++ if (!seq) {
++ fc_frame_free(fp);
+ goto retry;
+-
++ }
+ fsp->recov_seq = seq;
+ fsp->xfer_len = offset;
+ fsp->xfer_contig_end = offset;
+@@ -1709,7 +1708,6 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
+ fsp->cmd = sc_cmd; /* save the cmd */
+ fsp->lp = lp; /* save the softc ptr */
+ fsp->rport = rport; /* set the remote port ptr */
+- fsp->xfer_ddp = FC_XID_UNKNOWN;
+ sc_cmd->scsi_done = done;
+
+ /*
+@@ -1848,8 +1846,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
+ * scsi status is good but transport level
+ * underrun.
+ */
+- sc_cmd->result = (fsp->state & FC_SRB_RCV_STATUS ?
+- DID_OK : DID_ERROR) << 16;
++ sc_cmd->result = DID_OK << 16;
+ } else {
+ /*
+ * scsi got underrun, this is an error
+@@ -2049,16 +2046,18 @@ EXPORT_SYMBOL(fc_eh_host_reset);
+ int fc_slave_alloc(struct scsi_device *sdev)
+ {
+ struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
++ int queue_depth;
+
+ if (!rport || fc_remote_port_chkready(rport))
+ return -ENXIO;
+
+- if (sdev->tagged_supported)
+- scsi_activate_tcq(sdev, FC_FCP_DFLT_QUEUE_DEPTH);
+- else
+- scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
+- FC_FCP_DFLT_QUEUE_DEPTH);
+-
++ if (sdev->tagged_supported) {
++ if (sdev->host->hostt->cmd_per_lun)
++ queue_depth = sdev->host->hostt->cmd_per_lun;
++ else
++ queue_depth = FC_FCP_DFLT_QUEUE_DEPTH;
++ scsi_activate_tcq(sdev, queue_depth);
++ }
+ return 0;
+ }
+ EXPORT_SYMBOL(fc_slave_alloc);
+diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
+index 536492a..bd2f771 100644
+--- a/drivers/scsi/libfc/fc_lport.c
++++ b/drivers/scsi/libfc/fc_lport.c
+@@ -329,7 +329,7 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
+ * @sp: current sequence in the RLIR exchange
+ * @fp: RLIR request frame
+ *
+- * Locking Note: The lport lock is expected to be held before calling
++ * Locking Note: The lport lock is exected to be held before calling
+ * this function.
+ */
+ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
+@@ -348,7 +348,7 @@ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
+ * @sp: current sequence in the ECHO exchange
+ * @fp: ECHO request frame
+ *
+- * Locking Note: The lport lock is expected to be held before calling
++ * Locking Note: The lport lock is exected to be held before calling
+ * this function.
+ */
+ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
+@@ -361,7 +361,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
+ void *dp;
+ u32 f_ctl;
+
+- FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
++ FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
+ fc_lport_state(lport));
+
+ len = fr_len(in_fp) - sizeof(struct fc_frame_header);
+@@ -374,7 +374,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
+ if (fp) {
+ dp = fc_frame_payload_get(fp, len);
+ memcpy(dp, pp, len);
+- *((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
++ *((u32 *)dp) = htonl(ELS_LS_ACC << 24);
+ sp = lport->tt.seq_start_next(sp);
+ f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
+ fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
+@@ -385,12 +385,12 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
+ }
+
+ /**
+- * fc_lport_recv_rnid_req() - Handle received Request Node ID data request
+- * @sp: The sequence in the RNID exchange
+- * @fp: The RNID request frame
+- * @lport: The local port recieving the RNID
++ * fc_lport_recv_echo_req() - Handle received Request Node ID data request
++ * @lport: Fibre Channel local port recieving the RNID
++ * @sp: current sequence in the RNID exchange
++ * @fp: RNID request frame
+ *
+- * Locking Note: The lport lock is expected to be held before calling
++ * Locking Note: The lport lock is exected to be held before calling
+ * this function.
+ */
+ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
+@@ -667,7 +667,7 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
+ * Accept it with the common service parameters indicating our N port.
+ * Set up to do a PLOGI if we have the higher-number WWPN.
+ *
+- * Locking Note: The lport lock is expected to be held before calling
++ * Locking Note: The lport lock is exected to be held before calling
+ * this function.
+ */
+ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
+@@ -1115,7 +1115,7 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
+
+ if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
+ fc_lport_scr_resp, lport, lport->e_d_tov))
+- fc_lport_error(lport, NULL);
++ fc_lport_error(lport, fp);
+ }
+
+ /**
+@@ -1186,7 +1186,7 @@ static void fc_lport_enter_rpn_id(struct fc_lport *lport)
+ if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RPN_ID,
+ fc_lport_rpn_id_resp,
+ lport, lport->e_d_tov))
+- fc_lport_error(lport, NULL);
++ fc_lport_error(lport, fp);
+ }
+
+ static struct fc_rport_operations fc_lport_rport_ops = {
+@@ -1237,12 +1237,9 @@ static void fc_lport_timeout(struct work_struct *work)
+
+ switch (lport->state) {
+ case LPORT_ST_DISABLED:
+- WARN_ON(1);
+- break;
+ case LPORT_ST_READY:
+- WARN_ON(1);
+- break;
+ case LPORT_ST_RESET:
++ WARN_ON(1);
+ break;
+ case LPORT_ST_FLOGI:
+ fc_lport_enter_flogi(lport);
+@@ -1340,7 +1337,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
+
+ if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
+ fc_lport_logo_resp, lport, lport->e_d_tov))
+- fc_lport_error(lport, NULL);
++ fc_lport_error(lport, fp);
+ }
+
+ /**
+@@ -1456,7 +1453,7 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
+
+ if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI,
+ fc_lport_flogi_resp, lport, lport->e_d_tov))
+- fc_lport_error(lport, NULL);
++ fc_lport_error(lport, fp);
+ }
+
+ /* Configure a fc_lport */
+diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
+index ff558a6..03ea674 100644
+--- a/drivers/scsi/libfc/fc_rport.c
++++ b/drivers/scsi/libfc/fc_rport.c
+@@ -86,7 +86,6 @@ static const char *fc_rport_state_names[] = {
+ [RPORT_ST_LOGO] = "LOGO",
+ [RPORT_ST_ADISC] = "ADISC",
+ [RPORT_ST_DELETE] = "Delete",
+- [RPORT_ST_RESTART] = "Restart",
+ };
+
+ /**
+@@ -100,7 +99,8 @@ static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,
+ struct fc_rport_priv *rdata;
+
+ list_for_each_entry(rdata, &lport->disc.rports, peers)
+- if (rdata->ids.port_id == port_id)
++ if (rdata->ids.port_id == port_id &&
++ rdata->rp_state != RPORT_ST_DELETE)
+ return rdata;
+ return NULL;
+ }
+@@ -235,7 +235,6 @@ static void fc_rport_work(struct work_struct *work)
+ struct fc_rport_operations *rport_ops;
+ struct fc_rport_identifiers ids;
+ struct fc_rport *rport;
+- int restart = 0;
+
+ mutex_lock(&rdata->rp_mutex);
+ event = rdata->event;
+@@ -288,20 +287,8 @@ static void fc_rport_work(struct work_struct *work)
+ mutex_unlock(&rdata->rp_mutex);
+
+ if (port_id != FC_FID_DIR_SERV) {
+- /*
+- * We must drop rp_mutex before taking disc_mutex.
+- * Re-evaluate state to allow for restart.
+- * A transition to RESTART state must only happen
+- * while disc_mutex is held and rdata is on the list.
+- */
+ mutex_lock(&lport->disc.disc_mutex);
+- mutex_lock(&rdata->rp_mutex);
+- if (rdata->rp_state == RPORT_ST_RESTART)
+- restart = 1;
+- else
+- list_del(&rdata->peers);
+- rdata->event = RPORT_EV_NONE;
+- mutex_unlock(&rdata->rp_mutex);
++ list_del(&rdata->peers);
+ mutex_unlock(&lport->disc.disc_mutex);
+ }
+
+@@ -325,13 +312,7 @@ static void fc_rport_work(struct work_struct *work)
+ mutex_unlock(&rdata->rp_mutex);
+ fc_remote_port_delete(rport);
+ }
+- if (restart) {
+- mutex_lock(&rdata->rp_mutex);
+- FC_RPORT_DBG(rdata, "work restart\n");
+- fc_rport_enter_plogi(rdata);
+- mutex_unlock(&rdata->rp_mutex);
+- } else
+- kref_put(&rdata->kref, lport->tt.rport_destroy);
++ kref_put(&rdata->kref, lport->tt.rport_destroy);
+ break;
+
+ default:
+@@ -361,12 +342,6 @@ int fc_rport_login(struct fc_rport_priv *rdata)
+ FC_RPORT_DBG(rdata, "ADISC port\n");
+ fc_rport_enter_adisc(rdata);
+ break;
+- case RPORT_ST_RESTART:
+- break;
+- case RPORT_ST_DELETE:
+- FC_RPORT_DBG(rdata, "Restart deleted port\n");
+- fc_rport_state_enter(rdata, RPORT_ST_RESTART);
+- break;
+ default:
+ FC_RPORT_DBG(rdata, "Login to port\n");
+ fc_rport_enter_plogi(rdata);
+@@ -422,21 +397,20 @@ int fc_rport_logoff(struct fc_rport_priv *rdata)
+
+ if (rdata->rp_state == RPORT_ST_DELETE) {
+ FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n");
++ mutex_unlock(&rdata->rp_mutex);
+ goto out;
+ }
+
+- if (rdata->rp_state == RPORT_ST_RESTART)
+- FC_RPORT_DBG(rdata, "Port in Restart state, deleting\n");
+- else
+- fc_rport_enter_logo(rdata);
++ fc_rport_enter_logo(rdata);
+
+ /*
+ * Change the state to Delete so that we discard
+ * the response.
+ */
+ fc_rport_enter_delete(rdata, RPORT_EV_STOP);
+-out:
+ mutex_unlock(&rdata->rp_mutex);
++
++out:
+ return 0;
+ }
+
+@@ -492,7 +466,6 @@ static void fc_rport_timeout(struct work_struct *work)
+ case RPORT_ST_READY:
+ case RPORT_ST_INIT:
+ case RPORT_ST_DELETE:
+- case RPORT_ST_RESTART:
+ break;
+ }
+
+@@ -526,7 +499,6 @@ static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp)
+ fc_rport_enter_logo(rdata);
+ break;
+ case RPORT_ST_DELETE:
+- case RPORT_ST_RESTART:
+ case RPORT_ST_READY:
+ case RPORT_ST_INIT:
+ break;
+@@ -660,7 +632,7 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
+
+ if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PLOGI,
+ fc_rport_plogi_resp, rdata, lport->e_d_tov))
+- fc_rport_error_retry(rdata, NULL);
++ fc_rport_error_retry(rdata, fp);
+ else
+ kref_get(&rdata->kref);
+ }
+@@ -821,7 +793,7 @@ static void fc_rport_enter_prli(struct fc_rport_priv *rdata)
+
+ if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PRLI,
+ fc_rport_prli_resp, rdata, lport->e_d_tov))
+- fc_rport_error_retry(rdata, NULL);
++ fc_rport_error_retry(rdata, fp);
+ else
+ kref_get(&rdata->kref);
+ }
+@@ -917,7 +889,7 @@ static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)
+
+ if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_RTV,
+ fc_rport_rtv_resp, rdata, lport->e_d_tov))
+- fc_rport_error_retry(rdata, NULL);
++ fc_rport_error_retry(rdata, fp);
+ else
+ kref_get(&rdata->kref);
+ }
+@@ -947,7 +919,7 @@ static void fc_rport_enter_logo(struct fc_rport_priv *rdata)
+
+ if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_LOGO,
+ fc_rport_logo_resp, rdata, lport->e_d_tov))
+- fc_rport_error_retry(rdata, NULL);
++ fc_rport_error_retry(rdata, fp);
+ else
+ kref_get(&rdata->kref);
+ }
+@@ -1034,7 +1006,7 @@ static void fc_rport_enter_adisc(struct fc_rport_priv *rdata)
+ }
+ if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_ADISC,
+ fc_rport_adisc_resp, rdata, lport->e_d_tov))
+- fc_rport_error_retry(rdata, NULL);
++ fc_rport_error_retry(rdata, fp);
+ else
+ kref_get(&rdata->kref);
+ }
+@@ -1276,7 +1248,6 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
+ }
+ break;
+ case RPORT_ST_PRLI:
+- case RPORT_ST_RTV:
+ case RPORT_ST_READY:
+ case RPORT_ST_ADISC:
+ FC_RPORT_DBG(rdata, "Received PLOGI in logged-in state %d "
+@@ -1284,14 +1255,11 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
+ /* XXX TBD - should reset */
+ break;
+ case RPORT_ST_DELETE:
+- case RPORT_ST_LOGO:
+- case RPORT_ST_RESTART:
+- FC_RPORT_DBG(rdata, "Received PLOGI in state %s - send busy\n",
+- fc_rport_state(rdata));
+- mutex_unlock(&rdata->rp_mutex);
+- rjt_data.reason = ELS_RJT_BUSY;
+- rjt_data.explan = ELS_EXPL_NONE;
+- goto reject;
++ default:
++ FC_RPORT_DBG(rdata, "Received PLOGI in unexpected state %d\n",
++ rdata->rp_state);
++ fc_frame_free(rx_fp);
++ goto out;
+ }
+
+ /*
+@@ -1434,7 +1402,7 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
+ break;
+ case FC_TYPE_FCP:
+ fcp_parm = ntohl(rspp->spp_params);
+- if (fcp_parm & FCP_SPPF_RETRY)
++ if (fcp_parm * FCP_SPPF_RETRY)
+ rdata->flags |= FC_RP_FLAGS_RETRY;
+ rdata->supported_classes = FC_COS_CLASS3;
+ if (fcp_parm & FCP_SPPF_INIT_FCN)
+@@ -1542,14 +1510,14 @@ static void fc_rport_recv_logo_req(struct fc_lport *lport,
+ FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n",
+ fc_rport_state(rdata));
+
+- fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+-
+ /*
+- * If the remote port was created due to discovery, set state
+- * to log back in. It may have seen a stale RSCN about us.
++ * If the remote port was created due to discovery,
++ * log back in. It may have seen a stale RSCN about us.
+ */
+- if (rdata->disc_id)
+- fc_rport_state_enter(rdata, RPORT_ST_RESTART);
++ if (rdata->rp_state != RPORT_ST_DELETE && rdata->disc_id)
++ fc_rport_enter_plogi(rdata);
++ else
++ fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+ mutex_unlock(&rdata->rp_mutex);
+ } else
+ FC_RPORT_ID_DBG(lport, sid,
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 549bc7d..562d8ce 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -2408,7 +2408,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
+ vport->els_tmofunc.function = lpfc_els_timeout;
+ vport->els_tmofunc.data = (unsigned long)vport;
+
+- error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
++ error = scsi_add_host(shost, dev);
+ if (error)
+ goto out_put_shost;
+
+@@ -4384,13 +4384,9 @@ lpfc_sli_pci_mem_setup(struct lpfc_hba *phba)
+ pdev = phba->pcidev;
+
+ /* Set the device DMA mask size */
+- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0
+- || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) {
+- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0
+- || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) {
++ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
++ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
+ return error;
+- }
+- }
+
+ /* Get the bus address of Bar0 and Bar2 and the number of bytes
+ * required by each mapping.
+@@ -5944,13 +5940,9 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
+ pdev = phba->pcidev;
+
+ /* Set the device DMA mask size */
+- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0
+- || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) {
+- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0
+- || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) {
++ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
++ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
+ return error;
+- }
+- }
+
+ /* Get the bus address of SLI4 device Bar0, Bar1, and Bar2 and the
+ * number of bytes required by each mapping. They are actually
+diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
+index 518712c..a39addc 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.c
++++ b/drivers/scsi/megaraid/megaraid_sas.c
+@@ -3032,7 +3032,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ int error = 0, i;
+ void *sense = NULL;
+ dma_addr_t sense_handle;
+- unsigned long *sense_ptr;
++ u32 *sense_ptr;
+
+ memset(kbuff_arr, 0, sizeof(kbuff_arr));
+
+@@ -3109,7 +3109,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ }
+
+ sense_ptr =
+- (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
++ (u32 *) ((unsigned long)cmd->frame + ioc->sense_off);
+ *sense_ptr = sense_handle;
+ }
+
+@@ -3140,8 +3140,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ * sense_ptr points to the location that has the user
+ * sense buffer address
+ */
+- sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
+- ioc->sense_off);
++ sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw +
++ ioc->sense_off);
+
+ if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
+ sense, ioc->sense_len)) {
+@@ -3451,7 +3451,7 @@ out:
+ return retval;
+ }
+
+-static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR,
++static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO,
+ megasas_sysfs_show_poll_mode_io,
+ megasas_sysfs_set_poll_mode_io);
+
+diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
+index 5af66db..ab47c46 100644
+--- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
++++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
+@@ -348,14 +348,6 @@ typedef struct _MPI2_CONFIG_REPLY
+ #define MPI2_MFGPAGE_DEVID_SAS2108_3 (0x0077)
+ #define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064)
+ #define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065)
+-#define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080)
+-#define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081)
+-#define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082)
+-#define MPI2_MFGPAGE_DEVID_SAS2208_4 (0x0083)
+-#define MPI2_MFGPAGE_DEVID_SAS2208_5 (0x0084)
+-#define MPI2_MFGPAGE_DEVID_SAS2208_6 (0x0085)
+-#define MPI2_MFGPAGE_DEVID_SAS2208_7 (0x0086)
+-#define MPI2_MFGPAGE_DEVID_SAS2208_8 (0x0087)
+
+
+ /* Manufacturing Page 0 */
+diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+index 1743640..86ab32d 100644
+--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
++++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+@@ -196,28 +196,10 @@ static struct pci_device_id scsih_pci_table[] = {
+ PCI_ANY_ID, PCI_ANY_ID },
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
+ PCI_ANY_ID, PCI_ANY_ID },
+- /* Meteor ~ 2116 */
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
+ PCI_ANY_ID, PCI_ANY_ID },
+- /* Thunderbolt ~ 2208 */
+- { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
+- PCI_ANY_ID, PCI_ANY_ID },
+- { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
+- PCI_ANY_ID, PCI_ANY_ID },
+- { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
+- PCI_ANY_ID, PCI_ANY_ID },
+- { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
+- PCI_ANY_ID, PCI_ANY_ID },
+- { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
+- PCI_ANY_ID, PCI_ANY_ID },
+- { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
+- PCI_ANY_ID, PCI_ANY_ID },
+- { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7,
+- PCI_ANY_ID, PCI_ANY_ID },
+- { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8,
+- PCI_ANY_ID, PCI_ANY_ID },
+ {0} /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(pci, scsih_pci_table);
+diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
+index 21e2bc4..fbcb82a 100644
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -1654,8 +1654,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
+ fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
+ }
+
+- if (scsi_add_host_with_dma(vha->host, &fc_vport->dev,
+- &ha->pdev->dev)) {
++ if (scsi_add_host(vha->host, &fc_vport->dev)) {
+ DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n",
+ vha->host_no, vha->vp_idx));
+ goto vport_create_failed_2;
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 06bbe0d..b79fca7 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -2016,13 +2016,13 @@ skip_dpc:
+ DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n",
+ base_vha->host_no, ha));
+
++ base_vha->flags.init_done = 1;
++ base_vha->flags.online = 1;
++
+ ret = scsi_add_host(host, &pdev->dev);
+ if (ret)
+ goto probe_failed;
+
+- base_vha->flags.init_done = 1;
+- base_vha->flags.online = 1;
+-
+ ha->isp_ops->enable_intrs(ha);
+
+ scsi_scan_host(host);
+diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
+index 802e91c..93c2622 100644
+--- a/drivers/scsi/scsi_devinfo.c
++++ b/drivers/scsi/scsi_devinfo.c
+@@ -168,10 +168,11 @@ static struct {
+ {"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN | BLIST_INQUIRY_36},
+ {"Generic", "USB Storage-SMC", "0180", BLIST_FORCELUN | BLIST_INQUIRY_36},
+ {"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN | BLIST_INQUIRY_36},
+- {"HITACHI", "DF400", "*", BLIST_REPORTLUN2},
+- {"HITACHI", "DF500", "*", BLIST_REPORTLUN2},
+- {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2},
+- {"HITACHI", "OPEN-", "*", BLIST_REPORTLUN2},
++ {"HITACHI", "DF400", "*", BLIST_SPARSELUN},
++ {"HITACHI", "DF500", "*", BLIST_SPARSELUN},
++ {"HITACHI", "DF600", "*", BLIST_SPARSELUN},
++ {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN},
++ {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN},
+ {"HITACHI", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+ {"HITACHI", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+ {"HITACHI", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index bc9a881..5987da8 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -749,9 +749,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
+ */
+ req->next_rq->resid_len = scsi_in(cmd)->resid;
+
+- scsi_release_buffers(cmd);
+ blk_end_request_all(req, 0);
+
++ scsi_release_buffers(cmd);
+ scsi_next_command(cmd);
+ return;
+ }
+diff --git a/drivers/scsi/scsi_lib_dma.c b/drivers/scsi/scsi_lib_dma.c
+index dcd1285..ac6855c 100644
+--- a/drivers/scsi/scsi_lib_dma.c
++++ b/drivers/scsi/scsi_lib_dma.c
+@@ -23,7 +23,7 @@ int scsi_dma_map(struct scsi_cmnd *cmd)
+ int nseg = 0;
+
+ if (scsi_sg_count(cmd)) {
+- struct device *dev = cmd->device->host->dma_dev;
++ struct device *dev = cmd->device->host->shost_gendev.parent;
+
+ nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
+ cmd->sc_data_direction);
+@@ -41,7 +41,7 @@ EXPORT_SYMBOL(scsi_dma_map);
+ void scsi_dma_unmap(struct scsi_cmnd *cmd)
+ {
+ if (scsi_sg_count(cmd)) {
+- struct device *dev = cmd->device->host->dma_dev;
++ struct device *dev = cmd->device->host->shost_gendev.parent;
+
+ dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
+ cmd->sc_data_direction);
+diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
+index bf52dec..c6f70da 100644
+--- a/drivers/scsi/scsi_transport_fc.c
++++ b/drivers/scsi/scsi_transport_fc.c
+@@ -648,22 +648,11 @@ static __init int fc_transport_init(void)
+ return error;
+ error = transport_class_register(&fc_vport_class);
+ if (error)
+- goto unreg_host_class;
++ return error;
+ error = transport_class_register(&fc_rport_class);
+ if (error)
+- goto unreg_vport_class;
+- error = transport_class_register(&fc_transport_class);
+- if (error)
+- goto unreg_rport_class;
+- return 0;
+-
+-unreg_rport_class:
+- transport_class_unregister(&fc_rport_class);
+-unreg_vport_class:
+- transport_class_unregister(&fc_vport_class);
+-unreg_host_class:
+- transport_class_unregister(&fc_host_class);
+- return error;
++ return error;
++ return transport_class_register(&fc_transport_class);
+ }
+
+ static void __exit fc_transport_exit(void)
+@@ -2395,7 +2384,6 @@ fc_rport_final_delete(struct work_struct *work)
+ struct Scsi_Host *shost = rport_to_shost(rport);
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ unsigned long flags;
+- int do_callback = 0;
+
+ /*
+ * if a scan is pending, flush the SCSI Host work_q so that
+@@ -2434,15 +2422,8 @@ fc_rport_final_delete(struct work_struct *work)
+ * Avoid this call if we already called it when we preserved the
+ * rport for the binding.
+ */
+- spin_lock_irqsave(shost->host_lock, flags);
+ if (!(rport->flags & FC_RPORT_DEVLOSS_CALLBK_DONE) &&
+- (i->f->dev_loss_tmo_callbk)) {
+- rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
+- do_callback = 1;
+- }
+- spin_unlock_irqrestore(shost->host_lock, flags);
+-
+- if (do_callback)
++ (i->f->dev_loss_tmo_callbk))
+ i->f->dev_loss_tmo_callbk(rport);
+
+ fc_bsg_remove(rport->rqst_q);
+@@ -2989,7 +2970,6 @@ fc_timeout_deleted_rport(struct work_struct *work)
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+ unsigned long flags;
+- int do_callback = 0;
+
+ spin_lock_irqsave(shost->host_lock, flags);
+
+@@ -3055,6 +3035,7 @@ fc_timeout_deleted_rport(struct work_struct *work)
+ rport->roles = FC_PORT_ROLE_UNKNOWN;
+ rport->port_state = FC_PORTSTATE_NOTPRESENT;
+ rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
++ rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
+
+ /*
+ * Pre-emptively kill I/O rather than waiting for the work queue
+@@ -3064,40 +3045,32 @@ fc_timeout_deleted_rport(struct work_struct *work)
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ fc_terminate_rport_io(rport);
+
+- spin_lock_irqsave(shost->host_lock, flags);
+-
+- if (rport->port_state == FC_PORTSTATE_NOTPRESENT) { /* still missing */
+-
+- /* remove the identifiers that aren't used in the consisting binding */
+- switch (fc_host->tgtid_bind_type) {
+- case FC_TGTID_BIND_BY_WWPN:
+- rport->node_name = -1;
+- rport->port_id = -1;
+- break;
+- case FC_TGTID_BIND_BY_WWNN:
+- rport->port_name = -1;
+- rport->port_id = -1;
+- break;
+- case FC_TGTID_BIND_BY_ID:
+- rport->node_name = -1;
+- rport->port_name = -1;
+- break;
+- case FC_TGTID_BIND_NONE: /* to keep compiler happy */
+- break;
+- }
+-
+- /*
+- * As this only occurs if the remote port (scsi target)
+- * went away and didn't come back - we'll remove
+- * all attached scsi devices.
+- */
+- rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
+- fc_queue_work(shost, &rport->stgt_delete_work);
++ BUG_ON(rport->port_state != FC_PORTSTATE_NOTPRESENT);
+
+- do_callback = 1;
++ /* remove the identifiers that aren't used in the consisting binding */
++ switch (fc_host->tgtid_bind_type) {
++ case FC_TGTID_BIND_BY_WWPN:
++ rport->node_name = -1;
++ rport->port_id = -1;
++ break;
++ case FC_TGTID_BIND_BY_WWNN:
++ rport->port_name = -1;
++ rport->port_id = -1;
++ break;
++ case FC_TGTID_BIND_BY_ID:
++ rport->node_name = -1;
++ rport->port_name = -1;
++ break;
++ case FC_TGTID_BIND_NONE: /* to keep compiler happy */
++ break;
+ }
+
+- spin_unlock_irqrestore(shost->host_lock, flags);
++ /*
++ * As this only occurs if the remote port (scsi target)
++ * went away and didn't come back - we'll remove
++ * all attached scsi devices.
++ */
++ fc_queue_work(shost, &rport->stgt_delete_work);
+
+ /*
+ * Notify the driver that the rport is now dead. The LLDD will
+@@ -3105,7 +3078,7 @@ fc_timeout_deleted_rport(struct work_struct *work)
+ *
+ * Note: we set the CALLBK_DONE flag above to correspond
+ */
+- if (do_callback && i->f->dev_loss_tmo_callbk)
++ if (i->f->dev_loss_tmo_callbk)
+ i->f->dev_loss_tmo_callbk(rport);
+ }
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index de2f8c4..ad897df 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -627,10 +627,8 @@ static void __iscsi_block_session(struct work_struct *work)
+ spin_unlock_irqrestore(&session->lock, flags);
+ scsi_target_block(&session->dev);
+ ISCSI_DBG_TRANS_SESSION(session, "Completed SCSI target blocking\n");
+- if (session->recovery_tmo >= 0)
+- queue_delayed_work(iscsi_eh_timer_workq,
+- &session->recovery_work,
+- session->recovery_tmo * HZ);
++ queue_delayed_work(iscsi_eh_timer_workq, &session->recovery_work,
++ session->recovery_tmo * HZ);
+ }
+
+ void iscsi_block_session(struct iscsi_cls_session *session)
+@@ -1350,7 +1348,8 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+ switch (ev->u.set_param.param) {
+ case ISCSI_PARAM_SESS_RECOVERY_TMO:
+ sscanf(data, "%d", &value);
+- session->recovery_tmo = value;
++ if (value != 0)
++ session->recovery_tmo = value;
+ break;
+ default:
+ err = transport->set_param(conn, ev->u.set_param.param,
+diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
+index 5081f97..12d58a7 100644
+--- a/drivers/scsi/st.c
++++ b/drivers/scsi/st.c
+@@ -552,15 +552,13 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd
+ SRpnt->waiting = waiting;
+
+ if (STp->buffer->do_dio) {
+- mdata->page_order = 0;
+ mdata->nr_entries = STp->buffer->sg_segs;
+ mdata->pages = STp->buffer->mapped_pages;
+ } else {
+- mdata->page_order = STp->buffer->reserved_page_order;
+ mdata->nr_entries =
+ DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
+- mdata->pages = STp->buffer->reserved_pages;
+- mdata->offset = 0;
++ STp->buffer->map_data.pages = STp->buffer->reserved_pages;
++ STp->buffer->map_data.offset = 0;
+ }
+
+ memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
+@@ -3720,7 +3718,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
+ priority |= __GFP_ZERO;
+
+ if (STbuffer->frp_segs) {
+- order = STbuffer->reserved_page_order;
++ order = STbuffer->map_data.page_order;
+ b_size = PAGE_SIZE << order;
+ } else {
+ for (b_size = PAGE_SIZE, order = 0;
+@@ -3753,7 +3751,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
+ segs++;
+ }
+ STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
+- STbuffer->reserved_page_order = order;
++ STbuffer->map_data.page_order = order;
+
+ return 1;
+ }
+@@ -3766,7 +3764,7 @@ static void clear_buffer(struct st_buffer * st_bp)
+
+ for (i=0; i < st_bp->frp_segs; i++)
+ memset(page_address(st_bp->reserved_pages[i]), 0,
+- PAGE_SIZE << st_bp->reserved_page_order);
++ PAGE_SIZE << st_bp->map_data.page_order);
+ st_bp->cleared = 1;
+ }
+
+@@ -3774,7 +3772,7 @@ static void clear_buffer(struct st_buffer * st_bp)
+ /* Release the extra buffer */
+ static void normalize_buffer(struct st_buffer * STbuffer)
+ {
+- int i, order = STbuffer->reserved_page_order;
++ int i, order = STbuffer->map_data.page_order;
+
+ for (i = 0; i < STbuffer->frp_segs; i++) {
+ __free_pages(STbuffer->reserved_pages[i], order);
+@@ -3782,7 +3780,7 @@ static void normalize_buffer(struct st_buffer * STbuffer)
+ }
+ STbuffer->frp_segs = 0;
+ STbuffer->sg_segs = 0;
+- STbuffer->reserved_page_order = 0;
++ STbuffer->map_data.page_order = 0;
+ STbuffer->map_data.offset = 0;
+ }
+
+@@ -3792,7 +3790,7 @@ static void normalize_buffer(struct st_buffer * STbuffer)
+ static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
+ {
+ int i, cnt, res, offset;
+- int length = PAGE_SIZE << st_bp->reserved_page_order;
++ int length = PAGE_SIZE << st_bp->map_data.page_order;
+
+ for (i = 0, offset = st_bp->buffer_bytes;
+ i < st_bp->frp_segs && offset >= length; i++)
+@@ -3824,7 +3822,7 @@ static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, in
+ static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
+ {
+ int i, cnt, res, offset;
+- int length = PAGE_SIZE << st_bp->reserved_page_order;
++ int length = PAGE_SIZE << st_bp->map_data.page_order;
+
+ for (i = 0, offset = st_bp->read_pointer;
+ i < st_bp->frp_segs && offset >= length; i++)
+@@ -3857,7 +3855,7 @@ static void move_buffer_data(struct st_buffer * st_bp, int offset)
+ {
+ int src_seg, dst_seg, src_offset = 0, dst_offset;
+ int count, total;
+- int length = PAGE_SIZE << st_bp->reserved_page_order;
++ int length = PAGE_SIZE << st_bp->map_data.page_order;
+
+ if (offset == 0)
+ return;
+@@ -4579,6 +4577,7 @@ static int sgl_map_user_pages(struct st_buffer *STbp,
+ }
+
+ mdata->offset = uaddr & ~PAGE_MASK;
++ mdata->page_order = 0;
+ STbp->mapped_pages = pages;
+
+ return nr_pages;
+diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
+index f91a67c..544dc6b 100644
+--- a/drivers/scsi/st.h
++++ b/drivers/scsi/st.h
+@@ -46,7 +46,6 @@ struct st_buffer {
+ struct st_request *last_SRpnt;
+ struct st_cmdstatus cmdstat;
+ struct page **reserved_pages;
+- int reserved_page_order;
+ struct page **mapped_pages;
+ struct rq_map_data map_data;
+ unsigned char *b_data;
+diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
+index 5ed1b82..737b4c9 100644
+--- a/drivers/serial/8250.c
++++ b/drivers/serial/8250.c
+@@ -83,9 +83,6 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */
+
+ #define PASS_LIMIT 256
+
+-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+-
+-
+ /*
+ * We default to IRQ0 for the "no irq" hack. Some
+ * machine types want others as well - they're free
+@@ -1342,12 +1339,14 @@ static void serial8250_start_tx(struct uart_port *port)
+ serial_out(up, UART_IER, up->ier);
+
+ if (up->bugs & UART_BUG_TXEN) {
+- unsigned char lsr;
++ unsigned char lsr, iir;
+ lsr = serial_in(up, UART_LSR);
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++ iir = serial_in(up, UART_IIR) & 0x0f;
+ if ((up->port.type == PORT_RM9000) ?
+- (lsr & UART_LSR_THRE) :
+- (lsr & UART_LSR_TEMT))
++ (lsr & UART_LSR_THRE &&
++ (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) :
++ (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT))
+ transmit_chars(up);
+ }
+ }
+@@ -1795,7 +1794,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+- return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
++ return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+ }
+
+ static unsigned int serial8250_get_mctrl(struct uart_port *port)
+@@ -1853,6 +1852,8 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
+ spin_unlock_irqrestore(&up->port.lock, flags);
+ }
+
++#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
++
+ /*
+ * Wait for transmitter & holding register to empty
+ */
+diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
+index deac67e..d71dfe3 100644
+--- a/drivers/serial/8250_pnp.c
++++ b/drivers/serial/8250_pnp.c
+@@ -328,7 +328,15 @@ static const struct pnp_device_id pnp_dev_table[] = {
+ /* U.S. Robotics 56K Voice INT PnP*/
+ { "USR9190", 0 },
+ /* Wacom tablets */
+- { "WACFXXX", 0 },
++ { "WACF004", 0 },
++ { "WACF005", 0 },
++ { "WACF006", 0 },
++ { "WACF007", 0 },
++ { "WACF008", 0 },
++ { "WACF009", 0 },
++ { "WACF00A", 0 },
++ { "WACF00B", 0 },
++ { "WACF00C", 0 },
+ /* Compaq touchscreen */
+ { "FPI2002", 0 },
+ /* Fujitsu Stylistic touchscreens */
+@@ -346,8 +354,6 @@ static const struct pnp_device_id pnp_dev_table[] = {
+ { "FUJ02E5", 0 },
+ /* Fujitsu P-series tablet PC device */
+ { "FUJ02E6", 0 },
+- /* Fujitsu Wacom 2FGT Tablet PC device */
+- { "FUJ02E7", 0 },
+ /*
+ * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
+ * disguise)
+diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
+index e522572..c6d7e6e 100644
+--- a/drivers/serial/Kconfig
++++ b/drivers/serial/Kconfig
+@@ -663,6 +663,27 @@ config SERIAL_PXA_CONSOLE
+ your boot loader (lilo or loadlin) about how to pass options to the
+ kernel at boot time.)
+
++config SERIAL_TMPA910
++ bool "Additional TMPA910 serial port support"
++ depends on ARM && ARCH_TMPA910
++ select SERIAL_CORE
++ help
++ If you have a Firmware TMPA910 based machine and you
++ want to use an additional serial port
++
++config SERIAL_TMPA910_CONSOLE
++ bool "Console on Additional TMPA910 serial port"
++ depends on SERIAL_TMPA910
++ select SERIAL_CORE_CONSOLE
++ help
++ Add TMPA910 serial port to console
++ serial port
++
++config SERIAL_TMPA910_CONSOLE_PREFERED
++ bool "Add the first TMPA910 additional serial port to prefered console"
++ depends on SERIAL_TMPA910_CONSOLE
++
++
+ config SERIAL_SA1100
+ bool "SA1100 serial port support"
+ depends on ARM && ARCH_SA1100
+diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
+index d21d5dd..41c7f8f 100644
+--- a/drivers/serial/Makefile
++++ b/drivers/serial/Makefile
+@@ -32,6 +32,7 @@ obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
+ obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
+ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
+ obj-$(CONFIG_SERIAL_PXA) += pxa.o
++obj-$(CONFIG_SERIAL_TMPA910) += tmpa910.o
+ obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
+ obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
+ obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
+diff --git a/drivers/serial/tmpa910.c b/drivers/serial/tmpa910.c
+new file mode 100644
+index 0000000..c6f7269
+--- /dev/null
++++ b/drivers/serial/tmpa910.c
+@@ -0,0 +1,1215 @@
++/*
++ * linux/drivers/serial/tmpa910_fw.c
++ *
++ * Based on drivers/serial/pxa.c by Nicolas Pitre
++ *
++ * Author: Nicolas
++ * Created: Feb 20, 2003
++ * Copyright: (C) 2008 bplan GmbH
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++
++ */
++
++
++/*********/
++/*********/
++#include <linux/module.h>
++#include <linux/ioport.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/sysrq.h>
++#include <linux/serial_reg.h>
++#include <linux/circ_buf.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial_core.h>
++#include <linux/ioport.h>
++
++
++#include <asm/io.h>
++#include <mach/hardware.h>
++#include <asm/irq.h>
++/*********/
++/*********/
++
++
++#define DRIVER_NAME "tmpa910_uart"
++
++#define TMPA910_UART_REGSIZE 0x50
++#define TMPA910_SERIAL_MAX 2
++#define TMPA910_NAME_PATTERN "TMPA910 UART Channel %d"
++/*********/
++/*********/
++struct tmpa910_uart_regs
++{
++ uint32_t dr; // 0x000
++ uint32_t sr; // 0x004
++ uint32_t ecr; // 0x004
++ uint32_t rsd1[3]; // 0x008 -> 0x014
++ uint32_t fr; // 0x018
++ uint32_t rsd2; // 0x01c
++ uint32_t ilpr; // 0x020
++ uint32_t ibrd; // 0x024
++ uint32_t fbrd; // 0x028
++ uint32_t lcr_h; // 0x02c
++ uint32_t cr; // 0x030
++ uint32_t ifls; // 0x034
++ uint32_t imsc; // 0x038
++ uint32_t ris; // 0x03c
++ uint32_t mis; // 0x040
++ uint32_t icr; // 0x044
++ uint32_t dmacr; // 0x048
++};
++/*********/
++/*********/
++// The data register contains 8bit for the char and 4 status bits
++
++#define DR_OE (1<<11) // OE RO Undefined Overrun error
++ // 0y0: There is an empty space in the FIFO.
++ // 0y1: Overrun error flag
++#define DR_BE (1<<10) // BE RO Undefined Break error
++ // 0y0: No error detected
++ // 0y1: Error detected
++#define DR_PE (1<<9) // PE RO Undefined Parity error
++ // 0y0: No error detected
++ // 0y1: Error detected
++#define DR_FE (1<<8) // FE RO Undefined Framing error
++ // 0y0: No error detected
++ // 0y1: Error detected
++/*********/
++/*********/
++// The data register contains 8bit for the char and 4 status bits
++
++#define SR_OE (1<<3)
++#define SR_BE (1<<2)
++#define SR_PE (1<<1)
++#define SR_FE (1<<0)
++
++/*********/
++/*********/
++
++#define LCRH_SPS (1<<7) SPS R/W 0y0 Stick parity select:
++#define LCRH_WLEN_5B (0x0 )
++#define LCRH_WLEN_6B (0x1<<5)
++#define LCRH_WLEN_7B (0x2<<5)
++#define LCRH_WLEN_8B (0x3<<5)
++#define LCRH_FEN (1<<4) // R/W 0y0 FIFO control
++ // 0y1: FIFO mode
++ // 0y0: Character mode
++#define LCRH_STP2 (1<<3) // STP2 R/W 0y0 Stop bit select
++ // 0y0: 1 stop bit
++ // 0y1: 2 stop bits
++#define LCRH_EPS (1<<2) // EPS R/W 0y0 Even parity select (Refer to Table 3.13.1 for
++ // the truth table.)
++ // 0y1: Even
++ // 0y0: Odd
++#define LCRH_PEN (1<<1) // PEN R/W 0y0 Parity control (Refer to Table 3.13.1 for the
++ // truth table.)
++ // 0y0: Disable
++ // 0y1: Enable
++#define LCRH_BRK (1<<0) // BRK R/W 0y0 Send break
++ // 0y0: No effect
++ // 0y1: Send break
++
++/*********/
++/*********/
++#define CR_CTSEn (1<<15) // CTSEn R/W 0y0 CTS hardware flow control enable
++#define CR_RTSEn (1<<14) // RTSEn R/W 0y0 RTS hardware flow control enable
++
++#define CR_RTS (1<<11) // R/W 0y0 Complement of the UART Request To Send
++ // (nUARTRTS) modem status output
++ // 0y0: Modem status output is "1".
++ // 0y1: Modem status output is "0".
++#define CR_DTR (1<<10) // R/W 0y0 Complement of the UART Data Set Ready
++ // (nUARTDTR) modem status output
++ // 0y0: Modem status output is "1".
++ // 0y1: Modem status output is "0".
++#define CR_RXE (1<<9) // RXE R/W 0y1 UART receive enable
++#define CR_TXE (1<<8) // TXE R/W 0y1 UART transmit enable
++
++#define CR_SIRLP (1<<2) // SIRLP R/W 0y0 IrDA encoding mode select for transmitting "0"
++ // 0y0: "0" bits are transmitted as an active high
++ // pulse of 3/16th of the bit period.
++ // 0y1:"0" bits are transmitted with a pulse width
++ // that is 3 times the period of the IrLPBaud16
++ // input signal.
++
++#define CR_SIREN (1<<1) // SIREN R/W 0y0 SIR enable
++#define CR_UARTEN (1<<0) // UARTEN R/W 0y0 UART enable
++
++
++/*********/
++/*********/
++/* Flag register */
++
++#define FR_RI (1<<8) // Ring indicator flag
++#define FR_TXFE (1<<7) // Transmit FIFO empty flag
++#define FR_RXFF (1<<6) // Receive FIFO full flag
++#define FR_TXFF (1<<5) // Transmit FIFO full flag
++#define FR_RXFE (1<<4) // Receive FIFO empty flag
++#define FR_BUSY (1<<3) // Busy flag
++#define FR_DCD (1<<2) // Data carrier detect flag
++#define FR_DSR (1<<1) // Data set ready flag
++#define FR_CTS (1<<0) // Clear To Send flag
++
++
++/*********/
++/*********/
++
++// for interrupt mask and status
++// 0y0: Clear the mask
++// 0y1: Set the mask
++
++#define INT_OE (1<<10) // OEIM R/W 0y0 Overrun error
++#define INT_BE (1<<9) // BEIM R/W 0y0 Break error
++#define INT_BEIM (1<<8) // PEIM R/W 0y0 Parity error
++#define INT_FEIM (1<<7) // FEIM R/W 0y0 Framing error
++#define INT_RTIM (1<<6) // RTIM R/W 0y0 Receive timeout
++#define INT_TX (1<<5) // TXIM R/W 0y0 Transmit interrupt
++#define INT_RX (1<<4) // RXIM R/W 0y0 Receive interrupt
++#define INT_DSRM (1<<3) // DSRMIM R/W 0y0 U0DSRn modem interrupt
++#define INT_DCDM (1<<2) // DCDMIM R/W 0y0 U0DCDn modem interrupt
++#define INT_CTSM (1<<1) // CTSMIM R/W 0y0 U0CTSn modem interrupt
++#define INT_RIM (1<<0) // RIMIM R/W 0y0 U0RIn modem interrupt
++
++
++
++struct uart_tmpa910_handle {
++ struct uart_port port;
++ int channel;
++ int irq_allocated;
++
++ volatile struct tmpa910_uart_regs *regs;
++ char name[sizeof(TMPA910_NAME_PATTERN)];
++};
++
++/*********/
++/*********/
++static struct uart_tmpa910_handle serial_ports[TMPA910_SERIAL_MAX];
++
++static int _fill_uarthandle(
++ struct uart_tmpa910_handle *uart_tmpa910_handle,
++ int index);
++
++
++static inline void wait_for_xmitr(struct uart_tmpa910_handle *uart_tmpa910_handle);
++static inline void wait_for_txempty(struct uart_tmpa910_handle *uart_tmpa910_handle);
++/*********/
++/*********/
++
++static int _get_uartclk(struct uart_tmpa910_handle *uart_tmpa910_handle)
++{
++ return 96*1000*1000;
++}
++
++#ifdef __DEBUG__
++static void _dump_regs(struct uart_tmpa910_handle *uart_tmpa910_handle)
++{
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++
++ printk("port at 0x%p / 0x%lx\n", regs, (unsigned long) uart_tmpa910_handle->port.mapbase);
++
++ if (regs == NULL)
++ return;
++
++ printk("dr at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, dr ), regs->dr);
++ printk("sr at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, sr ), regs->sr);
++ printk("ecr at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, ecr ), regs->ecr);
++ printk("fr at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, fr), regs->fr);
++ printk("ilpr at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, ilpr ), regs->ilpr);
++ printk("ibrd at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, ibrd ), regs->ibrd);
++ printk("fbrd at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, fbrd ), regs->fbrd);
++ printk("lcr_h at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, lcr_h), regs->lcr_h);
++ printk("cr at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, cr ), regs->cr);
++ printk("ifls at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, ifls ), regs->ifls);
++ printk("imsc at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, imsc ), regs->imsc);
++ printk("ris at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, ris ), regs->ris);
++ printk("mis at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, mis ), regs->mis);
++ printk("icr at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, icr ), regs->icr);
++ printk("dmacr at 0x%2x: 0x%8x\n", offsetof(struct tmpa910_uart_regs, dmacr ), regs->dmacr);
++
++}
++
++#endif
++/*********/
++/*********/
++
++
++static int _map_tmpa910(struct uart_tmpa910_handle *uart_tmpa910_handle)
++{
++
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++
++ if (regs) {
++ printk(KERN_ERR "port already requested or mapped (regs=0x%p)\n", regs);
++ return 0;
++ }
++
++ regs = uart_tmpa910_handle->port.mapbase;
++ if (regs == NULL) {
++ printk(KERN_ERR "Fail to map UART controller (mapbase=0x%x)\n", uart_tmpa910_handle->port.mapbase);
++ return -EINVAL;
++ }
++
++
++ uart_tmpa910_handle->port.membase = (void *) regs;
++ uart_tmpa910_handle->regs = regs;
++
++
++#ifdef __DEBUG__
++ _dump_regs(uart_tmpa910_handle);
++#endif
++
++ return 0;
++}
++
++
++/*********/
++/*********/
++
++
++
++static void serial_tmpa910_enable_ms(struct uart_port *port)
++{
++}
++
++static void serial_tmpa910_stop_tx(struct uart_port *port)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++
++ regs->imsc &= ~INT_TX;
++}
++
++static void serial_tmpa910_stop_rx(struct uart_port *port)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++
++ regs->imsc &= ~INT_RX;
++}
++
++
++
++static void transmit_chars(struct uart_tmpa910_handle *uart_tmpa910_handle)
++{
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ struct circ_buf *xmit = &uart_tmpa910_handle->port.state->xmit;
++ int count;
++
++ if (uart_tmpa910_handle->port.x_char) {
++ wait_for_xmitr(uart_tmpa910_handle);
++ regs->dr = uart_tmpa910_handle->port.x_char & 0xff;
++ uart_tmpa910_handle->port.icount.tx++;
++ uart_tmpa910_handle->port.x_char = 0;
++ return;
++ }
++ if (uart_circ_empty(xmit) || uart_tx_stopped(&uart_tmpa910_handle->port)) {
++ serial_tmpa910_stop_tx(&uart_tmpa910_handle->port);
++ return;
++ }
++
++ count = uart_tmpa910_handle->port.fifosize;
++ do {
++ wait_for_xmitr(uart_tmpa910_handle);
++ regs->dr = xmit->buf[xmit->tail] & 0xff;
++ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
++ uart_tmpa910_handle->port.icount.tx++;
++ if (uart_circ_empty(xmit))
++ break;
++ } while (--count > 0);
++
++ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++ uart_write_wakeup(&uart_tmpa910_handle->port);
++
++
++ if (uart_circ_empty(xmit))
++ serial_tmpa910_stop_tx(&uart_tmpa910_handle->port);
++}
++
++
++static inline void
++receive_chars(struct uart_tmpa910_handle *uart_tmpa910_handle)
++{
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ struct tty_struct *tty = uart_tmpa910_handle->port.state->port.tty;
++ unsigned int ch, flag;
++ uint32_t fr_reg;
++ uint32_t dr_reg;
++ int max_count = 256;
++
++ do {
++ fr_reg = regs->fr;
++ dr_reg = regs->dr;
++
++ ch = regs->dr & 0xff;
++ flag = TTY_NORMAL;
++
++ uart_tmpa910_handle->port.icount.rx++;
++
++ if (unlikely(fr_reg & (UART_LSR_BI | UART_LSR_PE |
++ UART_LSR_FE | UART_LSR_OE))) {
++ /*
++ * For statistics only
++ */
++ if (dr_reg & DR_BE) {
++ uart_tmpa910_handle->port.icount.brk++;
++ /*
++ * We do the SysRQ and SAK checking
++ * here because otherwise the break
++ * may get masked by ignore_status_mask
++ * or read_status_mask.
++ */
++ if (uart_handle_break(&uart_tmpa910_handle->port))
++ goto ignore_char;
++ } else if (dr_reg & DR_PE)
++ uart_tmpa910_handle->port.icount.parity++;
++ else if (dr_reg &DR_FE)
++ uart_tmpa910_handle->port.icount.frame++;
++ if (dr_reg & DR_OE)
++ uart_tmpa910_handle->port.icount.overrun++;
++
++ /*
++ * Mask off conditions which should be ignored.
++ */
++ // *status &= up->port.read_status_mask;
++
++#if defined(CONFIG_SERIAL_TMPA910_CONSOLE) && 0
++ if (up->port.line == up->port.cons->index) {
++ /* Recover the break flag from console xmit */
++ *status |= up->lsr_break_flag;
++ uart_tmpa910_handle->lsr_break_flag = 0;
++ }
++#endif
++ if (dr_reg & DR_BE) {
++ flag = TTY_BREAK;
++ } else if (dr_reg & DR_PE)
++ flag = TTY_PARITY;
++ else if (dr_reg & DR_FE)
++ flag = TTY_FRAME;
++ }
++
++ if (uart_handle_sysrq_char(&uart_tmpa910_handle->port, ch))
++ goto ignore_char;
++
++ uart_insert_char(&uart_tmpa910_handle->port, dr_reg, DR_OE, ch, flag);
++
++ ignore_char:
++ fr_reg = regs->fr;
++ } while ( ((fr_reg & FR_RXFE)==0) && (max_count-- > 0));
++
++ tty_flip_buffer_push(tty);
++}
++
++
++static unsigned int serial_tmpa910_tx_empty(struct uart_port *port);
++static void serial_tmpa910_start_tx(struct uart_port *port)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ struct circ_buf *xmit = &uart_tmpa910_handle->port.state->xmit;
++
++ regs->imsc |= INT_TX;
++
++ if (uart_circ_chars_pending(xmit) )
++ {
++ wait_for_xmitr(uart_tmpa910_handle);
++ transmit_chars(uart_tmpa910_handle);
++ }
++}
++
++static inline void check_modem_status(struct uart_tmpa910_handle *uart_tmpa910_handle)
++{
++
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ uint32_t fr_reg;
++
++ fr_reg = regs->fr;
++
++ // rng is ring ? not documented..
++ if (fr_reg & FR_RI)
++ uart_tmpa910_handle->port.icount.rng++;
++ if (fr_reg & FR_DSR)
++ uart_tmpa910_handle->port.icount.dsr++;
++ if (fr_reg & FR_DCD)
++ uart_tmpa910_handle->port.icount.dcd++;
++ if (fr_reg & FR_CTS)
++ uart_tmpa910_handle->port.icount.cts++;
++
++ wake_up_interruptible(&uart_tmpa910_handle->port.state->port.delta_msr_wait);
++
++}
++
++/*
++ * This handles the interrupt from one port.
++ */
++
++
++static unsigned int serial_tmpa910_tx_empty(struct uart_port *port)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++
++ unsigned long flags;
++ unsigned int ret;
++
++
++ spin_lock_irqsave(&uart_tmpa910_handle->port.lock, flags);
++
++ ret = regs->fr & FR_TXFE;
++
++ spin_unlock_irqrestore(&uart_tmpa910_handle->port.lock, flags);
++
++ return ret;
++}
++
++static inline irqreturn_t
++serial_tmpa910_irq(int irq, void *dev_id)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)dev_id;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++
++ uint32_t mis_reg;
++ uint32_t icr_reg;
++
++ icr_reg = 0;
++ mis_reg = regs->mis;
++
++ if (mis_reg==0)
++ return IRQ_NONE;
++
++ if (mis_reg & INT_RX)
++ {
++ receive_chars(uart_tmpa910_handle);
++ icr_reg |= INT_RX;
++ }
++
++ check_modem_status(uart_tmpa910_handle);
++
++ if (mis_reg & INT_TX)
++ {
++ transmit_chars(uart_tmpa910_handle);
++ icr_reg |= INT_TX;
++ }
++
++ if (icr_reg)
++ regs->icr = icr_reg;
++
++ return IRQ_HANDLED;
++}
++
++static unsigned int serial_tmpa910_get_mctrl(struct uart_port *port)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++
++ unsigned int ret;
++ uint32_t fr_reg;
++
++ ret = 0;
++ fr_reg = regs->fr;
++
++ if (fr_reg & FR_DCD)
++ ret |= TIOCM_CAR;
++
++ if (fr_reg & FR_RI)
++ ret |= TIOCM_RNG;
++
++ if (fr_reg & FR_DSR)
++ ret |= TIOCM_DSR;
++
++ if (fr_reg & FR_CTS)
++ ret |= TIOCM_CTS;
++
++ return ret;
++}
++
++static void serial_tmpa910_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ uint32_t cr_reg;
++
++ cr_reg = 0;
++
++ if (mctrl & TIOCM_RTS)
++ cr_reg |= CR_RTS;
++ if (mctrl & TIOCM_DTR)
++ cr_reg |= CR_DTR;
++
++ regs->cr |= cr_reg;
++
++}
++
++static void serial_tmpa910_break_ctl(struct uart_port *port, int break_state)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ unsigned long flags;
++ uint32_t lcrh_reg;
++
++ spin_lock_irqsave(&uart_tmpa910_handle->port.lock, flags);
++
++ lcrh_reg = regs->lcr_h;
++
++ if (break_state == -1)
++ lcrh_reg |= LCRH_BRK;
++ else
++ lcrh_reg &= ~LCRH_BRK;
++
++
++ regs->lcr_h = lcrh_reg;
++
++ spin_unlock_irqrestore(&uart_tmpa910_handle->port.lock, flags);
++}
++
++
++static int serial_tmpa910_startup(struct uart_port *port)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ unsigned long flags;
++ int ret;
++
++ // Make sure the port is off and no IRQ could be generated
++ regs->cr = 0;
++ regs->imsc = 0;
++ regs->icr = 0x7ff;
++
++ // Clear errors if any
++ regs->ecr = 0x0;
++
++ /*
++ * Allocate the IRQ
++ */
++ ret = request_irq(uart_tmpa910_handle->port.irq, serial_tmpa910_irq, 0, uart_tmpa910_handle->name, uart_tmpa910_handle);
++ if (ret) {
++ printk(KERN_ERR "TMPA910 UART: Fail allocate the interrupt (vector=%d)\n", uart_tmpa910_handle->port.irq );
++ return ret;
++ }
++
++ uart_tmpa910_handle->irq_allocated = 1;
++
++ /*
++ * Clear the FIFO buffers and disable them.
++ * (they will be reenabled in set_termios())
++ */
++
++
++ /*
++ * Clear the interrupt registers.
++ */
++ regs->icr = 0x7ff;
++
++ /*
++ * Now, initialize the UART
++ */
++
++ spin_lock_irqsave(&uart_tmpa910_handle->port.lock, flags);
++ serial_tmpa910_set_mctrl(&uart_tmpa910_handle->port, uart_tmpa910_handle->port.mctrl);
++ spin_unlock_irqrestore(&uart_tmpa910_handle->port.lock, flags);
++
++ /*
++ * Finally, enable interrupts. Note: Modem status interrupts
++ * are set via set_termios(), which will be occurring imminently
++ * anyway, so we don't enable them here.
++ */
++ regs->imsc = INT_TX | INT_RX;
++ regs->lcr_h |= LCRH_FEN;
++ regs->cr |= CR_RXE | CR_TXE | CR_UARTEN;
++
++#ifdef __DEBUG__
++ _dump_regs(uart_tmpa910_handle);
++#endif
++
++ return 0;
++}
++
++static void serial_tmpa910_shutdown(struct uart_port *port)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ unsigned long flags;
++
++ /*
++ * Disable interrupts from this port
++ */
++ regs->cr = 0;
++ regs->imsc = 0;
++ regs->icr = 0x7ff;
++ regs->ecr = 0x0;
++
++ if (uart_tmpa910_handle->irq_allocated)
++ free_irq(uart_tmpa910_handle->port.irq, uart_tmpa910_handle);
++
++ uart_tmpa910_handle->irq_allocated = 0;
++
++
++ spin_lock_irqsave(&uart_tmpa910_handle->port.lock, flags);
++ serial_tmpa910_set_mctrl(&uart_tmpa910_handle->port, uart_tmpa910_handle->port.mctrl);
++ spin_unlock_irqrestore(&uart_tmpa910_handle->port.lock, flags);
++
++ /*
++ * Disable break condition and FIFOs
++ */
++
++}
++
++static inline int _get_div_fract(int uartclk, int baud, int div_integer)
++{
++ int a;
++
++ // Baud rate divisor = (UARTCLK)/(16 × baud)= integer part + fract part;
++ //
++ // When the required baud rate is 230400 and fUARTCLK = 4MHz:
++ // Baud rate divisor = (4 × 106)/(16 × 230400)= 1.085
++ // Therefore, fractional part is ((0.085 × 64)+ 0.5) = 5.94.
++
++ // a = divisor * 1000
++ a = ( (uartclk/16) *10) / (baud/100);
++
++ // a = integer part*1000 - divisor * 1000
++ // a -> fract part * 1000
++
++ a = a - div_integer*1000;
++ a = a * 64 + 500;
++ a = a / 1000;
++
++ return a;
++}
++
++static void
++serial_tmpa910_set_termios(struct uart_port *port, struct ktermios *termios,
++ struct ktermios *old)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ uint32_t lcrh_reg;
++ unsigned long flags;
++ unsigned int baud;
++ int div_integer;
++ int div_fract;
++
++ switch (termios->c_cflag & CSIZE) {
++ case CS5:
++ lcrh_reg = LCRH_WLEN_5B;
++ break;
++ case CS6:
++ lcrh_reg = LCRH_WLEN_5B;
++ break;
++ case CS7:
++ lcrh_reg = LCRH_WLEN_7B;
++ break;
++ default:
++ case CS8:
++ lcrh_reg = LCRH_WLEN_8B;
++ break;
++ }
++
++ if (termios->c_cflag & CSTOPB)
++ lcrh_reg |= LCRH_STP2;
++ if (termios->c_cflag & PARENB)
++ lcrh_reg |= LCRH_PEN;
++ if (!(termios->c_cflag & PARODD))
++ lcrh_reg |= LCRH_EPS;
++
++ /*
++ * Ask the core to calculate the divisor for us.
++ */
++ baud = uart_get_baud_rate(port, termios, old, 1200, _get_uartclk(uart_tmpa910_handle) / 16);
++ div_integer = uart_get_divisor(port, baud);
++ div_fract = _get_div_fract(_get_uartclk(uart_tmpa910_handle), baud, div_integer);
++
++ regs->ibrd = div_integer;
++ regs->fbrd = div_fract;
++ /*
++ * Ok, we're now changing the port state. Do it with
++ * interrupts disabled.
++ */
++ spin_lock_irqsave(&uart_tmpa910_handle->port.lock, flags);
++
++
++ /*
++ * Update the per-port timeout.
++ */
++ uart_update_timeout(port, termios->c_cflag, baud);
++
++ uart_tmpa910_handle->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
++ if (termios->c_iflag & INPCK)
++ uart_tmpa910_handle->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
++ if (termios->c_iflag & (BRKINT | PARMRK))
++ uart_tmpa910_handle->port.read_status_mask |= UART_LSR_BI;
++
++ /*
++ * Characters to ignore
++ */
++ uart_tmpa910_handle->port.ignore_status_mask = 0;
++ if (termios->c_iflag & IGNPAR)
++ uart_tmpa910_handle->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
++ if (termios->c_iflag & IGNBRK) {
++ uart_tmpa910_handle->port.ignore_status_mask |= UART_LSR_BI;
++ /*
++ * If we're ignoring parity and break indicators,
++ * ignore overruns too (for real raw support).
++ */
++ if (termios->c_iflag & IGNPAR)
++ uart_tmpa910_handle->port.ignore_status_mask |= UART_LSR_OE;
++ }
++
++ /*
++ * ignore all characters if CREAD is not set
++ */
++ if ((termios->c_cflag & CREAD) == 0)
++ uart_tmpa910_handle->port.ignore_status_mask |= UART_LSR_DR;
++
++ /*
++ * CTS flow control flag and modem status interrupts
++ */
++ //uart_tmpa910_handle->ier &= ~UART_IER_MSI;
++ //if (UART_ENABLE_MS(&uart_tmpa910_handle->port, termios->c_cflag))
++ // uart_tmpa910_handle->ier |= UART_IER_MSI;
++
++
++ serial_tmpa910_set_mctrl(&uart_tmpa910_handle->port, uart_tmpa910_handle->port.mctrl);
++
++
++ regs->lcr_h = lcrh_reg;
++ regs->cr |= CR_UARTEN;
++
++#ifdef __DEBUG__
++ _dump_regs(uart_tmpa910_handle);
++#endif
++ spin_unlock_irqrestore(&uart_tmpa910_handle->port.lock, flags);
++
++}
++
++static void
++serial_tmpa910_pm(struct uart_port *port, unsigned int state,
++ unsigned int oldstate)
++{
++}
++
++static void serial_tmpa910_release_port(struct uart_port *port)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++
++ port->membase = NULL;
++}
++
++
++
++static int serial_tmpa910_request_port(struct uart_port *port)
++{
++ return _map_tmpa910( (struct uart_tmpa910_handle *) port);
++}
++
++static void serial_tmpa910_config_port(struct uart_port *port, int flags)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++
++ uart_tmpa910_handle->port.type = PORT_TMPA910;
++}
++
++static int
++serial_tmpa910_verify_port(struct uart_port *port, struct serial_struct *ser)
++{
++ /* we don't want the core code to modify any port params */
++ return -EINVAL;
++}
++
++static const char *
++serial_tmpa910_type(struct uart_port *port)
++{
++ struct uart_tmpa910_handle *up = (struct uart_tmpa910_handle *)port;
++
++ return up->name;
++}
++
++
++
++struct uart_ops serial_tmpa910_pops = {
++ .tx_empty = serial_tmpa910_tx_empty,
++ .set_mctrl = serial_tmpa910_set_mctrl,
++ .get_mctrl = serial_tmpa910_get_mctrl,
++ .stop_tx = serial_tmpa910_stop_tx,
++ .start_tx = serial_tmpa910_start_tx,
++ .stop_rx = serial_tmpa910_stop_rx,
++ .enable_ms = serial_tmpa910_enable_ms,
++ .break_ctl = serial_tmpa910_break_ctl,
++ .startup = serial_tmpa910_startup,
++ .shutdown = serial_tmpa910_shutdown,
++ .set_termios = serial_tmpa910_set_termios,
++ .pm = serial_tmpa910_pm,
++ .type = serial_tmpa910_type,
++ .release_port = serial_tmpa910_release_port,
++ .request_port = serial_tmpa910_request_port,
++ .config_port = serial_tmpa910_config_port,
++ .verify_port = serial_tmpa910_verify_port,
++};
++
++
++
++
++static int _fill_uarthandle(
++ struct uart_tmpa910_handle *uart_tmpa910_handle,
++ int index )
++{
++ unsigned long mapbase;
++ char name[256];
++ struct device_node *dp = NULL;
++ const char *onestr;
++ const u32 *long_ptr;
++
++ unsigned int len;
++ int irq;
++
++ irq = 10+index;
++ mapbase = 0xf2000000 + 0x1000*index;
++
++ snprintf(uart_tmpa910_handle->name, sizeof(uart_tmpa910_handle->name), TMPA910_NAME_PATTERN, index);
++
++ uart_tmpa910_handle->channel = index;
++ uart_tmpa910_handle->port.type = PORT_TMPA910;
++ uart_tmpa910_handle->port.iotype = UPIO_MEM;
++ uart_tmpa910_handle->port.membase = NULL;
++ uart_tmpa910_handle->port.mapbase = mapbase;
++ uart_tmpa910_handle->port.irq = irq;
++ uart_tmpa910_handle->port.uartclk = _get_uartclk(uart_tmpa910_handle);
++ uart_tmpa910_handle->port.fifosize = 16;
++ uart_tmpa910_handle->port.ops = &serial_tmpa910_pops;
++ uart_tmpa910_handle->port.line = 0;
++
++ return 0;
++}
++
++/*
++ * Wait for transmitter & holding register to empty
++ */
++static inline void wait_for_xmitr(struct uart_tmpa910_handle *uart_tmpa910_handle)
++{
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ unsigned int tmout = 10000;
++
++ /* Wait up to 10ms for the character(s) to be sent. */
++ while( (regs->fr & FR_TXFF) )
++ {
++ if (--tmout == 0)
++ break;
++
++ udelay(1);
++ }
++
++ /* Wait up to 1s for flow control if necessary */
++ if (uart_tmpa910_handle->port.flags & UPF_CONS_FLOW) {
++ tmout = 1000000;
++ while (--tmout &&
++ ((regs->fr & FR_CTS) == 0))
++ udelay(1);
++ }
++
++}
++
++/*
++ * Wait until the TX FIFO is totally empty
++ */
++static inline void wait_for_txempty(struct uart_tmpa910_handle *uart_tmpa910_handle)
++{
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ unsigned int tmout = 10000;
++
++ /* Wait up to 10ms for the character(s) to be sent. */
++ while( (regs->fr & FR_TXFE) == 0 )
++ {
++ if (--tmout == 0)
++ break;
++
++ udelay(1);
++ }
++}
++
++
++
++
++#ifdef CONFIG_SERIAL_TMPA910_CONSOLE
++
++
++static struct uart_driver serial_tmpa910_reg;
++
++
++static void serial_tmpa910_console_putchar(struct uart_port *port, int ch)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = (struct uart_tmpa910_handle *)port;
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++
++ wait_for_xmitr(uart_tmpa910_handle);
++ regs->dr = ch & 0xff;
++}
++
++/*
++ * Print a string to the serial port trying not to disturb
++ * any possible real use of the port...
++ *
++ * The console_lock must be held when we get here.
++ */
++static void
++serial_tmpa910_console_write(struct console *co, const char *s, unsigned int count)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle = &serial_ports[co->index];
++ volatile struct tmpa910_uart_regs *regs = uart_tmpa910_handle->regs;
++ uint32_t imsc_reg;
++
++
++ /*
++ * First save the IER then disable the interrupts
++ */
++ imsc_reg = regs->imsc;
++ regs->imsc = 0;
++
++ uart_console_write(&uart_tmpa910_handle->port, s, count, serial_tmpa910_console_putchar);
++
++ /*
++ * Finally, wait for transmitter to become empty
++ * and restore the IER
++ */
++ regs->imsc = imsc_reg;
++
++}
++
++
++static int __init
++serial_tmpa910_console_setup(struct console *co, char *options)
++{
++ struct uart_tmpa910_handle *uart_tmpa910_handle;
++ struct uart_port *port;
++ int baud = 115200;
++ int bits = 8;
++ int parity = 'n';
++ int flow = 'n';
++ int ret;
++
++
++ if (co->index == -1 || co->index >= serial_tmpa910_reg.nr)
++ co->index = 0;
++
++
++ //co->index = 1;
++
++ spin_lock_init(&port->lock);
++
++ uart_tmpa910_handle = &serial_ports[co->index];
++ port = &uart_tmpa910_handle->port;
++
++
++ ret = _fill_uarthandle(uart_tmpa910_handle, co->index);
++ if (ret<0) {
++ return ret;
++ }
++
++ ret = _map_tmpa910(uart_tmpa910_handle);
++ if( ret < 0) {
++ printk(KERN_ERR "Fail to map IO mem. ret=%d\n", ret);
++ return ret;
++ }
++
++
++ if (options)
++ uart_parse_options(options, &baud, &parity, &bits, &flow);
++
++ return uart_set_options(&uart_tmpa910_handle->port, co, baud, parity, bits, flow);
++
++}
++
++static struct console serial_tmpa910_console = {
++ .name = "ttyS",
++ .write = serial_tmpa910_console_write,
++ .device = uart_console_device,
++ .setup = serial_tmpa910_console_setup,
++ .flags = CON_PRINTBUFFER,
++ .index = -1,
++ .data = &serial_tmpa910_reg,
++};
++
++static int __init
++serial_tmpa910_console_init(void)
++{
++#ifdef CONFIG_SERIAL_TMPA910_CONSOLE_PREFERED
++ add_preferred_console("ttyS", 0, NULL);
++ printk(DRIVER_NAME ": Welcome. Myself as prefered console :-)\n" );
++#else
++ printk(DRIVER_NAME ": Welcome\n" );
++#endif
++
++ register_console(&serial_tmpa910_console);
++ return 0;
++}
++
++console_initcall(serial_tmpa910_console_init);
++
++#define TMPA910_CONSOLE &serial_tmpa910_console
++#else
++#define TMPA910_CONSOLE NULL
++#endif
++
++
++static struct uart_driver serial_tmpa910_reg = {
++ .owner = THIS_MODULE,
++ .driver_name = "TMPA910 serial",
++ .dev_name = "ttyS",
++ .major = TTY_MAJOR,
++ .minor = 64,
++ .nr = TMPA910_SERIAL_MAX,
++ .cons = TMPA910_CONSOLE,
++};
++
++#if 1
++static int serial_tmpa910_suspend(struct platform_device *dev, pm_message_t state)
++{
++ struct uart_tmpa910_handle *sport = platform_get_drvdata(dev);
++
++ if (sport)
++ uart_suspend_port(&serial_tmpa910_reg, &sport->port);
++
++ return 0;
++}
++
++static int serial_tmpa910_resume(struct platform_device *dev)
++{
++ struct uart_tmpa910_handle *sport = platform_get_drvdata(dev);
++
++ if (sport)
++ uart_resume_port(&serial_tmpa910_reg, &sport->port);
++
++ return 0;
++}
++
++
++static int tmpa910_uart_portsetup(struct uart_tmpa910_handle *uart_tmpa910_handle);
++static int serial_tmpa910_probe(struct platform_device *pdev)
++{
++ static struct uart_tmpa910_handle serial_tmpa910_ports[TMPA910_SERIAL_MAX];
++
++ struct uart_tmpa910_handle *uart_tmpa910_handle;
++ struct uart_port *port;
++ int ret;
++ unsigned long mapbase;
++ int irq;
++ struct resource *addr;
++
++ uart_tmpa910_handle = &serial_ports[pdev->id];
++
++
++ if (pdev->num_resources < 2) {
++ printk(KERN_ERR "not enough ressources! %d\n", pdev->num_resources);
++ return -ENODEV;
++ }
++
++ addr = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ irq = platform_get_irq(pdev, 0);
++
++ if (addr == NULL) {
++ printk(KERN_ERR "no IO mem ressources!\n");
++ return -ENODEV;
++ }
++
++ if (irq == NO_IRQ) {
++ printk(KERN_ERR "no IRQ ressources! irq=%d\n", irq);
++ return -ENODEV;
++ }
++
++ mapbase = addr->start;
++
++ snprintf(uart_tmpa910_handle->name, sizeof(uart_tmpa910_handle->name), TMPA910_NAME_PATTERN, pdev->id);
++
++ uart_tmpa910_handle->channel = pdev->id;
++ uart_tmpa910_handle->port.type = PORT_TMPA910;
++ uart_tmpa910_handle->port.iotype = UPIO_MEM;
++ uart_tmpa910_handle->port.membase = NULL;
++ uart_tmpa910_handle->port.mapbase = mapbase;
++ uart_tmpa910_handle->port.irq = irq;
++ uart_tmpa910_handle->port.uartclk = _get_uartclk(uart_tmpa910_handle);
++ uart_tmpa910_handle->port.fifosize = 16;
++ uart_tmpa910_handle->port.ops = &serial_tmpa910_pops;
++ uart_tmpa910_handle->port.line = pdev->id;
++
++ port = &uart_tmpa910_handle->port;
++ spin_lock_init(&port->lock);
++
++ // do the needed setup (ressournces, allocation, hardware config...)
++ ret = tmpa910_uart_portsetup(uart_tmpa910_handle);
++ if (ret < 0) {
++ return ret;
++ }
++
++ ret = uart_add_one_port(&serial_tmpa910_reg, port);
++ if (ret != 0)
++ {
++ uart_unregister_driver(&serial_tmpa910_reg);
++ return ret;
++ }
++
++ serial_tmpa910_ports[pdev->id].port.dev = &pdev->dev;
++ platform_set_drvdata(pdev, port);
++
++ return 0;
++}
++
++static int serial_tmpa910_remove(struct platform_device *pdev)
++{
++ struct uart_tmpa910_handle *sport = platform_get_drvdata(pdev);
++
++ platform_set_drvdata(pdev, NULL);
++
++ if (sport)
++ uart_remove_one_port(&serial_tmpa910_reg, &sport->port);
++
++ return 0;
++}
++
++static struct platform_driver serial_tmpa910_driver = {
++ .probe = serial_tmpa910_probe,
++ .remove = serial_tmpa910_remove,
++
++ .suspend = serial_tmpa910_suspend,
++ .resume = serial_tmpa910_resume,
++ .driver = {
++ .name = "tmpa910-uart",
++ },
++};
++#endif
++
++static int tmpa910_uart_portsetup(struct uart_tmpa910_handle *uart_tmpa910_handle)
++{
++ return _map_tmpa910(uart_tmpa910_handle);
++
++}
++
++int __init serial_tmpa910_init(void)
++{
++ int ret;
++
++ ret = uart_register_driver(&serial_tmpa910_reg);
++ if (ret != 0)
++ return ret;
++
++ return platform_driver_register(&serial_tmpa910_driver);
++
++}
++
++void __exit serial_tmpa910_exit(void)
++{
++ platform_driver_unregister(&serial_tmpa910_driver);
++}
++
++module_init(serial_tmpa910_init);
++module_exit(serial_tmpa910_exit);
++
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
+index ab2ab3c..377f271 100644
+--- a/drivers/serial/uartlite.c
++++ b/drivers/serial/uartlite.c
+@@ -394,7 +394,7 @@ static void ulite_console_write(struct console *co, const char *s,
+ spin_unlock_irqrestore(&port->lock, flags);
+ }
+
+-static int __devinit ulite_console_setup(struct console *co, char *options)
++static int __init ulite_console_setup(struct console *co, char *options)
+ {
+ struct uart_port *port;
+ int baud = 9600;
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 4b6f7cb..b7c555b 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -222,6 +222,13 @@ config SPI_SH_SCI
+ help
+ SPI driver for SuperH SCI blocks.
+
++config SPI_TMPA910
++ tristate "Toshiba TMPA910 SPI controller"
++ depends on SPI_MASTER && ARCH_TMPA910
++ help
++ This enables using the Toshiba TMPA910 SPI
++ Controller in master SPI mode.
++
+ config SPI_STMP3XXX
+ tristate "Freescale STMP37xx/378x SPI/SSP controller"
+ depends on ARCH_STMP3XXX && SPI_MASTER
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index 21a1182..a3f7896 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -29,6 +29,7 @@ obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o
+ obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o
+ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
+ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
++obj-$(CONFIG_SPI_TMPA910) += spi_tmpa910.o
+ obj-$(CONFIG_SPI_TXX9) += spi_txx9.o
+ obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o
+ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
+diff --git a/drivers/spi/spi_tmpa910.c b/drivers/spi/spi_tmpa910.c
+new file mode 100644
+index 0000000..b35ac2a
+--- /dev/null
++++ b/drivers/spi/spi_tmpa910.c
+@@ -0,0 +1,774 @@
++/*
++ * drivers/spi/spi_tmpa910.c
++ *
++ * Copyright © 2009 bplan GmbH
++ *
++ * 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/module.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++
++#include <linux/workqueue.h>
++#include <linux/completion.h>
++
++#include <linux/spi/spi.h>
++
++#include <linux/io.h>
++#include <linux/delay.h>
++#include <linux/irq.h>
++
++#include <linux/time.h>
++
++struct tmpa910_spi_regs
++{
++ uint32_t cr0; // 0x0000 SSP Control register 0
++ uint32_t cr1; // 0x0004 SSP Control register 1
++ uint32_t dr; // 0x0008 SSP Receive FIFO register (read) and transmit FIFO data register (write)
++ uint32_t sr; // 0x000C SSP Status register
++ uint32_t cpsr; // 0x0010 SSP Clock prescale register
++ uint32_t imsc; // 0x0014 SSP Interrupt enable/disable register
++ uint32_t ris; // 0x0018 SSP Interrupt status prior to enable gate register
++ uint32_t mis; // 0x001C SSP Interrupt status after enable gate register
++ uint32_t icr; // 0x0020 SSP Interrupt clear register
++};
++
++struct tmpa910_spi_priv
++{
++ struct tmpa910_spi_regs *regs;
++ struct platform_device *pdev;
++ spinlock_t lock;
++ int channel;
++ int irq;
++
++ int bits_per_word;
++
++ struct workqueue_struct *workqueue;
++ struct work_struct work;
++
++ struct list_head queue;
++ struct completion done;
++ unsigned long io_start;
++ unsigned long io_lenght;
++};
++
++struct tmpa910_spi_cs {
++ int speed_hz;
++ int bits_per_word;
++ int cpsr; // CPSDVSR Clock prescale divisor (2 to 254)
++ int scr; // serial clock rate (0 to 255)
++
++
++};
++
++#define TMPA910_SPI_QUEUE
++
++int tmpa910_spi_transfer_setup(struct spi_device *spi,struct spi_transfer *t)
++{
++ struct tmpa910_spi_cs *cs = spi->controller_state;
++
++ if(t == 0)
++ {
++ // reset values
++
++ cs->speed_hz = spi->max_speed_hz;
++ cs->bits_per_word = spi->bits_per_word;
++ }
++ else
++ {
++ cs->speed_hz = (t->speed_hz ? t->speed_hz : spi->max_speed_hz);
++ cs->bits_per_word = (t->bits_per_word ? t->bits_per_word : spi->bits_per_word);
++ }
++
++ //cs->bits_per_word += 7;
++ //cs->bits_per_word >>=3;
++ //cs->bits_per_word <<=3;
++
++ return 0;
++}
++
++void tmpa910_spi_activate_cs(struct spi_device *spi)
++{
++ struct tmpa910_spi_priv *tsp = spi_master_get_devdata(spi->master);
++ struct tmpa910_spi_cs *cs = spi->controller_state;
++ struct tmpa910_spi_regs __iomem *regs = tsp->regs;
++
++ tsp->bits_per_word = cs->bits_per_word;
++
++ regs = regs; // dummy
++
++// if(tsp->activate_cs) {
++// tsp->activate_cs(spi->chip_select, (spi->mode & SPI_CS_HIGH) ? 1 : 0);
++// };
++}
++
++void tmpa910_spi_deactivate_cs(struct spi_device *spi)
++{
++ struct tmpa910_spi_priv *tsp = spi_master_get_devdata(spi->master);
++ struct tmpa910_spi_cs *cs = spi->controller_state;
++ struct tmpa910_spi_regs __iomem *regs = tsp->regs;
++
++ tsp->bits_per_word = cs->bits_per_word;
++
++ regs = regs; // dummy
++
++// if(tsp->deactivate_cs) {
++// tsp->deactivate_cs(spi->chip_select, (spi->mode & SPI_CS_HIGH) ? 1 : 0);
++// };
++}
++
++void tmpa910_spi_dump_regs(struct tmpa910_spi_priv *tsp)
++{
++ volatile struct tmpa910_spi_regs __iomem *regs = tsp->regs;
++
++ printk("tmpa910_spi_dump_regs tsp %p regs %p\n",tsp,regs);
++
++ printk(" SSP%dCR0 %08x\n",tsp->channel,regs->cr0);
++ printk(" SSP%dCR1 %08x\n",tsp->channel,regs->cr1);
++// printk(" SSP%dDR %08x\n",tsp->channel,regs->dr);
++ printk(" SSP%dSR %08x (RO)\n",tsp->channel,regs->sr);
++ printk(" SSP%dCPSR %08x\n",tsp->channel,regs->cpsr);
++ printk(" SSP%dIMSC %08x\n",tsp->channel,regs->imsc);
++ printk(" SSP%dRIS %08x (RO)\n",tsp->channel,regs->ris);
++ printk(" SSP%dMIS %08x (RO)\n",tsp->channel,regs->mis);
++// printk(" SSP%dICR %08x (WO)\n",tsp->channel,regs->icr);
++}
++
++static int tmpa910_spi_transfer_rxtx(struct spi_device *spi,struct spi_transfer *t)
++{
++ struct tmpa910_spi_priv *tsp = spi_master_get_devdata(spi->master);
++ volatile struct tmpa910_spi_regs __iomem *regs = tsp->regs;
++ unsigned char *rx_buf = (unsigned char *)t->rx_buf;
++ unsigned char *tx_buf = (unsigned char *)t->tx_buf;
++ int tx_cnt=0,rx_cnt=0;
++ volatile int dat=0;
++ int ris,mis;
++ volatile int sr;
++ int timeout;
++ struct tmpa910_spi_cs *cs=(struct tmpa910_spi_cs*)spi->controller_state;
++
++#define SSPSR_RXFIFO_FULL (1UL << 3) // 1 fifo is full, 0 fifo is not full
++#define SSPSR_RXFIFO_NOTEMPTY (1UL << 2) // 1 fifo is not empty, 0 fifo is empty
++#define SSPSR_RXFIFO_EMPTY (0UL)
++#define SSPSR_TXFIFO_NOTFULL (1UL << 1) // 1 txfifo is not full, 0 fifo is full
++#define SSPSR_TXFIFO_EMPTY (1UL << 0) // 1 txfifo is empty, 0 fifo is not empty
++
++
++ if(!t->tx_buf && !t->rx_buf && t->len)
++ return -EINVAL;
++
++ while(rx_cnt < t->len)
++ {
++
++ ris = regs->ris;
++ mis = regs->mis;
++
++ while(tx_cnt < t->len)
++ {
++ if((sr = regs->sr) & SSPSR_TXFIFO_NOTFULL) // only send if Transmit FIFO is not full
++ {
++ if(tx_buf != NULL)
++ {
++ regs->dr = *tx_buf++;
++ //udelay(1);
++ }
++ else
++ {
++ regs->dr = 0; // 0x55;
++ }
++ tx_cnt++;
++ //tx_cnt++;
++ }
++ else
++ {
++ break;
++ }
++ }
++
++ timeout=100000;
++ while((((sr = regs->sr) & SSPSR_RXFIFO_NOTEMPTY) == SSPSR_RXFIFO_EMPTY) && timeout--) { // wait for data to arrive (non empty Receive FIFO)
++ ris = regs->ris; mis = regs->mis;
++
++ if((tx_cnt < t->len) && ((sr = regs->sr) & SSPSR_TXFIFO_NOTFULL))
++ continue; // send more data ....
++ };
++
++ if(timeout <= 0)
++ {
++ printk(KERN_ERR "timeout! rx_cnt=%d. tx_cnt=%d, regs->sr=0x%x\n", rx_cnt,tx_cnt, regs->sr);
++ break;
++ }
++ else
++ {
++ if((((sr = regs->sr) & SSPSR_RXFIFO_NOTEMPTY)) && (rx_cnt < t->len))
++ {
++ if(rx_buf != NULL)
++ {
++ *rx_buf++ = regs->dr;
++ }
++ else
++ {
++ dat = regs->dr;
++ }
++ rx_cnt++;
++ //rx_cnt++;
++ }
++ }
++ }
++
++ return 0;
++}
++
++#define FRAME_FMT_MOTOSPI (0UL)
++#define FRAME_FMT_TI (1UL)
++#define FRAME_FMT_MICROWIRE (2UL)
++
++#define DEFAULT_FRAME_FMT FRAME_FMT_MOTOSPI // we only support Microwire frame format
++
++//#define PORTL_BASE 0xF080A000
++//#define PORTL_GPIODATA (PORTL_BASE + 0x4) // 0x03fc)
++
++static void tmpa910_spi_work(struct work_struct *work)
++{
++ struct tmpa910_spi_priv *tsp =container_of(work, struct tmpa910_spi_priv, work);
++ volatile struct tmpa910_spi_regs __iomem *regs = tsp->regs;
++ volatile int dat=0;
++ int cnt=0;
++ int first=1;
++
++ //tmpa910_spi_dump_regs(tsp);
++
++ spin_lock_irq(&tsp->lock);
++
++ while(!list_empty(&tsp->queue)) {
++ struct spi_message *m;
++ struct spi_device *spi;
++ struct spi_transfer *t = NULL;
++ int status=0;
++ struct tmpa910_spi_cs *cs;
++
++ m = container_of(tsp->queue.next, struct spi_message, queue);
++
++ list_del_init(&m->queue);
++
++ spin_unlock_irq(&tsp->lock);
++
++ spi = m->spi;
++
++ cs=(struct tmpa910_spi_cs*)spi->controller_state;
++
++ if(first)
++ {
++ regs->icr = 3; // kill pending ints
++
++ regs->cpsr= cs->cpsr;
++
++ regs->cr0 = (cs->scr << 8) // set SCR to 0
++ | (((spi->mode & SPI_CPHA) ? 1UL : 0UL) << 7) // SPCLK phase
++ | (((spi->mode & SPI_CPOL) ? 1UL : 0UL) << 6) // SPCLK polarity
++ | (DEFAULT_FRAME_FMT << 4) // we only support Microwire frame format
++ | ((cs->bits_per_word - 1)<< 0); // data-width (7==8bit,15==16bit)
++
++ regs->cr1 = (0UL << 3) // Slave mode SP0D0 output disable
++ | (0UL << 2) // Master (0)/slave (1) mode select
++ | (0UL << 1) // Synchronous serial port enable
++ | (((spi->mode & SPI_LOOP) ? 1UL : 0UL) << 0); // Loop back mode enable
++
++ #if 0
++ regs->imsc = (1UL << 3) // Transmit FIFO interrupt enable
++ | (1UL << 2) // Receive FIFO interrupt enable
++ | (1UL << 1) // Receive FIFO timeout interrupt enable
++ | (1UL << 0);// Receive overrun interrupt enable
++ #endif
++
++ #if 1
++ while((regs->sr & 4) != 0) {
++ dat=regs->dr;
++ cnt++;
++ }
++
++ if(cnt)
++ {
++ printk(" read %d bytes from receive FIFO\n",cnt);
++ }
++
++ if((regs->sr & 1) == 0)
++ {
++ printk(" transmit fifo is not empty !!\n");
++ }
++ #endif
++
++ //printk("current sr 0x%x\n",regs->sr);
++
++ first=0;
++
++ //GPIO[0] = 0;
++
++ }
++
++ regs->cr0 = (cs->scr << 8) // set SCR to 0
++ | (((spi->mode & SPI_CPHA) ? 1UL : 0UL) << 7) // SPCLK phase
++ | (((spi->mode & SPI_CPOL) ? 1UL : 0UL) << 6) // SPCLK polarity
++ | (DEFAULT_FRAME_FMT << 4) // we only support Microwire frame format
++ | ((cs->bits_per_word - 1)<< 0); // data-width (7==8bit,15==16bit)
++
++ regs->cr1 = (0UL << 3) // Slave mode SP0D0 output disable
++ | (0UL << 2) // Master (0)/slave (1) mode select
++ | (1UL << 1) // Synchronous serial port enable
++ | (((spi->mode & SPI_LOOP) ? 1UL : 0UL) << 0); // Loop back mode enable
++
++ list_for_each_entry(t, &m->transfers, transfer_list) {
++
++ /* check if setup is modifed */
++ if(t->bits_per_word || t->speed_hz) {
++ status = tmpa910_spi_transfer_setup(spi, t);
++
++ if(status < 0)
++ break;
++ printk("update bits_per_word or speed_hz\n");
++ }
++
++ // activate chip select
++
++ // get cs_change flag from t->cs_change
++
++ // do the actual transfer
++ status = tmpa910_spi_transfer_rxtx(spi, t);
++
++ if(status)
++ break;
++
++ m->actual_length += t->len;
++
++
++ if(t->delay_usecs)
++ {
++ printk("delay_usec %d\n",t->delay_usecs);
++ udelay(t->delay_usecs);
++ }
++
++ // deactive chip select again if transfer has cs_change flag set
++ }
++
++ m->status = status;
++ m->complete(m->context);
++
++ tmpa910_spi_transfer_setup(spi, NULL); // reset to default setup
++
++ spin_lock_irq(&tsp->lock);
++ }
++
++ if(!first)
++ {
++ regs->cr1 = (0UL << 3) // Slave mode SP0D0 output disable
++ | (0UL << 2) // Master (0)/slave (1) mode select
++ | (0UL << 1) // Synchronous serial port disable
++ | (0UL << 0); // Loop back mode enable
++ }
++
++ spin_unlock_irq(&tsp->lock);
++}
++
++#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_LOOP)
++
++#define PCLK_MHZ (96UL)
++
++/*
++ * Bit rate = f_pclk/(CPSDVSR x (1+SCR)
++ *
++ * CPSDVSR is an even value from 2 to 254
++ * SCR os a value from 0 to 255
++ *
++ */
++
++static int tmpa910_spi_setup(struct spi_device *spi)
++{
++ struct tmpa910_spi_priv *tsp = spi_master_get_devdata(spi->master);
++ struct tmpa910_spi_cs *cs = spi->controller_state;
++ unsigned long flags;
++ unsigned long ref_pclk_hz;
++ int cpsr = 96; // default to 1MHz
++ int scr = 0; //
++
++ printk(KERN_INFO "tmpa910_spi_setup spi_device %p\n",spi);
++
++ // if bits_per_word is 0, default to 8bits per word
++ if((spi->bits_per_word != 0) && ((spi->bits_per_word < 4) || (spi->bits_per_word > 16))) {
++ dev_dbg(&spi->dev, "setup: unsupported number of bits per word (%x)\n",spi->bits_per_word);
++ return -EINVAL;
++ }
++
++ if(spi->mode & (~MODEBITS)) {
++ dev_dbg(&spi->dev, "setup: unsupported mode bits (%x)\n",spi->mode & (~MODEBITS));
++ return -EINVAL;
++ }
++
++ if(cs == NULL) {
++ cs = kzalloc(sizeof(struct tmpa910_spi_cs), GFP_KERNEL);
++ if(cs == NULL) {
++ return -ENOMEM;
++ }
++ spi->controller_state = cs;
++ }
++
++ cs->bits_per_word = spi->bits_per_word;
++ cs->speed_hz = spi->max_speed_hz;
++
++ if(cs->speed_hz != 0)
++ {
++ ref_pclk_hz = PCLK_MHZ * 1000000;
++
++ if((cs->speed_hz * 2) > ref_pclk_hz) { // we can't go higher than half PCLK
++ kfree(cs);
++ return -EINVAL;
++ }
++
++ cpsr = ref_pclk_hz / cs->speed_hz;
++ cpsr += 1;
++ cpsr &= ~1; // multiple of 2
++
++ scr = 0;
++
++ if((ref_pclk_hz / cpsr) > cs->speed_hz)
++ {
++ cpsr+=2;
++ }
++
++ while(cpsr > 254)
++ {
++ cpsr >>= 1;
++ scr <<= 1;
++ }
++
++ cs->cpsr = cpsr;
++ cs->scr = scr;
++
++
++ }
++ else
++ {
++ // default to 1MHZ
++ cs->cpsr = 96;
++ cs->scr = 0;
++ }
++
++
++ spin_lock_irqsave(&tsp->lock, flags);
++ tmpa910_spi_deactivate_cs(spi);
++ spin_unlock_irqrestore(&tsp->lock, flags);
++
++ return 0;
++}
++
++static int tmpa910_spi_transfer(struct spi_device *spi,struct spi_message *m)
++{
++ struct tmpa910_spi_priv *tsp= spi_master_get_devdata(spi->master);
++ unsigned long flags;
++
++ m->actual_length = 0;
++ m->status = -EINPROGRESS;
++
++#ifdef TMPA910_SPI_QUEUE
++ spin_lock_irqsave(&tsp->lock, flags);
++ list_add_tail(&m->queue, &tsp->queue);
++ queue_work(tsp->workqueue, &tsp->work);
++ spin_unlock_irqrestore(&tsp->lock, flags);
++#endif
++ return 0;
++}
++
++static void tmpa910_spi_cleanup(struct spi_device *spi)
++{
++ kfree(spi->controller_state);
++}
++
++int tmpa910_spi_port_config(int id, struct tmpa910_spi_priv *tsp)
++{
++
++ tsp->bits_per_word = 8;
++
++ return 0;
++}
++
++
++static irqreturn_t tmpa910_spi_isr(int irq, void *dev_id)
++{
++ struct tmpa910_spi_priv *tsp = (struct tmpa910_spi_priv *)dev_id;
++ struct tmpa910_spi_regs __iomem *regs=tsp->regs;
++ int sr[8];
++ int ris[8];
++ int mis[8];
++ int i;
++ unsigned char data[8];
++
++ i=0;
++
++ while(i < 7)
++ {
++ ris[i] = regs->ris;
++ mis[i] = regs->mis;
++
++ while(((sr[i] = regs->sr) & 4) == 0); // wait for data to arrive
++
++ data[i] = regs->dr;
++
++ i++;
++ };
++
++
++ ris[0] = 0;
++
++ if((ris[0] & 8) || (mis[0] & 8))
++ {
++ printk("disabling Transmit FIFO interrupt\n");
++
++ regs->imsc = regs->imsc & ~8; // disable Transmit FIFO interrupt
++
++ return IRQ_HANDLED;
++ }
++
++ if((ris[0] & 4) || (mis[0] & 4))
++ {
++ printk("disabling Receive FIFO interrupt\n");
++
++ regs->imsc = regs->imsc & ~4; // disable related interrupt
++
++ return IRQ_HANDLED;
++ }
++
++ if((ris[0] & 2) || (mis[0] & 2))
++ {
++ printk("disabling Receive overrun interrupt\n");
++
++ regs->imsc = regs->imsc & ~2; // disable related interrupt
++
++ return IRQ_HANDLED;
++ }
++
++ if((ris[0] & 1) || (mis[0] & 1))
++ {
++ printk("disabling Receive overrun interrupt\n");
++
++ regs->imsc = regs->imsc & ~1; // disable related interrupt
++
++ return IRQ_HANDLED;
++ }
++
++ return IRQ_NONE;
++}
++
++static int __init tmpa910_spi_probe(struct platform_device *pdev)
++{
++
++ struct device *dev=&pdev->dev;
++ struct tmpa910_spi_priv *tsp;
++ struct spi_master *master;
++ struct resource *r;
++ int irq;
++ int ret;
++
++ dev_dbg(&pdev->dev,"tmpa910_spi_probe (pdev %p)",pdev);
++
++ switch(pdev->id) {
++ case 0:
++ case 1:
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ master = spi_alloc_master(dev, sizeof(struct tmpa910_spi_priv));
++
++ if(master == NULL) {
++ dev_err(&pdev->dev," No memory for spi_master !\n");
++ return -ENOMEM;
++ }
++
++ master = spi_master_get(master);
++
++ dev_set_drvdata(dev, master);
++
++ tsp = spi_master_get_devdata(master);
++ tsp->channel = pdev->id;
++
++ master->bus_num = pdev->id;
++ master->num_chipselect = 1; // there is only a single chip select
++ master->setup = tmpa910_spi_setup;
++ master->transfer = tmpa910_spi_transfer;
++ master->cleanup = tmpa910_spi_cleanup;
++
++ printk("spi probe master bus_num %d\n",master->bus_num);
++
++ tsp->pdev = pdev;
++ tsp->irq = NO_IRQ;
++
++
++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if(r == NULL) {
++ dev_err(&pdev->dev, "No IO memory resource for SPI\n");
++ ret = -ENODEV;
++ goto fail;
++ }
++
++ printk("spi probe resource start %x end %x\n",r->start,r->end);
++
++ r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
++ if(r == NULL) {
++ dev_err(&pdev->dev, "failed to request memory resource\n");
++ ret = -EBUSY;
++ goto fail;
++ }
++
++ tsp->io_start = r->start;
++ tsp->io_lenght = r->end - r->start + 1;
++
++ printk("spi probe mem region requested start %x end %x\n",r->start,r->end);
++
++
++ tsp->regs = ioremap(r->start, r->end - r->start +1);
++
++ printk("spi probe spi_regs %p\n",tsp->regs);
++
++ if(tsp->regs == NULL) {
++ dev_err(&pdev->dev, "ioremap() failed\n");
++ ret = -ENODEV;
++ goto fail;
++ }
++
++ irq = platform_get_irq(pdev,0);
++ if(irq < 0) {
++ dev_err(&pdev->dev, "no IRQ resource defined\n");
++ ret = -ENXIO;
++ goto fail;
++ }
++
++ printk("spi probe irq %d\n",irq);
++
++ tsp->irq = irq;
++
++ ret = request_irq(tsp->irq, tmpa910_spi_isr, 0, "tmpa910-spi", tsp);
++
++ if(ret) {
++ printk("failed to request irq!\n");
++ tsp->irq = -1;
++ goto fail;
++ }
++
++ spin_lock_init(&tsp->lock);
++ init_completion(&tsp->done);
++ INIT_WORK(&tsp->work, tmpa910_spi_work);
++ INIT_LIST_HEAD(&tsp->queue);
++
++ tsp->workqueue = create_singlethread_workqueue(dev_name(master->dev.parent));
++
++ if(tsp->workqueue == NULL) {
++ ret = -EBUSY;
++ printk("spi workqueue creation failed\n");
++ goto fail;
++ }
++
++ ret = spi_register_master(master);
++
++ if(ret) {
++ printk("spi_register_master returned %d\n",ret);
++ }
++ printk("tmpa910_spi_probe master 0x%p tsp 0x%p\n",master,tsp);
++
++ return 0;
++fail:
++ dev_err(&pdev->dev, "failed to probe SPI%d\n", pdev->id);
++ return ret;
++}
++
++static int tmpa910_spi_remove(struct platform_device *pdev)
++{
++ struct driver_data *drv_data = platform_get_drvdata(pdev);
++ struct spi_master *master = (struct spi_master *) drv_data;
++
++
++ drv_data = drv_data; // DUMMY
++
++
++ if (master)
++ {
++ struct tmpa910_spi_priv *tsp = spi_master_get_devdata( (void *) drv_data);
++
++ spi_unregister_master(master);
++
++ if (tsp)
++ {
++
++ if (tsp->regs)
++ {
++ volatile struct tmpa910_spi_regs __iomem *regs = tsp->regs;
++ // make sure to disable controller and interrupt
++ regs->cr1 = 0;
++ regs->imsc = 0;
++ iounmap(tsp->regs);
++ }
++
++ if (tsp->io_start)
++ {
++ release_mem_region(tsp->io_start, tsp->io_lenght);
++ }
++
++ if (tsp->irq>=0)
++ free_irq(tsp->irq, tsp);
++ }
++
++
++ spi_master_put(master);
++ }
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++
++static int tmpa910_spi_suspend(struct platform_device *pdev, pm_message_t msg)
++{
++ return 0;
++}
++
++static int tmpa910_spi_resume(struct platform_device *pdev)
++{
++ return 0;
++}
++
++#else
++
++#define tmpa910_spi_suspend NULL
++#define tmpa910_spi_resume NULL
++#endif
++
++static struct platform_driver tmpa910_spi_driver = {
++ .probe = tmpa910_spi_probe,
++ .remove = tmpa910_spi_remove,
++ .suspend = tmpa910_spi_suspend,
++ .resume = tmpa910_spi_resume,
++ .driver = {
++ .name = "tmpa910-spi",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init tmpa910_spi_init(void)
++{
++ return platform_driver_register(&tmpa910_spi_driver);
++}
++
++module_init(tmpa910_spi_init);
++
++static void __exit tmpa910_spi_exit(void)
++{
++ platform_driver_unregister(&tmpa910_spi_driver);
++}
++
++module_exit(tmpa910_spi_exit);
++
++MODULE_DESCRIPTION("Toshiba TMPA910 SPI Driver");
++MODULE_AUTHOR("bplan GmbH");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
+index eb70843..8943015 100644
+--- a/drivers/ssb/sprom.c
++++ b/drivers/ssb/sprom.c
+@@ -13,8 +13,6 @@
+
+ #include "ssb_private.h"
+
+-#include <linux/ctype.h>
+-
+
+ static const struct ssb_sprom *fallback_sprom;
+
+@@ -35,27 +33,17 @@ static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
+ static int hex2sprom(u16 *sprom, const char *dump, size_t len,
+ size_t sprom_size_words)
+ {
+- char c, tmp[5] = { 0 };
+- int err, cnt = 0;
++ char tmp[5] = { 0 };
++ int cnt = 0;
+ unsigned long parsed;
+
+- /* Strip whitespace at the end. */
+- while (len) {
+- c = dump[len - 1];
+- if (!isspace(c) && c != '\0')
+- break;
+- len--;
+- }
+- /* Length must match exactly. */
+- if (len != sprom_size_words * 4)
++ if (len < sprom_size_words * 2)
+ return -EINVAL;
+
+ while (cnt < sprom_size_words) {
+ memcpy(tmp, dump, 4);
+ dump += 4;
+- err = strict_strtoul(tmp, 16, &parsed);
+- if (err)
+- return err;
++ parsed = simple_strtoul(tmp, NULL, 16);
+ sprom[cnt++] = swab16((u16)parsed);
+ }
+
+diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
+index 43c57b7..f4c2657 100644
+--- a/drivers/staging/asus_oled/asus_oled.c
++++ b/drivers/staging/asus_oled/asus_oled.c
+@@ -194,11 +194,9 @@ static ssize_t set_enabled(struct device *dev, struct device_attribute *attr,
+ {
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct asus_oled_dev *odev = usb_get_intfdata(intf);
+- unsigned long value;
+- if (strict_strtoul(buf, 10, &value))
+- return -EINVAL;
++ int temp = strict_strtoul(buf, 10, NULL);
+
+- enable_oled(odev, value);
++ enable_oled(odev, temp);
+
+ return count;
+ }
+@@ -209,12 +207,10 @@ static ssize_t class_set_enabled(struct device *device,
+ {
+ struct asus_oled_dev *odev =
+ (struct asus_oled_dev *) dev_get_drvdata(device);
+- unsigned long value;
+
+- if (strict_strtoul(buf, 10, &value))
+- return -EINVAL;
++ int temp = strict_strtoul(buf, 10, NULL);
+
+- enable_oled(odev, value);
++ enable_oled(odev, temp);
+
+ return count;
+ }
+diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c
+index c2809f2..c5b6613 100644
+--- a/drivers/staging/hv/Hv.c
++++ b/drivers/staging/hv/Hv.c
+@@ -386,7 +386,7 @@ u16 HvSignalEvent(void)
+ * retrieve the initialized message and event pages. Otherwise, we create and
+ * initialize the message and event pages.
+ */
+-void HvSynicInit(void *irqarg)
++int HvSynicInit(u32 irqVector)
+ {
+ u64 version;
+ union hv_synic_simp simp;
+@@ -394,14 +394,13 @@ void HvSynicInit(void *irqarg)
+ union hv_synic_sint sharedSint;
+ union hv_synic_scontrol sctrl;
+ u64 guestID;
+- u32 irqVector = *((u32 *)(irqarg));
+- int cpu = smp_processor_id();
++ int ret = 0;
+
+ DPRINT_ENTER(VMBUS);
+
+ if (!gHvContext.HypercallPage) {
+ DPRINT_EXIT(VMBUS);
+- return;
++ return ret;
+ }
+
+ /* Check the version */
+@@ -426,27 +425,27 @@ void HvSynicInit(void *irqarg)
+ */
+ rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID);
+ if (guestID == HV_LINUX_GUEST_ID) {
+- gHvContext.synICMessagePage[cpu] =
++ gHvContext.synICMessagePage[0] =
+ phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT);
+- gHvContext.synICEventPage[cpu] =
++ gHvContext.synICEventPage[0] =
+ phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT);
+ } else {
+ DPRINT_ERR(VMBUS, "unknown guest id!!");
+ goto Cleanup;
+ }
+ DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p",
+- gHvContext.synICMessagePage[cpu],
+- gHvContext.synICEventPage[cpu]);
++ gHvContext.synICMessagePage[0],
++ gHvContext.synICEventPage[0]);
+ } else {
+- gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
+- if (gHvContext.synICMessagePage[cpu] == NULL) {
++ gHvContext.synICMessagePage[0] = osd_PageAlloc(1);
++ if (gHvContext.synICMessagePage[0] == NULL) {
+ DPRINT_ERR(VMBUS,
+ "unable to allocate SYNIC message page!!");
+ goto Cleanup;
+ }
+
+- gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
+- if (gHvContext.synICEventPage[cpu] == NULL) {
++ gHvContext.synICEventPage[0] = osd_PageAlloc(1);
++ if (gHvContext.synICEventPage[0] == NULL) {
+ DPRINT_ERR(VMBUS,
+ "unable to allocate SYNIC event page!!");
+ goto Cleanup;
+@@ -455,7 +454,7 @@ void HvSynicInit(void *irqarg)
+ /* Setup the Synic's message page */
+ rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+ simp.SimpEnabled = 1;
+- simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
++ simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[0])
+ >> PAGE_SHIFT;
+
+ DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx",
+@@ -466,7 +465,7 @@ void HvSynicInit(void *irqarg)
+ /* Setup the Synic's event page */
+ rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+ siefp.SiefpEnabled = 1;
+- siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
++ siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[0])
+ >> PAGE_SHIFT;
+
+ DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx",
+@@ -502,30 +501,32 @@ void HvSynicInit(void *irqarg)
+
+ DPRINT_EXIT(VMBUS);
+
+- return;
++ return ret;
+
+ Cleanup:
++ ret = -1;
++
+ if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
+- if (gHvContext.synICEventPage[cpu])
+- osd_PageFree(gHvContext.synICEventPage[cpu], 1);
++ if (gHvContext.synICEventPage[0])
++ osd_PageFree(gHvContext.synICEventPage[0], 1);
+
+- if (gHvContext.synICMessagePage[cpu])
+- osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
++ if (gHvContext.synICMessagePage[0])
++ osd_PageFree(gHvContext.synICMessagePage[0], 1);
+ }
+
+ DPRINT_EXIT(VMBUS);
+- return;
++
++ return ret;
+ }
+
+ /**
+ * HvSynicCleanup - Cleanup routine for HvSynicInit().
+ */
+-void HvSynicCleanup(void *arg)
++void HvSynicCleanup(void)
+ {
+ union hv_synic_sint sharedSint;
+ union hv_synic_simp simp;
+ union hv_synic_siefp siefp;
+- int cpu = smp_processor_id();
+
+ DPRINT_ENTER(VMBUS);
+
+@@ -538,7 +539,6 @@ void HvSynicCleanup(void *arg)
+
+ sharedSint.Masked = 1;
+
+- /* Need to correctly cleanup in the case of SMP!!! */
+ /* Disable the interrupt */
+ wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
+
+@@ -560,8 +560,8 @@ void HvSynicCleanup(void *arg)
+
+ wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+
+- osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
+- osd_PageFree(gHvContext.synICEventPage[cpu], 1);
++ osd_PageFree(gHvContext.synICMessagePage[0], 1);
++ osd_PageFree(gHvContext.synICEventPage[0], 1);
+ }
+
+ DPRINT_EXIT(VMBUS);
+diff --git a/drivers/staging/hv/Hv.h b/drivers/staging/hv/Hv.h
+index fce4b5c..5379e4b 100644
+--- a/drivers/staging/hv/Hv.h
++++ b/drivers/staging/hv/Hv.h
+@@ -93,7 +93,7 @@ static const struct hv_guid VMBUS_SERVICE_ID = {
+ },
+ };
+
+-#define MAX_NUM_CPUS 32
++#define MAX_NUM_CPUS 1
+
+
+ struct hv_input_signal_event_buffer {
+@@ -137,8 +137,8 @@ extern u16 HvPostMessage(union hv_connection_id connectionId,
+
+ extern u16 HvSignalEvent(void);
+
+-extern void HvSynicInit(void *irqarg);
++extern int HvSynicInit(u32 irqVector);
+
+-extern void HvSynicCleanup(void *arg);
++extern void HvSynicCleanup(void);
+
+ #endif /* __HV_H__ */
+diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c
+index 35a023e..a4dd06f 100644
+--- a/drivers/staging/hv/Vmbus.c
++++ b/drivers/staging/hv/Vmbus.c
+@@ -129,7 +129,7 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo)
+
+ /* strcpy(dev->name, "vmbus"); */
+ /* SynIC setup... */
+- on_each_cpu(HvSynicInit, (void *)irqvector, 1);
++ ret = HvSynicInit(*irqvector);
+
+ /* Connect to VMBus in the root partition */
+ ret = VmbusConnect();
+@@ -150,7 +150,7 @@ static int VmbusOnDeviceRemove(struct hv_device *dev)
+ DPRINT_ENTER(VMBUS);
+ VmbusChannelReleaseUnattachedChannels();
+ VmbusDisconnect();
+- on_each_cpu(HvSynicCleanup, NULL, 1);
++ HvSynicCleanup();
+ DPRINT_EXIT(VMBUS);
+
+ return ret;
+@@ -173,8 +173,7 @@ static void VmbusOnCleanup(struct hv_driver *drv)
+ */
+ static void VmbusOnMsgDPC(struct hv_driver *drv)
+ {
+- int cpu = smp_processor_id();
+- void *page_addr = gHvContext.synICMessagePage[cpu];
++ void *page_addr = gHvContext.synICMessagePage[0];
+ struct hv_message *msg = (struct hv_message *)page_addr +
+ VMBUS_MESSAGE_SINT;
+ struct hv_message *copied;
+@@ -231,12 +230,11 @@ static void VmbusOnEventDPC(struct hv_driver *drv)
+ static int VmbusOnISR(struct hv_driver *drv)
+ {
+ int ret = 0;
+- int cpu = smp_processor_id();
+ void *page_addr;
+ struct hv_message *msg;
+ union hv_synic_event_flags *event;
+
+- page_addr = gHvContext.synICMessagePage[cpu];
++ page_addr = gHvContext.synICMessagePage[0];
+ msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
+
+ DPRINT_ENTER(VMBUS);
+@@ -250,7 +248,7 @@ static int VmbusOnISR(struct hv_driver *drv)
+ }
+
+ /* TODO: Check if there are events to be process */
+- page_addr = gHvContext.synICEventPage[cpu];
++ page_addr = gHvContext.synICEventPage[0];
+ event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
+
+ /* Since we are a child, we only need to check bit 0 */
+diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+index 0d490c1..3222c22 100644
+--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
++++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+@@ -1318,13 +1318,13 @@ extern int ieee80211_encrypt_fragment(
+ struct sk_buff *frag,
+ int hdr_len);
+
+-extern int ieee80211_rtl_xmit(struct sk_buff *skb,
++extern int ieee80211_xmit(struct sk_buff *skb,
+ struct net_device *dev);
+ extern void ieee80211_txb_free(struct ieee80211_txb *);
+
+
+ /* ieee80211_rx.c */
+-extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
++extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+ struct ieee80211_rx_stats *rx_stats);
+ extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+ struct ieee80211_hdr_4addr *header,
+@@ -1376,8 +1376,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
+ extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
+ extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
+ extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
+-extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
+-extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
++extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
++extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
+ extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
+ extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
+ extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+@@ -1385,7 +1385,7 @@ extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct
+ extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
+ extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
+ extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn);
+-extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee);
++extern void ieee80211_start_scan(struct ieee80211_device *ieee);
+
+ //Add for RF power on power off by lizhaoming 080512
+ extern void SendDisassociation(struct ieee80211_device *ieee,
+diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+index 7ad305b..5e2e79b 100644
+--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
++++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+@@ -470,7 +470,7 @@ drop:
+ /* All received frames are sent to this function. @skb contains the frame in
+ * IEEE 802.11 format, i.e., in the format it was sent over air.
+ * This function is called only as a tasklet (software IRQ). */
+-int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
++int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+ struct ieee80211_rx_stats *rx_stats)
+ {
+ struct net_device *dev = ieee->dev;
+diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+index a2fa9a9..334e4c7 100644
+--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
++++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+@@ -689,7 +689,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee)
+ }
+
+ /* called with ieee->lock held */
+-void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
++void ieee80211_start_scan(struct ieee80211_device *ieee)
+ {
+ if(IS_DOT11D_ENABLE(ieee) )
+ {
+@@ -1196,7 +1196,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee)
+ }
+ }
+
+-void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
++void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
+ {
+ u8 *c;
+ struct sk_buff *skb;
+@@ -1898,7 +1898,7 @@ associate_complete:
+
+ ieee80211_associate_step2(ieee);
+ }else{
+- ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
++ ieee80211_auth_challenge(ieee, challenge, chlen);
+ }
+ }else{
+ ieee->softmac_stats.rx_auth_rs_err++;
+@@ -2047,7 +2047,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee)
+
+ }
+
+-void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
++void ieee80211_wake_queue(struct ieee80211_device *ieee)
+ {
+
+ unsigned long flags;
+@@ -2089,7 +2089,7 @@ exit :
+ }
+
+
+-void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
++void ieee80211_stop_queue(struct ieee80211_device *ieee)
+ {
+ //unsigned long flags;
+ //spin_lock_irqsave(&ieee->lock,flags);
+@@ -2301,7 +2301,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee)
+ //#else
+ if (ieee->state == IEEE80211_NOLINK){
+ ieee->actscanning = true;
+- ieee80211_rtl_start_scan(ieee);
++ ieee80211_start_scan(ieee);
+ }
+ //#endif
+ spin_unlock_irqrestore(&ieee->lock, flags);
+@@ -2357,7 +2357,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work)
+ if(ieee->state == IEEE80211_NOLINK){
+ ieee->beinretry = false;
+ ieee->actscanning = true;
+- ieee80211_rtl_start_scan(ieee);
++ ieee80211_start_scan(ieee);
+ }
+ //YJ,add,080828, notify os here
+ if(ieee->state == IEEE80211_NOLINK)
+diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+index c7996ea..e2945db 100644
+--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
++++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+@@ -305,7 +305,7 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
+ }
+
+ /* SKBs are added to the ieee->tx_queue. */
+-int ieee80211_rtl_xmit(struct sk_buff *skb,
++int ieee80211_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+ {
+ struct ieee80211_device *ieee = netdev_priv(dev);
+diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
+index 3f19143..53e654d 100644
+--- a/drivers/staging/rtl8187se/r8180_core.c
++++ b/drivers/staging/rtl8187se/r8180_core.c
+@@ -1830,7 +1830,7 @@ void rtl8180_rx(struct net_device *dev)
+ if(priv->rx_skb->len > 4)
+ skb_trim(priv->rx_skb,priv->rx_skb->len-4);
+ #ifndef RX_DONT_PASS_UL
+- if(!ieee80211_rtl_rx(priv->ieee80211,
++ if(!ieee80211_rx(priv->ieee80211,
+ priv->rx_skb, &stats)){
+ #endif // RX_DONT_PASS_UL
+
+@@ -1936,11 +1936,11 @@ rate)
+ if (!check_nic_enought_desc(dev, priority)){
+ DMESGW("Error: no descriptor left by previous TX (avail %d) ",
+ get_curr_tx_free_desc(dev, priority));
+- ieee80211_rtl_stop_queue(priv->ieee80211);
++ ieee80211_stop_queue(priv->ieee80211);
+ }
+ rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate);
+ if (!check_nic_enought_desc(dev, priority))
+- ieee80211_rtl_stop_queue(priv->ieee80211);
++ ieee80211_stop_queue(priv->ieee80211);
+
+ spin_unlock_irqrestore(&priv->tx_lock,flags);
+ }
+@@ -3846,7 +3846,7 @@ static const struct net_device_ops rtl8180_netdev_ops = {
+ .ndo_set_mac_address = r8180_set_mac_adr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+- .ndo_start_xmit = ieee80211_rtl_xmit,
++ .ndo_start_xmit = ieee80211_xmit,
+ };
+
+ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
+@@ -4066,7 +4066,7 @@ void rtl8180_try_wake_queue(struct net_device *dev, int pri)
+ spin_unlock_irqrestore(&priv->tx_lock,flags);
+
+ if(enough_desc)
+- ieee80211_rtl_wake_queue(priv->ieee80211);
++ ieee80211_wake_queue(priv->ieee80211);
+ }
+
+ void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
+diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
+index 637ee8e..766892e 100644
+--- a/drivers/staging/rtl8187se/r8180_wx.c
++++ b/drivers/staging/rtl8187se/r8180_wx.c
+@@ -377,7 +377,7 @@ static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
+ // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq);
+ //printk("start scan============================>\n");
+ ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
+-//ieee80211_rtl_start_scan(priv->ieee80211);
++//ieee80211_start_scan(priv->ieee80211);
+ /* intentionally forget to up sem */
+ // up(&priv->ieee80211->wx_sem);
+ ret = 0;
+diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
+index 2407508..c677cac 100644
+--- a/drivers/usb/Kconfig
++++ b/drivers/usb/Kconfig
+@@ -30,6 +30,7 @@ config USB_ARCH_HAS_OHCI
+ # ARM:
+ default y if SA1111
+ default y if ARCH_OMAP
++ default y if ARCH_TMPA910
+ default y if ARCH_LH7A404
+ default y if ARCH_S3C2410
+ default y if PXA27x
+diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
+index be3c9b8..51465f8 100644
+--- a/drivers/usb/Makefile
++++ b/drivers/usb/Makefile
+@@ -20,6 +20,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += host/
+ obj-$(CONFIG_USB_U132_HCD) += host/
+ obj-$(CONFIG_USB_R8A66597_HCD) += host/
+ obj-$(CONFIG_USB_HWA_HCD) += host/
++obj-$(CONFIG_USB_ISP1362_HCD) += host/
+ obj-$(CONFIG_USB_ISP1760_HCD) += host/
+
+ obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
+diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
+index d9461c9..2473cf0 100644
+--- a/drivers/usb/class/usbtmc.c
++++ b/drivers/usb/class/usbtmc.c
+@@ -562,16 +562,10 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf,
+ n_bytes = roundup(12 + this_part, 4);
+ memset(buffer + 12 + this_part, 0, n_bytes - (12 + this_part));
+
+- do {
+- retval = usb_bulk_msg(data->usb_dev,
+- usb_sndbulkpipe(data->usb_dev,
+- data->bulk_out),
+- buffer, n_bytes,
+- &actual, USBTMC_TIMEOUT);
+- if (retval != 0)
+- break;
+- n_bytes -= actual;
+- } while (n_bytes);
++ retval = usb_bulk_msg(data->usb_dev,
++ usb_sndbulkpipe(data->usb_dev,
++ data->bulk_out),
++ buffer, n_bytes, &actual, USBTMC_TIMEOUT);
+
+ data->bTag_last_write = data->bTag;
+ data->bTag++;
+diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
+index 355dffc..96f1171 100644
+--- a/drivers/usb/core/devices.c
++++ b/drivers/usb/core/devices.c
+@@ -494,7 +494,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
+ return 0;
+ /* allocate 2^1 pages = 8K (on i386);
+ * should be more than enough for one device */
+- pages_start = (char *)__get_free_pages(GFP_NOIO, 1);
++ pages_start = (char *)__get_free_pages(GFP_KERNEL, 1);
+ if (!pages_start)
+ return -ENOMEM;
+
+diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
+index 24120db..181f78c 100644
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -1312,9 +1312,9 @@ static int processcompl(struct async *as, void __user * __user *arg)
+ void __user *addr = as->userurb;
+ unsigned int i;
+
+- if (as->userbuffer && urb->actual_length)
++ if (as->userbuffer)
+ if (copy_to_user(as->userbuffer, urb->transfer_buffer,
+- urb->actual_length))
++ urb->transfer_buffer_length))
+ goto err_out;
+ if (put_user(as->status, &userurb->status))
+ goto err_out;
+@@ -1334,11 +1334,14 @@ static int processcompl(struct async *as, void __user * __user *arg)
+ }
+ }
+
++ free_async(as);
++
+ if (put_user(addr, (void __user * __user *)arg))
+ return -EFAULT;
+ return 0;
+
+ err_out:
++ free_async(as);
+ return -EFAULT;
+ }
+
+@@ -1368,11 +1371,8 @@ static struct async *reap_as(struct dev_state *ps)
+ static int proc_reapurb(struct dev_state *ps, void __user *arg)
+ {
+ struct async *as = reap_as(ps);
+- if (as) {
+- int retval = processcompl(as, (void __user * __user *)arg);
+- free_async(as);
+- return retval;
+- }
++ if (as)
++ return processcompl(as, (void __user * __user *)arg);
+ if (signal_pending(current))
+ return -EINTR;
+ return -EIO;
+@@ -1380,16 +1380,11 @@ static int proc_reapurb(struct dev_state *ps, void __user *arg)
+
+ static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
+ {
+- int retval;
+ struct async *as;
+
+- as = async_getcompleted(ps);
+- retval = -EAGAIN;
+- if (as) {
+- retval = processcompl(as, (void __user * __user *)arg);
+- free_async(as);
+- }
+- return retval;
++ if (!(as = async_getcompleted(ps)))
++ return -EAGAIN;
++ return processcompl(as, (void __user * __user *)arg);
+ }
+
+ #ifdef CONFIG_COMPAT
+@@ -1440,9 +1435,9 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
+ void __user *addr = as->userurb;
+ unsigned int i;
+
+- if (as->userbuffer && urb->actual_length)
++ if (as->userbuffer)
+ if (copy_to_user(as->userbuffer, urb->transfer_buffer,
+- urb->actual_length))
++ urb->transfer_buffer_length))
+ return -EFAULT;
+ if (put_user(as->status, &userurb->status))
+ return -EFAULT;
+@@ -1462,6 +1457,7 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
+ }
+ }
+
++ free_async(as);
+ if (put_user(ptr_to_compat(addr), (u32 __user *)arg))
+ return -EFAULT;
+ return 0;
+@@ -1470,11 +1466,8 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
+ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg)
+ {
+ struct async *as = reap_as(ps);
+- if (as) {
+- int retval = processcompl_compat(as, (void __user * __user *)arg);
+- free_async(as);
+- return retval;
+- }
++ if (as)
++ return processcompl_compat(as, (void __user * __user *)arg);
+ if (signal_pending(current))
+ return -EINTR;
+ return -EIO;
+@@ -1482,16 +1475,11 @@ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg)
+
+ static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg)
+ {
+- int retval;
+ struct async *as;
+
+- retval = -EAGAIN;
+- as = async_getcompleted(ps);
+- if (as) {
+- retval = processcompl_compat(as, (void __user * __user *)arg);
+- free_async(as);
+- }
+- return retval;
++ if (!(as = async_getcompleted(ps)))
++ return -EAGAIN;
++ return processcompl_compat(as, (void __user * __user *)arg);
+ }
+
+ #endif
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 1a7d54b..0f857e6 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1612,12 +1612,12 @@ static inline void announce_device(struct usb_device *udev) { }
+ #endif
+
+ /**
+- * usb_enumerate_device_otg - FIXME (usbcore-internal)
++ * usb_configure_device_otg - FIXME (usbcore-internal)
+ * @udev: newly addressed device (in ADDRESS state)
+ *
+- * Finish enumeration for On-The-Go devices
++ * Do configuration for On-The-Go devices
+ */
+-static int usb_enumerate_device_otg(struct usb_device *udev)
++static int usb_configure_device_otg(struct usb_device *udev)
+ {
+ int err = 0;
+
+@@ -1688,7 +1688,7 @@ fail:
+
+
+ /**
+- * usb_enumerate_device - Read device configs/intfs/otg (usbcore-internal)
++ * usb_configure_device - Detect and probe device intfs/otg (usbcore-internal)
+ * @udev: newly addressed device (in ADDRESS state)
+ *
+ * This is only called by usb_new_device() and usb_authorize_device()
+@@ -1699,7 +1699,7 @@ fail:
+ * the string descriptors, as they will be errored out by the device
+ * until it has been authorized.
+ */
+-static int usb_enumerate_device(struct usb_device *udev)
++static int usb_configure_device(struct usb_device *udev)
+ {
+ int err;
+
+@@ -1723,7 +1723,7 @@ static int usb_enumerate_device(struct usb_device *udev)
+ udev->descriptor.iManufacturer);
+ udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
+ }
+- err = usb_enumerate_device_otg(udev);
++ err = usb_configure_device_otg(udev);
+ fail:
+ return err;
+ }
+@@ -1733,8 +1733,8 @@ fail:
+ * usb_new_device - perform initial device setup (usbcore-internal)
+ * @udev: newly addressed device (in ADDRESS state)
+ *
+- * This is called with devices which have been detected but not fully
+- * enumerated. The device descriptor is available, but not descriptors
++ * This is called with devices which have been enumerated, but not yet
++ * configured. The device descriptor is available, but not descriptors
+ * for any device configuration. The caller must have locked either
+ * the parent hub (if udev is a normal device) or else the
+ * usb_bus_list_lock (if udev is a root hub). The parent's pointer to
+@@ -1757,8 +1757,8 @@ int usb_new_device(struct usb_device *udev)
+ if (udev->parent)
+ usb_autoresume_device(udev->parent);
+
+- usb_detect_quirks(udev);
+- err = usb_enumerate_device(udev); /* Read descriptors */
++ usb_detect_quirks(udev); /* Determine quirks */
++ err = usb_configure_device(udev); /* detect & probe dev/intfs */
+ if (err < 0)
+ goto fail;
+ dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",
+@@ -1803,23 +1803,21 @@ fail:
+ */
+ int usb_deauthorize_device(struct usb_device *usb_dev)
+ {
++ unsigned cnt;
+ usb_lock_device(usb_dev);
+ if (usb_dev->authorized == 0)
+ goto out_unauthorized;
+-
+ usb_dev->authorized = 0;
+ usb_set_configuration(usb_dev, -1);
+-
+- kfree(usb_dev->product);
+ usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
+- kfree(usb_dev->manufacturer);
+ usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
+- kfree(usb_dev->serial);
+ usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
+-
+- usb_destroy_configuration(usb_dev);
++ kfree(usb_dev->config);
++ usb_dev->config = NULL;
++ for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++)
++ kfree(usb_dev->rawdescriptors[cnt]);
+ usb_dev->descriptor.bNumConfigurations = 0;
+-
++ kfree(usb_dev->rawdescriptors);
+ out_unauthorized:
+ usb_unlock_device(usb_dev);
+ return 0;
+@@ -1829,11 +1827,15 @@ out_unauthorized:
+ int usb_authorize_device(struct usb_device *usb_dev)
+ {
+ int result = 0, c;
+-
+ usb_lock_device(usb_dev);
+ if (usb_dev->authorized == 1)
+ goto out_authorized;
+-
++ kfree(usb_dev->product);
++ usb_dev->product = NULL;
++ kfree(usb_dev->manufacturer);
++ usb_dev->manufacturer = NULL;
++ kfree(usb_dev->serial);
++ usb_dev->serial = NULL;
+ result = usb_autoresume_device(usb_dev);
+ if (result < 0) {
+ dev_err(&usb_dev->dev,
+@@ -1846,18 +1848,10 @@ int usb_authorize_device(struct usb_device *usb_dev)
+ "authorization: %d\n", result);
+ goto error_device_descriptor;
+ }
+-
+- kfree(usb_dev->product);
+- usb_dev->product = NULL;
+- kfree(usb_dev->manufacturer);
+- usb_dev->manufacturer = NULL;
+- kfree(usb_dev->serial);
+- usb_dev->serial = NULL;
+-
+ usb_dev->authorized = 1;
+- result = usb_enumerate_device(usb_dev);
++ result = usb_configure_device(usb_dev);
+ if (result < 0)
+- goto error_enumerate;
++ goto error_configure;
+ /* Choose and set the configuration. This registers the interfaces
+ * with the driver core and lets interface drivers bind to them.
+ */
+@@ -1872,10 +1866,8 @@ int usb_authorize_device(struct usb_device *usb_dev)
+ }
+ }
+ dev_info(&usb_dev->dev, "authorized to connect\n");
+-
+-error_enumerate:
++error_configure:
+ error_device_descriptor:
+- usb_autosuspend_device(usb_dev);
+ error_autoresume:
+ out_authorized:
+ usb_unlock_device(usb_dev); // complements locktree
+@@ -3286,9 +3278,6 @@ static void hub_events(void)
+ USB_PORT_FEAT_C_SUSPEND);
+ udev = hdev->children[i-1];
+ if (udev) {
+- /* TRSMRCY = 10 msec */
+- msleep(10);
+-
+ usb_lock_device(udev);
+ ret = remote_wakeup(hdev->
+ children[i-1]);
+diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
+index 980a8d2..da718e8 100644
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -911,11 +911,11 @@ char *usb_cache_string(struct usb_device *udev, int index)
+ if (index <= 0)
+ return NULL;
+
+- buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
++ buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL);
+ if (buf) {
+ len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
+ if (len > 0) {
+- smallbuf = kmalloc(++len, GFP_NOIO);
++ smallbuf = kmalloc(++len, GFP_KERNEL);
+ if (!smallbuf)
+ return buf;
+ memcpy(smallbuf, buf, len);
+@@ -1682,7 +1682,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
+ if (cp) {
+ nintf = cp->desc.bNumInterfaces;
+ new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
+- GFP_NOIO);
++ GFP_KERNEL);
+ if (!new_interfaces) {
+ dev_err(&dev->dev, "Out of memory\n");
+ return -ENOMEM;
+@@ -1691,7 +1691,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
+ for (; n < nintf; ++n) {
+ new_interfaces[n] = kzalloc(
+ sizeof(struct usb_interface),
+- GFP_NOIO);
++ GFP_KERNEL);
+ if (!new_interfaces[n]) {
+ dev_err(&dev->dev, "Out of memory\n");
+ ret = -ENOMEM;
+diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
+index fcdcad4..7ec3041 100644
+--- a/drivers/usb/core/sysfs.c
++++ b/drivers/usb/core/sysfs.c
+@@ -82,13 +82,9 @@ static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+ { \
+ struct usb_device *udev; \
+- int retval; \
+ \
+ udev = to_usb_device(dev); \
+- usb_lock_device(udev); \
+- retval = sprintf(buf, "%s\n", udev->name); \
+- usb_unlock_device(udev); \
+- return retval; \
++ return sprintf(buf, "%s\n", udev->name); \
+ } \
+ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
+
+@@ -115,12 +111,6 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf)
+ case USB_SPEED_HIGH:
+ speed = "480";
+ break;
+- case USB_SPEED_VARIABLE:
+- speed = "480";
+- break;
+- case USB_SPEED_SUPER:
+- speed = "5000";
+- break;
+ default:
+ speed = "unknown";
+ }
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+index 52e5e31..b1b85ab 100644
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -132,7 +132,7 @@ EXPORT_SYMBOL_GPL(usb_altnum_to_altsetting);
+
+ struct find_interface_arg {
+ int minor;
+- struct device_driver *drv;
++ struct usb_interface *interface;
+ };
+
+ static int __find_interface(struct device *dev, void *data)
+@@ -143,10 +143,12 @@ static int __find_interface(struct device *dev, void *data)
+ if (!is_usb_interface(dev))
+ return 0;
+
+- if (dev->driver != arg->drv)
+- return 0;
+ intf = to_usb_interface(dev);
+- return intf->minor == arg->minor;
++ if (intf->minor != -1 && intf->minor == arg->minor) {
++ arg->interface = intf;
++ return 1;
++ }
++ return 0;
+ }
+
+ /**
+@@ -154,24 +156,21 @@ static int __find_interface(struct device *dev, void *data)
+ * @drv: the driver whose current configuration is considered
+ * @minor: the minor number of the desired device
+ *
+- * This walks the bus device list and returns a pointer to the interface
+- * with the matching minor and driver. Note, this only works for devices
+- * that share the USB major number.
++ * This walks the driver device list and returns a pointer to the interface
++ * with the matching minor. Note, this only works for devices that share the
++ * USB major number.
+ */
+ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
+ {
+ struct find_interface_arg argb;
+- struct device *dev;
++ int retval;
+
+ argb.minor = minor;
+- argb.drv = &drv->drvwrap.driver;
+-
+- dev = bus_find_device(&usb_bus_type, NULL, &argb, __find_interface);
+-
+- /* Drop reference count from bus_find_device */
+- put_device(dev);
+-
+- return dev ? to_usb_interface(dev) : NULL;
++ argb.interface = NULL;
++ /* eat the error, it will be in argb.interface */
++ retval = driver_for_each_device(&drv->drvwrap.driver, NULL, &argb,
++ __find_interface);
++ return argb.interface;
+ }
+ EXPORT_SYMBOL_GPL(usb_find_interface);
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index a18e3c5..94386f8 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -187,6 +187,24 @@ config USB_LH7A40X
+ default USB_GADGET
+ select USB_GADGET_SELECTED
+
++config USB_GADGET_TMPA910
++ boolean "TMPA910 USB Device Controller"
++ depends on ARCH_TMPA910
++ help
++ The TOSHIBA ARM MCU TMPA910CRAXBG has a full speed USB Device
++ Controller with support for 3 configurable endpoints (plus
++ endpoint zero).
++
++ Say "y" to link the driver statically, or "m" to build a
++ dynamically linked module called "tmpa910_udc" and force all
++ gadget drivers to also be dynamically linked.
++
++config USB_TMPA910
++ tristate
++ depends on USB_GADGET_TMPA910
++ default USB_GADGET
++ select USB_GADGET_SELECTED
++
+ config USB_GADGET_OMAP
+ boolean "OMAP USB Device Controller"
+ depends on ARCH_OMAP
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 9d7b87c..ca84f6c 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -26,6 +26,7 @@ obj-$(CONFIG_USB_M66592) += m66592-udc.o
+ obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o
+ obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o
+ obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o
++obj-$(CONFIG_USB_TMPA910) += tmpa910_udc.o
+ obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o
+ obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o
+
+diff --git a/drivers/usb/gadget/tmpa910_udc.c b/drivers/usb/gadget/tmpa910_udc.c
+new file mode 100644
+index 0000000..6989574
+--- /dev/null
++++ b/drivers/usb/gadget/tmpa910_udc.c
+@@ -0,0 +1,2723 @@
++/*
++ * tmpa910_udc -- driver for tmpa910-series USB peripheral controller
++ *
++ *
++ * 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.
++ */
++
++//#undef DEBUG
++#define DEBUG
++//#undef VERBOSE
++#define VERBOSE
++#undef PACKET_TRACE
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/slab.h>
++#include <linux/smp_lock.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
++#include <linux/proc_fs.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/usb/ch9.h>
++#include <linux/usb/gadget.h>
++
++#include <asm/byteorder.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/mach-types.h>
++
++#include <mach/hardware.h>
++#include <mach/tmpa910_regs.h>
++
++#include "tmpa910_udc.h"
++
++
++const unsigned char Dev_Desc[DEVICE_DESC_SIZE] = {
++ 0x12, /* bLength*/
++ 0x01, /* bDescriptorType*/
++ 0x00, /* bcdUSB(Low) */
++ 0x02, /* bcdUSB(High) */
++ 0x00, /* bDeviceClass*/
++ 0x00, /* bDeviceSubClass*/
++ 0x00, /* bDeviceProtocol*/
++ 0x40, /* bMaxPacketSize0*/
++ 0x30, /* idVendor(Low) */
++ 0x09, /* idVendor(High) */
++ 0x05, /* idProduct(Low) */
++ 0x65, /* idProduct(High) */
++ 0x00, /* bcdDevice(Low) */
++ 0x01, /* bcdDevice(High) */
++ 0x00, /* iManufacturer*/
++ 0x00, /* iProduct*/
++ 0x00, /* iSerialNumber*/
++ 0x01 /* bNumConfigrations*/
++};
++
++//const unsigned char __align(4) Config_Desc[CONFIG_DESC_SIZE] = {
++const unsigned char Config_Desc[CONFIG_DESC_SIZE] = {
++/* Configuration Descriptor*/
++ 0x09, /* bLength*/
++ 0x02, /* bDescriptorType*/
++ 0x20, /* wTotalLength(Low) */
++ 0x00, /* wTotalLength(High) */
++ 0x01, /* bNumInterfaces*/
++ 0x01, /* bConfigurationValue */
++ 0x00, /* iConfiguration */
++ 0x80, /* bmAttributes */
++ 0x41, /* bMaxPower*/
++
++/* Interface Descriptor*/
++ 0x09, /* bLength*/
++ 0x04, /* bDescriptorType*/
++ 0x00, /* bInterfaceNumber*/
++ 0x00, /* bAlternateSetting*/
++ 0x02, /* bNumEndpoints*/
++ 0x08, /* bInterfaceClass*/
++ 0x06, /* bInterfaceSubClass*/
++ 0x50, /* bInterfaceProtocol*/
++ 0x00, /* iInterface*/
++
++/* EndPoint[1] Descriptor*/
++ 0x07, /* bLength*/
++ 0x05, /* bDescriptorType*/
++ 0x81, /* bEndPointAddress*/
++ 0x02, /* bmAttributes*/
++ 0x00, /* wMaxPacketSize(Low) */
++ 0x02, /* wMaxPacketSize(High) */
++ 0x01, /* bInterval*/
++
++/* EndPoint[2] Descriptor*/
++ 0x07, /* bLength*/
++ 0x05, /* bDescriptorType*/
++ 0x02, /* bEndPointAddress*/
++ 0x02, /* bmAttributes*/
++ 0x00, /* wMaxPacketSize(Low) */
++ 0x02, /* wMaxPacketSize(High) */
++ 0x01 /* bInterval*/
++};
++
++//const unsigned char __align(4) Qualifier_Desc[QUALFIER_DESC_SIZE] = {
++const unsigned char Qualifier_Desc[QUALFIER_DESC_SIZE] = {
++ 0x0A, /*bLength, (10byte) */
++ 0x06, /*bDescriptorType */
++ 0x00, /* bcdUSB(Low) */
++ 0x02, /* bcdUSB(High)*/
++ 0x00, /* bDeviceClass */
++ 0x00, /* bDeviceSubClass */
++ 0x00, /* bDeviceProtocol*/
++ 0x40, /* bMaxPacketSize0(64byte) */
++ 0x01, /* bNumConfiguration(2Configurations) */
++ 0x00, /* Reserve*/
++};
++
++//const unsigned char __align(4) Str_Desc_ROM[TOTAL_STRING_DESC] = {
++const unsigned char Str_Desc_ROM[TOTAL_STRING_DESC] = {
++ /* STRING DESCRIPTOR(Micro controller) */
++ 0x11 /* Size of Descriptor(byte) */
++ , 0x03 /* Descriptor Type */
++ , 0x54 /* 'T' */
++ , 0x4d /* 'M' */
++ , 0x50 /* 'P' */
++ , 0x41 /* 'A' */
++ , 0x39 /* '9' */
++ , 0x31 /* '1' */
++ , 0x30 /* '0' */
++ , 0x43 /* 'C' */
++ , 0x52 /* 'R' */
++ , 0x20 /* '' */
++ , 0x20 /* '' */
++ , 0x20 /* '' */
++ , 0x20 /* '' */
++ , 0x20 /* '' */
++ , 0x20 /* '' */
++
++ /* STRING DESCRIPTOR(Manufacturer) */
++ , 0x03 /* Size of Descriptor(byte) */
++ , 0x03 /* Descriptor Type */
++ , 0x00 /* String Descriptor Infomation */
++
++ /* STRING DESCRIPTOR(Product) */
++ , 0x03 /* Size of Descriptor(byte) */
++ , 0x03 /* Descriptor Type */
++ , 0x00 /* String Descriptor Infomation */
++
++ /* STRING DESCRIPTOR(Serial Number) */
++ , 0x03 /* Size of Descriptor(byte) */
++ , 0x03 /* Descriptor Type */
++ , 0x00 /* String Descriptor Infomation */
++
++};
++
++/*
++ * This controller is
++ *
++ * This driver expects the board has been wired with two GPIOs suppporting
++ * a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the
++ * testing hasn't covered such cases.)
++ *
++ * The pullup is most important (so it's integrated on sam926x parts). It
++ * provides software control over whether the host enumerates the device.
++ *
++ * The VBUS sensing helps during enumeration, and allows both USB clocks
++ * (and the transceiver) to stay gated off until they're necessary, saving
++ * power. During USB suspend, the 48 MHz clock is gated off in hardware;
++ * it may also be gated off by software during some Linux sleep states.
++ */
++
++#define DRIVER_VERSION "26 July 2008"
++
++static const char driver_name [] = "tmpa910-usb";
++static const char ep0name[] = "ep0";
++
++
++#define tmpa910_udp_read(dev, reg) \
++ __raw_readl((dev)->udp_baseaddr + (reg))
++#define tmpa910_udp_write(dev, reg, val) \
++ __raw_writel((val), (dev)->udp_baseaddr + (reg))
++
++static int tmpa910_ep_enable (struct usb_ep *ep,
++ const struct usb_endpoint_descriptor *desc)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return -1;
++}
++
++static int tmpa910_ep_disable (struct usb_ep *ep)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return -1;
++}
++
++struct usb_request *tmpa910_ep_alloc_request (struct usb_ep *ep,
++ gfp_t gfp_flags)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return NULL;
++}
++
++static void tmpa910_ep_free_request (struct usb_ep *ep, struct usb_request *req)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++}
++
++
++
++static int tmpa910_ep_queue (struct usb_ep *ep, struct usb_request *req,
++ gfp_t gfp_flags)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return -1;
++}
++
++static int tmpa910_ep_dequeue (struct usb_ep *ep, struct usb_request *req)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return -1;
++}
++
++static int tmpa910_ep_set_halt (struct usb_ep *ep, int value)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return -1;
++}
++
++static int tmpa910_get_frame (struct usb_gadget *usb_gadget)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return -1;
++}
++
++static int tmpa910_wakeup (struct usb_gadget *usb_gadget)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return 0;
++}
++
++static int tmpa910_set_selfpowered (struct usb_gadget *usb_gadget, int is_selfpowered)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return 0;
++}
++
++static int tmpa910_vbus_session (struct usb_gadget *usb_gadget, int is_active)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return 0;
++}
++
++static int tmpa910_pullup (struct usb_gadget *usb_gadget, int is_on)
++{
++printk("tmpa910_udc: %s, Line: %d\n", __FUNCTION__, __LINE__);
++return 0;
++}
++
++static const struct usb_ep_ops tmpa910_ep_ops = {
++ .enable = tmpa910_ep_enable,
++ .disable = tmpa910_ep_disable,
++ .alloc_request = tmpa910_ep_alloc_request,
++ .free_request = tmpa910_ep_free_request,
++ .queue = tmpa910_ep_queue,
++ .dequeue = tmpa910_ep_dequeue,
++ .set_halt = tmpa910_ep_set_halt,
++ // there's only imprecise fifo status reporting
++};
++
++static const struct usb_gadget_ops tmpa910_udc_ops = {
++ .get_frame = tmpa910_get_frame,
++ .wakeup = tmpa910_wakeup,
++ .set_selfpowered = tmpa910_set_selfpowered,
++ .vbus_session = tmpa910_vbus_session,
++ .pullup = tmpa910_pullup,
++};
++
++static void nop_release(struct device *dev){}
++
++static struct tmpa910_udc controller = {
++ .gadget = {
++ .ops = &tmpa910_udc_ops,
++ .ep0 = &controller.ep[0].ep,
++ .name = driver_name,
++ .dev = {
++ .release = nop_release,
++ }
++ },
++ .ep[0] = {
++ .ep = {
++ .name = ep0name,
++ .ops = &tmpa910_ep_ops,
++ },
++ .udc = &controller,
++ .maxpacket = 64,
++ .int_mask = 1 << 0,
++ },
++ .ep[1] = {
++ .ep = {
++ .name = "ep1",
++ .ops = &tmpa910_ep_ops,
++ },
++ .udc = &controller,
++ .is_pingpong = 1,
++ .maxpacket = 512,
++ .int_mask = 1 << 1,
++ },
++ .ep[2] = {
++ .ep = {
++ .name = "ep2",
++ .ops = &tmpa910_ep_ops,
++ },
++ .udc = &controller,
++ .is_pingpong = 1,
++ .maxpacket = 512,
++ .int_mask = 1 << 2,
++ },
++};
++
++/*-------------------------------------------------------------------------*/
++
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++#include <linux/seq_file.h>
++
++static const char debug_filename[] = "driver/udc";
++
++#define FOURBITS "%s%s%s%s"
++#define EIGHTBITS FOURBITS FOURBITS
++#endif
++
++#define CLKCR4 __REG(0xf0050050)
++/*
++ *********************************************************************
++ * VARIABLE DEFINITIONS
++ *********************************************************************
++ */
++
++/*==========================*/
++/* Table Definitions */
++/*==========================*/
++//unsigned char __align(4) g_USB_Send_Buf[BUFSIZE]; /* Send Buffer */
++//unsigned char __align(4) g_USB_Recv_Buf[BUFSIZE]; /* Receive Buffer */
++//unsigned char __align(4) g_USB_Recv_Rbuf[RINGBUFSIZE];
++
++unsigned char g_USB_Send_Buf[BUFSIZE]; /* Send Buffer */
++unsigned char g_USB_Recv_Buf[BUFSIZE]; /* Receive Buffer */
++unsigned char g_USB_Recv_Rbuf[RINGBUFSIZE];
++
++unsigned char *g_Recv_Rbuf_Wpt;
++unsigned char *g_Recv_Rbuf_Rpt;
++unsigned char g_USB_Rbuf_Status; /* USB RING BUFFER status */
++
++unsigned char g_USB_Status; /* USB Driver status */
++unsigned char g_USB_Bulk_In_Mode; /* Bulk-in mode */
++unsigned char g_USB_Bulk_Out_Mode; /* Bulk-out mode */
++
++/* For INTERRUPT CHECK*/
++unsigned long int g_Interrupt_Stasus;
++
++/* For ENDPOINT0 */
++//unsigned char __align(4) g_EP0_Recv_Buff[EP_MAX_PACKET_SIZE_FS]; /* EP0庴æ£å¶å¢å¼å½ */
++//unsigned char __align(4) g_EP0_Send_Buff[EP_MAX_PACKET_SIZE_FS]; /* EP0æ²æ£å¶å¢å¼å½ */
++unsigned char g_EP0_Recv_Buff[EP_MAX_PACKET_SIZE_FS]; /* EP0庴æ£å¶å¢å¼å½ */
++unsigned char g_EP0_Send_Buff[EP_MAX_PACKET_SIZE_FS]; /* EP0æ²æ£å¶å¢å¼å½ */
++unsigned char g_USB_Stage; /* åå¥ä¹åå¿¬æº */
++unsigned char g_USB_Stage_Error; /* åå¥ä¹åååä¹å¼åå */
++unsigned char g_EP0_Recv_Length; /* EP0庴æ£å¨ä¹åæ¿ */
++
++/* For BULK MODE */
++unsigned char *g_DMA_Send_Buff_Address; /* æ²æ£å¨ä¹å奿æºæå¾åªåå */
++unsigned char *g_DMA_Recv_Buff_Address; /* 庴æ£å¨ä¹å奿æºæå¾åªåå */
++unsigned long int g_DMA_Send_Length; /* å·æ²æ£å¨ä¹åæ¿ */
++unsigned long int g_DMA_Recv_Length; /* å·åº´æ£å¨ä¹åæ¿ */
++unsigned short int g_Bulk_Out_EP_Size; /* DMA庴æ£å¨ä¹åæ¿ */
++
++/* Descriptor Infomation */
++//unsigned short int __align(4) g_EP_PAYLOAD_SIZE[EP_SUPPORT_NO];
++unsigned short int g_EP_PAYLOAD_SIZE[EP_SUPPORT_NO];
++unsigned char g_Num_StringDesc;
++unsigned short int g_USB_Address;
++
++/* Request Parameter of Setup Data */
++unsigned char g_bmRequestType;
++unsigned char g_bRequest;
++unsigned short int g_wValue;
++unsigned short int g_wIndex;
++unsigned short int g_wLength;
++
++/* UDC State parameter */
++unsigned short int g_Current_State;
++unsigned char g_Current_Config;
++unsigned char g_Current_Interface;
++unsigned char g_Current_Alternate;
++
++unsigned short int g_Buf_Current_State;
++unsigned char g_Buf_Current_Config;
++unsigned char g_Buf_Current_Interface;
++unsigned char g_Buf_Current_Alternate;
++
++unsigned char g_Self_Powered_Bit;
++
++/* Endpoint Fifo Access */
++unsigned short int g_Remain_TotalLength;
++unsigned short int g_Expected_Length;
++unsigned long int g_Start_Address;
++
++/* FLAG DEFINE */
++FlagByte Dev_Status;
++FlagByte EP_ST;
++
++/*
++ *********************************************************************
++ * FUNCTION DECLARATIONS
++ *********************************************************************
++ */
++static short int USB_Receive_Request(void); /* Function of Request type Judegement */
++static short int Rq_Clear_Feature(void); /* Function of Clear_Feature Request management */
++static short int Rq_Set_Feature(void); /* Function of Set_Feature Request management */
++static short int Rq_Set_Address(void); /* Function of Set_Address Request management */
++static short int Rq_Get_Status(void); /* Function of Get_Status Request management */
++static short int Rq_Set_Configuration(void); /* Function of Set_Configuration Request management */
++static short int Rq_Get_Configuration(void); /* Function of Get_Configuration Request management */
++static short int Rq_Set_Interface(void); /* Function of Set_Interface Request management */
++static short int Rq_Get_Interface(void); /* Function of Get_Interface Request management */
++static short int Rq_Get_Descriptor(void); /* Function of Get_Descriptor Request management */
++static void EP0_FIFO_Read(void); /* Function of reading data from Endpointo's FIFO */
++static void EP0_FIFO_Write(void); /* Function of writing data to Endpoint0's FIFO */
++
++static void USB_Bulk_Out(void);
++static void USB_Bulk_In(void);
++static unsigned short int USB_Send_Length_Chk(const unsigned long int Length);
++static unsigned short int USB_Recv_Length_Chk(void);
++static void USB_Bulk_Out_Start(void);
++
++static void UDC2_Reg_Read(const unsigned long int, unsigned short int*);
++static void UDC2_Reg_Write(const unsigned long int, const unsigned short int);
++
++static void USB_Ctl_Init(void);
++static short int USB_Receive_Request(void);
++static unsigned char Rbuf_Stchk(void);
++static void MemcpyToRecvBufWithRewind(void **pdest, const void *psrc, unsigned long int cnt);
++//static void MemcpyFromRecvBufWithRewind(void *pdest, const void **prbf_rpt, unsigned long int cnt);
++static void USB_Int_Setup(void);
++static void USB_Int_Rx_Zero(void);
++static void USB_Int_Status(void);
++static void USB_Int_Status_NAK(void);
++static void USB_Int_EP0(void);
++static void USB_Int_EPx(void);
++static void USB_Int_SOF(void);
++static void USB_Int_Supend_Resume(void);
++static void USB_Int_USB_Reset_End(void);
++static void USB_Int_USB_Reset(void);
++static void USB_Int_MW_End(void);
++static void USB_Int_MR_End(void);
++//char usb_bulkin_mass_storage(void);
++//char usb_bulkout_mass_storage(void);
++
++/*
++ *********************************************************************
++ * FUNCTION DEFINITIONS
++ *********************************************************************
++ */
++/* DEFINE STANDARD DEVICE REQUEST FUNCTIONS */
++
++/*
++ *********************************************************************
++ * NAME :USB_Receive_Request
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : åå¢å©å¾å¢å¾åå
ååªåº´æ£å±»ä¸ååºå¨æ¢åµå°å¨å¶åå梫媮åªå¤æ
++ *
++ *********************************************************************
++ */
++static short int USB_Receive_Request(void)
++{
++ short int status;
++ unsigned short int request_reg;
++
++ status = 1;
++ UDC2_Reg_Read(UD2BRQ_OFFSET, &request_reg);
++
++ g_bmRequestType = (unsigned char) (request_reg & MASK_UINT16_LOWER_8BIT);
++ g_bRequest = (unsigned char) ((request_reg >> SHIFT_8BIT) & MASK_UINT16_LOWER_8BIT);
++
++ UDC2_Reg_Read(UD2VAL_OFFSET, &g_wValue);
++ UDC2_Reg_Read(UD2IDX_OFFSET, &g_wIndex);
++ UDC2_Reg_Read(UD2LEN_OFFSET, &g_wLength);
++
++ if( (g_bmRequestType & DIRECTION_TYPE_CHECK) == REQ_GET ){
++ fDirection = GET;
++ }
++ else{
++ fDirection = SET;
++ }
++
++ UDC2_Reg_Write(UD2CMD_OFFSET, SETUP_RECEIVED); /* Recieved Device Request. */
++
++ if( (g_bmRequestType & REQUEST_TYPE_CHECK) == STANDARD_RQ ){
++ switch( g_bRequest ){
++ case RQ_GET_STATUS:
++ status = Rq_Get_Status();
++ break;
++ case RQ_CLEAR_FEATURE:
++ status = Rq_Clear_Feature();
++ break;
++ case RQ_SET_FEATURE:
++ status = Rq_Set_Feature();
++ break;
++ case RQ_SET_ADDRESS:
++ status = Rq_Set_Address();
++ break;
++ case RQ_GET_DESCRIPTOR:
++ status = Rq_Get_Descriptor();
++ break;
++ case RQ_GET_CONFIGURATION:
++ status = Rq_Get_Configuration();
++ break;
++ case RQ_SET_CONFIGURATION:
++ status = Rq_Set_Configuration();
++ break;
++ case RQ_GET_INTERFACE:
++ status = Rq_Get_Interface();
++ break;
++ case RQ_SET_INTERFACE:
++ status = Rq_Set_Interface();
++ break;
++ case RQ_SYNCH_FRAME:
++ break;
++
++ default:
++ status = 0;
++ break;
++ }
++ }
++ else if( (g_bmRequestType & REQUEST_TYPE_CHECK) == USBCLASS_RQ ){
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++// status = usb_AnalyzeClassRequest_MassStorage();
++ }
++ else{
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ status = 0;
++ }
++
++ return status;
++}
++
++/*
++ *********************************************************************
++ * NAME : Rq_Get_Status
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : GET STATUS梫媮張æ£
++ *
++ *********************************************************************
++ */
++static short int Rq_Get_Status(void)
++{
++ unsigned char index;
++ unsigned char attribute;
++
++ index = 0;
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ if( (fDirection == SET) || ((g_bmRequestType & RECEIVE_TYPE_CHECK) >= RECEIVE_ERROR)
++ || (g_wValue != 0) || (g_wIndex >= NUM_BREQRUEST_MAX) || (g_wLength != WLENGTH_MAX) ){
++ return 0;
++ }
++ else{
++ g_USB_Stage = DATA_STAGE;
++
++ switch( g_bmRequestType & RECEIVE_TYPE_CHECK ){
++ case RQ_DEVICE:
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ break;
++ case CONFIGURED:
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++ attribute = Config_Desc[CONFIG_DESC_ATTRIBUTE] & ATTRIBUTE_CHECK;
++
++ if( (attribute & SELF_POWERED_BIT) == SELF_POWERED_BIT ){
++ fSelf_Powered = FLAG_ON;
++ }
++ else{
++ fSelf_Powered = FLAG_OFF;
++ }
++
++ if( (attribute & REMOTE_WAKEUP_BIT) == REMOTE_WAKEUP_BIT ){
++ fRemote_Wakeup = FLAG_ON;
++ }
++ else{
++ fRemote_Wakeup = FLAG_OFF;
++ }
++
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, Dev_PowerStatus);
++ break;
++ case RQ_INTERFACE:
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ break;
++ case ADDRESSED:
++ return 0;
++ /* FALL THROUGH */
++ case CONFIGURED:
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++
++ index = (unsigned char) (g_wIndex & INDEX_CHECK);
++ if( (g_Current_Config == 1) && (index > NUM_CONFIG1_INTERFACE) ){
++ return 0;
++ }
++ /* DO NOTHING */
++
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, 0);
++
++ break;
++ case RQ_ENDPOINT:
++ switch( g_Current_State & CURRENT_STATUS_CHECK){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ if( index == EP0 ){
++ break;
++ }
++ else{
++ return 0;
++ }
++ /* FALL THROUGH */
++ case CONFIGURED:
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++
++ index = (unsigned char) (g_wIndex & INDEX_CHECK);
++ if( ((g_Current_Config == 0) && (index > 0)) ||
++ ((g_Current_Config == 1) && (index > NUM_TOTAL_ENDPOINTS)) ){
++ return 0;
++ }
++ else{
++ if( ST_Feature > 0 ){
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, STALL_FEATURE);
++ }
++ else{
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, 0);
++ }
++ }
++ break;
++ default :
++ return 0;
++ /* FALL THROUGH */
++ }
++
++ g_USB_Stage = STATUS_STAGE;
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP0_EOP); /* process of EOP */
++ }
++
++ return 1;
++}
++
++/*
++ *********************************************************************
++ * NAME : Rq_Clear_Feature
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : CLEAR FEATURE梫媮張æ£
++ *
++ *********************************************************************
++ */
++static short int Rq_Clear_Feature(void)
++{
++ unsigned char index;
++ unsigned char attribute;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ if( ((g_bmRequestType & MASK_UCHAR_UPPER_6BIT) != 0) || (g_wLength != 0) ){
++ return 0;
++ }
++ else{
++ index = (unsigned char) (g_wIndex & INDEX_CHECK);
++
++ switch( g_bmRequestType & RECEIVE_TYPE_CHECK ){
++ case RQ_DEVICE:
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ return 0;
++ /* FALL THROUGH */
++ case CONFIGURED:
++ break;
++ default:
++ /* DO NOTHING */
++ break;
++ }
++
++ if( g_wIndex == 0 && g_wValue == 1 ){
++ attribute = Config_Desc[CONFIG_DESC_ATTRIBUTE] & ATTRIBUTE_CHECK;
++
++ if( (attribute & REMOTE_WAKEUP_BIT) == REMOTE_WAKEUP_BIT ){
++ fRemote_Wakeup = FLAG_OFF;
++ }
++ else{
++ return 0;
++ }
++ }
++ else{
++ return 0;
++ }
++ break;
++ case RQ_ENDPOINT:
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ if( index != EP0 ){
++ return 0;
++ }
++ /* DO NOTHING */
++ break;
++ case CONFIGURED:
++ break;
++ default:
++ /* DO NOTHING */
++ break;
++ }
++
++ if( (g_Current_Config == 1) && (index > NUM_TOTAL_ENDPOINTS) ){
++ return 0;
++ }
++ /* DO NOTHING */
++ if( g_wValue != 0 ){
++ return 0;
++ }
++ else{
++ switch( index ){
++ case EP0:
++ fEP0_Stall_Feature = FLAG_OFF;
++ break;
++ case EP1: fEP1_Stall_Feature = FLAG_OFF;
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP1_RESET);
++ break;
++ case EP2:
++ fEP2_Stall_Feature = FLAG_OFF;
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP2_RESET);
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++ }
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++ }
++
++ g_USB_Stage = STATUS_STAGE;
++ UDC2_Reg_Write(UD2CMD_OFFSET, SETUP_FIN);
++
++ return 1;
++}
++
++/*
++ *********************************************************************
++ * NAME : Rq_Set_Feature
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : SET FEATURE梫媮張æ£
++ *
++ *********************************************************************
++ */
++static short int Rq_Set_Feature(void)
++{
++ unsigned char index;
++ unsigned char attribute;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ if( ((g_bmRequestType & MASK_UCHAR_UPPER_6BIT) != 0) || (g_wLength != 0) ){
++ /* g_wLength 0 fix check */
++ return 0;
++ }
++ else{
++ switch( g_bmRequestType & RECEIVE_TYPE_CHECK ){ /* g_bmRequestType check */
++ case RQ_DEVICE:
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ return 0;
++ /* FALL THROUGH */
++ case CONFIGURED:
++ break;
++ default:
++ /* DO NOTHING */
++ break;
++ }
++ if( (g_wIndex == 0) && (g_wValue == 1) ){
++ attribute = Config_Desc[CONFIG_DESC_ATTRIBUTE] & ATTRIBUTE_CHECK;
++ if( (attribute & REMOTE_WAKEUP_BIT) == REMOTE_WAKEUP_BIT ){
++ fRemote_Wakeup = FLAG_ON;
++ }
++ else{
++ return 0;
++ }
++ }
++ else
++ return 0;
++ break;
++ case RQ_ENDPOINT:
++ index = (unsigned char) (g_wIndex & INDEX_CHECK);
++
++ switch( g_Current_State & CURRENT_STATUS_CHECK){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ if( index != EP0 ){
++ return 0;
++ }
++ /* DO NOTHING */
++ /* FALL THROUGH */
++ case CONFIGURED:
++ break;
++ default:
++ /* DO NOTHING */
++ break;
++ }
++
++ if( (g_Current_Config == 1) && (index > NUM_TOTAL_ENDPOINTS) ){
++ return 0;
++ }
++ /* DO NOTHING */
++
++ if( (g_wValue != 0) || (g_wIndex >= NUM_BREQRUEST_MAX) ){
++ return 0;
++ }
++ else{
++ switch( index ){
++ case EP0:
++ fEP0_Stall_Feature = FLAG_ON;
++ break;
++ case EP1:
++ fEP1_Stall_Feature = FLAG_ON;
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP1_STALL);
++ break;
++ case EP2:
++ fEP2_Stall_Feature = FLAG_ON;
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP2_STALL);
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++ }
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++ }
++
++ g_USB_Stage = STATUS_STAGE;
++
++ return 1;
++}
++
++/*
++ *********************************************************************
++ * NAME : Rq_Set_Address
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : SET ADDRESS梫媮張æ£
++ *
++ *********************************************************************
++ */
++static short int Rq_Set_Address(void)
++{
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ if( (g_bmRequestType != (REQ_SET|STANDARD_RQ|RQ_DEVICE)) || (g_wValue >= NUM_BREQRUEST_MAX) ||
++ (g_wIndex != 0) || (g_wLength != 0) ){
++ return 0;
++ }
++ else{
++ if( fEP0_Stall_Feature == 1 ){
++ return 0;
++ }
++ /* DO NOTHING */
++
++ g_USB_Address = g_wValue;
++
++ if( g_USB_Address > USB_ADDRESS_MAX ){
++ return 0;
++ }
++
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ if( g_USB_Address == 0 ){
++ g_Buf_Current_State = DEFAULT;
++ }
++ else{
++ g_Buf_Current_State = ADDRESSED;
++ }
++ break;
++ case ADDRESSED:
++ if( g_USB_Address == 0 ){
++ g_Buf_Current_State = DEFAULT;
++ }
++ else{
++ g_Buf_Current_State = ADDRESSED;
++ }
++ break;
++ case CONFIGURED:
++ if( g_USB_Address == 0 ){
++ g_Buf_Current_State = DEFAULT;
++ return 0;
++ }
++ else{
++ g_Buf_Current_State = CONFIGURED;
++ }
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++
++ g_USB_Stage = STATUS_STAGE;
++ }
++
++ return 1;
++}
++
++/*
++ *********************************************************************
++ * NAME : Rq_Get_Configuration
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : GET CONFIGURATION梫媮張æ£
++ *
++ *********************************************************************
++ */
++static short int Rq_Get_Configuration(void)
++{
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ if( ((g_bmRequestType & (DIRECTION_TYPE_CHECK | RECEIVE_TYPE_CHECK))
++ != (REQ_GET | STANDARD_RQ | RQ_DEVICE) )
++ || (g_wIndex != 0) || (g_wValue != 0) || (g_wLength != 1) ){
++ return 0;
++ }
++ else{
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, 0);
++ break;
++ case CONFIGURED:
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, g_Current_Config);
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++
++ g_USB_Stage = STATUS_STAGE;
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP0_EOP);
++ }
++
++ return 1;
++}
++
++/*
++ *********************************************************************
++ * NAME : Rq_Set_Configuration
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : SET CONFIGURATION梫媮張æ£
++ *
++ *********************************************************************
++ */
++static short int Rq_Set_Configuration(void)
++{
++ unsigned char index;
++
++ index = 0;
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ if( (g_bmRequestType != (REQ_SET|STANDARD_RQ|RQ_DEVICE) )
++ || (g_wValue >= NUM_BREQRUEST_MAX) || (g_wLength != 0) ){
++ return 0;
++ }
++ else{
++ index = (unsigned char) (g_wValue & MASK_UINT16_LOWER_8BIT);
++
++ if( index > NUM_CONFIG ){
++ return 0;
++ }
++
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ break;
++ case CONFIGURED:
++ break;
++ default:
++ /* DO NOTHING */
++ break;
++ }
++
++ if( index == 0 ){ /* Config 0 */
++ UDC2_Reg_Write(UD2CMD_OFFSET, All_EP_INVALID); /* INVALID */
++
++ g_Buf_Current_State = ADDRESSED;
++ g_Buf_Current_Config = index;
++ g_Buf_Current_Interface = 0;
++ g_Buf_Current_Alternate = 0;
++ }
++ else{
++ UDC2_Reg_Write(UD2CMD_OFFSET, All_EP_INVALID); /* INVALID */
++
++ if( index == 1 ){
++ UDC2_Reg_Write(UD2EP1_MaxPacketSize_OFFSET, g_EP_PAYLOAD_SIZE[EP1]);
++ UDC2_Reg_Write(UD2EP1_Status_OFFSET, EP_DUAL_BULK_IN);
++ UDC2_Reg_Write(UD2EP2_MaxPacketSize_OFFSET, g_EP_PAYLOAD_SIZE[EP2]);
++ UDC2_Reg_Write(UD2EP2_Status_OFFSET, EP_DUAL_BULK_OUT);
++
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP1_RESET); /*EP1 Reset */
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP2_RESET); /*EP2 Reset */
++ }
++ else{
++ return 0;
++ }
++
++ g_Buf_Current_State = CONFIGURED;
++ g_Buf_Current_Config = index;
++ g_Buf_Current_Interface = 0;
++ g_Buf_Current_Alternate = 0;
++
++ }
++
++ ST_Feature = STALL_FALL_CLEAR; /* Stall Feature All Clear */
++ g_USB_Stage = STATUS_STAGE;
++ }
++
++ return 1;
++}
++
++/*
++ *********************************************************************
++ * NAME : Rq_Get_Interface
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : GET INTERFACE梫媮張æ£
++ *
++ *********************************************************************
++ */
++static short int Rq_Get_Interface(void)
++{
++ unsigned char index;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ if( ((g_bmRequestType & (DIRECTION_TYPE_CHECK | RECEIVE_TYPE_CHECK))
++ != (REQ_GET | STANDARD_RQ | RQ_INTERFACE) ) || (g_wValue != 0) || (g_wLength != 1) ) {
++ return 0;
++ }
++ else{
++ g_USB_Stage = DATA_STAGE;
++
++ switch( g_Current_State & CURRENT_STATUS_CHECK){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ return 0;
++ /* FALL THROUGH */
++ case CONFIGURED:
++ break;
++ default:
++ /* DO NOTHING */
++ break;
++ }
++
++ index = (unsigned char) (g_wIndex & MASK_UINT16_LOWER_8BIT);
++
++ if( (g_Current_Config == 1) && (index > NUM_CONFIG1_INTERFACE) ){
++ return 0;
++ }
++ /* DO NOTHING */
++
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, g_Current_Alternate);
++ g_USB_Stage = STATUS_STAGE;
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP0_EOP); /* process of EOP */
++ }
++
++ return 1;
++}
++
++/*
++ *********************************************************************
++ * NAME : Rq_Set_Interface
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : SET INTERFACE梫媮張æ£
++ *
++ *********************************************************************
++ */
++static short int Rq_Set_Interface(void)
++{
++ unsigned char index_interface;
++ unsigned char value_alternate;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ if( (g_bmRequestType != (REQ_SET|STANDARD_RQ|RQ_INTERFACE) ) || (g_wValue >= NUM_BREQRUEST_MAX)
++ || (g_wIndex >= NUM_BREQRUEST_MAX) || (g_wLength != 0) ){
++ return 0;
++ }
++ else{
++
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ return 0;
++ /* FALL THROUGH */
++ case ADDRESSED:
++ return 0;
++ /* FALL THROUGH */
++ case CONFIGURED:
++ break;
++ default:
++ /* DO NOTHING */
++ break;
++ }
++
++ index_interface = (unsigned char) (g_wIndex & MASK_UINT16_LOWER_8BIT);
++ value_alternate = (unsigned char) (g_wValue & MASK_UINT16_LOWER_8BIT);
++
++ if( g_Current_Config == 1 ){
++ if( index_interface > NUM_CONFIG1_INTERFACE ){
++ return 0;
++ }
++ if( value_alternate > NUM_C1IO_ALT0 ){
++ return 0;
++ }
++ }
++ else{
++ return 0;
++ }
++
++ UDC2_Reg_Write(UD2CMD_OFFSET, All_EP_INVALID); /* INVALID */
++
++ UDC2_Reg_Write(UD2EP1_MaxPacketSize_OFFSET, g_EP_PAYLOAD_SIZE[EP1]);
++ UDC2_Reg_Write(UD2EP1_Status_OFFSET, EP_DUAL_BULK_IN);
++ UDC2_Reg_Write(UD2EP2_MaxPacketSize_OFFSET, g_EP_PAYLOAD_SIZE[EP2]);
++ UDC2_Reg_Write(UD2EP2_Status_OFFSET, EP_DUAL_BULK_OUT);
++
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP1_RESET); /*EP1 Reset */
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP2_RESET); /*EP2 Reset */
++
++ g_Buf_Current_Interface = index_interface;
++ g_Buf_Current_Alternate = value_alternate;
++
++ ST_Feature = STALL_FALL_CLEAR; /* Stall Feature All Clear */
++ g_USB_Stage = STATUS_STAGE;
++ }
++
++ return 1;
++}
++
++/*
++ *********************************************************************
++ * NAME : Rq_Get_Descriptor
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : GET DESCRIPTOR梫媮張æ£
++ *
++ *********************************************************************
++ */
++static short int Rq_Get_Descriptor(void)
++{
++ unsigned char type; /*status_reg; */
++ unsigned char index; /*status_reg; */
++ struct config_desc* config=NULL;
++ struct string_desc* string;
++ unsigned char* data1;
++ int i;
++ const unsigned char* table;
++ unsigned char ConfigDescData[CONFIG_DESC_SIZE];
++ unsigned short int Other_Speed_Payload_Size;
++ unsigned short int interrupt_status;
++
++ if( fDirection == SET ){
++ return 0;
++ }
++ else{
++ g_USB_Stage = DATA_STAGE;
++
++ type = (unsigned char) (g_wValue >> SHIFT_8BIT) ; /* Descriptor type */
++ index = (unsigned char) (g_wValue & MASK_UINT16_LOWER_8BIT) ; /* String Descriptor Index */
++
++ switch( g_Current_State & CURRENT_STATUS_CHECK ){
++ case DEFAULT:
++ UDC2_Reg_Write(UD2INT_OFFSET, USB_MASK);
++ break;
++ case ADDRESSED:
++ break;
++ case CONFIGURED:
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++
++ switch( type ){
++ case TYPE_DEVICE: /* Treatment of Device Descriptor */
++ if( (g_wIndex == 0) && (index == 0) ){
++ g_Expected_Length = DEVICE_DESC_SIZE;
++ g_Start_Address = (unsigned long int) Dev_Desc;
++ if( g_wLength <= g_Expected_Length ){
++ g_Remain_TotalLength = g_wLength;
++ }
++ else{
++ g_Remain_TotalLength = g_Expected_Length;
++ }
++ DBG("DESCDEV -- g_wIdx: %d; idx: %d; g_wLen: %d; g_ExpLen: %d; g_RemTotLen: %d\n",
++ g_wIndex, index, g_wLength, g_Expected_Length, g_Remain_TotalLength);
++ EP0_FIFO_Write();
++ }
++ else
++ return 0;
++ break;
++ case TYPE_CONFIG: /* Treatment of Config Descriptor */
++ DBG("Function: %s, Line: %d, index: %d, g_wIndex: %d\n", __FUNCTION__, __LINE__, index, g_wIndex);
++ if( (index > NUM_CONFIG) || (g_wIndex != 0) ){
++ return 0;
++ }
++ else{
++ data1 = ConfigDescData;
++ table = Config_Desc;
++ for( i=CONFIG_DESC_SIZE; i>0; data1++, table++, i--){
++ *data1 = *table;
++ }
++ ConfigDescData[CONFIG_DESC_TYPE] = TYPE_CONFIG;
++ ConfigDescData[CONFIG_EP1_SIZE_LOW] =
++ (unsigned char) (g_EP_PAYLOAD_SIZE[EP1] & MASK_UINT16_LOWER_8BIT);
++ ConfigDescData[CONFIG_EP1_SIZE_HIGH] =
++ (unsigned char) (g_EP_PAYLOAD_SIZE[EP1] >> SHIFT_8BIT);
++ ConfigDescData[CONFIG_EP2_SIZE_LOW] =
++ (unsigned char) (g_EP_PAYLOAD_SIZE[EP2] & MASK_UINT16_LOWER_8BIT);
++ ConfigDescData[CONFIG_EP2_SIZE_HIGH] =
++ (unsigned char) (g_EP_PAYLOAD_SIZE[EP2] >> SHIFT_8BIT);
++
++ config =(struct config_desc *)&ConfigDescData[0];
++
++ g_Expected_Length = config->wTotalLength;
++ g_Start_Address = (unsigned long int) config;
++
++ if( g_wLength <= g_Expected_Length ){
++ g_Remain_TotalLength = g_wLength;
++ }
++ else{
++ g_Remain_TotalLength = g_Expected_Length;
++ }
++
++ DBG("CFGDEV -- g_wIdx: %d; idx: %d; g_wLen: %d; g_ExpLen: %d; g_RemTotLen: %d\n",
++ g_wIndex, index, g_wLength, g_Expected_Length, g_Remain_TotalLength);
++ EP0_FIFO_Write();
++ }
++ break;
++ case TYPE_STRING: /* Treatment of String Descriptor */
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ if( index < g_Num_StringDesc ){
++ switch(index){
++ case STRING_DESC_INDEX_0:
++ string = (struct string_desc *)&Str_Desc_ROM[STR0_ADDRESS];
++ break;
++ case STRING_DESC_INDEX_1:
++ string = (struct string_desc *)&Str_Desc_ROM[STR1_ADDRESS];
++ break;
++ case STRING_DESC_INDEX_2:
++ string = (struct string_desc *)&Str_Desc_ROM[STR2_ADDRESS];
++ break;
++ case STRING_DESC_INDEX_3:
++ string = (struct string_desc *)&Str_Desc_ROM[STR1_ADDRESS];
++ break;
++ default:
++ return 0;
++ /* FALL THROUGH */
++ }
++
++ if( string->bLength == 0 ){
++ return 0;
++ }
++ else{
++ g_Start_Address = (unsigned long int) string;
++ g_Expected_Length = string->bLength;
++ if( g_wLength <= g_Expected_Length ){
++ g_Remain_TotalLength = g_wLength;
++ }
++ else{
++ g_Remain_TotalLength = g_Expected_Length;
++ }
++
++ EP0_FIFO_Write();
++ }
++ }
++ else{
++ return 0;
++ }
++ break;
++ case TYPE_DEVICE_QUALIFIER:
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ if( index > 0 ){
++ return 0;
++ }
++ else{
++ config = (struct config_desc*) &Qualifier_Desc[0];
++
++ g_Expected_Length = config->wTotalLength;
++ g_Start_Address = (unsigned long int) config;
++
++ if( g_wLength <= g_Expected_Length ){
++ g_Remain_TotalLength = g_wLength;
++ }
++ else{
++ g_Remain_TotalLength = g_Expected_Length;
++ }
++
++ EP0_FIFO_Write();
++ }
++ break;
++ case TYPE_OTHER_SPEED: /* Treatment of OTHER SPEED Descriptor */
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ if( index > 0 ){
++ return 0;
++ }
++ else{
++ data1 = ConfigDescData;
++ table = Config_Desc;
++ for( i=CONFIG_DESC_SIZE; i>0; data1++, table++, i--){
++ *data1 = *table;
++ }
++ ConfigDescData[CONFIG_DESC_TYPE] = TYPE_OTHER_SPEED;
++ Other_Speed_Payload_Size =
++ EP_MAX_PACKET_SIZE_HS + EP_MAX_PACKET_SIZE_FS - g_EP_PAYLOAD_SIZE[EP1];
++ ConfigDescData[CONFIG_EP1_SIZE_LOW] =
++ (unsigned char) (Other_Speed_Payload_Size & MASK_UINT16_LOWER_8BIT);
++ ConfigDescData[CONFIG_EP1_SIZE_HIGH] =
++ (unsigned char) (Other_Speed_Payload_Size >> SHIFT_8BIT);
++
++ Other_Speed_Payload_Size =
++ EP_MAX_PACKET_SIZE_HS + EP_MAX_PACKET_SIZE_FS - g_EP_PAYLOAD_SIZE[EP2];
++ ConfigDescData[CONFIG_EP2_SIZE_LOW] =
++ (unsigned char) (Other_Speed_Payload_Size & MASK_UINT16_LOWER_8BIT);
++ ConfigDescData[CONFIG_EP2_SIZE_HIGH] =
++ (unsigned char) (Other_Speed_Payload_Size >> SHIFT_8BIT);
++
++ g_Expected_Length = config->wTotalLength;
++ g_Start_Address = (unsigned long int) config;
++
++ if( g_wLength <= g_Expected_Length ){
++ g_Remain_TotalLength = g_wLength;
++ }
++ else{
++ g_Remain_TotalLength = g_Expected_Length;
++ }
++
++ EP0_FIFO_Write();
++ }
++
++ break;
++
++ default:
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ return 0;
++ /* FALL THROUGH */
++ }
++
++ /* STATUS NAK Interrupt DISABLE. */
++ UDC2_Reg_Read(UD2INT_OFFSET, &interrupt_status);
++ interrupt_status &= 0x00ff;
++ interrupt_status |= STATUS_NAK_D;
++ UDC2_Reg_Write(UD2INT_OFFSET, interrupt_status);
++ }
++
++ return 1;
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Bulk_Out
++ *--------------------------------------------------------------------
++ * DESCRIPTION : Mass Storage Class Bulk-Out Process @ EP2
++ *
++ * PARAMETER :
++ *
++ * RETURN VALUE :
++ *
++ * Comment : Called by USB_Int_EPx interrupt routine
++ *********************************************************************
++ */
++static void USB_Bulk_Out(void)
++{
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ if( ( g_USB_Bulk_Out_Mode != BULKOUTMODE_DMA) && ( g_USB_Rbuf_Status == RRBST_NORMAL) ){
++ USB_Bulk_Out_Start();
++ }
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Bulk_In
++ *--------------------------------------------------------------------
++ * DESCRIPTION : Mass Storage Class Bulk-In Process @ EP1
++ *
++ * PARAMETER :
++ *
++ * RETURN VALUE :
++ *
++ * Comment : Called by USB_Int_EPx interrupt routine
++ *********************************************************************
++ */
++static void USB_Bulk_In(void)
++{
++ unsigned char* buff; /* æ²æ£å¶å¢å¼å½åååå */
++ unsigned short int epsize; /* EPæ²æ£å£æ»å¨ä¹åæ¿ */
++ unsigned long int reg_data;
++ struct tmpa910_udc *udc = &controller;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ if( g_DMA_Send_Length > 0 ){
++ /*--------------------------*/
++ /* DMAæ®æ²å¿¬æºå åå¢å */
++ /*--------------------------*/
++ reg_data = tmpa910_udp_read(udc, UD2AB_INTSTS_OFFSET);
++ if( (reg_data&INT_MR_AHBERR ) == INT_MR_AHBERR){
++ tmpa910_udp_write(udc, UD2AB_UDMSTSET_OFFSET, UDC2AB_MR_RESET); /* å
ååä¹åä¹åªååå¢å© */
++ }
++ else {
++ g_USB_Bulk_In_Mode = BULKINMODE_DMA;
++ epsize = USB_Send_Length_Chk(g_DMA_Send_Length);
++ g_DMA_Send_Length -= epsize;
++// epsize = g_DMA_Send_Length;
++
++ buff = g_DMA_Send_Buff_Address; /* æ²æ£å¨ä¹å奿æºæåªåº¢æ¼ */
++ g_DMA_Send_Buff_Address += epsize;
++
++ tmpa910_udp_write(udc, UD2AB_MRSADR_OFFSET, (unsigned long int) buff);
++ tmpa910_udp_write(udc, UD2AB_MREADR_OFFSET, (unsigned long int) (buff + epsize-1));
++ tmpa910_udp_write(udc, UD2AB_UDMSTSET_OFFSET, UDC2AB_MR_ENABLE);/* DMAæ®æ²å¥å· */
++ }
++ }
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Send_Length_Chk
++ *--------------------------------------------------------------------
++ * DESCRIPTION : Check DMA sending data size according to EP payload
++ *
++ * PARAMETER : Length -- Current sent data length
++ *
++ * RETURN VALUE : size -- Data length to be allowed to send at EP
++ *
++ * Comment : Called by USB_Int_EPx interrupt routine
++ *********************************************************************
++ */
++static unsigned short int USB_Send_Length_Chk(const unsigned long int Length)
++{
++ unsigned short int size;
++
++ if( Length > 0 ){
++ if( Length > g_EP_PAYLOAD_SIZE[EP1] ){
++ size = g_EP_PAYLOAD_SIZE[EP1];
++ }
++ else{
++ size = (unsigned short int) Length;
++ }
++ }
++ else{
++ size = 0;
++ }
++ return size;
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Recv_Length_Chk
++ *--------------------------------------------------------------------
++ * DESCRIPTION : Check DMA receiving data size according to EP payload
++ *
++ * PARAMETER :
++ *
++ * RETURN VALUE : size -- Data length to be allowed to receive at EP
++ *
++ * Comment : Called by USB_Int_EPx interrupt routine
++ *********************************************************************
++ */
++static unsigned short int USB_Recv_Length_Chk(void)
++{
++ unsigned short int data_size;
++ unsigned short int size;
++
++ UDC2_Reg_Read(UD2EP2_DataSize_OFFSET, &data_size);
++
++ data_size &= UD2EP_DATASIZE_MASK;
++ if( data_size > 0 ){
++ if( data_size > g_EP_PAYLOAD_SIZE[EP2] ){
++ size = g_EP_PAYLOAD_SIZE[EP2];
++ }
++ else{
++ size = data_size;
++ }
++ }
++ else{
++ size = 0;
++ }
++ return size;
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Bulk_Out_Start
++ *--------------------------------------------------------------------
++ * DESCRIPTION : Start the current Bulk-Out course @ EP2
++ *
++ * PARAMETER :
++ *
++ * RETURN VALUE :
++ *
++ * Comment :
++ *********************************************************************
++ */
++static void USB_Bulk_Out_Start(void)
++{
++ unsigned char *buff; /* 庴æ£å¶å¢å¼å½åååå */
++ unsigned short int epsize; /* EP庴æ£å¨ä¹åæ¿ */
++ unsigned long int reg_data;
++ struct tmpa910_udc *udc = &controller;
++
++ /*--------------------------*/
++ /* å¨ä¹ååºæ¡³æåªå åå¢å */
++ /*--------------------------*/
++ epsize = USB_Recv_Length_Chk();
++
++ /* 庴æ£å¨ä¹ååå */
++ if( epsize > 0 ){
++ /* å¶ååå¾åå©åä¹åªåµDMAåªææ */
++ g_USB_Bulk_Out_Mode = BULKOUTMODE_DMA;
++
++ /*--------------------------*/
++ /* DMAæ®æ²ååååªå¯åå */
++ /*--------------------------*/
++ if( g_DMA_Recv_Length < epsize ){
++ g_DMA_Recv_Length = 0;
++ }
++ else{
++ g_DMA_Recv_Length -= epsize;
++ }
++
++
++ /*--------------------------*/
++ /* DMAæ®æ²å¿¬æºå åå¢å */
++ /*--------------------------*/
++ reg_data = tmpa910_udp_read(udc, UD2AB_INTSTS_OFFSET);
++ if( ((reg_data&INT_MW_AHBERR ) == INT_MW_AHBERR) || ((reg_data&INT_MW_RD_ERR ) == INT_MW_RD_ERR) ){
++ tmpa910_udp_write(udc, UD2AB_UDMSTSET_OFFSET, UDC2AB_MW_RESET);
++ }
++ else {
++ /*--------------------------------------*/
++ /* FIFOåå庴æ£å¶å¢å¼å½åDMAæ®æ²åªå³´å */
++ /*--------------------------------------*/
++ buff = g_DMA_Recv_Buff_Address; /* 庴æ£å¨ä¹åå½åå´¬åæåªåº¢æ¼ */
++ g_Bulk_Out_EP_Size = epsize; /* 庴æ£å¨ä¹åæ¿åªææ */
++ tmpa910_udp_write(udc, UD2AB_MWSADR_OFFSET, (unsigned long int)buff);
++ tmpa910_udp_write(udc, UD2AB_MWEADR_OFFSET,(unsigned long int)(buff + g_Bulk_Out_EP_Size-1));
++ //UD2AB_MWTOUT = 0xC9; /* DMA transfer timeout setting: CLK_U*200ns */
++ tmpa910_udp_write(udc, UD2AB_UDMSTSET_OFFSET, UDC2AB_MW_ENABLE); /* DMAæ®æ²å¥å· */
++ }
++ }
++ else{
++ /* åµæä¸USBåºåº´æ£å¦±å´¬åå±å¨å¸å¡å */
++ g_USB_Bulk_Out_Mode = BULKOUTMODE_USB;
++ }
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : EP0_FIFO_Read
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : EP0åååºå¨ä¹å庢æ¼å¼µæ£
++ *
++ *********************************************************************
++ */
++static void EP0_FIFO_Read(void)
++{
++ unsigned short int PacketSize;
++ unsigned char* data_p;
++ unsigned short int length;
++ unsigned short int interrupt_status;
++ unsigned short int* iaddress;
++
++ data_p = NULL;
++
++ if( g_Remain_TotalLength > g_EP_PAYLOAD_SIZE[EP0] ){ /* judgement of Remain TotalLength */
++ length = g_EP_PAYLOAD_SIZE[EP0];
++ iaddress = (unsigned short int *)g_Start_Address;
++
++ /* STATUS NAK Interrupt Enable. */
++ UDC2_Reg_Read(UD2INT_OFFSET, &interrupt_status);
++ interrupt_status &= STATUS_NAK_E;
++ UDC2_Reg_Write(UD2INT_OFFSET, interrupt_status);
++
++ DBG("0x");
++ while( length > 0 ){ /* write transmit data to endpoint0's Fifo */
++ UDC2_Reg_Read(UD2EP0_FIFO_OFFSET, iaddress);
++ DBG("%02x %02x ", *((unsigned char*)iaddress), *((unsigned char*)iaddress+1));
++ iaddress++;
++ length -= WORD_SIZE;
++ }
++ DBG("\n");
++
++ g_Remain_TotalLength -= g_EP_PAYLOAD_SIZE[EP0]; /*increment of Remain TotalLength */
++ g_Start_Address = (unsigned long int) iaddress; /* increment of g_Start_Address */
++ }
++ else{
++ length = g_Remain_TotalLength;
++ iaddress = (unsigned short int *)g_Start_Address;
++
++ DBG("0x");
++ while( length != 0 ){ /* read data from endpoint0's Fifo */
++ if( length == 1 ){
++ UDC2_Reg_Read(UD2EP0_MaxPacketSize_OFFSET, &PacketSize);
++ UDC2_Reg_Write(UD2EP0_MaxPacketSize_OFFSET, 1); /* process of EOP */
++
++ DBG("Function: %s, Line: %d, g_Remain_TotalLength: %d\n",
++ __FUNCTION__, __LINE__, g_Remain_TotalLength);
++ UDC2_Reg_Read(UD2EP0_FIFO_OFFSET, iaddress);
++ *data_p = (unsigned char)*iaddress;
++ length = 0;
++
++ DBG("%02x %02x ", *((unsigned char*)iaddress), *((unsigned char*)iaddress+1));
++
++ UDC2_Reg_Write(UD2EP0_MaxPacketSize_OFFSET, PacketSize);/* process of EOP */
++
++ }
++ else{
++ UDC2_Reg_Read(UD2EP0_FIFO_OFFSET, iaddress);
++ DBG("%02x %02x ", *((unsigned char*)iaddress), *((unsigned char*)iaddress+1));
++ iaddress++;
++ length -=WORD_SIZE;
++ }
++ }
++ DBG("\n");
++
++ g_USB_Stage = STATUS_STAGE; /* shift of Stage to STATUS_STAGE */
++
++ /* STATUS NAK Interrupt Disable. */
++ UDC2_Reg_Read(UD2INT_OFFSET, &interrupt_status);
++ interrupt_status |= STATUS_NAK_D;
++ UDC2_Reg_Write(UD2INT_OFFSET, interrupt_status);
++ }
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : EP0_FIFO_Write
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : status
++ * DESCRIPTION : EP0ååºå¨ä¹åæ²æ£å¼µæ£
++ *
++ *********************************************************************
++ */
++static void EP0_FIFO_Write(void)
++{
++ unsigned short int length;
++ unsigned short int interrupt_status;
++ unsigned char chardata;
++ unsigned short int* iaddress; /* 2byte Write data to EP0 FIFO */
++ unsigned short int PacketSize;
++
++ DBG("EP0_FIFO_Write\n");
++ if( g_Remain_TotalLength > g_EP_PAYLOAD_SIZE[EP0] ){ /* judgement of Remain TotalLength */
++ iaddress = (unsigned short int*)g_Start_Address;
++
++ /* STATUS NAK Interrupt Enable. */
++ UDC2_Reg_Read(UD2INT_OFFSET, &interrupt_status);
++ interrupt_status &= STATUS_NAK_E;
++ UDC2_Reg_Write(UD2INT_OFFSET, interrupt_status);
++
++ length = g_EP_PAYLOAD_SIZE[EP0];
++ DBG("%s: Int-Status: 0x%x; length:%d; RemainLen: %d; StartAddr:0x%lx\n",
++ __FUNCTION__, interrupt_status, length, g_Remain_TotalLength, g_Start_Address);
++
++ DBG("0x");
++ while( length > 0 ){ /* write transmit data to endpoint0's Fifo */
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, *iaddress);
++ DBG("%02x %02x ", *((unsigned char*)iaddress), *((unsigned char*)iaddress+1));
++ iaddress++;
++ length -= WORD_SIZE;
++ }
++ DBG("\n");
++
++ g_Remain_TotalLength -= g_EP_PAYLOAD_SIZE[EP0]; /* increment of RemainTotalLength */
++ g_Start_Address = (unsigned long int) iaddress; /* increment of g_Start_Address */
++ }
++ else{
++ length = g_Remain_TotalLength;
++ iaddress = (unsigned short int *)g_Start_Address;
++ DBG("0x");
++ while( length != 0 ){ /* write transmit data to endpoint0's Fifo */
++ if( length == 1 ){
++ UDC2_Reg_Read(UD2EP0_MaxPacketSize_OFFSET, &PacketSize);
++ UDC2_Reg_Write(UD2EP0_MaxPacketSize_OFFSET, 1); /* process of EOP */
++
++ chardata = (unsigned char) (*iaddress & MASK_UINT16_LOWER_8BIT);
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, (unsigned long int)chardata);
++ length = 0;
++
++ DBG("%02x ", chardata);
++ UDC2_Reg_Write(UD2EP0_MaxPacketSize_OFFSET, PacketSize); /* process of EOP */
++
++ }
++ else{
++ UDC2_Reg_Write(UD2EP0_FIFO_OFFSET, *iaddress);
++ DBG("%02x %02x ", *((unsigned char*)iaddress), *((unsigned char*)iaddress+1));
++ iaddress++;
++ length -= WORD_SIZE;
++ }
++ }
++ DBG("\n");
++
++ g_USB_Stage = STATUS_STAGE; /* shift of Stage to STATUS_STAGE */
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP0_EOP); /* process of EOP */
++
++ /* STATUS NAK Interrupt Disable. */
++ UDC2_Reg_Read(UD2INT_OFFSET, &interrupt_status);
++ interrupt_status |= STATUS_NAK_E;
++ UDC2_Reg_Write(UD2INT_OFFSET, interrupt_status);
++
++ }
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : UDC2_Reg_Read
++ *--------------------------------------------------------------------
++ * PARAMETER : ReqAddr:ååååå¾åªååä¸Data_p:å¨ä¹å奿æºæåååå
++ * RETURN VALUE : å´å
++ * DESCRIPTION : UDC2åååååååºå¨ä¹ååä¹åª
++ *
++ *********************************************************************
++ */
++static void UDC2_Reg_Read(const unsigned long int reqaddr, unsigned short int* data_p)
++{
++ unsigned long int read_addr;
++ unsigned long int reg_data;
++ struct tmpa910_udc *udc;
++
++ udc = &controller;
++ read_addr = (reqaddr & UDC2AB_READ_ADDRESS) | UDC2AB_READ_RQ;
++ tmpa910_udp_write(udc, UD2AB_UDC2RDREQ_OFFSET, read_addr);
++ ndelay(1);
++
++ do{
++ reg_data = tmpa910_udp_read(udc, UD2AB_UDC2RDREQ_OFFSET);
++ ndelay(1);
++ }while( (reg_data & UDC2AB_READ_RQ) == UDC2AB_READ_RQ );
++
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, INT_UDC2REG_RD);
++ ndelay(1);
++
++ reg_data = tmpa910_udp_read(udc, UD2AB_UDC2RDVL_OFFSET);
++ *data_p = (unsigned short int) (reg_data & MASK_UINT32_LOWER_16BIT);
++ ndelay(1);
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : UDC2_Reg_Write
++ *--------------------------------------------------------------------
++ * PARAMETER : ReqAddr:ååååå¾åªååä¸Data:å¨ä¹å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : UDC2ååååååºå¨ä¹ååä¹åª
++ * (UDC2å¾ååååªæ§å¸µæåµæåª)
++ *********************************************************************
++ */
++static void UDC2_Reg_Write(const unsigned long int reqAddr, const unsigned short int data)
++{
++ unsigned long int reg_data;
++ struct tmpa910_udc *udc;
++
++ udc = &controller;
++ reg_data = (unsigned long int) data;
++ ndelay(1);
++
++ tmpa910_udp_write(udc, reqAddr, reg_data);
++ ndelay(1);
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : MemcpyToRecvBufWithRewind
++ *--------------------------------------------------------------------
++ * PARAMETER : prbf_wpt -- Pointer to the write pointer of receive buffer
++ * psrc -- Pointer to the source data to be copied
++ * cnt -- Length of source data
++ * RETURN VALUE :
++ * DESCRIPTION : memory copy operation with rewind to target buffer
++ *
++ *********************************************************************
++ */
++static void MemcpyToRecvBufWithRewind(void **prbf_wpt, const void *psrc, unsigned long int cnt)
++{
++ unsigned long int a, b, delta1, delta2, p;
++
++ p = (unsigned long int) *prbf_wpt;
++ a = (unsigned long int) (p+cnt);
++ b = (unsigned long int) g_USB_Recv_Rbuf + sizeof( g_USB_Recv_Rbuf);
++
++ if( a >= b ){
++ //If rewind to start of receive buffer, just divide the source data into two parts
++ delta1 = b - (unsigned long int)*prbf_wpt;
++ delta2 = a - b;
++
++ //Copy source data from current write point to the end of receive buffer
++ memcpy((void*)*prbf_wpt, psrc, delta1);
++
++ //Copy remaining source data to receive buffer rewinding from beginning of receive buffer
++ memcpy((void*)g_USB_Recv_Rbuf, (void*)((unsigned long int)psrc + delta1), delta2);
++
++ //Modify the write pointer of receive buffer
++ *prbf_wpt = g_USB_Recv_Rbuf + a - b;
++ }
++ else {
++ //Totally copy source data to target receive buffer with no need of rewinding
++ memcpy(*prbf_wpt, psrc, cnt);
++
++ //Modify the write pointer of receive buffer
++ p += cnt;
++ *prbf_wpt = (void *)p;
++ }
++}
++
++/*
++ *********************************************************************
++ * NAME : MemcpyFromRecvBufWithRewind
++ *--------------------------------------------------------------------
++ * PARAMETER : pdest -- Pointer to the destination data
++ * prbf_rpt -- Pointer to the read pointer of receive buffer
++ * cnt -- Length of source data
++ * RETURN VALUE :
++ * DESCRIPTION : memory copy operation with rewind from target buffer
++ *
++ *********************************************************************
++ */
++#if 0
++static void MemcpyFromRecvBufWithRewind(void *pdest, const void **prbf_rpt, unsigned long int cnt)
++{
++ unsigned long int a, b, delta1, delta2, p;
++
++ p = (unsigned long int) *prbf_rpt;
++ a = (unsigned long int) (p+cnt);
++ b = (unsigned long int) g_USB_Recv_Rbuf + sizeof( g_USB_Recv_Rbuf);
++
++ if( a >= b ){
++ //If rewind to start of receive buffer, just divide the source data into two parts
++ delta1 = b - (unsigned long int)*prbf_rpt;
++ delta2 = a - b;
++
++ //Copy source data from current read point to the end of receive buffer
++ memcpy((void*)pdest, *prbf_rpt, delta1);
++
++ //Copy remaining source data to receive buffer rewinding from beginning of receive buffer
++ memcpy((void*)((unsigned long int)pdest + delta1), (void*)g_USB_Recv_Rbuf, delta2);
++
++ //Modify the read pointer of receive buffer
++ *prbf_rpt = g_USB_Recv_Rbuf + a - b;
++ }
++ else {
++ //Totally copy source data to target receive buffer with no need of rewinding
++ memcpy(pdest, *prbf_rpt, cnt);
++
++ //Modify the read pointer of receive buffer
++ p += cnt;
++ *prbf_rpt = (void *)p;
++ }
++}
++#endif
++
++/*
++ *********************************************************************
++ * NAME : Rbuf_Stchk
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE :
++ * DESCRIPTION : åååå¶å¢å¼å½åºå¨ä¹å庴æ£åå¥ä¹åååªå¦æ£
++ *
++ *********************************************************************
++ */
++static unsigned char Rbuf_Stchk(void)
++{
++ unsigned long int w1;
++ unsigned long int w2;
++ unsigned long int bt;
++ unsigned long int bs;
++
++ w1 = (unsigned long int) g_Recv_Rbuf_Rpt;
++ w2 = (unsigned long int) g_Recv_Rbuf_Wpt;
++ if( w1 == w2){
++ return RRBST_NORMAL;
++ }
++ else{
++ if( w1 > w2 ){
++ w1 = w1 - w2 -1;
++ }
++ else{
++ bt = (unsigned long int) g_USB_Recv_Rbuf;
++ bs = sizeof( g_USB_Recv_Rbuf);
++ w1 = ( (bt + bs) - w2) + (w1 - bt - 1);
++ }
++
++ if( w1 > g_EP_PAYLOAD_SIZE[EP2]){
++ return RRBST_NORMAL;
++ }
++ else{
++ return RRBST_FULL;
++ }
++ }
++
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Ctl_Init
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : æªæ¹ææ¢å¼¶å©å£
++ *
++ *********************************************************************
++ */
++static void USB_Ctl_Init(void)
++{
++ /*------------------------------*/
++ /* Stamdard Class initialize */
++ /*------------------------------*/
++ g_Current_State = DEFAULT;
++ g_Current_Config = USB_INIT;
++ g_Current_Interface = USB_INIT;
++ g_Current_Alternate = USB_INIT;
++ g_Buf_Current_Config = USB_INIT;
++ g_Buf_Current_Interface = USB_INIT;
++ g_Buf_Current_Alternate = USB_INIT;
++
++ g_USB_Stage = IDLE_STAGE;
++ g_EP_PAYLOAD_SIZE[EP0] = EP_MAX_PACKET_SIZE_FS ;
++ g_EP_PAYLOAD_SIZE[EP1] = EP_MAX_PACKET_SIZE_HS ;
++ g_EP_PAYLOAD_SIZE[EP2] = EP_MAX_PACKET_SIZE_HS ;
++
++ /*------------------------------*/
++ /* Vender Class initialize */
++ /*------------------------------*/
++ g_DMA_Recv_Buff_Address = (unsigned char *)g_USB_Recv_Buf;
++ g_Recv_Rbuf_Wpt = g_USB_Recv_Rbuf;
++ g_Recv_Rbuf_Rpt = g_USB_Recv_Rbuf;
++ g_USB_Rbuf_Status = RRBST_NORMAL; /* Normal status Set */
++ g_USB_Status = USB_STS_IDOL; /* USBåªååå¶å¿¬æºåªå¼¶å©å£ */
++ g_USB_Stage_Error = STAGE_NORMAL; /* åå¥ä¹åååä¹å¼åå弶å©å£ */
++ g_DMA_Recv_Length = 0; /* å·åº´æ£å¨ä¹å弶å©å£ */
++ g_DMA_Send_Length = 0; /* å·æ²æ£å¨ä¹å弶å©å£ */
++ g_Num_StringDesc = STRING_DESC_INIT; /* string descriptoræ¢å¼¶å©å£ */
++
++ return;
++
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_Setup
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : SETUPåå¥ä¹åå»æ¤åº´æ£å¦±åå´¬å
++ *
++ *********************************************************************
++ */
++static void USB_Int_Setup(void)
++{
++ short int status;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ UDC2_Reg_Write(UD2INT_OFFSET, INT_SETUP_CLEAR);
++
++ if( g_USB_Stage == IDLE_STAGE ){
++ g_USB_Stage = SETUP_STAGE; /* g_STAGE : IDLE -> SETUP */
++ }
++ /* DO NOTHING */
++
++ status = USB_Receive_Request();
++ if( status == 0 ){
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP0_STALL); /* EP0 STALL */
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP1_STALL); /* EP1 STALL */
++ UDC2_Reg_Write(UD2CMD_OFFSET, EP2_STALL); /* EP2 STALL */
++ }
++ /* DO NOTHING */
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_Rx_Zero
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : 0å¶åå©å¨ä¹å庴æ£å¦±åå´¬å
++ *
++ *********************************************************************
++ */
++static void USB_Int_Rx_Zero(void)
++{
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ UDC2_Reg_Write(UD2INT_OFFSET, INT_DATA_CLEAR);
++ if( g_USB_Stage == DATA_STAGE ){
++
++ if( fDirection == GET ){
++ EP0_FIFO_Write();
++ }
++ else{
++ EP0_FIFO_Read();
++ }
++ }
++ /* DO NOTHING */
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_Status
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : åå¥ä¹åååå¥ä¹åå»æ¤åº´æ£å¦±åå´¬å
++ *
++ *********************************************************************
++ */
++static void USB_Int_Status(void)
++{
++ unsigned short int interrupt_status;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ UDC2_Reg_Write(UD2INT_OFFSET, INT_STATUS_CLEAR);
++
++ if( g_USB_Stage == STATUS_STAGE ){
++ /* STATUS NAK Interrupt Enable. */
++ UDC2_Reg_Read(UD2INT_OFFSET, &interrupt_status);
++ interrupt_status |= INT_STATUSNAK_MASK;
++ UDC2_Reg_Write(UD2INT_OFFSET, interrupt_status);
++
++ if( (g_bRequest == RQ_SET_CONFIGURATION ) || (g_bRequest == RQ_SET_ADDRESS) ){
++ g_Current_State = g_Buf_Current_State; /* increment of state */
++ g_Current_State |= g_USB_Address;
++ UDC2_Reg_Write(UD2ADR_OFFSET, g_Current_State);
++ }
++ /* DO NOTHING */
++
++ g_Current_Config = g_Buf_Current_Config;
++ g_Current_Interface = g_Buf_Current_Interface;
++ g_Current_Alternate = g_Buf_Current_Alternate;
++ g_USB_Stage = IDLE_STAGE; /* Stage Information initialyze. */
++ }
++
++ return;
++
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_Status_NAK
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : STATUS NAK庴æ£å¦±åå´¬å
++ *
++ *********************************************************************
++ */
++static void USB_Int_Status_NAK(void)
++{
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ UDC2_Reg_Write(UD2INT_OFFSET, INT_STATUSNAK_CLEAR);
++ UDC2_Reg_Write(UD2CMD_OFFSET, SETUP_FIN);
++
++ return;
++
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_EP0
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : EP0å¨ä¹åæ²åº´æ£å¦±åå´¬å
++ *
++ *********************************************************************
++ */
++static void USB_Int_EP0(void)
++{
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ UDC2_Reg_Write(UD2INT_OFFSET, INT_EP0_CLEAR);
++
++ if( fDirection == GET ){ /*Write */
++ EP0_FIFO_Write();
++ }
++ else{ /*Read */
++ EP0_FIFO_Read();
++ }
++
++ return;
++
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_EPx
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : EP0&1å¨ä¹å庴æ£å¦±åå´¬å
++ *
++ *********************************************************************
++ */
++static void USB_Int_EPx(void)
++{
++ unsigned short int EP1_RegData;
++ unsigned short int EP2_RegData;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ UDC2_Reg_Write(UD2INT_OFFSET, INT_EP_CLEAR);
++
++ UDC2_Reg_Read(UD2EP1_MaxPacketSize_OFFSET, &EP1_RegData);
++ UDC2_Reg_Read(UD2EP2_MaxPacketSize_OFFSET, &EP2_RegData);
++
++ if( (EP1_RegData & UD2EP_DSET) == UD2EP_DSET ){ /*dset? */
++ USB_Bulk_In();
++// usb_bulkin();
++ }
++ /* DO NOTHING */
++
++ if( (EP2_RegData & UD2EP_DSET) == UD2EP_DSET ){ /*dset? */
++ USB_Bulk_Out();
++// usb_bulkout();
++ }
++ /* DO NOTHING */
++
++
++ return;
++
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_SOF
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : SOFå·åå¢å©åº´æ£å¦±åå´¬å
++ *
++ *********************************************************************
++ */
++static void USB_Int_SOF(void)
++{
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ UDC2_Reg_Write(UD2INT_OFFSET, INT_SOF_CLEAR);
++
++ return;
++
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_Supend_Resume
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : SUSPEND RESUME妱åå´¬å庴æ£å¼µæ£
++ *
++ *********************************************************************
++ */
++static void USB_Int_Supend_Resume(void)
++{
++ struct tmpa910_udc *udc = &controller;
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, INT_SUSPEND);
++ g_USB_Status = USB_STS_SUSPEND; /* 忬æºåªåååååªæåµæ
å */
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_USB_Reset_End
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : ååå¢å©å»æ¤å¦±åå´¬å庴æ£
++ *
++ *********************************************************************
++ */
++static void USB_Int_USB_Reset_End(void)
++{
++ unsigned short int state;
++ struct tmpa910_udc *udc = &controller;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, INT_RESET_END);
++
++ UDC2_Reg_Read(UD2ADR_OFFSET, &state);
++ state &= CURRENT_SPEED_CHECK; /* Current_Speed check*/
++ UDC2_Reg_Write(UD2INT_OFFSET, UDC2_INT_MASK); /*INT EPx MASK & Refresh; */
++
++ if( state == HIGH_SPEED ){
++ g_EP_PAYLOAD_SIZE[EP1] = EP_MAX_PACKET_SIZE_HS ; /* Payload Size = 512byte(HIGH SPEED) */
++ g_EP_PAYLOAD_SIZE[EP2] = EP_MAX_PACKET_SIZE_HS ; /* Payload Size = 512byte(HIGH SPEED) */
++ }
++ else{
++ g_EP_PAYLOAD_SIZE[EP1] = EP_MAX_PACKET_SIZE_FS ; /* Payload Size = 64byte(FULL SPEED) */
++ g_EP_PAYLOAD_SIZE[EP2] = EP_MAX_PACKET_SIZE_FS ; /* Payload Size = 64byte(FULL SPEED) */
++ }
++
++ g_USB_Rbuf_Status = 0;
++ g_USB_Bulk_Out_Mode = 0;
++ g_Recv_Rbuf_Wpt = g_USB_Recv_Rbuf;
++ g_Recv_Rbuf_Rpt = g_USB_Recv_Rbuf;
++
++ tmpa910_udp_write(udc, UD2AB_UDMSTSET_OFFSET, UDC2AB_MR_RESET | UDC2AB_MW_RESET);
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_USB_Reset
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : ååå¢å©å»æ¤å¦±åå´¬å庴æ£
++ *
++ *********************************************************************
++ */
++static void USB_Int_USB_Reset(void)
++{
++ struct tmpa910_udc *udc = &controller;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, INT_RESET);
++
++ return;
++}
++
++/*
++ *********************************************************************
++ * NAME : USB_Int_MR_End
++ *--------------------------------------------------------------------
++ * PARAMETER : å´å
++ * RETURN VALUE : å´å
++ * DESCRIPTION : å
ååä¹åä¹åªæ®æ²å»æ¤å¦±åå´¬å
++ *
++ *********************************************************************
++ */
++static void USB_Int_MR_End(void)
++{
++ struct tmpa910_udc *udc = &controller;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, INT_MR_END_ADD);
++
++ if( g_USB_Bulk_In_Mode == BULKINMODE_DMA ){
++ /* USBåºæ²æ£å£æ»å¦±å´¬åå¨å¸ */
++ if(g_DMA_Send_Length == 0) {
++ g_USB_Bulk_In_Mode = BULKINMODE_USB;
++
++ //Trigger next phase data transfer
++// usb_bulkin_mass_storage();
++ }
++ else{
++ //Continue next phase bulk-in transfer
++ USB_Bulk_In();
++ }
++ }
++
++ return;
++}
++
++static void USB_Int_MW_End(void)
++{
++ unsigned long int intsts;
++ struct tmpa910_udc *udc = &controller;
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, INT_MW_END_ADD);
++
++ //Optimize the speed using memcpy instead of "for" loop
++ MemcpyToRecvBufWithRewind((void **)&g_Recv_Rbuf_Wpt, (void *)g_USB_Recv_Buf, (unsigned long int)g_Bulk_Out_EP_Size);
++
++ g_USB_Rbuf_Status = Rbuf_Stchk();
++
++ //Check for last write error
++ intsts = tmpa910_udp_read(udc, UD2AB_INTSTS_OFFSET);
++ if( ( intsts & INT_MW_AHBERR ) == INT_MW_AHBERR ){
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, INT_MW_AHBERR);
++ tmpa910_udp_write(udc, UD2AB_UDMSTSET_OFFSET, UDC2AB_MW_RESET);
++ return;
++ }
++ if( (intsts&INT_MW_RD_ERR ) == INT_MW_RD_ERR ){
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, INT_MW_RD_ERR);
++ tmpa910_udp_write(udc, UD2AB_UDMSTSET_OFFSET, UDC2AB_MW_RESET);
++ return;
++ }
++
++ if( g_USB_Rbuf_Status == RRBST_NORMAL ){
++
++ //Here we've got the data and then begin bulk-out packet analysis
++// usb_bulkout_mass_storage();
++
++ //Trigger next phase data transfer
++ USB_Bulk_Out_Start();
++ }
++
++ return;
++}
++
++static inline void create_debug_file(struct tmpa910_udc *udc) {}
++static inline void remove_debug_file(struct tmpa910_udc *udc) {}
++
++/* reinit == restore inital software state */
++static void udc_reinit(struct tmpa910_udc *udc)
++{
++ u32 i;
++
++ INIT_LIST_HEAD(&udc->gadget.ep_list);
++ INIT_LIST_HEAD(&udc->gadget.ep0->ep_list);
++
++ for (i = 0; i < NUM_ENDPOINTS; i++) {
++ struct tmpa910_ep *ep = &udc->ep[i];
++
++ if (i != 0)
++ list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
++
++ ep->desc = NULL;
++ ep->stopped = 0;
++ ep->fifo_bank = 0;
++ ep->ep.maxpacket = ep->maxpacket;
++ ep->creg = (void __iomem *) udc->udp_baseaddr + 0x230 + 0x10*i + 0x00C;
++
++ // initialiser une queue par endpoint
++ INIT_LIST_HEAD(&ep->queue);
++ }
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++}
++
++static irqreturn_t tmpa910_udc_irq (int irq, void *_udc)
++{
++ struct tmpa910_udc *udc = &controller;
++ g_Interrupt_Stasus = tmpa910_udp_read(udc, UD2AB_INTSTS_OFFSET); /* read UDC Interrupt Register. */
++
++ /* Select Interrupt Process. */
++ if( ( g_Interrupt_Stasus & INT_SETUP ) == INT_SETUP ){
++ USB_Int_Setup();
++ }
++ else if( ( g_Interrupt_Stasus & INT_DATA ) == INT_DATA ){
++ USB_Int_Rx_Zero();
++ }
++ else if( ( g_Interrupt_Stasus & INT_STATUS ) == INT_STATUS ){
++ USB_Int_Status();
++ }
++ else if( ( g_Interrupt_Stasus & INT_STATUSNAK ) == INT_STATUSNAK ){
++ USB_Int_Status_NAK();
++ }
++ else if( ( g_Interrupt_Stasus & INT_EP0 ) == INT_EP0 ){
++ USB_Int_EP0();
++ }
++ else if( ( g_Interrupt_Stasus & INT_EP ) == INT_EP ){
++ USB_Int_EPx();
++ }
++ else if( ( g_Interrupt_Stasus & INT_SOF ) == INT_SOF ){
++ USB_Int_SOF();
++ }
++ else if( ( g_Interrupt_Stasus & INT_SUSPEND ) == INT_SUSPEND ){
++ USB_Int_Supend_Resume();
++ }
++ else if( ( g_Interrupt_Stasus & INT_RESET ) == INT_RESET ){
++ USB_Int_USB_Reset();
++ }
++ else if( ( g_Interrupt_Stasus & INT_RESET_END ) == INT_RESET_END ){
++ USB_Int_USB_Reset_End();
++ }
++ else if( ( g_Interrupt_Stasus & INT_MW_END_ADD ) == INT_MW_END_ADD ){
++ USB_Int_MW_End();
++ }
++ else if( ( g_Interrupt_Stasus & INT_MR_END_ADD ) == INT_MR_END_ADD ){
++ USB_Int_MR_End();
++ }
++ else {
++ DBG("In UDC irq, unexpected irq occured!\n");
++ }
++
++ if( ( g_Interrupt_Stasus & INT_MW_RD_ERR ) == INT_MW_RD_ERR ){
++ DBG("In UDC irq, master write or read error found!\n");
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, INT_MW_RD_ERR);
++ tmpa910_udp_write(udc, UD2AB_UDMSTSET_OFFSET, UDC2AB_MW_RESET);
++ }
++
++ // VICADDRESS = 0x1234567;
++
++ return IRQ_HANDLED;
++}
++
++/*-------------------------------------------------------------------------*/
++
++int usb_gadget_register_driver (struct usb_gadget_driver *driver)
++{
++ struct tmpa910_udc *udc;
++ int retval;
++
++ DBG("usb_gadget_register_driver");
++
++ udc = &controller;
++ if (!driver || driver->speed < USB_SPEED_FULL
++ || !driver->bind
++ || !driver->setup) {
++ DBG("bad parameter.\n");
++ return -EINVAL;
++ }
++
++ if (udc->driver) {
++ DBG("UDC already has a gadget driver\n");
++ return -EBUSY;
++ }
++
++ udc->driver = driver;
++ udc->gadget.dev.driver = &driver->driver;
++ dev_set_drvdata(&udc->gadget.dev, &driver->driver);
++ udc->enabled = 1;
++ udc->selfpowered = 1;
++
++ retval = driver->bind(&udc->gadget);
++ if (retval) {
++ DBG("driver->bind() returned %d\n", retval);
++ udc->driver = NULL;
++ udc->gadget.dev.driver = NULL;
++ dev_set_drvdata(&udc->gadget.dev, NULL);
++ udc->enabled = 0;
++ udc->selfpowered = 0;
++ return retval;
++ }
++
++ local_irq_disable();
++ //pullup(udc, 1);
++ local_irq_enable();
++
++ DBG("bound to %s\n", driver->driver.name);
++ return 0;
++}
++EXPORT_SYMBOL (usb_gadget_register_driver);
++
++int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
++{
++ struct tmpa910_udc *udc;
++
++ DBG("usb_gadget_unregister_driver");
++
++ udc = &controller;
++ if (!driver || driver != udc->driver || !driver->unbind)
++ return -EINVAL;
++
++ local_irq_disable();
++ udc->enabled = 0;
++// tmpa910_udp_write(udc, AT91_UDP_IDR, ~0);
++ //pullup(udc, 0);
++ local_irq_enable();
++
++ driver->unbind(&udc->gadget);
++ udc->driver = NULL;
++
++ DBG("unbound from %s\n", driver->driver.name);
++ return 0;
++}
++EXPORT_SYMBOL (usb_gadget_unregister_driver);
++
++/*-------------------------------------------------------------------------*/
++
++static void tmpa910udc_shutdown(struct platform_device *dev)
++{
++ DBG("tmpa910udc_shutdown");
++ //pullup(platform_get_drvdata(dev), 0);
++}
++
++static int __init tmpa910udc_probe(struct platform_device *pdev)
++{
++ unsigned long int reg_data;
++ struct device *dev;
++ struct tmpa910_udc *udc;
++ int retval;
++ struct resource *res;
++
++ printk("tmpa910udc_probe\n");
++
++
++ dev = &pdev->dev;
++
++ USB_Ctl_Init();
++
++ if (pdev->num_resources != 2) {
++ DBG("invalid num_resources");
++ return -ENODEV;
++ }
++ if ((pdev->resource[0].flags != IORESOURCE_MEM)
++ || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
++ DBG("invalid resource type");
++ return -ENODEV;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res)
++ return -ENXIO;
++
++ if (!request_mem_region(res->start,
++ res->end - res->start + 1,
++ driver_name)) {
++ DBG("someone's using UDC memory\n");
++ return -EBUSY;
++ }
++
++ /* init software state */
++ udc = &controller;
++ udc->gadget.dev.parent = dev;
++ udc->pdev = pdev;
++ udc->enabled = 0;
++
++ udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1);
++ if (!udc->udp_baseaddr) {
++ release_mem_region(res->start, res->end - res->start + 1);
++ return -ENOMEM;
++ }
++
++
++ printk("udp_baseaddr=0x%x / phy = 0x%x\n", (int) udc->udp_baseaddr, (int) res->start);
++
++ udc_reinit(udc);
++
++ retval = device_register(&udc->gadget.dev);
++ if (retval < 0)
++ goto fail0;
++
++#if 0
++ reg_data = SYSCR0;
++ reg_data &= 0x3f;
++ reg_data |= (1<<6); // [7:6]
++ SYSCR0 = reg_data; // USBCLKSEL = X1
++
++ CLKCR4 = USB_ENABLE; /* EN_USB */
++#endif
++ reg_data = tmpa910_udp_read(udc, UD2AB_PWCTL_OFFSET);
++ reg_data &= PWCTL_PHY_POWER_RESET_ON; // [5][1] <= 0
++ reg_data |= PWCTL_PHY_SUSPEND_ON; // [3] <= 1
++ tmpa910_udp_write(udc, UD2AB_PWCTL_OFFSET, reg_data);
++ mdelay(1);
++
++ reg_data = tmpa910_udp_read(udc, UD2AB_PWCTL_OFFSET);
++ reg_data |= PWCTL_PHY_RESET_OFF; // [5][3] <= 1
++ tmpa910_udp_write(udc, UD2AB_PWCTL_OFFSET, reg_data);
++ mdelay(1);
++
++ reg_data = tmpa910_udp_read(udc, UD2AB_PWCTL_OFFSET);
++ reg_data &= PWCTL_PHY_SUSPEND_OFF; // [3] <= 0
++ tmpa910_udp_write(udc, UD2AB_PWCTL_OFFSET, reg_data);
++ mdelay(1);
++ mdelay(1);
++
++ reg_data = tmpa910_udp_read(udc, UD2AB_PWCTL_OFFSET);
++ reg_data |= PWCTL_POWER_RESET_OFF; // [2] <= 1
++ tmpa910_udp_write(udc, UD2AB_PWCTL_OFFSET, reg_data);
++ mdelay(1);
++ mdelay(1);
++ mdelay(1);
++
++ UDC2_Reg_Write(UD2INT_OFFSET,UDC2_INT_MASK); /*INT EPx MASK & Refresh; */
++
++ tmpa910_udp_write(udc, UD2AB_INTSTS_OFFSET, UDC2AB_INT_ALL_CLEAR);
++ tmpa910_udp_write(udc, UD2AB_INTENB_OFFSET, UDC2AB_INT_MASK);
++ tmpa910_udp_write(udc, UD2AB_UDMSTSET_OFFSET, UDC2AB_MR_RESET | UDC2AB_MW_RESET);
++
++ /* request UDC and maybe VBUS irqs */
++ udc->udp_irq = platform_get_irq(pdev, 0);
++ if (request_irq(udc->udp_irq, tmpa910_udc_irq,
++ IRQF_DISABLED, driver_name, udc)) {
++ DBG("request irq %d failed\n", udc->udp_irq);
++ retval = -EBUSY;
++ goto fail1;
++ }
++
++ UDC2_Reg_Write(UD2CMD_OFFSET, All_EP_INVALID);
++
++ UDC2_Reg_Write(UD2CMD_OFFSET, USB_READY); // Pull-Up of DP will be made only after this command is issued,
++
++ DBG("Function: %s, Line: %d\n", __FUNCTION__, __LINE__);
++
++ udc->vbus = 1;
++
++ dev_set_drvdata(dev, udc);
++ device_init_wakeup(dev, 1);
++ create_debug_file(udc);
++
++ INFO("%s version %s\n", driver_name, DRIVER_VERSION);
++
++ return 0;
++
++fail1:
++ device_unregister(&udc->gadget.dev);
++fail0:
++ release_mem_region(res->start, res->end - res->start + 1);
++ return retval;
++}
++
++#define tmpa910udc_remove NULL
++#define tmpa910udc_suspend NULL
++#define tmpa910udc_resume NULL
++
++static struct platform_driver tmpa910_udc_driver = {
++ .remove = __exit_p(tmpa910udc_remove),
++ .shutdown = tmpa910udc_shutdown,
++ .suspend = tmpa910udc_suspend,
++ .resume = tmpa910udc_resume,
++ .driver = {
++ .name = (char *) driver_name,
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init udc_init_module(void)
++{
++ printk("udc_init_module\n");
++ return platform_driver_probe(&tmpa910_udc_driver, tmpa910udc_probe);
++}
++module_init(udc_init_module);
++
++static void __exit udc_exit_module(void)
++{
++ printk("udc_exit_module\n");
++ platform_driver_unregister(&tmpa910_udc_driver);
++}
++module_exit(udc_exit_module);
++
++MODULE_DESCRIPTION("TMPA910 udc driver");
++MODULE_AUTHOR("Wang Liguang");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/tmpa910_udc.h b/drivers/usb/gadget/tmpa910_udc.h
+new file mode 100644
+index 0000000..cafd97b
+--- /dev/null
++++ b/drivers/usb/gadget/tmpa910_udc.h
+@@ -0,0 +1,747 @@
++/*
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the
++ * Free Software Foundation, Inc.,
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++#ifndef TMPA910_UDC_H
++#define TMPA910_UDC_H
++
++/* USB Device Controller Registers */
++#define UD2AB_INTSTS_OFFSET 0x000
++#define UD2AB_INTENB_OFFSET 0x004
++#define UD2AB_MWTOUT_OFFSET 0x008
++#define UD2C2STSET_OFFSET 0x00c
++#define UD2AB_UDMSTSET_OFFSET 0x010
++#define UD2AB_DMA_CRDREQ_OFFSET 0x014
++#define UD2AB_DMA_CRDVL_OFFSET 0x018
++#define UD2AB_UDC2RDREQ_OFFSET 0x01c
++#define UD2AB_UDC2RDVL_OFFSET 0x020
++
++#define UD2AB_ARBT_SET_OFFSET 0x03c
++#define UD2AB_MWSADR_OFFSET 0x040
++#define UD2AB_MWEADR_OFFSET 0x044
++#define UD2AB_MWCADR_OFFSET 0x048
++#define UD2AB_MWAHBADR_OFFSET 0x04c
++#define UD2AB_MRSADR_OFFSET 0x050
++#define UD2AB_MREADR_OFFSET 0x054
++#define UD2AB_MRCADR_OFFSET 0x058
++#define UD2AB_MRAHBADR_OFFSET 0x05c
++#define UD2AB_PWCTL_OFFSET 0x080
++#define UD2AB_MSTSTS_OFFSET 0x084
++#define UD2AB_TOUTCNT_OFFSET 0x088
++#define UD2AB_TSTSET_OFFSET 0x08c
++#define UD2AB_TSTOUT_OFFSET 0x090
++
++/* ADDRESS ACCESS */
++#define UD2ADR_OFFSET 0x200
++#define UD2FRM_OFFSET 0x204
++#define UD2TMD_OFFSET 0x208
++#define UD2CMD_OFFSET 0x20c
++#define UD2BRQ_OFFSET 0x210
++#define UD2VAL_OFFSET 0x214
++#define UD2IDX_OFFSET 0x218
++#define UD2LEN_OFFSET 0x21c
++#define UD2INT_OFFSET 0x220
++#define UD2INT_EP_OFFSET 0x224
++#define UD2INT_EP_MASK_OFFSET 0x228
++#define UD2_RX_DATA_0_OFFSET 0x22C
++
++#define UD2EP0_MaxPacketSize_OFFSET 0x230
++#define UD2EP0_Status_OFFSET 0x234
++#define UD2EP0_DataSize_OFFSET 0x238
++#define UD2EP0_FIFO_OFFSET 0x23c
++
++#define UD2EP1_MaxPacketSize_OFFSET 0x240
++#define UD2EP1_Status_OFFSET 0x244
++#define UD2EP1_DataSize_OFFSET 0x248
++#define UD2EP1_FIFO_OFFSET 0x24c
++
++#define UD2EP2_MaxPacketSize_OFFSET 0x250
++#define UD2EP2_Status_OFFSET 0x254
++#define UD2EP2_DataSize_OFFSET 0x258
++#define UD2EP2_FIFO_OFFSET 0x25c
++
++#define UD2INTNAK_OFFSET 0x330
++#define UD2INTNAKMSK_OFFSET 0x334
++
++//
++#define FCLK_FREQ 192 /* FCLK frequency [MHz] */
++#define TIMCLK_FREQ FCLK_FREQ/4 /* TIMCLK frequency [MHz] */
++#define TIMER1_1MS TIMCLK_FREQ*1000
++#define TIMER1_720uS TIMCLK_FREQ*720
++#define TIMER1_2000CYCLE 2000/4
++
++#define TIMER1_INITIAL_VALUE 0x00000000L
++#define TIMER1_ENABLE 0x000000c3L
++#define TIMER1_TIMEOUT 0x00000000L
++
++/* SYSTEM CLOCK DEFINE */
++#define SYSCR0_USB_MASK 0x0000003f
++#define SYSCR0_SEL_X1USB 0x00000080
++#define SYSCR0_SEL_X1 0x00000040
++#define USB_ENABLE 0x00000001
++#define SYSCR1_FC 0x00000000
++#define SYSCR1_FC_4 0x00000002
++#define SYSCR2_SEL_PLL 0x00000002
++#define SYSCR2_LUPFLAG 0x00000001
++#define SYSCR3_PLL_ON 0x00000087
++#define SYSCR3_CLOCK_8 0x00000007
++#define SYSCR4_INIT 0x00000065
++#define DMAC_DISABLE 0x00000000
++
++/* debug */
++#define PT7_SEL_X1USB 0x00000080
++
++//usb_desc_format.h.h
++/*
++ *********************************************************************
++ * TYPE DEFINITIONS
++ *********************************************************************
++ */
++/* DEVICE DESCRIPTOR STRUCTURE*/
++struct device_desc{
++ unsigned char bLength;
++ unsigned char bDescripterType;
++ unsigned short int bcdUSB;
++ unsigned char bDeviceClass;
++ unsigned char bDeviceSubClass;
++ unsigned char bDeviceProtocol;
++ unsigned char bMaxPacketSize0;
++ unsigned short int idVendor;
++ unsigned short int idProduct;
++ unsigned short int bcdDevice;
++ unsigned char iManufacture;
++ unsigned char iProduct;
++ unsigned char iSerialNumber;
++ unsigned char bNumConfiguration;
++};
++
++/* CONFIGURATION DESCRIPTOR STRUCTURE*/
++struct config_desc{
++ unsigned char bLength;
++ unsigned char bDescripterType;
++ unsigned short int wTotalLength;
++ unsigned char bNumInterfaces;
++ unsigned char bConfigurationValue;
++ unsigned char iConfiguration;
++ unsigned char bmAttributes;
++ unsigned char MaxPower;
++};
++/* STRING DESCRIPTOR STRUCTURE*/
++struct string_desc{
++ unsigned char bLength;
++ unsigned char bDescripterType;
++};
++/* INTERFACE DESCRIPTOR STRUCTURE*/
++struct interface_desc{
++ unsigned char bLength;
++ unsigned char bDescripterType;
++ unsigned char bInterfaceNumber;
++ unsigned char bAltemateSetting;
++ unsigned char bNumEndPoints;
++ unsigned char bInterfaceClass;
++ unsigned char bInterfaceSubClass;
++ unsigned char bInterfaceProtocol;
++ unsigned char iInterface;
++};
++
++/* ENDPOINT DESCRIPTOR STRUCTURE*/
++struct endpoint_desc{
++ unsigned char bLength;
++ unsigned char bDescripterType;
++ unsigned char bEndPointAddress;
++ unsigned char bmAttributes;
++ unsigned short int wMaxPacketSize;
++ unsigned char bInterval;
++ };
++
++/* USB.2.0 Specification*/
++/* DEVICE QUALIFIER DESCRIPTOR STRUCTURE*/
++struct device_qualifier{
++ unsigned char bLength;
++ unsigned char bDescriptorType;
++ unsigned short int bcdUSB;
++ unsigned char bDeviceClass;
++ unsigned char bDeviceSubClass;
++ unsigned char bDeviceProtocol;
++ unsigned char bMaxPacketSize0;
++ unsigned char bNumConfigurations;
++ unsigned char bReserved;
++};
++
++/* OTHER SPEED CONFIGRATION DESCRIPTOR STRUCTURE*/
++struct other_speed_config{
++ unsigned char bLength;
++ unsigned char bDescriptorType;
++ unsigned short int wTotalLength;
++ unsigned char bNumInterfaces;
++ unsigned char bConfigurationValue;
++ unsigned char iConfiguraion;
++ unsigned char bmAttributes;
++ unsigned char bMaxPower;
++};
++
++//usb_desc_format.h
++/*
++ *********************************************************************
++ * MACRO DEFINITIONS
++ *********************************************************************
++*/
++/* PACKET SIZE DEFINISION */
++#define EP_MAX_PACKET_SIZE_FS 0x0040
++#define EP_MAX_PACKET_SIZE_HS 0x0200
++#define BUFSIZE (EP_MAX_PACKET_SIZE_HS*4)
++#define RINGBUFSIZE (EP_MAX_PACKET_SIZE_HS*4)
++
++/* MASKDEFINISION */
++#define MASK_UCHAR_UPPER_6BIT 0xfc
++#define MASK_UINT16_LOWER_8BIT 0x00ff
++#define MASK_UINT32_LOWER_16BIT 0x0000ffff
++#define SHIFT_8BIT 8
++#define WORD_SIZE 2
++
++/* USB DEVICE CONTROLLER HARDWARE */
++#define EP_SUPPORT_NO 0x03 /* ENDPOINT0 Support Number for UDC [0-2]*/
++#define EP0 0x00 /* Endpoint0*/
++#define EP1 0x01 /* Endpoint1*/
++#define EP2 0x02 /* Endpoint2*/
++
++/* STANDARD REQUEST */
++#define RQ_GET_STATUS 0x00 /* Request Type = Get_Status()*/
++#define RQ_CLEAR_FEATURE 0x01 /* Request Type = Clear_Feature()*/
++#define RQ_SET_FEATURE 0x03 /* Request Type = Set_Feature()*/
++#define RQ_SET_ADDRESS 0x05 /* managed by Hardware*/
++#define RQ_GET_DESCRIPTOR 0x06 /* Request Type = Get_Descriptor()*/
++#define RQ_SET_DESCRIPTOR 0x07 /* Request Type = Set_Descriptor()*/
++#define RQ_GET_CONFIGURATION 0x08 /* Request Type = Get_Configuration()*/
++#define RQ_SET_CONFIGURATION 0x09 /* Request Type = Set_Configuration()*/
++#define RQ_GET_INTERFACE 0x0A /* Request Type = Get_Interface()*/
++#define RQ_SET_INTERFACE 0x0B /* Request Type = Set_Interface()*/
++#define RQ_SYNCH_FRAME 0x0C /* Request Type = Synch Frame()*/
++
++/* DESCRIPTOR TYPE */
++#define TYPE_DEVICE 0x01 /* Recipient in Get_Descriptor = Device*/
++#define TYPE_CONFIG 0x02 /* Recipient in Get_Descriptor = Config*/
++#define TYPE_STRING 0x03 /* Recipient in Get_Descriptor = String*/
++#define TYPE_DEVICE_QUALIFIER 0x06
++#define TYPE_OTHER_SPEED 0x07 /* Recipient in Get_Descriptor = OTHER SPEED*/
++
++/* SPEED CHECK */
++#define CURRENT_SPEED_CHECK 0x3000 /* UD2ADDRSTATE REG CHECK */
++#define FULL_SPEED 0x1000
++#define HIGH_SPEED 0x2000
++
++/* DIRECTON (bmRequestType:7bit) */
++#define DIRECTION_TYPE_CHECK 0x80 /* Reruest Direction */
++#define REQ_GET 0x80 /* Reruest Direction */
++#define REQ_SET 0x00 /* Reruest Direction */
++#define SET 0 /* Type of Set Request(bit field) */
++#define GET 1 /* Type of Get Request(bit field) */
++
++/* TYPE (bmRequestType:5-6bit)*/
++#define REQUEST_TYPE_CHECK 0x60 /* Request Type Mask*/
++#define STANDARD_RQ 0x00 /* Standard Request*/
++#define USBCLASS_RQ 0x20 /* Class request*/
++#define VENDOR_RQ 0x40 /* Vendor Request*/
++
++/* RECEIVE TYPE (bmRequestType:0-4bit) */
++#define RECEIVE_TYPE_CHECK 0x1f
++#define RQ_DEVICE 0x00 /* Recipient=Device*/
++#define RQ_INTERFACE 0x01 /* Recipient=Interface*/
++#define RQ_ENDPOINT 0x02 /* Recipient=Endpoint*/
++#define RECEIVE_ERROR 0x03 /* Error Request Type*/
++
++#define CONFIG_DESC_TYPE 1
++#define CONFIG_DESC_ATTRIBUTE 7
++#define CONFIG_EP1_SIZE_LOW 22
++#define CONFIG_EP1_SIZE_HIGH 23
++#define CONFIG_EP2_SIZE_LOW 29
++#define CONFIG_EP2_SIZE_HIGH 30
++
++#define STRING_DESC_INIT 0xff
++#define STRING_DESC_INDEX_0 0
++#define STRING_DESC_INDEX_1 1
++#define STRING_DESC_INDEX_2 2
++#define STRING_DESC_INDEX_3 3
++
++/* ATTRIBUTE(bmAttributes) */
++#define ATTRIBUTE_CHECK 0xe0
++#define SELF_POWERED_BIT 0x40
++#define REMOTE_WAKEUP_BIT 0x20
++
++/* COMMAND DEFINE for UDC COMMAND REGISTER(16bit). */
++#define SETUP_FIN 0x0001 /* to set SETUP FIN*/
++
++/* Endpoint reset command.*/
++#define EP0_RESET 0x0003 /* ENDPOINT0 RESET*/
++#define EP1_RESET 0x0013 /* ENDPOINT1 RESET*/
++#define EP2_RESET 0x0023 /* ENDPOINT2 RESET*/
++
++/* Endpoint stall command.*/
++#define EP0_STALL 0x0004 /* to set STALL for Endpoint0*/
++#define EP1_STALL 0x0014 /* to set STALL for Endpoint1*/
++#define EP2_STALL 0x0024 /* to set STALL for Endpoint2*/
++
++#define STATUS_NAK_E 0xfdff /* STATUS_NAK Interrupt Enaable */
++#define STATUS_NAK_D 0x0200 /* STATUS_NAK Interrupt Desable */
++
++#define All_EP_INVALID 0x0009 /* to set All ENDPOINT Invalid*/
++#define USB_READY 0x000A /* to set USB Ready*/
++#define SETUP_RECEIVED 0x000B /* to set Setup Received. ENDPOINT-0 Only*/
++
++/* EP EOP command.*/
++#define EP0_EOP 0x000C /* to set ENDPOINT0 EOP*/
++#define EP1_EOP 0x001C /* to set ENDPOINT1 EOP*/
++#define EP2_EOP 0x002C /* to set ENDPOINT2 EOP*/
++
++/* UDC Stage parameters */
++#define IDLE_STAGE 0x00 /* Idle Stage*/
++#define SETUP_STAGE 0x01 /* Setup Stage*/
++#define DATA_STAGE 0x02 /* Data Stage*/
++#define STATUS_STAGE 0x03 /* status Stage*/
++
++/* Define Judgement of Function */
++#define NORMAL 0x00 /* Nomally End*/
++#define ERROR_1 0x01 /* Abnormally End*/
++#define ERROR_2 0x02 /* Abnormally End*/
++
++/* UDC State parameters */
++#define CURRENT_STATUS_CHECK 0x0f00 /* */
++#define IDLE 0x0000 /* Idle State*/
++#define DEFAULT 0x0100 /* Default State*/
++#define ADDRESSED 0x0200 /* Address State*/
++#define CONFIGURED 0x0400 /* Configured State*/
++
++/* wIndex CHECK */
++#define INDEX_CHECK 0x000f
++
++/* - DESCRIPTOR INFORMATION - */
++
++/* CONFIG DESCRIPTOR INFOMATION */
++#define TOTAL_STRING_DESC 0x58 /* Total length of String Descriptor*/
++#define STR0_ADDRESS 0x00 /* Start address of String0 descriptor*/
++#define STR1_ADDRESS 0x11 /* Start address of String1 descriptor*/
++#define STR2_ADDRESS 0x14 /* Start address of String2 descriptor*/
++#define NUM_CONFIG 0x01 /* Maximum configuration index of device*/
++#define NUM_TOTAL_ENDPOINTS 0x04 /* maximum endpoint index of config1*/
++#define NUM_BREQRUEST_MAX 0x0100 /* maximum value of bRequest */
++#define NUM_CONFIG1_INTERFACE 0x01 /* maximum interface index of config1*/
++#define NUM_C1IO_ALT0 0x00 /* Config1-Interface0-AlternateSettig0*/
++#define OTHER_SPEED_ADD 0x40 /* Start address of String3 descriptor*/
++
++/* USB INTERRUPT SETTING */
++#define INT_ADDRESS_DEFAULT 0x00000000 /* Interrupt Bit */
++#define INT_USB_ENABLE 0x00200000 /* Interrupt Bit */
++#define INT_USB_DISABLE 0x00200000 /* Interrupt Bit */
++#define UDC2_INT_MASK 0x90ff /* Interrupt Bit */
++#define UDC2AB_INT_MASK 0x002407ff /* Interrupt Bit */
++#define UDC2AB_INT_ALL_CLEAR 0x33fe07ff /* Interrupt Bit */
++
++/*UDC2 INTERRUPT */
++#define INT_SETUP 0x0001 /* Interrupt Bit of INT_SETUP*/
++#define INT_STATUSNAK 0x0002 /* Interrupt Bit of INT_STATUSNAK*/
++#define INT_STATUS 0x0004 /* Interrupt Bit of INT_STATUS*/
++#define INT_DATA 0x0008 /* Interrupt Bit of INT_ENDPOINT0*/
++#define INT_RX_DATA0 0x0008 /* Interrupt Bit of INT_RX_DATA0*/
++#define INT_SOF 0x0010 /* Interrupt Bit of INT_SOF*/
++#define INT_EP0 0x0020 /* Interrupt Bit of INT_EP0*/
++#define INT_EP 0x0040 /* Interrupt Bit of INT_EP*/
++#define INT_NAK 0x0080 /* Interrupt Bit of INT_NAK*/
++
++/*UDC2 INTERRUPT CLEAR*/
++#define INT_MASK_VALUE 0x9000 /* Interrupt Bit of INT_SETUP*/
++#define INT_SETUP_CLEAR INT_SETUP | INT_MASK_VALUE /* Interrupt Bit of INT_SETUP*/
++#define INT_STATUSNAK_CLEAR INT_STATUSNAK | INT_MASK_VALUE /* Interrupt Bit of INT_STATUSNAK*/
++#define INT_STATUS_CLEAR INT_STATUS | INT_MASK_VALUE /* Interrupt Bit of INT_STATUS*/
++#define INT_DATA_CLEAR INT_DATA | INT_MASK_VALUE /* Interrupt Bit of INT_ENDPOINT0*/
++#define INT_RX_DATA0_CLEAR INT_RX_DATA0 | INT_MASK_VALUE /* Interrupt Bit of INT_RX_DATA0*/
++#define INT_SOF_CLEAR INT_SOF | INT_MASK_VALUE /* Interrupt Bit of INT_SOF*/
++#define INT_EP0_CLEAR INT_EP0 | INT_MASK_VALUE /* Interrupt Bit of INT_EP0*/
++#define INT_EP_CLEAR INT_EP | INT_MASK_VALUE /* Interrupt Bit of INT_EP*/
++#define INT_NAK_CLEAR INT_NAK | INT_MASK_VALUE /* Interrupt Bit of INT_NAK*/
++
++/*UDC2 INTERRUPT MASK */
++#define INT_SETUP_MASK INT_SETUP << 8
++#define INT_STATUSNAK_MASK INT_STATUSNAK << 8
++#define INT_STATUS_MASK INT_STATUS << 8
++#define INT_DATA_MASK INT_DATA << 8
++#define INT_RX_DATA0_MASK INT_RX_DATA0 << 8
++#define INT_SOF_MASK INT_SOF << 8
++#define INT_EP0_MASK INT_EP0 << 8
++#define INT_EP_MASK INT_EP << 8
++#define INT_NAK_MASK INT_NAK << 8
++
++/*UDC2 AHB INTERRUPT */
++#define INT_SUSPEND 0x00000100L /* Interrupt Bit of INT_SUSPEND*/
++#define INT_RESET 0x00000200L /* Interrupt Bit of INT_RESET_START*/
++#define INT_RESET_END 0x00000400L /* Interrupt Bit of INT_RESET_END*/
++
++#define INT_MW_SET_ADD 0x00020000L /* Interrupt Bit of INT_EP0*/
++#define INT_MW_END_ADD 0x00040000L /* Interrupt Bit of INT_EP*/
++#define INT_MW_TIMEOUT 0x00080000L /* Interrupt Bit of INT_NAK*/
++#define INT_MW_AHBERR 0x00100000L /* Interrupt Bit of INT_SOF*/
++#define INT_MR_END_ADD 0x00200000L /* Interrupt Bit of INT_EP0*/
++#define INT_MR_EP_DSET 0x00400000L /* Interrupt Bit of INT_EP*/
++#define INT_MR_AHBERR 0x00800000L /* Interrupt Bit of INT_NAK*/
++#define INT_UDC2REG_RD 0x01000000L /* Interrupt Bit of INT_SOF*/
++#define INT_DMACREG_RD 0x02000000L /* Interrupt Bit of INT_EP0*/
++#define INT_PW_DETECT 0x10000000L /* Interrupt Bit of INT_SOF*/
++#define INT_MW_RD_ERR 0x20000000L /* Interrupt Bit of INT_EP0*/
++#define UDC2AB_READ_RQ 0x80000000L /* UDC2RQ 32BIT */
++#define UDC2AB_READ_ADDRESS 0x000003fcL /* UDC2RQ 32BIT */
++#define UDC2AB_MR_RESET 0x00000040L
++#define UDC2AB_MW_RESET 0x00000004L
++#define UDC2AB_MR_ENABLE 0x00000010L /* MASTER READ ENABLE */
++#define UDC2AB_MW_ENABLE 0x00000001L /* MASTER WRITE ENABLE */
++#define UDC2AB_MR_EP_EMPTY 0x00000010L /* MASTER WRITE ENABLE */
++
++#define UD2INT_EP_EP1 0x0002
++#define UD2INT_EP_EP2 0x0004
++#define UD2EP12_ENABLE 0xFFF8
++#define UD2EP1_ENABLE 0xFFFD
++#define UD2EP2_ENABLE 0xFFFB
++#define UD2EP_DSET 0x1000
++#define UD2EP_DATASIZE_MASK 0x07FF
++
++#define UD2C2STSET_EOP_D 0x00000000L
++
++#define EP_DUAL_BULK_IN 0xC088
++#define EP_DUAL_BULK_OUT 0xC008
++#define EP_SINGLE_BULK_IN 0x4088
++#define EP_SINGLE_BULK_OUT 0x4008
++#define EP_SINGLE_BULK_OUT_C 0x0008
++
++/* status Register Result */
++#define STALL 0x0600 /* EP STALL*/
++#define STALL_FEATURE 0x0001
++#define STALL_FALL_CLEAR 0x00
++
++#define USB_INIT 0x00
++#define USB_MASK 0x1a00 /* sof, rx_data0, status_nak dissable */
++#define USB_ADDRESS_MAX 0x007f
++
++/* DESCRIPTOR SIZE*/
++#define WLENGTH_MAX 2
++#define DEVICE_DESC_SIZE 18
++#define CONFIG_DESC_SIZE 32
++#define QUALFIER_DESC_SIZE 10
++
++/* UDC2AB PWCTL SETTING */
++#define PWCTL_PHY_SUSPEND_ON 0x00000008
++#define PWCTL_PHY_SUSPEND_OFF 0x000000f7
++#define PWCTL_PHY_POWER_RESET_ON 0x000000dd
++#define PWCTL_PHY_RESET_OFF 0x00000028
++#define PWCTL_POWER_RESET_OFF 0x00000002
++
++/*
++ *********************************************************************
++ * TYPE DEFINITIONS
++ *********************************************************************
++ */
++/* FLAG INFORMATION */
++#define FLAG_OFF 0
++#define FLAG_ON 1
++typedef struct byte_field {
++ unsigned short int bitF:1;
++ unsigned short int bitE:1;
++ unsigned short int bitD:1;
++ unsigned short int bitC:1;
++ unsigned short int bitB:1;
++ unsigned short int bitA:1;
++ unsigned short int bit9:1;
++ unsigned short int bit8:1;
++
++ unsigned short int bit7:1;
++ unsigned short int bit6:1;
++ unsigned short int bit5:1;
++ unsigned short int bit4:1;
++ unsigned short int bit3:1;
++ unsigned short int bit2:1;
++ unsigned short int bit1:1;
++ unsigned short int bit0:1;
++} Byte_Field;
++
++typedef union _byte_io {
++ unsigned short int byte;
++ Byte_Field bit;
++} FlagByte;
++
++//usb_vender_class.h
++/*
++ *********************************************************************
++ * MACRO DEFINITIONS
++ *********************************************************************
++ */
++/* DRIVER STATUS */
++#define USB_STS_IDOL 0
++#define USB_STS_SUSPEND 1
++#define USB_STS_RESUME 2
++
++/* BULK IN&OUT MODE */
++#define BULKINMODE_USB 0
++#define BULKINMODE_DMA 1
++#define BULKOUTMODE_USB 0
++#define BULKOUTMODE_DMA 1
++
++/* g_USB_Stage ERROR */
++#define STAGE_NORMAL 0x00 /* Normal operation */
++#define STAGE_ERROR 0x01 /* Stage Error */
++
++/* REQUEST PROCESSING */
++#define ERR_REQUEST 0x02
++
++/* RECEIVE RING BUFFER STATUS */
++#define RRBST_NORMAL 0x00 /* Normal STATUS */
++#define RRBST_FULL 0x01 /* FULL STATUS */
++
++/* USB DOWNLOAD STATUS */
++#define USBDPG_IDOL 0x00
++#define USBDPG_MINF 0x01
++#define USBDPG_TSTART 0x02
++#define USBDPG_TRESULT 0x03
++#define USBDPG_TRESULT_DMA 0x04
++#define USBDPG_END 0x05
++#define USBDPG_E_NOR 0x00
++#define USBDPG_E_NOT 0x02
++#define USBDPG_E_FERR 0x04
++#define USBDPG_E_SOVER 0x06
++#define USBDPG_E_AERR 0x08
++#define USBDPG_E_PERR 0x0A
++
++/* KIND VENDOR COMMAND */
++#define REQ_VEN_MINF 0x00
++#define MINF_SIZE 0x0F
++#define MINF_ADDRESS 0x02
++#define REQ_VEN_TSTART 0x02
++#define REQ_VEN_TRESULT 0x04
++
++/* RAM AREA DEFINE */
++#define USB_DLTOP 0xF8002000L
++#define USB_DLBTM 0xF800DFFFL
++
++/* BULK PROCESSING DEFINE */
++#define BULK_OUT_SUCCESS 0x00 /* Bulk-out processing success */
++#define BULK_OUT_ERROR 0xFF /* Bulk-out processing error */
++#define BULK_IN_SUCCESS 0x00 /* Bulk-in processing success */
++#define BULK_IN_ERROR 0xFF /* Bulk-in processing error */
++
++/* S RECORD DECODE STATE */
++#define STATE0 0
++#define STATE1 1
++#define STATE2 2
++#define STATE3 3
++#define STATE4 4
++#define STATE5 5
++#define NORMAL_RECORD 3
++#define END_RECORD 7
++#define ADDRESS_GET 4
++#define SUM_RESULT 0xff
++
++/*
++ *********************************************************************
++ * EXTERNAL FUNCTION DECLARATION
++ *********************************************************************
++ */
++
++//usb_ram.h
++/*
++ *********************************************************************
++ * EXTERNAL VARIABLE DECLARATION
++ *********************************************************************
++ */
++extern unsigned char g_USB_Send_Buf[BUFSIZE]; /* Send Buffer */
++extern unsigned char g_USB_Recv_Buf[BUFSIZE]; /* Receive Buffer */
++extern unsigned char g_USB_Recv_Rbuf[RINGBUFSIZE];
++
++extern unsigned char *g_Recv_Rbuf_Wpt;
++extern unsigned char *g_Recv_Rbuf_Rpt;
++extern unsigned char g_USB_Rbuf_Status;
++extern unsigned char g_USB_Status;
++extern unsigned char g_USB_Bulk_In_Mode;
++extern unsigned char g_USB_Bulk_Out_Mode;
++
++/* For INTERRUPT CHECK*/
++extern unsigned long int g_Interrupt_Stasus;
++
++/* For ENDPOINT0 */
++extern unsigned char g_EP0_Recv_Buff[EP_MAX_PACKET_SIZE_FS]; /* EP0 receive buffer */
++extern unsigned char g_EP0_Send_Buff[EP_MAX_PACKET_SIZE_FS]; /* EP0 sending buffer */
++extern unsigned char g_USB_Stage;
++extern unsigned char g_USB_Stage_Error;
++extern unsigned char g_EP0_Recv_Length;
++
++/* For BULK MODE */
++extern unsigned char *g_DMA_Send_Buff_Address;
++extern unsigned char *g_DMA_Recv_Buff_Address;
++extern unsigned long int g_DMA_Send_Length;
++extern unsigned long int g_DMA_Recv_Length;
++extern unsigned short int g_Bulk_Out_EP_Size;
++
++/* For USB MAIN */
++extern unsigned long int g_USB_Dpg_Adress;
++
++extern unsigned short int g_USB_Dpg_Size;
++extern unsigned short int g_USB_Dpg_Size_cnt;
++extern unsigned char g_USB_Dpg_Stt;
++extern unsigned char g_USB_Dpg_Error_Stt;
++
++/* Descriptor Infomation */
++extern unsigned short int g_EP_PAYLOAD_SIZE[EP_SUPPORT_NO];
++extern unsigned char g_Num_StringDesc;
++extern unsigned short int g_USB_Address;
++
++/* Request Parameter of Setup Data */
++extern unsigned char g_bmRequestType;
++extern unsigned char g_bRequest;
++extern unsigned short int g_wValue;
++extern unsigned short int g_wIndex;
++extern unsigned short int g_wLength;
++
++/* UDC State parameter */
++extern unsigned short int g_Current_State;
++extern unsigned char g_Current_Config;
++extern unsigned char g_Current_Interface;
++extern unsigned char g_Current_Alternate;
++extern unsigned short int g_Buf_Current_State;
++extern unsigned char g_Buf_Current_Config;
++extern unsigned char g_Buf_Current_Interface;
++extern unsigned char g_Buf_Current_Alternate;
++extern unsigned char g_Self_Powered_Bit;
++
++/* Endpoint Fifo Access */
++extern unsigned short int g_Remain_TotalLength;
++extern unsigned short int g_Expected_Length;
++extern unsigned long int g_Start_Address;
++
++
++extern const unsigned char Config_Desc[CONFIG_DESC_SIZE];
++extern const unsigned char Dev_Desc[DEVICE_DESC_SIZE];
++extern const unsigned char Qualifier_Desc[QUALFIER_DESC_SIZE];
++extern const unsigned char Str_Desc_ROM[TOTAL_STRING_DESC]; /* String Descriptor Data */
++
++/* FLAG DEFINE */
++extern FlagByte Dev_Status;
++#define Dev_PowerStatus Dev_Status.byte
++#define fSelf_Powered Dev_Status.bit.bit0
++#define fRemote_Wakeup Dev_Status.bit.bit1
++#define fDirection Dev_Status.bit.bit2
++#define fErrorTrasfer Dev_Status.bit.bit3
++#define fBODirection Dev_Status.bit.bit4
++
++/* DEFINE FEATURE FLAG. */
++extern FlagByte EP_ST;
++#define ST_Feature EP_ST.byte
++#define fEP0_Stall_Feature EP_ST.bit.bit0
++#define fEP1_Stall_Feature EP_ST.bit.bit1
++#define fEP2_Stall_Feature EP_ST.bit.bit2
++#define fEP3_Stall_Feature EP_ST.bit.bit3
++
++/*
++ * controller driver data structures
++ */
++
++#define NUM_ENDPOINTS 4
++
++/*
++ * hardware won't disable bus reset, or resume while the controller
++ * is suspended ... watching suspend helps keep the logic symmetric.
++ */
++#define MINIMUS_INTERRUPTUS \
++ (AT91_UDP_ENDBUSRES | AT91_UDP_RXRSM | AT91_UDP_RXSUSP)
++
++struct tmpa910_ep {
++ struct usb_ep ep;
++ struct list_head queue;
++ struct tmpa910_udc *udc;
++ void __iomem *creg;
++
++ unsigned maxpacket:16;
++ u8 int_mask;
++ unsigned is_pingpong:1;
++
++ unsigned stopped:1;
++ unsigned is_in:1;
++ unsigned is_iso:1;
++ unsigned fifo_bank:1;
++
++ const struct usb_endpoint_descriptor
++ *desc;
++};
++
++/*
++ * driver is non-SMP, and just blocks IRQs whenever it needs
++ * access protection for chip registers or driver state
++ */
++struct tmpa910_udc {
++ struct usb_gadget gadget;
++ struct tmpa910_ep ep[NUM_ENDPOINTS];
++ struct usb_gadget_driver *driver;
++ unsigned vbus:1;
++ unsigned enabled:1;
++ unsigned clocked:1;
++ unsigned suspended:1;
++ unsigned req_pending:1;
++ unsigned wait_for_addr_ack:1;
++ unsigned wait_for_config_ack:1;
++ unsigned selfpowered:1;
++ unsigned active_suspend:1;
++ u8 addr;
++// struct tmpa910_udc_data board;
++// struct clk *iclk, *fclk;
++ struct platform_device *pdev;
++ struct proc_dir_entry *pde;
++ void __iomem *udp_baseaddr;
++ int udp_irq;
++};
++
++static inline struct tmpa910_udc *to_udc(struct usb_gadget *g)
++{
++ return container_of(g, struct tmpa910_udc, gadget);
++}
++
++struct tmpa910_request {
++ struct usb_request req;
++ struct list_head queue;
++};
++
++/*-------------------------------------------------------------------------*/
++
++#define DEBUG
++#ifdef DEBUG
++#define DBG(stuff...) printk("udc: " stuff)
++#else
++#define DBG(stuff...) do{}while(0)
++#endif
++
++#ifdef VERBOSE
++# define VERBOSED DBG
++#else
++# define VDBG(stuff...) do{}while(0)
++#endif
++
++#ifdef PACKET_TRACE
++# define PACKET VDBG
++#else
++# define PACKET(stuff...) do{}while(0)
++#endif
++
++#define ERR(stuff...) printk(KERN_ERR "udc: " stuff)
++#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff)
++#define INFO(stuff...) printk(KERN_INFO "udc: " stuff)
++
++#endif
++
++
+diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
+index 2d77240..f3c86fb 100644
+--- a/drivers/usb/gadget/zero.c
++++ b/drivers/usb/gadget/zero.c
+@@ -56,7 +56,8 @@
+ #include "g_zero.h"
+ #include "gadget_chips.h"
+
+-
++#define __DEBUG__
++#include <linux/debug.h>
+ /*-------------------------------------------------------------------------*/
+
+ /*
+@@ -328,6 +329,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
+ init_utsname()->sysname, init_utsname()->release,
+ gadget->name);
+
++ NPRINTK("success\n");
+ return 0;
+ }
+
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index 9b43b22..264995c 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -189,6 +189,15 @@ config USB_OHCI_HCD
+ To compile this driver as a module, choose M here: the
+ module will be called ohci-hcd.
+
++config USB_OHCI_HCD_TMPA900
++ bool "OHCI support for Toshiba TMPA900"
++ depends on USB_OHCI_HCD && ARCH_TMPA910
++ default y
++ ---help---
++ Enables support for the USB OHCI controller found on Toshiba
++ TMPA900 processor. Warning ! This controller only support
++ SRAM based descriptors and data
++
+ config USB_OHCI_HCD_PPC_SOC
+ bool "OHCI support for on-chip PPC USB controller"
+ depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+index e18c677..f5f5601 100644
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -785,10 +785,9 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
+
+ /* start 20 msec resume signaling from this port,
+ * and make khubd collect PORT_STAT_C_SUSPEND to
+- * stop that signaling. Use 5 ms extra for safety,
+- * like usb_port_resume() does.
++ * stop that signaling.
+ */
+- ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
++ ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
+ ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
+ mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
+ }
+diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
+index 698f461..1b6f1c0 100644
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -120,26 +120,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
+ del_timer_sync(&ehci->watchdog);
+ del_timer_sync(&ehci->iaa_watchdog);
+
++ port = HCS_N_PORTS (ehci->hcs_params);
+ spin_lock_irq (&ehci->lock);
+
+- /* Once the controller is stopped, port resumes that are already
+- * in progress won't complete. Hence if remote wakeup is enabled
+- * for the root hub and any ports are in the middle of a resume or
+- * remote wakeup, we must fail the suspend.
+- */
+- if (hcd->self.root_hub->do_remote_wakeup) {
+- port = HCS_N_PORTS(ehci->hcs_params);
+- while (port--) {
+- if (ehci->reset_done[port] != 0) {
+- spin_unlock_irq(&ehci->lock);
+- ehci_dbg(ehci, "suspend failed because "
+- "port %d is resuming\n",
+- port + 1);
+- return -EBUSY;
+- }
+- }
+- }
+-
+ /* stop schedules, clean any completed work */
+ if (HC_IS_RUNNING(hcd->state)) {
+ ehci_quiesce (ehci);
+@@ -155,7 +138,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
+ */
+ ehci->bus_suspended = 0;
+ ehci->owned_ports = 0;
+- port = HCS_N_PORTS(ehci->hcs_params);
+ while (port--) {
+ u32 __iomem *reg = &ehci->regs->port_status [port];
+ u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
+diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
+index c0d4b39..139a2cc 100644
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -827,10 +827,9 @@ qh_make (
+ * But interval 1 scheduling is simpler, and
+ * includes high bandwidth.
+ */
+- urb->interval = 1;
+- } else if (qh->period > ehci->periodic_size) {
+- qh->period = ehci->periodic_size;
+- urb->interval = qh->period << 3;
++ dbg ("intr period %d uframes, NYET!",
++ urb->interval);
++ goto done;
+ }
+ } else {
+ int think_time;
+@@ -853,10 +852,6 @@ qh_make (
+ usb_calc_bus_time (urb->dev->speed,
+ is_input, 0, max_packet (maxp)));
+ qh->period = urb->interval;
+- if (qh->period > ehci->periodic_size) {
+- qh->period = ehci->periodic_size;
+- urb->interval = qh->period;
+- }
+ }
+ }
+
+diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
+index 24eb747..e9a111e 100644
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -50,7 +50,8 @@
+
+ /*-------------------------------------------------------------------------*/
+
+-#undef OHCI_VERBOSE_DEBUG /* not always helpful */
++//#define OHCI_VERBOSE_DEBUG /* not always helpful */
++//#define VERBOSE_DEBUG /* not always helpful */
+
+ /* For initializing controller (mask in an HCFS mode too) */
+ #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
+@@ -80,10 +81,12 @@ static void ohci_dump (struct ohci_hcd *ohci, int verbose);
+ static int ohci_init (struct ohci_hcd *ohci);
+ static void ohci_stop (struct usb_hcd *hcd);
+
+-#if defined(CONFIG_PM) || defined(CONFIG_PCI)
++#if defined(CONFIG_PM) || defined(CONFIG_PCI) || defined(CONFIG_USB_OHCI_HCD_TMPA900)
+ static int ohci_restart (struct ohci_hcd *ohci);
+ #endif
+
++void (*ohci_usb_hcd_giveback_urb)(struct usb_hcd *hcd, struct urb *urb, int status) = usb_hcd_giveback_urb;
++
+ #ifdef CONFIG_PCI
+ static void quirk_amd_pll(int state);
+ static void amd_iso_dev_put(void);
+@@ -134,6 +137,7 @@ MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake");
+
+ /*-------------------------------------------------------------------------*/
+
++
+ /*
+ * queue up an urb for anything except the root hub
+ */
+@@ -251,6 +255,7 @@ static int ohci_urb_enqueue (
+ * enable that part of the schedule, if needed
+ * and update count of queued periodic urbs
+ */
++
+ urb->hcpriv = urb_priv;
+ td_submit_urb (ohci, urb);
+
+@@ -920,7 +925,7 @@ static void ohci_stop (struct usb_hcd *hcd)
+
+ /*-------------------------------------------------------------------------*/
+
+-#if defined(CONFIG_PM) || defined(CONFIG_PCI)
++#if defined(CONFIG_PM) || defined(CONFIG_PCI) || defined(CONFIG_USB_OHCI_HCD_TMPA900)
+
+ /* must not be called from interrupt context */
+ static int ohci_restart (struct ohci_hcd *ohci)
+@@ -979,6 +984,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
+ ohci_err (ohci, "can't restart, %d\n", temp);
+ return temp;
+ }
++
+ ohci_dbg(ohci, "restart complete\n");
+ return 0;
+ }
+@@ -1085,6 +1091,11 @@ MODULE_LICENSE ("GPL");
+ #define TMIO_OHCI_DRIVER ohci_hcd_tmio_driver
+ #endif
+
++#ifdef CONFIG_USB_OHCI_HCD_TMPA900
++#include "ohci-tmpa900.c"
++#define TMPA900_OHCI_DRIVER ohci_hcd_tmpa900_driver
++#endif
++
+ #if !defined(PCI_DRIVER) && \
+ !defined(PLATFORM_DRIVER) && \
+ !defined(OF_PLATFORM_DRIVER) && \
+@@ -1092,6 +1103,7 @@ MODULE_LICENSE ("GPL");
+ !defined(PS3_SYSTEM_BUS_DRIVER) && \
+ !defined(SM501_OHCI_DRIVER) && \
+ !defined(TMIO_OHCI_DRIVER) && \
++ !defined(CONFIG_USB_OHCI_HCD_TMPA900) && \
+ !defined(SSB_OHCI_DRIVER)
+ #error "missing bus glue for ohci-hcd"
+ #endif
+@@ -1164,6 +1176,12 @@ static int __init ohci_hcd_mod_init(void)
+ goto error_tmio;
+ #endif
+
++#ifdef TMPA900_OHCI_DRIVER
++ retval = platform_driver_register(&TMPA900_OHCI_DRIVER);
++ if (retval < 0)
++ goto error_tmpa900;
++#endif
++
+ return retval;
+
+ /* Error path */
+@@ -1175,6 +1193,10 @@ static int __init ohci_hcd_mod_init(void)
+ platform_driver_unregister(&SM501_OHCI_DRIVER);
+ error_sm501:
+ #endif
++#ifdef TMPA900_OHCI_DRIVER
++ platform_driver_unregister(&TMPA900_OHCI_DRIVER);
++ error_tmpa900:
++#endif
+ #ifdef SSB_OHCI_DRIVER
+ ssb_driver_unregister(&SSB_OHCI_DRIVER);
+ error_ssb:
+@@ -1218,6 +1240,11 @@ static void __exit ohci_hcd_mod_exit(void)
+ #ifdef SM501_OHCI_DRIVER
+ platform_driver_unregister(&SM501_OHCI_DRIVER);
+ #endif
++
++#ifdef TMPA900_OHCI_DRIVER
++ platform_driver_unregister(&TMPA900_OHCI_DRIVER);
++#endif
++
+ #ifdef SSB_OHCI_DRIVER
+ ssb_driver_unregister(&SSB_OHCI_DRIVER);
+ #endif
+diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
+index 2f20d3d..0d3226c 100644
+--- a/drivers/usb/host/ohci-mem.c
++++ b/drivers/usb/host/ohci-mem.c
+@@ -80,11 +80,72 @@ dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma)
+ return td;
+ }
+
++
++#ifdef CONFIG_USB_OHCI_HCD_TMPA900
++typedef unsigned long a32;
++
++static a32 tmpa9x0_sram_alloc(unsigned long size, unsigned long align);
++static void tmpa9x0_sram_free(a32 block);
++static unsigned int tmpa9x0_sram_to_phys(void *virt_sram);
++
++static struct td *
++td_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
++{
++
++ struct td *td;
++
++ td = (struct td *) tmpa9x0_sram_alloc (sizeof (*td),32 );
++ if (td) {
++ memset (td, 0, sizeof *td);
++ td->td_dma = tmpa9x0_sram_to_phys(td);
++ td->hwNextTD = cpu_to_hc32 (hc, td->td_dma);
++
++ }
++ return td;
++}
++
++static void
++td_free (struct ohci_hcd *hc, struct td *td)
++{
++ struct td **prev = &hc->td_hash [TD_HASH_FUNC (td->td_dma)];
++
++ while (*prev && *prev != td)
++ prev = &(*prev)->td_hash;
++ if (*prev)
++ *prev = td->td_hash;
++ else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0)
++ ohci_dbg (hc, "no hash for td %p\n", td);
++ tmpa9x0_sram_free ( (a32) td);
++}
++
++/*-------------------------------------------------------------------------*/
++
++/* EDs ... */
++static struct ed *
++ed_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
++{
++ struct ed *ed;
++
++ ed = (struct ed *) tmpa9x0_sram_alloc (sizeof (*ed),32 );
++ if (ed) {
++ memset (ed, 0, sizeof (*ed));
++ INIT_LIST_HEAD (&ed->td_list);
++ ed->dma = tmpa9x0_sram_to_phys(ed) ;
++ }
++ return ed;
++}
++
++static void
++ed_free (struct ohci_hcd *hc, struct ed *ed)
++{
++ tmpa9x0_sram_free( (a32) ed);
++}
++
++#else /* CONFIG_USB_OHCI_HCD_TMPA900 */
+ /* TDs ... */
+ static struct td *
+ td_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
+ {
+- dma_addr_t dma;
+ struct td *td;
+
+ td = dma_pool_alloc (hc->td_cache, mem_flags, &dma);
+@@ -95,6 +156,8 @@ td_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
+ td->td_dma = dma;
+ /* hashed in td_fill */
+ }
++
++
+ return td;
+ }
+
+@@ -127,6 +190,7 @@ ed_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
+ INIT_LIST_HEAD (&ed->td_list);
+ ed->dma = dma;
+ }
++
+ return ed;
+ }
+
+@@ -135,4 +199,4 @@ ed_free (struct ohci_hcd *hc, struct ed *ed)
+ {
+ dma_pool_free (hc->ed_cache, ed, ed->dma);
+ }
+-
++#endif /* CONFIG_USB_OHCI_HCD_TMPA900 */
+diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
+index 35288bc..fa4f55e 100644
+--- a/drivers/usb/host/ohci-q.c
++++ b/drivers/usb/host/ohci-q.c
+@@ -68,7 +68,7 @@ __acquires(ohci->lock)
+ /* urb->complete() can reenter this HCD */
+ usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb);
+ spin_unlock (&ohci->lock);
+- usb_hcd_giveback_urb(ohci_to_hcd(ohci), urb, status);
++ ohci_usb_hcd_giveback_urb(ohci_to_hcd(ohci), urb, status);
+ spin_lock (&ohci->lock);
+
+ /* stop periodic dma if it's not needed */
+@@ -628,6 +628,7 @@ static void td_submit_urb (
+ data_len -= 4096;
+ cnt++;
+ }
++
+ /* maybe avoid ED halt on final TD short read */
+ if (!(urb->transfer_flags & URB_SHORT_NOT_OK))
+ info |= TD_R;
+@@ -661,9 +662,12 @@ static void td_submit_urb (
+ ? TD_CC | TD_DP_IN | TD_T_DATA1
+ : TD_CC | TD_DP_OUT | TD_T_DATA1;
+ td_fill (ohci, info, data, 0, urb, cnt++);
++
++#if 0
+ /* maybe kickstart control list */
+ wmb ();
+ ohci_writel (ohci, OHCI_CLF, &ohci->regs->cmdstatus);
++#endif
+ break;
+
+ /* ISO has no retransmit, so no toggle; and it uses special TDs.
+diff --git a/drivers/usb/host/ohci-tmpa900.c b/drivers/usb/host/ohci-tmpa900.c
+new file mode 100644
+index 0000000..e970c83
+--- /dev/null
++++ b/drivers/usb/host/ohci-tmpa900.c
+@@ -0,0 +1,824 @@
++/*
++ * OHCI HCD (Host Controller Driver) for USB.
++ *
++ * (C) Copyright 1999 Roman Weissgaerber <weissg at vienna.at>
++ * (C) Copyright 2000-2005 David Brownell
++ * (C) Copyright 2002 Hewlett-Packard Company
++ * (C) Copyright 2008 Magnus Damm
++ * (C) Copyright 2009 bPlan GmbH
++ *
++ * Toshiba TMPA900 Bus Glue - based on ohci-tmpa900.c
++ *
++ * This file is licenced under the GPL.
++ */
++
++#include <linux/interrupt.h>
++#include <linux/jiffies.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/spinlock.h>
++
++#include <asm/cacheflush.h>
++
++#include "ohci-tmpa900_sram.c"
++
++
++static int _ohci_init (struct ohci_hcd *ohci)
++{
++ int ret;
++ struct usb_hcd *hcd = ohci_to_hcd(ohci);
++
++ disable (ohci);
++ ohci->regs = hcd->regs;
++
++ /* REVISIT this BIOS handshake is now moved into PCI "quirks", and
++ * was never needed for most non-PCI systems ... remove the code?
++ */
++
++ /* Disable HC interrupts */
++ ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
++
++ /* flush the writes, and save key bits like RWC */
++ if (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_RWC)
++ ohci->hc_control |= OHCI_CTRL_RWC;
++
++ /* Read the number of ports unless overridden */
++ if (ohci->num_ports == 0)
++ ohci->num_ports = roothub_a(ohci) & RH_A_NDP;
++
++ if (ohci->hcca)
++ return 0;
++
++ ohci->hcca = (struct ohci_hcca*) tmpa9x0_sram_alloc(sizeof *ohci->hcca, 256);
++ if (!ohci->hcca)
++ return -ENOMEM;
++
++ ohci->hcca_dma = tmpa9x0_sram_to_phys(ohci->hcca);
++
++ if ((ret = ohci_mem_init (ohci)) < 0)
++ ohci_stop (hcd);
++ else {
++ create_debug_files (ohci);
++ }
++
++ return ret;
++}
++
++
++
++static void tmpa9x0_ohci_stop (struct usb_hcd *hcd)
++{
++ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
++
++ ohci_dump (ohci, 1);
++
++ flush_scheduled_work();
++
++ ohci_usb_reset (ohci);
++ ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
++ free_irq(hcd->irq, hcd);
++ hcd->irq = -1;
++
++ if (quirk_zfmicro(ohci))
++ del_timer(&ohci->unlink_watchdog);
++
++ remove_debug_files (ohci);
++ ohci_mem_cleanup (ohci);
++ if (ohci->hcca) {
++ tmpa9x0_sram_free ( (a32) ohci->hcca);
++ ohci->hcca = NULL;
++ ohci->hcca_dma = 0;
++ }
++}
++
++
++static int ohci_tmpa900_init(struct usb_hcd *hcd)
++{
++ int ret;
++
++ ret = _ohci_init(hcd_to_ohci(hcd));
++
++ return ret;
++}
++
++static int ohci_tmpa900_start(struct usb_hcd *hcd)
++{
++ struct device *dev = hcd->self.controller;
++ int ret;
++
++ ret = ohci_run(hcd_to_ohci(hcd));
++ if (ret < 0) {
++ dev_err(dev, "can't start %s", hcd->self.bus_name);
++ tmpa9x0_ohci_stop(hcd);
++ }
++
++ return ret;
++}
++
++/*-------------------------------------------------------------------------*/
++
++/* an interrupt happens */
++
++static irqreturn_t tmpa9x0_ohci_irq (struct usb_hcd *hcd)
++{
++ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
++ struct ohci_regs __iomem *regs = ohci->regs;
++ int ints;
++
++ /* Read interrupt status (and flush pending writes). We ignore the
++ * optimization of checking the LSB of hcca->done_head; it doesn't
++ * work on all systems (edge triggering for OHCI can be a factor).
++ */
++
++ ints = ohci_readl(ohci, ®s->intrstatus);
++
++ /* Check for an all 1's result which is a typical consequence
++ * of dead, unclocked, or unplugged (CardBus...) devices
++ */
++ if (ints == ~(u32)0) {
++ disable (ohci);
++ ohci_dbg (ohci, "device removed!\n");
++ return IRQ_HANDLED;
++ }
++
++ /* We only care about interrupts that are enabled */
++ ints &= ohci_readl(ohci, ®s->intrenable);
++
++ /* interrupt for some other device? */
++ if (ints == 0)
++ return IRQ_NOTMINE;
++
++ if (ints & OHCI_INTR_UE) {
++ // e.g. due to PCI Master/Target Abort
++ if (quirk_nec(ohci)) {
++ /* Workaround for a silicon bug in some NEC chips used
++ * in Apple's PowerBooks. Adapted from Darwin code.
++ */
++ ohci_err (ohci, "OHCI Unrecoverable Error, scheduling NEC chip restart\n");
++
++ ohci_writel (ohci, OHCI_INTR_UE, ®s->intrdisable);
++
++ schedule_work (&ohci->nec_work);
++ } else {
++ disable (ohci);
++ ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
++ }
++
++ ohci_dump (ohci, 1);
++ ohci_usb_reset (ohci);
++ }
++
++ if (ints & OHCI_INTR_RHSC) {
++ ohci->next_statechange = jiffies + STATECHANGE_DELAY;
++ ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC,
++ ®s->intrstatus);
++
++ /* NOTE: Vendors didn't always make the same implementation
++ * choices for RHSC. Many followed the spec; RHSC triggers
++ * on an edge, like setting and maybe clearing a port status
++ * change bit. With others it's level-triggered, active
++ * until khubd clears all the port status change bits. We'll
++ * always disable it here and rely on polling until khubd
++ * re-enables it.
++ */
++ ohci_writel(ohci, OHCI_INTR_RHSC, ®s->intrdisable);
++ usb_hcd_poll_rh_status(hcd);
++ }
++
++ /* For connect and disconnect events, we expect the controller
++ * to turn on RHSC along with RD. But for remote wakeup events
++ * this might not happen.
++ */
++ else if (ints & OHCI_INTR_RD) {
++ ohci_writel(ohci, OHCI_INTR_RD, ®s->intrstatus);
++ hcd->poll_rh = 1;
++ if (ohci->autostop) {
++ spin_lock (&ohci->lock);
++ ohci_rh_resume (ohci);
++ spin_unlock (&ohci->lock);
++ } else
++ usb_hcd_resume_root_hub(hcd);
++ }
++
++ if (ints & OHCI_INTR_WDH) {
++ spin_lock (&ohci->lock);
++ dl_done_list (ohci);
++ spin_unlock (&ohci->lock);
++ }
++
++ if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {
++ spin_lock(&ohci->lock);
++ if (ohci->ed_to_check) {
++ struct ed *ed = ohci->ed_to_check;
++
++ if (check_ed(ohci, ed)) {
++ /* HC thinks the TD list is empty; HCD knows
++ * at least one TD is outstanding
++ */
++ if (--ohci->zf_delay == 0) {
++ struct td *td = list_entry(
++ ed->td_list.next,
++ struct td, td_list);
++ ohci_warn(ohci,
++ "Reclaiming orphan TD %p\n",
++ td);
++ takeback_td(ohci, td);
++ ohci->ed_to_check = NULL;
++ }
++ } else
++ ohci->ed_to_check = NULL;
++ }
++ spin_unlock(&ohci->lock);
++ }
++
++ /* could track INTR_SO to reduce available PCI/... bandwidth */
++
++ /* handle any pending URB/ED unlinks, leaving INTR_SF enabled
++ * when there's still unlinking to be done (next frame).
++ */
++ spin_lock (&ohci->lock);
++ if (ohci->ed_rm_list)
++ {
++ finish_unlinks (ohci, ohci_frame_no(ohci));
++ }
++ if ((ints & OHCI_INTR_SF) != 0
++ && !ohci->ed_rm_list
++ && !ohci->ed_to_check
++ && HC_IS_RUNNING(hcd->state))
++ ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable);
++ spin_unlock (&ohci->lock);
++
++ if (HC_IS_RUNNING(hcd->state)) {
++ ohci_writel (ohci, ints, ®s->intrstatus);
++ ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable);
++ // flush those writes
++ (void) ohci_readl (ohci, &ohci->regs->control);
++ }
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * queue up an urb for anything except the root hub
++ */
++static int tmpa9x0_urb_enqueue (
++ struct usb_hcd *hcd,
++ struct urb *urb,
++ gfp_t mem_flags)
++{
++ int transfer_buffer_length;
++
++
++ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
++ struct ed *ed;
++ urb_priv_t *urb_priv;
++ unsigned int pipe = urb->pipe;
++ int i, size = 0;
++ unsigned long flags;
++ int retval = 0;
++
++#ifdef OHCI_VERBOSE_DEBUG
++ urb_print(urb, "SUB", usb_pipein(pipe), -EINPROGRESS);
++#endif
++
++ /* every endpoint has a ed, locate and maybe (re)initialize it */
++ if (! (ed = ed_get (ohci, urb->ep, urb->dev, pipe, urb->interval)))
++ return -ENOMEM;
++
++ /* for the private part of the URB we need the number of TDs (size) */
++ switch (ed->type) {
++ case PIPE_CONTROL:
++ /* td_submit_urb() doesn't yet handle these */
++ if (urb->transfer_buffer_length > 4096)
++ return -EMSGSIZE;
++
++ /* 1 TD for setup, 1 for ACK, plus ... */
++ size = 2;
++ /* FALLTHROUGH */
++ // case PIPE_INTERRUPT:
++ // case PIPE_BULK:
++ default:
++ /* one TD for every 4096 Bytes (can be upto 8K) */
++ size += urb->transfer_buffer_length / 4096;
++ /* ... and for any remaining bytes ... */
++ if ((urb->transfer_buffer_length % 4096) != 0)
++ size++;
++ /* ... and maybe a zero length packet to wrap it up */
++ if (size == 0)
++ size++;
++ else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0
++ && (urb->transfer_buffer_length
++ % usb_maxpacket (urb->dev, pipe,
++ usb_pipeout (pipe))) == 0)
++ size++;
++ break;
++ case PIPE_ISOCHRONOUS: /* number of packets from URB */
++ size = urb->number_of_packets;
++ break;
++ }
++
++ /* allocate the private part of the URB */
++ urb_priv = kzalloc (sizeof (urb_priv_t) + size * sizeof (struct td *),
++ mem_flags);
++ if (!urb_priv)
++ return -ENOMEM;
++
++ INIT_LIST_HEAD (&urb_priv->pending);
++ urb_priv->length = size;
++ urb_priv->ed = ed;
++
++ // Changes against orignal ohci func
++ // we allocate SRAM for setup and data
++ // replace the original urb pointer
++ // and backup then in our priv urb
++ if ( usb_endpoint_xfer_control(&urb->ep->desc) )
++ {
++ void *setup_in_sram;
++ unsigned int setup_in_sram_phys;
++
++ printk(KERN_DEBUG "Allcoate 8 bytes for setup in SRAM\n" );
++ setup_in_sram = (void *) tmpa9x0_sram_alloc(8, 32 );
++ if (setup_in_sram == NULL)
++ {
++ printk("Out of SRAM! setup\n");
++ return -ENOMEM;
++ }
++
++ setup_in_sram_phys = tmpa9x0_sram_to_phys(setup_in_sram);
++
++ memcpy(setup_in_sram, urb->setup_packet, 8);
++ dmac_clean_range(setup_in_sram, (uint8_t *) setup_in_sram );
++
++ urb_priv->urb_setup = urb->setup_packet;
++ urb_priv->urb_setup_dma = urb->setup_dma;
++
++ urb->setup_packet = setup_in_sram;
++ urb->setup_dma = setup_in_sram_phys;
++
++ // bitte enqueue me in one list
++ printk(KERN_DEBUG "Ok setup in SRAM at 0x%p/0x%8x\n", urb->setup_packet, urb->setup_dma);
++ }
++ else
++ {
++ urb_priv->urb_setup = NULL;
++ urb_priv->urb_setup_dma = 0;
++ }
++
++ transfer_buffer_length = urb->transfer_buffer_length;
++
++ if (transfer_buffer_length>0)
++ {
++ void *data_in_sram;
++ unsigned int data_in_sram_phys;
++
++ printk(KERN_DEBUG "Allcoate %d bytes for data in SRAM\n", transfer_buffer_length );
++ data_in_sram = (void *) tmpa9x0_sram_alloc(transfer_buffer_length,32 );
++ if (data_in_sram == NULL)
++ {
++ printk(KERN_ERR "Out of SRAM! data (%d)\n", transfer_buffer_length);
++ return -ENOMEM;
++ }
++
++ data_in_sram_phys = tmpa9x0_sram_to_phys(data_in_sram);
++
++ if (usb_pipeout(urb->pipe) )
++ {
++ memcpy(data_in_sram, urb->transfer_buffer, transfer_buffer_length);
++ dmac_clean_range(data_in_sram, (uint8_t *) data_in_sram + transfer_buffer_length );
++ }
++
++
++ urb_priv->urb_data = urb->transfer_buffer;
++ urb_priv->urb_data_dma = urb->transfer_dma;
++
++ urb->transfer_buffer = data_in_sram;
++ urb->transfer_dma = data_in_sram_phys;
++
++ // bitte enqueue me in one list
++ printk(KERN_DEBUG "Ok data in SRAM at 0x%p/0x%8x. old 0x%p / priv 0x%p adr 0x%p\n",
++ data_in_sram, data_in_sram_phys, urb_priv->urb_data, urb_priv, &urb_priv->urb_data);
++ }
++ else
++ {
++ urb_priv->urb_data = NULL;
++ urb_priv->urb_data_dma = 0;
++ }
++
++ /* allocate the TDs (deferring hash chain updates) */
++ for (i = 0; i < size; i++) {
++ urb_priv->td [i] = td_alloc (ohci, mem_flags);
++ if (!urb_priv->td [i]) {
++ urb_priv->length = i;
++ urb_free_priv (ohci, urb_priv);
++ return -ENOMEM;
++ }
++ }
++
++ spin_lock_irqsave (&ohci->lock, flags);
++
++ /* don't submit to a dead HC */
++ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
++ retval = -ENODEV;
++ goto fail;
++ }
++ if (!HC_IS_RUNNING(hcd->state)) {
++ retval = -ENODEV;
++ goto fail;
++ }
++ retval = usb_hcd_link_urb_to_ep(hcd, urb);
++ if (retval)
++ goto fail;
++
++ /* schedule the ed if needed */
++ if (ed->state == ED_IDLE) {
++ retval = ed_schedule (ohci, ed);
++ if (retval < 0) {
++ usb_hcd_unlink_urb_from_ep(hcd, urb);
++ goto fail;
++ }
++ if (ed->type == PIPE_ISOCHRONOUS) {
++ u16 frame = ohci_frame_no(ohci);
++
++ /* delay a few frames before the first TD */
++ frame += max_t (u16, 8, ed->interval);
++ frame &= ~(ed->interval - 1);
++ frame |= ed->branch;
++ urb->start_frame = frame;
++
++ /* yes, only URB_ISO_ASAP is supported, and
++ * urb->start_frame is never used as input.
++ */
++ }
++ } else if (ed->type == PIPE_ISOCHRONOUS)
++ urb->start_frame = ed->last_iso + ed->interval;
++
++ /* fill the TDs and link them to the ed; and
++ * enable that part of the schedule, if needed
++ * and update count of queued periodic urbs
++ */
++
++ urb->hcpriv = urb_priv;
++ td_submit_urb (ohci, urb);
++
++
++#if 0
++ if(1)
++ {
++ struct td *td;
++ uint32_t *ptr;
++ printk("ed %p / 0x%8x\n", ed, ed->dma);
++ printk(" hwINFO 0x%8x\n", ed->hwINFO);
++ printk(" hwHeadP 0x%8x\n", ed->hwHeadP);
++ printk(" hwNextED 0x%8x\n", ed->hwNextED);
++
++ for (i = 0; i < size; i++)
++ {
++ td = urb_priv->td[i];
++ printk(" td %p / 0x%8x\n", td, td->td_dma);
++ printk(" hwINFO 0x%8x\n", td->hwINFO);
++ printk(" hwCBP 0x%8x\n", td->hwCBP);
++ printk(" hwNextTD 0x%8x\n", td->hwNextTD);
++ printk(" hwBE 0x%8x\n", td->hwBE);
++ }
++
++ ptr = (uint32_t *) hcd->regs;
++
++ printk("ctrl at 0x%p\n", ptr);
++ for (i = 0; i < 0x60; i+=4)
++ {
++ printk(" [0x%2x] 0x%8x\n", i, ptr[i/4]);
++ }
++
++
++ }
++#endif
++
++ /* maybe kickstart control list */
++ wmb ();
++ ohci_writel (ohci, OHCI_CLF, &ohci->regs->cmdstatus);
++
++fail:
++ if (retval)
++ urb_free_priv (ohci, urb_priv);
++ spin_unlock_irqrestore (&ohci->lock, flags);
++ return retval;
++
++}
++
++
++static void _free_urb_priv_sram(struct urb *urb)
++{
++ urb_priv_t *urb_priv;
++ urb_priv = urb->hcpriv;
++
++ if (urb_priv == NULL)
++ {
++ printk(KERN_DEBUG "Potential memory leak\n");
++ return ;
++ }
++
++ if (urb_priv->urb_data)
++ {
++ if (usb_pipein(urb->pipe) )
++ {
++
++ dmac_flush_range(urb->transfer_buffer, (uint8_t *) urb->transfer_buffer + urb->actual_length );
++ memcpy(urb_priv->urb_data, urb->transfer_buffer, urb->actual_length);
++ }
++
++ tmpa9x0_sram_free( (a32) urb->transfer_buffer );
++
++ urb->transfer_buffer = urb_priv->urb_data;
++ urb->transfer_dma = urb_priv->urb_data_dma;
++ }
++
++ if (urb_priv->urb_setup)
++ {
++ tmpa9x0_sram_free( (a32) urb->setup_packet);
++
++ urb->setup_packet = urb_priv->urb_setup;
++ urb->setup_dma = urb_priv->urb_setup_dma;
++ }
++}
++
++/*
++ * decouple the URB from the HC queues (TDs, urb_priv).
++ * reporting is always done
++ * asynchronously, and we might be dealing with an urb that's
++ * partially transferred, or an ED with other urbs being unlinked.
++ */
++static int tmpa9x0_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
++{
++ int ret;
++
++ printk(KERN_DEBUG "data at 0x%p / phys 0x%8x, len %d\n", urb->transfer_buffer, urb->transfer_dma, urb->transfer_buffer_length);
++
++ _free_urb_priv_sram(urb);
++
++ ret = ohci_urb_dequeue(hcd, urb, status);
++
++ return ret;
++}
++
++
++void tmpa9x0_usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
++{
++ _free_urb_priv_sram(urb);
++
++ usb_hcd_giveback_urb(hcd, urb, status);
++}
++
++/*-------------------------------------------------------------------------*/
++
++static const struct hc_driver ohci_tmpa900_hc_driver = {
++ .description = hcd_name,
++ .product_desc = "tmpa900 OHCI",
++ .hcd_priv_size = sizeof(struct ohci_hcd),
++
++ /*
++ * generic hardware linkage
++ */
++ .irq = tmpa9x0_ohci_irq,
++ .flags = HCD_USB11 | HCD_MEMORY,
++
++ /*
++ * basic lifecycle operations
++ */
++ .reset = ohci_tmpa900_init,
++ .start = ohci_tmpa900_start,
++ .stop = tmpa9x0_ohci_stop,
++ .shutdown = ohci_shutdown,
++
++ /*
++ * managing i/o requests and associated device resources
++ */
++ .urb_enqueue = tmpa9x0_urb_enqueue,
++ .urb_dequeue = tmpa9x0_urb_dequeue,
++ .endpoint_disable = ohci_endpoint_disable,
++
++ /*
++ * scheduling support
++ */
++ .get_frame_number = ohci_get_frame,
++
++ /*
++ * root hub support
++ */
++ .hub_status_data = ohci_hub_status_data,
++ .hub_control = ohci_hub_control,
++#warning check this, renamed?
++// .hub_irq_enable = ohci_rhsc_enable,
++#ifdef CONFIG_PM
++ .bus_suspend = ohci_bus_suspend,
++ .bus_resume = ohci_bus_resume,
++#endif
++ .start_port_reset = ohci_start_port_reset,
++};
++
++
++
++/* Check for NEC chip and apply quirk for allegedly lost interrupts.
++ */
++
++static void ohci_quirk_nec_worker(struct work_struct *work)
++{
++ struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work);
++ int status;
++
++ status = ohci_init(ohci);
++ if (status != 0) {
++ ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n",
++ "ohci_init", status);
++ return;
++ }
++
++ status = ohci_restart(ohci);
++ if (status != 0)
++ ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n",
++ "ohci_restart", status);
++
++}
++
++static int ohci_quirk_nec(struct usb_hcd *hcd)
++{
++ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
++
++ ohci->flags |= OHCI_QUIRK_NEC;
++ INIT_WORK(&ohci->nec_work, ohci_quirk_nec_worker);
++ ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n");
++
++ return 0;
++}
++
++
++/*-------------------------------------------------------------------------*/
++
++static int ohci_hcd_tmpa900_drv_probe(struct platform_device *pdev)
++{
++ const struct hc_driver *driver = &ohci_tmpa900_hc_driver;
++ struct device *dev = &pdev->dev;
++ struct resource *res, *mem;
++ int retval, irq;
++ struct usb_hcd *hcd = NULL;
++ void *sram_virt;
++ irq = retval = platform_get_irq(pdev, 0);
++ if (retval < 0)
++ goto err0;
++
++ ohci_usb_hcd_giveback_urb = tmpa9x0_usb_hcd_giveback_urb;
++
++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ if (mem == NULL) {
++ dev_err(dev, "no resource definition for memory\n");
++ retval = -ENOENT;
++ goto err0;
++ }
++
++ if (!request_mem_region(mem->start, mem->end - mem->start + 1,
++ pdev->name)) {
++ dev_err(dev, "request_mem_region failed\n");
++ retval = -EBUSY;
++ goto err0;
++ }
++
++ printk(KERN_DEBUG "SRAM at 0x%x 0x%x 0x%x\n",
++ mem->start,
++ mem->start - mem->parent->start,
++ (mem->end - mem->start) + 1);
++
++ sram_virt = ioremap(mem->start, SRAMSIZE);
++ if (!sram_virt) {
++ dev_err(dev, "cannot remap sram\n");
++ retval = -ENXIO;
++ goto err1;
++ }
++
++ printk(KERN_DEBUG "SRAM at 0x%x / 0x%p\n",mem->start, sram_virt);
++
++ tmpa9x0_sram_init( (a32) sram_virt, mem->start);
++
++ /* allocate, reserve and remap resources for registers */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (res == NULL) {
++ dev_err(dev, "no resource definition for registers\n");
++ retval = -ENOENT;
++ goto err2;
++ }
++
++ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
++ if (!hcd) {
++ retval = -ENOMEM;
++ goto err2;
++ }
++
++ hcd->rsrc_start = res->start;
++ hcd->rsrc_len = res->end - res->start + 1;
++
++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, pdev->name)) {
++ dev_err(dev, "request_mem_region failed\n");
++ retval = -EBUSY;
++ goto err3;
++ }
++
++ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
++ if (hcd->regs == NULL) {
++ dev_err(dev, "cannot remap registers\n");
++ retval = -ENXIO;
++ goto err4;
++ }
++
++ ohci_hcd_init(hcd_to_ohci(hcd));
++
++ //ohci_quirk_nec(hcd);
++
++ //hcd_to_ohci(hcd)->flags |= OHCI_QUIRK_SUPERIO;
++ //hcd_to_ohci(hcd)->flags |= OHCI_QUIRK_NEC;
++
++ retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
++ if (retval)
++ goto err4;
++
++ /* enable power and unmask interrupts */
++
++
++ return 0;
++err4:
++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++err3:
++ usb_put_hcd(hcd);
++err2:
++ dma_release_declared_memory(dev);
++err1:
++ release_mem_region(mem->start, mem->end - mem->start + 1);
++err0:
++ return retval;
++}
++
++static int ohci_hcd_tmpa900_drv_remove(struct platform_device *pdev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(pdev);
++ struct resource *mem;
++
++ usb_remove_hcd(hcd);
++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++ usb_put_hcd(hcd);
++ dma_release_declared_memory(&pdev->dev);
++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ if (mem)
++ release_mem_region(mem->start, mem->end - mem->start + 1);
++
++ platform_set_drvdata(pdev, NULL);
++ return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++
++#ifdef CONFIG_PM
++static int ohci_tmpa900_suspend(struct platform_device *pdev, pm_message_t msg)
++{
++ struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(pdev));
++
++ if (time_before(jiffies, ohci->next_statechange))
++ msleep(5);
++ ohci->next_statechange = jiffies;
++
++
++ ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
++ return 0;
++}
++
++static int ohci_tmpa900_resume(struct platform_device *pdev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(pdev);
++ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++
++ if (time_before(jiffies, ohci->next_statechange))
++ msleep(5);
++ ohci->next_statechange = jiffies;
++
++
++ ohci_finish_controller_resume(hcd);
++ return 0;
++}
++#else
++#define ohci_tmpa900_suspend NULL
++#define ohci_tmpa900_resume NULL
++#endif
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * Driver definition to register with the tmpa900 bus
++ */
++static struct platform_driver ohci_hcd_tmpa900_driver = {
++ .probe = ohci_hcd_tmpa900_drv_probe,
++ .remove = ohci_hcd_tmpa900_drv_remove,
++ .shutdown = usb_hcd_platform_shutdown,
++ .suspend = ohci_tmpa900_suspend,
++ .resume = ohci_tmpa900_resume,
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "tmpa900-usb",
++ },
++};
++MODULE_ALIAS("platform:tmpa900-usb");
+diff --git a/drivers/usb/host/ohci-tmpa900_sram.c b/drivers/usb/host/ohci-tmpa900_sram.c
+new file mode 100644
+index 0000000..05bc2b7
+--- /dev/null
++++ b/drivers/usb/host/ohci-tmpa900_sram.c
+@@ -0,0 +1,184 @@
++//typedef unsigned long a32;
++
++// mem sizes we are dealing with
++#define CACHELINESIZE 0x20
++#define CACHELINEMASK 0x1F
++#define SRAMSIZE (8*1024)
++
++// used constants
++#define ALLOC_BITMAP_FREE 0
++#define ALLOC_BITMAP_USED 1
++#define ALLOC_BITMAP_LAST 3
++
++// with byte bitmap we need 512 bytes versus 32 byte for 2 bit entry
++// additionaly code for 2bit entry will exceed savings in array size
++#define ALLOC_BITMAP_SIZE (SRAMSIZE/CACHELINESIZE)
++
++static unsigned char g_sram_alloc_bitmap[ALLOC_BITMAP_SIZE];
++static a32 g_sram_base = 0xFFFFFFFF;
++static a32 g_sram_phys = 0xFFFFFFFF;
++/*
++ * init allocator
++ * set all to free, init base
++ *
++ */
++
++static spinlock_t sram_lock;
++
++// convert virt sram address to phys
++static unsigned int tmpa9x0_sram_to_phys(void *virt_sram)
++{
++ return ((unsigned int) virt_sram - (unsigned int) g_sram_base ) + g_sram_phys;
++}
++
++
++static void tmpa9x0_sram_init(a32 sram_base, a32 phys_base){
++ int i;
++
++ if (g_sram_base != 0xFFFFFFFF)
++ return;
++
++
++ g_sram_phys = phys_base;
++
++ // set global base
++ g_sram_base=sram_base;
++
++ spin_lock_init(&sram_lock);
++
++ // set global alloc bitmap
++ for( i = 0 ; i < ALLOC_BITMAP_SIZE ; i++)
++ g_sram_alloc_bitmap[i]=ALLOC_BITMAP_FREE;
++
++ // done
++ return;
++}
++
++/*
++ * alloc from sram pool with given alignment
++ * minimum size is CACHELINESIZE with CACHELINE align
++ * NOTE: time to find a free memory range raises with
++ * bitmap size/and !free entries
++ */
++static a32 tmpa9x0_sram_alloc(unsigned long size, unsigned long align){
++ unsigned long s_current,step,needed,i,last;
++ unsigned long flags;
++
++ // init?
++ if( g_sram_base == 0xFFFFFFFF )
++ return 0;
++
++ // check size
++ if( size == 0 )
++ return 0;
++
++ else if( size & CACHELINEMASK )
++ size = (size + CACHELINEMASK) & ~CACHELINEMASK;
++
++ // see your local sram dealer first
++ if( size > SRAMSIZE )
++ return 0;
++
++ //check align
++ if( align == 0)
++ align = CACHELINESIZE;
++ else if( align & CACHELINEMASK )
++ align = (align + CACHELINEMASK) & ~CACHELINEMASK;
++
++ // assume sram_base is aligned to SRAMSIZE, we can allways align within SRAMSIZE
++ if( align > SRAMSIZE )
++ return 0;
++
++ // scan bitmap for a valid/free block
++ step = align/CACHELINESIZE;
++ needed = size/CACHELINESIZE;
++ last = ALLOC_BITMAP_SIZE - needed + 1 ;
++
++ spin_lock_irqsave (&sram_lock, flags);
++
++ for( s_current = 0 ; s_current < last ; s_current += step ){
++ // check free
++ for( i = 0; i < needed ; i++ )
++ {
++ if( g_sram_alloc_bitmap[s_current + i] != ALLOC_BITMAP_FREE )
++ {
++ goto next_block;
++ }
++ }
++ // mark used
++ for( i = 0; i < needed ; i++ ){
++ g_sram_alloc_bitmap[s_current + i] = ALLOC_BITMAP_USED;
++ }
++ g_sram_alloc_bitmap[s_current + i - 1 ] = ALLOC_BITMAP_LAST;
++
++ // return result
++ // NPRINTK("return 0x%8.8x, s_current=%d, i=%d\n", (g_sram_base + s_current*CACHELINESIZE), s_current, i);
++ spin_unlock_irqrestore (&sram_lock, flags);
++
++ return (g_sram_base + s_current*CACHELINESIZE);
++next_block:;
++ }
++
++#if 0
++ if (printk_ratelimit())
++ printk("Out of SRAM %d\n", size);
++#endif
++ spin_unlock_irqrestore (&sram_lock, flags);
++ return 0;
++}
++
++/*
++ * free block allocated from sram pool
++ *
++ */
++static void tmpa9x0_sram_free(a32 block){
++ unsigned long tofree,i,size;
++ unsigned long flags;
++ //NPRINTK("block=%p\n",block);
++
++ // zero block
++ if( !block )
++ return;
++
++ // cheating address
++ if( block & CACHELINEMASK )
++ return;
++
++ // out of range (low)
++ if( block < g_sram_base )
++ return;
++
++ // out of range (hi)
++ if( (tofree = ((block - g_sram_base)/CACHELINESIZE)) >= ALLOC_BITMAP_SIZE )
++ return;
++
++ // check bitmap valid at start pos
++ if( tofree && (g_sram_alloc_bitmap[tofree-1] == ALLOC_BITMAP_USED ))
++ return;
++
++
++spin_lock_irqsave (&sram_lock, flags);
++
++ // find size of block
++ for( size = 0 , i = tofree ; i < ALLOC_BITMAP_SIZE ; i++ ){
++ // done bitmap corrupted ?!
++ if( g_sram_alloc_bitmap[i] == ALLOC_BITMAP_FREE )
++ goto end;
++ // used entry
++ if( g_sram_alloc_bitmap[i] == ALLOC_BITMAP_USED )
++ size++;
++ // last entry
++ if( g_sram_alloc_bitmap[i] == ALLOC_BITMAP_LAST ){
++ size++;
++ // mark free
++ for( i = 0; i < size ; i++ )
++ g_sram_alloc_bitmap[tofree + i] = ALLOC_BITMAP_FREE;
++ // done OK
++
++ goto end;
++ }
++ }
++
++end:
++ spin_unlock_irqrestore (&sram_lock, flags);
++}
+diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
+index 5bf15fe..c400ec3 100644
+--- a/drivers/usb/host/ohci.h
++++ b/drivers/usb/host/ohci.h
+@@ -328,6 +328,12 @@ typedef struct urb_priv {
+ u16 length; // # tds in this request
+ u16 td_cnt; // tds already serviced
+ struct list_head pending;
++#ifdef CONFIG_USB_OHCI_HCD_TMPA900
++ void *urb_data;
++ dma_addr_t urb_data_dma;
++ void *urb_setup;
++ dma_addr_t urb_setup_dma;
++#endif
+ struct td *td [0]; // all TDs in this request
+
+ } urb_priv_t;
+@@ -421,7 +427,7 @@ struct ohci_hcd {
+ #endif
+ };
+
+-#ifdef CONFIG_PCI
++#if 1
+ static inline int quirk_nec(struct ohci_hcd *ohci)
+ {
+ return ohci->flags & OHCI_QUIRK_NEC;
+diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
+index 9260c74..e33d362 100644
+--- a/drivers/usb/host/r8a66597-hcd.c
++++ b/drivers/usb/host/r8a66597-hcd.c
+@@ -35,9 +35,7 @@
+ #include <linux/usb.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
+-#include <linux/mm.h>
+ #include <linux/irq.h>
+-#include <asm/cacheflush.h>
+
+ #include "../core/hcd.h"
+ #include "r8a66597.h"
+@@ -218,17 +216,8 @@ static void disable_controller(struct r8a66597 *r8a66597)
+ {
+ int port;
+
+- /* disable interrupts */
+ r8a66597_write(r8a66597, 0, INTENB0);
+- r8a66597_write(r8a66597, 0, INTENB1);
+- r8a66597_write(r8a66597, 0, BRDYENB);
+- r8a66597_write(r8a66597, 0, BEMPENB);
+- r8a66597_write(r8a66597, 0, NRDYENB);
+-
+- /* clear status */
+- r8a66597_write(r8a66597, 0, BRDYSTS);
+- r8a66597_write(r8a66597, 0, NRDYSTS);
+- r8a66597_write(r8a66597, 0, BEMPSTS);
++ r8a66597_write(r8a66597, 0, INTSTS0);
+
+ for (port = 0; port < r8a66597->max_root_hub; port++)
+ r8a66597_disable_port(r8a66597, port);
+@@ -822,26 +811,6 @@ static void enable_r8a66597_pipe(struct r8a66597 *r8a66597, struct urb *urb,
+ enable_r8a66597_pipe_dma(r8a66597, dev, pipe, urb);
+ }
+
+-static void r8a66597_urb_done(struct r8a66597 *r8a66597, struct urb *urb,
+- int status)
+-__releases(r8a66597->lock)
+-__acquires(r8a66597->lock)
+-{
+- if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) {
+- void *ptr;
+-
+- for (ptr = urb->transfer_buffer;
+- ptr < urb->transfer_buffer + urb->transfer_buffer_length;
+- ptr += PAGE_SIZE)
+- flush_dcache_page(virt_to_page(ptr));
+- }
+-
+- usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb);
+- spin_unlock(&r8a66597->lock);
+- usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb, status);
+- spin_lock(&r8a66597->lock);
+-}
+-
+ /* this function must be called with interrupt disabled */
+ static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address)
+ {
+@@ -862,9 +831,15 @@ static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address)
+ list_del(&td->queue);
+ kfree(td);
+
+- if (urb)
+- r8a66597_urb_done(r8a66597, urb, -ENODEV);
++ if (urb) {
++ usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597),
++ urb);
+
++ spin_unlock(&r8a66597->lock);
++ usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb,
++ -ENODEV);
++ spin_lock(&r8a66597->lock);
++ }
+ break;
+ }
+ }
+@@ -1301,7 +1276,10 @@ __releases(r8a66597->lock) __acquires(r8a66597->lock)
+ if (usb_pipeisoc(urb->pipe))
+ urb->start_frame = r8a66597_get_frame(hcd);
+
+- r8a66597_urb_done(r8a66597, urb, status);
++ usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb);
++ spin_unlock(&r8a66597->lock);
++ usb_hcd_giveback_urb(hcd, urb, status);
++ spin_lock(&r8a66597->lock);
+ }
+
+ if (restart) {
+@@ -2492,12 +2470,6 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
+ r8a66597->rh_timer.data = (unsigned long)r8a66597;
+ r8a66597->reg = (unsigned long)reg;
+
+- /* make sure no interrupts are pending */
+- ret = r8a66597_clock_enable(r8a66597);
+- if (ret < 0)
+- goto clean_up3;
+- disable_controller(r8a66597);
+-
+ for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) {
+ INIT_LIST_HEAD(&r8a66597->pipe_queue[i]);
+ init_timer(&r8a66597->td_timer[i]);
+diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
+index 99cd00f..5cd0e48 100644
+--- a/drivers/usb/host/uhci-hcd.c
++++ b/drivers/usb/host/uhci-hcd.c
+@@ -749,20 +749,7 @@ static int uhci_rh_suspend(struct usb_hcd *hcd)
+ spin_lock_irq(&uhci->lock);
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
+ rc = -ESHUTDOWN;
+- else if (uhci->dead)
+- ; /* Dead controllers tell no tales */
+-
+- /* Once the controller is stopped, port resumes that are already
+- * in progress won't complete. Hence if remote wakeup is enabled
+- * for the root hub and any ports are in the middle of a resume or
+- * remote wakeup, we must fail the suspend.
+- */
+- else if (hcd->self.root_hub->do_remote_wakeup &&
+- uhci->resuming_ports) {
+- dev_dbg(uhci_dev(uhci), "suspend failed because a port "
+- "is resuming\n");
+- rc = -EBUSY;
+- } else
++ else if (!uhci->dead)
+ suspend_rh(uhci, UHCI_RH_SUSPENDED);
+ spin_unlock_irq(&uhci->lock);
+ return rc;
+diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
+index 8270055..885b585 100644
+--- a/drivers/usb/host/uhci-hub.c
++++ b/drivers/usb/host/uhci-hub.c
+@@ -167,7 +167,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
+ /* Port received a wakeup request */
+ set_bit(port, &uhci->resuming_ports);
+ uhci->ports_timeout = jiffies +
+- msecs_to_jiffies(25);
++ msecs_to_jiffies(20);
+
+ /* Make sure we see the port again
+ * after the resuming period is over. */
+diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
+index 62ff5e7..1d8e39a 100644
+--- a/drivers/usb/misc/appledisplay.c
++++ b/drivers/usb/misc/appledisplay.c
+@@ -72,8 +72,8 @@ struct appledisplay {
+ struct usb_device *udev; /* usb device */
+ struct urb *urb; /* usb request block */
+ struct backlight_device *bd; /* backlight device */
+- u8 *urbdata; /* interrupt URB data buffer */
+- u8 *msgdata; /* control message data buffer */
++ char *urbdata; /* interrupt URB data buffer */
++ char *msgdata; /* control message data buffer */
+
+ struct delayed_work work;
+ int button_pressed;
+diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
+index 59860b3..602ee05 100644
+--- a/drivers/usb/misc/emi62.c
++++ b/drivers/usb/misc/emi62.c
+@@ -167,7 +167,7 @@ static int emi62_load_firmware (struct usb_device *dev)
+ err("%s - error loading firmware: error = %d", __func__, err);
+ goto wraperr;
+ }
+- } while (rec);
++ } while (i > 0);
+
+ /* Assert reset (stop the CPU in the EMI) */
+ err = emi62_set_reset(dev,1);
+diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
+index 067e5a9..522efb3 100644
+--- a/drivers/usb/musb/musb_gadget_ep0.c
++++ b/drivers/usb/musb/musb_gadget_ep0.c
+@@ -199,6 +199,7 @@ service_in_request(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest)
+ static void musb_g_ep0_giveback(struct musb *musb, struct usb_request *req)
+ {
+ musb_g_giveback(&musb->endpoints[0].ep_in, req, 0);
++ musb->ep0_state = MUSB_EP0_STAGE_SETUP;
+ }
+
+ /*
+@@ -647,7 +648,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
+ musb->ep0_state = MUSB_EP0_STAGE_STATUSIN;
+ break;
+ default:
+- ERR("SetupEnd came in a wrong ep0stage %s\n",
++ ERR("SetupEnd came in a wrong ep0stage %s",
+ decode_ep0stage(musb->ep0_state));
+ }
+ csr = musb_readw(regs, MUSB_CSR0);
+@@ -770,18 +771,12 @@ setup:
+ handled = service_zero_data_request(
+ musb, &setup);
+
+- /*
+- * We're expecting no data in any case, so
+- * always set the DATAEND bit -- doing this
+- * here helps avoid SetupEnd interrupt coming
+- * in the idle stage when we're stalling...
+- */
+- musb->ackpend |= MUSB_CSR0_P_DATAEND;
+-
+ /* status stage might be immediate */
+- if (handled > 0)
++ if (handled > 0) {
++ musb->ackpend |= MUSB_CSR0_P_DATAEND;
+ musb->ep0_state =
+ MUSB_EP0_STAGE_STATUSIN;
++ }
+ break;
+
+ /* sequence #1 (IN to host), includes GET_STATUS
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 13a1b39..ebcc6d0 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -598,20 +598,6 @@ static struct usb_device_id id_table_combined [] = {
+ { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
+ { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_USOPTL4_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_USPTL4_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_2_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR2_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_485USB9F_2W_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_485USB9F_4W_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_232USB9M_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_485USBTB_2W_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_485USBTB_4W_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_TTL5USB9M_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_TTL3USB9M_PID) },
+- { USB_DEVICE(BANDB_VID, BANDB_ZZ_PROG1_USB_PID) },
+ { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) },
+ { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
+diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
+index 4586a24..6f31e0d 100644
+--- a/drivers/usb/serial/ftdi_sio.h
++++ b/drivers/usb/serial/ftdi_sio.h
+@@ -662,20 +662,6 @@
+ #define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */
+ #define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */
+ #define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */
+-#define BANDB_USOPTL4_PID 0xAC11
+-#define BANDB_USPTL4_PID 0xAC12
+-#define BANDB_USO9ML2DR_2_PID 0xAC16
+-#define BANDB_USO9ML2DR_PID 0xAC17
+-#define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */
+-#define BANDB_USOPTL4DR_PID 0xAC19
+-#define BANDB_485USB9F_2W_PID 0xAC25
+-#define BANDB_485USB9F_4W_PID 0xAC26
+-#define BANDB_232USB9M_PID 0xAC27
+-#define BANDB_485USBTB_2W_PID 0xAC33
+-#define BANDB_485USBTB_4W_PID 0xAC34
+-#define BANDB_TTL5USB9M_PID 0xAC49
+-#define BANDB_TTL3USB9M_PID 0xAC50
+-#define BANDB_ZZ_PROG1_USB_PID 0xBA02
+
+ /*
+ * RM Michaelides CANview USB (http://www.rmcan.com)
+diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
+index e0fb294..bbe005c 100644
+--- a/drivers/usb/serial/generic.c
++++ b/drivers/usb/serial/generic.c
+@@ -489,8 +489,6 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
+ dbg("%s - port %d", __func__, port->number);
+
+ if (port->serial->type->max_in_flight_urbs) {
+- kfree(urb->transfer_buffer);
+-
+ spin_lock_irqsave(&port->lock, flags);
+ --port->urbs_in_flight;
+ port->tx_bytes_flight -= urb->transfer_buffer_length;
+diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
+index 485fa9c..f11abf5 100644
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -121,14 +121,8 @@
+ * moschip_id_table_combined
+ */
+ #define USB_VENDOR_ID_BANDB 0x0856
+-#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22
+-#define BANDB_DEVICE_ID_USO9ML2_4 0xAC24
+-#define BANDB_DEVICE_ID_US9ML2_2 0xAC29
+-#define BANDB_DEVICE_ID_US9ML2_4 0xAC30
+-#define BANDB_DEVICE_ID_USPTL4_2 0xAC31
+-#define BANDB_DEVICE_ID_USPTL4_4 0xAC32
+-#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
+ #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44
++#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
+
+ /* This driver also supports
+ * ATEN UC2324 device using Moschip MCS7840
+@@ -183,14 +177,8 @@
+ static struct usb_device_id moschip_port_id_table[] = {
+ {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
+ {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
++ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+ {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
+ {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
+ {} /* terminating entry */
+@@ -199,14 +187,8 @@ static struct usb_device_id moschip_port_id_table[] = {
+ static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
+ {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
+ {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
+- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
++ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+ {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
+ {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
+ {} /* terminating entry */
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index be3dff1..0577e4b 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -340,10 +340,6 @@ static int option_resume(struct usb_serial *serial);
+ #define FOUR_G_SYSTEMS_VENDOR_ID 0x1c9e
+ #define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603
+
+-/* Haier products */
+-#define HAIER_VENDOR_ID 0x201e
+-#define HAIER_PRODUCT_CE100 0x2009
+-
+ static struct usb_device_id option_ids[] = {
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
+@@ -584,48 +580,12 @@ static struct usb_device_id option_ids[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0154, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
+@@ -639,13 +599,11 @@ static struct usb_device_id option_ids[] = {
+ { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
+ { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
+ { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
+- { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
+ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
+ { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
+ { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
+ { USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) },
+- { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
+ { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
+diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
+index cfa26d5..db3dbca 100644
+--- a/drivers/usb/storage/scsiglue.c
++++ b/drivers/usb/storage/scsiglue.c
+@@ -537,12 +537,17 @@ struct scsi_host_template usb_stor_host_template = {
+ .slave_alloc = slave_alloc,
+ .slave_configure = slave_configure,
+
++#ifdef CONFIG_USB_OHCI_HCD_TMPA900
++// Limit the tranfer as far as we can to workaround hardware issue
++ .sg_tablesize = 1,
++ .max_sectors = 1,
++#else
+ /* lots of sg segments can be handled */
+ .sg_tablesize = SG_ALL,
+
+ /* limit the total size of a transfer to 120 KB */
+ .max_sectors = 240,
+-
++#endif
+ /* merge commands... this seems to help performance, but
+ * periodically someone should test to see which setting is more
+ * optimal.
+diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
+index cc313d1..589f6b4 100644
+--- a/drivers/usb/storage/transport.c
++++ b/drivers/usb/storage/transport.c
+@@ -666,11 +666,10 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
+ * to wait for at least one CHECK_CONDITION to determine
+ * SANE_SENSE support
+ */
+- if (unlikely((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) &&
++ if ((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) &&
+ result == USB_STOR_TRANSPORT_GOOD &&
+ !(us->fflags & US_FL_SANE_SENSE) &&
+- !(us->fflags & US_FL_BAD_SENSE) &&
+- !(srb->cmnd[2] & 0x20))) {
++ !(srb->cmnd[2] & 0x20)) {
+ US_DEBUGP("-- SAT supported, increasing auto-sense\n");
+ us->fflags |= US_FL_SANE_SENSE;
+ }
+@@ -719,12 +718,6 @@ Retry_Sense:
+ if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
+ US_DEBUGP("-- auto-sense aborted\n");
+ srb->result = DID_ABORT << 16;
+-
+- /* If SANE_SENSE caused this problem, disable it */
+- if (sense_size != US_SENSE_SIZE) {
+- us->fflags &= ~US_FL_SANE_SENSE;
+- us->fflags |= US_FL_BAD_SENSE;
+- }
+ goto Handle_Errors;
+ }
+
+@@ -734,11 +727,10 @@ Retry_Sense:
+ * (small) sense request. This fixes some USB GSM modems
+ */
+ if (temp_result == USB_STOR_TRANSPORT_FAILED &&
+- sense_size != US_SENSE_SIZE) {
++ (us->fflags & US_FL_SANE_SENSE) &&
++ sense_size != US_SENSE_SIZE) {
+ US_DEBUGP("-- auto-sense failure, retry small sense\n");
+ sense_size = US_SENSE_SIZE;
+- us->fflags &= ~US_FL_SANE_SENSE;
+- us->fflags |= US_FL_BAD_SENSE;
+ goto Retry_Sense;
+ }
+
+@@ -762,7 +754,6 @@ Retry_Sense:
+ */
+ if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) &&
+ !(us->fflags & US_FL_SANE_SENSE) &&
+- !(us->fflags & US_FL_BAD_SENSE) &&
+ (srb->sense_buffer[0] & 0x7C) == 0x70) {
+ US_DEBUGP("-- SANE_SENSE support enabled\n");
+ us->fflags |= US_FL_SANE_SENSE;
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index c932f90..d4f034e 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -818,13 +818,6 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
+-/* Reported by Daniel Kukula <daniel.kuku at gmail.com> */
+-UNUSUAL_DEV( 0x067b, 0x1063, 0x0100, 0x0100,
+- "Prolific Technology, Inc.",
+- "Prolific Storage Gadget",
+- US_SC_DEVICE, US_PR_DEVICE, NULL,
+- US_FL_BAD_SENSE ),
+-
+ /* Reported by Rogerio Brito <rbrito at ime.usp.br> */
+ UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001,
+ "Prolific Technology, Inc.",
+@@ -1807,6 +1800,13 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999,
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_GO_SLOW ),
+
++/* Reported by Rohan Hart <rohan.hart17 at gmail.com> */
++UNUSUAL_DEV( 0x2770, 0x915d, 0x0010, 0x0010,
++ "INTOVA",
++ "Pixtreme",
++ US_SC_DEVICE, US_PR_DEVICE, NULL,
++ US_FL_FIX_CAPACITY ),
++
+ /* Reported by Frederic Marchal <frederic.marchal at wowcompany.com>
+ * Mio Moov 330
+ */
+diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
+index 33197fa..8060b85 100644
+--- a/drivers/usb/storage/usb.c
++++ b/drivers/usb/storage/usb.c
+@@ -228,7 +228,6 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
+ if (data_len<36) // You lose.
+ return;
+
+- memset(data+8, ' ', 28);
+ if(data[0]&0x20) { /* USB device currently not connected. Return
+ peripheral qualifier 001b ("...however, the
+ physical device is not currently connected
+@@ -238,15 +237,15 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
+ device, it may return zeros or ASCII spaces
+ (20h) in those fields until the data is
+ available from the device."). */
++ memset(data+8,0,28);
+ } else {
+ u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
+- int n;
+-
+- n = strlen(us->unusual_dev->vendorName);
+- memcpy(data+8, us->unusual_dev->vendorName, min(8, n));
+- n = strlen(us->unusual_dev->productName);
+- memcpy(data+16, us->unusual_dev->productName, min(16, n));
+-
++ memcpy(data+8, us->unusual_dev->vendorName,
++ strlen(us->unusual_dev->vendorName) > 8 ? 8 :
++ strlen(us->unusual_dev->vendorName));
++ memcpy(data+16, us->unusual_dev->productName,
++ strlen(us->unusual_dev->productName) > 16 ? 16 :
++ strlen(us->unusual_dev->productName));
+ data[32] = 0x30 + ((bcdDevice>>12) & 0x0F);
+ data[33] = 0x30 + ((bcdDevice>>8) & 0x0F);
+ data[34] = 0x30 + ((bcdDevice>>4) & 0x0F);
+@@ -430,8 +429,7 @@ static void adjust_quirks(struct us_data *us)
+ u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor);
+ u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
+ unsigned f = 0;
+- unsigned int mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE |
+- US_FL_FIX_CAPACITY |
++ unsigned int mask = (US_FL_SANE_SENSE | US_FL_FIX_CAPACITY |
+ US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE |
+ US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
+ US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
+@@ -461,9 +459,6 @@ static void adjust_quirks(struct us_data *us)
+ case 'a':
+ f |= US_FL_SANE_SENSE;
+ break;
+- case 'b':
+- f |= US_FL_BAD_SENSE;
+- break;
+ case 'c':
+ f |= US_FL_FIX_CAPACITY;
+ break;
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 188e1ba..d48718a 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -924,6 +924,14 @@ config FB_EPSON1355
+ framebuffer. Product specs at
+ <http://www.erd.epson.com/vdc/html/products.htm>.
+
++
++config FB_TMPA910
++ bool "Tohiba TMPA910 buffer device support"
++ depends on (FB = y) && (ARCH_TMPA910)
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++
+ config FB_S1D13XXX
+ tristate "Epson S1D13XXX framebuffer support"
+ depends on FB
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index 80232e1..3acf77a 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -127,6 +127,7 @@ obj-$(CONFIG_FB_OMAP) += omap/
+ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
+ obj-$(CONFIG_FB_CARMINE) += carminefb.o
+ obj-$(CONFIG_FB_MB862XX) += mb862xx/
++obj-$(CONFIG_FB_TMPA910) += tmpa910_fb.o
+ obj-$(CONFIG_FB_MSM) += msm/
+
+ # Platform or fallback drivers go here
+diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
+index b4b6dec..66358fa 100644
+--- a/drivers/video/imxfb.c
++++ b/drivers/video/imxfb.c
+@@ -593,8 +593,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
+ */
+ static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
+ {
+- struct fb_info *info = platform_get_drvdata(dev);
+- struct imxfb_info *fbi = info->par;
++ struct imxfb_info *fbi = platform_get_drvdata(dev);
+
+ pr_debug("%s\n", __func__);
+
+@@ -604,8 +603,7 @@ static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
+
+ static int imxfb_resume(struct platform_device *dev)
+ {
+- struct fb_info *info = platform_get_drvdata(dev);
+- struct imxfb_info *fbi = info->par;
++ struct imxfb_info *fbi = platform_get_drvdata(dev);
+
+ pr_debug("%s\n", __func__);
+
+diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c
+index c15f8a5..09f6e04 100644
+--- a/drivers/video/matrox/g450_pll.c
++++ b/drivers/video/matrox/g450_pll.c
+@@ -368,8 +368,7 @@ static int __g450_setclk(struct matrox_fb_info *minfo, unsigned int fout,
+ M1064_XDVICLKCTRL_C1DVICLKEN |
+ M1064_XDVICLKCTRL_DVILOOPCTL |
+ M1064_XDVICLKCTRL_P1LOOPBWDTCTL;
+- /* Setting this breaks PC systems so don't do it */
+- /* matroxfb_DAC_out(minfo, M1064_XDVICLKCTRL, tmp); */
++ matroxfb_DAC_out(minfo, M1064_XDVICLKCTRL, tmp);
+ matroxfb_DAC_out(minfo, M1064_XPWRCTRL,
+ xpwrctrl);
+
+diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
+index 772ba3f..054ef29 100644
+--- a/drivers/video/mx3fb.c
++++ b/drivers/video/mx3fb.c
+@@ -324,11 +324,8 @@ static void sdc_enable_channel(struct mx3fb_info *mx3_fbi)
+ unsigned long flags;
+ dma_cookie_t cookie;
+
+- if (mx3_fbi->txd)
+- dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi,
+- to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg);
+- else
+- dev_dbg(mx3fb->dev, "mx3fbi %p, txd = NULL\n", mx3_fbi);
++ dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi,
++ to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg);
+
+ /* This enables the channel */
+ if (mx3_fbi->cookie < 0) {
+@@ -649,7 +646,6 @@ static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t a
+
+ static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value)
+ {
+- dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value);
+ /* This might be board-specific */
+ mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL);
+ return;
+@@ -1490,12 +1486,12 @@ static int mx3fb_probe(struct platform_device *pdev)
+ goto ersdc0;
+ }
+
+- mx3fb->backlight_level = 255;
+-
+ ret = init_fb_chan(mx3fb, to_idmac_chan(chan));
+ if (ret < 0)
+ goto eisdc0;
+
++ mx3fb->backlight_level = 255;
++
+ return 0;
+
+ eisdc0:
+diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
+index 53cb722..adf9632 100644
+--- a/drivers/video/s3c-fb.c
++++ b/drivers/video/s3c-fb.c
+@@ -211,23 +211,21 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
+
+ /**
+ * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock.
++ * @id: window id.
+ * @sfb: The hardware state.
+ * @pixclock: The pixel clock wanted, in picoseconds.
+ *
+ * Given the specified pixel clock, work out the necessary divider to get
+ * close to the output frequency.
+ */
+-static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
++static int s3c_fb_calc_pixclk(unsigned char id, struct s3c_fb *sfb, unsigned int pixclk)
+ {
++ struct s3c_fb_pd_win *win = sfb->pdata->win[id];
+ unsigned long clk = clk_get_rate(sfb->bus_clk);
+- unsigned long long tmp;
+ unsigned int result;
+
+- tmp = (unsigned long long)clk;
+- tmp *= pixclk;
+-
+- do_div(tmp, 1000000000UL);
+- result = (unsigned int)tmp / 1000;
++ pixclk *= win->win_mode.refresh;
++ result = clk / pixclk;
+
+ dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n",
+ pixclk, clk, result, clk / result);
+@@ -303,7 +301,7 @@ static int s3c_fb_set_par(struct fb_info *info)
+ /* use window 0 as the basis for the lcd output timings */
+
+ if (win_no == 0) {
+- clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock);
++ clkdiv = s3c_fb_calc_pixclk(win_no, sfb, var->pixclock);
+
+ data = sfb->pdata->vidcon0;
+ data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
+diff --git a/drivers/video/tmpa910_fb.c b/drivers/video/tmpa910_fb.c
+new file mode 100644
+index 0000000..76143fa
+--- /dev/null
++++ b/drivers/video/tmpa910_fb.c
+@@ -0,0 +1,396 @@
++/*
++ * linux/drivers/video/tmpa910_lcdc.c -- TMPA910 frame buffer device
++ *
++ * Copyright (C) 2008 bplan GmbH
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file COPYING in the main directory of this archive for
++ * more details.
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <mach/tmpa910_regs.h>
++
++#include <asm/byteorder.h>
++#include <linux/screen_info.h>
++
++#include <video/tmpa910_fb.h>
++
++/********/
++/* Supported palette hacks */
++enum {
++ cmap_unknown,
++};
++struct hw_tmpa910_lcdc
++{
++ uint32_t LCDTiming0; // (LCDC_Base+0x00
++ uint32_t LCDTiming1; // (LCDC_Base+0x04
++ uint32_t LCDTiming2; // (LCDC_Base+0x08
++ uint32_t LCDTiming3; // (LCDC_Base+0x0C
++ uint32_t LCDUPBASE; // (LCDC_Base+0x10
++ uint32_t LCDLPBASE; // (LCDC_Base+0x14
++ uint32_t LCDIMSC; // (LCDC_Base+0x18
++ uint32_t LCDControl; // (LCDC_Base+0x1C
++ uint32_t LCDRIS; // (LCDC_Base+0x20
++ uint32_t LCDMIS; // (LCDC_Base+0x24
++ uint32_t LCDICR; // (LCDC_Base+0x28
++ uint32_t LCDUPCURR; // (LCDC_Base+0x2C
++ uint32_t LCDLPCURR; // (LCDC_Base+0x30
++ uint32_t Rsd[0x1c0]; // Reserved
++ uint32_t LCDPalette; // (LCDC_Base+0x200
++};
++
++struct tmpa910_lcdc_par {
++ volatile void __iomem *cmap_adr;
++ volatile void __iomem *cmap_data;
++ int cmap_type;
++ int blanked;
++ struct hw_tmpa910_lcdc *hw_tmpa910_lcdc;
++};
++
++struct tmpa910_lcdc_par default_par;
++/********/
++/********/
++
++static int tmpa910_lcdc_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
++ u_int transp, struct fb_info *info);
++static int tmpa910_lcdc_blank(int blank, struct fb_info *info);
++
++/********/
++/********/
++static struct fb_ops tmpa910_lcdc_ops = {
++ .owner = THIS_MODULE,
++ .fb_setcolreg = tmpa910_lcdc_setcolreg,
++ .fb_blank = tmpa910_lcdc_blank,
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++};
++
++/******************/
++static void _init_it(struct hw_tmpa910_lcdc *hw_tmpa910_lcdc, uint32_t *LCDReg, int width, int height)
++{
++ LCDDA_LDACR0 = 0x00; /* LCDDA functions off */
++ LCDDA_LDACR1 = (1<<31); /* reset LCDDA */
++
++ hw_tmpa910_lcdc->LCDControl= 0;
++
++ hw_tmpa910_lcdc->LCDTiming0 = LCDReg[0];
++ hw_tmpa910_lcdc->LCDTiming1 = LCDReg[1];
++ hw_tmpa910_lcdc->LCDTiming2 = LCDReg[2];
++ hw_tmpa910_lcdc->LCDTiming3 = LCDReg[3];
++
++ hw_tmpa910_lcdc->LCDUPBASE = 0;
++ hw_tmpa910_lcdc->LCDLPBASE = 0;
++
++ hw_tmpa910_lcdc->LCDIMSC = 0;
++ hw_tmpa910_lcdc->LCDControl = LCDReg[4];
++ barrier();
++}
++
++static void _setup_fb(struct hw_tmpa910_lcdc *hw_tmpa910_lcdc, uint32_t fb_addr)
++{
++ hw_tmpa910_lcdc->LCDUPBASE = fb_addr;
++ hw_tmpa910_lcdc->LCDLPBASE = 0x00;
++ udelay(200);
++ hw_tmpa910_lcdc->LCDControl |= 0x1;
++ barrier();
++}
++
++static void _stop_it(struct hw_tmpa910_lcdc *hw_tmpa910_lcdc)
++{
++ hw_tmpa910_lcdc->LCDControl = 0;
++}
++
++static int tmpa910_lcdc_setcolreg(unsigned regno, unsigned red, unsigned green,
++ unsigned blue, unsigned transp, struct fb_info *info)
++{
++
++ u32 rgba, *pal;
++/*
++ pr_debug("info=%p,tmpa910_lcdc_setcolreg=%p\n", info, tmpa910_lcdc_setcolreg);
++ pr_debug("info=%p, bpp=%d. tmpa910_lcdc_setcolreg=%p, \n", info,
++ info->var.bits_per_pixel, tmpa910_lcdc_setcolreg,
++ info->pseudo_palette);
++*/
++ pal = info->pseudo_palette;
++
++ if (regno >= 16)
++ return -EINVAL;
++
++#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
++
++ red = CNVT_TOHW(red, info->var.red.length);
++ green = CNVT_TOHW(green, info->var.green.length);
++ blue = CNVT_TOHW(blue, info->var.blue.length);
++ transp = CNVT_TOHW(transp, info->var.transp.length);
++
++#undef CNVT_TOHW
++
++ rgba = (red << info->var.red.offset) |
++ (green << info->var.green.offset) |
++ (blue << info->var.blue.offset) |
++ (transp << info->var.transp.offset);
++
++ pal[regno] = rgba;
++
++ return 0;
++}
++
++ /*
++ * Blank the display.
++ */
++
++static int tmpa910_lcdc_blank(int blank, struct fb_info *info)
++{
++ return 0;
++}
++
++//static void __iomem *tmpa910_lcdc_map_reg(struct device_node *np, int index,
++// unsigned long offset, unsigned long size)
++// SNIP
++
++
++
++static int __init tmpa910_lcdc_init_fb(
++ struct platform_device *pdev,
++ const char *name, const char *full_name,
++ int width, int height, int depth,
++ int pitch, uint32_t *LCDReg, unsigned long address, void *lcdc_base)
++{
++ struct tmpa910_lcdc_par *par = &default_par;
++ struct fb_fix_screeninfo *fix;
++ struct fb_var_screeninfo *var;
++ struct fb_info *info;
++
++ int ret;
++
++ //printk(KERN_INFO "Using %dx%d %s at %lx, depth=%d, pitch=%d\n",
++ // width, height, name, address, depth, pitch);
++
++
++ info = framebuffer_alloc(0, &pdev->dev);
++ if (info == NULL) {
++ return -ENOMEM;
++ }
++
++
++ fix = &info->fix;
++ var = &info->var;
++
++ strcpy(fix->id, name);
++ strncat(fix->id, name, sizeof(fix->id) - sizeof("tmpa910_lcdc "));
++ fix->id[sizeof(fix->id) - 1] = '\0';
++
++ var->xres = var->xres_virtual = width;
++ var->yres = var->yres_virtual = height;
++ fix->line_length = pitch;
++
++ fix->smem_start = address;
++ fix->smem_len = pitch * height;
++ fix->type = FB_TYPE_PACKED_PIXELS;
++ fix->type_aux = 0;
++
++ par->cmap_type = cmap_unknown;
++
++ fix->visual = FB_VISUAL_TRUECOLOR;
++
++ var->xoffset = var->yoffset = 0;
++ switch (depth) {
++
++ case 16: /* RGB 565 */
++ var->bits_per_pixel = 16;
++ var->red.offset = 11;
++ var->red.length = 5;
++ var->green.offset = 5;
++ var->green.length = 6;
++ var->blue.offset = 0;
++ var->blue.length = 5;
++ var->transp.offset = 0;
++ var->transp.length = 0;
++ break;
++
++ case 32: /* RGB 888 */
++ var->bits_per_pixel = 32;
++ var->red.offset = 0;
++ var->red.length = 8;
++ var->green.offset = 8;
++ var->green.length = 8;
++ var->blue.offset = 16;
++ var->blue.length = 8;
++ var->transp.offset = 24;
++ var->transp.length = 8;
++
++
++ break;
++ }
++
++ // Some defaults, not very important for the overall functionnality
++ var->red.msb_right = var->green.msb_right = var->blue.msb_right =
++ var->transp.msb_right = 0;
++ var->grayscale = 0;
++ var->nonstd = 0;
++ var->activate = 0;
++ var->height = var->width = -1;
++ var->pixclock = 10000;
++ var->left_margin = var->right_margin = 16;
++ var->upper_margin = var->lower_margin = 16;
++ var->hsync_len = var->vsync_len = 8;
++ var->sync = 0;
++ var->vmode = FB_VMODE_NONINTERLACED;
++
++ info->fbops = &tmpa910_lcdc_ops;
++ info->screen_base = ioremap(address, fix->smem_len);
++
++ // Here real LCD hw init
++ par->hw_tmpa910_lcdc = (void *) (lcdc_base);
++ _init_it( par->hw_tmpa910_lcdc, LCDReg, width, height);
++ _setup_fb( par->hw_tmpa910_lcdc, (uint32_t) address);
++
++ // ok
++ info->par = par;
++ info->pseudo_palette = (void *)(info + 1);
++ info->flags = FBINFO_DEFAULT;
++
++ info->pixmap.flags = FB_PIXMAP_IO;
++
++ fb_alloc_cmap(&info->cmap, 256, 0);
++
++ pr_debug("register_framebuffer(%p), var->bits_per_pixel=%d\n", info,
++ info->var.bits_per_pixel);
++
++ // The final touch
++ ret = register_framebuffer(info);
++ if ( ret< 0) {
++ kfree(info);
++ return ret;
++ }
++
++ // Success :-)
++ printk(KERN_INFO "fb%d: Toshiba TMPA9x0 Frame buffer device at 0x%lx (mapped 0x%p)\n",
++ info->node, address, info->screen_base);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++
++static int tmpa910_lcdc_suspend(struct platform_device *pdev, pm_message_t mesg)
++{
++ return 0;
++}
++
++static int tmpa910_lcdc_resume(struct platform_device *pdev)
++{
++ return 0;
++}
++
++#else
++#define tmpa910_lcdc_suspend NULL
++#define tmpa910_lcdc_resume NULL
++#endif
++
++
++static int __init tmpa910_lcdc_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct resource *regs = NULL;
++ struct resource *fb = NULL;
++ int ret;
++ struct tmpa910_lcdc_platforminfo *platforminfo;
++
++ ret = -ENOMEM;
++
++ platforminfo = (struct tmpa910_lcdc_platforminfo *) dev->platform_data;
++
++ if (!platforminfo) {
++ printk(KERN_ERR "no platforminfo\n");
++ ret = -ENXIO;
++ return ret;
++ }
++
++ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!regs) {
++ printk(KERN_ERR "resources unusable\n");
++ ret = -ENXIO;
++ return ret;
++ }
++
++ fb = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ if (!fb) {
++ printk(KERN_ERR "resources unusable\n");
++ ret = -ENXIO;
++ return ret;
++ }
++
++ ret = tmpa910_lcdc_init_fb(pdev,
++ "TMPA910 FB" , "Toshiba TMPA910 Frame Buffer",
++ platforminfo->width, platforminfo->height,
++ platforminfo->depth, platforminfo->pitch,
++ platforminfo->LCDReg,
++ fb->start, (void *) regs->start);
++
++ return ret;
++}
++
++static int __exit tmpa910_lcdc_remove(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct tmpa910_lcdc_par *par = info->par;
++
++ if (!par)
++ return 0;
++
++ _stop_it(par->hw_tmpa910_lcdc);
++
++ unregister_framebuffer(info);
++
++ fb_dealloc_cmap(&info->cmap);
++
++ if (info->screen_base)
++ iounmap(info->screen_base);
++
++ info->screen_base = NULL;
++
++ dev_set_drvdata(dev, NULL);
++
++ framebuffer_release(info);
++
++ return 0;
++}
++
++static struct platform_driver tmpa910_lcdc_driver = {
++ .remove = __exit_p(tmpa910_lcdc_remove),
++ .suspend = tmpa910_lcdc_suspend,
++ .resume = tmpa910_lcdc_resume,
++
++ .driver = {
++ .name = "tmpa910_lcdc",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init tmpa910_lcdc_init(void)
++{
++ return platform_driver_probe(&tmpa910_lcdc_driver, tmpa910_lcdc_probe);
++}
++
++static void __exit tmpa910_lcdc_exit(void)
++{
++ platform_driver_unregister(&tmpa910_lcdc_driver);
++}
++
++module_init(tmpa910_lcdc_init);
++module_exit(tmpa910_lcdc_exit);
++MODULE_LICENSE("GPL")
+diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
+index 4bdb7f1..6a51edd 100644
+--- a/drivers/watchdog/iTCO_wdt.c
++++ b/drivers/watchdog/iTCO_wdt.c
+@@ -1,5 +1,5 @@
+ /*
+- * intel TCO Watchdog Driver
++ * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets)
+ *
+ * (c) Copyright 2006-2009 Wim Van Sebroeck <wim at iguana.be>.
+ *
+@@ -14,24 +14,47 @@
+ *
+ * The TCO watchdog is implemented in the following I/O controller hubs:
+ * (See the intel documentation on http://developer.intel.com.)
+- * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO)
+- * document number 290687-002, 298242-027: 82801BA (ICH2)
+- * document number 290733-003, 290739-013: 82801CA (ICH3-S)
+- * document number 290716-001, 290718-007: 82801CAM (ICH3-M)
+- * document number 290744-001, 290745-025: 82801DB (ICH4)
+- * document number 252337-001, 252663-008: 82801DBM (ICH4-M)
+- * document number 273599-001, 273645-002: 82801E (C-ICH)
+- * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R)
+- * document number 300641-004, 300884-013: 6300ESB
+- * document number 301473-002, 301474-026: 82801F (ICH6)
+- * document number 313082-001, 313075-006: 631xESB, 632xESB
+- * document number 307013-003, 307014-024: 82801G (ICH7)
+- * document number 313056-003, 313057-017: 82801H (ICH8)
+- * document number 316972-004, 316973-012: 82801I (ICH9)
+- * document number 319973-002, 319974-002: 82801J (ICH10)
+- * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH)
+- * document number 320066-003, 320257-008: EP80597 (IICH)
+- * document number TBD : Cougar Point (CPT)
++ * 82801AA (ICH) : document number 290655-003, 290677-014,
++ * 82801AB (ICHO) : document number 290655-003, 290677-014,
++ * 82801BA (ICH2) : document number 290687-002, 298242-027,
++ * 82801BAM (ICH2-M) : document number 290687-002, 298242-027,
++ * 82801CA (ICH3-S) : document number 290733-003, 290739-013,
++ * 82801CAM (ICH3-M) : document number 290716-001, 290718-007,
++ * 82801DB (ICH4) : document number 290744-001, 290745-025,
++ * 82801DBM (ICH4-M) : document number 252337-001, 252663-008,
++ * 82801E (C-ICH) : document number 273599-001, 273645-002,
++ * 82801EB (ICH5) : document number 252516-001, 252517-028,
++ * 82801ER (ICH5R) : document number 252516-001, 252517-028,
++ * 6300ESB (6300ESB) : document number 300641-004, 300884-013,
++ * 82801FB (ICH6) : document number 301473-002, 301474-026,
++ * 82801FR (ICH6R) : document number 301473-002, 301474-026,
++ * 82801FBM (ICH6-M) : document number 301473-002, 301474-026,
++ * 82801FW (ICH6W) : document number 301473-001, 301474-026,
++ * 82801FRW (ICH6RW) : document number 301473-001, 301474-026,
++ * 631xESB (631xESB) : document number 313082-001, 313075-006,
++ * 632xESB (632xESB) : document number 313082-001, 313075-006,
++ * 82801GB (ICH7) : document number 307013-003, 307014-024,
++ * 82801GR (ICH7R) : document number 307013-003, 307014-024,
++ * 82801GDH (ICH7DH) : document number 307013-003, 307014-024,
++ * 82801GBM (ICH7-M) : document number 307013-003, 307014-024,
++ * 82801GHM (ICH7-M DH) : document number 307013-003, 307014-024,
++ * 82801GU (ICH7-U) : document number 307013-003, 307014-024,
++ * 82801HB (ICH8) : document number 313056-003, 313057-017,
++ * 82801HR (ICH8R) : document number 313056-003, 313057-017,
++ * 82801HBM (ICH8M) : document number 313056-003, 313057-017,
++ * 82801HH (ICH8DH) : document number 313056-003, 313057-017,
++ * 82801HO (ICH8DO) : document number 313056-003, 313057-017,
++ * 82801HEM (ICH8M-E) : document number 313056-003, 313057-017,
++ * 82801IB (ICH9) : document number 316972-004, 316973-012,
++ * 82801IR (ICH9R) : document number 316972-004, 316973-012,
++ * 82801IH (ICH9DH) : document number 316972-004, 316973-012,
++ * 82801IO (ICH9DO) : document number 316972-004, 316973-012,
++ * 82801IBM (ICH9M) : document number 316972-004, 316973-012,
++ * 82801IEM (ICH9M-E) : document number 316972-004, 316973-012,
++ * 82801JIB (ICH10) : document number 319973-002, 319974-002,
++ * 82801JIR (ICH10R) : document number 319973-002, 319974-002,
++ * 82801JD (ICH10D) : document number 319973-002, 319974-002,
++ * 82801JDO (ICH10DO) : document number 319973-002, 319974-002
+ */
+
+ /*
+@@ -99,24 +122,6 @@ enum iTCO_chipsets {
+ TCO_ICH10R, /* ICH10R */
+ TCO_ICH10D, /* ICH10D */
+ TCO_ICH10DO, /* ICH10DO */
+- TCO_PCH, /* PCH Desktop Full Featured */
+- TCO_PCHM, /* PCH Mobile Full Featured */
+- TCO_P55, /* P55 */
+- TCO_PM55, /* PM55 */
+- TCO_H55, /* H55 */
+- TCO_QM57, /* QM57 */
+- TCO_H57, /* H57 */
+- TCO_HM55, /* HM55 */
+- TCO_Q57, /* Q57 */
+- TCO_HM57, /* HM57 */
+- TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */
+- TCO_QS57, /* QS57 */
+- TCO_3400, /* 3400 */
+- TCO_3420, /* 3420 */
+- TCO_3450, /* 3450 */
+- TCO_EP80579, /* EP80579 */
+- TCO_CPTD, /* CPT Desktop */
+- TCO_CPTM, /* CPT Mobile */
+ };
+
+ static struct {
+@@ -157,24 +162,6 @@ static struct {
+ {"ICH10R", 2},
+ {"ICH10D", 2},
+ {"ICH10DO", 2},
+- {"PCH Desktop Full Featured", 2},
+- {"PCH Mobile Full Featured", 2},
+- {"P55", 2},
+- {"PM55", 2},
+- {"H55", 2},
+- {"QM57", 2},
+- {"H57", 2},
+- {"HM55", 2},
+- {"Q57", 2},
+- {"HM57", 2},
+- {"PCH Mobile SFF Full Featured", 2},
+- {"QS57", 2},
+- {"3400", 2},
+- {"3420", 2},
+- {"3450", 2},
+- {"EP80579", 2},
+- {"CPT Desktop", 2},
+- {"CPT Mobile", 2},
+ {NULL, 0}
+ };
+
+@@ -243,24 +230,6 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
+ { ITCO_PCI_DEVICE(0x3a16, TCO_ICH10R)},
+ { ITCO_PCI_DEVICE(0x3a1a, TCO_ICH10D)},
+ { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)},
+- { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)},
+- { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)},
+- { ITCO_PCI_DEVICE(0x3b02, TCO_P55)},
+- { ITCO_PCI_DEVICE(0x3b03, TCO_PM55)},
+- { ITCO_PCI_DEVICE(0x3b06, TCO_H55)},
+- { ITCO_PCI_DEVICE(0x3b07, TCO_QM57)},
+- { ITCO_PCI_DEVICE(0x3b08, TCO_H57)},
+- { ITCO_PCI_DEVICE(0x3b09, TCO_HM55)},
+- { ITCO_PCI_DEVICE(0x3b0a, TCO_Q57)},
+- { ITCO_PCI_DEVICE(0x3b0b, TCO_HM57)},
+- { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)},
+- { ITCO_PCI_DEVICE(0x3b0f, TCO_QS57)},
+- { ITCO_PCI_DEVICE(0x3b12, TCO_3400)},
+- { ITCO_PCI_DEVICE(0x3b14, TCO_3420)},
+- { ITCO_PCI_DEVICE(0x3b16, TCO_3450)},
+- { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)},
+- { ITCO_PCI_DEVICE(0x1c42, TCO_CPTD)},
+- { ITCO_PCI_DEVICE(0x1c43, TCO_CPTM)},
+ { 0, }, /* End of list */
+ };
+ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
+diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
+index 4204336..d31505b 100644
+--- a/drivers/xen/balloon.c
++++ b/drivers/xen/balloon.c
+@@ -66,6 +66,8 @@ struct balloon_stats {
+ /* We aim for 'current allocation' == 'target allocation'. */
+ unsigned long current_pages;
+ unsigned long target_pages;
++ /* We may hit the hard limit in Xen. If we do then we remember it. */
++ unsigned long hard_limit;
+ /*
+ * Drivers may alter the memory reservation independently, but they
+ * must inform the balloon driver so we avoid hitting the hard limit.
+@@ -134,8 +136,6 @@ static void balloon_append(struct page *page)
+ list_add(&page->lru, &ballooned_pages);
+ balloon_stats.balloon_low++;
+ }
+-
+- totalram_pages--;
+ }
+
+ /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
+@@ -156,8 +156,6 @@ static struct page *balloon_retrieve(void)
+ else
+ balloon_stats.balloon_low--;
+
+- totalram_pages++;
+-
+ return page;
+ }
+
+@@ -183,7 +181,7 @@ static void balloon_alarm(unsigned long unused)
+
+ static unsigned long current_target(void)
+ {
+- unsigned long target = balloon_stats.target_pages;
++ unsigned long target = min(balloon_stats.target_pages, balloon_stats.hard_limit);
+
+ target = min(target,
+ balloon_stats.current_pages +
+@@ -219,10 +217,23 @@ static int increase_reservation(unsigned long nr_pages)
+ set_xen_guest_handle(reservation.extent_start, frame_list);
+ reservation.nr_extents = nr_pages;
+ rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
+- if (rc < 0)
++ if (rc < nr_pages) {
++ if (rc > 0) {
++ int ret;
++
++ /* We hit the Xen hard limit: reprobe. */
++ reservation.nr_extents = rc;
++ ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
++ &reservation);
++ BUG_ON(ret != rc);
++ }
++ if (rc >= 0)
++ balloon_stats.hard_limit = (balloon_stats.current_pages + rc -
++ balloon_stats.driver_pages);
+ goto out;
++ }
+
+- for (i = 0; i < rc; i++) {
++ for (i = 0; i < nr_pages; i++) {
+ page = balloon_retrieve();
+ BUG_ON(page == NULL);
+
+@@ -248,12 +259,13 @@ static int increase_reservation(unsigned long nr_pages)
+ __free_page(page);
+ }
+
+- balloon_stats.current_pages += rc;
++ balloon_stats.current_pages += nr_pages;
++ totalram_pages = balloon_stats.current_pages;
+
+ out:
+ spin_unlock_irqrestore(&balloon_lock, flags);
+
+- return rc < 0 ? rc : rc != nr_pages;
++ return 0;
+ }
+
+ static int decrease_reservation(unsigned long nr_pages)
+@@ -311,6 +323,7 @@ static int decrease_reservation(unsigned long nr_pages)
+ BUG_ON(ret != nr_pages);
+
+ balloon_stats.current_pages -= nr_pages;
++ totalram_pages = balloon_stats.current_pages;
+
+ spin_unlock_irqrestore(&balloon_lock, flags);
+
+@@ -354,6 +367,7 @@ static void balloon_process(struct work_struct *work)
+ static void balloon_set_new_target(unsigned long target)
+ {
+ /* No need for lock. Not read-modify-write updates. */
++ balloon_stats.hard_limit = ~0UL;
+ balloon_stats.target_pages = target;
+ schedule_work(&balloon_worker);
+ }
+@@ -408,10 +422,12 @@ static int __init balloon_init(void)
+ pr_info("xen_balloon: Initialising balloon driver.\n");
+
+ balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn);
++ totalram_pages = balloon_stats.current_pages;
+ balloon_stats.target_pages = balloon_stats.current_pages;
+ balloon_stats.balloon_low = 0;
+ balloon_stats.balloon_high = 0;
+ balloon_stats.driver_pages = 0UL;
++ balloon_stats.hard_limit = ~0UL;
+
+ init_timer(&balloon_timer);
+ balloon_timer.data = 0;
+@@ -456,6 +472,9 @@ module_exit(balloon_exit);
+ BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages));
+ BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low));
+ BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high));
++BALLOON_SHOW(hard_limit_kb,
++ (balloon_stats.hard_limit!=~0UL) ? "%lu\n" : "???\n",
++ (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0);
+ BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages));
+
+ static ssize_t show_target_kb(struct sys_device *dev, struct sysdev_attribute *attr,
+@@ -525,6 +544,7 @@ static struct attribute *balloon_info_attrs[] = {
+ &attr_current_kb.attr,
+ &attr_low_kb.attr,
+ &attr_high_kb.attr,
++ &attr_hard_limit_kb.attr,
+ &attr_driver_kb.attr,
+ NULL
+ };
+diff --git a/drivers/xen/events.c b/drivers/xen/events.c
+index ce602dd..2f57276 100644
+--- a/drivers/xen/events.c
++++ b/drivers/xen/events.c
+@@ -474,9 +474,6 @@ static void unbind_from_irq(unsigned int irq)
+ bind_evtchn_to_cpu(evtchn, 0);
+
+ evtchn_to_irq[evtchn] = -1;
+- }
+-
+- if (irq_info[irq].type != IRQT_UNBOUND) {
+ irq_info[irq] = mk_unbound_info();
+
+ dynamic_irq_cleanup(irq);
+diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
+index 5d42d55..10d03d7 100644
+--- a/drivers/xen/manage.c
++++ b/drivers/xen/manage.c
+@@ -43,6 +43,7 @@ static int xen_suspend(void *data)
+ if (err) {
+ printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
+ err);
++ dpm_resume_noirq(PMSG_RESUME);
+ return err;
+ }
+
+@@ -68,6 +69,7 @@ static int xen_suspend(void *data)
+ }
+
+ sysdev_resume();
++ dpm_resume_noirq(PMSG_RESUME);
+
+ return 0;
+ }
+@@ -79,12 +81,6 @@ static void do_suspend(void)
+
+ shutting_down = SHUTDOWN_SUSPEND;
+
+- err = stop_machine_create();
+- if (err) {
+- printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err);
+- goto out;
+- }
+-
+ #ifdef CONFIG_PREEMPT
+ /* If the kernel is preemptible, we need to freeze all the processes
+ to prevent them from being in the middle of a pagetable update
+@@ -92,14 +88,14 @@ static void do_suspend(void)
+ err = freeze_processes();
+ if (err) {
+ printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
+- goto out_destroy_sm;
++ return;
+ }
+ #endif
+
+ err = dpm_suspend_start(PMSG_SUSPEND);
+ if (err) {
+ printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err);
+- goto out_thaw;
++ goto out;
+ }
+
+ printk(KERN_DEBUG "suspending xenstore...\n");
+@@ -108,39 +104,32 @@ static void do_suspend(void)
+ err = dpm_suspend_noirq(PMSG_SUSPEND);
+ if (err) {
+ printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
+- goto out_resume;
++ goto resume_devices;
+ }
+
+ err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
+-
+- dpm_resume_noirq(PMSG_RESUME);
+-
+ if (err) {
+ printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
+- cancelled = 1;
++ goto out;
+ }
+
+-out_resume:
+ if (!cancelled) {
+ xen_arch_resume();
+ xs_resume();
+ } else
+ xs_suspend_cancel();
+
++ dpm_resume_noirq(PMSG_RESUME);
++
++resume_devices:
+ dpm_resume_end(PMSG_RESUME);
+
+ /* Make sure timer events get retriggered on all CPUs */
+ clock_was_set();
+-
+-out_thaw:
++out:
+ #ifdef CONFIG_PREEMPT
+ thaw_processes();
+-
+-out_destroy_sm:
+ #endif
+- stop_machine_destroy();
+-
+-out:
+ shutting_down = SHUTDOWN_INVALID;
+ }
+ #endif /* CONFIG_PM_SLEEP */
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index 649fcdf..d42e25d 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -454,21 +454,21 @@ static ssize_t xendev_show_nodename(struct device *dev,
+ {
+ return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
+ }
+-static DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
++DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
+
+ static ssize_t xendev_show_devtype(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
+ }
+-static DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
++DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
+
+ static ssize_t xendev_show_modalias(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype);
+ }
+-static DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL);
++DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL);
+
+ int xenbus_probe_node(struct xen_bus_type *bus,
+ const char *type,
+@@ -843,7 +843,7 @@ postcore_initcall(xenbus_probe_init);
+
+ MODULE_LICENSE("GPL");
+
+-static int is_device_connecting(struct device *dev, void *data)
++static int is_disconnected_device(struct device *dev, void *data)
+ {
+ struct xenbus_device *xendev = to_xenbus_device(dev);
+ struct device_driver *drv = data;
+@@ -861,15 +861,14 @@ static int is_device_connecting(struct device *dev, void *data)
+ return 0;
+
+ xendrv = to_xenbus_driver(dev->driver);
+- return (xendev->state < XenbusStateConnected ||
+- (xendev->state == XenbusStateConnected &&
+- xendrv->is_ready && !xendrv->is_ready(xendev)));
++ return (xendev->state != XenbusStateConnected ||
++ (xendrv->is_ready && !xendrv->is_ready(xendev)));
+ }
+
+-static int exists_connecting_device(struct device_driver *drv)
++static int exists_disconnected_device(struct device_driver *drv)
+ {
+ return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
+- is_device_connecting);
++ is_disconnected_device);
+ }
+
+ static int print_device_status(struct device *dev, void *data)
+@@ -885,13 +884,10 @@ static int print_device_status(struct device *dev, void *data)
+ /* Information only: is this too noisy? */
+ printk(KERN_INFO "XENBUS: Device with no driver: %s\n",
+ xendev->nodename);
+- } else if (xendev->state < XenbusStateConnected) {
+- enum xenbus_state rstate = XenbusStateUnknown;
+- if (xendev->otherend)
+- rstate = xenbus_read_driver_state(xendev->otherend);
++ } else if (xendev->state != XenbusStateConnected) {
+ printk(KERN_WARNING "XENBUS: Timeout connecting "
+- "to device: %s (local state %d, remote state %d)\n",
+- xendev->nodename, xendev->state, rstate);
++ "to device: %s (state %d)\n",
++ xendev->nodename, xendev->state);
+ }
+
+ return 0;
+@@ -901,7 +897,7 @@ static int print_device_status(struct device *dev, void *data)
+ static int ready_to_wait_for_devices;
+
+ /*
+- * On a 5-minute timeout, wait for all devices currently configured. We need
++ * On a 10 second timeout, wait for all devices currently configured. We need
+ * to do this to guarantee that the filesystems and / or network devices
+ * needed for boot are available, before we can allow the boot to proceed.
+ *
+@@ -916,30 +912,18 @@ static int ready_to_wait_for_devices;
+ */
+ static void wait_for_devices(struct xenbus_driver *xendrv)
+ {
+- unsigned long start = jiffies;
++ unsigned long timeout = jiffies + 10*HZ;
+ struct device_driver *drv = xendrv ? &xendrv->driver : NULL;
+- unsigned int seconds_waited = 0;
+
+ if (!ready_to_wait_for_devices || !xen_domain())
+ return;
+
+- while (exists_connecting_device(drv)) {
+- if (time_after(jiffies, start + (seconds_waited+5)*HZ)) {
+- if (!seconds_waited)
+- printk(KERN_WARNING "XENBUS: Waiting for "
+- "devices to initialise: ");
+- seconds_waited += 5;
+- printk("%us...", 300 - seconds_waited);
+- if (seconds_waited == 300)
+- break;
+- }
+-
++ while (exists_disconnected_device(drv)) {
++ if (time_after(jiffies, timeout))
++ break;
+ schedule_timeout_interruptible(HZ/10);
+ }
+
+- if (seconds_waited)
+- printk("\n");
+-
+ bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
+ print_device_status);
+ }
+diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
+index 69357c0..14a8644 100644
+--- a/fs/9p/vfs_super.c
++++ b/fs/9p/vfs_super.c
+@@ -188,8 +188,7 @@ static void v9fs_kill_super(struct super_block *s)
+
+ P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s);
+
+- if (s->s_root)
+- v9fs_dentry_release(s->s_root); /* clunk root */
++ v9fs_dentry_release(s->s_root); /* clunk root */
+
+ kill_anon_super(s);
+
+diff --git a/fs/affs/affs.h b/fs/affs/affs.h
+index 0e40caa..e511dc6 100644
+--- a/fs/affs/affs.h
++++ b/fs/affs/affs.h
+@@ -106,8 +106,8 @@ struct affs_sb_info {
+ u32 s_last_bmap;
+ struct buffer_head *s_bmap_bh;
+ char *s_prefix; /* Prefix for volumes and assigns. */
++ int s_prefix_len; /* Length of prefix. */
+ char s_volume[32]; /* Volume prefix for absolute symlinks. */
+- spinlock_t symlink_lock; /* protects the previous two */
+ };
+
+ #define SF_INTL 0x0001 /* International filesystem. */
+diff --git a/fs/affs/namei.c b/fs/affs/namei.c
+index d70bbba..960d336 100644
+--- a/fs/affs/namei.c
++++ b/fs/affs/namei.c
+@@ -341,13 +341,10 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+ p = (char *)AFFS_HEAD(bh)->table;
+ lc = '/';
+ if (*symname == '/') {
+- struct affs_sb_info *sbi = AFFS_SB(sb);
+ while (*symname == '/')
+ symname++;
+- spin_lock(&sbi->symlink_lock);
+- while (sbi->s_volume[i]) /* Cannot overflow */
+- *p++ = sbi->s_volume[i++];
+- spin_unlock(&sbi->symlink_lock);
++ while (AFFS_SB(sb)->s_volume[i]) /* Cannot overflow */
++ *p++ = AFFS_SB(sb)->s_volume[i++];
+ }
+ while (i < maxlen && (c = *symname++)) {
+ if (c == '.' && lc == '/' && *symname == '.' && symname[1] == '/') {
+diff --git a/fs/affs/super.c b/fs/affs/super.c
+index d41e967..104fdcb 100644
+--- a/fs/affs/super.c
++++ b/fs/affs/super.c
+@@ -203,7 +203,7 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
+ switch (token) {
+ case Opt_bs:
+ if (match_int(&args[0], &n))
+- return 0;
++ return -EINVAL;
+ if (n != 512 && n != 1024 && n != 2048
+ && n != 4096) {
+ printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
+@@ -213,7 +213,7 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
+ break;
+ case Opt_mode:
+ if (match_octal(&args[0], &option))
+- return 0;
++ return 1;
+ *mode = option & 0777;
+ *mount_opts |= SF_SETMODE;
+ break;
+@@ -221,6 +221,8 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
+ *mount_opts |= SF_MUFS;
+ break;
+ case Opt_prefix:
++ /* Free any previous prefix */
++ kfree(*prefix);
+ *prefix = match_strdup(&args[0]);
+ if (!*prefix)
+ return 0;
+@@ -231,21 +233,21 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
+ break;
+ case Opt_reserved:
+ if (match_int(&args[0], reserved))
+- return 0;
++ return 1;
+ break;
+ case Opt_root:
+ if (match_int(&args[0], root))
+- return 0;
++ return 1;
+ break;
+ case Opt_setgid:
+ if (match_int(&args[0], &option))
+- return 0;
++ return 1;
+ *gid = option;
+ *mount_opts |= SF_SETGID;
+ break;
+ case Opt_setuid:
+ if (match_int(&args[0], &option))
+- return 0;
++ return -EINVAL;
+ *uid = option;
+ *mount_opts |= SF_SETUID;
+ break;
+@@ -309,14 +311,11 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
+ return -ENOMEM;
+ sb->s_fs_info = sbi;
+ mutex_init(&sbi->s_bmlock);
+- spin_lock_init(&sbi->symlink_lock);
+
+ if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,
+ &blocksize,&sbi->s_prefix,
+ sbi->s_volume, &mount_flags)) {
+ printk(KERN_ERR "AFFS: Error parsing options\n");
+- kfree(sbi->s_prefix);
+- kfree(sbi);
+ return -EINVAL;
+ }
+ /* N.B. after this point s_prefix must be released */
+@@ -517,18 +516,14 @@ affs_remount(struct super_block *sb, int *flags, char *data)
+ unsigned long mount_flags;
+ int res = 0;
+ char *new_opts = kstrdup(data, GFP_KERNEL);
+- char volume[32];
+- char *prefix = NULL;
+
+ pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);
+
+ *flags |= MS_NODIRATIME;
+
+- memcpy(volume, sbi->s_volume, 32);
+ if (!parse_options(data, &uid, &gid, &mode, &reserved, &root_block,
+- &blocksize, &prefix, volume,
++ &blocksize, &sbi->s_prefix, sbi->s_volume,
+ &mount_flags)) {
+- kfree(prefix);
+ kfree(new_opts);
+ return -EINVAL;
+ }
+@@ -539,14 +534,6 @@ affs_remount(struct super_block *sb, int *flags, char *data)
+ sbi->s_mode = mode;
+ sbi->s_uid = uid;
+ sbi->s_gid = gid;
+- /* protect against readers */
+- spin_lock(&sbi->symlink_lock);
+- if (prefix) {
+- kfree(sbi->s_prefix);
+- sbi->s_prefix = prefix;
+- }
+- memcpy(sbi->s_volume, volume, 32);
+- spin_unlock(&sbi->symlink_lock);
+
+ if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+ unlock_kernel();
+diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c
+index ee00f08..4178253 100644
+--- a/fs/affs/symlink.c
++++ b/fs/affs/symlink.c
+@@ -20,6 +20,7 @@ static int affs_symlink_readpage(struct file *file, struct page *page)
+ int i, j;
+ char c;
+ char lc;
++ char *pf;
+
+ pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino);
+
+@@ -31,15 +32,11 @@ static int affs_symlink_readpage(struct file *file, struct page *page)
+ j = 0;
+ lf = (struct slink_front *)bh->b_data;
+ lc = 0;
++ pf = AFFS_SB(inode->i_sb)->s_prefix ? AFFS_SB(inode->i_sb)->s_prefix : "/";
+
+ if (strchr(lf->symname,':')) { /* Handle assign or volume name */
+- struct affs_sb_info *sbi = AFFS_SB(inode->i_sb);
+- char *pf;
+- spin_lock(&sbi->symlink_lock);
+- pf = sbi->s_prefix ? sbi->s_prefix : "/";
+ while (i < 1023 && (c = pf[i]))
+ link[i++] = c;
+- spin_unlock(&sbi->symlink_lock);
+ while (i < 1023 && lf->symname[j] != ':')
+ link[i++] = lf->symname[j++];
+ if (i < 1023)
+diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
+index 34ddda8..33baf27 100644
+--- a/fs/befs/linuxvfs.c
++++ b/fs/befs/linuxvfs.c
+@@ -873,7 +873,6 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
+ brelse(bh);
+
+ unacquire_priv_sbp:
+- kfree(befs_sb->mount_opts.iocharset);
+ kfree(sb->s_fs_info);
+
+ unacquire_none:
+diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
+index 8f3d9fd..6f60336 100644
+--- a/fs/bfs/inode.c
++++ b/fs/bfs/inode.c
+@@ -353,35 +353,35 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
+ struct inode *inode;
+ unsigned i, imap_len;
+ struct bfs_sb_info *info;
+- int ret = -EINVAL;
++ long ret = -EINVAL;
+ unsigned long i_sblock, i_eblock, i_eoff, s_size;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+- mutex_init(&info->bfs_lock);
+ s->s_fs_info = info;
+
+ sb_set_blocksize(s, BFS_BSIZE);
+
+- info->si_sbh = sb_bread(s, 0);
+- if (!info->si_sbh)
++ bh = sb_bread(s, 0);
++ if(!bh)
+ goto out;
+- bfs_sb = (struct bfs_super_block *)info->si_sbh->b_data;
++ bfs_sb = (struct bfs_super_block *)bh->b_data;
+ if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
+ if (!silent)
+ printf("No BFS filesystem on %s (magic=%08x)\n",
+ s->s_id, le32_to_cpu(bfs_sb->s_magic));
+- goto out1;
++ goto out;
+ }
+ if (BFS_UNCLEAN(bfs_sb, s) && !silent)
+ printf("%s is unclean, continuing\n", s->s_id);
+
+ s->s_magic = BFS_MAGIC;
++ info->si_sbh = bh;
+
+ if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) {
+ printf("Superblock is corrupted\n");
+- goto out1;
++ goto out;
+ }
+
+ info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) /
+@@ -390,7 +390,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
+ imap_len = (info->si_lasti / 8) + 1;
+ info->si_imap = kzalloc(imap_len, GFP_KERNEL);
+ if (!info->si_imap)
+- goto out1;
++ goto out;
+ for (i = 0; i < BFS_ROOT_INO; i++)
+ set_bit(i, info->si_imap);
+
+@@ -398,13 +398,15 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
+ inode = bfs_iget(s, BFS_ROOT_INO);
+ if (IS_ERR(inode)) {
+ ret = PTR_ERR(inode);
+- goto out2;
++ kfree(info->si_imap);
++ goto out;
+ }
+ s->s_root = d_alloc_root(inode);
+ if (!s->s_root) {
+ iput(inode);
+ ret = -ENOMEM;
+- goto out2;
++ kfree(info->si_imap);
++ goto out;
+ }
+
+ info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1) >> BFS_BSIZE_BITS;
+@@ -417,8 +419,10 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
+ bh = sb_bread(s, info->si_blocks - 1);
+ if (!bh) {
+ printf("Last block not available: %lu\n", info->si_blocks - 1);
++ iput(inode);
+ ret = -EIO;
+- goto out3;
++ kfree(info->si_imap);
++ goto out;
+ }
+ brelse(bh);
+
+@@ -455,8 +459,11 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
+ printf("Inode 0x%08x corrupted\n", i);
+
+ brelse(bh);
+- ret = -EIO;
+- goto out3;
++ s->s_root = NULL;
++ kfree(info->si_imap);
++ kfree(info);
++ s->s_fs_info = NULL;
++ return -EIO;
+ }
+
+ if (!di->i_ino) {
+@@ -476,17 +483,11 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
+ s->s_dirt = 1;
+ }
+ dump_imap("read_super", s);
++ mutex_init(&info->bfs_lock);
+ return 0;
+
+-out3:
+- dput(s->s_root);
+- s->s_root = NULL;
+-out2:
+- kfree(info->si_imap);
+-out1:
+- brelse(info->si_sbh);
+ out:
+- mutex_destroy(&info->bfs_lock);
++ brelse(bh);
+ kfree(info);
+ s->s_fs_info = NULL;
+ return ret;
+diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
+index 0133b5a..b639dcf 100644
+--- a/fs/binfmt_aout.c
++++ b/fs/binfmt_aout.c
+@@ -263,7 +263,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+ #else
+ set_personality(PER_LINUX);
+ #endif
+- setup_new_exec(bprm);
+
+ current->mm->end_code = ex.a_text +
+ (current->mm->start_code = N_TXTADDR(ex));
+diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
+index 1ed37ba..b9b3bb5 100644
+--- a/fs/binfmt_elf.c
++++ b/fs/binfmt_elf.c
+@@ -662,6 +662,27 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+ if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
+ goto out_free_interp;
+
++ /*
++ * The early SET_PERSONALITY here is so that the lookup
++ * for the interpreter happens in the namespace of the
++ * to-be-execed image. SET_PERSONALITY can select an
++ * alternate root.
++ *
++ * However, SET_PERSONALITY is NOT allowed to switch
++ * this task into the new images's memory mapping
++ * policy - that is, TASK_SIZE must still evaluate to
++ * that which is appropriate to the execing application.
++ * This is because exit_mmap() needs to have TASK_SIZE
++ * evaluate to the size of the old image.
++ *
++ * So if (say) a 64-bit application is execing a 32-bit
++ * application it is the architecture's responsibility
++ * to defer changing the value of TASK_SIZE until the
++ * switch really is going to happen - do this in
++ * flush_thread(). - akpm
++ */
++ SET_PERSONALITY(loc->elf_ex);
++
+ interpreter = open_exec(elf_interpreter);
+ retval = PTR_ERR(interpreter);
+ if (IS_ERR(interpreter))
+@@ -709,6 +730,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+ /* Verify the interpreter has a valid arch */
+ if (!elf_check_arch(&loc->interp_elf_ex))
+ goto out_free_dentry;
++ } else {
++ /* Executables without an interpreter also need a personality */
++ SET_PERSONALITY(loc->elf_ex);
+ }
+
+ /* Flush all traces of the currently running executable */
+@@ -728,8 +752,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+
+ if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+ current->flags |= PF_RANDOMIZE;
+-
+- setup_new_exec(bprm);
++ arch_pick_mmap_layout(current->mm);
+
+ /* Do this so that we can load the interpreter, if need be. We will
+ change some of these later */
+diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
+index e7a0bb4..38502c6 100644
+--- a/fs/binfmt_elf_fdpic.c
++++ b/fs/binfmt_elf_fdpic.c
+@@ -171,9 +171,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
+ #ifdef ELF_FDPIC_PLAT_INIT
+ unsigned long dynaddr;
+ #endif
+-#ifndef CONFIG_MMU
+- unsigned long stack_prot;
+-#endif
+ struct file *interpreter = NULL; /* to shut gcc up */
+ char *interpreter_name = NULL;
+ int executable_stack;
+@@ -319,11 +316,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
+ * defunct, deceased, etc. after this point we have to exit via
+ * error_kill */
+ set_personality(PER_LINUX_FDPIC);
+- if (elf_read_implies_exec(&exec_params.hdr, executable_stack))
+- current->personality |= READ_IMPLIES_EXEC;
+-
+- setup_new_exec(bprm);
+-
+ set_binfmt(&elf_fdpic_format);
+
+ current->mm->start_code = 0;
+@@ -385,13 +377,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
+ if (stack_size < PAGE_SIZE * 2)
+ stack_size = PAGE_SIZE * 2;
+
+- stack_prot = PROT_READ | PROT_WRITE;
+- if (executable_stack == EXSTACK_ENABLE_X ||
+- (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC))
+- stack_prot |= PROT_EXEC;
+-
+ down_write(¤t->mm->mmap_sem);
+- current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot,
++ current->mm->start_brk = do_mmap(NULL, 0, stack_size,
++ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN,
+ 0);
+
+diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
+index ca88c46..a279665 100644
+--- a/fs/binfmt_flat.c
++++ b/fs/binfmt_flat.c
+@@ -519,7 +519,6 @@ static int load_flat_file(struct linux_binprm * bprm,
+
+ /* OK, This is the point of no return */
+ set_personality(PER_LINUX_32BIT);
+- setup_new_exec(bprm);
+ }
+
+ /*
+diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
+index 35cf002..eff74b9 100644
+--- a/fs/binfmt_som.c
++++ b/fs/binfmt_som.c
+@@ -227,7 +227,6 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+ /* OK, This is the point of no return */
+ current->flags &= ~PF_FORKNOEXEC;
+ current->personality = PER_HPUX;
+- setup_new_exec(bprm);
+
+ /* Set the task size for HP-UX processes such that
+ * the gateway page is outside the address space.
+diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
+index a16f29e..49a34e7 100644
+--- a/fs/bio-integrity.c
++++ b/fs/bio-integrity.c
+@@ -61,7 +61,7 @@ static inline unsigned int vecs_to_idx(unsigned int nr)
+
+ static inline int use_bip_pool(unsigned int idx)
+ {
+- if (idx == BIOVEC_MAX_IDX)
++ if (idx == BIOVEC_NR_POOLS)
+ return 1;
+
+ return 0;
+@@ -95,7 +95,6 @@ struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *bio,
+
+ /* Use mempool if lower order alloc failed or max vecs were requested */
+ if (bip == NULL) {
+- idx = BIOVEC_MAX_IDX; /* so we free the payload properly later */
+ bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask);
+
+ if (unlikely(bip == NULL)) {
+diff --git a/fs/bio.c b/fs/bio.c
+index e0c9e71..12da5db 100644
+--- a/fs/bio.c
++++ b/fs/bio.c
+@@ -542,18 +542,13 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
+
+ if (page == prev->bv_page &&
+ offset == prev->bv_offset + prev->bv_len) {
+- unsigned int prev_bv_len = prev->bv_len;
+ prev->bv_len += len;
+
+ if (q->merge_bvec_fn) {
+ struct bvec_merge_data bvm = {
+- /* prev_bvec is already charged in
+- bi_size, discharge it in order to
+- simulate merging updated prev_bvec
+- as new bvec. */
+ .bi_bdev = bio->bi_bdev,
+ .bi_sector = bio->bi_sector,
+- .bi_size = bio->bi_size - prev_bv_len,
++ .bi_size = bio->bi_size,
+ .bi_rw = bio->bi_rw,
+ };
+
+diff --git a/fs/block_dev.c b/fs/block_dev.c
+index 34e2d20..8bed055 100644
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -246,8 +246,7 @@ struct super_block *freeze_bdev(struct block_device *bdev)
+ if (!sb)
+ goto out;
+ if (sb->s_flags & MS_RDONLY) {
+- sb->s_frozen = SB_FREEZE_TRANS;
+- up_write(&sb->s_umount);
++ deactivate_locked_super(sb);
+ mutex_unlock(&bdev->bd_fsfreeze_mutex);
+ return sb;
+ }
+@@ -308,7 +307,7 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb)
+ BUG_ON(sb->s_bdev != bdev);
+ down_write(&sb->s_umount);
+ if (sb->s_flags & MS_RDONLY)
+- goto out_unfrozen;
++ goto out_deactivate;
+
+ if (sb->s_op->unfreeze_fs) {
+ error = sb->s_op->unfreeze_fs(sb);
+@@ -322,11 +321,11 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb)
+ }
+ }
+
+-out_unfrozen:
+ sb->s_frozen = SB_UNFROZEN;
+ smp_wmb();
+ wake_up(&sb->s_wait_unfrozen);
+
++out_deactivate:
+ if (sb)
+ deactivate_locked_super(sb);
+ out_unlock:
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 3bbcaa7..63ea83f 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -2287,12 +2287,12 @@ int
+ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ char *mount_data_global, const char *devname)
+ {
+- int rc;
++ int rc = 0;
+ int xid;
+ struct smb_vol *volume_info;
+- struct cifsSesInfo *pSesInfo;
+- struct cifsTconInfo *tcon;
+- struct TCP_Server_Info *srvTcp;
++ struct cifsSesInfo *pSesInfo = NULL;
++ struct cifsTconInfo *tcon = NULL;
++ struct TCP_Server_Info *srvTcp = NULL;
+ char *full_path;
+ char *mount_data = mount_data_global;
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+@@ -2301,10 +2301,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ int referral_walks_count = 0;
+ try_mount_again:
+ #endif
+- rc = 0;
+- tcon = NULL;
+- pSesInfo = NULL;
+- srvTcp = NULL;
+ full_path = NULL;
+
+ xid = GetXid();
+@@ -2601,7 +2597,6 @@ remote_path_check:
+
+ cleanup_volume_info(&volume_info);
+ referral_walks_count++;
+- FreeXid(xid);
+ goto try_mount_again;
+ }
+ #else /* No DFS support, return error on mount */
+diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
+index f5618f8..f84062f 100644
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -666,7 +666,6 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
+ min(len, max_len), nlt,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+- pqst->len -= nls_nullsize(nlt);
+ } else {
+ pqst->name = filename;
+ pqst->len = len;
+diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
+index 39c6ee8..d22438e 100644
+--- a/fs/debugfs/inode.c
++++ b/fs/debugfs/inode.c
+@@ -32,9 +32,7 @@ static struct vfsmount *debugfs_mount;
+ static int debugfs_mount_count;
+ static bool debugfs_registered;
+
+-static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev,
+- void *data, const struct file_operations *fops)
+-
++static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev)
+ {
+ struct inode *inode = new_inode(sb);
+
+@@ -46,18 +44,14 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
+ init_special_inode(inode, mode, dev);
+ break;
+ case S_IFREG:
+- inode->i_fop = fops ? fops : &debugfs_file_operations;
+- inode->i_private = data;
++ inode->i_fop = &debugfs_file_operations;
+ break;
+ case S_IFLNK:
+ inode->i_op = &debugfs_link_operations;
+- inode->i_fop = fops;
+- inode->i_private = data;
+ break;
+ case S_IFDIR:
+ inode->i_op = &simple_dir_inode_operations;
+- inode->i_fop = fops ? fops : &simple_dir_operations;
+- inode->i_private = data;
++ inode->i_fop = &simple_dir_operations;
+
+ /* directory inodes start off with i_nlink == 2
+ * (for "." entry) */
+@@ -70,8 +64,7 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
+
+ /* SMP-safe */
+ static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
+- int mode, dev_t dev, void *data,
+- const struct file_operations *fops)
++ int mode, dev_t dev)
+ {
+ struct inode *inode;
+ int error = -EPERM;
+@@ -79,7 +72,7 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
+ if (dentry->d_inode)
+ return -EEXIST;
+
+- inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops);
++ inode = debugfs_get_inode(dir->i_sb, mode, dev);
+ if (inode) {
+ d_instantiate(dentry, inode);
+ dget(dentry);
+@@ -88,13 +81,12 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
+ return error;
+ }
+
+-static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode,
+- void *data, const struct file_operations *fops)
++static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+ {
+ int res;
+
+ mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+- res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
++ res = debugfs_mknod(dir, dentry, mode, 0);
+ if (!res) {
+ inc_nlink(dir);
+ fsnotify_mkdir(dir, dentry);
+@@ -102,20 +94,18 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode,
+ return res;
+ }
+
+-static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode,
+- void *data, const struct file_operations *fops)
++static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode)
+ {
+ mode = (mode & S_IALLUGO) | S_IFLNK;
+- return debugfs_mknod(dir, dentry, mode, 0, data, fops);
++ return debugfs_mknod(dir, dentry, mode, 0);
+ }
+
+-static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode,
+- void *data, const struct file_operations *fops)
++static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
+ {
+ int res;
+
+ mode = (mode & S_IALLUGO) | S_IFREG;
+- res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
++ res = debugfs_mknod(dir, dentry, mode, 0);
+ if (!res)
+ fsnotify_create(dir, dentry);
+ return res;
+@@ -149,9 +139,7 @@ static struct file_system_type debug_fs_type = {
+
+ static int debugfs_create_by_name(const char *name, mode_t mode,
+ struct dentry *parent,
+- struct dentry **dentry,
+- void *data,
+- const struct file_operations *fops)
++ struct dentry **dentry)
+ {
+ int error = 0;
+
+@@ -176,16 +164,13 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
+ if (!IS_ERR(*dentry)) {
+ switch (mode & S_IFMT) {
+ case S_IFDIR:
+- error = debugfs_mkdir(parent->d_inode, *dentry, mode,
+- data, fops);
++ error = debugfs_mkdir(parent->d_inode, *dentry, mode);
+ break;
+ case S_IFLNK:
+- error = debugfs_link(parent->d_inode, *dentry, mode,
+- data, fops);
++ error = debugfs_link(parent->d_inode, *dentry, mode);
+ break;
+ default:
+- error = debugfs_create(parent->d_inode, *dentry, mode,
+- data, fops);
++ error = debugfs_create(parent->d_inode, *dentry, mode);
+ break;
+ }
+ dput(*dentry);
+@@ -236,13 +221,19 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode,
+ if (error)
+ goto exit;
+
+- error = debugfs_create_by_name(name, mode, parent, &dentry,
+- data, fops);
++ error = debugfs_create_by_name(name, mode, parent, &dentry);
+ if (error) {
+ dentry = NULL;
+ simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+ goto exit;
+ }
++
++ if (dentry->d_inode) {
++ if (data)
++ dentry->d_inode->i_private = data;
++ if (fops)
++ dentry->d_inode->i_fop = fops;
++ }
+ exit:
+ return dentry;
+ }
+diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
+index 8882ecc..d5f8c96 100644
+--- a/fs/devpts/inode.c
++++ b/fs/devpts/inode.c
+@@ -517,23 +517,11 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
+
+ struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
+ {
+- struct dentry *dentry;
+- struct tty_struct *tty;
+-
+ BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
+
+- /* Ensure dentry has not been deleted by devpts_pty_kill() */
+- dentry = d_find_alias(pts_inode);
+- if (!dentry)
+- return NULL;
+-
+- tty = NULL;
+ if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
+- tty = (struct tty_struct *)pts_inode->i_private;
+-
+- dput(dentry);
+-
+- return tty;
++ return (struct tty_struct *)pts_inode->i_private;
++ return NULL;
+ }
+
+ void devpts_pty_kill(struct tty_struct *tty)
+diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
+index 7cb0a59..fbb6e5e 100644
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -1748,7 +1748,7 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
+ char *cipher_name, size_t *key_size)
+ {
+ char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
+- char *full_alg_name = NULL;
++ char *full_alg_name;
+ int rc;
+
+ *key_tfm = NULL;
+@@ -1763,6 +1763,7 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
+ if (rc)
+ goto out;
+ *key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC);
++ kfree(full_alg_name);
+ if (IS_ERR(*key_tfm)) {
+ rc = PTR_ERR(*key_tfm);
+ printk(KERN_ERR "Unable to allocate crypto cipher with name "
+@@ -1785,7 +1786,6 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
+ goto out;
+ }
+ out:
+- kfree(full_alg_name);
+ return rc;
+ }
+
+diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
+index 1744f17..9e94405 100644
+--- a/fs/ecryptfs/file.c
++++ b/fs/ecryptfs/file.c
+@@ -191,6 +191,13 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
+ | ECRYPTFS_ENCRYPTED);
+ }
+ mutex_unlock(&crypt_stat->cs_mutex);
++ if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY)
++ && !(file->f_flags & O_RDONLY)) {
++ rc = -EPERM;
++ printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs "
++ "file must hence be opened RO\n", __func__);
++ goto out;
++ }
+ if (!ecryptfs_inode_to_private(inode)->lower_file) {
+ rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
+ if (rc) {
+@@ -201,13 +208,6 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
+ goto out;
+ }
+ }
+- if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY)
+- && !(file->f_flags & O_RDONLY)) {
+- rc = -EPERM;
+- printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs "
+- "file must hence be opened RO\n", __func__);
+- goto out;
+- }
+ ecryptfs_set_file_lower(
+ file, ecryptfs_inode_to_private(inode)->lower_file);
+ if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
+diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
+index 728f07e..056fed6 100644
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -971,21 +971,6 @@ out:
+ return rc;
+ }
+
+-int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+- struct kstat *stat)
+-{
+- struct kstat lower_stat;
+- int rc;
+-
+- rc = vfs_getattr(ecryptfs_dentry_to_lower_mnt(dentry),
+- ecryptfs_dentry_to_lower(dentry), &lower_stat);
+- if (!rc) {
+- generic_fillattr(dentry->d_inode, stat);
+- stat->blocks = lower_stat.blocks;
+- }
+- return rc;
+-}
+-
+ int
+ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+ size_t size, int flags)
+@@ -1115,7 +1100,6 @@ const struct inode_operations ecryptfs_dir_iops = {
+ const struct inode_operations ecryptfs_main_iops = {
+ .permission = ecryptfs_permission,
+ .setattr = ecryptfs_setattr,
+- .getattr = ecryptfs_getattr,
+ .setxattr = ecryptfs_setxattr,
+ .getxattr = ecryptfs_getxattr,
+ .listxattr = ecryptfs_listxattr,
+diff --git a/fs/exec.c b/fs/exec.c
+index da36c20..ba112bd 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -572,9 +572,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
+ struct vm_area_struct *prev = NULL;
+ unsigned long vm_flags;
+ unsigned long stack_base;
+- unsigned long stack_size;
+- unsigned long stack_expand;
+- unsigned long rlim_stack;
+
+ #ifdef CONFIG_STACK_GROWSUP
+ /* Limit stack size to 1GB */
+@@ -631,24 +628,10 @@ int setup_arg_pages(struct linux_binprm *bprm,
+ goto out_unlock;
+ }
+
+- stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+- stack_size = vma->vm_end - vma->vm_start;
+- /*
+- * Align this down to a page boundary as expand_stack
+- * will align it up.
+- */
+- rlim_stack = rlimit(RLIMIT_STACK) & PAGE_MASK;
+- rlim_stack = min(rlim_stack, stack_size);
+ #ifdef CONFIG_STACK_GROWSUP
+- if (stack_size + stack_expand > rlim_stack)
+- stack_base = vma->vm_start + rlim_stack;
+- else
+- stack_base = vma->vm_end + stack_expand;
++ stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+ #else
+- if (stack_size + stack_expand > rlim_stack)
+- stack_base = vma->vm_end - rlim_stack;
+- else
+- stack_base = vma->vm_start - stack_expand;
++ stack_base = vma->vm_start - EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+ #endif
+ ret = expand_stack(vma, stack_base);
+ if (ret)
+@@ -948,7 +931,9 @@ void set_task_comm(struct task_struct *tsk, char *buf)
+
+ int flush_old_exec(struct linux_binprm * bprm)
+ {
+- int retval;
++ char * name;
++ int i, ch, retval;
++ char tcomm[sizeof(current->comm)];
+
+ /*
+ * Make sure we have a private signal table and that
+@@ -969,25 +954,6 @@ int flush_old_exec(struct linux_binprm * bprm)
+
+ bprm->mm = NULL; /* We're using it now */
+
+- current->flags &= ~PF_RANDOMIZE;
+- flush_thread();
+- current->personality &= ~bprm->per_clear;
+-
+- return 0;
+-
+-out:
+- return retval;
+-}
+-EXPORT_SYMBOL(flush_old_exec);
+-
+-void setup_new_exec(struct linux_binprm * bprm)
+-{
+- int i, ch;
+- char * name;
+- char tcomm[sizeof(current->comm)];
+-
+- arch_pick_mmap_layout(current->mm);
+-
+ /* This is the point of no return */
+ current->sas_ss_sp = current->sas_ss_size = 0;
+
+@@ -1009,6 +975,9 @@ void setup_new_exec(struct linux_binprm * bprm)
+ tcomm[i] = '\0';
+ set_task_comm(current, tcomm);
+
++ current->flags &= ~PF_RANDOMIZE;
++ flush_thread();
++
+ /* Set the new mm task size. We have to do that late because it may
+ * depend on TIF_32BIT which is only updated in flush_thread() on
+ * some architectures like powerpc
+@@ -1024,6 +993,8 @@ void setup_new_exec(struct linux_binprm * bprm)
+ set_dumpable(current->mm, suid_dumpable);
+ }
+
++ current->personality &= ~bprm->per_clear;
++
+ /*
+ * Flush performance counters when crossing a
+ * security domain:
+@@ -1038,8 +1009,14 @@ void setup_new_exec(struct linux_binprm * bprm)
+
+ flush_signal_handlers(current, 0);
+ flush_old_files(current->files);
++
++ return 0;
++
++out:
++ return retval;
+ }
+-EXPORT_SYMBOL(setup_new_exec);
++
++EXPORT_SYMBOL(flush_old_exec);
+
+ /*
+ * Prepare credentials and lock ->cred_guard_mutex.
+diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
+index 6f7df0f..6c10f74 100644
+--- a/fs/exofs/inode.c
++++ b/fs/exofs/inode.c
+@@ -731,28 +731,13 @@ static int exofs_write_begin_export(struct file *file,
+ fsdata);
+ }
+
+-static int exofs_write_end(struct file *file, struct address_space *mapping,
+- loff_t pos, unsigned len, unsigned copied,
+- struct page *page, void *fsdata)
+-{
+- struct inode *inode = mapping->host;
+- /* According to comment in simple_write_end i_mutex is held */
+- loff_t i_size = inode->i_size;
+- int ret;
+-
+- ret = simple_write_end(file, mapping,pos, len, copied, page, fsdata);
+- if (i_size != inode->i_size)
+- mark_inode_dirty(inode);
+- return ret;
+-}
+-
+ const struct address_space_operations exofs_aops = {
+ .readpage = exofs_readpage,
+ .readpages = exofs_readpages,
+ .writepage = exofs_writepage,
+ .writepages = exofs_writepages,
+ .write_begin = exofs_write_begin_export,
+- .write_end = exofs_write_end,
++ .write_end = simple_write_end,
+ };
+
+ /******************************************************************************
+diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
+index f9d6937..354ed3b 100644
+--- a/fs/ext3/inode.c
++++ b/fs/ext3/inode.c
+@@ -1151,16 +1151,6 @@ static int do_journal_get_write_access(handle_t *handle,
+ return ext3_journal_get_write_access(handle, bh);
+ }
+
+-/*
+- * Truncate blocks that were not used by write. We have to truncate the
+- * pagecache as well so that corresponding buffers get properly unmapped.
+- */
+-static void ext3_truncate_failed_write(struct inode *inode)
+-{
+- truncate_inode_pages(inode->i_mapping, inode->i_size);
+- ext3_truncate(inode);
+-}
+-
+ static int ext3_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+@@ -1219,7 +1209,7 @@ write_begin_failed:
+ unlock_page(page);
+ page_cache_release(page);
+ if (pos + len > inode->i_size)
+- ext3_truncate_failed_write(inode);
++ ext3_truncate(inode);
+ }
+ if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
+ goto retry;
+@@ -1314,7 +1304,7 @@ static int ext3_ordered_write_end(struct file *file,
+ page_cache_release(page);
+
+ if (pos + len > inode->i_size)
+- ext3_truncate_failed_write(inode);
++ ext3_truncate(inode);
+ return ret ? ret : copied;
+ }
+
+@@ -1340,7 +1330,7 @@ static int ext3_writeback_write_end(struct file *file,
+ page_cache_release(page);
+
+ if (pos + len > inode->i_size)
+- ext3_truncate_failed_write(inode);
++ ext3_truncate(inode);
+ return ret ? ret : copied;
+ }
+
+@@ -1393,7 +1383,7 @@ static int ext3_journalled_write_end(struct file *file,
+ page_cache_release(page);
+
+ if (pos + len > inode->i_size)
+- ext3_truncate_failed_write(inode);
++ ext3_truncate(inode);
+ return ret ? ret : copied;
+ }
+
+diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
+index f3032c9..1d04189 100644
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -761,13 +761,7 @@ static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb,
+ static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb,
+ ext4_group_t group)
+ {
+- if (!ext4_bg_has_super(sb, group))
+- return 0;
+-
+- if (EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG))
+- return le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
+- else
+- return EXT4_SB(sb)->s_gdb_count;
++ return ext4_bg_has_super(sb, group) ? EXT4_SB(sb)->s_gdb_count : 0;
+ }
+
+ /**
+diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
+index dc79b75..50784ef 100644
+--- a/fs/ext4/block_validity.c
++++ b/fs/ext4/block_validity.c
+@@ -160,7 +160,7 @@ int ext4_setup_system_zone(struct super_block *sb)
+ if (ext4_bg_has_super(sb, i) &&
+ ((i < 5) || ((i % flex_size) == 0)))
+ add_system_zone(sbi, ext4_group_first_block_no(sb, i),
+- ext4_bg_num_gdb(sb, i) + 1);
++ sbi->s_gdb_count + 1);
+ gdp = ext4_get_group_desc(sb, i, NULL);
+ ret = add_system_zone(sbi, ext4_block_bitmap(sb, gdp), 1);
+ if (ret)
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index d0a2afb..8825515 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -698,22 +698,11 @@ struct ext4_inode_info {
+ __u16 i_extra_isize;
+
+ spinlock_t i_block_reservation_lock;
+-#ifdef CONFIG_QUOTA
+- /* quota space reservation, managed internally by quota code */
+- qsize_t i_reserved_quota;
+-#endif
+
+ /* completed async DIOs that might need unwritten extents handling */
+ struct list_head i_aio_dio_complete_list;
+ /* current io_end structure for async DIO write*/
+ ext4_io_end_t *cur_aio_dio;
+-
+- /*
+- * Transactions that contain inode's metadata needed to complete
+- * fsync and fdatasync, respectively.
+- */
+- tid_t i_sync_tid;
+- tid_t i_datasync_tid;
+ };
+
+ /*
+@@ -761,7 +750,6 @@ struct ext4_inode_info {
+ #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
+ #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */
+ #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */
+-#define EXT4_MOUNT_DISCARD 0x40000000 /* Issue DISCARD requests */
+
+ #define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt
+ #define set_opt(o, opt) o |= EXT4_MOUNT_##opt
+@@ -1436,7 +1424,7 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
+ extern int ext4_block_truncate_page(handle_t *handle,
+ struct address_space *mapping, loff_t from);
+ extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
+-extern qsize_t *ext4_get_reserved_space(struct inode *inode);
++extern qsize_t ext4_get_reserved_space(struct inode *inode);
+ extern int flush_aio_dio_completed_IO(struct inode *inode);
+ /* ioctl.c */
+ extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
+diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
+index 1892a77..a286598 100644
+--- a/fs/ext4/ext4_jbd2.h
++++ b/fs/ext4/ext4_jbd2.h
+@@ -49,7 +49,7 @@
+
+ #define EXT4_DATA_TRANS_BLOCKS(sb) (EXT4_SINGLEDATA_TRANS_BLOCKS(sb) + \
+ EXT4_XATTR_TRANS_BLOCKS - 2 + \
+- EXT4_MAXQUOTAS_TRANS_BLOCKS(sb))
++ 2*EXT4_QUOTA_TRANS_BLOCKS(sb))
+
+ /*
+ * Define the number of metadata blocks we need to account to modify data.
+@@ -57,7 +57,7 @@
+ * This include super block, inode block, quota blocks and xattr blocks
+ */
+ #define EXT4_META_TRANS_BLOCKS(sb) (EXT4_XATTR_TRANS_BLOCKS + \
+- EXT4_MAXQUOTAS_TRANS_BLOCKS(sb))
++ 2*EXT4_QUOTA_TRANS_BLOCKS(sb))
+
+ /* Delete operations potentially hit one directory's namespace plus an
+ * entire inode, plus arbitrary amounts of bitmap/indirection data. Be
+@@ -92,7 +92,6 @@
+ * but inode, sb and group updates are done only once */
+ #define EXT4_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
+ (EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)+3+DQUOT_INIT_REWRITE) : 0)
+-
+ #define EXT4_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
+ (EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)+3+DQUOT_DEL_REWRITE) : 0)
+ #else
+@@ -100,9 +99,6 @@
+ #define EXT4_QUOTA_INIT_BLOCKS(sb) 0
+ #define EXT4_QUOTA_DEL_BLOCKS(sb) 0
+ #endif
+-#define EXT4_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_TRANS_BLOCKS(sb))
+-#define EXT4_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_INIT_BLOCKS(sb))
+-#define EXT4_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_DEL_BLOCKS(sb))
+
+ int
+ ext4_mark_iloc_dirty(handle_t *handle,
+@@ -258,19 +254,6 @@ static inline int ext4_jbd2_file_inode(handle_t *handle, struct inode *inode)
+ return 0;
+ }
+
+-static inline void ext4_update_inode_fsync_trans(handle_t *handle,
+- struct inode *inode,
+- int datasync)
+-{
+- struct ext4_inode_info *ei = EXT4_I(inode);
+-
+- if (ext4_handle_valid(handle)) {
+- ei->i_sync_tid = handle->h_transaction->t_tid;
+- if (datasync)
+- ei->i_datasync_tid = handle->h_transaction->t_tid;
+- }
+-}
+-
+ /* super.c */
+ int ext4_force_commit(struct super_block *sb);
+
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 8b8bae4..715264b 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -1761,9 +1761,7 @@ int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
+ while (block < last && block != EXT_MAX_BLOCK) {
+ num = last - block;
+ /* find extent for this block */
+- down_read(&EXT4_I(inode)->i_data_sem);
+ path = ext4_ext_find_extent(inode, block, path);
+- up_read(&EXT4_I(inode)->i_data_sem);
+ if (IS_ERR(path)) {
+ err = PTR_ERR(path);
+ path = NULL;
+@@ -2076,7 +2074,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
+ ext_debug("free last %u blocks starting %llu\n", num, start);
+ for (i = 0; i < num; i++) {
+ bh = sb_find_get_block(inode->i_sb, start + i);
+- ext4_forget(handle, metadata, inode, bh, start + i);
++ ext4_forget(handle, 0, inode, bh, start + i);
+ }
+ ext4_free_blocks(handle, inode, start, num, metadata);
+ } else if (from == le32_to_cpu(ex->ee_block)
+@@ -2169,7 +2167,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
+ correct_index = 1;
+ credits += (ext_depth(inode)) + 1;
+ }
+- credits += EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);
++ credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
+
+ err = ext4_ext_truncate_extend_restart(handle, inode, credits);
+ if (err)
+@@ -3066,8 +3064,6 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
+ if (flags == EXT4_GET_BLOCKS_DIO_CONVERT_EXT) {
+ ret = ext4_convert_unwritten_extents_dio(handle, inode,
+ path);
+- if (ret >= 0)
+- ext4_update_inode_fsync_trans(handle, inode, 1);
+ goto out2;
+ }
+ /* buffered IO case */
+@@ -3095,8 +3091,6 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
+ ret = ext4_ext_convert_to_initialized(handle, inode,
+ path, iblock,
+ max_blocks);
+- if (ret >= 0)
+- ext4_update_inode_fsync_trans(handle, inode, 1);
+ out:
+ if (ret <= 0) {
+ err = ret;
+@@ -3335,16 +3329,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
+ allocated = ext4_ext_get_actual_len(&newex);
+ set_buffer_new(bh_result);
+
+- /*
+- * Cache the extent and update transaction to commit on fdatasync only
+- * when it is _not_ an uninitialized extent.
+- */
+- if ((flags & EXT4_GET_BLOCKS_UNINIT_EXT) == 0) {
++ /* Cache only when it is _not_ an uninitialized extent */
++ if ((flags & EXT4_GET_BLOCKS_UNINIT_EXT) == 0)
+ ext4_ext_put_in_cache(inode, iblock, allocated, newblock,
+ EXT4_EXT_CACHE_EXTENT);
+- ext4_update_inode_fsync_trans(handle, inode, 1);
+- } else
+- ext4_update_inode_fsync_trans(handle, inode, 0);
+ out:
+ if (allocated > max_blocks)
+ allocated = max_blocks;
+@@ -3732,8 +3720,10 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ * Walk the extent tree gathering extent information.
+ * ext4_ext_fiemap_cb will push extents back to user.
+ */
++ down_read(&EXT4_I(inode)->i_data_sem);
+ error = ext4_ext_walk_space(inode, start_blk, len_blks,
+ ext4_ext_fiemap_cb, fieinfo);
++ up_read(&EXT4_I(inode)->i_data_sem);
+ }
+
+ return error;
+diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
+index d6049e4..2b15312 100644
+--- a/fs/ext4/fsync.c
++++ b/fs/ext4/fsync.c
+@@ -51,30 +51,25 @@
+ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
+ {
+ struct inode *inode = dentry->d_inode;
+- struct ext4_inode_info *ei = EXT4_I(inode);
+ journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
+- int ret;
+- tid_t commit_tid;
++ int err, ret = 0;
+
+ J_ASSERT(ext4_journal_current_handle() == NULL);
+
+ trace_ext4_sync_file(file, dentry, datasync);
+
+- if (inode->i_sb->s_flags & MS_RDONLY)
+- return 0;
+-
+ ret = flush_aio_dio_completed_IO(inode);
+ if (ret < 0)
+- return ret;
+-
+- if (!journal)
+- return simple_fsync(file, dentry, datasync);
+-
++ goto out;
+ /*
+- * data=writeback,ordered:
++ * data=writeback:
+ * The caller's filemap_fdatawrite()/wait will sync the data.
+- * Metadata is in the journal, we wait for proper transaction to
+- * commit here.
++ * sync_inode() will sync the metadata
++ *
++ * data=ordered:
++ * The caller's filemap_fdatawrite() will write the data and
++ * sync_inode() will write the inode if it is dirty. Then the caller's
++ * filemap_fdatawait() will wait on the pages.
+ *
+ * data=journal:
+ * filemap_fdatawrite won't do anything (the buffers are clean).
+@@ -84,13 +79,32 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
+ * (they were dirtied by commit). But that's OK - the blocks are
+ * safe in-journal, which is all fsync() needs to ensure.
+ */
+- if (ext4_should_journal_data(inode))
+- return ext4_force_commit(inode->i_sb);
++ if (ext4_should_journal_data(inode)) {
++ ret = ext4_force_commit(inode->i_sb);
++ goto out;
++ }
+
+- commit_tid = datasync ? ei->i_datasync_tid : ei->i_sync_tid;
+- if (jbd2_log_start_commit(journal, commit_tid))
+- jbd2_log_wait_commit(journal, commit_tid);
+- else if (journal->j_flags & JBD2_BARRIER)
++ if (!journal)
++ ret = sync_mapping_buffers(inode->i_mapping);
++
++ if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
++ goto out;
++
++ /*
++ * The VFS has written the file data. If the inode is unaltered
++ * then we need not start a commit.
++ */
++ if (inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC)) {
++ struct writeback_control wbc = {
++ .sync_mode = WB_SYNC_ALL,
++ .nr_to_write = 0, /* sys_fsync did this */
++ };
++ err = sync_inode(inode, &wbc);
++ if (ret == 0)
++ ret = err;
++ }
++out:
++ if (journal && (journal->j_flags & JBD2_BARRIER))
+ blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
+ return ret;
+ }
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index e233879..2c8caa5 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1021,12 +1021,10 @@ static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode,
+ if (!err)
+ err = ext4_splice_branch(handle, inode, iblock,
+ partial, indirect_blks, count);
+- if (err)
++ else
+ goto cleanup;
+
+ set_buffer_new(bh_result);
+-
+- ext4_update_inode_fsync_trans(handle, inode, 1);
+ got_it:
+ map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key));
+ if (count > blocks_to_boundary)
+@@ -1045,12 +1043,17 @@ out:
+ return err;
+ }
+
+-#ifdef CONFIG_QUOTA
+-qsize_t *ext4_get_reserved_space(struct inode *inode)
++qsize_t ext4_get_reserved_space(struct inode *inode)
+ {
+- return &EXT4_I(inode)->i_reserved_quota;
++ unsigned long long total;
++
++ spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
++ total = EXT4_I(inode)->i_reserved_data_blocks +
++ EXT4_I(inode)->i_reserved_meta_blocks;
++ spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
++
++ return total;
+ }
+-#endif
+ /*
+ * Calculate the number of metadata blocks need to reserve
+ * to allocate @blocks for non extent file based file
+@@ -1531,16 +1534,6 @@ static int do_journal_get_write_access(handle_t *handle,
+ return ext4_journal_get_write_access(handle, bh);
+ }
+
+-/*
+- * Truncate blocks that were not used by write. We have to truncate the
+- * pagecache as well so that corresponding buffers get properly unmapped.
+- */
+-static void ext4_truncate_failed_write(struct inode *inode)
+-{
+- truncate_inode_pages(inode->i_mapping, inode->i_size);
+- ext4_truncate(inode);
+-}
+-
+ static int ext4_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+@@ -1606,7 +1599,7 @@ retry:
+
+ ext4_journal_stop(handle);
+ if (pos + len > inode->i_size) {
+- ext4_truncate_failed_write(inode);
++ ext4_truncate(inode);
+ /*
+ * If truncate failed early the inode might
+ * still be on the orphan list; we need to
+@@ -1716,7 +1709,7 @@ static int ext4_ordered_write_end(struct file *file,
+ ret = ret2;
+
+ if (pos + len > inode->i_size) {
+- ext4_truncate_failed_write(inode);
++ ext4_truncate(inode);
+ /*
+ * If truncate failed early the inode might still be
+ * on the orphan list; we need to make sure the inode
+@@ -1758,7 +1751,7 @@ static int ext4_writeback_write_end(struct file *file,
+ ret = ret2;
+
+ if (pos + len > inode->i_size) {
+- ext4_truncate_failed_write(inode);
++ ext4_truncate(inode);
+ /*
+ * If truncate failed early the inode might still be
+ * on the orphan list; we need to make sure the inode
+@@ -1821,7 +1814,7 @@ static int ext4_journalled_write_end(struct file *file,
+ if (!ret)
+ ret = ret2;
+ if (pos + len > inode->i_size) {
+- ext4_truncate_failed_write(inode);
++ ext4_truncate(inode);
+ /*
+ * If truncate failed early the inode might still be
+ * on the orphan list; we need to make sure the inode
+@@ -1853,17 +1846,19 @@ repeat:
+
+ md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks;
+ total = md_needed + nrblocks;
+- spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
+
+ /*
+ * Make quota reservation here to prevent quota overflow
+ * later. Real quota accounting is done at pages writeout
+ * time.
+ */
+- if (vfs_dq_reserve_block(inode, total))
++ if (vfs_dq_reserve_block(inode, total)) {
++ spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
+ return -EDQUOT;
++ }
+
+ if (ext4_claim_free_blocks(sbi, total)) {
++ spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
+ vfs_dq_release_reservation_block(inode, total);
+ if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
+ yield();
+@@ -1871,11 +1866,10 @@ repeat:
+ }
+ return -ENOSPC;
+ }
+- spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
+ EXT4_I(inode)->i_reserved_data_blocks += nrblocks;
+- EXT4_I(inode)->i_reserved_meta_blocks += md_needed;
+- spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
++ EXT4_I(inode)->i_reserved_meta_blocks = mdblocks;
+
++ spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
+ return 0; /* success */
+ }
+
+@@ -2794,7 +2788,7 @@ static int ext4_da_writepages_trans_blocks(struct inode *inode)
+ * number of contiguous block. So we will limit
+ * number of contiguous block to a sane value
+ */
+- if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) &&
++ if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
+ (max_blocks > EXT4_MAX_TRANS_DATA))
+ max_blocks = EXT4_MAX_TRANS_DATA;
+
+@@ -3097,7 +3091,7 @@ retry:
+ * i_size_read because we hold i_mutex.
+ */
+ if (pos + len > inode->i_size)
+- ext4_truncate_failed_write(inode);
++ ext4_truncate(inode);
+ }
+
+ if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+@@ -4126,8 +4120,6 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
+ __le32 *last)
+ {
+ __le32 *p;
+- int is_metadata = S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode);
+-
+ if (try_to_extend_transaction(handle, inode)) {
+ if (bh) {
+ BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
+@@ -4158,11 +4150,11 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
+
+ *p = 0;
+ tbh = sb_find_get_block(inode->i_sb, nr);
+- ext4_forget(handle, is_metadata, inode, tbh, nr);
++ ext4_forget(handle, 0, inode, tbh, nr);
+ }
+ }
+
+- ext4_free_blocks(handle, inode, block_to_free, count, is_metadata);
++ ext4_free_blocks(handle, inode, block_to_free, count, 0);
+ }
+
+ /**
+@@ -4789,8 +4781,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ struct ext4_iloc iloc;
+ struct ext4_inode *raw_inode;
+ struct ext4_inode_info *ei;
++ struct buffer_head *bh;
+ struct inode *inode;
+- journal_t *journal = EXT4_SB(sb)->s_journal;
+ long ret;
+ int block;
+
+@@ -4801,11 +4793,11 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ return inode;
+
+ ei = EXT4_I(inode);
+- iloc.bh = 0;
+
+ ret = __ext4_get_inode_loc(inode, &iloc, 0);
+ if (ret < 0)
+ goto bad_inode;
++ bh = iloc.bh;
+ raw_inode = ext4_raw_inode(&iloc);
+ inode->i_mode = le16_to_cpu(raw_inode->i_mode);
+ inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
+@@ -4828,6 +4820,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ if (inode->i_mode == 0 ||
+ !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) {
+ /* this inode is deleted */
++ brelse(bh);
+ ret = -ESTALE;
+ goto bad_inode;
+ }
+@@ -4844,9 +4837,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
+ inode->i_size = ext4_isize(raw_inode);
+ ei->i_disksize = inode->i_size;
+-#ifdef CONFIG_QUOTA
+- ei->i_reserved_quota = 0;
+-#endif
+ inode->i_generation = le32_to_cpu(raw_inode->i_generation);
+ ei->i_block_group = iloc.block_group;
+ ei->i_last_alloc_group = ~0;
+@@ -4858,35 +4848,11 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ ei->i_data[block] = raw_inode->i_block[block];
+ INIT_LIST_HEAD(&ei->i_orphan);
+
+- /*
+- * Set transaction id's of transactions that have to be committed
+- * to finish f[data]sync. We set them to currently running transaction
+- * as we cannot be sure that the inode or some of its metadata isn't
+- * part of the transaction - the inode could have been reclaimed and
+- * now it is reread from disk.
+- */
+- if (journal) {
+- transaction_t *transaction;
+- tid_t tid;
+-
+- spin_lock(&journal->j_state_lock);
+- if (journal->j_running_transaction)
+- transaction = journal->j_running_transaction;
+- else
+- transaction = journal->j_committing_transaction;
+- if (transaction)
+- tid = transaction->t_tid;
+- else
+- tid = journal->j_commit_sequence;
+- spin_unlock(&journal->j_state_lock);
+- ei->i_sync_tid = tid;
+- ei->i_datasync_tid = tid;
+- }
+-
+ if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
+ ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
+ if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
+ EXT4_INODE_SIZE(inode->i_sb)) {
++ brelse(bh);
+ ret = -EIO;
+ goto bad_inode;
+ }
+@@ -4918,7 +4884,10 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+
+ ret = 0;
+ if (ei->i_file_acl &&
+- !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
++ ((ei->i_file_acl <
++ (le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block) +
++ EXT4_SB(sb)->s_gdb_count)) ||
++ (ei->i_file_acl >= ext4_blocks_count(EXT4_SB(sb)->s_es)))) {
+ ext4_error(sb, __func__,
+ "bad extended attribute block %llu in inode #%lu",
+ ei->i_file_acl, inode->i_ino);
+@@ -4936,8 +4905,10 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ /* Validate block references which are part of inode */
+ ret = ext4_check_inode_blockref(inode);
+ }
+- if (ret)
++ if (ret) {
++ brelse(bh);
+ goto bad_inode;
++ }
+
+ if (S_ISREG(inode->i_mode)) {
+ inode->i_op = &ext4_file_inode_operations;
+@@ -4965,6 +4936,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ init_special_inode(inode, inode->i_mode,
+ new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
+ } else {
++ brelse(bh);
+ ret = -EIO;
+ ext4_error(inode->i_sb, __func__,
+ "bogus i_mode (%o) for inode=%lu",
+@@ -4977,7 +4949,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ return inode;
+
+ bad_inode:
+- brelse(iloc.bh);
+ iget_failed(inode);
+ return ERR_PTR(ret);
+ }
+@@ -5137,7 +5108,6 @@ static int ext4_do_update_inode(handle_t *handle,
+ err = rc;
+ ei->i_state &= ~EXT4_STATE_NEW;
+
+- ext4_update_inode_fsync_trans(handle, inode, 0);
+ out_brelse:
+ brelse(bh);
+ ext4_std_error(inode->i_sb, err);
+@@ -5257,8 +5227,8 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
+
+ /* (user+group)*(old+new) structure, inode write (sb,
+ * inode block, ? - but truncate inode update has it) */
+- handle = ext4_journal_start(inode, (EXT4_MAXQUOTAS_INIT_BLOCKS(inode->i_sb)+
+- EXT4_MAXQUOTAS_DEL_BLOCKS(inode->i_sb))+3);
++ handle = ext4_journal_start(inode, 2*(EXT4_QUOTA_INIT_BLOCKS(inode->i_sb)+
++ EXT4_QUOTA_DEL_BLOCKS(inode->i_sb))+3);
+ if (IS_ERR(handle)) {
+ error = PTR_ERR(handle);
+ goto err_out;
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index b63d193..c1cdf61 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -221,38 +221,31 @@ setversion_out:
+ struct file *donor_filp;
+ int err;
+
+- if (!(filp->f_mode & FMODE_READ) ||
+- !(filp->f_mode & FMODE_WRITE))
+- return -EBADF;
+-
+ if (copy_from_user(&me,
+ (struct move_extent __user *)arg, sizeof(me)))
+ return -EFAULT;
+- me.moved_len = 0;
+
+ donor_filp = fget(me.donor_fd);
+ if (!donor_filp)
+ return -EBADF;
+
+- if (!(donor_filp->f_mode & FMODE_WRITE)) {
+- err = -EBADF;
+- goto mext_out;
++ if (!capable(CAP_DAC_OVERRIDE)) {
++ if ((current->real_cred->fsuid != inode->i_uid) ||
++ !(inode->i_mode & S_IRUSR) ||
++ !(donor_filp->f_dentry->d_inode->i_mode &
++ S_IRUSR)) {
++ fput(donor_filp);
++ return -EACCES;
++ }
+ }
+
+- err = mnt_want_write(filp->f_path.mnt);
+- if (err)
+- goto mext_out;
+-
+ err = ext4_move_extents(filp, donor_filp, me.orig_start,
+ me.donor_start, me.len, &me.moved_len);
+- mnt_drop_write(filp->f_path.mnt);
+- if (me.moved_len > 0)
+- file_remove_suid(donor_filp);
++ fput(donor_filp);
+
+ if (copy_to_user((struct move_extent *)arg, &me, sizeof(me)))
+- err = -EFAULT;
+-mext_out:
+- fput(donor_filp);
++ return -EFAULT;
++
+ return err;
+ }
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 7d71148..bba1282 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2529,6 +2529,7 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
+ struct ext4_group_info *db;
+ int err, count = 0, count2 = 0;
+ struct ext4_free_data *entry;
++ ext4_fsblk_t discard_block;
+ struct list_head *l, *ltmp;
+
+ list_for_each_safe(l, ltmp, &txn->t_private_list) {
+@@ -2558,19 +2559,13 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
+ page_cache_release(e4b.bd_bitmap_page);
+ }
+ ext4_unlock_group(sb, entry->group);
+- if (test_opt(sb, DISCARD)) {
+- ext4_fsblk_t discard_block;
+- struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+-
+- discard_block = (ext4_fsblk_t)entry->group *
+- EXT4_BLOCKS_PER_GROUP(sb)
+- + entry->start_blk
+- + le32_to_cpu(es->s_first_data_block);
+- trace_ext4_discard_blocks(sb,
+- (unsigned long long)discard_block,
+- entry->count);
+- sb_issue_discard(sb, discard_block, entry->count);
+- }
++ discard_block = (ext4_fsblk_t) entry->group * EXT4_BLOCKS_PER_GROUP(sb)
++ + entry->start_blk
++ + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
++ trace_ext4_discard_blocks(sb, (unsigned long long)discard_block,
++ entry->count);
++ sb_issue_discard(sb, discard_block, entry->count);
++
+ kmem_cache_free(ext4_free_ext_cachep, entry);
+ ext4_mb_release_desc(&e4b);
+ }
+@@ -3011,24 +3006,6 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
+ }
+
+ /*
+- * Called on failure; free up any blocks from the inode PA for this
+- * context. We don't need this for MB_GROUP_PA because we only change
+- * pa_free in ext4_mb_release_context(), but on failure, we've already
+- * zeroed out ac->ac_b_ex.fe_len, so group_pa->pa_free is not changed.
+- */
+-static void ext4_discard_allocated_blocks(struct ext4_allocation_context *ac)
+-{
+- struct ext4_prealloc_space *pa = ac->ac_pa;
+- int len;
+-
+- if (pa && pa->pa_type == MB_INODE_PA) {
+- len = ac->ac_b_ex.fe_len;
+- pa->pa_free += len;
+- }
+-
+-}
+-
+-/*
+ * use blocks preallocated to inode
+ */
+ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
+@@ -4313,7 +4290,6 @@ repeat:
+ ac->ac_status = AC_STATUS_CONTINUE;
+ goto repeat;
+ } else if (*errp) {
+- ext4_discard_allocated_blocks(ac);
+ ac->ac_b_ex.fe_len = 0;
+ ar->len = 0;
+ ext4_mb_show_ac(ac);
+diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
+index 8646149..a93d5b8 100644
+--- a/fs/ext4/migrate.c
++++ b/fs/ext4/migrate.c
+@@ -238,7 +238,7 @@ static int extend_credit_for_blkdel(handle_t *handle, struct inode *inode)
+ * So allocate a credit of 3. We may update
+ * quota (user and group).
+ */
+- needed = 3 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);
++ needed = 3 + 2*EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
+
+ if (ext4_journal_extend(handle, needed) != 0)
+ retval = ext4_journal_restart(handle, needed);
+@@ -477,7 +477,7 @@ int ext4_ext_migrate(struct inode *inode)
+ handle = ext4_journal_start(inode,
+ EXT4_DATA_TRANS_BLOCKS(inode->i_sb) +
+ EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+- EXT4_MAXQUOTAS_INIT_BLOCKS(inode->i_sb)
++ 2 * EXT4_QUOTA_INIT_BLOCKS(inode->i_sb)
+ + 1);
+ if (IS_ERR(handle)) {
+ retval = PTR_ERR(handle);
+diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
+index f5b03a1..25b6b14 100644
+--- a/fs/ext4/move_extent.c
++++ b/fs/ext4/move_extent.c
+@@ -77,14 +77,12 @@ static int
+ mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
+ struct ext4_extent **extent)
+ {
+- struct ext4_extent_header *eh;
+ int ppos, leaf_ppos = path->p_depth;
+
+ ppos = leaf_ppos;
+ if (EXT_LAST_EXTENT(path[ppos].p_hdr) > path[ppos].p_ext) {
+ /* leaf block */
+ *extent = ++path[ppos].p_ext;
+- path[ppos].p_block = ext_pblock(path[ppos].p_ext);
+ return 0;
+ }
+
+@@ -121,18 +119,9 @@ mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
+ ext_block_hdr(path[cur_ppos+1].p_bh);
+ }
+
+- path[leaf_ppos].p_ext = *extent = NULL;
+-
+- eh = path[leaf_ppos].p_hdr;
+- if (le16_to_cpu(eh->eh_entries) == 0)
+- /* empty leaf is found */
+- return -ENODATA;
+-
+ /* leaf block */
+ path[leaf_ppos].p_ext = *extent =
+ EXT_FIRST_EXTENT(path[leaf_ppos].p_hdr);
+- path[leaf_ppos].p_block =
+- ext_pblock(path[leaf_ppos].p_ext);
+ return 0;
+ }
+ }
+@@ -166,15 +155,40 @@ mext_check_null_inode(struct inode *inode1, struct inode *inode2,
+ }
+
+ /**
+- * double_down_write_data_sem - Acquire two inodes' write lock of i_data_sem
++ * mext_double_down_read - Acquire two inodes' read semaphore
++ *
++ * @orig_inode: original inode structure
++ * @donor_inode: donor inode structure
++ * Acquire read semaphore of the two inodes (orig and donor) by i_ino order.
++ */
++static void
++mext_double_down_read(struct inode *orig_inode, struct inode *donor_inode)
++{
++ struct inode *first = orig_inode, *second = donor_inode;
++
++ /*
++ * Use the inode number to provide the stable locking order instead
++ * of its address, because the C language doesn't guarantee you can
++ * compare pointers that don't come from the same array.
++ */
++ if (donor_inode->i_ino < orig_inode->i_ino) {
++ first = donor_inode;
++ second = orig_inode;
++ }
++
++ down_read(&EXT4_I(first)->i_data_sem);
++ down_read(&EXT4_I(second)->i_data_sem);
++}
++
++/**
++ * mext_double_down_write - Acquire two inodes' write semaphore
+ *
+ * @orig_inode: original inode structure
+ * @donor_inode: donor inode structure
+- * Acquire write lock of i_data_sem of the two inodes (orig and donor) by
+- * i_ino order.
++ * Acquire write semaphore of the two inodes (orig and donor) by i_ino order.
+ */
+ static void
+-double_down_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
++mext_double_down_write(struct inode *orig_inode, struct inode *donor_inode)
+ {
+ struct inode *first = orig_inode, *second = donor_inode;
+
+@@ -189,18 +203,32 @@ double_down_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
+ }
+
+ down_write(&EXT4_I(first)->i_data_sem);
+- down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
++ down_write(&EXT4_I(second)->i_data_sem);
+ }
+
+ /**
+- * double_up_write_data_sem - Release two inodes' write lock of i_data_sem
++ * mext_double_up_read - Release two inodes' read semaphore
+ *
+ * @orig_inode: original inode structure to be released its lock first
+ * @donor_inode: donor inode structure to be released its lock second
+- * Release write lock of i_data_sem of two inodes (orig and donor).
++ * Release read semaphore of two inodes (orig and donor).
+ */
+ static void
+-double_up_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
++mext_double_up_read(struct inode *orig_inode, struct inode *donor_inode)
++{
++ up_read(&EXT4_I(orig_inode)->i_data_sem);
++ up_read(&EXT4_I(donor_inode)->i_data_sem);
++}
++
++/**
++ * mext_double_up_write - Release two inodes' write semaphore
++ *
++ * @orig_inode: original inode structure to be released its lock first
++ * @donor_inode: donor inode structure to be released its lock second
++ * Release write semaphore of two inodes (orig and donor).
++ */
++static void
++mext_double_up_write(struct inode *orig_inode, struct inode *donor_inode)
+ {
+ up_write(&EXT4_I(orig_inode)->i_data_sem);
+ up_write(&EXT4_I(donor_inode)->i_data_sem);
+@@ -633,7 +661,6 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext,
+ * @donor_inode: donor inode
+ * @from: block offset of orig_inode
+ * @count: block count to be replaced
+- * @err: pointer to save return value
+ *
+ * Replace original inode extents and donor inode extents page by page.
+ * We implement this replacement in the following three steps:
+@@ -644,33 +671,33 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext,
+ * 3. Change the block information of donor inode to point at the saved
+ * original inode blocks in the dummy extents.
+ *
+- * Return replaced block count.
++ * Return 0 on success, or a negative error value on failure.
+ */
+ static int
+ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
+ struct inode *donor_inode, ext4_lblk_t from,
+- ext4_lblk_t count, int *err)
++ ext4_lblk_t count)
+ {
+ struct ext4_ext_path *orig_path = NULL;
+ struct ext4_ext_path *donor_path = NULL;
+ struct ext4_extent *oext, *dext;
+ struct ext4_extent tmp_dext, tmp_oext;
+ ext4_lblk_t orig_off = from, donor_off = from;
++ int err = 0;
+ int depth;
+ int replaced_count = 0;
+ int dext_alen;
+
+- /* Protect extent trees against block allocations via delalloc */
+- double_down_write_data_sem(orig_inode, donor_inode);
++ mext_double_down_write(orig_inode, donor_inode);
+
+ /* Get the original extent for the block "orig_off" */
+- *err = get_ext_path(orig_inode, orig_off, &orig_path);
+- if (*err)
++ err = get_ext_path(orig_inode, orig_off, &orig_path);
++ if (err)
+ goto out;
+
+ /* Get the donor extent for the head */
+- *err = get_ext_path(donor_inode, donor_off, &donor_path);
+- if (*err)
++ err = get_ext_path(donor_inode, donor_off, &donor_path);
++ if (err)
+ goto out;
+ depth = ext_depth(orig_inode);
+ oext = orig_path[depth].p_ext;
+@@ -680,9 +707,9 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
+ dext = donor_path[depth].p_ext;
+ tmp_dext = *dext;
+
+- *err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
++ err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
+ donor_off, count);
+- if (*err)
++ if (err)
+ goto out;
+
+ /* Loop for the donor extents */
+@@ -691,7 +718,7 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
+ if (!dext) {
+ ext4_error(donor_inode->i_sb, __func__,
+ "The extent for donor must be found");
+- *err = -EIO;
++ err = -EIO;
+ goto out;
+ } else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) {
+ ext4_error(donor_inode->i_sb, __func__,
+@@ -699,20 +726,20 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
+ "extent(%u) should be equal",
+ donor_off,
+ le32_to_cpu(tmp_dext.ee_block));
+- *err = -EIO;
++ err = -EIO;
+ goto out;
+ }
+
+ /* Set donor extent to orig extent */
+- *err = mext_leaf_block(handle, orig_inode,
++ err = mext_leaf_block(handle, orig_inode,
+ orig_path, &tmp_dext, &orig_off);
+- if (*err)
++ if (err < 0)
+ goto out;
+
+ /* Set orig extent to donor extent */
+- *err = mext_leaf_block(handle, donor_inode,
++ err = mext_leaf_block(handle, donor_inode,
+ donor_path, &tmp_oext, &donor_off);
+- if (*err)
++ if (err < 0)
+ goto out;
+
+ dext_alen = ext4_ext_get_actual_len(&tmp_dext);
+@@ -726,25 +753,35 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
+
+ if (orig_path)
+ ext4_ext_drop_refs(orig_path);
+- *err = get_ext_path(orig_inode, orig_off, &orig_path);
+- if (*err)
++ err = get_ext_path(orig_inode, orig_off, &orig_path);
++ if (err)
+ goto out;
+ depth = ext_depth(orig_inode);
+ oext = orig_path[depth].p_ext;
++ if (le32_to_cpu(oext->ee_block) +
++ ext4_ext_get_actual_len(oext) <= orig_off) {
++ err = 0;
++ goto out;
++ }
+ tmp_oext = *oext;
+
+ if (donor_path)
+ ext4_ext_drop_refs(donor_path);
+- *err = get_ext_path(donor_inode, donor_off, &donor_path);
+- if (*err)
++ err = get_ext_path(donor_inode, donor_off, &donor_path);
++ if (err)
+ goto out;
+ depth = ext_depth(donor_inode);
+ dext = donor_path[depth].p_ext;
++ if (le32_to_cpu(dext->ee_block) +
++ ext4_ext_get_actual_len(dext) <= donor_off) {
++ err = 0;
++ goto out;
++ }
+ tmp_dext = *dext;
+
+- *err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
++ err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
+ donor_off, count - replaced_count);
+- if (*err)
++ if (err)
+ goto out;
+ }
+
+@@ -758,12 +795,8 @@ out:
+ kfree(donor_path);
+ }
+
+- ext4_ext_invalidate_cache(orig_inode);
+- ext4_ext_invalidate_cache(donor_inode);
+-
+- double_up_write_data_sem(orig_inode, donor_inode);
+-
+- return replaced_count;
++ mext_double_up_write(orig_inode, donor_inode);
++ return err;
+ }
+
+ /**
+@@ -775,17 +808,16 @@ out:
+ * @data_offset_in_page: block index where data swapping starts
+ * @block_len_in_page: the number of blocks to be swapped
+ * @uninit: orig extent is uninitialized or not
+- * @err: pointer to save return value
+ *
+ * Save the data in original inode blocks and replace original inode extents
+ * with donor inode extents by calling mext_replace_branches().
+- * Finally, write out the saved data in new original inode blocks. Return
+- * replaced block count.
++ * Finally, write out the saved data in new original inode blocks. Return 0
++ * on success, or a negative error value on failure.
+ */
+ static int
+ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
+ pgoff_t orig_page_offset, int data_offset_in_page,
+- int block_len_in_page, int uninit, int *err)
++ int block_len_in_page, int uninit)
+ {
+ struct inode *orig_inode = o_filp->f_dentry->d_inode;
+ struct address_space *mapping = orig_inode->i_mapping;
+@@ -797,11 +829,9 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
+ long long offs = orig_page_offset << PAGE_CACHE_SHIFT;
+ unsigned long blocksize = orig_inode->i_sb->s_blocksize;
+ unsigned int w_flags = 0;
+- unsigned int tmp_data_size, data_size, replaced_size;
++ unsigned int tmp_data_len, data_len;
+ void *fsdata;
+- int i, jblocks;
+- int err2 = 0;
+- int replaced_count = 0;
++ int ret, i, jblocks;
+ int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
+
+ /*
+@@ -811,8 +841,8 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
+ jblocks = ext4_writepage_trans_blocks(orig_inode) * 2;
+ handle = ext4_journal_start(orig_inode, jblocks);
+ if (IS_ERR(handle)) {
+- *err = PTR_ERR(handle);
+- return 0;
++ ret = PTR_ERR(handle);
++ return ret;
+ }
+
+ if (segment_eq(get_fs(), KERNEL_DS))
+@@ -828,36 +858,39 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
+ * Just swap data blocks between orig and donor.
+ */
+ if (uninit) {
+- replaced_count = mext_replace_branches(handle, orig_inode,
+- donor_inode, orig_blk_offset,
+- block_len_in_page, err);
++ ret = mext_replace_branches(handle, orig_inode,
++ donor_inode, orig_blk_offset,
++ block_len_in_page);
++
++ /* Clear the inode cache not to refer to the old data */
++ ext4_ext_invalidate_cache(orig_inode);
++ ext4_ext_invalidate_cache(donor_inode);
+ goto out2;
+ }
+
+ offs = (long long)orig_blk_offset << orig_inode->i_blkbits;
+
+- /* Calculate data_size */
++ /* Calculate data_len */
+ if ((orig_blk_offset + block_len_in_page - 1) ==
+ ((orig_inode->i_size - 1) >> orig_inode->i_blkbits)) {
+ /* Replace the last block */
+- tmp_data_size = orig_inode->i_size & (blocksize - 1);
++ tmp_data_len = orig_inode->i_size & (blocksize - 1);
+ /*
+- * If data_size equal zero, it shows data_size is multiples of
++ * If data_len equal zero, it shows data_len is multiples of
+ * blocksize. So we set appropriate value.
+ */
+- if (tmp_data_size == 0)
+- tmp_data_size = blocksize;
++ if (tmp_data_len == 0)
++ tmp_data_len = blocksize;
+
+- data_size = tmp_data_size +
++ data_len = tmp_data_len +
+ ((block_len_in_page - 1) << orig_inode->i_blkbits);
+- } else
+- data_size = block_len_in_page << orig_inode->i_blkbits;
+-
+- replaced_size = data_size;
++ } else {
++ data_len = block_len_in_page << orig_inode->i_blkbits;
++ }
+
+- *err = a_ops->write_begin(o_filp, mapping, offs, data_size, w_flags,
++ ret = a_ops->write_begin(o_filp, mapping, offs, data_len, w_flags,
+ &page, &fsdata);
+- if (unlikely(*err < 0))
++ if (unlikely(ret < 0))
+ goto out;
+
+ if (!PageUptodate(page)) {
+@@ -878,17 +911,14 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
+ /* Release old bh and drop refs */
+ try_to_release_page(page, 0);
+
+- replaced_count = mext_replace_branches(handle, orig_inode, donor_inode,
+- orig_blk_offset, block_len_in_page,
+- &err2);
+- if (err2) {
+- if (replaced_count) {
+- block_len_in_page = replaced_count;
+- replaced_size =
+- block_len_in_page << orig_inode->i_blkbits;
+- } else
+- goto out;
+- }
++ ret = mext_replace_branches(handle, orig_inode, donor_inode,
++ orig_blk_offset, block_len_in_page);
++ if (ret < 0)
++ goto out;
++
++ /* Clear the inode cache not to refer to the old data */
++ ext4_ext_invalidate_cache(orig_inode);
++ ext4_ext_invalidate_cache(donor_inode);
+
+ if (!page_has_buffers(page))
+ create_empty_buffers(page, 1 << orig_inode->i_blkbits, 0);
+@@ -898,16 +928,16 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
+ bh = bh->b_this_page;
+
+ for (i = 0; i < block_len_in_page; i++) {
+- *err = ext4_get_block(orig_inode,
++ ret = ext4_get_block(orig_inode,
+ (sector_t)(orig_blk_offset + i), bh, 0);
+- if (*err < 0)
++ if (ret < 0)
+ goto out;
+
+ if (bh->b_this_page != NULL)
+ bh = bh->b_this_page;
+ }
+
+- *err = a_ops->write_end(o_filp, mapping, offs, data_size, replaced_size,
++ ret = a_ops->write_end(o_filp, mapping, offs, data_len, data_len,
+ page, fsdata);
+ page = NULL;
+
+@@ -921,10 +951,7 @@ out:
+ out2:
+ ext4_journal_stop(handle);
+
+- if (err2)
+- *err = err2;
+-
+- return replaced_count;
++ return ret < 0 ? ret : 0;
+ }
+
+ /**
+@@ -935,6 +962,7 @@ out2:
+ * @orig_start: logical start offset in block for orig
+ * @donor_start: logical start offset in block for donor
+ * @len: the number of blocks to be moved
++ * @moved_len: moved block length
+ *
+ * Check the arguments of ext4_move_extents() whether the files can be
+ * exchanged with each other.
+@@ -942,8 +970,8 @@ out2:
+ */
+ static int
+ mext_check_arguments(struct inode *orig_inode,
+- struct inode *donor_inode, __u64 orig_start,
+- __u64 donor_start, __u64 *len)
++ struct inode *donor_inode, __u64 orig_start,
++ __u64 donor_start, __u64 *len, __u64 moved_len)
+ {
+ ext4_lblk_t orig_blocks, donor_blocks;
+ unsigned int blkbits = orig_inode->i_blkbits;
+@@ -957,13 +985,6 @@ mext_check_arguments(struct inode *orig_inode,
+ return -EINVAL;
+ }
+
+- if (donor_inode->i_mode & (S_ISUID|S_ISGID)) {
+- ext4_debug("ext4 move extent: suid or sgid is set"
+- " to donor file [ino:orig %lu, donor %lu]\n",
+- orig_inode->i_ino, donor_inode->i_ino);
+- return -EINVAL;
+- }
+-
+ /* Ext4 move extent does not support swapfile */
+ if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) {
+ ext4_debug("ext4 move extent: The argument files should "
+@@ -1004,6 +1025,13 @@ mext_check_arguments(struct inode *orig_inode,
+ return -EINVAL;
+ }
+
++ if (moved_len) {
++ ext4_debug("ext4 move extent: moved_len should be 0 "
++ "[ino:orig %lu, donor %lu]\n", orig_inode->i_ino,
++ donor_inode->i_ino);
++ return -EINVAL;
++ }
++
+ if ((orig_start > EXT_MAX_BLOCK) ||
+ (donor_start > EXT_MAX_BLOCK) ||
+ (*len > EXT_MAX_BLOCK) ||
+@@ -1204,16 +1232,16 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
+ return -EINVAL;
+ }
+
+- /* Protect orig and donor inodes against a truncate */
++ /* protect orig and donor against a truncate */
+ ret1 = mext_inode_double_lock(orig_inode, donor_inode);
+ if (ret1 < 0)
+ return ret1;
+
+- /* Protect extent tree against block allocations via delalloc */
+- double_down_write_data_sem(orig_inode, donor_inode);
++ mext_double_down_read(orig_inode, donor_inode);
+ /* Check the filesystem environment whether move_extent can be done */
+ ret1 = mext_check_arguments(orig_inode, donor_inode, orig_start,
+- donor_start, &len);
++ donor_start, &len, *moved_len);
++ mext_double_up_read(orig_inode, donor_inode);
+ if (ret1)
+ goto out;
+
+@@ -1327,39 +1355,36 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
+ seq_start = le32_to_cpu(ext_cur->ee_block);
+ rest_blocks = seq_blocks;
+
+- /*
+- * Up semaphore to avoid following problems:
+- * a. transaction deadlock among ext4_journal_start,
+- * ->write_begin via pagefault, and jbd2_journal_commit
+- * b. racing with ->readpage, ->write_begin, and ext4_get_block
+- * in move_extent_per_page
+- */
+- double_up_write_data_sem(orig_inode, donor_inode);
++ /* Discard preallocations of two inodes */
++ down_write(&EXT4_I(orig_inode)->i_data_sem);
++ ext4_discard_preallocations(orig_inode);
++ up_write(&EXT4_I(orig_inode)->i_data_sem);
++
++ down_write(&EXT4_I(donor_inode)->i_data_sem);
++ ext4_discard_preallocations(donor_inode);
++ up_write(&EXT4_I(donor_inode)->i_data_sem);
+
+ while (orig_page_offset <= seq_end_page) {
+
+ /* Swap original branches with new branches */
+- block_len_in_page = move_extent_per_page(
+- o_filp, donor_inode,
++ ret1 = move_extent_per_page(o_filp, donor_inode,
+ orig_page_offset,
+ data_offset_in_page,
+- block_len_in_page, uninit,
+- &ret1);
+-
++ block_len_in_page, uninit);
++ if (ret1 < 0)
++ goto out;
++ orig_page_offset++;
+ /* Count how many blocks we have exchanged */
+ *moved_len += block_len_in_page;
+- if (ret1 < 0)
+- break;
+ if (*moved_len > len) {
+ ext4_error(orig_inode->i_sb, __func__,
+ "We replaced blocks too much! "
+ "sum of replaced: %llu requested: %llu",
+ *moved_len, len);
+ ret1 = -EIO;
+- break;
++ goto out;
+ }
+
+- orig_page_offset++;
+ data_offset_in_page = 0;
+ rest_blocks -= block_len_in_page;
+ if (rest_blocks > blocks_per_page)
+@@ -1368,10 +1393,6 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
+ block_len_in_page = rest_blocks;
+ }
+
+- double_down_write_data_sem(orig_inode, donor_inode);
+- if (ret1 < 0)
+- break;
+-
+ /* Decrease buffer counter */
+ if (holecheck_path)
+ ext4_ext_drop_refs(holecheck_path);
+@@ -1393,11 +1414,6 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
+
+ }
+ out:
+- if (*moved_len) {
+- ext4_discard_preallocations(orig_inode);
+- ext4_discard_preallocations(donor_inode);
+- }
+-
+ if (orig_path) {
+ ext4_ext_drop_refs(orig_path);
+ kfree(orig_path);
+@@ -1406,7 +1422,7 @@ out:
+ ext4_ext_drop_refs(holecheck_path);
+ kfree(holecheck_path);
+ }
+- double_up_write_data_sem(orig_inode, donor_inode);
++
+ ret2 = mext_inode_double_unlock(orig_inode, donor_inode);
+
+ if (ret1)
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 17a17e1..6d2c1b8 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1292,6 +1292,9 @@ errout:
+ * add_dirent_to_buf will attempt search the directory block for
+ * space. It will return -ENOSPC if no space is available, and -EIO
+ * and -EEXIST if directory entry already exists.
++ *
++ * NOTE! bh is NOT released in the case where ENOSPC is returned. In
++ * all other cases bh is released.
+ */
+ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
+ struct inode *inode, struct ext4_dir_entry_2 *de,
+@@ -1312,10 +1315,14 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
+ top = bh->b_data + blocksize - reclen;
+ while ((char *) de <= top) {
+ if (!ext4_check_dir_entry("ext4_add_entry", dir, de,
+- bh, offset))
++ bh, offset)) {
++ brelse(bh);
+ return -EIO;
+- if (ext4_match(namelen, name, de))
++ }
++ if (ext4_match(namelen, name, de)) {
++ brelse(bh);
+ return -EEXIST;
++ }
+ nlen = EXT4_DIR_REC_LEN(de->name_len);
+ rlen = ext4_rec_len_from_disk(de->rec_len, blocksize);
+ if ((de->inode? rlen - nlen: rlen) >= reclen)
+@@ -1330,6 +1337,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
+ err = ext4_journal_get_write_access(handle, bh);
+ if (err) {
+ ext4_std_error(dir->i_sb, err);
++ brelse(bh);
+ return err;
+ }
+
+@@ -1369,6 +1377,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
+ err = ext4_handle_dirty_metadata(handle, dir, bh);
+ if (err)
+ ext4_std_error(dir->i_sb, err);
++ brelse(bh);
+ return 0;
+ }
+
+@@ -1462,9 +1471,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
+ if (!(de))
+ return retval;
+
+- retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
+- brelse(bh);
+- return retval;
++ return add_dirent_to_buf(handle, dentry, inode, de, bh);
+ }
+
+ /*
+@@ -1507,10 +1514,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
+ if(!bh)
+ return retval;
+ retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
+- if (retval != -ENOSPC) {
+- brelse(bh);
++ if (retval != -ENOSPC)
+ return retval;
+- }
+
+ if (blocks == 1 && !dx_fallback &&
+ EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
+@@ -1523,9 +1528,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
+ de = (struct ext4_dir_entry_2 *) bh->b_data;
+ de->inode = 0;
+ de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize);
+- retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
+- brelse(bh);
+- return retval;
++ return add_dirent_to_buf(handle, dentry, inode, de, bh);
+ }
+
+ /*
+@@ -1558,8 +1561,10 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
+ goto journal_error;
+
+ err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
+- if (err != -ENOSPC)
++ if (err != -ENOSPC) {
++ bh = NULL;
+ goto cleanup;
++ }
+
+ /* Block full, should compress but for now just split */
+ dxtrace(printk(KERN_DEBUG "using %u of %u node entries\n",
+@@ -1652,6 +1657,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
+ if (!de)
+ goto cleanup;
+ err = add_dirent_to_buf(handle, dentry, inode, de, bh);
++ bh = NULL;
+ goto cleanup;
+
+ journal_error:
+@@ -1769,7 +1775,7 @@ static int ext4_create(struct inode *dir, struct dentry *dentry, int mode,
+ retry:
+ handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+ EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+- EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
++ 2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+@@ -1803,7 +1809,7 @@ static int ext4_mknod(struct inode *dir, struct dentry *dentry,
+ retry:
+ handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+ EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+- EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
++ 2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+@@ -1840,7 +1846,7 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+ retry:
+ handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+ EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+- EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
++ 2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+@@ -2253,7 +2259,7 @@ static int ext4_symlink(struct inode *dir,
+ retry:
+ handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+ EXT4_INDEX_EXTRA_TRANS_BLOCKS + 5 +
+- EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
++ 2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 3b2c554..3cfc343 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -247,7 +247,7 @@ static int setup_new_group_blocks(struct super_block *sb,
+ goto exit_bh;
+
+ if (IS_ERR(gdb = bclean(handle, sb, block))) {
+- err = PTR_ERR(gdb);
++ err = PTR_ERR(bh);
+ goto exit_bh;
+ }
+ ext4_handle_dirty_metadata(handle, NULL, gdb);
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 92943f2..d4ca92a 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -603,6 +603,10 @@ static void ext4_put_super(struct super_block *sb)
+ if (sb->s_dirt)
+ ext4_commit_super(sb, 1);
+
++ ext4_release_system_zone(sb);
++ ext4_mb_release(sb);
++ ext4_ext_release(sb);
++ ext4_xattr_put_super(sb);
+ if (sbi->s_journal) {
+ err = jbd2_journal_destroy(sbi->s_journal);
+ sbi->s_journal = NULL;
+@@ -610,12 +614,6 @@ static void ext4_put_super(struct super_block *sb)
+ ext4_abort(sb, __func__,
+ "Couldn't clean up the journal");
+ }
+-
+- ext4_release_system_zone(sb);
+- ext4_mb_release(sb);
+- ext4_ext_release(sb);
+- ext4_xattr_put_super(sb);
+-
+ if (!(sb->s_flags & MS_RDONLY)) {
+ EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+ es->s_state = cpu_to_le16(sbi->s_mount_state);
+@@ -704,13 +702,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
+ ei->i_allocated_meta_blocks = 0;
+ ei->i_delalloc_reserved_flag = 0;
+ spin_lock_init(&(ei->i_block_reservation_lock));
+-#ifdef CONFIG_QUOTA
+- ei->i_reserved_quota = 0;
+-#endif
+ INIT_LIST_HEAD(&ei->i_aio_dio_complete_list);
+ ei->cur_aio_dio = NULL;
+- ei->i_sync_tid = 0;
+- ei->i_datasync_tid = 0;
+
+ return &ei->vfs_inode;
+ }
+@@ -906,12 +899,6 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
+ if (test_opt(sb, NO_AUTO_DA_ALLOC))
+ seq_puts(seq, ",noauto_da_alloc");
+
+- if (test_opt(sb, DISCARD))
+- seq_puts(seq, ",discard");
+-
+- if (test_opt(sb, NOLOAD))
+- seq_puts(seq, ",norecovery");
+-
+ ext4_show_quota_options(seq, sb);
+
+ return 0;
+@@ -1004,9 +991,7 @@ static const struct dquot_operations ext4_quota_operations = {
+ .reserve_space = dquot_reserve_space,
+ .claim_space = dquot_claim_space,
+ .release_rsv = dquot_release_reserved_space,
+-#ifdef CONFIG_QUOTA
+ .get_reserved_space = ext4_get_reserved_space,
+-#endif
+ .alloc_inode = dquot_alloc_inode,
+ .free_space = dquot_free_space,
+ .free_inode = dquot_free_inode,
+@@ -1094,8 +1079,7 @@ enum {
+ Opt_usrquota, Opt_grpquota, Opt_i_version,
+ Opt_stripe, Opt_delalloc, Opt_nodelalloc,
+ Opt_block_validity, Opt_noblock_validity,
+- Opt_inode_readahead_blks, Opt_journal_ioprio,
+- Opt_discard, Opt_nodiscard,
++ Opt_inode_readahead_blks, Opt_journal_ioprio
+ };
+
+ static const match_table_t tokens = {
+@@ -1120,7 +1104,6 @@ static const match_table_t tokens = {
+ {Opt_acl, "acl"},
+ {Opt_noacl, "noacl"},
+ {Opt_noload, "noload"},
+- {Opt_noload, "norecovery"},
+ {Opt_nobh, "nobh"},
+ {Opt_bh, "bh"},
+ {Opt_commit, "commit=%u"},
+@@ -1161,8 +1144,6 @@ static const match_table_t tokens = {
+ {Opt_auto_da_alloc, "auto_da_alloc=%u"},
+ {Opt_auto_da_alloc, "auto_da_alloc"},
+ {Opt_noauto_da_alloc, "noauto_da_alloc"},
+- {Opt_discard, "discard"},
+- {Opt_nodiscard, "nodiscard"},
+ {Opt_err, NULL},
+ };
+
+@@ -1584,12 +1565,6 @@ set_qf_format:
+ else
+ set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);
+ break;
+- case Opt_discard:
+- set_opt(sbi->s_mount_opt, DISCARD);
+- break;
+- case Opt_nodiscard:
+- clear_opt(sbi->s_mount_opt, DISCARD);
+- break;
+ default:
+ ext4_msg(sb, KERN_ERR,
+ "Unrecognized mount option \"%s\" "
+@@ -1698,14 +1673,14 @@ static int ext4_fill_flex_info(struct super_block *sb)
+ size_t size;
+ int i;
+
+- sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
+- groups_per_flex = 1 << sbi->s_log_groups_per_flex;
+-
+- if (groups_per_flex < 2) {
++ if (!sbi->s_es->s_log_groups_per_flex) {
+ sbi->s_log_groups_per_flex = 0;
+ return 1;
+ }
+
++ sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
++ groups_per_flex = 1 << sbi->s_log_groups_per_flex;
++
+ /* We allocate both existing and potentially added groups */
+ flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
+ ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
+@@ -3693,11 +3668,13 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
+ buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last;
+ buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) -
+ percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter);
++ ext4_free_blocks_count_set(es, buf->f_bfree);
+ buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
+ if (buf->f_bfree < ext4_r_blocks_count(es))
+ buf->f_bavail = 0;
+ buf->f_files = le32_to_cpu(es->s_inodes_count);
+ buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter);
++ es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
+ buf->f_namelen = EXT4_NAME_LEN;
+ fsid = le64_to_cpup((void *)es->s_uuid) ^
+ le64_to_cpup((void *)es->s_uuid + sizeof(u64));
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 0257019..fed5b01 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -988,10 +988,6 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ if (error)
+ goto cleanup;
+
+- error = ext4_journal_get_write_access(handle, is.iloc.bh);
+- if (error)
+- goto cleanup;
+-
+ if (EXT4_I(inode)->i_state & EXT4_STATE_NEW) {
+ struct ext4_inode *raw_inode = ext4_raw_inode(&is.iloc);
+ memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
+@@ -1017,6 +1013,9 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ if (flags & XATTR_CREATE)
+ goto cleanup;
+ }
++ error = ext4_journal_get_write_access(handle, is.iloc.bh);
++ if (error)
++ goto cleanup;
+ if (!value) {
+ if (!is.s.not_found)
+ error = ext4_xattr_ibody_set(handle, inode, &i, &is);
+diff --git a/fs/fcntl.c b/fs/fcntl.c
+index 97e01dc..2cf93ec 100644
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -618,90 +618,60 @@ static DEFINE_RWLOCK(fasync_lock);
+ static struct kmem_cache *fasync_cache __read_mostly;
+
+ /*
+- * Remove a fasync entry. If successfully removed, return
+- * positive and clear the FASYNC flag. If no entry exists,
+- * do nothing and return 0.
+- *
+- * NOTE! It is very important that the FASYNC flag always
+- * match the state "is the filp on a fasync list".
+- *
+- * We always take the 'filp->f_lock', in since fasync_lock
+- * needs to be irq-safe.
++ * fasync_helper() is used by almost all character device drivers
++ * to set up the fasync queue. It returns negative on error, 0 if it did
++ * no changes and positive if it added/deleted the entry.
+ */
+-static int fasync_remove_entry(struct file *filp, struct fasync_struct **fapp)
++int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
+ {
+ struct fasync_struct *fa, **fp;
++ struct fasync_struct *new = NULL;
+ int result = 0;
+
+- spin_lock(&filp->f_lock);
+- write_lock_irq(&fasync_lock);
+- for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
+- if (fa->fa_file != filp)
+- continue;
+- *fp = fa->fa_next;
+- kmem_cache_free(fasync_cache, fa);
+- filp->f_flags &= ~FASYNC;
+- result = 1;
+- break;
++ if (on) {
++ new = kmem_cache_alloc(fasync_cache, GFP_KERNEL);
++ if (!new)
++ return -ENOMEM;
+ }
+- write_unlock_irq(&fasync_lock);
+- spin_unlock(&filp->f_lock);
+- return result;
+-}
+-
+-/*
+- * Add a fasync entry. Return negative on error, positive if
+- * added, and zero if did nothing but change an existing one.
+- *
+- * NOTE! It is very important that the FASYNC flag always
+- * match the state "is the filp on a fasync list".
+- */
+-static int fasync_add_entry(int fd, struct file *filp, struct fasync_struct **fapp)
+-{
+- struct fasync_struct *new, *fa, **fp;
+- int result = 0;
+-
+- new = kmem_cache_alloc(fasync_cache, GFP_KERNEL);
+- if (!new)
+- return -ENOMEM;
+
++ /*
++ * We need to take f_lock first since it's not an IRQ-safe
++ * lock.
++ */
+ spin_lock(&filp->f_lock);
+ write_lock_irq(&fasync_lock);
+ for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
+- if (fa->fa_file != filp)
+- continue;
+- fa->fa_fd = fd;
+- kmem_cache_free(fasync_cache, new);
+- goto out;
++ if (fa->fa_file == filp) {
++ if(on) {
++ fa->fa_fd = fd;
++ kmem_cache_free(fasync_cache, new);
++ } else {
++ *fp = fa->fa_next;
++ kmem_cache_free(fasync_cache, fa);
++ result = 1;
++ }
++ goto out;
++ }
+ }
+
+- new->magic = FASYNC_MAGIC;
+- new->fa_file = filp;
+- new->fa_fd = fd;
+- new->fa_next = *fapp;
+- *fapp = new;
+- result = 1;
+- filp->f_flags |= FASYNC;
+-
++ if (on) {
++ new->magic = FASYNC_MAGIC;
++ new->fa_file = filp;
++ new->fa_fd = fd;
++ new->fa_next = *fapp;
++ *fapp = new;
++ result = 1;
++ }
+ out:
++ if (on)
++ filp->f_flags |= FASYNC;
++ else
++ filp->f_flags &= ~FASYNC;
+ write_unlock_irq(&fasync_lock);
+ spin_unlock(&filp->f_lock);
+ return result;
+ }
+
+-/*
+- * fasync_helper() is used by almost all character device drivers
+- * to set up the fasync queue, and for regular files by the file
+- * lease code. It returns negative on error, 0 if it did no changes
+- * and positive if it added/deleted the entry.
+- */
+-int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
+-{
+- if (!on)
+- return fasync_remove_entry(filp, fapp);
+- return fasync_add_entry(fd, filp, fapp);
+-}
+-
+ EXPORT_SYMBOL(fasync_helper);
+
+ void __kill_fasync(struct fasync_struct *fa, int sig, int band)
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index a9f5e13..c18913a 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -828,9 +828,6 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
+ if (!page)
+ break;
+
+- if (mapping_writably_mapped(mapping))
+- flush_dcache_page(page);
+-
+ pagefault_disable();
+ tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes);
+ pagefault_enable();
+diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c
+index 424b033..6d98f11 100644
+--- a/fs/hfs/catalog.c
++++ b/fs/hfs/catalog.c
+@@ -289,10 +289,6 @@ int hfs_cat_move(u32 cnid, struct inode *src_dir, struct qstr *src_name,
+ err = hfs_brec_find(&src_fd);
+ if (err)
+ goto out;
+- if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) {
+- err = -EIO;
+- goto out;
+- }
+
+ hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset,
+ src_fd.entrylength);
+diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
+index 2b3b861..7c69b98 100644
+--- a/fs/hfs/dir.c
++++ b/fs/hfs/dir.c
+@@ -79,11 +79,6 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ filp->f_pos++;
+ /* fall through */
+ case 1:
+- if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {
+- err = -EIO;
+- goto out;
+- }
+-
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
+ if (entry.type != HFS_CDR_THD) {
+ printk(KERN_ERR "hfs: bad catalog folder thread\n");
+@@ -114,12 +109,6 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ err = -EIO;
+ goto out;
+ }
+-
+- if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {
+- err = -EIO;
+- goto out;
+- }
+-
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
+ type = entry.type;
+ len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName);
+diff --git a/fs/hfs/super.c b/fs/hfs/super.c
+index 5ed7252..f7fcbe4 100644
+--- a/fs/hfs/super.c
++++ b/fs/hfs/super.c
+@@ -409,13 +409,8 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
+ /* try to get the root inode */
+ hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
+ res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd);
+- if (!res) {
+- if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) {
+- res = -EIO;
+- goto bail;
+- }
++ if (!res)
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength);
+- }
+ if (res) {
+ hfs_find_exit(&fd);
+ goto bail_no_root;
+diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
+index 8896c1d..d4cfd6d 100644
+--- a/fs/jbd2/commit.c
++++ b/fs/jbd2/commit.c
+@@ -636,10 +636,6 @@ void jbd2_journal_commit_transaction(journal_t *journal)
+ JBUFFER_TRACE(jh, "ph3: write metadata");
+ flags = jbd2_journal_write_metadata_buffer(commit_transaction,
+ jh, &new_jh, blocknr);
+- if (flags < 0) {
+- jbd2_journal_abort(journal, flags);
+- continue;
+- }
+ set_bit(BH_JWrite, &jh2bh(new_jh)->b_state);
+ wbuf[bufs++] = jh2bh(new_jh);
+
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
+index b7ca3a9..fed8538 100644
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -78,7 +78,6 @@ EXPORT_SYMBOL(jbd2_journal_errno);
+ EXPORT_SYMBOL(jbd2_journal_ack_err);
+ EXPORT_SYMBOL(jbd2_journal_clear_err);
+ EXPORT_SYMBOL(jbd2_log_wait_commit);
+-EXPORT_SYMBOL(jbd2_log_start_commit);
+ EXPORT_SYMBOL(jbd2_journal_start_commit);
+ EXPORT_SYMBOL(jbd2_journal_force_commit_nested);
+ EXPORT_SYMBOL(jbd2_journal_wipe);
+@@ -359,10 +358,6 @@ repeat:
+
+ jbd_unlock_bh_state(bh_in);
+ tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS);
+- if (!tmp) {
+- jbd2_journal_put_journal_head(new_jh);
+- return -ENOMEM;
+- }
+ jbd_lock_bh_state(bh_in);
+ if (jh_in->b_frozen_data) {
+ jbd2_free(tmp, bh_in->b_size);
+@@ -1253,13 +1248,6 @@ int jbd2_journal_load(journal_t *journal)
+ if (jbd2_journal_recover(journal))
+ goto recovery_error;
+
+- if (journal->j_failed_commit) {
+- printk(KERN_ERR "JBD2: journal transaction %u on %s "
+- "is corrupt.\n", journal->j_failed_commit,
+- journal->j_devname);
+- return -EIO;
+- }
+-
+ /* OK, we've finished with the dynamic journal bits:
+ * reinitialise the dynamic contents of the superblock in memory
+ * and reset them on disk. */
+diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
+index 3b6f2fa..090c556 100644
+--- a/fs/jffs2/gc.c
++++ b/fs/jffs2/gc.c
+@@ -700,8 +700,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
+ struct jffs2_raw_inode ri;
+ struct jffs2_node_frag *last_frag;
+ union jffs2_device_node dev;
+- char *mdata = NULL;
+- int mdatalen = 0;
++ char *mdata = NULL, mdatalen = 0;
+ uint32_t alloclen, ilen;
+ int ret;
+
+diff --git a/fs/namei.c b/fs/namei.c
+index a2b3c28..d11f404 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -234,7 +234,6 @@ int generic_permission(struct inode *inode, int mask,
+ /*
+ * Searching includes executable on directories, else just read.
+ */
+- mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
+ if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
+ if (capable(CAP_DAC_READ_SEARCH))
+ return 0;
+diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
+index 0d28982..e1d415e 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -342,7 +342,6 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
+ data->res.fattr = &data->fattr;
+ data->res.eof = 0;
+ data->res.count = bytes;
+- nfs_fattr_init(&data->fattr);
+ msg.rpc_argp = &data->args;
+ msg.rpc_resp = &data->res;
+
+@@ -576,7 +575,6 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
+ data->res.count = 0;
+ data->res.fattr = &data->fattr;
+ data->res.verf = &data->verf;
+- nfs_fattr_init(&data->fattr);
+
+ NFS_PROTO(data->inode)->commit_setup(data, &msg);
+
+@@ -768,7 +766,6 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
+ data->res.fattr = &data->fattr;
+ data->res.count = bytes;
+ data->res.verf = &data->verf;
+- nfs_fattr_init(&data->fattr);
+
+ task_setup_data.task = &data->task;
+ task_setup_data.callback_data = data;
+diff --git a/fs/nfs/file.c b/fs/nfs/file.c
+index 393d40f..f5fdd39 100644
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -486,8 +486,6 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
+ {
+ dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
+
+- if (gfp & __GFP_WAIT)
+- nfs_wb_page(page->mapping->host, page);
+ /* If PagePrivate() is set, then the page is not freeable */
+ if (PagePrivate(page))
+ return 0;
+diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
+index 237874f..fa58800 100644
+--- a/fs/nfs/fscache.c
++++ b/fs/nfs/fscache.c
+@@ -354,11 +354,12 @@ void nfs_fscache_reset_inode_cookie(struct inode *inode)
+ */
+ int nfs_fscache_release_page(struct page *page, gfp_t gfp)
+ {
+- if (PageFsCache(page)) {
+- struct nfs_inode *nfsi = NFS_I(page->mapping->host);
+- struct fscache_cookie *cookie = nfsi->fscache;
++ struct nfs_inode *nfsi = NFS_I(page->mapping->host);
++ struct fscache_cookie *cookie = nfsi->fscache;
+
+- BUG_ON(!cookie);
++ BUG_ON(!cookie);
++
++ if (PageFsCache(page)) {
+ dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
+ cookie, page, nfsi);
+
+diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
+index 59047f8..0adefc4 100644
+--- a/fs/nfs/mount_clnt.c
++++ b/fs/nfs/mount_clnt.c
+@@ -120,7 +120,7 @@ static struct {
+ { .status = MNT3ERR_INVAL, .errno = -EINVAL, },
+ { .status = MNT3ERR_NAMETOOLONG, .errno = -ENAMETOOLONG, },
+ { .status = MNT3ERR_NOTSUPP, .errno = -ENOTSUPP, },
+- { .status = MNT3ERR_SERVERFAULT, .errno = -EREMOTEIO, },
++ { .status = MNT3ERR_SERVERFAULT, .errno = -ESERVERFAULT, },
+ };
+
+ struct mountres {
+diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
+index 7bc2da8..5e078b2 100644
+--- a/fs/nfs/nfs2xdr.c
++++ b/fs/nfs/nfs2xdr.c
+@@ -699,7 +699,7 @@ static struct {
+ { NFSERR_BAD_COOKIE, -EBADCOOKIE },
+ { NFSERR_NOTSUPP, -ENOTSUPP },
+ { NFSERR_TOOSMALL, -ETOOSMALL },
+- { NFSERR_SERVERFAULT, -EREMOTEIO },
++ { NFSERR_SERVERFAULT, -ESERVERFAULT },
+ { NFSERR_BADTYPE, -EBADTYPE },
+ { NFSERR_JUKEBOX, -EJUKEBOX },
+ { -1, -EIO }
+diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
+index b4a6b1a..6ea07a3 100644
+--- a/fs/nfs/nfs4_fs.h
++++ b/fs/nfs/nfs4_fs.h
+@@ -141,7 +141,6 @@ enum {
+ NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */
+ NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */
+ NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */
+- NFS_STATE_POSIX_LOCKS, /* Posix locks are supported */
+ };
+
+ struct nfs4_state {
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 6c20059..741a562 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -1573,8 +1573,6 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
+ status = PTR_ERR(state);
+ if (IS_ERR(state))
+ goto err_opendata_put;
+- if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0)
+- set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
+ nfs4_opendata_put(opendata);
+ nfs4_put_state_owner(sp);
+ *res = state;
+@@ -3978,22 +3976,6 @@ static const struct rpc_call_ops nfs4_lock_ops = {
+ .rpc_release = nfs4_lock_release,
+ };
+
+-static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error)
+-{
+- struct nfs_client *clp = server->nfs_client;
+- struct nfs4_state *state = lsp->ls_state;
+-
+- switch (error) {
+- case -NFS4ERR_ADMIN_REVOKED:
+- case -NFS4ERR_BAD_STATEID:
+- case -NFS4ERR_EXPIRED:
+- if (new_lock_owner != 0 ||
+- (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
+- nfs4_state_mark_reclaim_nograce(clp, state);
+- lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
+- };
+-}
+-
+ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int reclaim)
+ {
+ struct nfs4_lockdata *data;
+@@ -4029,9 +4011,6 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
+ ret = nfs4_wait_for_completion_rpc_task(task);
+ if (ret == 0) {
+ ret = data->rpc_status;
+- if (ret)
+- nfs4_handle_setlk_error(data->server, data->lsp,
+- data->arg.new_lock_owner, ret);
+ } else
+ data->cancelled = 1;
+ rpc_put_task(task);
+@@ -4081,11 +4060,8 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
+ {
+ struct nfs_inode *nfsi = NFS_I(state->inode);
+ unsigned char fl_flags = request->fl_flags;
+- int status = -ENOLCK;
++ int status;
+
+- if ((fl_flags & FL_POSIX) &&
+- !test_bit(NFS_STATE_POSIX_LOCKS, &state->flags))
+- goto out;
+ /* Is this a delegated open? */
+ status = nfs4_set_lock_state(state, request);
+ if (status != 0)
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index a4cd1b7..20b4e30 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -4554,7 +4554,7 @@ static int decode_sequence(struct xdr_stream *xdr,
+ * If the server returns different values for sessionID, slotID or
+ * sequence number, the server is looney tunes.
+ */
+- status = -EREMOTEIO;
++ status = -ESERVERFAULT;
+
+ if (memcmp(id.data, res->sr_session->sess_id.data,
+ NFS4_MAX_SESSIONID_LEN)) {
+@@ -5678,7 +5678,7 @@ static struct {
+ { NFS4ERR_BAD_COOKIE, -EBADCOOKIE },
+ { NFS4ERR_NOTSUPP, -ENOTSUPP },
+ { NFS4ERR_TOOSMALL, -ETOOSMALL },
+- { NFS4ERR_SERVERFAULT, -EREMOTEIO },
++ { NFS4ERR_SERVERFAULT, -ESERVERFAULT },
+ { NFS4ERR_BADTYPE, -EBADTYPE },
+ { NFS4ERR_LOCKED, -EAGAIN },
+ { NFS4ERR_SYMLINK, -ELOOP },
+@@ -5705,7 +5705,7 @@ nfs4_stat_to_errno(int stat)
+ }
+ if (stat <= 10000 || stat > 10100) {
+ /* The server is looney tunes. */
+- return -EREMOTEIO;
++ return -ESERVERFAULT;
+ }
+ /* If we cannot translate the error, the recovery routines should
+ * handle it.
+diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
+index a12c45b..e297593 100644
+--- a/fs/nfs/pagelist.c
++++ b/fs/nfs/pagelist.c
+@@ -176,12 +176,6 @@ void nfs_release_request(struct nfs_page *req)
+ kref_put(&req->wb_kref, nfs_free_request);
+ }
+
+-static int nfs_wait_bit_uninterruptible(void *word)
+-{
+- io_schedule();
+- return 0;
+-}
+-
+ /**
+ * nfs_wait_on_request - Wait for a request to complete.
+ * @req: request to wait upon.
+@@ -192,9 +186,14 @@ static int nfs_wait_bit_uninterruptible(void *word)
+ int
+ nfs_wait_on_request(struct nfs_page *req)
+ {
+- return wait_on_bit(&req->wb_flags, PG_BUSY,
+- nfs_wait_bit_uninterruptible,
+- TASK_UNINTERRUPTIBLE);
++ int ret = 0;
++
++ if (!test_bit(PG_BUSY, &req->wb_flags))
++ goto out;
++ ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY,
++ nfs_wait_bit_killable, TASK_KILLABLE);
++out:
++ return ret;
+ }
+
+ /**
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index 4bf23f6..90be551 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -241,7 +241,6 @@ static int nfs_show_stats(struct seq_file *, struct vfsmount *);
+ static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *);
+ static int nfs_xdev_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
+-static void nfs_put_super(struct super_block *);
+ static void nfs_kill_super(struct super_block *);
+ static int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
+
+@@ -265,7 +264,6 @@ static const struct super_operations nfs_sops = {
+ .alloc_inode = nfs_alloc_inode,
+ .destroy_inode = nfs_destroy_inode,
+ .write_inode = nfs_write_inode,
+- .put_super = nfs_put_super,
+ .statfs = nfs_statfs,
+ .clear_inode = nfs_clear_inode,
+ .umount_begin = nfs_umount_begin,
+@@ -335,7 +333,6 @@ static const struct super_operations nfs4_sops = {
+ .alloc_inode = nfs_alloc_inode,
+ .destroy_inode = nfs_destroy_inode,
+ .write_inode = nfs_write_inode,
+- .put_super = nfs_put_super,
+ .statfs = nfs_statfs,
+ .clear_inode = nfs4_clear_inode,
+ .umount_begin = nfs_umount_begin,
+@@ -737,6 +734,8 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (data) {
++ data->rsize = NFS_MAX_FILE_IO_SIZE;
++ data->wsize = NFS_MAX_FILE_IO_SIZE;
+ data->acregmin = NFS_DEF_ACREGMIN;
+ data->acregmax = NFS_DEF_ACREGMAX;
+ data->acdirmin = NFS_DEF_ACDIRMIN;
+@@ -2199,17 +2198,6 @@ error_splat_super:
+ }
+
+ /*
+- * Ensure that we unregister the bdi before kill_anon_super
+- * releases the device name
+- */
+-static void nfs_put_super(struct super_block *s)
+-{
+- struct nfs_server *server = NFS_SB(s);
+-
+- bdi_unregister(&server->backing_dev_info);
+-}
+-
+-/*
+ * Destroy an NFS2/3 superblock
+ */
+ static void nfs_kill_super(struct super_block *s)
+@@ -2217,6 +2205,7 @@ static void nfs_kill_super(struct super_block *s)
+ struct nfs_server *server = NFS_SB(s);
+
+ kill_anon_super(s);
++ bdi_unregister(&server->backing_dev_info);
+ nfs_fscache_release_super_cookie(s);
+ nfs_free_server(server);
+ }
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index cf6c06f..53eb26c 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -1542,7 +1542,6 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
+ break;
+ }
+ ret = nfs_wait_on_request(req);
+- nfs_release_request(req);
+ if (ret < 0)
+ goto out;
+ }
+@@ -1613,16 +1612,15 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
+ if (ret)
+ goto out_unlock;
+ page_cache_get(newpage);
+- spin_lock(&mapping->host->i_lock);
+ req->wb_page = newpage;
+ SetPagePrivate(newpage);
+- set_page_private(newpage, (unsigned long)req);
++ set_page_private(newpage, page_private(page));
+ ClearPagePrivate(page);
+ set_page_private(page, 0);
+- spin_unlock(&mapping->host->i_lock);
+ page_cache_release(page);
+ out_unlock:
+ nfs_clear_page_tag_locked(req);
++ nfs_release_request(req);
+ out:
+ return ret;
+ }
+diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
+index 6d9c6aa..725d02f 100644
+--- a/fs/nfsd/nfs4acl.c
++++ b/fs/nfsd/nfs4acl.c
+@@ -389,7 +389,7 @@ sort_pacl(struct posix_acl *pacl)
+ sort_pacl_range(pacl, 1, i-1);
+
+ BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ);
+- j = ++i;
++ j = i++;
+ while (pacl->a_entries[j].e_tag == ACL_GROUP)
+ j++;
+ sort_pacl_range(pacl, i, j-1);
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index 570dd1c..a293f02 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -774,9 +774,12 @@ static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
+ int (*fsync) (struct file *, struct dentry *, int);
+ int err;
+
+- err = filemap_write_and_wait(inode->i_mapping);
++ err = filemap_fdatawrite(inode->i_mapping);
+ if (err == 0 && fop && (fsync = fop->fsync))
+ err = fsync(filp, dp, 0);
++ if (err == 0)
++ err = filemap_fdatawait(inode->i_mapping);
++
+ return err;
+ }
+
+diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
+index 1afb0a1..c9ee67b 100644
+--- a/fs/notify/inotify/inotify_fsnotify.c
++++ b/fs/notify/inotify/inotify_fsnotify.c
+@@ -121,7 +121,7 @@ static int idr_callback(int id, void *p, void *data)
+ if (warned)
+ return 0;
+
+- warned = true;
++ warned = false;
+ entry = p;
+ ientry = container_of(entry, struct inotify_inode_mark_entry, fsn_entry);
+
+diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
+index ca44337..dcd2040 100644
+--- a/fs/notify/inotify/inotify_user.c
++++ b/fs/notify/inotify/inotify_user.c
+@@ -558,7 +558,7 @@ retry:
+
+ spin_lock(&group->inotify_data.idr_lock);
+ ret = idr_get_new_above(&group->inotify_data.idr, &tmp_ientry->fsn_entry,
+- group->inotify_data.last_wd+1,
++ group->inotify_data.last_wd,
+ &tmp_ientry->wd);
+ spin_unlock(&group->inotify_data.idr_lock);
+ if (ret) {
+@@ -638,7 +638,7 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign
+
+ spin_lock_init(&group->inotify_data.idr_lock);
+ idr_init(&group->inotify_data.idr);
+- group->inotify_data.last_wd = 0;
++ group->inotify_data.last_wd = 1;
+ group->inotify_data.user = user;
+ group->inotify_data.fa = NULL;
+
+diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c
+index 49cfd5f..038a602 100644
+--- a/fs/partitions/efi.c
++++ b/fs/partitions/efi.c
+@@ -1,9 +1,7 @@
+ /************************************************************
+ * EFI GUID Partition Table handling
+- *
+- * http://www.uefi.org/specs/
+- * http://www.intel.com/technology/efi/
+- *
++ * Per Intel EFI Specification v1.02
++ * http://developer.intel.com/technology/efi/efi.htm
+ * efi.[ch] by Matt Domsch <Matt_Domsch at dell.com>
+ * Copyright 2000,2001,2002,2004 Dell Inc.
+ *
+@@ -94,7 +92,6 @@
+ *
+ ************************************************************/
+ #include <linux/crc32.h>
+-#include <linux/math64.h>
+ #include "check.h"
+ #include "efi.h"
+
+@@ -144,8 +141,7 @@ last_lba(struct block_device *bdev)
+ {
+ if (!bdev || !bdev->bd_inode)
+ return 0;
+- return div_u64(bdev->bd_inode->i_size,
+- bdev_logical_block_size(bdev)) - 1ULL;
++ return (bdev->bd_inode->i_size >> 9) - 1ULL;
+ }
+
+ static inline int
+@@ -192,7 +188,6 @@ static size_t
+ read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
+ {
+ size_t totalreadcount = 0;
+- sector_t n = lba * (bdev_logical_block_size(bdev) / 512);
+
+ if (!bdev || !buffer || lba > last_lba(bdev))
+ return 0;
+@@ -200,7 +195,7 @@ read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
+ while (count) {
+ int copied = 512;
+ Sector sect;
+- unsigned char *data = read_dev_sector(bdev, n++, §);
++ unsigned char *data = read_dev_sector(bdev, lba++, §);
+ if (!data)
+ break;
+ if (copied > count)
+@@ -262,16 +257,15 @@ static gpt_header *
+ alloc_read_gpt_header(struct block_device *bdev, u64 lba)
+ {
+ gpt_header *gpt;
+- unsigned ssz = bdev_logical_block_size(bdev);
+-
+ if (!bdev)
+ return NULL;
+
+- gpt = kzalloc(ssz, GFP_KERNEL);
++ gpt = kzalloc(sizeof (gpt_header), GFP_KERNEL);
+ if (!gpt)
+ return NULL;
+
+- if (read_lba(bdev, lba, (u8 *) gpt, ssz) < ssz) {
++ if (read_lba(bdev, lba, (u8 *) gpt,
++ sizeof (gpt_header)) < sizeof (gpt_header)) {
+ kfree(gpt);
+ gpt=NULL;
+ return NULL;
+@@ -607,7 +601,6 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev)
+ gpt_header *gpt = NULL;
+ gpt_entry *ptes = NULL;
+ u32 i;
+- unsigned ssz = bdev_logical_block_size(bdev) / 512;
+
+ if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) {
+ kfree(gpt);
+@@ -618,14 +611,13 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev)
+ pr_debug("GUID Partition Table is valid! Yea!\n");
+
+ for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
+- u64 start = le64_to_cpu(ptes[i].starting_lba);
+- u64 size = le64_to_cpu(ptes[i].ending_lba) -
+- le64_to_cpu(ptes[i].starting_lba) + 1ULL;
+-
+ if (!is_pte_valid(&ptes[i], last_lba(bdev)))
+ continue;
+
+- put_partition(state, i+1, start * ssz, size * ssz);
++ put_partition(state, i+1, le64_to_cpu(ptes[i].starting_lba),
++ (le64_to_cpu(ptes[i].ending_lba) -
++ le64_to_cpu(ptes[i].starting_lba) +
++ 1ULL));
+
+ /* If this is a RAID volume, tell md */
+ if (!efi_guidcmp(ptes[i].partition_type_guid,
+diff --git a/fs/partitions/efi.h b/fs/partitions/efi.h
+index 6998b58..2cc89d0 100644
+--- a/fs/partitions/efi.h
++++ b/fs/partitions/efi.h
+@@ -37,6 +37,7 @@
+ #define EFI_PMBR_OSTYPE_EFI 0xEF
+ #define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
+
++#define GPT_BLOCK_SIZE 512
+ #define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
+ #define GPT_HEADER_REVISION_V1 0x00010000
+ #define GPT_PRIMARY_PARTITION_TABLE_LBA 1
+@@ -78,12 +79,7 @@ typedef struct _gpt_header {
+ __le32 num_partition_entries;
+ __le32 sizeof_partition_entry;
+ __le32 partition_entry_array_crc32;
+-
+- /* The rest of the logical block is reserved by UEFI and must be zero.
+- * EFI standard handles this by:
+- *
+- * uint8_t reserved2[ BlockSize - 92 ];
+- */
++ u8 reserved2[GPT_BLOCK_SIZE - 92];
+ } __attribute__ ((packed)) gpt_header;
+
+ typedef struct _gpt_entry_attributes {
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 2534987..39b49c4 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -1388,70 +1388,6 @@ void vfs_dq_drop(struct inode *inode)
+ EXPORT_SYMBOL(vfs_dq_drop);
+
+ /*
+- * inode_reserved_space is managed internally by quota, and protected by
+- * i_lock similar to i_blocks+i_bytes.
+- */
+-static qsize_t *inode_reserved_space(struct inode * inode)
+-{
+- /* Filesystem must explicitly define it's own method in order to use
+- * quota reservation interface */
+- BUG_ON(!inode->i_sb->dq_op->get_reserved_space);
+- return inode->i_sb->dq_op->get_reserved_space(inode);
+-}
+-
+-static void inode_add_rsv_space(struct inode *inode, qsize_t number)
+-{
+- spin_lock(&inode->i_lock);
+- *inode_reserved_space(inode) += number;
+- spin_unlock(&inode->i_lock);
+-}
+-
+-
+-static void inode_claim_rsv_space(struct inode *inode, qsize_t number)
+-{
+- spin_lock(&inode->i_lock);
+- *inode_reserved_space(inode) -= number;
+- __inode_add_bytes(inode, number);
+- spin_unlock(&inode->i_lock);
+-}
+-
+-static void inode_sub_rsv_space(struct inode *inode, qsize_t number)
+-{
+- spin_lock(&inode->i_lock);
+- *inode_reserved_space(inode) -= number;
+- spin_unlock(&inode->i_lock);
+-}
+-
+-static qsize_t inode_get_rsv_space(struct inode *inode)
+-{
+- qsize_t ret;
+-
+- if (!inode->i_sb->dq_op->get_reserved_space)
+- return 0;
+- spin_lock(&inode->i_lock);
+- ret = *inode_reserved_space(inode);
+- spin_unlock(&inode->i_lock);
+- return ret;
+-}
+-
+-static void inode_incr_space(struct inode *inode, qsize_t number,
+- int reserve)
+-{
+- if (reserve)
+- inode_add_rsv_space(inode, number);
+- else
+- inode_add_bytes(inode, number);
+-}
+-
+-static void inode_decr_space(struct inode *inode, qsize_t number, int reserve)
+-{
+- if (reserve)
+- inode_sub_rsv_space(inode, number);
+- else
+- inode_sub_bytes(inode, number);
+-}
+-
+-/*
+ * Following four functions update i_blocks+i_bytes fields and
+ * quota information (together with appropriate checks)
+ * NOTE: We absolutely rely on the fact that caller dirties
+@@ -1469,21 +1405,6 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
+ int cnt, ret = QUOTA_OK;
+ char warntype[MAXQUOTAS];
+
+- /*
+- * First test before acquiring mutex - solves deadlocks when we
+- * re-enter the quota code and are already holding the mutex
+- */
+- if (IS_NOQUOTA(inode)) {
+- inode_incr_space(inode, number, reserve);
+- goto out;
+- }
+-
+- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+- if (IS_NOQUOTA(inode)) {
+- inode_incr_space(inode, number, reserve);
+- goto out_unlock;
+- }
+-
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+ warntype[cnt] = QUOTA_NL_NOWARN;
+
+@@ -1494,8 +1415,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
+ if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt)
+ == NO_QUOTA) {
+ ret = NO_QUOTA;
+- spin_unlock(&dq_data_lock);
+- goto out_flush_warn;
++ goto out_unlock;
+ }
+ }
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+@@ -1506,32 +1426,64 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
+ else
+ dquot_incr_space(inode->i_dquot[cnt], number);
+ }
+- inode_incr_space(inode, number, reserve);
++ if (!reserve)
++ inode_add_bytes(inode, number);
++out_unlock:
+ spin_unlock(&dq_data_lock);
++ flush_warnings(inode->i_dquot, warntype);
++ return ret;
++}
++
++int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
++{
++ int cnt, ret = QUOTA_OK;
++
++ /*
++ * First test before acquiring mutex - solves deadlocks when we
++ * re-enter the quota code and are already holding the mutex
++ */
++ if (IS_NOQUOTA(inode)) {
++ inode_add_bytes(inode, number);
++ goto out;
++ }
++
++ down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
++ if (IS_NOQUOTA(inode)) {
++ inode_add_bytes(inode, number);
++ goto out_unlock;
++ }
++
++ ret = __dquot_alloc_space(inode, number, warn, 0);
++ if (ret == NO_QUOTA)
++ goto out_unlock;
+
+- if (reserve)
+- goto out_flush_warn;
+ /* Dirtify all the dquots - this can block when journalling */
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+ if (inode->i_dquot[cnt])
+ mark_dquot_dirty(inode->i_dquot[cnt]);
+-out_flush_warn:
+- flush_warnings(inode->i_dquot, warntype);
+ out_unlock:
+ up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+ out:
+ return ret;
+ }
+-
+-int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
+-{
+- return __dquot_alloc_space(inode, number, warn, 0);
+-}
+ EXPORT_SYMBOL(dquot_alloc_space);
+
+ int dquot_reserve_space(struct inode *inode, qsize_t number, int warn)
+ {
+- return __dquot_alloc_space(inode, number, warn, 1);
++ int ret = QUOTA_OK;
++
++ if (IS_NOQUOTA(inode))
++ goto out;
++
++ down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
++ if (IS_NOQUOTA(inode))
++ goto out_unlock;
++
++ ret = __dquot_alloc_space(inode, number, warn, 1);
++out_unlock:
++ up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
++out:
++ return ret;
+ }
+ EXPORT_SYMBOL(dquot_reserve_space);
+
+@@ -1588,14 +1540,14 @@ int dquot_claim_space(struct inode *inode, qsize_t number)
+ int ret = QUOTA_OK;
+
+ if (IS_NOQUOTA(inode)) {
+- inode_claim_rsv_space(inode, number);
++ inode_add_bytes(inode, number);
+ goto out;
+ }
+
+ down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+ if (IS_NOQUOTA(inode)) {
+ up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+- inode_claim_rsv_space(inode, number);
++ inode_add_bytes(inode, number);
+ goto out;
+ }
+
+@@ -1607,7 +1559,7 @@ int dquot_claim_space(struct inode *inode, qsize_t number)
+ number);
+ }
+ /* Update inode bytes */
+- inode_claim_rsv_space(inode, number);
++ inode_add_bytes(inode, number);
+ spin_unlock(&dq_data_lock);
+ /* Dirtify all the dquots - this can block when journalling */
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+@@ -1620,9 +1572,38 @@ out:
+ EXPORT_SYMBOL(dquot_claim_space);
+
+ /*
++ * Release reserved quota space
++ */
++void dquot_release_reserved_space(struct inode *inode, qsize_t number)
++{
++ int cnt;
++
++ if (IS_NOQUOTA(inode))
++ goto out;
++
++ down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
++ if (IS_NOQUOTA(inode))
++ goto out_unlock;
++
++ spin_lock(&dq_data_lock);
++ /* Release reserved dquots */
++ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
++ if (inode->i_dquot[cnt])
++ dquot_free_reserved_space(inode->i_dquot[cnt], number);
++ }
++ spin_unlock(&dq_data_lock);
++
++out_unlock:
++ up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
++out:
++ return;
++}
++EXPORT_SYMBOL(dquot_release_reserved_space);
++
++/*
+ * This operation can block, but only after everything is updated
+ */
+-int __dquot_free_space(struct inode *inode, qsize_t number, int reserve)
++int dquot_free_space(struct inode *inode, qsize_t number)
+ {
+ unsigned int cnt;
+ char warntype[MAXQUOTAS];
+@@ -1631,7 +1612,7 @@ int __dquot_free_space(struct inode *inode, qsize_t number, int reserve)
+ * re-enter the quota code and are already holding the mutex */
+ if (IS_NOQUOTA(inode)) {
+ out_sub:
+- inode_decr_space(inode, number, reserve);
++ inode_sub_bytes(inode, number);
+ return QUOTA_OK;
+ }
+
+@@ -1646,43 +1627,21 @@ out_sub:
+ if (!inode->i_dquot[cnt])
+ continue;
+ warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number);
+- if (reserve)
+- dquot_free_reserved_space(inode->i_dquot[cnt], number);
+- else
+- dquot_decr_space(inode->i_dquot[cnt], number);
++ dquot_decr_space(inode->i_dquot[cnt], number);
+ }
+- inode_decr_space(inode, number, reserve);
++ inode_sub_bytes(inode, number);
+ spin_unlock(&dq_data_lock);
+-
+- if (reserve)
+- goto out_unlock;
+ /* Dirtify all the dquots - this can block when journalling */
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+ if (inode->i_dquot[cnt])
+ mark_dquot_dirty(inode->i_dquot[cnt]);
+-out_unlock:
+ flush_warnings(inode->i_dquot, warntype);
+ up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+ return QUOTA_OK;
+ }
+-
+-int dquot_free_space(struct inode *inode, qsize_t number)
+-{
+- return __dquot_free_space(inode, number, 0);
+-}
+ EXPORT_SYMBOL(dquot_free_space);
+
+ /*
+- * Release reserved quota space
+- */
+-void dquot_release_reserved_space(struct inode *inode, qsize_t number)
+-{
+- __dquot_free_space(inode, number, 1);
+-
+-}
+-EXPORT_SYMBOL(dquot_release_reserved_space);
+-
+-/*
+ * This operation can block, but only after everything is updated
+ */
+ int dquot_free_inode(const struct inode *inode, qsize_t number)
+@@ -1720,6 +1679,19 @@ int dquot_free_inode(const struct inode *inode, qsize_t number)
+ EXPORT_SYMBOL(dquot_free_inode);
+
+ /*
++ * call back function, get reserved quota space from underlying fs
++ */
++qsize_t dquot_get_reserved_space(struct inode *inode)
++{
++ qsize_t reserved_space = 0;
++
++ if (sb_any_quota_active(inode->i_sb) &&
++ inode->i_sb->dq_op->get_reserved_space)
++ reserved_space = inode->i_sb->dq_op->get_reserved_space(inode);
++ return reserved_space;
++}
++
++/*
+ * Transfer the number of inode and blocks from one diskquota to an other.
+ *
+ * This operation can block, but only after everything is updated
+@@ -1762,7 +1734,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
+ }
+ spin_lock(&dq_data_lock);
+ cur_space = inode_get_bytes(inode);
+- rsv_space = inode_get_rsv_space(inode);
++ rsv_space = dquot_get_reserved_space(inode);
+ space = cur_space + rsv_space;
+ /* Build the transfer_from list and check the limits */
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
+index d240c15..a14d6cd 100644
+--- a/fs/reiserfs/inode.c
++++ b/fs/reiserfs/inode.c
+@@ -2531,12 +2531,6 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
+ return reiserfs_write_full_page(page, wbc);
+ }
+
+-static void reiserfs_truncate_failed_write(struct inode *inode)
+-{
+- truncate_inode_pages(inode->i_mapping, inode->i_size);
+- reiserfs_truncate_file(inode, 0);
+-}
+-
+ static int reiserfs_write_begin(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+@@ -2603,8 +2597,6 @@ static int reiserfs_write_begin(struct file *file,
+ if (ret) {
+ unlock_page(page);
+ page_cache_release(page);
+- /* Truncate allocated blocks */
+- reiserfs_truncate_failed_write(inode);
+ }
+ return ret;
+ }
+@@ -2697,7 +2689,8 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
+ ** transaction tracking stuff when the size changes. So, we have
+ ** to do the i_size updates here.
+ */
+- if (pos + copied > inode->i_size) {
++ pos += copied;
++ if (pos > inode->i_size) {
+ struct reiserfs_transaction_handle myth;
+ reiserfs_write_lock(inode->i_sb);
+ /* If the file have grown beyond the border where it
+@@ -2715,7 +2708,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
+ goto journal_error;
+ }
+ reiserfs_update_inode_transaction(inode);
+- inode->i_size = pos + copied;
++ inode->i_size = pos;
+ /*
+ * this will just nest into our transaction. It's important
+ * to use mark_inode_dirty so the inode gets pushed around on the
+@@ -2742,10 +2735,6 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
+ out:
+ unlock_page(page);
+ page_cache_release(page);
+-
+- if (pos + len > inode->i_size)
+- reiserfs_truncate_failed_write(inode);
+-
+ return ret == 0 ? copied : ret;
+
+ journal_error:
+diff --git a/fs/romfs/super.c b/fs/romfs/super.c
+index 42d2135..c117fa8 100644
+--- a/fs/romfs/super.c
++++ b/fs/romfs/super.c
+@@ -544,7 +544,6 @@ error:
+ error_rsb_inval:
+ ret = -EINVAL;
+ error_rsb:
+- kfree(rsb);
+ return ret;
+ }
+
+diff --git a/fs/stat.c b/fs/stat.c
+index c4ecd52..075694e 100644
+--- a/fs/stat.c
++++ b/fs/stat.c
+@@ -401,9 +401,9 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, char __user *, filename,
+ }
+ #endif /* __ARCH_WANT_STAT64 */
+
+-/* Caller is here responsible for sufficient locking (ie. inode->i_lock) */
+-void __inode_add_bytes(struct inode *inode, loff_t bytes)
++void inode_add_bytes(struct inode *inode, loff_t bytes)
+ {
++ spin_lock(&inode->i_lock);
+ inode->i_blocks += bytes >> 9;
+ bytes &= 511;
+ inode->i_bytes += bytes;
+@@ -411,12 +411,6 @@ void __inode_add_bytes(struct inode *inode, loff_t bytes)
+ inode->i_blocks++;
+ inode->i_bytes -= 512;
+ }
+-}
+-
+-void inode_add_bytes(struct inode *inode, loff_t bytes)
+-{
+- spin_lock(&inode->i_lock);
+- __inode_add_bytes(inode, bytes);
+ spin_unlock(&inode->i_lock);
+ }
+
+diff --git a/fs/super.c b/fs/super.c
+index aff046b..19eb70b 100644
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -901,9 +901,8 @@ int get_sb_single(struct file_system_type *fs_type,
+ return error;
+ }
+ s->s_flags |= MS_ACTIVE;
+- } else {
+- do_remount_sb(s, flags, data, 0);
+ }
++ do_remount_sb(s, flags, data, 0);
+ simple_set_mnt(mnt, s);
+ return 0;
+ }
+diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
+index 02a022a..e28cecf 100644
+--- a/fs/sysfs/inode.c
++++ b/fs/sysfs/inode.c
+@@ -94,29 +94,30 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
+ if (!sd_attrs)
+ return -ENOMEM;
+ sd->s_iattr = sd_attrs;
+- }
+- /* attributes were changed at least once in past */
+- iattrs = &sd_attrs->ia_iattr;
+-
+- if (ia_valid & ATTR_UID)
+- iattrs->ia_uid = iattr->ia_uid;
+- if (ia_valid & ATTR_GID)
+- iattrs->ia_gid = iattr->ia_gid;
+- if (ia_valid & ATTR_ATIME)
+- iattrs->ia_atime = timespec_trunc(iattr->ia_atime,
+- inode->i_sb->s_time_gran);
+- if (ia_valid & ATTR_MTIME)
+- iattrs->ia_mtime = timespec_trunc(iattr->ia_mtime,
+- inode->i_sb->s_time_gran);
+- if (ia_valid & ATTR_CTIME)
+- iattrs->ia_ctime = timespec_trunc(iattr->ia_ctime,
+- inode->i_sb->s_time_gran);
+- if (ia_valid & ATTR_MODE) {
+- umode_t mode = iattr->ia_mode;
+-
+- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+- mode &= ~S_ISGID;
+- iattrs->ia_mode = sd->s_mode = mode;
++ } else {
++ /* attributes were changed at least once in past */
++ iattrs = &sd_attrs->ia_iattr;
++
++ if (ia_valid & ATTR_UID)
++ iattrs->ia_uid = iattr->ia_uid;
++ if (ia_valid & ATTR_GID)
++ iattrs->ia_gid = iattr->ia_gid;
++ if (ia_valid & ATTR_ATIME)
++ iattrs->ia_atime = timespec_trunc(iattr->ia_atime,
++ inode->i_sb->s_time_gran);
++ if (ia_valid & ATTR_MTIME)
++ iattrs->ia_mtime = timespec_trunc(iattr->ia_mtime,
++ inode->i_sb->s_time_gran);
++ if (ia_valid & ATTR_CTIME)
++ iattrs->ia_ctime = timespec_trunc(iattr->ia_ctime,
++ inode->i_sb->s_time_gran);
++ if (ia_valid & ATTR_MODE) {
++ umode_t mode = iattr->ia_mode;
++
++ if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
++ mode &= ~S_ISGID;
++ iattrs->ia_mode = sd->s_mode = mode;
++ }
+ }
+ return error;
+ }
+diff --git a/fs/udf/super.c b/fs/udf/super.c
+index 1e4543c..9d1b8c2 100644
+--- a/fs/udf/super.c
++++ b/fs/udf/super.c
+@@ -1078,39 +1078,21 @@ static int udf_fill_partdesc_info(struct super_block *sb,
+ return 0;
+ }
+
+-static void udf_find_vat_block(struct super_block *sb, int p_index,
+- int type1_index, sector_t start_block)
+-{
+- struct udf_sb_info *sbi = UDF_SB(sb);
+- struct udf_part_map *map = &sbi->s_partmaps[p_index];
+- sector_t vat_block;
+- struct kernel_lb_addr ino;
+-
+- /*
+- * VAT file entry is in the last recorded block. Some broken disks have
+- * it a few blocks before so try a bit harder...
+- */
+- ino.partitionReferenceNum = type1_index;
+- for (vat_block = start_block;
+- vat_block >= map->s_partition_root &&
+- vat_block >= start_block - 3 &&
+- !sbi->s_vat_inode; vat_block--) {
+- ino.logicalBlockNum = vat_block - map->s_partition_root;
+- sbi->s_vat_inode = udf_iget(sb, &ino);
+- }
+-}
+-
+ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
+ {
+ struct udf_sb_info *sbi = UDF_SB(sb);
+ struct udf_part_map *map = &sbi->s_partmaps[p_index];
++ struct kernel_lb_addr ino;
+ struct buffer_head *bh = NULL;
+ struct udf_inode_info *vati;
+ uint32_t pos;
+ struct virtualAllocationTable20 *vat20;
+ sector_t blocks = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits;
+
+- udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block);
++ /* VAT file entry is in the last recorded block */
++ ino.partitionReferenceNum = type1_index;
++ ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root;
++ sbi->s_vat_inode = udf_iget(sb, &ino);
+ if (!sbi->s_vat_inode &&
+ sbi->s_last_block != blocks - 1) {
+ printk(KERN_NOTICE "UDF-fs: Failed to read VAT inode from the"
+@@ -1118,7 +1100,9 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
+ "block of the device (%lu).\n",
+ (unsigned long)sbi->s_last_block,
+ (unsigned long)blocks - 1);
+- udf_find_vat_block(sb, p_index, type1_index, blocks - 1);
++ ino.partitionReferenceNum = type1_index;
++ ino.logicalBlockNum = blocks - 1 - map->s_partition_root;
++ sbi->s_vat_inode = udf_iget(sb, &ino);
+ }
+ if (!sbi->s_vat_inode)
+ return 1;
+diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
+index 0946997..9d7febd 100644
+--- a/include/acpi/platform/aclinux.h
++++ b/include/acpi/platform/aclinux.h
+@@ -152,7 +152,7 @@ static inline void *acpi_os_acquire_object(acpi_cache_t * cache)
+ #include <linux/hardirq.h>
+ #define ACPI_PREEMPTION_POINT() \
+ do { \
+- if (!in_atomic_preempt_off() && !irqs_disabled()) \
++ if (!in_atomic_preempt_off()) \
+ cond_resched(); \
+ } while (0)
+
+diff --git a/include/drm/drmP.h b/include/drm/drmP.h
+index 7ad3faa..c8e64bb 100644
+--- a/include/drm/drmP.h
++++ b/include/drm/drmP.h
+@@ -1295,7 +1295,6 @@ extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
+ extern void drm_handle_vblank(struct drm_device *dev, int crtc);
+ extern int drm_vblank_get(struct drm_device *dev, int crtc);
+ extern void drm_vblank_put(struct drm_device *dev, int crtc);
+-extern void drm_vblank_off(struct drm_device *dev, int crtc);
+ extern void drm_vblank_cleanup(struct drm_device *dev);
+ /* Modesetting support */
+ extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
+@@ -1402,7 +1401,7 @@ extern int drm_ati_pcigart_cleanup(struct drm_device *dev,
+ struct drm_ati_pcigart_info * gart_info);
+
+ extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size,
+- size_t align);
++ size_t align, dma_addr_t maxaddr);
+ extern void __drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah);
+ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah);
+
+diff --git a/include/drm/drm_os_linux.h b/include/drm/drm_os_linux.h
+index 3933691..26641e9 100644
+--- a/include/drm/drm_os_linux.h
++++ b/include/drm/drm_os_linux.h
+@@ -123,5 +123,5 @@ do { \
+ remove_wait_queue(&(queue), &entry); \
+ } while (0)
+
+-#define DRM_WAKEUP( queue ) wake_up( queue )
++#define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
+ #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
+diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
+index b199170..6983a7c 100644
+--- a/include/drm/ttm/ttm_memory.h
++++ b/include/drm/ttm/ttm_memory.h
+@@ -33,7 +33,6 @@
+ #include <linux/wait.h>
+ #include <linux/errno.h>
+ #include <linux/kobject.h>
+-#include <linux/mm.h>
+
+ /**
+ * struct ttm_mem_shrink - callback to shrink TTM memory usage.
+diff --git a/include/linux/acpi.h b/include/linux/acpi.h
+index c010b94..dfcd920 100644
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -253,13 +253,6 @@ void __init acpi_old_suspend_ordering(void);
+ void __init acpi_s4_no_nvs(void);
+ #endif /* CONFIG_PM_SLEEP */
+
+-struct acpi_osc_context {
+- char *uuid_str; /* uuid string */
+- int rev;
+- struct acpi_buffer cap; /* arg2/arg3 */
+- struct acpi_buffer ret; /* free by caller if success */
+-};
+-
+ #define OSC_QUERY_TYPE 0
+ #define OSC_SUPPORT_TYPE 1
+ #define OSC_CONTROL_TYPE 2
+@@ -272,15 +265,6 @@ struct acpi_osc_context {
+ #define OSC_INVALID_REVISION_ERROR 8
+ #define OSC_CAPABILITIES_MASK_ERROR 16
+
+-acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
+-
+-/* platform-wide _OSC bits */
+-#define OSC_SB_PAD_SUPPORT 1
+-#define OSC_SB_PPC_OST_SUPPORT 2
+-#define OSC_SB_PR3_SUPPORT 4
+-#define OSC_SB_CPUHP_OST_SUPPORT 8
+-#define OSC_SB_APEI_SUPPORT 16
+-
+ /* _OSC DW1 Definition (OS Support Fields) */
+ #define OSC_EXT_PCI_CONFIG_SUPPORT 1
+ #define OSC_ACTIVE_STATE_PWR_SUPPORT 2
+diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
+index 340f441..aece486 100644
+--- a/include/linux/binfmts.h
++++ b/include/linux/binfmts.h
+@@ -101,7 +101,6 @@ extern int prepare_binprm(struct linux_binprm *);
+ extern int __must_check remove_arg_zero(struct linux_binprm *);
+ extern int search_binary_handler(struct linux_binprm *,struct pt_regs *);
+ extern int flush_old_exec(struct linux_binprm * bprm);
+-extern void setup_new_exec(struct linux_binprm * bprm);
+
+ extern int suid_dumpable;
+ #define SUID_DUMP_DISABLE 0 /* No setuid dumping */
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 912b8ff..221cecd 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -942,8 +942,6 @@ extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt);
+ extern void blk_set_default_limits(struct queue_limits *lim);
+ extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ sector_t offset);
+-extern int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev,
+- sector_t offset);
+ extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
+ sector_t offset);
+ extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b);
+@@ -1116,18 +1114,11 @@ static inline int queue_alignment_offset(struct request_queue *q)
+ return q->limits.alignment_offset;
+ }
+
+-static inline int queue_limit_alignment_offset(struct queue_limits *lim, sector_t offset)
+-{
+- unsigned int granularity = max(lim->physical_block_size, lim->io_min);
+-
+- offset &= granularity - 1;
+- return (granularity + lim->alignment_offset - offset) & (granularity - 1);
+-}
+-
+ static inline int queue_sector_alignment_offset(struct request_queue *q,
+ sector_t sector)
+ {
+- return queue_limit_alignment_offset(&q->limits, sector << 9);
++ return ((sector << 9) - q->limits.alignment_offset)
++ & (q->limits.io_min - 1);
+ }
+
+ static inline int bdev_alignment_offset(struct block_device *bdev)
+diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
+index 64b1a4c..83d2fbd 100644
+--- a/include/linux/clocksource.h
++++ b/include/linux/clocksource.h
+@@ -151,7 +151,6 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
+ * subtraction of non 64 bit counters
+ * @mult: cycle to nanosecond multiplier
+ * @shift: cycle to nanosecond divisor (power of two)
+- * @max_idle_ns: max idle time permitted by the clocksource (nsecs)
+ * @flags: flags describing special properties
+ * @vread: vsyscall based read
+ * @resume: resume function for the clocksource, if necessary
+@@ -169,7 +168,6 @@ struct clocksource {
+ cycle_t mask;
+ u32 mult;
+ u32 shift;
+- u64 max_idle_ns;
+ unsigned long flags;
+ cycle_t (*vread)(void);
+ void (*resume)(void);
+diff --git a/include/linux/connector.h b/include/linux/connector.h
+index ecb61c4..3a14615 100644
+--- a/include/linux/connector.h
++++ b/include/linux/connector.h
+@@ -24,6 +24,9 @@
+
+ #include <linux/types.h>
+
++#define CN_IDX_CONNECTOR 0xffffffff
++#define CN_VAL_CONNECTOR 0xffffffff
++
+ /*
+ * Process Events connector unique ids -- used for message routing
+ */
+@@ -70,6 +73,30 @@ struct cn_msg {
+ __u8 data[0];
+ };
+
++/*
++ * Notify structure - requests notification about
++ * registering/unregistering idx/val in range [first, first+range].
++ */
++struct cn_notify_req {
++ __u32 first;
++ __u32 range;
++};
++
++/*
++ * Main notification control message
++ * *_notify_num - number of appropriate cn_notify_req structures after
++ * this struct.
++ * group - notification receiver's idx.
++ * len - total length of the attached data.
++ */
++struct cn_ctl_msg {
++ __u32 idx_notify_num;
++ __u32 val_notify_num;
++ __u32 group;
++ __u32 len;
++ __u8 data[0];
++};
++
+ #ifdef __KERNEL__
+
+ #include <asm/atomic.h>
+@@ -122,6 +149,11 @@ struct cn_callback_entry {
+ u32 seq, group;
+ };
+
++struct cn_ctl_entry {
++ struct list_head notify_entry;
++ struct cn_ctl_msg *msg;
++};
++
+ struct cn_dev {
+ struct cb_id id;
+
+diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
+index d77b547..789cf5f 100644
+--- a/include/linux/cpumask.h
++++ b/include/linux/cpumask.h
+@@ -84,7 +84,6 @@ extern const struct cpumask *const cpu_active_mask;
+ #define num_online_cpus() cpumask_weight(cpu_online_mask)
+ #define num_possible_cpus() cpumask_weight(cpu_possible_mask)
+ #define num_present_cpus() cpumask_weight(cpu_present_mask)
+-#define num_active_cpus() cpumask_weight(cpu_active_mask)
+ #define cpu_online(cpu) cpumask_test_cpu((cpu), cpu_online_mask)
+ #define cpu_possible(cpu) cpumask_test_cpu((cpu), cpu_possible_mask)
+ #define cpu_present(cpu) cpumask_test_cpu((cpu), cpu_present_mask)
+@@ -93,7 +92,6 @@ extern const struct cpumask *const cpu_active_mask;
+ #define num_online_cpus() 1
+ #define num_possible_cpus() 1
+ #define num_present_cpus() 1
+-#define num_active_cpus() 1
+ #define cpu_online(cpu) ((cpu) == 0)
+ #define cpu_possible(cpu) ((cpu) == 0)
+ #define cpu_present(cpu) ((cpu) == 0)
+diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
+index 9a33c5f..90d1c21 100644
+--- a/include/linux/enclosure.h
++++ b/include/linux/enclosure.h
+@@ -42,8 +42,6 @@ enum enclosure_status {
+ ENCLOSURE_STATUS_NOT_INSTALLED,
+ ENCLOSURE_STATUS_UNKNOWN,
+ ENCLOSURE_STATUS_UNAVAILABLE,
+- /* last element for counting purposes */
+- ENCLOSURE_STATUS_MAX
+ };
+
+ /* SFF-8485 activity light settings */
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 98ea200..2620a8c 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2314,7 +2314,6 @@ extern const struct inode_operations page_symlink_inode_operations;
+ extern int generic_readlink(struct dentry *, char __user *, int);
+ extern void generic_fillattr(struct inode *, struct kstat *);
+ extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+-void __inode_add_bytes(struct inode *inode, loff_t bytes);
+ void inode_add_bytes(struct inode *inode, loff_t bytes);
+ void inode_sub_bytes(struct inode *inode, loff_t bytes);
+ loff_t inode_get_bytes(struct inode *inode);
+diff --git a/include/linux/hid.h b/include/linux/hid.h
+index 8709365..10f6284 100644
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -312,7 +312,6 @@ struct hid_item {
+ #define HID_QUIRK_MULTI_INPUT 0x00000040
+ #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
+ #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
+-#define HID_QUIRK_NO_INIT_REPORTS 0x20000000
+
+ /*
+ * This is the global environment of the parser. This information is
+diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
+index 9bace4b..ff037f0 100644
+--- a/include/linux/hrtimer.h
++++ b/include/linux/hrtimer.h
+@@ -446,7 +446,7 @@ extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
+
+ static inline void timer_stats_account_hrtimer(struct hrtimer *timer)
+ {
+- if (likely(!timer_stats_active))
++ if (likely(!timer->start_site))
+ return;
+ timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
+ timer->function, timer->start_comm, 0);
+@@ -457,6 +457,8 @@ extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer,
+
+ static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
+ {
++ if (likely(!timer_stats_active))
++ return;
+ __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0));
+ }
+
+diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
+index 9cd0bcf..ad27c7d 100644
+--- a/include/linux/inetdevice.h
++++ b/include/linux/inetdevice.h
+@@ -83,7 +83,6 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
+ #define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
+ #define IN_DEV_MFORWARD(in_dev) IN_DEV_ANDCONF((in_dev), MC_FORWARDING)
+ #define IN_DEV_RPFILTER(in_dev) IN_DEV_MAXCONF((in_dev), RP_FILTER)
+-#define IN_DEV_SRC_VMARK(in_dev) IN_DEV_ORCONF((in_dev), SRC_VMARK)
+ #define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \
+ ACCEPT_SOURCE_ROUTE)
+ #define IN_DEV_BOOTP_RELAY(in_dev) IN_DEV_ANDCONF((in_dev), BOOTP_RELAY)
+diff --git a/include/linux/kvm.h b/include/linux/kvm.h
+index 0eadd71..f8f8900 100644
+--- a/include/linux/kvm.h
++++ b/include/linux/kvm.h
+@@ -116,11 +116,6 @@ struct kvm_run {
+ __u64 cr8;
+ __u64 apic_base;
+
+-#ifdef __KVM_S390
+- /* the processor status word for s390 */
+- __u64 psw_mask; /* psw upper half */
+- __u64 psw_addr; /* psw lower half */
+-#endif
+ union {
+ /* KVM_EXIT_UNKNOWN */
+ struct {
+@@ -172,6 +167,8 @@ struct kvm_run {
+ /* KVM_EXIT_S390_SIEIC */
+ struct {
+ __u8 icptcode;
++ __u64 mask; /* psw upper half */
++ __u64 addr; /* psw lower half */
+ __u16 ipa;
+ __u32 ipb;
+ } s390_sieic;
+@@ -439,7 +436,6 @@ struct kvm_ioeventfd {
+ #endif
+ #define KVM_CAP_IOEVENTFD 36
+ #define KVM_CAP_SET_IDENTITY_MAP_ADDR 37
+-#define KVM_CAP_ADJUST_CLOCK 39
+
+ #ifdef KVM_CAP_IRQ_ROUTING
+
+@@ -478,7 +474,6 @@ struct kvm_irq_routing {
+ };
+
+ #endif
+-#define KVM_CAP_S390_PSW 42
+
+ #ifdef KVM_CAP_MCE
+ /* x86 MCE */
+@@ -502,12 +497,6 @@ struct kvm_irqfd {
+ __u8 pad[20];
+ };
+
+-struct kvm_clock_data {
+- __u64 clock;
+- __u32 flags;
+- __u32 pad[9];
+-};
+-
+ /*
+ * ioctls for VM fds
+ */
+@@ -557,8 +546,6 @@ struct kvm_clock_data {
+ #define KVM_CREATE_PIT2 _IOW(KVMIO, 0x77, struct kvm_pit_config)
+ #define KVM_SET_BOOT_CPU_ID _IO(KVMIO, 0x78)
+ #define KVM_IOEVENTFD _IOW(KVMIO, 0x79, struct kvm_ioeventfd)
+-#define KVM_SET_CLOCK _IOW(KVMIO, 0x7b, struct kvm_clock_data)
+-#define KVM_GET_CLOCK _IOR(KVMIO, 0x7c, struct kvm_clock_data)
+
+ /*
+ * ioctls for vcpu fds
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index b0f6d97..8769864 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -354,9 +354,6 @@ enum {
+ /* max tries if error condition is still set after ->error_handler */
+ ATA_EH_MAX_TRIES = 5,
+
+- /* sometimes resuming a link requires several retries */
+- ATA_LINK_RESUME_TRIES = 5,
+-
+ /* how hard are we gonna try to probe/recover devices */
+ ATA_PROBE_MAX_TRIES = 3,
+ ATA_EH_DEV_TRIES = 3,
+diff --git a/include/linux/mfd/wm8350/pmic.h b/include/linux/mfd/wm8350/pmic.h
+index e786fe9..be3264e 100644
+--- a/include/linux/mfd/wm8350/pmic.h
++++ b/include/linux/mfd/wm8350/pmic.h
+@@ -666,20 +666,20 @@
+ #define WM8350_ISINK_FLASH_DUR_64MS (1 << 8)
+ #define WM8350_ISINK_FLASH_DUR_96MS (2 << 8)
+ #define WM8350_ISINK_FLASH_DUR_1024MS (3 << 8)
+-#define WM8350_ISINK_FLASH_ON_INSTANT (0 << 0)
+-#define WM8350_ISINK_FLASH_ON_0_25S (1 << 0)
+-#define WM8350_ISINK_FLASH_ON_0_50S (2 << 0)
+-#define WM8350_ISINK_FLASH_ON_1_00S (3 << 0)
+-#define WM8350_ISINK_FLASH_ON_1_95S (1 << 0)
+-#define WM8350_ISINK_FLASH_ON_3_91S (2 << 0)
+-#define WM8350_ISINK_FLASH_ON_7_80S (3 << 0)
+-#define WM8350_ISINK_FLASH_OFF_INSTANT (0 << 4)
+-#define WM8350_ISINK_FLASH_OFF_0_25S (1 << 4)
+-#define WM8350_ISINK_FLASH_OFF_0_50S (2 << 4)
+-#define WM8350_ISINK_FLASH_OFF_1_00S (3 << 4)
+-#define WM8350_ISINK_FLASH_OFF_1_95S (1 << 4)
+-#define WM8350_ISINK_FLASH_OFF_3_91S (2 << 4)
+-#define WM8350_ISINK_FLASH_OFF_7_80S (3 << 4)
++#define WM8350_ISINK_FLASH_ON_INSTANT (0 << 4)
++#define WM8350_ISINK_FLASH_ON_0_25S (1 << 4)
++#define WM8350_ISINK_FLASH_ON_0_50S (2 << 4)
++#define WM8350_ISINK_FLASH_ON_1_00S (3 << 4)
++#define WM8350_ISINK_FLASH_ON_1_95S (1 << 4)
++#define WM8350_ISINK_FLASH_ON_3_91S (2 << 4)
++#define WM8350_ISINK_FLASH_ON_7_80S (3 << 4)
++#define WM8350_ISINK_FLASH_OFF_INSTANT (0 << 0)
++#define WM8350_ISINK_FLASH_OFF_0_25S (1 << 0)
++#define WM8350_ISINK_FLASH_OFF_0_50S (2 << 0)
++#define WM8350_ISINK_FLASH_OFF_1_00S (3 << 0)
++#define WM8350_ISINK_FLASH_OFF_1_95S (1 << 0)
++#define WM8350_ISINK_FLASH_OFF_3_91S (2 << 0)
++#define WM8350_ISINK_FLASH_OFF_7_80S (3 << 0)
+
+ /*
+ * Regulator Interrupts.
+diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
+index 3c62ed4..ed5d750 100644
+--- a/include/linux/pagemap.h
++++ b/include/linux/pagemap.h
+@@ -253,8 +253,6 @@ extern struct page * read_cache_page_async(struct address_space *mapping,
+ extern struct page * read_cache_page(struct address_space *mapping,
+ pgoff_t index, filler_t *filler,
+ void *data);
+-extern struct page * read_cache_page_gfp(struct address_space *mapping,
+- pgoff_t index, gfp_t gfp_mask);
+ extern int read_cache_pages(struct address_space *mapping,
+ struct list_head *pages, filler_t *filler, void *data);
+
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 2547515..f5c7cd3 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -564,9 +564,6 @@ void pcibios_align_resource(void *, struct resource *, resource_size_t,
+ resource_size_t);
+ void pcibios_update_irq(struct pci_dev *, int irq);
+
+-/* Weak but can be overriden by arch */
+-void pci_fixup_cardbus(struct pci_bus *);
+-
+ /* Generic PCI functions used internally */
+
+ extern struct pci_bus *pci_find_bus(int domain, int busnr);
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+index 1b7f2a7..84cf1f3 100644
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -2290,20 +2290,6 @@
+ #define PCI_DEVICE_ID_MPC8536 0x0051
+ #define PCI_DEVICE_ID_P2020E 0x0070
+ #define PCI_DEVICE_ID_P2020 0x0071
+-#define PCI_DEVICE_ID_P2010E 0x0078
+-#define PCI_DEVICE_ID_P2010 0x0079
+-#define PCI_DEVICE_ID_P1020E 0x0100
+-#define PCI_DEVICE_ID_P1020 0x0101
+-#define PCI_DEVICE_ID_P1011E 0x0108
+-#define PCI_DEVICE_ID_P1011 0x0109
+-#define PCI_DEVICE_ID_P1022E 0x0110
+-#define PCI_DEVICE_ID_P1022 0x0111
+-#define PCI_DEVICE_ID_P1013E 0x0118
+-#define PCI_DEVICE_ID_P1013 0x0119
+-#define PCI_DEVICE_ID_P4080E 0x0400
+-#define PCI_DEVICE_ID_P4080 0x0401
+-#define PCI_DEVICE_ID_P4040E 0x0408
+-#define PCI_DEVICE_ID_P4040 0x0409
+ #define PCI_DEVICE_ID_MPC8641 0x7010
+ #define PCI_DEVICE_ID_MPC8641D 0x7011
+ #define PCI_DEVICE_ID_MPC8610 0x7018
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index 81c9689..9e70126 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -219,7 +219,7 @@ struct perf_event_attr {
+ #define PERF_EVENT_IOC_DISABLE _IO ('$', 1)
+ #define PERF_EVENT_IOC_REFRESH _IO ('$', 2)
+ #define PERF_EVENT_IOC_RESET _IO ('$', 3)
+-#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64)
++#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, u64)
+ #define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5)
+
+ enum perf_event_ioc_flags {
+diff --git a/include/linux/quota.h b/include/linux/quota.h
+index 8fd8efc..78c4889 100644
+--- a/include/linux/quota.h
++++ b/include/linux/quota.h
+@@ -313,9 +313,8 @@ struct dquot_operations {
+ int (*claim_space) (struct inode *, qsize_t);
+ /* release rsved quota for delayed alloc */
+ void (*release_rsv) (struct inode *, qsize_t);
+- /* get reserved quota for delayed alloc, value returned is managed by
+- * quota code only */
+- qsize_t *(*get_reserved_space) (struct inode *);
++ /* get reserved quota for delayed alloc */
++ qsize_t (*get_reserved_space) (struct inode *);
+ };
+
+ /* Operations handling requests from userspace */
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index e48311e..75e6e60 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -1354,7 +1354,7 @@ struct task_struct {
+ char comm[TASK_COMM_LEN]; /* executable name excluding path
+ - access with [gs]et_task_comm (which lock
+ it with task_lock())
+- - initialized normally by setup_new_exec */
++ - initialized normally by flush_old_exec */
+ /* file system info */
+ int link_count, total_link_count;
+ #ifdef CONFIG_SYSVIPC
+@@ -2086,18 +2086,11 @@ static inline int is_si_special(const struct siginfo *info)
+ return info <= SEND_SIG_FORCED;
+ }
+
+-/*
+- * True if we are on the alternate signal stack.
+- */
++/* True if we are on the alternate signal stack. */
++
+ static inline int on_sig_stack(unsigned long sp)
+ {
+-#ifdef CONFIG_STACK_GROWSUP
+- return sp >= current->sas_ss_sp &&
+- sp - current->sas_ss_sp < current->sas_ss_size;
+-#else
+- return sp > current->sas_ss_sp &&
+- sp - current->sas_ss_sp <= current->sas_ss_size;
+-#endif
++ return (sp - current->sas_ss_sp < current->sas_ss_size);
+ }
+
+ static inline int sas_ss_flags(unsigned long sp)
+@@ -2583,28 +2576,6 @@ static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
+
+ #define TASK_STATE_TO_CHAR_STR "RSDTtZX"
+
+-static inline unsigned long task_rlimit(const struct task_struct *tsk,
+- unsigned int limit)
+-{
+- return ACCESS_ONCE(tsk->signal->rlim[limit].rlim_cur);
+-}
+-
+-static inline unsigned long task_rlimit_max(const struct task_struct *tsk,
+- unsigned int limit)
+-{
+- return ACCESS_ONCE(tsk->signal->rlim[limit].rlim_max);
+-}
+-
+-static inline unsigned long rlimit(unsigned int limit)
+-{
+- return task_rlimit(current, limit);
+-}
+-
+-static inline unsigned long rlimit_max(unsigned int limit)
+-{
+- return task_rlimit_max(current, limit);
+-}
+-
+ #endif /* __KERNEL__ */
+
+ #endif
+diff --git a/include/linux/security.h b/include/linux/security.h
+index d40d23f..239e40d 100644
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -95,13 +95,8 @@ struct seq_file;
+ extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
+ extern int cap_netlink_recv(struct sk_buff *skb, int cap);
+
+-#ifdef CONFIG_MMU
+ extern unsigned long mmap_min_addr;
+ extern unsigned long dac_mmap_min_addr;
+-#else
+-#define dac_mmap_min_addr 0UL
+-#endif
+-
+ /*
+ * Values used in the task_security_ops calls
+ */
+@@ -126,7 +121,6 @@ struct request_sock;
+ #define LSM_UNSAFE_PTRACE 2
+ #define LSM_UNSAFE_PTRACE_CAP 4
+
+-#ifdef CONFIG_MMU
+ /*
+ * If a hint addr is less than mmap_min_addr change hint to be as
+ * low as possible but still greater than mmap_min_addr
+@@ -141,7 +135,6 @@ static inline unsigned long round_hint_to_min(unsigned long hint)
+ }
+ extern int mmap_min_addr_handler(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos);
+-#endif
+
+ #ifdef CONFIG_SECURITY
+
+diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
+index db532ce..ea910a3 100644
+--- a/include/linux/serial_core.h
++++ b/include/linux/serial_core.h
+@@ -179,6 +179,10 @@
+ /* BCM63xx family SoCs */
+ #define PORT_BCM63XX 89
+
++/* Toshiba TMPA9x0 SoC */
++#define PORT_TMPA910 90
++
++
+ #ifdef __KERNEL__
+
+ #include <linux/compiler.h>
+diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
+index 93515c6..a990ace 100644
+--- a/include/linux/syscalls.h
++++ b/include/linux/syscalls.h
+@@ -879,8 +879,4 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
+ asmlinkage long sys_perf_event_open(
+ struct perf_event_attr __user *attr_uptr,
+ pid_t pid, int cpu, int group_fd, unsigned long flags);
+-
+-asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len,
+- unsigned long prot, unsigned long flags,
+- unsigned long fd, unsigned long pgoff);
+ #endif
+diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
+index 0eb6942..1e4743e 100644
+--- a/include/linux/sysctl.h
++++ b/include/linux/sysctl.h
+@@ -490,7 +490,6 @@ enum
+ NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
+ NET_IPV4_CONF_ARP_ACCEPT=21,
+ NET_IPV4_CONF_ARP_NOTIFY=22,
+- NET_IPV4_CONF_SRC_VMARK=24,
+ __NET_IPV4_CONF_MAX
+ };
+
+diff --git a/include/linux/time.h b/include/linux/time.h
+index 6e026e4..fe04e5e 100644
+--- a/include/linux/time.h
++++ b/include/linux/time.h
+@@ -148,7 +148,6 @@ extern void monotonic_to_bootbased(struct timespec *ts);
+
+ extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
+ extern int timekeeping_valid_for_hres(void);
+-extern u64 timekeeping_max_deferment(void);
+ extern void update_wall_time(void);
+ extern void update_xtime_cache(u64 nsec);
+ extern void timekeeping_leap_insert(int leapsecond);
+diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h
+index a4b947e..3d15fb9 100644
+--- a/include/linux/usb_usual.h
++++ b/include/linux/usb_usual.h
+@@ -56,9 +56,7 @@
+ US_FLAG(SANE_SENSE, 0x00008000) \
+ /* Sane Sense (> 18 bytes) */ \
+ US_FLAG(CAPACITY_OK, 0x00010000) \
+- /* READ CAPACITY response is correct */ \
+- US_FLAG(BAD_SENSE, 0x00020000) \
+- /* Bad Sense (never more than 18 bytes) */
++ /* READ CAPACITY response is correct */
+
+ #define US_FLAG(name, value) US_FL_##name = value ,
+ enum { US_DO_ALL_FLAGS };
+diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
+index 3c123c3..227c2a5 100644
+--- a/include/linux/vmalloc.h
++++ b/include/linux/vmalloc.h
+@@ -115,11 +115,9 @@ extern rwlock_t vmlist_lock;
+ extern struct vm_struct *vmlist;
+ extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
+
+-#ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA
+ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
+ const size_t *sizes, int nr_vms,
+ size_t align, gfp_t gfp_mask);
+-#endif
+
+ void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms);
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 69db943..2f47e54 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -342,7 +342,6 @@ enum ip_defrag_users
+ IP_DEFRAG_CALL_RA_CHAIN,
+ IP_DEFRAG_CONNTRACK_IN,
+ IP_DEFRAG_CONNTRACK_OUT,
+- IP_DEFRAG_CONNTRACK_BRIDGE_IN,
+ IP_DEFRAG_VS_IN,
+ IP_DEFRAG_VS_OUT,
+ IP_DEFRAG_VS_FWD
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index 639bbf0..8c31d8a 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -354,16 +354,8 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1,
+
+ struct inet_frag_queue;
+
+-enum ip6_defrag_users {
+- IP6_DEFRAG_LOCAL_DELIVER,
+- IP6_DEFRAG_CONNTRACK_IN,
+- IP6_DEFRAG_CONNTRACK_OUT,
+- IP6_DEFRAG_CONNTRACK_BRIDGE_IN,
+-};
+-
+ struct ip6_create_arg {
+ __be32 id;
+- u32 user;
+ struct in6_addr *src;
+ struct in6_addr *dst;
+ };
+diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+index 1ee717e..abc55ad 100644
+--- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
++++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+@@ -9,7 +9,7 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
+
+ extern int nf_ct_frag6_init(void);
+ extern void nf_ct_frag6_cleanup(void);
+-extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
++extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb);
+ extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
+ struct net_device *in,
+ struct net_device *out,
+diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
+index 63d4498..ba1ba0c 100644
+--- a/include/net/netns/conntrack.h
++++ b/include/net/netns/conntrack.h
+@@ -11,8 +11,6 @@ struct nf_conntrack_ecache;
+ struct netns_ct {
+ atomic_t count;
+ unsigned int expect_count;
+- unsigned int htable_size;
+- struct kmem_cache *nf_conntrack_cachep;
+ struct hlist_nulls_head *hash;
+ struct hlist_head *expect_hash;
+ struct hlist_nulls_head unconfirmed;
+@@ -30,6 +28,5 @@ struct netns_ct {
+ #endif
+ int hash_vmalloc;
+ int expect_vmalloc;
+- char *slabname;
+ };
+ #endif
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 9a4b8b7..2eb3814 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -40,7 +40,6 @@ struct netns_ipv4 {
+ struct xt_table *iptable_security;
+ struct xt_table *nat_table;
+ struct hlist_head *nat_bysource;
+- unsigned int nat_htable_size;
+ int nat_vmalloced;
+ #endif
+
+diff --git a/include/net/netrom.h b/include/net/netrom.h
+index ab170a6..15696b1 100644
+--- a/include/net/netrom.h
++++ b/include/net/netrom.h
+@@ -132,8 +132,6 @@ static __inline__ void nr_node_put(struct nr_node *nr_node)
+ static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh)
+ {
+ if (atomic_dec_and_test(&nr_neigh->refcount)) {
+- if (nr_neigh->ax25)
+- ax25_cb_put(nr_neigh->ax25);
+ kfree(nr_neigh->digipeat);
+ kfree(nr_neigh);
+ }
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 842ac4d..03a49c7 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1263,20 +1263,14 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu
+ * TCP connection after "boundary" unsucessful, exponentially backed-off
+ * retransmissions with an initial RTO of TCP_RTO_MIN.
+ */
+-static inline bool retransmits_timed_out(struct sock *sk,
++static inline bool retransmits_timed_out(const struct sock *sk,
+ unsigned int boundary)
+ {
+ unsigned int timeout, linear_backoff_thresh;
+- unsigned int start_ts;
+
+ if (!inet_csk(sk)->icsk_retransmits)
+ return false;
+
+- if (unlikely(!tcp_sk(sk)->retrans_stamp))
+- start_ts = TCP_SKB_CB(tcp_write_queue_head(sk))->when;
+- else
+- start_ts = tcp_sk(sk)->retrans_stamp;
+-
+ linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN);
+
+ if (boundary <= linear_backoff_thresh)
+@@ -1285,7 +1279,7 @@ static inline bool retransmits_timed_out(struct sock *sk,
+ timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN +
+ (boundary - linear_backoff_thresh) * TCP_RTO_MAX;
+
+- return (tcp_time_stamp - start_ts) >= timeout;
++ return (tcp_time_stamp - tcp_sk(sk)->retrans_stamp) >= timeout;
+ }
+
+ static inline struct sk_buff *tcp_send_head(struct sock *sk)
+diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
+index 148126d..c35d238 100644
+--- a/include/scsi/fc_frame.h
++++ b/include/scsi/fc_frame.h
+@@ -37,9 +37,6 @@
+ #define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */
+ #define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */
+
+-/* Max number of skb frags allowed, reserving one for fcoe_crc_eof page */
+-#define FC_FRAME_SG_LEN (MAX_SKB_FRAGS - 1)
+-
+ #define fp_skb(fp) (&((fp)->skb))
+ #define fr_hdr(fp) ((fp)->skb.data)
+ #define fr_len(fp) ((fp)->skb.len)
+diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
+index 09a124b..65dc9aa 100644
+--- a/include/scsi/libfc.h
++++ b/include/scsi/libfc.h
+@@ -145,7 +145,6 @@ enum fc_rport_state {
+ RPORT_ST_LOGO, /* port logout sent */
+ RPORT_ST_ADISC, /* Discover Address sent */
+ RPORT_ST_DELETE, /* port being deleted */
+- RPORT_ST_RESTART, /* remote port being deleted and will restart */
+ };
+
+ /**
+diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h
+index 6856612..2cc8e8b 100644
+--- a/include/scsi/osd_protocol.h
++++ b/include/scsi/osd_protocol.h
+@@ -17,7 +17,6 @@
+ #define __OSD_PROTOCOL_H__
+
+ #include <linux/types.h>
+-#include <linux/kernel.h>
+ #include <asm/unaligned.h>
+ #include <scsi/scsi.h>
+
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index 0b4baba..47941fc 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -677,12 +677,6 @@ struct Scsi_Host {
+ void *shost_data;
+
+ /*
+- * Points to the physical bus device we'd use to do DMA
+- * Needed just in case we have virtual hosts.
+- */
+- struct device *dma_dev;
+-
+- /*
+ * We should ensure that this is aligned, both for better performance
+ * and also because some compilers (m68k) don't automatically force
+ * alignment to a long boundary.
+@@ -726,9 +720,7 @@ extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
+ extern void scsi_flush_work(struct Scsi_Host *);
+
+ extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
+-extern int __must_check scsi_add_host_with_dma(struct Scsi_Host *,
+- struct device *,
+- struct device *);
++extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *);
+ extern void scsi_scan_host(struct Scsi_Host *);
+ extern void scsi_rescan_device(struct device *);
+ extern void scsi_remove_host(struct Scsi_Host *);
+@@ -739,12 +731,6 @@ extern const char *scsi_host_state_name(enum scsi_host_state);
+
+ extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
+
+-static inline int __must_check scsi_add_host(struct Scsi_Host *host,
+- struct device *dev)
+-{
+- return scsi_add_host_with_dma(host, dev, dev);
+-}
+-
+ static inline struct device *scsi_get_device(struct Scsi_Host *shost)
+ {
+ return shost->shost_gendev.parent;
+diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
+index dacb8ef..cc0d966 100644
+--- a/include/trace/ftrace.h
++++ b/include/trace/ftrace.h
+@@ -159,7 +159,7 @@
+ #undef __get_str
+
+ #undef TP_printk
+-#define TP_printk(fmt, args...) "\"%s\", %s\n", fmt, __stringify(args)
++#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
+
+ #undef TP_fast_assign
+ #define TP_fast_assign(args...) args
+diff --git a/include/video/tmpa910_fb.h b/include/video/tmpa910_fb.h
+new file mode 100644
+index 0000000..a852022
+--- /dev/null
++++ b/include/video/tmpa910_fb.h
+@@ -0,0 +1,42 @@
++/*
++ * Header file for TMPA910 LCD Controller
++ *
++ * Data structure and register user interface
++ *
++ * Copyright (C) 2008 bplam GmbH
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __TMPA910_LCDC_H__
++#define __TMPA910_LCDC_H__
++
++/* register set indices */
++#define LCDREG_TIMING0_H 0
++#define LCDREG_TIMING1_V 1
++#define LCDREG_TIMING2_CLK 2
++#define LCDREG_TIMING3_LEC 3
++#define LCDREG_LCDCONTROL 4
++
++struct tmpa910_lcdc_platforminfo {
++ uint32_t LCDReg[5];
++ int width;
++ int height;
++ int depth;
++ int pitch;
++};
++
++
++
++#endif /* __TMPA910_LCDC_H__ */
+diff --git a/init/calibrate.c b/init/calibrate.c
+index 6eb48e5..a379c90 100644
+--- a/init/calibrate.c
++++ b/init/calibrate.c
+@@ -123,26 +123,23 @@ void __cpuinit calibrate_delay(void)
+ {
+ unsigned long ticks, loopbit;
+ int lps_precision = LPS_PREC;
+- static bool printed;
+
+ if (preset_lpj) {
+ loops_per_jiffy = preset_lpj;
+- if (!printed)
+- pr_info("Calibrating delay loop (skipped) "
+- "preset value.. ");
+- } else if ((!printed) && lpj_fine) {
++ printk(KERN_INFO
++ "Calibrating delay loop (skipped) preset value.. ");
++ } else if ((smp_processor_id() == 0) && lpj_fine) {
+ loops_per_jiffy = lpj_fine;
+- pr_info("Calibrating delay loop (skipped), "
++ printk(KERN_INFO
++ "Calibrating delay loop (skipped), "
+ "value calculated using timer frequency.. ");
+ } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
+- if (!printed)
+- pr_info("Calibrating delay using timer "
+- "specific routine.. ");
++ printk(KERN_INFO
++ "Calibrating delay using timer specific routine.. ");
+ } else {
+ loops_per_jiffy = (1<<12);
+
+- if (!printed)
+- pr_info("Calibrating delay loop... ");
++ printk(KERN_INFO "Calibrating delay loop... ");
+ while ((loops_per_jiffy <<= 1) != 0) {
+ /* wait for "start of" clock tick */
+ ticks = jiffies;
+@@ -173,10 +170,7 @@ void __cpuinit calibrate_delay(void)
+ loops_per_jiffy &= ~loopbit;
+ }
+ }
+- if (!printed)
+- pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",
++ printk(KERN_CONT "%lu.%02lu BogoMIPS (lpj=%lu)\n",
+ loops_per_jiffy/(500000/HZ),
+ (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy);
+-
+- printed = true;
+ }
+diff --git a/ipc/msg.c b/ipc/msg.c
+index 779f762..2ceab7f 100644
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -125,7 +125,6 @@ void msg_init_ns(struct ipc_namespace *ns)
+ void msg_exit_ns(struct ipc_namespace *ns)
+ {
+ free_ipcs(ns, &msg_ids(ns), freeque);
+- idr_destroy(&ns->ids[IPC_MSG_IDS].ipcs_idr);
+ }
+ #endif
+
+diff --git a/ipc/sem.c b/ipc/sem.c
+index 2f2a479..87c2b64 100644
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -129,7 +129,6 @@ void sem_init_ns(struct ipc_namespace *ns)
+ void sem_exit_ns(struct ipc_namespace *ns)
+ {
+ free_ipcs(ns, &sem_ids(ns), freeary);
+- idr_destroy(&ns->ids[IPC_SEM_IDS].ipcs_idr);
+ }
+ #endif
+
+diff --git a/ipc/shm.c b/ipc/shm.c
+index e9b039f..464694e 100644
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -101,7 +101,6 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
+ void shm_exit_ns(struct ipc_namespace *ns)
+ {
+ free_ipcs(ns, &shm_ids(ns), do_shm_rmid);
+- idr_destroy(&ns->ids[IPC_SHM_IDS].ipcs_idr);
+ }
+ #endif
+
+@@ -291,28 +290,28 @@ static unsigned long shm_get_unmapped_area(struct file *file,
+ unsigned long flags)
+ {
+ struct shm_file_data *sfd = shm_file_data(file);
+- return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
+- pgoff, flags);
++ return get_unmapped_area(sfd->file, addr, len, pgoff, flags);
+ }
+
+-static const struct file_operations shm_file_operations = {
+- .mmap = shm_mmap,
+- .fsync = shm_fsync,
+- .release = shm_release,
+-};
++int is_file_shm_hugepages(struct file *file)
++{
++ int ret = 0;
++
++ if (file->f_op == &shm_file_operations) {
++ struct shm_file_data *sfd;
++ sfd = shm_file_data(file);
++ ret = is_file_hugepages(sfd->file);
++ }
++ return ret;
++}
+
+-static const struct file_operations shm_file_operations_huge = {
++static const struct file_operations shm_file_operations = {
+ .mmap = shm_mmap,
+ .fsync = shm_fsync,
+ .release = shm_release,
+ .get_unmapped_area = shm_get_unmapped_area,
+ };
+
+-int is_file_shm_hugepages(struct file *file)
+-{
+- return file->f_op == &shm_file_operations_huge;
+-}
+-
+ static const struct vm_operations_struct shm_vm_ops = {
+ .open = shm_open, /* callback for a new vm-area open */
+ .close = shm_close, /* callback for when the vm-area is released */
+@@ -890,10 +889,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
+ if (!sfd)
+ goto out_put_dentry;
+
+- file = alloc_file(path.mnt, path.dentry, f_mode,
+- is_file_hugepages(shp->shm_file) ?
+- &shm_file_operations_huge :
+- &shm_file_operations);
++ file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
+ if (!file)
+ goto out_free;
+ ima_counts_get(file);
+diff --git a/kernel/acct.c b/kernel/acct.c
+index a6605ca..9a4715a 100644
+--- a/kernel/acct.c
++++ b/kernel/acct.c
+@@ -536,8 +536,7 @@ static void do_acct_process(struct bsd_acct_struct *acct,
+ do_div(elapsed, AHZ);
+ ac.ac_btime = get_seconds() - elapsed;
+ /* we really need to bite the bullet and change layout */
+- ac.ac_uid = orig_cred->uid;
+- ac.ac_gid = orig_cred->gid;
++ current_uid_gid(&ac.ac_uid, &ac.ac_gid);
+ #if ACCT_VERSION==2
+ ac.ac_ahz = AHZ;
+ #endif
+diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
+index 4b05bd9..2451dc6 100644
+--- a/kernel/audit_tree.c
++++ b/kernel/audit_tree.c
+@@ -277,7 +277,7 @@ static void untag_chunk(struct node *p)
+ owner->root = NULL;
+ }
+
+- for (i = j = 0; j <= size; i++, j++) {
++ for (i = j = 0; i < size; i++, j++) {
+ struct audit_tree *s;
+ if (&chunk->owners[j] == p) {
+ list_del_init(&p->list);
+@@ -290,7 +290,7 @@ static void untag_chunk(struct node *p)
+ if (!s) /* result of earlier fallback */
+ continue;
+ get_tree(s);
+- list_replace_init(&chunk->owners[j].list, &new->owners[i].list);
++ list_replace_init(&chunk->owners[i].list, &new->owners[j].list);
+ }
+
+ list_replace_rcu(&chunk->hash, &new->hash);
+@@ -373,17 +373,15 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
+ for (n = 0; n < old->count; n++) {
+ if (old->owners[n].owner == tree) {
+ spin_unlock(&hash_lock);
+- put_inotify_watch(&old->watch);
++ put_inotify_watch(watch);
+ return 0;
+ }
+ }
+ spin_unlock(&hash_lock);
+
+ chunk = alloc_chunk(old->count + 1);
+- if (!chunk) {
+- put_inotify_watch(&old->watch);
++ if (!chunk)
+ return -ENOMEM;
+- }
+
+ mutex_lock(&inode->inotify_mutex);
+ if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) {
+@@ -427,8 +425,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
+ spin_unlock(&hash_lock);
+ inotify_evict_watch(&old->watch);
+ mutex_unlock(&inode->inotify_mutex);
+- put_inotify_watch(&old->watch); /* pair to inotify_find_watch */
+- put_inotify_watch(&old->watch); /* and kill it */
++ put_inotify_watch(&old->watch);
+ return 0;
+ }
+
+diff --git a/kernel/cgroup.c b/kernel/cgroup.c
+index 1fbcc74..0249f4b 100644
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -2468,6 +2468,7 @@ static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp,
+ /* make sure l doesn't vanish out from under us */
+ down_write(&l->mutex);
+ mutex_unlock(&cgrp->pidlist_mutex);
++ l->use_count++;
+ return l;
+ }
+ }
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 291ac58..6ba0f1e 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -212,8 +212,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
+ err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
+ hcpu, -1, &nr_calls);
+ if (err == NOTIFY_BAD) {
+- set_cpu_active(cpu, true);
+-
+ nr_calls--;
+ __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
+ hcpu, nr_calls, NULL);
+@@ -225,11 +223,11 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
+
+ /* Ensure that we are not runnable on dying cpu */
+ cpumask_copy(old_allowed, ¤t->cpus_allowed);
+- set_cpus_allowed_ptr(current, cpu_active_mask);
++ set_cpus_allowed_ptr(current,
++ cpumask_of(cpumask_any_but(cpu_online_mask, cpu)));
+
+ err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
+ if (err) {
+- set_cpu_active(cpu, true);
+ /* CPU didn't die: tell everyone. Can't complain. */
+ if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
+ hcpu) == NOTIFY_BAD)
+@@ -294,6 +292,9 @@ int __ref cpu_down(unsigned int cpu)
+
+ err = _cpu_down(cpu, 0);
+
++ if (cpu_online(cpu))
++ set_cpu_active(cpu, true);
++
+ out:
+ cpu_maps_update_done();
+ stop_machine_destroy();
+@@ -386,23 +387,15 @@ int disable_nonboot_cpus(void)
+ * with the userspace trying to use the CPU hotplug at the same time
+ */
+ cpumask_clear(frozen_cpus);
+-
+- for_each_online_cpu(cpu) {
+- if (cpu == first_cpu)
+- continue;
+- set_cpu_active(cpu, false);
+- }
+-
+- synchronize_sched();
+-
+ printk("Disabling non-boot CPUs ...\n");
+ for_each_online_cpu(cpu) {
+ if (cpu == first_cpu)
+ continue;
+ error = _cpu_down(cpu, 1);
+- if (!error)
++ if (!error) {
+ cpumask_set_cpu(cpu, frozen_cpus);
+- else {
++ printk("CPU%d is down\n", cpu);
++ } else {
+ printk(KERN_ERR "Error taking CPU%d down: %d\n",
+ cpu, error);
+ break;
+diff --git a/kernel/cpuset.c b/kernel/cpuset.c
+index 39e5121..b5cb469 100644
+--- a/kernel/cpuset.c
++++ b/kernel/cpuset.c
+@@ -873,7 +873,7 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
+ if (retval < 0)
+ return retval;
+
+- if (!cpumask_subset(trialcs->cpus_allowed, cpu_active_mask))
++ if (!cpumask_subset(trialcs->cpus_allowed, cpu_online_mask))
+ return -EINVAL;
+ }
+ retval = validate_change(cs, trialcs);
+@@ -2011,7 +2011,7 @@ static void scan_for_empty_cpusets(struct cpuset *root)
+ }
+
+ /* Continue past cpusets with all cpus, mems online */
+- if (cpumask_subset(cp->cpus_allowed, cpu_active_mask) &&
++ if (cpumask_subset(cp->cpus_allowed, cpu_online_mask) &&
+ nodes_subset(cp->mems_allowed, node_states[N_HIGH_MEMORY]))
+ continue;
+
+@@ -2020,7 +2020,7 @@ static void scan_for_empty_cpusets(struct cpuset *root)
+ /* Remove offline cpus and mems from this cpuset. */
+ mutex_lock(&callback_mutex);
+ cpumask_and(cp->cpus_allowed, cp->cpus_allowed,
+- cpu_active_mask);
++ cpu_online_mask);
+ nodes_and(cp->mems_allowed, cp->mems_allowed,
+ node_states[N_HIGH_MEMORY]);
+ mutex_unlock(&callback_mutex);
+@@ -2058,10 +2058,8 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
+ switch (phase) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+- case CPU_DOWN_PREPARE:
+- case CPU_DOWN_PREPARE_FROZEN:
+- case CPU_DOWN_FAILED:
+- case CPU_DOWN_FAILED_FROZEN:
++ case CPU_DEAD:
++ case CPU_DEAD_FROZEN:
+ break;
+
+ default:
+@@ -2070,7 +2068,7 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
+
+ cgroup_lock();
+ mutex_lock(&callback_mutex);
+- cpumask_copy(top_cpuset.cpus_allowed, cpu_active_mask);
++ cpumask_copy(top_cpuset.cpus_allowed, cpu_online_mask);
+ mutex_unlock(&callback_mutex);
+ scan_for_empty_cpusets(&top_cpuset);
+ ndoms = generate_sched_domains(&doms, &attr);
+@@ -2117,7 +2115,7 @@ static int cpuset_track_online_nodes(struct notifier_block *self,
+
+ void __init cpuset_init_smp(void)
+ {
+- cpumask_copy(top_cpuset.cpus_allowed, cpu_active_mask);
++ cpumask_copy(top_cpuset.cpus_allowed, cpu_online_mask);
+ top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
+
+ hotcpu_notifier(cpuset_track_online_cpus, 0);
+diff --git a/kernel/cred.c b/kernel/cred.c
+index 1ed8ca1..dd76cfe 100644
+--- a/kernel/cred.c
++++ b/kernel/cred.c
+@@ -224,7 +224,7 @@ struct cred *cred_alloc_blank(void)
+ #ifdef CONFIG_KEYS
+ new->tgcred = kzalloc(sizeof(*new->tgcred), GFP_KERNEL);
+ if (!new->tgcred) {
+- kmem_cache_free(cred_jar, new);
++ kfree(new);
+ return NULL;
+ }
+ atomic_set(&new->tgcred->usage, 1);
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 1ad4fa6..fb65e82 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -203,6 +203,8 @@ static void drop_futex_key_refs(union futex_key *key)
+ * @uaddr: virtual address of the futex
+ * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED
+ * @key: address where result is stored.
++ * @rw: mapping needs to be read/write (values: VERIFY_READ,
++ * VERIFY_WRITE)
+ *
+ * Returns a negative error code or 0
+ * The key words are stored in *key on success.
+@@ -214,7 +216,7 @@ static void drop_futex_key_refs(union futex_key *key)
+ * lock_page() might sleep, the caller should not hold a spinlock.
+ */
+ static int
+-get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
++get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
+ {
+ unsigned long address = (unsigned long)uaddr;
+ struct mm_struct *mm = current->mm;
+@@ -237,7 +239,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
+ * but access_ok() should be faster than find_vma()
+ */
+ if (!fshared) {
+- if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
++ if (unlikely(!access_ok(rw, uaddr, sizeof(u32))))
+ return -EFAULT;
+ key->private.mm = mm;
+ key->private.address = address;
+@@ -246,7 +248,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
+ }
+
+ again:
+- err = get_user_pages_fast(address, 1, 1, &page);
++ err = get_user_pages_fast(address, 1, rw == VERIFY_WRITE, &page);
+ if (err < 0)
+ return err;
+
+@@ -302,14 +304,8 @@ void put_futex_key(int fshared, union futex_key *key)
+ */
+ static int fault_in_user_writeable(u32 __user *uaddr)
+ {
+- struct mm_struct *mm = current->mm;
+- int ret;
+-
+- down_read(&mm->mmap_sem);
+- ret = get_user_pages(current, mm, (unsigned long)uaddr,
+- 1, 1, 0, NULL, NULL);
+- up_read(&mm->mmap_sem);
+-
++ int ret = get_user_pages(current, current->mm, (unsigned long)uaddr,
++ 1, 1, 0, NULL, NULL);
+ return ret < 0 ? ret : 0;
+ }
+
+@@ -530,25 +526,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
+ return -EINVAL;
+
+ WARN_ON(!atomic_read(&pi_state->refcount));
+-
+- /*
+- * When pi_state->owner is NULL then the owner died
+- * and another waiter is on the fly. pi_state->owner
+- * is fixed up by the task which acquires
+- * pi_state->rt_mutex.
+- *
+- * We do not check for pid == 0 which can happen when
+- * the owner died and robust_list_exit() cleared the
+- * TID.
+- */
+- if (pid && pi_state->owner) {
+- /*
+- * Bail out if user space manipulated the
+- * futex value.
+- */
+- if (pid != task_pid_vnr(pi_state->owner))
+- return -EINVAL;
+- }
++ WARN_ON(pid && pi_state->owner &&
++ pi_state->owner->pid != pid);
+
+ atomic_inc(&pi_state->refcount);
+ *ps = pi_state;
+@@ -775,13 +754,6 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
+ if (!pi_state)
+ return -EINVAL;
+
+- /*
+- * If current does not own the pi_state then the futex is
+- * inconsistent and user space fiddled with the futex value.
+- */
+- if (pi_state->owner != current)
+- return -EINVAL;
+-
+ spin_lock(&pi_state->pi_mutex.wait_lock);
+ new_owner = rt_mutex_next_owner(&pi_state->pi_mutex);
+
+@@ -889,7 +861,7 @@ static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset)
+ if (!bitset)
+ return -EINVAL;
+
+- ret = get_futex_key(uaddr, fshared, &key);
++ ret = get_futex_key(uaddr, fshared, &key, VERIFY_READ);
+ if (unlikely(ret != 0))
+ goto out;
+
+@@ -935,10 +907,10 @@ futex_wake_op(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
+ int ret, op_ret;
+
+ retry:
+- ret = get_futex_key(uaddr1, fshared, &key1);
++ ret = get_futex_key(uaddr1, fshared, &key1, VERIFY_READ);
+ if (unlikely(ret != 0))
+ goto out;
+- ret = get_futex_key(uaddr2, fshared, &key2);
++ ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE);
+ if (unlikely(ret != 0))
+ goto out_put_key1;
+
+@@ -1197,10 +1169,11 @@ retry:
+ pi_state = NULL;
+ }
+
+- ret = get_futex_key(uaddr1, fshared, &key1);
++ ret = get_futex_key(uaddr1, fshared, &key1, VERIFY_READ);
+ if (unlikely(ret != 0))
+ goto out;
+- ret = get_futex_key(uaddr2, fshared, &key2);
++ ret = get_futex_key(uaddr2, fshared, &key2,
++ requeue_pi ? VERIFY_WRITE : VERIFY_READ);
+ if (unlikely(ret != 0))
+ goto out_put_key1;
+
+@@ -1759,7 +1732,7 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, int fshared,
+ */
+ retry:
+ q->key = FUTEX_KEY_INIT;
+- ret = get_futex_key(uaddr, fshared, &q->key);
++ ret = get_futex_key(uaddr, fshared, &q->key, VERIFY_READ);
+ if (unlikely(ret != 0))
+ return ret;
+
+@@ -1925,7 +1898,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
+ q.requeue_pi_key = NULL;
+ retry:
+ q.key = FUTEX_KEY_INIT;
+- ret = get_futex_key(uaddr, fshared, &q.key);
++ ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_WRITE);
+ if (unlikely(ret != 0))
+ goto out;
+
+@@ -1995,7 +1968,7 @@ retry_private:
+ /* Unqueue and drop the lock */
+ unqueue_me_pi(&q);
+
+- goto out_put_key;
++ goto out;
+
+ out_unlock_put_key:
+ queue_unlock(&q, hb);
+@@ -2044,7 +2017,7 @@ retry:
+ if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current))
+ return -EPERM;
+
+- ret = get_futex_key(uaddr, fshared, &key);
++ ret = get_futex_key(uaddr, fshared, &key, VERIFY_WRITE);
+ if (unlikely(ret != 0))
+ goto out;
+
+@@ -2236,7 +2209,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared,
+ rt_waiter.task = NULL;
+
+ key2 = FUTEX_KEY_INIT;
+- ret = get_futex_key(uaddr2, fshared, &key2);
++ ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE);
+ if (unlikely(ret != 0))
+ goto out;
+
+diff --git a/kernel/module.c b/kernel/module.c
+index dfa33e8..5842a71 100644
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -1030,23 +1030,11 @@ static int try_to_force_load(struct module *mod, const char *reason)
+ }
+
+ #ifdef CONFIG_MODVERSIONS
+-/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */
+-static unsigned long maybe_relocated(unsigned long crc,
+- const struct module *crc_owner)
+-{
+-#ifdef ARCH_RELOCATES_KCRCTAB
+- if (crc_owner == NULL)
+- return crc - (unsigned long)reloc_start;
+-#endif
+- return crc;
+-}
+-
+ static int check_version(Elf_Shdr *sechdrs,
+ unsigned int versindex,
+ const char *symname,
+ struct module *mod,
+- const unsigned long *crc,
+- const struct module *crc_owner)
++ const unsigned long *crc)
+ {
+ unsigned int i, num_versions;
+ struct modversion_info *versions;
+@@ -1067,10 +1055,10 @@ static int check_version(Elf_Shdr *sechdrs,
+ if (strcmp(versions[i].name, symname) != 0)
+ continue;
+
+- if (versions[i].crc == maybe_relocated(*crc, crc_owner))
++ if (versions[i].crc == *crc)
+ return 1;
+ DEBUGP("Found checksum %lX vs module %lX\n",
+- maybe_relocated(*crc, crc_owner), versions[i].crc);
++ *crc, versions[i].crc);
+ goto bad_version;
+ }
+
+@@ -1093,8 +1081,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
+ if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL,
+ &crc, true, false))
+ BUG();
+- return check_version(sechdrs, versindex, "module_layout", mod, crc,
+- NULL);
++ return check_version(sechdrs, versindex, "module_layout", mod, crc);
+ }
+
+ /* First part is kernel version, which we ignore if module has crcs. */
+@@ -1112,8 +1099,7 @@ static inline int check_version(Elf_Shdr *sechdrs,
+ unsigned int versindex,
+ const char *symname,
+ struct module *mod,
+- const unsigned long *crc,
+- const struct module *crc_owner)
++ const unsigned long *crc)
+ {
+ return 1;
+ }
+@@ -1148,8 +1134,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
+ /* use_module can fail due to OOM,
+ or module initialization or unloading */
+ if (sym) {
+- if (!check_version(sechdrs, versindex, name, mod, crc, owner)
+- || !use_module(mod, owner))
++ if (!check_version(sechdrs, versindex, name, mod, crc) ||
++ !use_module(mod, owner))
+ sym = NULL;
+ }
+ return sym;
+@@ -1160,12 +1146,6 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
+ * J. Corbet <corbet at lwn.net>
+ */
+ #if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS)
+-
+-static inline bool sect_empty(const Elf_Shdr *sect)
+-{
+- return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0;
+-}
+-
+ struct module_sect_attr
+ {
+ struct module_attribute mattr;
+@@ -1207,7 +1187,8 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
+
+ /* Count loaded sections and allocate structures */
+ for (i = 0; i < nsect; i++)
+- if (!sect_empty(&sechdrs[i]))
++ if (sechdrs[i].sh_flags & SHF_ALLOC
++ && sechdrs[i].sh_size)
+ nloaded++;
+ size[0] = ALIGN(sizeof(*sect_attrs)
+ + nloaded * sizeof(sect_attrs->attrs[0]),
+@@ -1225,7 +1206,9 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
+ sattr = §_attrs->attrs[0];
+ gattr = §_attrs->grp.attrs[0];
+ for (i = 0; i < nsect; i++) {
+- if (sect_empty(&sechdrs[i]))
++ if (! (sechdrs[i].sh_flags & SHF_ALLOC))
++ continue;
++ if (!sechdrs[i].sh_size)
+ continue;
+ sattr->address = sechdrs[i].sh_addr;
+ sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
+@@ -1309,7 +1292,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
+ /* Count notes sections and allocate structures. */
+ notes = 0;
+ for (i = 0; i < nsect; i++)
+- if (!sect_empty(&sechdrs[i]) &&
++ if ((sechdrs[i].sh_flags & SHF_ALLOC) &&
+ (sechdrs[i].sh_type == SHT_NOTE))
+ ++notes;
+
+@@ -1325,7 +1308,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
+ notes_attrs->notes = notes;
+ nattr = ¬es_attrs->attrs[0];
+ for (loaded = i = 0; i < nsect; ++i) {
+- if (sect_empty(&sechdrs[i]))
++ if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+ continue;
+ if (sechdrs[i].sh_type == SHT_NOTE) {
+ nattr->attr.name = mod->sect_attrs->attrs[loaded].name;
+diff --git a/kernel/perf_event.c b/kernel/perf_event.c
+index 413d101..7f29643 100644
+--- a/kernel/perf_event.c
++++ b/kernel/perf_event.c
+@@ -1359,9 +1359,6 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
+ if (event->state != PERF_EVENT_STATE_ACTIVE)
+ continue;
+
+- if (event->cpu != -1 && event->cpu != smp_processor_id())
+- continue;
+-
+ hwc = &event->hw;
+
+ interrupts = hwc->interrupts;
+@@ -1586,7 +1583,7 @@ static struct perf_event_context *find_get_context(pid_t pid, int cpu)
+ if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+ return ERR_PTR(-EACCES);
+
+- if (cpu < 0 || cpu >= nr_cpumask_bits)
++ if (cpu < 0 || cpu > num_possible_cpus())
+ return ERR_PTR(-EINVAL);
+
+ /*
+@@ -2177,7 +2174,6 @@ static void perf_mmap_data_free(struct perf_mmap_data *data)
+ perf_mmap_free_page((unsigned long)data->user_page);
+ for (i = 0; i < data->nr_pages; i++)
+ perf_mmap_free_page((unsigned long)data->data_pages[i]);
+- kfree(data);
+ }
+
+ #else
+@@ -2218,7 +2214,6 @@ static void perf_mmap_data_free_work(struct work_struct *work)
+ perf_mmap_unmark_page(base + (i * PAGE_SIZE));
+
+ vfree(base);
+- kfree(data);
+ }
+
+ static void perf_mmap_data_free(struct perf_mmap_data *data)
+@@ -2324,6 +2319,7 @@ static void perf_mmap_data_free_rcu(struct rcu_head *rcu_head)
+
+ data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
+ perf_mmap_data_free(data);
++ kfree(data);
+ }
+
+ static void perf_mmap_data_release(struct perf_event *event)
+@@ -3229,12 +3225,6 @@ static void perf_event_task_output(struct perf_event *event,
+
+ static int perf_event_task_match(struct perf_event *event)
+ {
+- if (event->state != PERF_EVENT_STATE_ACTIVE)
+- return 0;
+-
+- if (event->cpu != -1 && event->cpu != smp_processor_id())
+- return 0;
+-
+ if (event->attr.comm || event->attr.mmap || event->attr.task)
+ return 1;
+
+@@ -3264,13 +3254,13 @@ static void perf_event_task_event(struct perf_task_event *task_event)
+
+ cpuctx = &get_cpu_var(perf_cpu_context);
+ perf_event_task_ctx(&cpuctx->ctx, task_event);
++ put_cpu_var(perf_cpu_context);
+
+ rcu_read_lock();
+ if (!ctx)
+ ctx = rcu_dereference(task_event->task->perf_event_ctxp);
+ if (ctx)
+ perf_event_task_ctx(ctx, task_event);
+- put_cpu_var(perf_cpu_context);
+ rcu_read_unlock();
+ }
+
+@@ -3347,12 +3337,6 @@ static void perf_event_comm_output(struct perf_event *event,
+
+ static int perf_event_comm_match(struct perf_event *event)
+ {
+- if (event->state != PERF_EVENT_STATE_ACTIVE)
+- return 0;
+-
+- if (event->cpu != -1 && event->cpu != smp_processor_id())
+- return 0;
+-
+ if (event->attr.comm)
+ return 1;
+
+@@ -3393,6 +3377,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
+
+ cpuctx = &get_cpu_var(perf_cpu_context);
+ perf_event_comm_ctx(&cpuctx->ctx, comm_event);
++ put_cpu_var(perf_cpu_context);
+
+ rcu_read_lock();
+ /*
+@@ -3402,7 +3387,6 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
+ ctx = rcu_dereference(current->perf_event_ctxp);
+ if (ctx)
+ perf_event_comm_ctx(ctx, comm_event);
+- put_cpu_var(perf_cpu_context);
+ rcu_read_unlock();
+ }
+
+@@ -3477,12 +3461,6 @@ static void perf_event_mmap_output(struct perf_event *event,
+ static int perf_event_mmap_match(struct perf_event *event,
+ struct perf_mmap_event *mmap_event)
+ {
+- if (event->state != PERF_EVENT_STATE_ACTIVE)
+- return 0;
+-
+- if (event->cpu != -1 && event->cpu != smp_processor_id())
+- return 0;
+-
+ if (event->attr.mmap)
+ return 1;
+
+@@ -3560,6 +3538,7 @@ got_name:
+
+ cpuctx = &get_cpu_var(perf_cpu_context);
+ perf_event_mmap_ctx(&cpuctx->ctx, mmap_event);
++ put_cpu_var(perf_cpu_context);
+
+ rcu_read_lock();
+ /*
+@@ -3569,7 +3548,6 @@ got_name:
+ ctx = rcu_dereference(current->perf_event_ctxp);
+ if (ctx)
+ perf_event_mmap_ctx(ctx, mmap_event);
+- put_cpu_var(perf_cpu_context);
+ rcu_read_unlock();
+
+ kfree(buf);
+@@ -3832,9 +3810,6 @@ static int perf_swevent_match(struct perf_event *event,
+ enum perf_type_id type,
+ u32 event_id, struct pt_regs *regs)
+ {
+- if (event->cpu != -1 && event->cpu != smp_processor_id())
+- return 0;
+-
+ if (!perf_swevent_is_counting(event))
+ return 0;
+
+@@ -3974,7 +3949,6 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
+ event->pmu->read(event);
+
+ data.addr = 0;
+- data.period = event->hw.last_period;
+ regs = get_irq_regs();
+ /*
+ * In case we exclude kernel IPs or are somehow not in interrupt
+diff --git a/kernel/rcutree.c b/kernel/rcutree.c
+index 683c4f3..f3077c0 100644
+--- a/kernel/rcutree.c
++++ b/kernel/rcutree.c
+@@ -176,29 +176,9 @@ static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
+ return &rsp->node[0];
+ }
+
+-/*
+- * Record the specified "completed" value, which is later used to validate
+- * dynticks counter manipulations and CPU-offline checks. Specify
+- * "rsp->completed - 1" to unconditionally invalidate any future dynticks
+- * manipulations and CPU-offline checks. Such invalidation is useful at
+- * the beginning of a grace period.
+- */
+-static void dyntick_record_completed(struct rcu_state *rsp, long comp)
+-{
+- rsp->dynticks_completed = comp;
+-}
+-
+ #ifdef CONFIG_SMP
+
+ /*
+- * Recall the previously recorded value of the completion for dynticks.
+- */
+-static long dyntick_recall_completed(struct rcu_state *rsp)
+-{
+- return rsp->dynticks_completed;
+-}
+-
+-/*
+ * If the specified CPU is offline, tell the caller that it is in
+ * a quiescent state. Otherwise, whack it with a reschedule IPI.
+ * Grace periods can end up waiting on an offline CPU when that
+@@ -355,9 +335,28 @@ void rcu_irq_exit(void)
+ set_need_resched();
+ }
+
++/*
++ * Record the specified "completed" value, which is later used to validate
++ * dynticks counter manipulations. Specify "rsp->completed - 1" to
++ * unconditionally invalidate any future dynticks manipulations (which is
++ * useful at the beginning of a grace period).
++ */
++static void dyntick_record_completed(struct rcu_state *rsp, long comp)
++{
++ rsp->dynticks_completed = comp;
++}
++
+ #ifdef CONFIG_SMP
+
+ /*
++ * Recall the previously recorded value of the completion for dynticks.
++ */
++static long dyntick_recall_completed(struct rcu_state *rsp)
++{
++ return rsp->dynticks_completed;
++}
++
++/*
+ * Snapshot the specified CPU's dynticks counter so that we can later
+ * credit them with an implicit quiescent state. Return 1 if this CPU
+ * is in dynticks idle mode, which is an extended quiescent state.
+@@ -420,8 +419,24 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
+
+ #else /* #ifdef CONFIG_NO_HZ */
+
++static void dyntick_record_completed(struct rcu_state *rsp, long comp)
++{
++}
++
+ #ifdef CONFIG_SMP
+
++/*
++ * If there are no dynticks, then the only way that a CPU can passively
++ * be in a quiescent state is to be offline. Unlike dynticks idle, which
++ * is a point in time during the prior (already finished) grace period,
++ * an offline CPU is always in a quiescent state, and thus can be
++ * unconditionally applied. So just return the current value of completed.
++ */
++static long dyntick_recall_completed(struct rcu_state *rsp)
++{
++ return rsp->completed;
++}
++
+ static int dyntick_save_progress_counter(struct rcu_data *rdp)
+ {
+ return 0;
+@@ -538,33 +553,13 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
+ /*
+ * Update CPU-local rcu_data state to record the newly noticed grace period.
+ * This is used both when we started the grace period and when we notice
+- * that someone else started the grace period. The caller must hold the
+- * ->lock of the leaf rcu_node structure corresponding to the current CPU,
+- * and must have irqs disabled.
++ * that someone else started the grace period.
+ */
+-static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+-{
+- if (rdp->gpnum != rnp->gpnum) {
+- rdp->qs_pending = 1;
+- rdp->passed_quiesc = 0;
+- rdp->gpnum = rnp->gpnum;
+- }
+-}
+-
+ static void note_new_gpnum(struct rcu_state *rsp, struct rcu_data *rdp)
+ {
+- unsigned long flags;
+- struct rcu_node *rnp;
+-
+- local_irq_save(flags);
+- rnp = rdp->mynode;
+- if (rdp->gpnum == ACCESS_ONCE(rnp->gpnum) || /* outside lock. */
+- !spin_trylock(&rnp->lock)) { /* irqs already off, retry later. */
+- local_irq_restore(flags);
+- return;
+- }
+- __note_new_gpnum(rsp, rnp, rdp);
+- spin_unlock_irqrestore(&rnp->lock, flags);
++ rdp->qs_pending = 1;
++ rdp->passed_quiesc = 0;
++ rdp->gpnum = rsp->gpnum;
+ }
+
+ /*
+@@ -588,79 +583,6 @@ check_for_new_grace_period(struct rcu_state *rsp, struct rcu_data *rdp)
+ }
+
+ /*
+- * Advance this CPU's callbacks, but only if the current grace period
+- * has ended. This may be called only from the CPU to whom the rdp
+- * belongs. In addition, the corresponding leaf rcu_node structure's
+- * ->lock must be held by the caller, with irqs disabled.
+- */
+-static void
+-__rcu_process_gp_end(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+-{
+- /* Did another grace period end? */
+- if (rdp->completed != rnp->completed) {
+-
+- /* Advance callbacks. No harm if list empty. */
+- rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[RCU_WAIT_TAIL];
+- rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_READY_TAIL];
+- rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+-
+- /* Remember that we saw this grace-period completion. */
+- rdp->completed = rnp->completed;
+- }
+-}
+-
+-/*
+- * Advance this CPU's callbacks, but only if the current grace period
+- * has ended. This may be called only from the CPU to whom the rdp
+- * belongs.
+- */
+-static void
+-rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp)
+-{
+- unsigned long flags;
+- struct rcu_node *rnp;
+-
+- local_irq_save(flags);
+- rnp = rdp->mynode;
+- if (rdp->completed == ACCESS_ONCE(rnp->completed) || /* outside lock. */
+- !spin_trylock(&rnp->lock)) { /* irqs already off, retry later. */
+- local_irq_restore(flags);
+- return;
+- }
+- __rcu_process_gp_end(rsp, rnp, rdp);
+- spin_unlock_irqrestore(&rnp->lock, flags);
+-}
+-
+-/*
+- * Do per-CPU grace-period initialization for running CPU. The caller
+- * must hold the lock of the leaf rcu_node structure corresponding to
+- * this CPU.
+- */
+-static void
+-rcu_start_gp_per_cpu(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+-{
+- /* Prior grace period ended, so advance callbacks for current CPU. */
+- __rcu_process_gp_end(rsp, rnp, rdp);
+-
+- /*
+- * Because this CPU just now started the new grace period, we know
+- * that all of its callbacks will be covered by this upcoming grace
+- * period, even the ones that were registered arbitrarily recently.
+- * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL.
+- *
+- * Other CPUs cannot be sure exactly when the grace period started.
+- * Therefore, their recently registered callbacks must pass through
+- * an additional RCU_NEXT_READY stage, so that they will be handled
+- * by the next RCU grace period.
+- */
+- rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+- rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+-
+- /* Set state so that this CPU will detect the next quiescent state. */
+- __note_new_gpnum(rsp, rnp, rdp);
+-}
+-
+-/*
+ * Start a new RCU grace period if warranted, re-initializing the hierarchy
+ * in preparation for detecting the next grace period. The caller must hold
+ * the root node's ->lock, which is released before return. Hard irqs must
+@@ -685,15 +607,28 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
+ rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
+ record_gp_stall_check_time(rsp);
+ dyntick_record_completed(rsp, rsp->completed - 1);
++ note_new_gpnum(rsp, rdp);
++
++ /*
++ * Because this CPU just now started the new grace period, we know
++ * that all of its callbacks will be covered by this upcoming grace
++ * period, even the ones that were registered arbitrarily recently.
++ * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL.
++ *
++ * Other CPUs cannot be sure exactly when the grace period started.
++ * Therefore, their recently registered callbacks must pass through
++ * an additional RCU_NEXT_READY stage, so that they will be handled
++ * by the next RCU grace period.
++ */
++ rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
++ rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+
+ /* Special-case the common single-level case. */
+ if (NUM_RCU_NODES == 1) {
+ rcu_preempt_check_blocked_tasks(rnp);
+ rnp->qsmask = rnp->qsmaskinit;
+ rnp->gpnum = rsp->gpnum;
+- rnp->completed = rsp->completed;
+ rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state OK. */
+- rcu_start_gp_per_cpu(rsp, rnp, rdp);
+ spin_unlock_irqrestore(&rnp->lock, flags);
+ return;
+ }
+@@ -726,9 +661,6 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
+ rcu_preempt_check_blocked_tasks(rnp);
+ rnp->qsmask = rnp->qsmaskinit;
+ rnp->gpnum = rsp->gpnum;
+- rnp->completed = rsp->completed;
+- if (rnp == rdp->mynode)
+- rcu_start_gp_per_cpu(rsp, rnp, rdp);
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
+ }
+
+@@ -740,6 +672,34 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
+ }
+
+ /*
++ * Advance this CPU's callbacks, but only if the current grace period
++ * has ended. This may be called only from the CPU to whom the rdp
++ * belongs.
++ */
++static void
++rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp)
++{
++ long completed_snap;
++ unsigned long flags;
++
++ local_irq_save(flags);
++ completed_snap = ACCESS_ONCE(rsp->completed); /* outside of lock. */
++
++ /* Did another grace period end? */
++ if (rdp->completed != completed_snap) {
++
++ /* Advance callbacks. No harm if list empty. */
++ rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[RCU_WAIT_TAIL];
++ rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_READY_TAIL];
++ rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
++
++ /* Remember that we saw this grace-period completion. */
++ rdp->completed = completed_snap;
++ }
++ local_irq_restore(flags);
++}
++
++/*
+ * Clean up after the prior grace period and let rcu_start_gp() start up
+ * the next grace period if one is needed. Note that the caller must
+ * hold rnp->lock, as required by rcu_start_gp(), which will release it.
+@@ -750,6 +710,7 @@ static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags)
+ WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
+ rsp->completed = rsp->gpnum;
+ rsp->signaled = RCU_GP_IDLE;
++ rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]);
+ rcu_start_gp(rsp, flags); /* releases root node's rnp->lock. */
+ }
+
+@@ -1183,7 +1144,6 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
+ long lastcomp;
+ struct rcu_node *rnp = rcu_get_root(rsp);
+ u8 signaled;
+- u8 forcenow;
+
+ if (!rcu_gp_in_progress(rsp))
+ return; /* No grace period in progress, nothing to force. */
+@@ -1220,23 +1180,16 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
+ if (rcu_process_dyntick(rsp, lastcomp,
+ dyntick_save_progress_counter))
+ goto unlock_ret;
+- /* fall into next case. */
+-
+- case RCU_SAVE_COMPLETED:
+
+ /* Update state, record completion counter. */
+- forcenow = 0;
+ spin_lock(&rnp->lock);
+ if (lastcomp == rsp->completed &&
+- rsp->signaled == signaled) {
++ rsp->signaled == RCU_SAVE_DYNTICK) {
+ rsp->signaled = RCU_FORCE_QS;
+ dyntick_record_completed(rsp, lastcomp);
+- forcenow = signaled == RCU_SAVE_COMPLETED;
+ }
+ spin_unlock(&rnp->lock);
+- if (!forcenow)
+- break;
+- /* fall into next case. */
++ break;
+
+ case RCU_FORCE_QS:
+
+@@ -1591,16 +1544,21 @@ static void __cpuinit
+ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable)
+ {
+ unsigned long flags;
++ long lastcomp;
+ unsigned long mask;
+ struct rcu_data *rdp = rsp->rda[cpu];
+ struct rcu_node *rnp = rcu_get_root(rsp);
+
+ /* Set up local state, ensuring consistent view of global state. */
+ spin_lock_irqsave(&rnp->lock, flags);
++ lastcomp = rsp->completed;
++ rdp->completed = lastcomp;
++ rdp->gpnum = lastcomp;
+ rdp->passed_quiesc = 0; /* We could be racing with new GP, */
+ rdp->qs_pending = 1; /* so set up to respond to current GP. */
+ rdp->beenonline = 1; /* We have now been online. */
+ rdp->preemptable = preemptable;
++ rdp->passed_quiesc_completed = lastcomp - 1;
+ rdp->qlen_last_fqs_check = 0;
+ rdp->n_force_qs_snap = rsp->n_force_qs;
+ rdp->blimit = blimit;
+@@ -1622,11 +1580,6 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable)
+ spin_lock(&rnp->lock); /* irqs already disabled. */
+ rnp->qsmaskinit |= mask;
+ mask = rnp->grpmask;
+- if (rnp == rdp->mynode) {
+- rdp->gpnum = rnp->completed; /* if GP in progress... */
+- rdp->completed = rnp->completed;
+- rdp->passed_quiesc_completed = rnp->completed - 1;
+- }
+ spin_unlock(&rnp->lock); /* irqs already disabled. */
+ rnp = rnp->parent;
+ } while (rnp != NULL && !(rnp->qsmaskinit & mask));
+diff --git a/kernel/rcutree.h b/kernel/rcutree.h
+index ddb79ec..1899023 100644
+--- a/kernel/rcutree.h
++++ b/kernel/rcutree.h
+@@ -84,9 +84,6 @@ struct rcu_node {
+ long gpnum; /* Current grace period for this node. */
+ /* This will either be equal to or one */
+ /* behind the root rcu_node's gpnum. */
+- long completed; /* Last grace period completed for this node. */
+- /* This will either be equal to or one */
+- /* behind the root rcu_node's gpnum. */
+ unsigned long qsmask; /* CPUs or groups that need to switch in */
+ /* order for current grace period to proceed.*/
+ /* In leaf rcu_node, each bit corresponds to */
+@@ -207,12 +204,11 @@ struct rcu_data {
+ #define RCU_GP_IDLE 0 /* No grace period in progress. */
+ #define RCU_GP_INIT 1 /* Grace period being initialized. */
+ #define RCU_SAVE_DYNTICK 2 /* Need to scan dyntick state. */
+-#define RCU_SAVE_COMPLETED 3 /* Need to save rsp->completed. */
+-#define RCU_FORCE_QS 4 /* Need to force quiescent state. */
++#define RCU_FORCE_QS 3 /* Need to force quiescent state. */
+ #ifdef CONFIG_NO_HZ
+ #define RCU_SIGNAL_INIT RCU_SAVE_DYNTICK
+ #else /* #ifdef CONFIG_NO_HZ */
+-#define RCU_SIGNAL_INIT RCU_SAVE_COMPLETED
++#define RCU_SIGNAL_INIT RCU_FORCE_QS
+ #endif /* #else #ifdef CONFIG_NO_HZ */
+
+ #define RCU_JIFFIES_TILL_FORCE_QS 3 /* for rsp->jiffies_force_qs */
+@@ -278,8 +274,9 @@ struct rcu_state {
+ unsigned long jiffies_stall; /* Time at which to check */
+ /* for CPU stalls. */
+ #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
++#ifdef CONFIG_NO_HZ
+ long dynticks_completed; /* Value of completed @ snap. */
+- /* Protected by fqslock. */
++#endif /* #ifdef CONFIG_NO_HZ */
+ };
+
+ #ifdef RCU_TREE_NONCORE
+@@ -301,7 +298,7 @@ DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data);
+ #else /* #ifdef RCU_TREE_NONCORE */
+
+ /* Forward declarations for rcutree_plugin.h */
+-static void rcu_bootup_announce(void);
++static inline void rcu_bootup_announce(void);
+ long rcu_batches_completed(void);
+ static void rcu_preempt_note_context_switch(int cpu);
+ static int rcu_preempted_readers(struct rcu_node *rnp);
+diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
+index c03edf7..ef2a58c 100644
+--- a/kernel/rcutree_plugin.h
++++ b/kernel/rcutree_plugin.h
+@@ -33,7 +33,7 @@ DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data);
+ /*
+ * Tell them what RCU they are running.
+ */
+-static void rcu_bootup_announce(void)
++static inline void rcu_bootup_announce(void)
+ {
+ printk(KERN_INFO
+ "Experimental preemptable hierarchical RCU implementation.\n");
+@@ -481,7 +481,7 @@ void exit_rcu(void)
+ /*
+ * Tell them what RCU they are running.
+ */
+-static void rcu_bootup_announce(void)
++static inline void rcu_bootup_announce(void)
+ {
+ printk(KERN_INFO "Hierarchical RCU implementation.\n");
+ }
+diff --git a/kernel/sched.c b/kernel/sched.c
+index 60d74cc..3c11ae0 100644
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -591,8 +591,6 @@ struct rq {
+
+ u64 rt_avg;
+ u64 age_stamp;
+- u64 idle_stamp;
+- u64 avg_idle;
+ #endif
+
+ /* calc_load related fields */
+@@ -816,7 +814,6 @@ const_debug unsigned int sysctl_sched_nr_migrate = 32;
+ * default: 0.25ms
+ */
+ unsigned int sysctl_sched_shares_ratelimit = 250000;
+-unsigned int normalized_sysctl_sched_shares_ratelimit = 250000;
+
+ /*
+ * Inject some fuzzyness into changing the per-cpu group shares
+@@ -1813,7 +1810,6 @@ static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares)
+ #endif
+
+ static void calc_load_account_active(struct rq *this_rq);
+-static void update_sysctl(void);
+
+ #include "sched_stats.h"
+ #include "sched_idletask.c"
+@@ -2038,9 +2034,6 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
+ {
+ s64 delta;
+
+- if (p->sched_class != &fair_sched_class)
+- return 0;
+-
+ /*
+ * Buddy candidates are cache hot:
+ */
+@@ -2049,6 +2042,9 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
+ &p->se == cfs_rq_of(&p->se)->last))
+ return 1;
+
++ if (p->sched_class != &fair_sched_class)
++ return 0;
++
+ if (sysctl_sched_migration_cost == -1)
+ return 1;
+ if (sysctl_sched_migration_cost == 0)
+@@ -2444,17 +2440,6 @@ out_running:
+ #ifdef CONFIG_SMP
+ if (p->sched_class->task_wake_up)
+ p->sched_class->task_wake_up(rq, p);
+-
+- if (unlikely(rq->idle_stamp)) {
+- u64 delta = rq->clock - rq->idle_stamp;
+- u64 max = 2*sysctl_sched_migration_cost;
+-
+- if (delta > max)
+- rq->avg_idle = max;
+- else
+- update_avg(&rq->avg_idle, delta);
+- rq->idle_stamp = 0;
+- }
+ #endif
+ out:
+ task_rq_unlock(rq, &flags);
+@@ -3179,6 +3164,10 @@ static void pull_task(struct rq *src_rq, struct task_struct *p,
+ deactivate_task(src_rq, p, 0);
+ set_task_cpu(p, this_cpu);
+ activate_task(this_rq, p, 0);
++ /*
++ * Note that idle threads have a prio of MAX_PRIO, for this test
++ * to be always true for them.
++ */
+ check_preempt_curr(this_rq, p, 0);
+ }
+
+@@ -4137,7 +4126,7 @@ static int load_balance(int this_cpu, struct rq *this_rq,
+ unsigned long flags;
+ struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask);
+
+- cpumask_copy(cpus, cpu_active_mask);
++ cpumask_setall(cpus);
+
+ /*
+ * When power savings policy is enabled for the parent domain, idle
+@@ -4300,7 +4289,7 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
+ int all_pinned = 0;
+ struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask);
+
+- cpumask_copy(cpus, cpu_active_mask);
++ cpumask_setall(cpus);
+
+ /*
+ * When power savings policy is enabled for the parent domain, idle
+@@ -4440,11 +4429,6 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
+ int pulled_task = 0;
+ unsigned long next_balance = jiffies + HZ;
+
+- this_rq->idle_stamp = this_rq->clock;
+-
+- if (this_rq->avg_idle < sysctl_sched_migration_cost)
+- return;
+-
+ for_each_domain(this_cpu, sd) {
+ unsigned long interval;
+
+@@ -4459,10 +4443,8 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
+ interval = msecs_to_jiffies(sd->balance_interval);
+ if (time_after(next_balance, sd->last_balance + interval))
+ next_balance = sd->last_balance + interval;
+- if (pulled_task) {
+- this_rq->idle_stamp = 0;
++ if (pulled_task)
+ break;
+- }
+ }
+ if (pulled_task || time_after(jiffies, this_rq->next_balance)) {
+ /*
+@@ -4697,7 +4679,7 @@ int select_nohz_load_balancer(int stop_tick)
+ cpumask_set_cpu(cpu, nohz.cpu_mask);
+
+ /* time for ilb owner also to sleep */
+- if (cpumask_weight(nohz.cpu_mask) == num_active_cpus()) {
++ if (cpumask_weight(nohz.cpu_mask) == num_online_cpus()) {
+ if (atomic_read(&nohz.load_balancer) == cpu)
+ atomic_set(&nohz.load_balancer, -1);
+ return 0;
+@@ -6980,6 +6962,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
+ __sched_fork(idle);
+ idle->se.exec_start = sched_clock();
+
++ idle->prio = idle->normal_prio = MAX_PRIO;
+ cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu));
+ __set_task_cpu(idle, cpu);
+
+@@ -7020,23 +7003,22 @@ cpumask_var_t nohz_cpu_mask;
+ *
+ * This idea comes from the SD scheduler of Con Kolivas:
+ */
+-static void update_sysctl(void)
++static inline void sched_init_granularity(void)
+ {
+- unsigned int cpus = min(num_online_cpus(), 8U);
+- unsigned int factor = 1 + ilog2(cpus);
++ unsigned int factor = 1 + ilog2(num_online_cpus());
++ const unsigned long limit = 200000000;
+
+-#define SET_SYSCTL(name) \
+- (sysctl_##name = (factor) * normalized_sysctl_##name)
+- SET_SYSCTL(sched_min_granularity);
+- SET_SYSCTL(sched_latency);
+- SET_SYSCTL(sched_wakeup_granularity);
+- SET_SYSCTL(sched_shares_ratelimit);
+-#undef SET_SYSCTL
+-}
++ sysctl_sched_min_granularity *= factor;
++ if (sysctl_sched_min_granularity > limit)
++ sysctl_sched_min_granularity = limit;
+
+-static inline void sched_init_granularity(void)
+-{
+- update_sysctl();
++ sysctl_sched_latency *= factor;
++ if (sysctl_sched_latency > limit)
++ sysctl_sched_latency = limit;
++
++ sysctl_sched_wakeup_granularity *= factor;
++
++ sysctl_sched_shares_ratelimit *= factor;
+ }
+
+ #ifdef CONFIG_SMP
+@@ -7073,7 +7055,7 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
+ int ret = 0;
+
+ rq = task_rq_lock(p, &flags);
+- if (!cpumask_intersects(new_mask, cpu_active_mask)) {
++ if (!cpumask_intersects(new_mask, cpu_online_mask)) {
+ ret = -EINVAL;
+ goto out;
+ }
+@@ -7095,7 +7077,7 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
+ if (cpumask_test_cpu(task_cpu(p), new_mask))
+ goto out;
+
+- if (migrate_task(p, cpumask_any_and(cpu_active_mask, new_mask), &req)) {
++ if (migrate_task(p, cpumask_any_and(cpu_online_mask, new_mask), &req)) {
+ /* Need help from migration thread: drop lock and wait. */
+ struct task_struct *mt = rq->migration_thread;
+
+@@ -7249,19 +7231,19 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
+
+ again:
+ /* Look for allowed, online CPU in same node. */
+- for_each_cpu_and(dest_cpu, nodemask, cpu_active_mask)
++ for_each_cpu_and(dest_cpu, nodemask, cpu_online_mask)
+ if (cpumask_test_cpu(dest_cpu, &p->cpus_allowed))
+ goto move;
+
+ /* Any allowed, online CPU? */
+- dest_cpu = cpumask_any_and(&p->cpus_allowed, cpu_active_mask);
++ dest_cpu = cpumask_any_and(&p->cpus_allowed, cpu_online_mask);
+ if (dest_cpu < nr_cpu_ids)
+ goto move;
+
+ /* No more Mr. Nice Guy. */
+ if (dest_cpu >= nr_cpu_ids) {
+ cpuset_cpus_allowed_locked(p, &p->cpus_allowed);
+- dest_cpu = cpumask_any_and(cpu_active_mask, &p->cpus_allowed);
++ dest_cpu = cpumask_any_and(cpu_online_mask, &p->cpus_allowed);
+
+ /*
+ * Don't tell them about moving exiting tasks or
+@@ -7290,7 +7272,7 @@ move:
+ */
+ static void migrate_nr_uninterruptible(struct rq *rq_src)
+ {
+- struct rq *rq_dest = cpu_rq(cpumask_any(cpu_active_mask));
++ struct rq *rq_dest = cpu_rq(cpumask_any(cpu_online_mask));
+ unsigned long flags;
+
+ local_irq_save(flags);
+@@ -7544,7 +7526,7 @@ static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
+ static struct ctl_table_header *sd_sysctl_header;
+ static void register_sched_domain_sysctl(void)
+ {
+- int i, cpu_num = num_possible_cpus();
++ int i, cpu_num = num_online_cpus();
+ struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1);
+ char buf[32];
+
+@@ -7554,7 +7536,7 @@ static void register_sched_domain_sysctl(void)
+ if (entry == NULL)
+ return;
+
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ snprintf(buf, 32, "cpu%d", i);
+ entry->procname = kstrdup(buf, GFP_KERNEL);
+ entry->mode = 0555;
+@@ -7684,6 +7666,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
+ spin_lock_irq(&rq->lock);
+ update_rq_clock(rq);
+ deactivate_task(rq, rq->idle, 0);
++ rq->idle->static_prio = MAX_PRIO;
+ __setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
+ rq->idle->sched_class = &idle_sched_class;
+ migrate_dead_tasks(cpu);
+@@ -7922,8 +7905,6 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent)
+
+ static void free_rootdomain(struct root_domain *rd)
+ {
+- synchronize_sched();
+-
+ cpupri_cleanup(&rd->cpupri);
+
+ free_cpumask_var(rd->rto_mask);
+@@ -8064,7 +8045,6 @@ static cpumask_var_t cpu_isolated_map;
+ /* Setup the mask of cpus configured for isolated domains */
+ static int __init isolated_cpu_setup(char *str)
+ {
+- alloc_bootmem_cpumask_var(&cpu_isolated_map);
+ cpulist_parse(str, cpu_isolated_map);
+ return 1;
+ }
+@@ -9042,7 +9022,7 @@ match1:
+ if (doms_new == NULL) {
+ ndoms_cur = 0;
+ doms_new = fallback_doms;
+- cpumask_andnot(&doms_new[0], cpu_active_mask, cpu_isolated_map);
++ cpumask_andnot(&doms_new[0], cpu_online_mask, cpu_isolated_map);
+ WARN_ON_ONCE(dattr_new);
+ }
+
+@@ -9173,10 +9153,8 @@ static int update_sched_domains(struct notifier_block *nfb,
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+- case CPU_DOWN_PREPARE:
+- case CPU_DOWN_PREPARE_FROZEN:
+- case CPU_DOWN_FAILED:
+- case CPU_DOWN_FAILED_FROZEN:
++ case CPU_DEAD:
++ case CPU_DEAD_FROZEN:
+ partition_sched_domains(1, NULL, NULL);
+ return NOTIFY_OK;
+
+@@ -9223,7 +9201,7 @@ void __init sched_init_smp(void)
+ #endif
+ get_online_cpus();
+ mutex_lock(&sched_domains_mutex);
+- arch_init_sched_domains(cpu_active_mask);
++ arch_init_sched_domains(cpu_online_mask);
+ cpumask_andnot(non_isolated_cpus, cpu_possible_mask, cpu_isolated_map);
+ if (cpumask_empty(non_isolated_cpus))
+ cpumask_set_cpu(smp_processor_id(), non_isolated_cpus);
+@@ -9544,8 +9522,6 @@ void __init sched_init(void)
+ rq->cpu = i;
+ rq->online = 0;
+ rq->migration_thread = NULL;
+- rq->idle_stamp = 0;
+- rq->avg_idle = 2*sysctl_sched_migration_cost;
+ INIT_LIST_HEAD(&rq->migration_queue);
+ rq_attach_root(rq, &def_root_domain);
+ #endif
+@@ -9595,9 +9571,7 @@ void __init sched_init(void)
+ zalloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT);
+ alloc_cpumask_var(&nohz.ilb_grp_nohz_mask, GFP_NOWAIT);
+ #endif
+- /* May be allocated at isolcpus cmdline parse time */
+- if (cpu_isolated_map == NULL)
+- zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
++ zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
+ #endif /* SMP */
+
+ perf_event_init();
+diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
+index 5b49613..479ce56 100644
+--- a/kernel/sched_clock.c
++++ b/kernel/sched_clock.c
+@@ -236,18 +236,6 @@ void sched_clock_idle_wakeup_event(u64 delta_ns)
+ }
+ EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
+
+-unsigned long long cpu_clock(int cpu)
+-{
+- unsigned long long clock;
+- unsigned long flags;
+-
+- local_irq_save(flags);
+- clock = sched_clock_cpu(cpu);
+- local_irq_restore(flags);
+-
+- return clock;
+-}
+-
+ #else /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
+
+ void sched_clock_init(void)
+@@ -263,12 +251,17 @@ u64 sched_clock_cpu(int cpu)
+ return sched_clock();
+ }
+
++#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
+
+ unsigned long long cpu_clock(int cpu)
+ {
+- return sched_clock_cpu(cpu);
+-}
++ unsigned long long clock;
++ unsigned long flags;
+
+-#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
++ local_irq_save(flags);
++ clock = sched_clock_cpu(cpu);
++ local_irq_restore(flags);
+
++ return clock;
++}
+ EXPORT_SYMBOL_GPL(cpu_clock);
+diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
+index 6988cf0..efb8440 100644
+--- a/kernel/sched_debug.c
++++ b/kernel/sched_debug.c
+@@ -285,16 +285,12 @@ static void print_cpu(struct seq_file *m, int cpu)
+
+ #ifdef CONFIG_SCHEDSTATS
+ #define P(n) SEQ_printf(m, " .%-30s: %d\n", #n, rq->n);
+-#define P64(n) SEQ_printf(m, " .%-30s: %Ld\n", #n, rq->n);
+
+ P(yld_count);
+
+ P(sched_switch);
+ P(sched_count);
+ P(sched_goidle);
+-#ifdef CONFIG_SMP
+- P64(avg_idle);
+-#endif
+
+ P(ttwu_count);
+ P(ttwu_local);
+diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
+index d80812d..37087a7 100644
+--- a/kernel/sched_fair.c
++++ b/kernel/sched_fair.c
+@@ -35,14 +35,12 @@
+ * run vmstat and monitor the context-switches (cs) field)
+ */
+ unsigned int sysctl_sched_latency = 5000000ULL;
+-unsigned int normalized_sysctl_sched_latency = 5000000ULL;
+
+ /*
+ * Minimal preemption granularity for CPU-bound tasks:
+ * (default: 1 msec * (1 + ilog(ncpus)), units: nanoseconds)
+ */
+ unsigned int sysctl_sched_min_granularity = 1000000ULL;
+-unsigned int normalized_sysctl_sched_min_granularity = 1000000ULL;
+
+ /*
+ * is kept at sysctl_sched_latency / sysctl_sched_min_granularity
+@@ -72,7 +70,6 @@ unsigned int __read_mostly sysctl_sched_compat_yield;
+ * have immediate wakeup/sleep latencies.
+ */
+ unsigned int sysctl_sched_wakeup_granularity = 1000000UL;
+-unsigned int normalized_sysctl_sched_wakeup_granularity = 1000000UL;
+
+ const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
+
+@@ -1377,9 +1374,6 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
+
+ rcu_read_lock();
+ for_each_domain(cpu, tmp) {
+- if (!(tmp->flags & SD_LOAD_BALANCE))
+- continue;
+-
+ /*
+ * If power savings logic is enabled for a domain, see if we
+ * are not overloaded, if so, don't balance wider.
+@@ -1404,38 +1398,11 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
+ want_sd = 0;
+ }
+
+- if (want_affine && (tmp->flags & SD_WAKE_AFFINE)) {
+- int candidate = -1, i;
+-
+- if (cpumask_test_cpu(prev_cpu, sched_domain_span(tmp)))
+- candidate = cpu;
+-
+- /*
+- * Check for an idle shared cache.
+- */
+- if (tmp->flags & SD_PREFER_SIBLING) {
+- if (candidate == cpu) {
+- if (!cpu_rq(prev_cpu)->cfs.nr_running)
+- candidate = prev_cpu;
+- }
+-
+- if (candidate == -1 || candidate == cpu) {
+- for_each_cpu(i, sched_domain_span(tmp)) {
+- if (!cpumask_test_cpu(i, &p->cpus_allowed))
+- continue;
+- if (!cpu_rq(i)->cfs.nr_running) {
+- candidate = i;
+- break;
+- }
+- }
+- }
+- }
++ if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
++ cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
+
+- if (candidate >= 0) {
+- affine_sd = tmp;
+- want_affine = 0;
+- cpu = candidate;
+- }
++ affine_sd = tmp;
++ want_affine = 0;
+ }
+
+ if (!want_sd && !want_affine)
+@@ -1883,17 +1850,6 @@ move_one_task_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
+
+ return 0;
+ }
+-
+-static void rq_online_fair(struct rq *rq)
+-{
+- update_sysctl();
+-}
+-
+-static void rq_offline_fair(struct rq *rq)
+-{
+- update_sysctl();
+-}
+-
+ #endif /* CONFIG_SMP */
+
+ /*
+@@ -2041,8 +1997,6 @@ static const struct sched_class fair_sched_class = {
+
+ .load_balance = load_balance_fair,
+ .move_one_task = move_one_task_fair,
+- .rq_online = rq_online_fair,
+- .rq_offline = rq_offline_fair,
+ #endif
+
+ .set_curr_task = set_curr_task_fair,
+diff --git a/kernel/signal.c b/kernel/signal.c
+index 4d0658d..6705320 100644
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -939,8 +939,7 @@ static void print_fatal_signal(struct pt_regs *regs, int signr)
+ for (i = 0; i < 16; i++) {
+ unsigned char insn;
+
+- if (get_user(insn, (unsigned char *)(regs->ip + i)))
+- break;
++ __get_user(insn, (unsigned char *)(regs->ip + i));
+ printk("%02x ", insn);
+ }
+ }
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index b8bd058..0d949c5 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -1345,7 +1345,6 @@ static struct ctl_table vm_table[] = {
+ .strategy = &sysctl_jiffies,
+ },
+ #endif
+-#ifdef CONFIG_MMU
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "mmap_min_addr",
+@@ -1354,7 +1353,6 @@ static struct ctl_table vm_table[] = {
+ .mode = 0644,
+ .proc_handler = &mmap_min_addr_handler,
+ },
+-#endif
+ #ifdef CONFIG_NUMA
+ {
+ .ctl_name = CTL_UNNUMBERED,
+@@ -1607,8 +1605,7 @@ static struct ctl_table debug_table[] = {
+ .data = &show_unhandled_signals,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
+- .extra1 = &zero,
++ .proc_handler = proc_dointvec
+ },
+ #endif
+ { .ctl_name = 0 }
+diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
+index 469193c..b6e7aae 100644
+--- a/kernel/sysctl_check.c
++++ b/kernel/sysctl_check.c
+@@ -220,7 +220,6 @@ static const struct trans_ctl_table trans_net_ipv4_conf_vars_table[] = {
+ { NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" },
+ { NET_IPV4_CONF_ARP_ACCEPT, "arp_accept" },
+ { NET_IPV4_CONF_ARP_NOTIFY, "arp_notify" },
+- { NET_IPV4_CONF_SRC_VMARK, "src_valid_mark" },
+ {}
+ };
+
+diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
+index 0d809ae..620b58a 100644
+--- a/kernel/time/clockevents.c
++++ b/kernel/time/clockevents.c
+@@ -20,8 +20,6 @@
+ #include <linux/sysdev.h>
+ #include <linux/tick.h>
+
+-#include "tick-internal.h"
+-
+ /* The registered clock event devices */
+ static LIST_HEAD(clockevent_devices);
+ static LIST_HEAD(clockevents_released);
+@@ -239,9 +237,8 @@ void clockevents_exchange_device(struct clock_event_device *old,
+ */
+ void clockevents_notify(unsigned long reason, void *arg)
+ {
+- struct clock_event_device *dev, *tmp;
++ struct list_head *node, *tmp;
+ unsigned long flags;
+- int cpu;
+
+ spin_lock_irqsave(&clockevents_lock, flags);
+ clockevents_do_notify(reason, arg);
+@@ -252,20 +249,8 @@ void clockevents_notify(unsigned long reason, void *arg)
+ * Unregister the clock event devices which were
+ * released from the users in the notify chain.
+ */
+- list_for_each_entry_safe(dev, tmp, &clockevents_released, list)
+- list_del(&dev->list);
+- /*
+- * Now check whether the CPU has left unused per cpu devices
+- */
+- cpu = *((int *)arg);
+- list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
+- if (cpumask_test_cpu(cpu, dev->cpumask) &&
+- cpumask_weight(dev->cpumask) == 1 &&
+- !tick_is_broadcast_device(dev)) {
+- BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED);
+- list_del(&dev->list);
+- }
+- }
++ list_for_each_safe(node, tmp, &clockevents_released)
++ list_del(node);
+ break;
+ default:
+ break;
+diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
+index ecc7adb..5e18c6a 100644
+--- a/kernel/time/clocksource.c
++++ b/kernel/time/clocksource.c
+@@ -413,47 +413,6 @@ void clocksource_touch_watchdog(void)
+ clocksource_resume_watchdog();
+ }
+
+-/**
+- * clocksource_max_deferment - Returns max time the clocksource can be deferred
+- * @cs: Pointer to clocksource
+- *
+- */
+-static u64 clocksource_max_deferment(struct clocksource *cs)
+-{
+- u64 max_nsecs, max_cycles;
+-
+- /*
+- * Calculate the maximum number of cycles that we can pass to the
+- * cyc2ns function without overflowing a 64-bit signed result. The
+- * maximum number of cycles is equal to ULLONG_MAX/cs->mult which
+- * is equivalent to the below.
+- * max_cycles < (2^63)/cs->mult
+- * max_cycles < 2^(log2((2^63)/cs->mult))
+- * max_cycles < 2^(log2(2^63) - log2(cs->mult))
+- * max_cycles < 2^(63 - log2(cs->mult))
+- * max_cycles < 1 << (63 - log2(cs->mult))
+- * Please note that we add 1 to the result of the log2 to account for
+- * any rounding errors, ensure the above inequality is satisfied and
+- * no overflow will occur.
+- */
+- max_cycles = 1ULL << (63 - (ilog2(cs->mult) + 1));
+-
+- /*
+- * The actual maximum number of cycles we can defer the clocksource is
+- * determined by the minimum of max_cycles and cs->mask.
+- */
+- max_cycles = min_t(u64, max_cycles, (u64) cs->mask);
+- max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult, cs->shift);
+-
+- /*
+- * To ensure that the clocksource does not wrap whilst we are idle,
+- * limit the time the clocksource can be deferred by 12.5%. Please
+- * note a margin of 12.5% is used because this can be computed with
+- * a shift, versus say 10% which would require division.
+- */
+- return max_nsecs - (max_nsecs >> 5);
+-}
+-
+ #ifdef CONFIG_GENERIC_TIME
+
+ /**
+@@ -552,9 +511,6 @@ static void clocksource_enqueue(struct clocksource *cs)
+ */
+ int clocksource_register(struct clocksource *cs)
+ {
+- /* calculate max idle time permitted for this clocksource */
+- cs->max_idle_ns = clocksource_max_deferment(cs);
+-
+ mutex_lock(&clocksource_mutex);
+ clocksource_enqueue(cs);
+ clocksource_select();
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index 44320b1..89aed59 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -216,7 +216,6 @@ void tick_nohz_stop_sched_tick(int inidle)
+ struct tick_sched *ts;
+ ktime_t last_update, expires, now;
+ struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
+- u64 time_delta;
+ int cpu;
+
+ local_irq_save(flags);
+@@ -276,17 +275,6 @@ void tick_nohz_stop_sched_tick(int inidle)
+ seq = read_seqbegin(&xtime_lock);
+ last_update = last_jiffies_update;
+ last_jiffies = jiffies;
+-
+- /*
+- * On SMP we really should only care for the CPU which
+- * has the do_timer duty assigned. All other CPUs can
+- * sleep as long as they want.
+- */
+- if (cpu == tick_do_timer_cpu ||
+- tick_do_timer_cpu == TICK_DO_TIMER_NONE)
+- time_delta = timekeeping_max_deferment();
+- else
+- time_delta = KTIME_MAX;
+ } while (read_seqretry(&xtime_lock, seq));
+
+ /* Get the next timer wheel timer */
+@@ -306,26 +294,11 @@ void tick_nohz_stop_sched_tick(int inidle)
+ if ((long)delta_jiffies >= 1) {
+
+ /*
+- * calculate the expiry time for the next timer wheel
+- * timer. delta_jiffies >= NEXT_TIMER_MAX_DELTA signals
+- * that there is no timer pending or at least extremely
+- * far into the future (12 days for HZ=1000). In this
+- * case we set the expiry to the end of time.
+- */
+- if (likely(delta_jiffies < NEXT_TIMER_MAX_DELTA)) {
+- /*
+- * Calculate the time delta for the next timer event.
+- * If the time delta exceeds the maximum time delta
+- * permitted by the current clocksource then adjust
+- * the time delta accordingly to ensure the
+- * clocksource does not wrap.
+- */
+- time_delta = min_t(u64, time_delta,
+- tick_period.tv64 * delta_jiffies);
+- expires = ktime_add_ns(last_update, time_delta);
+- } else {
+- expires.tv64 = KTIME_MAX;
+- }
++ * calculate the expiry time for the next timer wheel
++ * timer
++ */
++ expires = ktime_add_ns(last_update, tick_period.tv64 *
++ delta_jiffies);
+
+ /*
+ * If this cpu is the one which updates jiffies, then
+@@ -369,19 +342,22 @@ void tick_nohz_stop_sched_tick(int inidle)
+
+ ts->idle_sleeps++;
+
+- /* Mark expires */
+- ts->idle_expires = expires;
+-
+ /*
+- * If the expiration time == KTIME_MAX, then
+- * in this case we simply stop the tick timer.
++ * delta_jiffies >= NEXT_TIMER_MAX_DELTA signals that
++ * there is no timer pending or at least extremly far
++ * into the future (12 days for HZ=1000). In this case
++ * we simply stop the tick timer:
+ */
+- if (unlikely(expires.tv64 == KTIME_MAX)) {
++ if (unlikely(delta_jiffies >= NEXT_TIMER_MAX_DELTA)) {
++ ts->idle_expires.tv64 = KTIME_MAX;
+ if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
+ hrtimer_cancel(&ts->sched_timer);
+ goto out;
+ }
+
++ /* Mark expiries */
++ ts->idle_expires = expires;
++
+ if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
+ hrtimer_start(&ts->sched_timer, expires,
+ HRTIMER_MODE_ABS_PINNED);
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 8b709de..c3a4e29 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -488,17 +488,6 @@ int timekeeping_valid_for_hres(void)
+ }
+
+ /**
+- * timekeeping_max_deferment - Returns max time the clocksource can be deferred
+- *
+- * Caller must observe xtime_lock via read_seqbegin/read_seqretry to
+- * ensure that the clocksource does not change!
+- */
+-u64 timekeeping_max_deferment(void)
+-{
+- return timekeeper.clock->max_idle_ns;
+-}
+-
+-/**
+ * read_persistent_clock - Return time from the persistent clock.
+ *
+ * Weak dummy function for arches that do not yet support it.
+@@ -845,7 +834,6 @@ void getboottime(struct timespec *ts)
+
+ set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec);
+ }
+-EXPORT_SYMBOL_GPL(getboottime);
+
+ /**
+ * monotonic_to_bootbased - Convert the monotonic time to boot based.
+@@ -855,7 +843,6 @@ void monotonic_to_bootbased(struct timespec *ts)
+ {
+ *ts = timespec_add_safe(*ts, total_sleep_time);
+ }
+-EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
+
+ unsigned long get_seconds(void)
+ {
+diff --git a/lib/dma-debug.c b/lib/dma-debug.c
+index 084e879..ce6b7ea 100644
+--- a/lib/dma-debug.c
++++ b/lib/dma-debug.c
+@@ -670,13 +670,12 @@ static int device_dma_allocations(struct device *dev)
+ return count;
+ }
+
+-static int dma_debug_device_change(struct notifier_block *nb, unsigned long action, void *data)
++static int dma_debug_device_change(struct notifier_block *nb,
++ unsigned long action, void *data)
+ {
+ struct device *dev = data;
+ int count;
+
+- if (global_disable)
+- return 0;
+
+ switch (action) {
+ case BUS_NOTIFY_UNBOUND_DRIVER:
+@@ -698,9 +697,6 @@ void dma_debug_add_bus(struct bus_type *bus)
+ {
+ struct notifier_block *nb;
+
+- if (global_disable)
+- return;
+-
+ nb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
+ if (nb == NULL) {
+ pr_err("dma_debug_add_bus: out of memory\n");
+@@ -913,9 +909,6 @@ static void check_sync(struct device *dev,
+ ref->size);
+ }
+
+- if (entry->direction == DMA_BIDIRECTIONAL)
+- goto out;
+-
+ if (ref->direction != entry->direction) {
+ err_printk(dev, entry, "DMA-API: device driver syncs "
+ "DMA memory with different direction "
+@@ -926,6 +919,9 @@ static void check_sync(struct device *dev,
+ dir2name[ref->direction]);
+ }
+
++ if (entry->direction == DMA_BIDIRECTIONAL)
++ goto out;
++
+ if (to_cpu && !(entry->direction == DMA_FROM_DEVICE) &&
+ !(ref->direction == DMA_TO_DEVICE))
+ err_printk(dev, entry, "DMA-API: device driver syncs "
+@@ -948,6 +944,7 @@ static void check_sync(struct device *dev,
+
+ out:
+ put_hash_bucket(bucket, &flags);
++
+ }
+
+ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
+diff --git a/lib/rational.c b/lib/rational.c
+index 3ed247b..b3c099b 100644
+--- a/lib/rational.c
++++ b/lib/rational.c
+@@ -7,7 +7,6 @@
+ */
+
+ #include <linux/rational.h>
+-#include <linux/module.h>
+
+ /*
+ * calculate best rational approximation for a given fraction
+diff --git a/mm/Kconfig b/mm/Kconfig
+index 2c19c0b..44cf6f0 100644
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -227,7 +227,6 @@ config KSM
+
+ config DEFAULT_MMAP_MIN_ADDR
+ int "Low address space to protect from user allocation"
+- depends on MMU
+ default 4096
+ help
+ This is the portion of low virtual memory which should be protected
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 8e96c90..ef169f3 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -1655,15 +1655,14 @@ EXPORT_SYMBOL(generic_file_readonly_mmap);
+ static struct page *__read_cache_page(struct address_space *mapping,
+ pgoff_t index,
+ int (*filler)(void *,struct page*),
+- void *data,
+- gfp_t gfp)
++ void *data)
+ {
+ struct page *page;
+ int err;
+ repeat:
+ page = find_get_page(mapping, index);
+ if (!page) {
+- page = __page_cache_alloc(gfp | __GFP_COLD);
++ page = page_cache_alloc_cold(mapping);
+ if (!page)
+ return ERR_PTR(-ENOMEM);
+ err = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL);
+@@ -1683,18 +1682,31 @@ repeat:
+ return page;
+ }
+
+-static struct page *do_read_cache_page(struct address_space *mapping,
++/**
++ * read_cache_page_async - read into page cache, fill it if needed
++ * @mapping: the page's address_space
++ * @index: the page index
++ * @filler: function to perform the read
++ * @data: destination for read data
++ *
++ * Same as read_cache_page, but don't wait for page to become unlocked
++ * after submitting it to the filler.
++ *
++ * Read into the page cache. If a page already exists, and PageUptodate() is
++ * not set, try to fill the page but don't wait for it to become unlocked.
++ *
++ * If the page does not get brought uptodate, return -EIO.
++ */
++struct page *read_cache_page_async(struct address_space *mapping,
+ pgoff_t index,
+ int (*filler)(void *,struct page*),
+- void *data,
+- gfp_t gfp)
+-
++ void *data)
+ {
+ struct page *page;
+ int err;
+
+ retry:
+- page = __read_cache_page(mapping, index, filler, data, gfp);
++ page = __read_cache_page(mapping, index, filler, data);
+ if (IS_ERR(page))
+ return page;
+ if (PageUptodate(page))
+@@ -1719,67 +1731,8 @@ out:
+ mark_page_accessed(page);
+ return page;
+ }
+-
+-/**
+- * read_cache_page_async - read into page cache, fill it if needed
+- * @mapping: the page's address_space
+- * @index: the page index
+- * @filler: function to perform the read
+- * @data: destination for read data
+- *
+- * Same as read_cache_page, but don't wait for page to become unlocked
+- * after submitting it to the filler.
+- *
+- * Read into the page cache. If a page already exists, and PageUptodate() is
+- * not set, try to fill the page but don't wait for it to become unlocked.
+- *
+- * If the page does not get brought uptodate, return -EIO.
+- */
+-struct page *read_cache_page_async(struct address_space *mapping,
+- pgoff_t index,
+- int (*filler)(void *,struct page*),
+- void *data)
+-{
+- return do_read_cache_page(mapping, index, filler, data, mapping_gfp_mask(mapping));
+-}
+ EXPORT_SYMBOL(read_cache_page_async);
+
+-static struct page *wait_on_page_read(struct page *page)
+-{
+- if (!IS_ERR(page)) {
+- wait_on_page_locked(page);
+- if (!PageUptodate(page)) {
+- page_cache_release(page);
+- page = ERR_PTR(-EIO);
+- }
+- }
+- return page;
+-}
+-
+-/**
+- * read_cache_page_gfp - read into page cache, using specified page allocation flags.
+- * @mapping: the page's address_space
+- * @index: the page index
+- * @gfp: the page allocator flags to use if allocating
+- *
+- * This is the same as "read_mapping_page(mapping, index, NULL)", but with
+- * any new page allocations done using the specified allocation flags. Note
+- * that the Radix tree operations will still use GFP_KERNEL, so you can't
+- * expect to do this atomically or anything like that - but you can pass in
+- * other page requirements.
+- *
+- * If the page does not get brought uptodate, return -EIO.
+- */
+-struct page *read_cache_page_gfp(struct address_space *mapping,
+- pgoff_t index,
+- gfp_t gfp)
+-{
+- filler_t *filler = (filler_t *)mapping->a_ops->readpage;
+-
+- return wait_on_page_read(do_read_cache_page(mapping, index, filler, NULL, gfp));
+-}
+-EXPORT_SYMBOL(read_cache_page_gfp);
+-
+ /**
+ * read_cache_page - read into page cache, fill it if needed
+ * @mapping: the page's address_space
+@@ -1797,7 +1750,18 @@ struct page *read_cache_page(struct address_space *mapping,
+ int (*filler)(void *,struct page*),
+ void *data)
+ {
+- return wait_on_page_read(read_cache_page_async(mapping, index, filler, data));
++ struct page *page;
++
++ page = read_cache_page_async(mapping, index, filler, data);
++ if (IS_ERR(page))
++ goto out;
++ wait_on_page_locked(page);
++ if (!PageUptodate(page)) {
++ page_cache_release(page);
++ page = ERR_PTR(-EIO);
++ }
++ out:
++ return page;
+ }
+ EXPORT_SYMBOL(read_cache_page);
+
+@@ -2253,9 +2217,6 @@ again:
+ if (unlikely(status))
+ break;
+
+- if (mapping_writably_mapped(mapping))
+- flush_dcache_page(page);
+-
+ pagefault_disable();
+ copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
+ pagefault_enable();
+diff --git a/mm/internal.h b/mm/internal.h
+index 17bc0df..22ec8d2 100644
+--- a/mm/internal.h
++++ b/mm/internal.h
+@@ -107,10 +107,9 @@ static inline int is_mlocked_vma(struct vm_area_struct *vma, struct page *page)
+ }
+
+ /*
+- * must be called with vma's mmap_sem held for read or write, and page locked.
++ * must be called with vma's mmap_sem held for read, and page locked.
+ */
+ extern void mlock_vma_page(struct page *page);
+-extern void munlock_vma_page(struct page *page);
+
+ /*
+ * Clear the page's PageMlocked(). This can be useful in a situation where
+diff --git a/mm/ksm.c b/mm/ksm.c
+index e9501f8..5575f86 100644
+--- a/mm/ksm.c
++++ b/mm/ksm.c
+@@ -34,7 +34,6 @@
+ #include <linux/ksm.h>
+
+ #include <asm/tlbflush.h>
+-#include "internal.h"
+
+ /*
+ * A few notes about the KSM scanning process,
+@@ -768,14 +767,15 @@ static int try_to_merge_one_page(struct vm_area_struct *vma,
+ * ptes are necessarily already write-protected. But in either
+ * case, we need to lock and check page_count is not raised.
+ */
+- if (write_protect_page(vma, oldpage, &orig_pte) == 0 &&
+- pages_identical(oldpage, newpage))
+- err = replace_page(vma, oldpage, newpage, orig_pte);
++ if (write_protect_page(vma, oldpage, &orig_pte)) {
++ unlock_page(oldpage);
++ goto out_putpage;
++ }
++ unlock_page(oldpage);
+
+- if ((vma->vm_flags & VM_LOCKED) && !err)
+- munlock_vma_page(oldpage);
++ if (pages_identical(oldpage, newpage))
++ err = replace_page(vma, oldpage, newpage, orig_pte);
+
+- unlock_page(oldpage);
+ out_putpage:
+ put_page(oldpage);
+ put_page(newpage);
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index 66035bf..f99f599 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -758,13 +758,7 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem)
+ task_unlock(task);
+ if (!curr)
+ return 0;
+- /*
+- * We should check use_hierarchy of "mem" not "curr". Because checking
+- * use_hierarchy of "curr" here make this function true if hierarchy is
+- * enabled in "curr" and "curr" is a child of "mem" in *cgroup*
+- * hierarchy(even if use_hierarchy is disabled in "mem").
+- */
+- if (mem->use_hierarchy)
++ if (curr->use_hierarchy)
+ ret = css_is_ancestor(&curr->css, &mem->css);
+ else
+ ret = (curr == mem);
+@@ -2381,7 +2375,7 @@ static int mem_cgroup_force_empty(struct mem_cgroup *mem, bool free_all)
+ if (free_all)
+ goto try_to_free;
+ move_account:
+- do {
++ while (mem->res.usage > 0) {
+ ret = -EBUSY;
+ if (cgroup_task_count(cgrp) || !list_empty(&cgrp->children))
+ goto out;
+@@ -2408,8 +2402,8 @@ move_account:
+ if (ret == -ENOMEM)
+ goto try_to_free;
+ cond_resched();
+- /* "ret" should also be checked to ensure all lists are empty. */
+- } while (mem->res.usage > 0 || ret);
++ }
++ ret = 0;
+ out:
+ css_put(&mem->css);
+ return ret;
+@@ -2442,7 +2436,10 @@ try_to_free:
+ }
+ lru_add_drain();
+ /* try move_account...there may be some *locked* pages. */
+- goto move_account;
++ if (mem->res.usage)
++ goto move_account;
++ ret = 0;
++ goto out;
+ }
+
+ int mem_cgroup_force_empty_write(struct cgroup *cont, unsigned int event)
+@@ -2544,7 +2541,6 @@ static u64 mem_cgroup_read(struct cgroup *cont, struct cftype *cft)
+ val += idx_val;
+ mem_cgroup_get_recursive_idx_stat(mem,
+ MEM_CGROUP_STAT_SWAPOUT, &idx_val);
+- val += idx_val;
+ val <<= PAGE_SHIFT;
+ } else
+ val = res_counter_read_u64(&mem->memsw, name);
+diff --git a/mm/memory.c b/mm/memory.c
+index 4e59455..6ab19dd 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2514,7 +2514,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ ret = VM_FAULT_HWPOISON;
+ } else {
+ print_bad_pte(vma, address, orig_pte, NULL);
+- ret = VM_FAULT_SIGBUS;
++ ret = VM_FAULT_OOM;
+ }
+ goto out;
+ }
+@@ -2910,7 +2910,7 @@ static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+ * Page table corrupted: show pte and kill process.
+ */
+ print_bad_pte(vma, address, orig_pte, NULL);
+- return VM_FAULT_SIGBUS;
++ return VM_FAULT_OOM;
+ }
+
+ pgoff = pte_to_pgoff(orig_pte);
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 0e39f94..7dbcb22 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -953,9 +953,6 @@ static int do_pages_move(struct mm_struct *mm, struct task_struct *task,
+ goto out_pm;
+
+ err = -ENODEV;
+- if (node < 0 || node >= MAX_NUMNODES)
+- goto out_pm;
+-
+ if (!node_state(node, N_HIGH_MEMORY))
+ goto out_pm;
+
+diff --git a/mm/mincore.c b/mm/mincore.c
+index 7a3436e..8cb508f 100644
+--- a/mm/mincore.c
++++ b/mm/mincore.c
+@@ -14,7 +14,6 @@
+ #include <linux/syscalls.h>
+ #include <linux/swap.h>
+ #include <linux/swapops.h>
+-#include <linux/hugetlb.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -73,42 +72,6 @@ static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pag
+ if (!vma || addr < vma->vm_start)
+ return -ENOMEM;
+
+-#ifdef CONFIG_HUGETLB_PAGE
+- if (is_vm_hugetlb_page(vma)) {
+- struct hstate *h;
+- unsigned long nr_huge;
+- unsigned char present;
+-
+- i = 0;
+- nr = min(pages, (vma->vm_end - addr) >> PAGE_SHIFT);
+- h = hstate_vma(vma);
+- nr_huge = ((addr + pages * PAGE_SIZE - 1) >> huge_page_shift(h))
+- - (addr >> huge_page_shift(h)) + 1;
+- nr_huge = min(nr_huge,
+- (vma->vm_end - addr) >> huge_page_shift(h));
+- while (1) {
+- /* hugepage always in RAM for now,
+- * but generally it needs to be check */
+- ptep = huge_pte_offset(current->mm,
+- addr & huge_page_mask(h));
+- present = !!(ptep &&
+- !huge_pte_none(huge_ptep_get(ptep)));
+- while (1) {
+- vec[i++] = present;
+- addr += PAGE_SIZE;
+- /* reach buffer limit */
+- if (i == nr)
+- return nr;
+- /* check hugepage border */
+- if (!((addr & ~huge_page_mask(h))
+- >> PAGE_SHIFT))
+- break;
+- }
+- }
+- return nr;
+- }
+-#endif
+-
+ /*
+ * Calculate how many pages there are left in the last level of the
+ * PTE array for our address.
+diff --git a/mm/mlock.c b/mm/mlock.c
+index 2e05c97..bd6f0e4 100644
+--- a/mm/mlock.c
++++ b/mm/mlock.c
+@@ -99,14 +99,14 @@ void mlock_vma_page(struct page *page)
+ * not get another chance to clear PageMlocked. If we successfully
+ * isolate the page and try_to_munlock() detects other VM_LOCKED vmas
+ * mapping the page, it will restore the PageMlocked state, unless the page
+- * is mapped in a non-linear vma. So, we go ahead and ClearPageMlocked(),
++ * is mapped in a non-linear vma. So, we go ahead and SetPageMlocked(),
+ * perhaps redundantly.
+ * If we lose the isolation race, and the page is mapped by other VM_LOCKED
+ * vmas, we'll detect this in vmscan--via try_to_munlock() or try_to_unmap()
+ * either of which will restore the PageMlocked state by calling
+ * mlock_vma_page() above, if it can grab the vma's mmap sem.
+ */
+-void munlock_vma_page(struct page *page)
++static void munlock_vma_page(struct page *page)
+ {
+ BUG_ON(!PageLocked(page));
+
+diff --git a/mm/mmap.c b/mm/mmap.c
+index ae19746..73f5e4b 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -932,9 +932,13 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
+ if (!(flags & MAP_FIXED))
+ addr = round_hint_to_min(addr);
+
++ error = arch_mmap_check(addr, len, flags);
++ if (error)
++ return error;
++
+ /* Careful about overflows.. */
+ len = PAGE_ALIGN(len);
+- if (!len)
++ if (!len || len > TASK_SIZE)
+ return -ENOMEM;
+
+ /* offset overflow? */
+@@ -945,6 +949,24 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
+ if (mm->map_count > sysctl_max_map_count)
+ return -ENOMEM;
+
++ if (flags & MAP_HUGETLB) {
++ struct user_struct *user = NULL;
++ if (file)
++ return -EINVAL;
++
++ /*
++ * VM_NORESERVE is used because the reservations will be
++ * taken when vm_ops->mmap() is called
++ * A dummy user value is used because we are not locking
++ * memory so no accounting is necessary
++ */
++ len = ALIGN(len, huge_page_size(&default_hstate));
++ file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE,
++ &user, HUGETLB_ANONHUGE_INODE);
++ if (IS_ERR(file))
++ return PTR_ERR(file);
++ }
++
+ /* Obtain the address to map to. we verify (or select) it and ensure
+ * that it represents a valid section of the address space.
+ */
+@@ -1437,14 +1459,6 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
+ unsigned long (*get_area)(struct file *, unsigned long,
+ unsigned long, unsigned long, unsigned long);
+
+- unsigned long error = arch_mmap_check(addr, len, flags);
+- if (error)
+- return error;
+-
+- /* Careful about overflows.. */
+- if (len > TASK_SIZE)
+- return -ENOMEM;
+-
+ get_area = current->mm->get_unmapped_area;
+ if (file && file->f_op && file->f_op->get_unmapped_area)
+ get_area = file->f_op->get_unmapped_area;
+@@ -1989,14 +2003,20 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
+ if (!len)
+ return addr;
+
++ if ((addr + len) > TASK_SIZE || (addr + len) < addr)
++ return -EINVAL;
++
++ if (is_hugepage_only_range(mm, addr, len))
++ return -EINVAL;
++
+ error = security_file_mmap(NULL, 0, 0, 0, addr, 1);
+ if (error)
+ return error;
+
+ flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
+
+- error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);
+- if (error & ~PAGE_MASK)
++ error = arch_mmap_check(addr, len, flags);
++ if (error)
+ return error;
+
+ /*
+diff --git a/mm/mremap.c b/mm/mremap.c
+index 8451908..97bff25 100644
+--- a/mm/mremap.c
++++ b/mm/mremap.c
+@@ -261,137 +261,6 @@ static unsigned long move_vma(struct vm_area_struct *vma,
+ return new_addr;
+ }
+
+-static struct vm_area_struct *vma_to_resize(unsigned long addr,
+- unsigned long old_len, unsigned long new_len, unsigned long *p)
+-{
+- struct mm_struct *mm = current->mm;
+- struct vm_area_struct *vma = find_vma(mm, addr);
+-
+- if (!vma || vma->vm_start > addr)
+- goto Efault;
+-
+- if (is_vm_hugetlb_page(vma))
+- goto Einval;
+-
+- /* We can't remap across vm area boundaries */
+- if (old_len > vma->vm_end - addr)
+- goto Efault;
+-
+- if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) {
+- if (new_len > old_len)
+- goto Efault;
+- }
+-
+- if (vma->vm_flags & VM_LOCKED) {
+- unsigned long locked, lock_limit;
+- locked = mm->locked_vm << PAGE_SHIFT;
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+- locked += new_len - old_len;
+- if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+- goto Eagain;
+- }
+-
+- if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT))
+- goto Enomem;
+-
+- if (vma->vm_flags & VM_ACCOUNT) {
+- unsigned long charged = (new_len - old_len) >> PAGE_SHIFT;
+- if (security_vm_enough_memory(charged))
+- goto Efault;
+- *p = charged;
+- }
+-
+- return vma;
+-
+-Efault: /* very odd choice for most of the cases, but... */
+- return ERR_PTR(-EFAULT);
+-Einval:
+- return ERR_PTR(-EINVAL);
+-Enomem:
+- return ERR_PTR(-ENOMEM);
+-Eagain:
+- return ERR_PTR(-EAGAIN);
+-}
+-
+-static unsigned long mremap_to(unsigned long addr,
+- unsigned long old_len, unsigned long new_addr,
+- unsigned long new_len)
+-{
+- struct mm_struct *mm = current->mm;
+- struct vm_area_struct *vma;
+- unsigned long ret = -EINVAL;
+- unsigned long charged = 0;
+- unsigned long map_flags;
+-
+- if (new_addr & ~PAGE_MASK)
+- goto out;
+-
+- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
+- goto out;
+-
+- /* Check if the location we're moving into overlaps the
+- * old location at all, and fail if it does.
+- */
+- if ((new_addr <= addr) && (new_addr+new_len) > addr)
+- goto out;
+-
+- if ((addr <= new_addr) && (addr+old_len) > new_addr)
+- goto out;
+-
+- ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
+- if (ret)
+- goto out;
+-
+- ret = do_munmap(mm, new_addr, new_len);
+- if (ret)
+- goto out;
+-
+- if (old_len >= new_len) {
+- ret = do_munmap(mm, addr+new_len, old_len - new_len);
+- if (ret && old_len != new_len)
+- goto out;
+- old_len = new_len;
+- }
+-
+- vma = vma_to_resize(addr, old_len, new_len, &charged);
+- if (IS_ERR(vma)) {
+- ret = PTR_ERR(vma);
+- goto out;
+- }
+-
+- map_flags = MAP_FIXED;
+- if (vma->vm_flags & VM_MAYSHARE)
+- map_flags |= MAP_SHARED;
+-
+- ret = get_unmapped_area(vma->vm_file, new_addr, new_len, vma->vm_pgoff +
+- ((addr - vma->vm_start) >> PAGE_SHIFT),
+- map_flags);
+- if (ret & ~PAGE_MASK)
+- goto out1;
+-
+- ret = move_vma(vma, addr, old_len, new_len, new_addr);
+- if (!(ret & ~PAGE_MASK))
+- goto out;
+-out1:
+- vm_unacct_memory(charged);
+-
+-out:
+- return ret;
+-}
+-
+-static int vma_expandable(struct vm_area_struct *vma, unsigned long delta)
+-{
+- unsigned long end = vma->vm_end + delta;
+- if (end < vma->vm_end) /* overflow */
+- return 0;
+- if (vma->vm_next && vma->vm_next->vm_start < end) /* intersection */
+- return 0;
+- if (get_unmapped_area(NULL, vma->vm_start, end - vma->vm_start,
+- 0, MAP_FIXED) & ~PAGE_MASK)
+- return 0;
+- return 1;
+-}
+-
+ /*
+ * Expand (or shrink) an existing mapping, potentially moving it at the
+ * same time (controlled by the MREMAP_MAYMOVE flag and available VM space)
+@@ -425,10 +294,32 @@ unsigned long do_mremap(unsigned long addr,
+ if (!new_len)
+ goto out;
+
++ /* new_addr is only valid if MREMAP_FIXED is specified */
+ if (flags & MREMAP_FIXED) {
+- if (flags & MREMAP_MAYMOVE)
+- ret = mremap_to(addr, old_len, new_addr, new_len);
+- goto out;
++ if (new_addr & ~PAGE_MASK)
++ goto out;
++ if (!(flags & MREMAP_MAYMOVE))
++ goto out;
++
++ if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
++ goto out;
++
++ /* Check if the location we're moving into overlaps the
++ * old location at all, and fail if it does.
++ */
++ if ((new_addr <= addr) && (new_addr+new_len) > addr)
++ goto out;
++
++ if ((addr <= new_addr) && (addr+old_len) > new_addr)
++ goto out;
++
++ ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
++ if (ret)
++ goto out;
++
++ ret = do_munmap(mm, new_addr, new_len);
++ if (ret)
++ goto out;
+ }
+
+ /*
+@@ -441,23 +332,60 @@ unsigned long do_mremap(unsigned long addr,
+ if (ret && old_len != new_len)
+ goto out;
+ ret = addr;
+- goto out;
++ if (!(flags & MREMAP_FIXED) || (new_addr == addr))
++ goto out;
++ old_len = new_len;
+ }
+
+ /*
+- * Ok, we need to grow..
++ * Ok, we need to grow.. or relocate.
+ */
+- vma = vma_to_resize(addr, old_len, new_len, &charged);
+- if (IS_ERR(vma)) {
+- ret = PTR_ERR(vma);
++ ret = -EFAULT;
++ vma = find_vma(mm, addr);
++ if (!vma || vma->vm_start > addr)
++ goto out;
++ if (is_vm_hugetlb_page(vma)) {
++ ret = -EINVAL;
++ goto out;
++ }
++ /* We can't remap across vm area boundaries */
++ if (old_len > vma->vm_end - addr)
++ goto out;
++ if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) {
++ if (new_len > old_len)
++ goto out;
++ }
++ if (vma->vm_flags & VM_LOCKED) {
++ unsigned long locked, lock_limit;
++ locked = mm->locked_vm << PAGE_SHIFT;
++ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ locked += new_len - old_len;
++ ret = -EAGAIN;
++ if (locked > lock_limit && !capable(CAP_IPC_LOCK))
++ goto out;
++ }
++ if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
++ ret = -ENOMEM;
+ goto out;
+ }
+
++ if (vma->vm_flags & VM_ACCOUNT) {
++ charged = (new_len - old_len) >> PAGE_SHIFT;
++ if (security_vm_enough_memory(charged))
++ goto out_nc;
++ }
++
+ /* old_len exactly to the end of the area..
++ * And we're not relocating the area.
+ */
+- if (old_len == vma->vm_end - addr) {
++ if (old_len == vma->vm_end - addr &&
++ !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
++ (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
++ unsigned long max_addr = TASK_SIZE;
++ if (vma->vm_next)
++ max_addr = vma->vm_next->vm_start;
+ /* can we just expand the current mapping? */
+- if (vma_expandable(vma, new_len - old_len)) {
++ if (max_addr - addr >= new_len) {
+ int pages = (new_len - old_len) >> PAGE_SHIFT;
+
+ vma_adjust(vma, vma->vm_start,
+@@ -481,27 +409,28 @@ unsigned long do_mremap(unsigned long addr,
+ */
+ ret = -ENOMEM;
+ if (flags & MREMAP_MAYMOVE) {
+- unsigned long map_flags = 0;
+- if (vma->vm_flags & VM_MAYSHARE)
+- map_flags |= MAP_SHARED;
+-
+- new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
+- vma->vm_pgoff +
+- ((addr - vma->vm_start) >> PAGE_SHIFT),
+- map_flags);
+- if (new_addr & ~PAGE_MASK) {
+- ret = new_addr;
+- goto out;
+- }
++ if (!(flags & MREMAP_FIXED)) {
++ unsigned long map_flags = 0;
++ if (vma->vm_flags & VM_MAYSHARE)
++ map_flags |= MAP_SHARED;
++
++ new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
++ vma->vm_pgoff, map_flags);
++ if (new_addr & ~PAGE_MASK) {
++ ret = new_addr;
++ goto out;
++ }
+
+- ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
+- if (ret)
+- goto out;
++ ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
++ if (ret)
++ goto out;
++ }
+ ret = move_vma(vma, addr, old_len, new_len, new_addr);
+ }
+ out:
+ if (ret & ~PAGE_MASK)
+ vm_unacct_memory(charged);
++out_nc:
+ return ret;
+ }
+
+diff --git a/mm/oom_kill.c b/mm/oom_kill.c
+index 9092b43..ea2147d 100644
+--- a/mm/oom_kill.c
++++ b/mm/oom_kill.c
+@@ -404,7 +404,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
+ cpuset_print_task_mems_allowed(current);
+ task_unlock(current);
+ dump_stack();
+- mem_cgroup_print_oom_info(mem, p);
++ mem_cgroup_print_oom_info(mem, current);
+ show_mem();
+ if (sysctl_oom_dump_tasks)
+ dump_tasks(mem);
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 36992b6..2bc2ac6 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -559,9 +559,8 @@ static void free_pcppages_bulk(struct zone *zone, int count,
+ page = list_entry(list->prev, struct page, lru);
+ /* must delete as __free_one_page list manipulates */
+ list_del(&page->lru);
+- /* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */
+- __free_one_page(page, zone, 0, page_private(page));
+- trace_mm_page_pcpu_drain(page, 0, page_private(page));
++ __free_one_page(page, zone, 0, migratetype);
++ trace_mm_page_pcpu_drain(page, 0, migratetype);
+ } while (--count && --batch_free && !list_empty(list));
+ }
+ spin_unlock(&zone->lock);
+@@ -1226,10 +1225,10 @@ again:
+ }
+ spin_lock_irqsave(&zone->lock, flags);
+ page = __rmqueue(zone, order, migratetype);
++ __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
+ spin_unlock(&zone->lock);
+ if (!page)
+ goto failed;
+- __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
+ }
+
+ __count_zone_vm_events(PGALLOC, zone, 1 << order);
+diff --git a/mm/pagewalk.c b/mm/pagewalk.c
+index a286915..d5878be 100644
+--- a/mm/pagewalk.c
++++ b/mm/pagewalk.c
+@@ -1,7 +1,6 @@
+ #include <linux/mm.h>
+ #include <linux/highmem.h>
+ #include <linux/sched.h>
+-#include <linux/hugetlb.h>
+
+ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
+ struct mm_walk *walk)
+@@ -108,7 +107,6 @@ int walk_page_range(unsigned long addr, unsigned long end,
+ pgd_t *pgd;
+ unsigned long next;
+ int err = 0;
+- struct vm_area_struct *vma;
+
+ if (addr >= end)
+ return err;
+@@ -119,22 +117,11 @@ int walk_page_range(unsigned long addr, unsigned long end,
+ pgd = pgd_offset(walk->mm, addr);
+ do {
+ next = pgd_addr_end(addr, end);
+-
+- /* skip hugetlb vma to avoid hugepage PMD being cleared
+- * in pmd_none_or_clear_bad(). */
+- vma = find_vma(walk->mm, addr);
+- if (vma && is_vm_hugetlb_page(vma)) {
+- if (vma->vm_end < next)
+- next = vma->vm_end;
+- continue;
+- }
+-
+ if (pgd_none_or_clear_bad(pgd)) {
+ if (walk->pte_hole)
+ err = walk->pte_hole(addr, next, walk);
+ if (err)
+ break;
+- pgd++;
+ continue;
+ }
+ if (walk->pgd_entry)
+@@ -144,8 +131,7 @@ int walk_page_range(unsigned long addr, unsigned long end,
+ err = walk_pud_range(pgd, addr, next, walk);
+ if (err)
+ break;
+- pgd++;
+- } while (addr = next, addr != end);
++ } while (pgd++, addr = next, addr != end);
+
+ return err;
+ }
+diff --git a/mm/truncate.c b/mm/truncate.c
+index 258bda7..450cebd 100644
+--- a/mm/truncate.c
++++ b/mm/truncate.c
+@@ -516,20 +516,22 @@ EXPORT_SYMBOL_GPL(invalidate_inode_pages2);
+ */
+ void truncate_pagecache(struct inode *inode, loff_t old, loff_t new)
+ {
+- struct address_space *mapping = inode->i_mapping;
+-
+- /*
+- * unmap_mapping_range is called twice, first simply for
+- * efficiency so that truncate_inode_pages does fewer
+- * single-page unmaps. However after this first call, and
+- * before truncate_inode_pages finishes, it is possible for
+- * private pages to be COWed, which remain after
+- * truncate_inode_pages finishes, hence the second
+- * unmap_mapping_range call must be made for correctness.
+- */
+- unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1);
+- truncate_inode_pages(mapping, new);
+- unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1);
++ if (new < old) {
++ struct address_space *mapping = inode->i_mapping;
++
++ /*
++ * unmap_mapping_range is called twice, first simply for
++ * efficiency so that truncate_inode_pages does fewer
++ * single-page unmaps. However after this first call, and
++ * before truncate_inode_pages finishes, it is possible for
++ * private pages to be COWed, which remain after
++ * truncate_inode_pages finishes, hence the second
++ * unmap_mapping_range call must be made for correctness.
++ */
++ unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1);
++ truncate_inode_pages(mapping, new);
++ unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1);
++ }
+ }
+ EXPORT_SYMBOL(truncate_pagecache);
+
+diff --git a/mm/util.c b/mm/util.c
+index b377ce4..7c35ad9 100644
+--- a/mm/util.c
++++ b/mm/util.c
+@@ -4,10 +4,6 @@
+ #include <linux/module.h>
+ #include <linux/err.h>
+ #include <linux/sched.h>
+-#include <linux/hugetlb.h>
+-#include <linux/syscalls.h>
+-#include <linux/mman.h>
+-#include <linux/file.h>
+ #include <asm/uaccess.h>
+
+ #define CREATE_TRACE_POINTS
+@@ -272,46 +268,6 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start,
+ }
+ EXPORT_SYMBOL_GPL(get_user_pages_fast);
+
+-SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
+- unsigned long, prot, unsigned long, flags,
+- unsigned long, fd, unsigned long, pgoff)
+-{
+- struct file * file = NULL;
+- unsigned long retval = -EBADF;
+-
+- if (!(flags & MAP_ANONYMOUS)) {
+- if (unlikely(flags & MAP_HUGETLB))
+- return -EINVAL;
+- file = fget(fd);
+- if (!file)
+- goto out;
+- } else if (flags & MAP_HUGETLB) {
+- struct user_struct *user = NULL;
+- /*
+- * VM_NORESERVE is used because the reservations will be
+- * taken when vm_ops->mmap() is called
+- * A dummy user value is used because we are not locking
+- * memory so no accounting is necessary
+- */
+- len = ALIGN(len, huge_page_size(&default_hstate));
+- file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE,
+- &user, HUGETLB_ANONHUGE_INODE);
+- if (IS_ERR(file))
+- return PTR_ERR(file);
+- }
+-
+- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+-
+- down_write(¤t->mm->mmap_sem);
+- retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+- up_write(¤t->mm->mmap_sem);
+-
+- if (file)
+- fput(file);
+-out:
+- return retval;
+-}
+-
+ /* Tracepoints definitions. */
+ EXPORT_TRACEPOINT_SYMBOL(kmalloc);
+ EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc);
+diff --git a/mm/vmalloc.c b/mm/vmalloc.c
+index c228731..0f551a4 100644
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -509,9 +509,6 @@ static unsigned long lazy_max_pages(void)
+
+ static atomic_t vmap_lazy_nr = ATOMIC_INIT(0);
+
+-/* for per-CPU blocks */
+-static void purge_fragmented_blocks_allcpus(void);
+-
+ /*
+ * Purges all lazily-freed vmap areas.
+ *
+@@ -542,9 +539,6 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end,
+ } else
+ spin_lock(&purge_lock);
+
+- if (sync)
+- purge_fragmented_blocks_allcpus();
+-
+ rcu_read_lock();
+ list_for_each_entry_rcu(va, &vmap_area_list, list) {
+ if (va->flags & VM_LAZY_FREE) {
+@@ -561,8 +555,10 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end,
+ }
+ rcu_read_unlock();
+
+- if (nr)
++ if (nr) {
++ BUG_ON(nr > atomic_read(&vmap_lazy_nr));
+ atomic_sub(nr, &vmap_lazy_nr);
++ }
+
+ if (nr || force_flush)
+ flush_tlb_kernel_range(*start, *end);
+@@ -673,6 +669,8 @@ static bool vmap_initialized __read_mostly = false;
+ struct vmap_block_queue {
+ spinlock_t lock;
+ struct list_head free;
++ struct list_head dirty;
++ unsigned int nr_dirty;
+ };
+
+ struct vmap_block {
+@@ -682,9 +680,10 @@ struct vmap_block {
+ unsigned long free, dirty;
+ DECLARE_BITMAP(alloc_map, VMAP_BBMAP_BITS);
+ DECLARE_BITMAP(dirty_map, VMAP_BBMAP_BITS);
+- struct list_head free_list;
+- struct rcu_head rcu_head;
+- struct list_head purge;
++ union {
++ struct list_head free_list;
++ struct rcu_head rcu_head;
++ };
+ };
+
+ /* Queue of free and dirty vmap blocks, for allocation and flushing purposes */
+@@ -760,7 +759,7 @@ static struct vmap_block *new_vmap_block(gfp_t gfp_mask)
+ vbq = &get_cpu_var(vmap_block_queue);
+ vb->vbq = vbq;
+ spin_lock(&vbq->lock);
+- list_add_rcu(&vb->free_list, &vbq->free);
++ list_add(&vb->free_list, &vbq->free);
+ spin_unlock(&vbq->lock);
+ put_cpu_var(vmap_cpu_blocks);
+
+@@ -779,6 +778,8 @@ static void free_vmap_block(struct vmap_block *vb)
+ struct vmap_block *tmp;
+ unsigned long vb_idx;
+
++ BUG_ON(!list_empty(&vb->free_list));
++
+ vb_idx = addr_to_vb_idx(vb->va->va_start);
+ spin_lock(&vmap_block_tree_lock);
+ tmp = radix_tree_delete(&vmap_block_tree, vb_idx);
+@@ -789,61 +790,12 @@ static void free_vmap_block(struct vmap_block *vb)
+ call_rcu(&vb->rcu_head, rcu_free_vb);
+ }
+
+-static void purge_fragmented_blocks(int cpu)
+-{
+- LIST_HEAD(purge);
+- struct vmap_block *vb;
+- struct vmap_block *n_vb;
+- struct vmap_block_queue *vbq = &per_cpu(vmap_block_queue, cpu);
+-
+- rcu_read_lock();
+- list_for_each_entry_rcu(vb, &vbq->free, free_list) {
+-
+- if (!(vb->free + vb->dirty == VMAP_BBMAP_BITS && vb->dirty != VMAP_BBMAP_BITS))
+- continue;
+-
+- spin_lock(&vb->lock);
+- if (vb->free + vb->dirty == VMAP_BBMAP_BITS && vb->dirty != VMAP_BBMAP_BITS) {
+- vb->free = 0; /* prevent further allocs after releasing lock */
+- vb->dirty = VMAP_BBMAP_BITS; /* prevent purging it again */
+- bitmap_fill(vb->alloc_map, VMAP_BBMAP_BITS);
+- bitmap_fill(vb->dirty_map, VMAP_BBMAP_BITS);
+- spin_lock(&vbq->lock);
+- list_del_rcu(&vb->free_list);
+- spin_unlock(&vbq->lock);
+- spin_unlock(&vb->lock);
+- list_add_tail(&vb->purge, &purge);
+- } else
+- spin_unlock(&vb->lock);
+- }
+- rcu_read_unlock();
+-
+- list_for_each_entry_safe(vb, n_vb, &purge, purge) {
+- list_del(&vb->purge);
+- free_vmap_block(vb);
+- }
+-}
+-
+-static void purge_fragmented_blocks_thiscpu(void)
+-{
+- purge_fragmented_blocks(smp_processor_id());
+-}
+-
+-static void purge_fragmented_blocks_allcpus(void)
+-{
+- int cpu;
+-
+- for_each_possible_cpu(cpu)
+- purge_fragmented_blocks(cpu);
+-}
+-
+ static void *vb_alloc(unsigned long size, gfp_t gfp_mask)
+ {
+ struct vmap_block_queue *vbq;
+ struct vmap_block *vb;
+ unsigned long addr = 0;
+ unsigned int order;
+- int purge = 0;
+
+ BUG_ON(size & ~PAGE_MASK);
+ BUG_ON(size > PAGE_SIZE*VMAP_MAX_ALLOC);
+@@ -856,37 +808,24 @@ again:
+ int i;
+
+ spin_lock(&vb->lock);
+- if (vb->free < 1UL << order)
+- goto next;
+ i = bitmap_find_free_region(vb->alloc_map,
+ VMAP_BBMAP_BITS, order);
+
+- if (i < 0) {
+- if (vb->free + vb->dirty == VMAP_BBMAP_BITS) {
+- /* fragmented and no outstanding allocations */
+- BUG_ON(vb->dirty != VMAP_BBMAP_BITS);
+- purge = 1;
++ if (i >= 0) {
++ addr = vb->va->va_start + (i << PAGE_SHIFT);
++ BUG_ON(addr_to_vb_idx(addr) !=
++ addr_to_vb_idx(vb->va->va_start));
++ vb->free -= 1UL << order;
++ if (vb->free == 0) {
++ spin_lock(&vbq->lock);
++ list_del_init(&vb->free_list);
++ spin_unlock(&vbq->lock);
+ }
+- goto next;
+- }
+- addr = vb->va->va_start + (i << PAGE_SHIFT);
+- BUG_ON(addr_to_vb_idx(addr) !=
+- addr_to_vb_idx(vb->va->va_start));
+- vb->free -= 1UL << order;
+- if (vb->free == 0) {
+- spin_lock(&vbq->lock);
+- list_del_rcu(&vb->free_list);
+- spin_unlock(&vbq->lock);
++ spin_unlock(&vb->lock);
++ break;
+ }
+ spin_unlock(&vb->lock);
+- break;
+-next:
+- spin_unlock(&vb->lock);
+ }
+-
+- if (purge)
+- purge_fragmented_blocks_thiscpu();
+-
+ put_cpu_var(vmap_cpu_blocks);
+ rcu_read_unlock();
+
+@@ -923,11 +862,11 @@ static void vb_free(const void *addr, unsigned long size)
+ BUG_ON(!vb);
+
+ spin_lock(&vb->lock);
+- BUG_ON(bitmap_allocate_region(vb->dirty_map, offset >> PAGE_SHIFT, order));
++ bitmap_allocate_region(vb->dirty_map, offset >> PAGE_SHIFT, order);
+
+ vb->dirty += 1UL << order;
+ if (vb->dirty == VMAP_BBMAP_BITS) {
+- BUG_ON(vb->free);
++ BUG_ON(vb->free || !list_empty(&vb->free_list));
+ spin_unlock(&vb->lock);
+ free_vmap_block(vb);
+ } else
+@@ -1096,6 +1035,8 @@ void __init vmalloc_init(void)
+ vbq = &per_cpu(vmap_block_queue, i);
+ spin_lock_init(&vbq->lock);
+ INIT_LIST_HEAD(&vbq->free);
++ INIT_LIST_HEAD(&vbq->dirty);
++ vbq->nr_dirty = 0;
+ }
+
+ /* Import existing vmlist entries. */
+@@ -2052,7 +1993,6 @@ void free_vm_area(struct vm_struct *area)
+ }
+ EXPORT_SYMBOL_GPL(free_vm_area);
+
+-#ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA
+ static struct vmap_area *node_to_va(struct rb_node *n)
+ {
+ return n ? rb_entry(n, struct vmap_area, rb_node) : NULL;
+@@ -2317,7 +2257,6 @@ err_free:
+ kfree(vms);
+ return NULL;
+ }
+-#endif
+
+ /**
+ * pcpu_free_vm_areas - free vmalloc areas for percpu allocator
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 692807f..777af57 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -1464,26 +1464,20 @@ static int inactive_file_is_low(struct zone *zone, struct scan_control *sc)
+ return low;
+ }
+
+-static int inactive_list_is_low(struct zone *zone, struct scan_control *sc,
+- int file)
+-{
+- if (file)
+- return inactive_file_is_low(zone, sc);
+- else
+- return inactive_anon_is_low(zone, sc);
+-}
+-
+ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
+ struct zone *zone, struct scan_control *sc, int priority)
+ {
+ int file = is_file_lru(lru);
+
+- if (is_active_lru(lru)) {
+- if (inactive_list_is_low(zone, sc, file))
+- shrink_active_list(nr_to_scan, zone, sc, priority, file);
++ if (lru == LRU_ACTIVE_FILE && inactive_file_is_low(zone, sc)) {
++ shrink_active_list(nr_to_scan, zone, sc, priority, file);
+ return 0;
+ }
+
++ if (lru == LRU_ACTIVE_ANON && inactive_anon_is_low(zone, sc)) {
++ shrink_active_list(nr_to_scan, zone, sc, priority, file);
++ return 0;
++ }
+ return shrink_inactive_list(nr_to_scan, zone, sc, priority, file);
+ }
+
+diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
+index 1491260..bf706f8 100644
+--- a/net/ax25/ax25_out.c
++++ b/net/ax25/ax25_out.c
+@@ -92,12 +92,6 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax2
+ #endif
+ }
+
+- /*
+- * There is one ref for the state machine; a caller needs
+- * one more to put it back, just like with the existing one.
+- */
+- ax25_cb_hold(ax25);
+-
+ ax25_cb_add(ax25);
+
+ ax25->state = AX25_STATE_1;
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index 0b7f262..bd1c654 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1406,9 +1406,6 @@ static int do_ebt_set_ctl(struct sock *sk,
+ {
+ int ret;
+
+- if (!capable(CAP_NET_ADMIN))
+- return -EPERM;
+-
+ switch(cmd) {
+ case EBT_SO_SET_ENTRIES:
+ ret = do_replace(sock_net(sk), user, len);
+@@ -1428,9 +1425,6 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+ struct ebt_replace tmp;
+ struct ebt_table *t;
+
+- if (!capable(CAP_NET_ADMIN))
+- return -EPERM;
+-
+ if (copy_from_user(&tmp, user, sizeof(tmp)))
+ return -EFAULT;
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 584046e..fe10551 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4860,11 +4860,6 @@ int register_netdevice(struct net_device *dev)
+ rollback_registered(dev);
+ dev->reg_state = NETREG_UNREGISTERED;
+ }
+- /*
+- * Prevent userspace races by waiting until the network
+- * device is fully setup before sending notifications.
+- */
+- rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
+
+ out:
+ return ret;
+@@ -5403,12 +5398,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
+ /* Notify protocols, that a new device appeared. */
+ call_netdevice_notifiers(NETDEV_REGISTER, dev);
+
+- /*
+- * Prevent userspace races by waiting until the network
+- * device is fully setup before sending notifications.
+- */
+- rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
+-
+ synchronize_net();
+ err = 0;
+ out:
+diff --git a/net/core/dst.c b/net/core/dst.c
+index cb1b348..57bc4d5 100644
+--- a/net/core/dst.c
++++ b/net/core/dst.c
+@@ -17,7 +17,6 @@
+ #include <linux/string.h>
+ #include <linux/types.h>
+ #include <net/net_namespace.h>
+-#include <linux/sched.h>
+
+ #include <net/dst.h>
+
+@@ -80,7 +79,6 @@ loop:
+ while ((dst = next) != NULL) {
+ next = dst->next;
+ prefetch(&next->next);
+- cond_resched();
+ if (likely(atomic_read(&dst->__refcnt))) {
+ last->next = dst;
+ last = dst;
+diff --git a/net/core/pktgen.c b/net/core/pktgen.c
+index 6a993b1..6e79e96 100644
+--- a/net/core/pktgen.c
++++ b/net/core/pktgen.c
+@@ -3516,7 +3516,6 @@ static int pktgen_thread_worker(void *arg)
+ wait_event_interruptible_timeout(t->queue,
+ t->control != 0,
+ HZ/10);
+- try_to_freeze();
+ continue;
+ }
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index d4fd895..eb42873 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -1334,11 +1334,13 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
+ case NETDEV_UNREGISTER:
+ rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
+ break;
++ case NETDEV_REGISTER:
++ rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
++ break;
+ case NETDEV_UP:
+ case NETDEV_DOWN:
+ rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
+ break;
+- case NETDEV_REGISTER:
+ case NETDEV_CHANGE:
+ case NETDEV_GOING_DOWN:
+ break;
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 6605e75..7626b6a 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1181,10 +1181,6 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
+
+ if (newsk->sk_prot->sockets_allocated)
+ percpu_counter_inc(newsk->sk_prot->sockets_allocated);
+-
+- if (sock_flag(newsk, SOCK_TIMESTAMP) ||
+- sock_flag(newsk, SOCK_TIMESTAMPING_RX_SOFTWARE))
+- net_enable_timestamp();
+ }
+ out:
+ return newsk;
+diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
+index 0030e73..5df2f6a 100644
+--- a/net/ipv4/devinet.c
++++ b/net/ipv4/devinet.c
+@@ -1450,7 +1450,6 @@ static struct devinet_sysctl_table {
+ DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
+ DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
+ "accept_source_route"),
+- DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
+ DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
+ DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
+ DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+index 29391ee..aa00398 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -251,8 +251,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
+ if (in_dev) {
+ no_addr = in_dev->ifa_list == NULL;
+ rpf = IN_DEV_RPFILTER(in_dev);
+- if (mark && !IN_DEV_SRC_VMARK(in_dev))
+- fl.mark = 0;
+ }
+ rcu_read_unlock();
+
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index 4d50daa..f989518 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -501,8 +501,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
+ if (skb->sk) {
+ frag->sk = skb->sk;
+ frag->destructor = sock_wfree;
++ truesizes += frag->truesize;
+ }
+- truesizes += frag->truesize;
+ }
+
+ /* Everything is OK. Generate! */
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index 98442f3..27774c9 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -925,10 +925,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
+ if (t && !IS_ERR(t)) {
+ struct arpt_getinfo info;
+ const struct xt_table_info *private = t->private;
+-#ifdef CONFIG_COMPAT
+- struct xt_table_info tmp;
+
++#ifdef CONFIG_COMPAT
+ if (compat) {
++ struct xt_table_info tmp;
+ ret = compat_table_info(private, &tmp);
+ xt_compat_flush_offsets(NFPROTO_ARP);
+ private = &tmp;
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index 62aff31..cde755d 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -1132,10 +1132,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
+ if (t && !IS_ERR(t)) {
+ struct ipt_getinfo info;
+ const struct xt_table_info *private = t->private;
+-#ifdef CONFIG_COMPAT
+- struct xt_table_info tmp;
+
++#ifdef CONFIG_COMPAT
+ if (compat) {
++ struct xt_table_info tmp;
+ ret = compat_table_info(private, &tmp);
+ xt_compat_flush_offsets(AF_INET);
+ private = &tmp;
+diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+index 1032a15..aa95bb8 100644
+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+@@ -213,7 +213,7 @@ static ctl_table ip_ct_sysctl_table[] = {
+ {
+ .ctl_name = NET_IPV4_NF_CONNTRACK_BUCKETS,
+ .procname = "ip_conntrack_buckets",
+- .data = &init_net.ct.htable_size,
++ .data = &nf_conntrack_htable_size,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+index 2fb7b76..8668a3d 100644
+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+@@ -32,7 +32,7 @@ static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
+ struct hlist_nulls_node *n;
+
+ for (st->bucket = 0;
+- st->bucket < net->ct.htable_size;
++ st->bucket < nf_conntrack_htable_size;
+ st->bucket++) {
+ n = rcu_dereference(net->ct.hash[st->bucket].first);
+ if (!is_a_nulls(n))
+@@ -50,7 +50,7 @@ static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
+ head = rcu_dereference(head->next);
+ while (is_a_nulls(head)) {
+ if (likely(get_nulls_value(head) == st->bucket)) {
+- if (++st->bucket >= net->ct.htable_size)
++ if (++st->bucket >= nf_conntrack_htable_size)
+ return NULL;
+ }
+ head = rcu_dereference(net->ct.hash[st->bucket].first);
+diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
+index 331ead3..fa2d6b6 100644
+--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
++++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
+@@ -14,7 +14,6 @@
+ #include <net/route.h>
+ #include <net/ip.h>
+
+-#include <linux/netfilter_bridge.h>
+ #include <linux/netfilter_ipv4.h>
+ #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+
+@@ -35,20 +34,6 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
+ return err;
+ }
+
+-static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
+- struct sk_buff *skb)
+-{
+-#ifdef CONFIG_BRIDGE_NETFILTER
+- if (skb->nf_bridge &&
+- skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
+- return IP_DEFRAG_CONNTRACK_BRIDGE_IN;
+-#endif
+- if (hooknum == NF_INET_PRE_ROUTING)
+- return IP_DEFRAG_CONNTRACK_IN;
+- else
+- return IP_DEFRAG_CONNTRACK_OUT;
+-}
+-
+ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+@@ -65,8 +50,10 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
+ #endif
+ /* Gather fragments. */
+ if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
+- enum ip_defrag_users user = nf_ct_defrag_user(hooknum, skb);
+- if (nf_ct_ipv4_gather_frags(skb, user))
++ if (nf_ct_ipv4_gather_frags(skb,
++ hooknum == NF_INET_PRE_ROUTING ?
++ IP_DEFRAG_CONNTRACK_IN :
++ IP_DEFRAG_CONNTRACK_OUT))
+ return NF_STOLEN;
+ }
+ return NF_ACCEPT;
+diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
+index 26066a2..fe1a644 100644
+--- a/net/ipv4/netfilter/nf_nat_core.c
++++ b/net/ipv4/netfilter/nf_nat_core.c
+@@ -35,6 +35,9 @@ static DEFINE_SPINLOCK(nf_nat_lock);
+
+ static struct nf_conntrack_l3proto *l3proto __read_mostly;
+
++/* Calculated at init based on memory size */
++static unsigned int nf_nat_htable_size __read_mostly;
++
+ #define MAX_IP_NAT_PROTO 256
+ static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]
+ __read_mostly;
+@@ -69,7 +72,7 @@ EXPORT_SYMBOL_GPL(nf_nat_proto_put);
+
+ /* We keep an extra hash for each conntrack, for fast searching. */
+ static inline unsigned int
+-hash_by_src(const struct net *net, const struct nf_conntrack_tuple *tuple)
++hash_by_src(const struct nf_conntrack_tuple *tuple)
+ {
+ unsigned int hash;
+
+@@ -77,7 +80,7 @@ hash_by_src(const struct net *net, const struct nf_conntrack_tuple *tuple)
+ hash = jhash_3words((__force u32)tuple->src.u3.ip,
+ (__force u32)tuple->src.u.all,
+ tuple->dst.protonum, 0);
+- return ((u64)hash * net->ipv4.nat_htable_size) >> 32;
++ return ((u64)hash * nf_nat_htable_size) >> 32;
+ }
+
+ /* Is this tuple already taken? (not by us) */
+@@ -144,7 +147,7 @@ find_appropriate_src(struct net *net,
+ struct nf_conntrack_tuple *result,
+ const struct nf_nat_range *range)
+ {
+- unsigned int h = hash_by_src(net, tuple);
++ unsigned int h = hash_by_src(tuple);
+ const struct nf_conn_nat *nat;
+ const struct nf_conn *ct;
+ const struct hlist_node *n;
+@@ -327,7 +330,7 @@ nf_nat_setup_info(struct nf_conn *ct,
+ if (have_to_hash) {
+ unsigned int srchash;
+
+- srchash = hash_by_src(net, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
++ srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+ spin_lock_bh(&nf_nat_lock);
+ /* nf_conntrack_alter_reply might re-allocate exntension aera */
+ nat = nfct_nat(ct);
+@@ -676,10 +679,8 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct,
+
+ static int __net_init nf_nat_net_init(struct net *net)
+ {
+- /* Leave them the same for the moment. */
+- net->ipv4.nat_htable_size = net->ct.htable_size;
+- net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&net->ipv4.nat_htable_size,
+- &net->ipv4.nat_vmalloced, 0);
++ net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
++ &net->ipv4.nat_vmalloced, 0);
+ if (!net->ipv4.nat_bysource)
+ return -ENOMEM;
+ return 0;
+@@ -702,7 +703,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
+ nf_ct_iterate_cleanup(net, &clean_nat, NULL);
+ synchronize_rcu();
+ nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced,
+- net->ipv4.nat_htable_size);
++ nf_nat_htable_size);
+ }
+
+ static struct pernet_operations nf_nat_net_ops = {
+@@ -723,6 +724,9 @@ static int __init nf_nat_init(void)
+ return ret;
+ }
+
++ /* Leave them the same for the moment. */
++ nf_nat_htable_size = nf_conntrack_htable_size;
++
+ ret = register_pernet_subsys(&nf_nat_net_ops);
+ if (ret < 0)
+ goto cleanup_extend;
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 4bac362..df159ff 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -559,11 +559,6 @@ static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
+ return skb_dst(skb) ? ip6_dst_idev(skb_dst(skb)) : __in6_dev_get(skb->dev);
+ }
+
+-static inline struct net *ipv6_skb_net(struct sk_buff *skb)
+-{
+- return skb_dst(skb) ? dev_net(skb_dst(skb)->dev) : dev_net(skb->dev);
+-}
+-
+ /* Router Alert as of RFC 2711 */
+
+ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
+@@ -585,8 +580,8 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
+ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
+ {
+ const unsigned char *nh = skb_network_header(skb);
+- struct net *net = ipv6_skb_net(skb);
+ u32 pkt_len;
++ struct net *net = dev_net(skb_dst(skb)->dev);
+
+ if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
+ LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index 1de56fd..cc9f8ef 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -1164,10 +1164,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
+ if (t && !IS_ERR(t)) {
+ struct ip6t_getinfo info;
+ const struct xt_table_info *private = t->private;
+-#ifdef CONFIG_COMPAT
+- struct xt_table_info tmp;
+
++#ifdef CONFIG_COMPAT
+ if (compat) {
++ struct xt_table_info tmp;
+ ret = compat_table_info(private, &tmp);
+ xt_compat_flush_offsets(AF_INET6);
+ private = &tmp;
+diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+index 0956eba..5f2ec20 100644
+--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
++++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+@@ -20,7 +20,6 @@
+ #include <net/ipv6.h>
+ #include <net/inet_frag.h>
+
+-#include <linux/netfilter_bridge.h>
+ #include <linux/netfilter_ipv6.h>
+ #include <net/netfilter/nf_conntrack.h>
+ #include <net/netfilter/nf_conntrack_helper.h>
+@@ -188,21 +187,6 @@ out:
+ return nf_conntrack_confirm(skb);
+ }
+
+-static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
+- struct sk_buff *skb)
+-{
+-#ifdef CONFIG_BRIDGE_NETFILTER
+- if (skb->nf_bridge &&
+- skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
+- return IP6_DEFRAG_CONNTRACK_BRIDGE_IN;
+-#endif
+- if (hooknum == NF_INET_PRE_ROUTING)
+- return IP6_DEFRAG_CONNTRACK_IN;
+- else
+- return IP6_DEFRAG_CONNTRACK_OUT;
+-
+-}
+-
+ static unsigned int ipv6_defrag(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+@@ -215,7 +199,8 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
+ if (skb->nfct)
+ return NF_ACCEPT;
+
+- reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
++ reasm = nf_ct_frag6_gather(skb);
++
+ /* queued */
+ if (reasm == NULL)
+ return NF_STOLEN;
+diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
+index 4b6a539..f3aba25 100644
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
+@@ -170,14 +170,13 @@ out:
+ /* Creation primitives. */
+
+ static __inline__ struct nf_ct_frag6_queue *
+-fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
++fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
+ {
+ struct inet_frag_queue *q;
+ struct ip6_create_arg arg;
+ unsigned int hash;
+
+ arg.id = id;
+- arg.user = user;
+ arg.src = src;
+ arg.dst = dst;
+
+@@ -562,7 +561,7 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
+ return 0;
+ }
+
+-struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
++struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
+ {
+ struct sk_buff *clone;
+ struct net_device *dev = skb->dev;
+@@ -608,7 +607,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
+ if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
+ nf_ct_frag6_evictor();
+
+- fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
++ fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
+ if (fq == NULL) {
+ pr_debug("Can't find and can't create new queue\n");
+ goto ret_orig;
+diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
+index 4d18699..da5bd0e 100644
+--- a/net/ipv6/reassembly.c
++++ b/net/ipv6/reassembly.c
+@@ -72,7 +72,6 @@ struct frag_queue
+ struct inet_frag_queue q;
+
+ __be32 id; /* fragment id */
+- u32 user;
+ struct in6_addr saddr;
+ struct in6_addr daddr;
+
+@@ -142,7 +141,7 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a)
+ struct ip6_create_arg *arg = a;
+
+ fq = container_of(q, struct frag_queue, q);
+- return (fq->id == arg->id && fq->user == arg->user &&
++ return (fq->id == arg->id &&
+ ipv6_addr_equal(&fq->saddr, arg->src) &&
+ ipv6_addr_equal(&fq->daddr, arg->dst));
+ }
+@@ -164,7 +163,6 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
+ struct ip6_create_arg *arg = a;
+
+ fq->id = arg->id;
+- fq->user = arg->user;
+ ipv6_addr_copy(&fq->saddr, arg->src);
+ ipv6_addr_copy(&fq->daddr, arg->dst);
+ }
+@@ -246,7 +244,6 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
+ unsigned int hash;
+
+ arg.id = id;
+- arg.user = IP6_DEFRAG_LOCAL_DELIVER;
+ arg.src = src;
+ arg.dst = dst;
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index fe2d3f8..7b5131b 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -338,8 +338,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
+ sinfo->rx_packets = sta->rx_packets;
+ sinfo->tx_packets = sta->tx_packets;
+
+- if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
+- (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
++ if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = (s8)sta->last_signal;
+ }
+@@ -1306,9 +1305,6 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+ struct ieee80211_conf *conf = &local->hw.conf;
+
+- if (sdata->vif.type != NL80211_IFTYPE_STATION)
+- return -EOPNOTSUPP;
+-
+ if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
+ return -EOPNOTSUPP;
+
+diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
+index d87645e..37b9051 100644
+--- a/net/mac80211/driver-trace.h
++++ b/net/mac80211/driver-trace.h
+@@ -655,7 +655,7 @@ TRACE_EVENT(drv_ampdu_action,
+ __entry->ret = ret;
+ __entry->action = action;
+ __entry->tid = tid;
+- __entry->ssn = ssn ? *ssn : 0;
++ __entry->ssn = *ssn;
+ ),
+
+ TP_printk(
+diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
+index 07600a6..f1362f3 100644
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -455,10 +455,6 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
+
+ ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
+
+- if (time_before(jiffies, ifibss->last_scan_completed +
+- IEEE80211_IBSS_MERGE_INTERVAL))
+- return;
+-
+ if (ieee80211_sta_active_ibss(sdata))
+ return;
+
+@@ -643,7 +639,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
+ }
+ if (pos[1] != 0 &&
+ (pos[1] != ifibss->ssid_len ||
+- memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) {
++ !memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) {
+ /* Ignore ProbeReq for foreign SSID */
+ return;
+ }
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index 5a46164..10d316e 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -808,7 +808,6 @@ struct ieee80211_local {
+ unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
+
+ bool pspolling;
+- bool scan_ps_enabled;
+ /*
+ * PS can only be enabled when we have exactly one managed
+ * interface (and monitors) in PS, this then points there.
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 079c500..b8295cb 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -15,14 +15,12 @@
+ #include <linux/netdevice.h>
+ #include <linux/rtnetlink.h>
+ #include <net/mac80211.h>
+-#include <net/ieee80211_radiotap.h>
+ #include "ieee80211_i.h"
+ #include "sta_info.h"
+ #include "debugfs_netdev.h"
+ #include "mesh.h"
+ #include "led.h"
+ #include "driver-ops.h"
+-#include "wme.h"
+
+ /**
+ * DOC: Interface list locking
+@@ -644,12 +642,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
+ WARN_ON(flushed);
+ }
+
+-static u16 ieee80211_netdev_select_queue(struct net_device *dev,
+- struct sk_buff *skb)
+-{
+- return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb);
+-}
+-
+ static const struct net_device_ops ieee80211_dataif_ops = {
+ .ndo_open = ieee80211_open,
+ .ndo_stop = ieee80211_stop,
+@@ -658,35 +650,8 @@ static const struct net_device_ops ieee80211_dataif_ops = {
+ .ndo_set_multicast_list = ieee80211_set_multicast_list,
+ .ndo_change_mtu = ieee80211_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+- .ndo_select_queue = ieee80211_netdev_select_queue,
+ };
+
+-static u16 ieee80211_monitor_select_queue(struct net_device *dev,
+- struct sk_buff *skb)
+-{
+- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+- struct ieee80211_local *local = sdata->local;
+- struct ieee80211_hdr *hdr;
+- struct ieee80211_radiotap_header *rtap = (void *)skb->data;
+-
+- if (local->hw.queues < 4)
+- return 0;
+-
+- if (skb->len < 4 ||
+- skb->len < le16_to_cpu(rtap->it_len) + 2 /* frame control */)
+- return 0; /* doesn't matter, frame will be dropped */
+-
+- hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
+-
+- if (!ieee80211_is_data(hdr->frame_control)) {
+- skb->priority = 7;
+- return ieee802_1d_to_ac[skb->priority];
+- }
+-
+- skb->priority = 0;
+- return ieee80211_downgrade_queue(local, skb);
+-}
+-
+ static const struct net_device_ops ieee80211_monitorif_ops = {
+ .ndo_open = ieee80211_open,
+ .ndo_stop = ieee80211_stop,
+@@ -695,7 +660,6 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
+ .ndo_set_multicast_list = ieee80211_set_multicast_list,
+ .ndo_change_mtu = ieee80211_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+- .ndo_select_queue = ieee80211_monitor_select_queue,
+ };
+
+ static void ieee80211_if_setup(struct net_device *dev)
+@@ -804,8 +768,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
+
+ ASSERT_RTNL();
+
+- ndev = alloc_netdev_mq(sizeof(*sdata) + local->hw.vif_data_size,
+- name, ieee80211_if_setup, local->hw.queues);
++ ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size,
++ name, ieee80211_if_setup);
+ if (!ndev)
+ return -ENOMEM;
+ dev_net_set(ndev, wiphy_net(local->hw.wiphy));
+diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
+index 010ff2f..dd1c193 100644
+--- a/net/mac80211/mesh.h
++++ b/net/mac80211/mesh.h
+@@ -186,9 +186,8 @@ struct mesh_rmc {
+ */
+ #define MESH_PREQ_MIN_INT 10
+ #define MESH_DIAM_TRAVERSAL_TIME 50
+-/* A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds before
+- * timing out. This way it will remain ACTIVE and no data frames will be
+- * unnecesarily held in the pending queue.
++/* Paths will be refreshed if they are closer than PATH_REFRESH_TIME to their
++ * expiration
+ */
+ #define MESH_PATH_REFRESH_TIME 1000
+ #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
+diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
+index 93c49fc..29b82e9 100644
+--- a/net/mac80211/mesh_hwmp.c
++++ b/net/mac80211/mesh_hwmp.c
+@@ -813,7 +813,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
+ }
+
+ if (mpath->flags & MESH_PATH_ACTIVE) {
+- if (time_after(jiffies, mpath->exp_time -
++ if (time_after(jiffies, mpath->exp_time +
+ msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time))
+ && !memcmp(sdata->dev->dev_addr, hdr->addr4,
+ ETH_ALEN)
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 6cae295..dc5049d 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -904,14 +904,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
+ sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+ IEEE80211_STA_BEACON_POLL);
+
+- /*
+- * Always handle WMM once after association regardless
+- * of the first value the AP uses. Setting -1 here has
+- * that effect because the AP values is an unsigned
+- * 4-bit value.
+- */
+- sdata->u.mgd.wmm_last_param_set = -1;
+-
+ ieee80211_led_assoc(local, 1);
+
+ sdata->vif.bss_conf.assoc = 1;
+@@ -1953,9 +1945,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
+ rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
+ break;
+ case IEEE80211_STYPE_ACTION:
+- if (mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT)
+- break;
+-
++ /* XXX: differentiate, can only happen for CSA now! */
+ ieee80211_sta_process_chanswitch(sdata,
+ &mgmt->u.action.u.chan_switch.sw_elem,
+ ifmgd->associated);
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 16c6cdc..7170bf4 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -1514,6 +1514,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
+ mpp_path_add(mesh_hdr->eaddr2, hdr->addr4, sdata);
+ } else {
+ spin_lock_bh(&mppath->state_lock);
++ mppath->exp_time = jiffies;
+ if (compare_ether_addr(mppath->mpp, hdr->addr4) != 0)
+ memcpy(mppath->mpp, hdr->addr4, ETH_ALEN);
+ spin_unlock_bh(&mppath->state_lock);
+@@ -1548,9 +1549,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
+ memset(info, 0, sizeof(*info));
+ info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
+ info->control.vif = &rx->sdata->vif;
+- skb_set_queue_mapping(skb,
+- ieee80211_select_queue(rx->sdata, fwd_skb));
+- ieee80211_set_qos_hdr(local, skb);
++ ieee80211_select_queue(local, fwd_skb);
+ if (is_multicast_ether_addr(fwd_hdr->addr1))
+ IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
+ fwded_mcast);
+@@ -1810,10 +1809,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
+ }
+ break;
+ default:
+- /* do not process rejected action frames */
+- if (mgmt->u.action.category & 0x80)
+- return RX_DROP_MONITOR;
+-
+ return RX_CONTINUE;
+ }
+
+diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
+index 1a41909..71e10ca 100644
+--- a/net/mac80211/scan.c
++++ b/net/mac80211/scan.c
+@@ -196,8 +196,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
+ static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
+ {
+ struct ieee80211_local *local = sdata->local;
+-
+- local->scan_ps_enabled = false;
++ bool ps = false;
+
+ /* FIXME: what to do when local->pspolling is true? */
+
+@@ -205,13 +204,12 @@ static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
+ cancel_work_sync(&local->dynamic_ps_enable_work);
+
+ if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+- local->scan_ps_enabled = true;
++ ps = true;
+ local->hw.conf.flags &= ~IEEE80211_CONF_PS;
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+ }
+
+- if (!(local->scan_ps_enabled) ||
+- !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
++ if (!ps || !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
+ /*
+ * If power save was enabled, no need to send a nullfunc
+ * frame because AP knows that we are sleeping. But if the
+@@ -232,7 +230,7 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
+
+ if (!local->ps_sdata)
+ ieee80211_send_nullfunc(local, sdata, 0);
+- else if (local->scan_ps_enabled) {
++ else {
+ /*
+ * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
+ * will send a nullfunc frame with the powersave bit set
+@@ -248,16 +246,6 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
+ */
+ local->hw.conf.flags |= IEEE80211_CONF_PS;
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+- } else if (local->hw.conf.dynamic_ps_timeout > 0) {
+- /*
+- * If IEEE80211_CONF_PS was not set and the dynamic_ps_timer
+- * had been running before leaving the operating channel,
+- * restart the timer now and send a nullfunc frame to inform
+- * the AP that we are awake.
+- */
+- ieee80211_send_nullfunc(local, sdata, 0);
+- mod_timer(&local->dynamic_ps_timer, jiffies +
+- msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
+ }
+ }
+
+@@ -276,14 +264,10 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
+
+ mutex_lock(&local->scan_mtx);
+
+- /*
+- * It's ok to abort a not-yet-running scan (that
+- * we have one at all will be verified by checking
+- * local->scan_req next), but not to complete it
+- * successfully.
+- */
+- if (WARN_ON(!local->scanning && !aborted))
+- aborted = true;
++ if (WARN_ON(!local->scanning)) {
++ mutex_unlock(&local->scan_mtx);
++ return;
++ }
+
+ if (WARN_ON(!local->scan_req)) {
+ mutex_unlock(&local->scan_mtx);
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 441f68e..eaa4118 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1401,7 +1401,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
+
+ if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
+ local->hw.conf.dynamic_ps_timeout > 0 &&
+- !local->quiescing &&
+ !(local->scanning) && local->ps_sdata) {
+ if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+ ieee80211_stop_queues_by_reason(&local->hw,
+@@ -1482,7 +1481,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
+ return;
+ }
+
+- ieee80211_set_qos_hdr(local, skb);
++ ieee80211_select_queue(local, skb);
+ ieee80211_tx(sdata, skb, false);
+ dev_put(sdata->dev);
+ }
+@@ -2226,9 +2225,6 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
+ if (!encrypt)
+ info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+
+- /* send all internal mgmt frames on VO */
+- skb_set_queue_mapping(skb, 0);
+-
+ /*
+ * The other path calling ieee80211_xmit is from the tasklet,
+ * and while we can handle concurrent transmissions locking
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 553cffe..e6c08da 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -269,7 +269,6 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
+ enum queue_stop_reason reason)
+ {
+ struct ieee80211_local *local = hw_to_local(hw);
+- struct ieee80211_sub_if_data *sdata;
+
+ if (WARN_ON(queue >= hw->queues))
+ return;
+@@ -282,11 +281,6 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
+
+ if (!skb_queue_empty(&local->pending[queue]))
+ tasklet_schedule(&local->tx_pending_tasklet);
+-
+- rcu_read_lock();
+- list_for_each_entry_rcu(sdata, &local->interfaces, list)
+- netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
+- rcu_read_unlock();
+ }
+
+ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
+@@ -311,17 +305,11 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
+ enum queue_stop_reason reason)
+ {
+ struct ieee80211_local *local = hw_to_local(hw);
+- struct ieee80211_sub_if_data *sdata;
+
+ if (WARN_ON(queue >= hw->queues))
+ return;
+
+ __set_bit(reason, &local->queue_stop_reasons[queue]);
+-
+- rcu_read_lock();
+- list_for_each_entry_rcu(sdata, &local->interfaces, list)
+- netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue));
+- rcu_read_unlock();
+ }
+
+ void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
+@@ -591,7 +579,7 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
+ if (elen > left)
+ break;
+
+- if (calc_crc && id < 64 && (filter & (1ULL << id)))
++ if (calc_crc && id < 64 && (filter & BIT(id)))
+ crc = crc32_be(crc, pos - 2, elen + 2);
+
+ switch (id) {
+@@ -1043,19 +1031,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
+
+ /* restart hardware */
+ if (local->open_count) {
+- /*
+- * Upon resume hardware can sometimes be goofy due to
+- * various platform / driver / bus issues, so restarting
+- * the device may at times not work immediately. Propagate
+- * the error.
+- */
+ res = drv_start(local);
+- if (res) {
+- WARN(local->suspended, "Harware became unavailable "
+- "upon resume. This is could be a software issue"
+- "prior to suspend or a harware issue\n");
+- return res;
+- }
+
+ ieee80211_led_radio(local, true);
+ }
+diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
+index 6d32ebf..b19b769 100644
+--- a/net/mac80211/wme.c
++++ b/net/mac80211/wme.c
+@@ -44,62 +44,22 @@ static int wme_downgrade_ac(struct sk_buff *skb)
+ }
+
+
+-/* Indicate which queue to use. */
+-u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
+- struct sk_buff *skb)
++/* Indicate which queue to use. */
++static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
+ {
+- struct ieee80211_local *local = sdata->local;
+- struct sta_info *sta = NULL;
+- u32 sta_flags = 0;
+- const u8 *ra = NULL;
+- bool qos = false;
++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+
+- if (local->hw.queues < 4 || skb->len < 6) {
+- skb->priority = 0; /* required for correct WPA/11i MIC */
+- return min_t(u16, local->hw.queues - 1,
+- ieee802_1d_to_ac[skb->priority]);
+- }
+-
+- rcu_read_lock();
+- switch (sdata->vif.type) {
+- case NL80211_IFTYPE_AP_VLAN:
+- case NL80211_IFTYPE_AP:
+- ra = skb->data;
+- break;
+- case NL80211_IFTYPE_WDS:
+- ra = sdata->u.wds.remote_addr;
+- break;
+-#ifdef CONFIG_MAC80211_MESH
+- case NL80211_IFTYPE_MESH_POINT:
+- /*
+- * XXX: This is clearly broken ... but already was before,
+- * because ieee80211_fill_mesh_addresses() would clear A1
+- * except for multicast addresses.
+- */
+- break;
+-#endif
+- case NL80211_IFTYPE_STATION:
+- ra = sdata->u.mgd.bssid;
+- break;
+- case NL80211_IFTYPE_ADHOC:
+- ra = skb->data;
+- break;
+- default:
+- break;
++ if (!ieee80211_is_data(hdr->frame_control)) {
++ /* management frames go on AC_VO queue, but are sent
++ * without QoS control fields */
++ return 0;
+ }
+
+- if (!sta && ra && !is_multicast_ether_addr(ra)) {
+- sta = sta_info_get(local, ra);
+- if (sta)
+- sta_flags = get_sta_flags(sta);
++ if (0 /* injected */) {
++ /* use AC from radiotap */
+ }
+
+- if (sta_flags & WLAN_STA_WME)
+- qos = true;
+-
+- rcu_read_unlock();
+-
+- if (!qos) {
++ if (!ieee80211_is_data_qos(hdr->frame_control)) {
+ skb->priority = 0; /* required for correct WPA/11i MIC */
+ return ieee802_1d_to_ac[skb->priority];
+ }
+@@ -108,12 +68,6 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
+ * data frame has */
+ skb->priority = cfg80211_classify8021d(skb);
+
+- return ieee80211_downgrade_queue(local, skb);
+-}
+-
+-u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
+- struct sk_buff *skb)
+-{
+ /* in case we are a client verify acm is not set for this ac */
+ while (unlikely(local->wmm_acm & BIT(skb->priority))) {
+ if (wme_downgrade_ac(skb)) {
+@@ -131,17 +85,24 @@ u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
+ return ieee802_1d_to_ac[skb->priority];
+ }
+
+-void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb)
++void ieee80211_select_queue(struct ieee80211_local *local, struct sk_buff *skb)
+ {
+- struct ieee80211_hdr *hdr = (void *)skb->data;
+-
+- /* Fill in the QoS header if there is one. */
++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
++ u16 queue;
++ u8 tid;
++
++ queue = classify80211(local, skb);
++ if (unlikely(queue >= local->hw.queues))
++ queue = local->hw.queues - 1;
++
++ /*
++ * Now we know the 1d priority, fill in the QoS header if
++ * there is one (and we haven't done this before).
++ */
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ u8 *p = ieee80211_get_qos_ctl(hdr);
+- u8 ack_policy = 0, tid;
+-
++ u8 ack_policy = 0;
+ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
+-
+ if (unlikely(local->wifi_wme_noack_test))
+ ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK <<
+ QOS_CONTROL_ACK_POLICY_SHIFT;
+@@ -149,4 +110,6 @@ void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb)
+ *p++ = ack_policy | tid;
+ *p = 0;
+ }
++
++ skb_set_queue_mapping(skb, queue);
+ }
+diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
+index 6053b1c..d4fd87c 100644
+--- a/net/mac80211/wme.h
++++ b/net/mac80211/wme.h
+@@ -20,11 +20,7 @@
+
+ extern const int ieee802_1d_to_ac[8];
+
+-u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
+- struct sk_buff *skb);
+-void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb);
+-u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
+- struct sk_buff *skb);
+-
++void ieee80211_select_queue(struct ieee80211_local *local,
++ struct sk_buff *skb);
+
+ #endif /* _WME_H */
+diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
+index 02b2610..446e9bd 100644
+--- a/net/netfilter/ipvs/ip_vs_ctl.c
++++ b/net/netfilter/ipvs/ip_vs_ctl.c
+@@ -2714,8 +2714,6 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc,
+ if (!(nla_af && (nla_fwmark || (nla_port && nla_protocol && nla_addr))))
+ return -EINVAL;
+
+- memset(usvc, 0, sizeof(*usvc));
+-
+ usvc->af = nla_get_u16(nla_af);
+ #ifdef CONFIG_IP_VS_IPV6
+ if (usvc->af != AF_INET && usvc->af != AF_INET6)
+@@ -2903,8 +2901,6 @@ static int ip_vs_genl_parse_dest(struct ip_vs_dest_user_kern *udest,
+ if (!(nla_addr && nla_port))
+ return -EINVAL;
+
+- memset(udest, 0, sizeof(*udest));
+-
+ nla_memcpy(&udest->addr, nla_addr, sizeof(udest->addr));
+ udest->port = nla_get_u16(nla_port);
+
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 1374179..b9168c1 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -30,7 +30,6 @@
+ #include <linux/netdevice.h>
+ #include <linux/socket.h>
+ #include <linux/mm.h>
+-#include <linux/nsproxy.h>
+ #include <linux/rculist_nulls.h>
+
+ #include <net/netfilter/nf_conntrack.h>
+@@ -64,6 +63,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_max);
+ struct nf_conn nf_conntrack_untracked __read_mostly;
+ EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
+
++static struct kmem_cache *nf_conntrack_cachep __read_mostly;
++
+ static int nf_conntrack_hash_rnd_initted;
+ static unsigned int nf_conntrack_hash_rnd;
+
+@@ -85,10 +86,9 @@ static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
+ return ((u64)h * size) >> 32;
+ }
+
+-static inline u_int32_t hash_conntrack(const struct net *net,
+- const struct nf_conntrack_tuple *tuple)
++static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
+ {
+- return __hash_conntrack(tuple, net->ct.htable_size,
++ return __hash_conntrack(tuple, nf_conntrack_htable_size,
+ nf_conntrack_hash_rnd);
+ }
+
+@@ -296,7 +296,7 @@ __nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple)
+ {
+ struct nf_conntrack_tuple_hash *h;
+ struct hlist_nulls_node *n;
+- unsigned int hash = hash_conntrack(net, tuple);
++ unsigned int hash = hash_conntrack(tuple);
+
+ /* Disable BHs the entire time since we normally need to disable them
+ * at least once for the stats anyway.
+@@ -366,11 +366,10 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
+
+ void nf_conntrack_hash_insert(struct nf_conn *ct)
+ {
+- struct net *net = nf_ct_net(ct);
+ unsigned int hash, repl_hash;
+
+- hash = hash_conntrack(net, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+- repl_hash = hash_conntrack(net, &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
++ hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
++ repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+
+ __nf_conntrack_hash_insert(ct, hash, repl_hash);
+ }
+@@ -398,8 +397,8 @@ __nf_conntrack_confirm(struct sk_buff *skb)
+ if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
+ return NF_ACCEPT;
+
+- hash = hash_conntrack(net, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+- repl_hash = hash_conntrack(net, &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
++ hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
++ repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+
+ /* We're not in hash table, and we refuse to set up related
+ connections for unconfirmed conns. But packet copies and
+@@ -469,7 +468,7 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
+ struct net *net = nf_ct_net(ignored_conntrack);
+ struct nf_conntrack_tuple_hash *h;
+ struct hlist_nulls_node *n;
+- unsigned int hash = hash_conntrack(net, tuple);
++ unsigned int hash = hash_conntrack(tuple);
+
+ /* Disable BHs the entire time since we need to disable them at
+ * least once for the stats anyway.
+@@ -504,7 +503,7 @@ static noinline int early_drop(struct net *net, unsigned int hash)
+ int dropped = 0;
+
+ rcu_read_lock();
+- for (i = 0; i < net->ct.htable_size; i++) {
++ for (i = 0; i < nf_conntrack_htable_size; i++) {
+ hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash],
+ hnnode) {
+ tmp = nf_ct_tuplehash_to_ctrack(h);
+@@ -518,8 +517,7 @@ static noinline int early_drop(struct net *net, unsigned int hash)
+ ct = NULL;
+ if (ct || cnt >= NF_CT_EVICTION_RANGE)
+ break;
+-
+- hash = (hash + 1) % net->ct.htable_size;
++ hash = (hash + 1) % nf_conntrack_htable_size;
+ }
+ rcu_read_unlock();
+
+@@ -553,7 +551,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net,
+
+ if (nf_conntrack_max &&
+ unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) {
+- unsigned int hash = hash_conntrack(net, orig);
++ unsigned int hash = hash_conntrack(orig);
+ if (!early_drop(net, hash)) {
+ atomic_dec(&net->ct.count);
+ if (net_ratelimit())
+@@ -568,7 +566,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net,
+ * Do not use kmem_cache_zalloc(), as this cache uses
+ * SLAB_DESTROY_BY_RCU.
+ */
+- ct = kmem_cache_alloc(net->ct.nf_conntrack_cachep, gfp);
++ ct = kmem_cache_alloc(nf_conntrack_cachep, gfp);
+ if (ct == NULL) {
+ pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
+ atomic_dec(&net->ct.count);
+@@ -607,7 +605,7 @@ void nf_conntrack_free(struct nf_conn *ct)
+ nf_ct_ext_destroy(ct);
+ atomic_dec(&net->ct.count);
+ nf_ct_ext_free(ct);
+- kmem_cache_free(net->ct.nf_conntrack_cachep, ct);
++ kmem_cache_free(nf_conntrack_cachep, ct);
+ }
+ EXPORT_SYMBOL_GPL(nf_conntrack_free);
+
+@@ -1010,7 +1008,7 @@ get_next_corpse(struct net *net, int (*iter)(struct nf_conn *i, void *data),
+ struct hlist_nulls_node *n;
+
+ spin_lock_bh(&nf_conntrack_lock);
+- for (; *bucket < net->ct.htable_size; (*bucket)++) {
++ for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
+ hlist_nulls_for_each_entry(h, n, &net->ct.hash[*bucket], hnnode) {
+ ct = nf_ct_tuplehash_to_ctrack(h);
+ if (iter(ct, data))
+@@ -1109,12 +1107,9 @@ static void nf_ct_release_dying_list(struct net *net)
+
+ static void nf_conntrack_cleanup_init_net(void)
+ {
+- /* wait until all references to nf_conntrack_untracked are dropped */
+- while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
+- schedule();
+-
+ nf_conntrack_helper_fini();
+ nf_conntrack_proto_fini();
++ kmem_cache_destroy(nf_conntrack_cachep);
+ }
+
+ static void nf_conntrack_cleanup_net(struct net *net)
+@@ -1126,14 +1121,15 @@ static void nf_conntrack_cleanup_net(struct net *net)
+ schedule();
+ goto i_see_dead_people;
+ }
++ /* wait until all references to nf_conntrack_untracked are dropped */
++ while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
++ schedule();
+
+ nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
+- net->ct.htable_size);
++ nf_conntrack_htable_size);
+ nf_conntrack_ecache_fini(net);
+ nf_conntrack_acct_fini(net);
+ nf_conntrack_expect_fini(net);
+- kmem_cache_destroy(net->ct.nf_conntrack_cachep);
+- kfree(net->ct.slabname);
+ free_percpu(net->ct.stat);
+ }
+
+@@ -1188,12 +1184,10 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
+ {
+ int i, bucket, vmalloced, old_vmalloced;
+ unsigned int hashsize, old_size;
++ int rnd;
+ struct hlist_nulls_head *hash, *old_hash;
+ struct nf_conntrack_tuple_hash *h;
+
+- if (current->nsproxy->net_ns != &init_net)
+- return -EOPNOTSUPP;
+-
+ /* On boot, we can set this without any fancy locking. */
+ if (!nf_conntrack_htable_size)
+ return param_set_uint(val, kp);
+@@ -1206,29 +1200,33 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
+ if (!hash)
+ return -ENOMEM;
+
++ /* We have to rehahs for the new table anyway, so we also can
++ * use a newrandom seed */
++ get_random_bytes(&rnd, sizeof(rnd));
++
+ /* Lookups in the old hash might happen in parallel, which means we
+ * might get false negatives during connection lookup. New connections
+ * created because of a false negative won't make it into the hash
+ * though since that required taking the lock.
+ */
+ spin_lock_bh(&nf_conntrack_lock);
+- for (i = 0; i < init_net.ct.htable_size; i++) {
++ for (i = 0; i < nf_conntrack_htable_size; i++) {
+ while (!hlist_nulls_empty(&init_net.ct.hash[i])) {
+ h = hlist_nulls_entry(init_net.ct.hash[i].first,
+ struct nf_conntrack_tuple_hash, hnnode);
+ hlist_nulls_del_rcu(&h->hnnode);
+- bucket = __hash_conntrack(&h->tuple, hashsize,
+- nf_conntrack_hash_rnd);
++ bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
+ hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]);
+ }
+ }
+- old_size = init_net.ct.htable_size;
++ old_size = nf_conntrack_htable_size;
+ old_vmalloced = init_net.ct.hash_vmalloc;
+ old_hash = init_net.ct.hash;
+
+- init_net.ct.htable_size = nf_conntrack_htable_size = hashsize;
++ nf_conntrack_htable_size = hashsize;
+ init_net.ct.hash_vmalloc = vmalloced;
+ init_net.ct.hash = hash;
++ nf_conntrack_hash_rnd = rnd;
+ spin_unlock_bh(&nf_conntrack_lock);
+
+ nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
+@@ -1267,6 +1265,15 @@ static int nf_conntrack_init_init_net(void)
+ NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
+ nf_conntrack_max);
+
++ nf_conntrack_cachep = kmem_cache_create("nf_conntrack",
++ sizeof(struct nf_conn),
++ 0, SLAB_DESTROY_BY_RCU, NULL);
++ if (!nf_conntrack_cachep) {
++ printk(KERN_ERR "Unable to create nf_conn slab cache\n");
++ ret = -ENOMEM;
++ goto err_cache;
++ }
++
+ ret = nf_conntrack_proto_init();
+ if (ret < 0)
+ goto err_proto;
+@@ -1275,19 +1282,13 @@ static int nf_conntrack_init_init_net(void)
+ if (ret < 0)
+ goto err_helper;
+
+- /* Set up fake conntrack: to never be deleted, not in any hashes */
+-#ifdef CONFIG_NET_NS
+- nf_conntrack_untracked.ct_net = &init_net;
+-#endif
+- atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
+- /* - and look it like as a confirmed connection */
+- set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
+-
+ return 0;
+
+ err_helper:
+ nf_conntrack_proto_fini();
+ err_proto:
++ kmem_cache_destroy(nf_conntrack_cachep);
++err_cache:
+ return ret;
+ }
+
+@@ -1309,24 +1310,7 @@ static int nf_conntrack_init_net(struct net *net)
+ ret = -ENOMEM;
+ goto err_stat;
+ }
+-
+- net->ct.slabname = kasprintf(GFP_KERNEL, "nf_conntrack_%p", net);
+- if (!net->ct.slabname) {
+- ret = -ENOMEM;
+- goto err_slabname;
+- }
+-
+- net->ct.nf_conntrack_cachep = kmem_cache_create(net->ct.slabname,
+- sizeof(struct nf_conn), 0,
+- SLAB_DESTROY_BY_RCU, NULL);
+- if (!net->ct.nf_conntrack_cachep) {
+- printk(KERN_ERR "Unable to create nf_conn slab cache\n");
+- ret = -ENOMEM;
+- goto err_cache;
+- }
+-
+- net->ct.htable_size = nf_conntrack_htable_size;
+- net->ct.hash = nf_ct_alloc_hashtable(&net->ct.htable_size,
++ net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
+ &net->ct.hash_vmalloc, 1);
+ if (!net->ct.hash) {
+ ret = -ENOMEM;
+@@ -1343,6 +1327,15 @@ static int nf_conntrack_init_net(struct net *net)
+ if (ret < 0)
+ goto err_ecache;
+
++ /* Set up fake conntrack:
++ - to never be deleted, not in any hashes */
++#ifdef CONFIG_NET_NS
++ nf_conntrack_untracked.ct_net = &init_net;
++#endif
++ atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
++ /* - and look it like as a confirmed connection */
++ set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
++
+ return 0;
+
+ err_ecache:
+@@ -1351,12 +1344,8 @@ err_acct:
+ nf_conntrack_expect_fini(net);
+ err_expect:
+ nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
+- net->ct.htable_size);
++ nf_conntrack_htable_size);
+ err_hash:
+- kmem_cache_destroy(net->ct.nf_conntrack_cachep);
+-err_cache:
+- kfree(net->ct.slabname);
+-err_slabname:
+ free_percpu(net->ct.stat);
+ err_stat:
+ return ret;
+diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
+index e73eb04..2032dfe 100644
+--- a/net/netfilter/nf_conntrack_expect.c
++++ b/net/netfilter/nf_conntrack_expect.c
+@@ -569,7 +569,7 @@ static void exp_proc_remove(struct net *net)
+ #endif /* CONFIG_PROC_FS */
+ }
+
+-module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0400);
++module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600);
+
+ int nf_conntrack_expect_init(struct net *net)
+ {
+@@ -577,7 +577,7 @@ int nf_conntrack_expect_init(struct net *net)
+
+ if (net_eq(net, &init_net)) {
+ if (!nf_ct_expect_hsize) {
+- nf_ct_expect_hsize = net->ct.htable_size / 256;
++ nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
+ if (!nf_ct_expect_hsize)
+ nf_ct_expect_hsize = 1;
+ }
+diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
+index 7dfd469..5509dd1 100644
+--- a/net/netfilter/nf_conntrack_ftp.c
++++ b/net/netfilter/nf_conntrack_ftp.c
+@@ -323,24 +323,24 @@ static void update_nl_seq(struct nf_conn *ct, u32 nl_seq,
+ struct nf_ct_ftp_master *info, int dir,
+ struct sk_buff *skb)
+ {
+- unsigned int i, oldest;
++ unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
+
+ /* Look for oldest: if we find exact match, we're done. */
+ for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
+ if (info->seq_aft_nl[dir][i] == nl_seq)
+ return;
++
++ if (oldest == info->seq_aft_nl_num[dir] ||
++ before(info->seq_aft_nl[dir][i],
++ info->seq_aft_nl[dir][oldest]))
++ oldest = i;
+ }
+
+ if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
+ info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
+- } else {
+- if (before(info->seq_aft_nl[dir][0], info->seq_aft_nl[dir][1]))
+- oldest = 0;
+- else
+- oldest = 1;
+-
+- if (after(nl_seq, info->seq_aft_nl[dir][oldest]))
+- info->seq_aft_nl[dir][oldest] = nl_seq;
++ } else if (oldest != NUM_SEQ_TO_REMEMBER &&
++ after(nl_seq, info->seq_aft_nl[dir][oldest])) {
++ info->seq_aft_nl[dir][oldest] = nl_seq;
+ }
+ }
+
+diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
+index 4b1a56b..65c2a7b 100644
+--- a/net/netfilter/nf_conntrack_helper.c
++++ b/net/netfilter/nf_conntrack_helper.c
+@@ -192,7 +192,7 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
+ /* Get rid of expecteds, set helpers to NULL. */
+ hlist_nulls_for_each_entry(h, nn, &net->ct.unconfirmed, hnnode)
+ unhelp(h, me);
+- for (i = 0; i < net->ct.htable_size; i++) {
++ for (i = 0; i < nf_conntrack_htable_size; i++) {
+ hlist_nulls_for_each_entry(h, nn, &net->ct.hash[i], hnnode)
+ unhelp(h, me);
+ }
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index d521718..59d8064 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -594,7 +594,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
+
+ rcu_read_lock();
+ last = (struct nf_conn *)cb->args[1];
+- for (; cb->args[0] < init_net.ct.htable_size; cb->args[0]++) {
++ for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
+ restart:
+ hlist_nulls_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]],
+ hnnode) {
+diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
+index 1a84bf6..1935153 100644
+--- a/net/netfilter/nf_conntrack_standalone.c
++++ b/net/netfilter/nf_conntrack_standalone.c
+@@ -51,7 +51,7 @@ static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
+ struct hlist_nulls_node *n;
+
+ for (st->bucket = 0;
+- st->bucket < net->ct.htable_size;
++ st->bucket < nf_conntrack_htable_size;
+ st->bucket++) {
+ n = rcu_dereference(net->ct.hash[st->bucket].first);
+ if (!is_a_nulls(n))
+@@ -69,7 +69,7 @@ static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
+ head = rcu_dereference(head->next);
+ while (is_a_nulls(head)) {
+ if (likely(get_nulls_value(head) == st->bucket)) {
+- if (++st->bucket >= net->ct.htable_size)
++ if (++st->bucket >= nf_conntrack_htable_size)
+ return NULL;
+ }
+ head = rcu_dereference(net->ct.hash[st->bucket].first);
+@@ -358,7 +358,7 @@ static ctl_table nf_ct_sysctl_table[] = {
+ {
+ .ctl_name = NET_NF_CONNTRACK_BUCKETS,
+ .procname = "nf_conntrack_buckets",
+- .data = &init_net.ct.htable_size,
++ .data = &nf_conntrack_htable_size,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+@@ -429,7 +429,6 @@ static int nf_conntrack_standalone_init_sysctl(struct net *net)
+ goto out_kmemdup;
+
+ table[1].data = &net->ct.count;
+- table[2].data = &net->ct.htable_size;
+ table[3].data = &net->ct.sysctl_checksum;
+ table[4].data = &net->ct.sysctl_log_invalid;
+
+diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
+index ae66305..6dc4652 100644
+--- a/net/netfilter/xt_conntrack.c
++++ b/net/netfilter/xt_conntrack.c
+@@ -113,8 +113,7 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info,
+ }
+
+ static bool
+-conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par,
+- u16 state_mask, u16 status_mask)
++conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
+ {
+ const struct xt_conntrack_mtinfo2 *info = par->matchinfo;
+ enum ip_conntrack_info ctinfo;
+@@ -137,7 +136,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par,
+ if (test_bit(IPS_DST_NAT_BIT, &ct->status))
+ statebit |= XT_CONNTRACK_STATE_DNAT;
+ }
+- if (!!(state_mask & statebit) ^
++ if (!!(info->state_mask & statebit) ^
+ !(info->invert_flags & XT_CONNTRACK_STATE))
+ return false;
+ }
+@@ -173,7 +172,7 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par,
+ return false;
+
+ if ((info->match_flags & XT_CONNTRACK_STATUS) &&
+- (!!(status_mask & ct->status) ^
++ (!!(info->status_mask & ct->status) ^
+ !(info->invert_flags & XT_CONNTRACK_STATUS)))
+ return false;
+
+@@ -193,17 +192,11 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par,
+ static bool
+ conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
+ {
+- const struct xt_conntrack_mtinfo1 *info = par->matchinfo;
++ const struct xt_conntrack_mtinfo2 *const *info = par->matchinfo;
++ struct xt_match_param newpar = *par;
+
+- return conntrack_mt(skb, par, info->state_mask, info->status_mask);
+-}
+-
+-static bool
+-conntrack_mt_v2(const struct sk_buff *skb, const struct xt_match_param *par)
+-{
+- const struct xt_conntrack_mtinfo2 *info = par->matchinfo;
+-
+- return conntrack_mt(skb, par, info->state_mask, info->status_mask);
++ newpar.matchinfo = *info;
++ return conntrack_mt(skb, &newpar);
+ }
+
+ static bool conntrack_mt_check(const struct xt_mtchk_param *par)
+@@ -216,11 +209,45 @@ static bool conntrack_mt_check(const struct xt_mtchk_param *par)
+ return true;
+ }
+
++static bool conntrack_mt_check_v1(const struct xt_mtchk_param *par)
++{
++ struct xt_conntrack_mtinfo1 *info = par->matchinfo;
++ struct xt_conntrack_mtinfo2 *up;
++ int ret = conntrack_mt_check(par);
++
++ if (ret < 0)
++ return ret;
++
++ up = kmalloc(sizeof(*up), GFP_KERNEL);
++ if (up == NULL) {
++ nf_ct_l3proto_module_put(par->family);
++ return -ENOMEM;
++ }
++
++ /*
++ * The strategy here is to minimize the overhead of v1 matching,
++ * by prebuilding a v2 struct and putting the pointer into the
++ * v1 dataspace.
++ */
++ memcpy(up, info, offsetof(typeof(*info), state_mask));
++ up->state_mask = info->state_mask;
++ up->status_mask = info->status_mask;
++ *(void **)info = up;
++ return true;
++}
++
+ static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
+ {
+ nf_ct_l3proto_module_put(par->family);
+ }
+
++static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par)
++{
++ struct xt_conntrack_mtinfo2 **info = par->matchinfo;
++ kfree(*info);
++ conntrack_mt_destroy(par);
++}
++
+ static struct xt_match conntrack_mt_reg[] __read_mostly = {
+ {
+ .name = "conntrack",
+@@ -228,8 +255,8 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
+ .family = NFPROTO_UNSPEC,
+ .matchsize = sizeof(struct xt_conntrack_mtinfo1),
+ .match = conntrack_mt_v1,
+- .checkentry = conntrack_mt_check,
+- .destroy = conntrack_mt_destroy,
++ .checkentry = conntrack_mt_check_v1,
++ .destroy = conntrack_mt_destroy_v1,
+ .me = THIS_MODULE,
+ },
+ {
+@@ -237,7 +264,7 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
+ .revision = 2,
+ .family = NFPROTO_UNSPEC,
+ .matchsize = sizeof(struct xt_conntrack_mtinfo2),
+- .match = conntrack_mt_v2,
++ .match = conntrack_mt,
+ .checkentry = conntrack_mt_check,
+ .destroy = conntrack_mt_destroy,
+ .me = THIS_MODULE,
+diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
+index 850ffc0..4eb1ac9 100644
+--- a/net/netrom/nr_route.c
++++ b/net/netrom/nr_route.c
+@@ -842,13 +842,12 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ dptr = skb_push(skb, 1);
+ *dptr = AX25_P_NETROM;
+
+- ax25s = nr_neigh->ax25;
+- nr_neigh->ax25 = ax25_send_frame(skb, 256,
+- (ax25_address *)dev->dev_addr,
+- &nr_neigh->callsign,
+- nr_neigh->digipeat, nr_neigh->dev);
+- if (ax25s)
++ ax25s = ax25_send_frame(skb, 256, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->digipeat, nr_neigh->dev);
++ if (nr_neigh->ax25 && ax25s) {
++ /* We were already holding this ax25_cb */
+ ax25_cb_put(ax25s);
++ }
++ nr_neigh->ax25 = ax25s;
+
+ dev_put(dev);
+ ret = (nr_neigh->ax25 != NULL);
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 41866eb..f2d116a 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -1028,20 +1028,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
+
+ status = TP_STATUS_SEND_REQUEST;
+ err = dev_queue_xmit(skb);
+- if (unlikely(err > 0)) {
+- err = net_xmit_errno(err);
+- if (err && __packet_get_status(po, ph) ==
+- TP_STATUS_AVAILABLE) {
+- /* skb was destructed already */
+- skb = NULL;
+- goto out_status;
+- }
+- /*
+- * skb was dropped but not destructed yet;
+- * let's treat it like congestion or err < 0
+- */
+- err = 0;
+- }
++ if (unlikely(err > 0 && (err = net_xmit_errno(err)) != 0))
++ goto out_xmit;
+ packet_increment_head(&po->tx_ring);
+ len_sum += tp_len;
+ } while (likely((ph != NULL) || ((!(msg->msg_flags & MSG_DONTWAIT))
+@@ -1051,6 +1039,9 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
+ err = len_sum;
+ goto out_put;
+
++out_xmit:
++ skb->destructor = sock_wfree;
++ atomic_dec(&po->tx_ring.pending);
+ out_status:
+ __packet_set_status(po, ph, status);
+ kfree_skb(skb);
+diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
+index 5ef5f69..bd86a63 100644
+--- a/net/rose/rose_link.c
++++ b/net/rose/rose_link.c
+@@ -101,17 +101,13 @@ static void rose_t0timer_expiry(unsigned long param)
+ static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh)
+ {
+ ax25_address *rose_call;
+- ax25_cb *ax25s;
+
+ if (ax25cmp(&rose_callsign, &null_ax25_address) == 0)
+ rose_call = (ax25_address *)neigh->dev->dev_addr;
+ else
+ rose_call = &rose_callsign;
+
+- ax25s = neigh->ax25;
+ neigh->ax25 = ax25_send_frame(skb, 260, rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
+- if (ax25s)
+- ax25_cb_put(ax25s);
+
+ return (neigh->ax25 != NULL);
+ }
+@@ -124,17 +120,13 @@ static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh)
+ static int rose_link_up(struct rose_neigh *neigh)
+ {
+ ax25_address *rose_call;
+- ax25_cb *ax25s;
+
+ if (ax25cmp(&rose_callsign, &null_ax25_address) == 0)
+ rose_call = (ax25_address *)neigh->dev->dev_addr;
+ else
+ rose_call = &rose_callsign;
+
+- ax25s = neigh->ax25;
+ neigh->ax25 = ax25_find_cb(rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
+- if (ax25s)
+- ax25_cb_put(ax25s);
+
+ return (neigh->ax25 != NULL);
+ }
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 08230fa..f3e2198 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -234,8 +234,6 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+
+ if ((s = rose_neigh_list) == rose_neigh) {
+ rose_neigh_list = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+ kfree(rose_neigh->digipeat);
+ kfree(rose_neigh);
+ return;
+@@ -244,8 +242,6 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+ while (s != NULL && s->next != NULL) {
+ if (s->next == rose_neigh) {
+ s->next = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+ kfree(rose_neigh->digipeat);
+ kfree(rose_neigh);
+ return;
+@@ -814,7 +810,6 @@ void rose_link_failed(ax25_cb *ax25, int reason)
+
+ if (rose_neigh != NULL) {
+ rose_neigh->ax25 = NULL;
+- ax25_cb_put(ax25);
+
+ rose_del_route_by_neigh(rose_neigh);
+ rose_kill_by_neigh(rose_neigh);
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index 9c5a19d..fc6a43c 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -485,7 +485,7 @@ gss_refresh_upcall(struct rpc_task *task)
+ dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid,
+ cred->cr_uid);
+ gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
+- if (PTR_ERR(gss_msg) == -EAGAIN) {
++ if (IS_ERR(gss_msg) == -EAGAIN) {
+ /* XXX: warning on the first, under the assumption we
+ * shouldn't normally hit this case on a refresh. */
+ warn_gssd();
+@@ -644,22 +644,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
+ p = gss_fill_context(p, end, ctx, gss_msg->auth->mech);
+ if (IS_ERR(p)) {
+ err = PTR_ERR(p);
+- switch (err) {
+- case -EACCES:
+- gss_msg->msg.errno = err;
+- err = mlen;
+- break;
+- case -EFAULT:
+- case -ENOMEM:
+- case -EINVAL:
+- case -ENOSYS:
+- gss_msg->msg.errno = -EAGAIN;
+- break;
+- default:
+- printk(KERN_CRIT "%s: bad return from "
+- "gss_fill_context: %ld\n", __func__, err);
+- BUG();
+- }
++ gss_msg->msg.errno = (err == -EAGAIN) ? -EAGAIN : -EACCES;
+ goto err_release_msg;
+ }
+ gss_msg->ctx = gss_get_ctx(ctx);
+diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
+index 2deb0ed..ef45eba 100644
+--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
++++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
+@@ -131,10 +131,8 @@ gss_import_sec_context_kerberos(const void *p,
+ struct krb5_ctx *ctx;
+ int tmp;
+
+- if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) {
+- p = ERR_PTR(-ENOMEM);
++ if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS)))
+ goto out_err;
+- }
+
+ p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
+ if (IS_ERR(p))
+diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
+index 76e4c6f..6efbb0c 100644
+--- a/net/sunrpc/auth_gss/gss_mech_switch.c
++++ b/net/sunrpc/auth_gss/gss_mech_switch.c
+@@ -252,7 +252,7 @@ gss_import_sec_context(const void *input_token, size_t bufsize,
+ struct gss_ctx **ctx_id)
+ {
+ if (!(*ctx_id = kzalloc(sizeof(**ctx_id), GFP_KERNEL)))
+- return -ENOMEM;
++ return GSS_S_FAILURE;
+ (*ctx_id)->mech_type = gss_mech_get(mech);
+
+ return mech->gm_ops
+diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
+index 0266cca..df124f7 100644
+--- a/net/sunrpc/svc_xprt.c
++++ b/net/sunrpc/svc_xprt.c
+@@ -711,8 +711,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
+ spin_unlock_bh(&pool->sp_lock);
+
+ len = 0;
+- if (test_bit(XPT_LISTENER, &xprt->xpt_flags) &&
+- !test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
++ if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
+ struct svc_xprt *newxpt;
+ newxpt = xprt->xpt_ops->xpo_accept(xprt);
+ if (newxpt) {
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index 0d86248..0a6b7a0 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -94,18 +94,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
+ }
+ }
+
+- /*
+- * We might be coming here because the driver reported
+- * a successful association at the same time as the
+- * user requested a deauth. In that case, we will have
+- * removed the BSS from the auth_bsses list due to the
+- * deauth request when the assoc response makes it. If
+- * the two code paths acquire the lock the other way
+- * around, that's just the standard situation of a
+- * deauth being requested while connected.
+- */
+- if (!bss)
+- goto out;
++ WARN_ON(!bss);
+ } else if (wdev->conn) {
+ cfg80211_sme_failed_assoc(wdev);
+ need_connect_result = false;
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index efd24a7..f256dff 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -1714,7 +1714,7 @@ int regulatory_hint_user(const char *alpha2)
+ request->wiphy_idx = WIPHY_IDX_STALE;
+ request->alpha2[0] = alpha2[0];
+ request->alpha2[1] = alpha2[1];
+- request->initiator = NL80211_REGDOM_SET_BY_USER;
++ request->initiator = NL80211_REGDOM_SET_BY_USER,
+
+ queue_regulatory_request(request);
+
+diff --git a/net/wireless/sme.c b/net/wireless/sme.c
+index b2930e3..9f0b280 100644
+--- a/net/wireless/sme.c
++++ b/net/wireless/sme.c
+@@ -655,7 +655,6 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+- wdev->wext.connect.ssid_len = 0;
+ #endif
+ }
+
+diff --git a/security/Makefile b/security/Makefile
+index 510bbc8..95ecc06 100644
+--- a/security/Makefile
++++ b/security/Makefile
+@@ -8,8 +8,7 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack
+ subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
+
+ # always enable default capabilities
+-obj-y += commoncap.o
+-obj-$(CONFIG_MMU) += min_addr.o
++obj-y += commoncap.o min_addr.o
+
+ # Object file lists
+ obj-$(CONFIG_SECURITY) += security.o capability.o
+diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
+index 1cad4c7..06ec722 100644
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -1236,7 +1236,6 @@ long keyctl_get_security(key_serial_t keyid,
+ */
+ long keyctl_session_to_parent(void)
+ {
+-#ifdef TIF_NOTIFY_RESUME
+ struct task_struct *me, *parent;
+ const struct cred *mycred, *pcred;
+ struct cred *cred, *oldcred;
+@@ -1327,15 +1326,6 @@ not_permitted:
+ error_keyring:
+ key_ref_put(keyring_r);
+ return ret;
+-
+-#else /* !TIF_NOTIFY_RESUME */
+- /*
+- * To be removed when TIF_NOTIFY_RESUME has been implemented on
+- * m68k/xtensa
+- */
+-#warning TIF_NOTIFY_RESUME not implemented
+- return -EOPNOTSUPP;
+-#endif /* !TIF_NOTIFY_RESUME */
+ }
+
+ /*****************************************************************************/
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+index 36d9e25..bb230d5 100644
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -2366,7 +2366,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
+ initrlim = init_task.signal->rlim + i;
+ rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
+ }
+- update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur);
++ update_rlimit_cpu(rlim->rlim_cur);
+ }
+ }
+
+diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
+index 885683a..83ed1ba 100644
+--- a/sound/arm/Kconfig
++++ b/sound/arm/Kconfig
+@@ -11,6 +11,21 @@ menuconfig SND_ARM
+
+ if SND_ARM
+
++config SND_TMPA910_WM8976
++ tristate "TMPA910 WM8976 driver"
++ depends on ARCH_TMPA910 && SND
++ select SND_PCM
++ help
++ Say Y here if you have a Toshiba tmpa910 EVB
++ and want to use its WM8976 audio chip.
++
++config SND_TMPA910_PCM1773
++ tristate "TMPA910 PCM1773 driver"
++ depends on ARCH_TMPA910 && SND
++ select SND_PCM
++ help
++ Say Y here if you have a Toshiba tmpa910
++ and want to use the TOPAS910 PCM1773 audio chip.
+ config SND_ARMAACI
+ tristate "ARM PrimeCell PL041 AC Link support"
+ depends on ARM_AMBA
+diff --git a/sound/arm/Makefile b/sound/arm/Makefile
+index 5a549ed..8e501df 100644
+--- a/sound/arm/Makefile
++++ b/sound/arm/Makefile
+@@ -2,6 +2,12 @@
+ # Makefile for ALSA
+ #
+
++obj-$(CONFIG_SND_TMPA910_WM8976) += snd-tmpa910-wm8976.o
++snd-tmpa910-wm8976-objs := tmpa910_i2s.o wm8976.o
++
++obj-$(CONFIG_SND_TMPA910_PCM1773) += snd-tmpa910-pcm1773.o
++snd-tmpa910-pcm1773-objs := tmpa910_i2s.o pcm1773.o
++
+ obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o
+ snd-aaci-objs := aaci.o devdma.o
+
+diff --git a/sound/arm/pcm1773.c b/sound/arm/pcm1773.c
+new file mode 100644
+index 0000000..564c278
+--- /dev/null
++++ b/sound/arm/pcm1773.c
+@@ -0,0 +1,490 @@
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
++#include <asm/irq.h>
++#include <asm/delay.h>
++
++#include <sound/core.h>
++#include <sound/info.h>
++#include <sound/control.h>
++#include <sound/pcm.h>
++#define SNDRV_GET_ID
++#include <sound/initval.h>
++
++#include <mach/dma.h>
++#include <mach/irqs.h>
++#include <mach/tmpa910_regs.h>
++
++#include "tmpa910_i2s.h"
++
++#define I2S_DMA_RX I2S0
++#define I2S_DMA_TX I2S1
++#define I2S_IRQ_ERR I2S_INT
++
++
++/***********/
++/***********/
++
++#undef CONFIG_SND_DEBUG_CURRPTR /* causes output every frame! */
++//#define CONFIG_SND_DEBUG_CURRPTR
++
++#undef NOCONTROLS /* define this to omit all the ALSA controls */
++
++#define DRIVER_NAME "PCM1773-I2S"
++#define CHIP_NAME "BB PCM1773"
++#define PCM_NAME "PCM1773_PCM"
++
++/* Only one PCM1773 soundcard is supported */
++static struct platform_device *g_device = NULL;
++
++
++/* Chip level */
++#define PCM1773_BUF_SZ 0x10000 /* 64kb */
++#define PCM_BUFFER_MAX (PCM1773_BUF_SZ / 2)
++
++#define CHANNELS_OUTPUT 2
++#define FRAGMENTS_MIN 2
++#define FRAGMENTS_MAX 32
++
++#define AUDIO_RATE_DEFAULT 32000
++
++typedef struct snd_pcm1773 pcm1773_t;
++typedef struct snd_pcm_substream snd_pcm_substream_t;
++typedef struct snd_pcm_hardware snd_pcm_hardware_t;
++typedef struct snd_pcm_hw_params snd_pcm_hw_params_t;
++typedef struct snd_pcm_runtime snd_pcm_runtime_t;
++typedef struct snd_pcm_ops snd_pcm_ops_t;
++
++struct snd_pcm1773 {
++
++ struct snd_card *card;
++ struct tmpa910_i2s *i2s;
++ spinlock_t pcm1773_lock;
++
++ struct snd_pcm *pcm;
++
++ /* if non-null, current subtream running */
++ snd_pcm_substream_t *tx_substream;
++};
++
++static void init_pcm1773(void)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++
++ /* I2S Register Set */
++ I2SCOMMON = 0x18; // IISSCLK = Fosch(X1), Set SCK/WS/CLKO of Tx and Rx as Common
++
++ // The codec hardware officially supports
++ // only 41.1 Khz freq but it works also
++ // well with others. We use 31.25 Khz because
++ // it is pretty close to 32Khz. The audiable resut is
++ // ok
++ I2STMCON = 0x05; // I2SMCLK = Fosch/2 = 12MHz
++ // I2SSCLK = 12MHz/12 = 1000KHz
++ // I2SWS = 1000KHz/32 = 31.25KHz
++
++ I2SRMCON = 0x04;
++ I2STCON = 0x00; // IIS Standard Format
++ I2STFCLR = 0x01; // Clear FIFO
++ I2STMS = 0x01; // MasterTx
++
++ local_irq_restore(flags);
++}
++
++/*======================================*/
++/* AUDIO CLOCK INTERFACE */
++static void enable_audio_sysclk(void)
++{
++}
++
++static void disable_audio_sysclk(void)
++{
++}
++
++
++/*************************************************************
++ * pcm methods
++ *************************************************************/
++
++static snd_pcm_hardware_t snd_pcm1773_playback_hw = {
++ .info = ( SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER ),
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ .rates = SNDRV_PCM_RATE_32000,
++ .rate_min = AUDIO_RATE_DEFAULT,
++ .rate_max = AUDIO_RATE_DEFAULT,
++ .channels_min = 2,
++ .channels_max = 2,
++ .buffer_bytes_max = PCM_BUFFER_MAX,
++ .period_bytes_min = 0x1000, //4KB
++ .period_bytes_max = 0x1000, //8KB
++ .periods_min = FRAGMENTS_MIN,
++ .periods_max = FRAGMENTS_MAX,
++};
++
++static int snd_pcm1773_playback_open(snd_pcm_substream_t *substream)
++{
++ pcm1773_t *chip = snd_pcm_substream_chip(substream);
++
++ chip->tx_substream = substream;
++ substream->runtime->hw = snd_pcm1773_playback_hw;
++
++ return 0;
++}
++
++static int snd_pcm1773_playback_close(snd_pcm_substream_t *substream)
++{
++ pcm1773_t *chip = snd_pcm_substream_chip(substream);
++
++ chip->tx_substream = NULL;
++
++ return 0;
++}
++
++//I2S in following
++static int snd_pcm1773_hw_params(snd_pcm_substream_t *substream,
++ snd_pcm_hw_params_t *hwparams)
++{
++ /*
++ * Allocate all available memory for our DMA buffer.
++ * Necessary because we get a 4x increase in bytes for the 2 channel mode.
++ * (we lie to the ALSA midlayer through the hwparams data)
++ * We're relying on the driver not supporting full duplex mode
++ * to allow us to grab all the memory.
++ */
++ //printk("params_buffer_bytes return %d\n", params_buffer_bytes(hwparams));
++ if( snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hwparams)) < 0 )
++ return -ENOMEM;
++ return 0;
++}
++
++static int snd_pcm1773_hw_free(snd_pcm_substream_t * substream)
++{
++ snd_pcm_lib_free_pages(substream);
++ return 0;
++}
++
++static int snd_pcm1773_playback_prepare(snd_pcm_substream_t *substream)
++{
++
++ pcm1773_t *chip = snd_pcm_substream_chip(substream);
++ snd_pcm_runtime_t *runtime = substream->runtime;
++
++ int fragsize_bytes = frames_to_bytes(runtime, runtime->period_size);
++
++ int err = 0;
++ int word_len = 4;
++
++// snd_assert((substream == chip->tx_substream), return -EINVAL);
++
++ snd_printd(KERN_INFO "channels:%d, period_bytes:0x%lx, periods:%d\n",
++ runtime->channels,
++ frames_to_bytes(runtime, runtime->period_size),
++ runtime->periods);
++
++ err = tmpa910_i2s_config_tx_dma(chip->i2s, runtime->dma_area, runtime->dma_addr,
++ runtime->periods, fragsize_bytes, word_len);
++
++ return err;
++}
++
++static int snd_pcm1773_playback_trigger(snd_pcm_substream_t *substream, int cmd)
++{
++ pcm1773_t *chip = snd_pcm_substream_chip(substream);
++
++ spin_lock(&chip->pcm1773_lock);
++ switch (cmd)
++ {
++ case SNDRV_PCM_TRIGGER_START:
++ //printk(" SNDRV_PCM_TRIGGER_START\n");
++ tmpa910_i2s_tx_start(chip->i2s);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ tmpa910_i2s_tx_stop(chip->i2s);
++ //printk(" SNDRV_PCM_TRIGGER_STOP\n");
++ break;
++ default:
++ spin_unlock(&chip->pcm1773_lock);
++ return -EINVAL;
++ }
++ spin_unlock(&chip->pcm1773_lock);
++
++ snd_printd(KERN_INFO "playback cmd:%s\n", cmd?"start":"stop");
++
++ return 0;
++}
++
++static snd_pcm_uframes_t snd_pcm1773_playback_pointer(snd_pcm_substream_t *substream)
++{
++ pcm1773_t *chip = snd_pcm_substream_chip(substream);
++ snd_pcm_runtime_t *runtime = substream->runtime;
++ unsigned int offset;
++
++ // snd_printk_marker();
++
++ offset = tmpa910_i2s_curr_offset_tx(chip->i2s);
++
++ offset = bytes_to_frames(runtime, offset);
++ if (offset >= runtime->buffer_size)
++ offset = 0;
++
++ // printk("runtime: 0x%p, offset:0x%x\n", runtime, offset);
++ // tmpa910_i2s_hw_dump();
++ // tmpa910_i2s_dma_dump();
++
++ return offset;
++}
++
++/* pcm method tables */
++static snd_pcm_ops_t snd_pcm1773_playback_ops = {
++ .open = snd_pcm1773_playback_open,
++ .close = snd_pcm1773_playback_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = snd_pcm1773_hw_params,
++ .hw_free = snd_pcm1773_hw_free,
++ .prepare = snd_pcm1773_playback_prepare,
++ .trigger = snd_pcm1773_playback_trigger,
++ .pointer = snd_pcm1773_playback_pointer,
++};
++
++/*************************************************************
++ * card and device
++ *************************************************************/
++static int snd_pcm1773_stop(struct snd_pcm1773 *chip)
++{
++ return 0;
++}
++
++static int snd_pcm1773_dev_free(struct snd_device *device)
++{
++ struct snd_pcm1773 *chip = (pcm1773_t *)device->device_data;
++
++ return snd_pcm1773_stop(chip);
++}
++
++static struct snd_device_ops snd_pcm1773_ops = {
++ .dev_free = snd_pcm1773_dev_free,
++};
++
++static int snd_pcm1773_configure(pcm1773_t *chip)
++{
++ int err = 0;
++ struct tmpa910_i2s *i2s= chip->i2s;
++
++ err = err | tmpa910_i2s_config_tx(i2s);
++
++ if (err)
++ {
++ snd_printk(KERN_ERR "Unable to set i2s configuration\n");
++ }
++
++ return err;
++}
++
++static void snd_pcm1773_dma_tx(void *data)
++{
++ struct snd_pcm1773 *pcm1773 = data;
++ unsigned tmp;
++
++ // tmpa910_i2s_hw_dump();
++ // tmpa910_i2s_dma_dump();
++
++ if (pcm1773->tx_substream)
++ {
++ snd_pcm_period_elapsed(pcm1773->tx_substream);
++
++ tmp = I2SINT;
++ // printk("I2SINT: 0x%x\n", tmp);
++ //printk("DMACSoftBReq: 0x%03x\n", DMACSoftBReq);
++ if (tmp)
++ {
++ I2SINT = tmp;
++ I2STFCLR = 0x01; // Clear FIFO
++ //printk("I2SINT: 0x%x\n", tmp);
++ }
++ }
++ //printk("DMACSoftBReq: 0x%03x\n", DMACSoftBReq);
++}
++
++static void snd_pcm1773_i2s_err(void *data)
++{
++ printk(KERN_ERR DRIVER_NAME ":%s: err happened on i2s\n", __FUNCTION__);
++}
++
++static int __devinit snd_pcm1773_pcm(struct snd_pcm1773 *pcm1773)
++{
++ struct snd_pcm *pcm;
++ int err = 0;
++
++ /* 1 playback substream, of 2-8 channels each */
++ if((err = snd_pcm_new(pcm1773->card, PCM_NAME, 0, 1, 0, &pcm)) < 0)
++ {
++ return err;
++ }
++
++ /*
++ * this sets up our initial buffers and sets the dma_type to isa.
++ * isa works but I'm not sure why (or if) it's the right choice
++ * this may be too large, trying it for now
++ */
++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
++ snd_dma_isa_data(), PCM1773_BUF_SZ, 0);
++
++
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_pcm1773_playback_ops);
++ pcm1773->pcm = pcm;
++ pcm->info_flags = 0;
++
++ strcpy(pcm->name, PCM_NAME);
++ pcm->private_data = pcm1773;
++
++ return 0;
++}
++
++static int __devinit snd_pcm1773_probe(struct platform_device *pdev)
++{
++ int err = 0;
++ struct snd_card *card = NULL;
++ struct snd_pcm1773 *pcm1773;
++ struct tmpa910_i2s *i2s;
++ char * id = "TMPA910 + PCM1773";
++
++
++ if (g_device != NULL)
++ return -ENOENT;
++
++ snd_card_create(-1, id, THIS_MODULE, sizeof(struct snd_pcm1773), &card);
++ if (card == NULL) {
++ snd_printdd(KERN_DEBUG "%s: snd_card_new() failed\n", __FUNCTION__);
++ printk("snd_card_new faild.\n");
++ return -ENOMEM;
++ }
++
++ pcm1773 = card->private_data;
++ pcm1773->card = card;
++ if ((i2s = tmpa910_i2s_init(0, NULL, I2S_DMA_TX, snd_pcm1773_dma_tx,
++ I2S_IRQ_ERR, snd_pcm1773_i2s_err, pcm1773)) == NULL)
++ {
++ printk(KERN_ERR DRIVER_NAME ": Failed to find device on i2s\n");
++ err = -ENODEV;
++ goto __i2s_err;
++ }
++
++ pcm1773->i2s = i2s;
++
++ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pcm1773, &snd_pcm1773_ops);
++ if (err)
++ {
++ printk(KERN_ERR "snd_device_new faild.\n");
++ goto __nodev;
++ }
++
++ if ((err = snd_pcm1773_pcm(pcm1773)) < 0)
++ {
++ printk(KERN_ERR "snd_pcm1773_pcm faild.\n");
++ goto __nodev;
++ }
++
++ if ((err = snd_pcm1773_configure(pcm1773)) < 0)
++ {
++ printk(KERN_ERR "snd_pcm1773_configure faild.\n");
++ goto __nodev;
++ }
++
++ strcpy(card->driver, DRIVER_NAME);
++ strcpy(card->shortname, CHIP_NAME);
++ sprintf(card->longname, "%s at I2S tx dma %d err irq %d",
++ card->shortname,
++ I2S_DMA_TX, I2S_IRQ_ERR);
++
++ snd_card_set_dev(card, &pdev->dev);
++
++ if ((err = snd_card_register(card)) < 0)
++ {
++ printk(KERN_ERR "snd_card_register faild.\n");
++ goto __nodev;
++ }
++
++ platform_set_drvdata(pdev, card);
++
++ return 0;
++
++__nodev:
++ tmpa910_i2s_free(i2s);
++__i2s_err:
++ snd_card_free(card);
++
++ return err;
++}
++
++static int __devexit snd_pcm1773_remove(struct platform_device *pdev)
++{
++ struct snd_card *card;
++ struct snd_pcm1773 *pcm1773;
++
++ card = platform_get_drvdata(pdev);
++ pcm1773 = card->private_data;
++
++ snd_pcm1773_stop(pcm1773);
++ tmpa910_i2s_free(pcm1773->i2s);
++
++ snd_card_free(card);
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++#define TMPA910_PCM1773_DRIVER "tmpa910_pcm1773"
++static struct platform_driver snd_pcm1773_driver = {
++ .probe = snd_pcm1773_probe,
++ .remove = __devexit_p(snd_pcm1773_remove),
++ .driver = {
++ .name = DRIVER_NAME,
++ },
++};
++
++static int __init snd_pcm1773_init(void)
++{
++ int err;
++
++ init_pcm1773();
++ enable_audio_sysclk();
++
++ if ((err = platform_driver_register(&snd_pcm1773_driver)) < 0)
++ {
++ printk(KERN_ERR "platform_driver_register failed. ret=%d\n", platform_driver_register);
++ return err;
++ }
++
++ g_device = platform_device_register_simple(DRIVER_NAME,
++ 0, NULL, 0);
++
++ if (g_device==NULL)
++ {
++ printk(KERN_ERR "platform_device_register_simple failed\n");
++ return -ENODEV;
++ }
++
++ return 0;
++}
++
++static void __exit snd_pcm1773_exit(void)
++{
++ if (g_device)
++ {
++ platform_device_unregister(g_device);
++ platform_driver_unregister(&snd_pcm1773_driver);
++ disable_audio_sysclk();
++ }
++}
++
++MODULE_AUTHOR("OPEN-engineering.de <info at open-engineering.de>");
++MODULE_DESCRIPTION("TMPA910/PCM1773");
++MODULE_LICENSE("GPL");
++
++module_init(snd_pcm1773_init);
++module_exit(snd_pcm1773_exit);
++
+diff --git a/sound/arm/tmpa910_i2s.c b/sound/arm/tmpa910_i2s.c
+new file mode 100644
+index 0000000..3dc9a57
+--- /dev/null
++++ b/sound/arm/tmpa910_i2s.c
+@@ -0,0 +1,457 @@
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++
++#include <asm/bug.h>
++#include <asm/dma.h>
++#include <asm/cacheflush.h>
++#include <mach/dma.h>
++#include <mach/tmpa910_regs.h>
++
++#include "tmpa910_i2s.h"
++
++#undef TMPA910_I2S_DEBUG
++
++#ifdef TMPA910_I2S_DEBUG
++#define i2s_printd(level, format, arg...) \
++ printk(level "i2s: " format, ## arg)
++#define I2S_ASSERT(expr) \
++ do { \
++ if (unlikely(!(expr))) { \
++ printk(KERN_ERR "%s: %d, bug\n", __FUNCTION__, __LINE__); \
++ } \
++ } while(0)
++#else
++#define i2s_printd(level, format, arg...)
++#define I2S_ASSERT(expr)
++#endif
++
++int tmpa910_i2s_config_tx(struct tmpa910_i2s *i2s)
++{
++ return 0;
++}
++
++static void setup_tx_desc(struct scatter_dma_t *desc, unsigned int phydesc,
++ unsigned int phy_buf, int fragcount, size_t fragsize)
++{
++ int i;
++
++ for (i=0; i<fragcount; i++)
++ {
++ desc[i].lli = (unsigned long)(phydesc + (i + 1) * sizeof(struct scatter_dma_t));
++ desc[i].srcaddr = (unsigned long)(phy_buf + i*fragsize); //Phy Addr
++ desc[i].dstaddr = (unsigned long)I2STDAT_ADR;
++ desc[i].control = 0x84492000 + (unsigned long)(fragsize >> 2);
++ }
++
++ /* make circular */
++ desc[fragcount-1].lli = (unsigned long)phydesc;
++}
++
++static void setup_rx_desc(struct scatter_dma_t *desc, unsigned int phydesc,
++ unsigned int phy_buf, int fragcount, size_t fragsize)
++{
++ int i;
++
++ //printk("The fragcount is %d.\n",fragcount);
++
++ for (i=0; i<fragcount; ++i)
++ {
++ desc[i].lli = (unsigned long)(phydesc + (i + 1) * sizeof(struct scatter_dma_t));
++ desc[i].srcaddr = (unsigned long)I2SRDAT_ADR;
++ desc[i].dstaddr = (unsigned long)(phy_buf + i*fragsize); //Phy Addr
++ desc[i].control = 0x88492000 + (unsigned long)(fragsize >> 2);
++ }
++
++ /* make circular */
++ desc[fragcount-1].lli = (unsigned long)phydesc;
++}
++
++static int i2s_tx_start(struct tmpa910_i2s *i2s)
++{
++ tmpa910_dma_enable(i2s->dma_tx_ch);
++
++ /* I2S DMA set complete */
++ I2STDMA1 = 0x0001;
++ /* I2S transfer start */
++ I2STSLVON = 0x0001;
++
++ //printk("====> Start TX I2S\n");
++ return 0;
++}
++
++static int i2s_rx_start(struct tmpa910_i2s *i2s)
++{
++ tmpa910_dma_enable(i2s->dma_rx_ch);
++
++ /*----I2S DMA set complete */
++ I2SRDMA1 = 0x0001;
++
++ /*----I2S transfer start */
++ I2SRSLVON = 0x0001;
++
++ //printk("====> Start RX I2S\n");
++ return 0;
++}
++
++static int i2s_tx_stop(struct tmpa910_i2s *i2s)
++{
++ I2STDMA1 = 0x0000;
++ I2STSLVON = 0x0000;
++
++ tmpa910_dma_disable(i2s->dma_tx_ch);
++
++ //printk("====> Stop TX I2S\n");
++
++ return 0;
++}
++
++static int i2s_rx_stop(struct tmpa910_i2s *i2s)
++{
++ I2SRDMA1 = 0x0000;
++ I2SRSLVON = 0x0000;
++
++ tmpa910_dma_disable(i2s->dma_rx_ch);
++
++ //printk("====> Stop RX I2S\n");
++
++ return 0;
++}
++
++static inline int i2s_tx_dma_start(struct tmpa910_i2s *i2s)
++{
++ int dma_ch = i2s->dma_tx_ch;
++ struct scatter_dma_t *dma_desc;
++
++ i2s->curr_tx_desc = i2s->dma_tx_desc;
++ dma_desc = i2s->curr_tx_desc;
++
++ DMA_SRC_ADDR(dma_ch) = dma_desc->srcaddr;
++ DMA_DEST_ADDR(dma_ch) = dma_desc->dstaddr;
++ DMA_LLI(dma_ch) = dma_desc->lli;
++ DMA_CONTROL(dma_ch) = dma_desc->control;
++ DMA_CONFIG(dma_ch) = 0x00008a81;
++
++ return 0;
++}
++
++static inline int i2s_rx_dma_start(struct tmpa910_i2s *i2s)
++{
++ int dma_ch = i2s->dma_rx_ch;
++ struct scatter_dma_t *dma_desc;
++
++ i2s->curr_rx_desc = i2s->dma_rx_desc;
++ dma_desc = i2s->curr_rx_desc;
++
++ DMA_SRC_ADDR(dma_ch) = dma_desc->srcaddr;
++// printk("srcaddr = 0x%02x\n", dma_desc->srcaddr);
++ DMA_DEST_ADDR(dma_ch) = dma_desc->dstaddr;
++// printk("dest addr = 0x%02x\n", dma_desc->dstaddr);
++ DMA_LLI(dma_ch) = dma_desc->lli;
++// printk("lli addr = 0x%02x\n", dma_desc->lli);
++ DMA_CONTROL(dma_ch) = dma_desc->control;
++// printk("control = 0x%02x\n", dma_desc->control);
++ DMA_CONFIG(dma_ch) = 0x00009017;
++
++ return 0;
++}
++
++int tmpa910_i2s_tx_start(struct tmpa910_i2s *i2s)
++{
++ i2s_printd(KERN_INFO, "%s: tx_run:%d\n", __FUNCTION__, i2s->tx_run);
++
++ if (i2s->tx_run)
++ return -EBUSY;
++
++ i2s_tx_dma_start(i2s);
++ i2s_tx_start(i2s);
++ i2s->tx_run = 1;
++
++ return 0;
++}
++
++int tmpa910_i2s_rx_start(struct tmpa910_i2s *i2s)
++{
++ i2s_printd(KERN_INFO, "%s: rx_run:%d\n", __FUNCTION__, i2s->rx_run);
++
++ if (i2s->rx_run)
++ return -EBUSY;
++
++ i2s_rx_dma_start(i2s);
++ i2s_rx_start(i2s);
++ i2s->rx_run = 1;
++
++ return 0;
++}
++
++int tmpa910_i2s_tx_stop(struct tmpa910_i2s *i2s)
++{
++ if (!i2s->tx_run)
++ return 0;
++
++ /* Both rx and tx dma stopped */
++ i2s_tx_stop(i2s);
++ i2s->curr_tx_desc = NULL;
++
++ i2s->tx_run = 0;
++
++ return 0;
++}
++
++int tmpa910_i2s_rx_stop(struct tmpa910_i2s *i2s)
++{
++ if (!i2s->rx_run)
++ return 0;
++
++ i2s_rx_stop(i2s);
++ i2s->curr_rx_desc = NULL;
++
++ i2s->rx_run = 0;
++
++ return 0;
++}
++
++int tmpa910_i2s_config_tx_dma(struct tmpa910_i2s *i2s,
++ unsigned char *cpu_buf, unsigned int phy_buf,
++ int fragcount, size_t fragsize, size_t size)
++{
++ unsigned int count;
++ dma_addr_t addr;
++
++ i2s_printd(KERN_INFO, "%s( %p, %X, %d, %x, %x )\n", __FUNCTION__, cpu_buf, phy_buf,
++ fragcount, fragsize, size);
++
++ count = fragsize / size;
++
++ /* for fragments larger than 16k words we use 2d dma,
++ * denote fragecount as two numbers' mutliply and both of them
++ * are less than 64k.*/
++ if (count >= 0x1000)
++ {
++ printk("Error: tx dma size too large %d\n", count);
++ return -EINVAL;
++ }
++
++ if (i2s->dma_tx_desc)
++ {
++ dma_free_coherent(NULL, i2s->tx_desc_bytes, i2s->dma_tx_desc, 0);
++ }
++
++ i2s->dma_tx_desc = dma_alloc_coherent(NULL, fragcount * sizeof(struct scatter_dma_t), &addr, 0);
++ i2s->tx_desc_bytes = fragcount * sizeof(struct scatter_dma_t);
++ i2s->dma_tx_phydesc = addr;
++ i2s->dma_tx_buf = phy_buf;
++
++ if (!i2s->dma_tx_desc)
++ {
++ return -ENOMEM;
++ }
++
++ setup_tx_desc(i2s->dma_tx_desc, addr, phy_buf, fragcount, fragsize);
++
++ return 0;
++}
++
++int tmpa910_i2s_config_rx_dma(struct tmpa910_i2s *i2s,
++ unsigned char *cpu_buf, unsigned int phy_buf,
++ int fragcount, size_t fragsize, size_t size)
++{
++ unsigned int count;
++ dma_addr_t addr;
++
++ i2s_printd(KERN_INFO, "%s( %p, %X, %d, %x, %x )\n", __FUNCTION__, cpu_buf, phy_buf,
++ fragcount, fragsize, size);
++
++ count = fragsize / size;
++
++ /* for fragments larger than 16k words we use 2d dma,
++ * denote fragecount as two numbers' mutliply and both of them
++ * are less than 64k.*/
++ if (count >= 0x1000)
++ {
++ printk("Error: rx dma size too large %d\n", count);
++ return -EINVAL;
++ }
++
++ if (i2s->dma_rx_desc)
++ {
++ dma_free_coherent(NULL, i2s->rx_desc_bytes, i2s->dma_rx_desc, 0);
++ }
++
++ i2s->dma_rx_desc = dma_alloc_coherent(NULL, fragcount * sizeof(struct scatter_dma_t), &addr, 0);
++ i2s->rx_desc_bytes = fragcount * sizeof(struct scatter_dma_t);
++ i2s->dma_rx_phydesc = addr;
++ i2s->dma_rx_buf = phy_buf;
++
++ if (!i2s->dma_rx_desc)
++ {
++ return -ENOMEM;
++ }
++
++ setup_rx_desc(i2s->dma_rx_desc, addr, phy_buf, fragcount, fragsize);
++
++ return 0;
++}
++
++
++unsigned int tmpa910_i2s_curr_offset_tx(struct tmpa910_i2s *i2s)
++{
++ int dma_ch = i2s->dma_tx_ch;
++ unsigned int addr, size;
++
++ addr = DMA_SRC_ADDR(dma_ch);
++ size = addr - i2s->dma_tx_buf;
++
++ //printk("size[%d]", size);
++
++ return size;
++}
++
++unsigned int tmpa910_i2s_curr_offset_rx(struct tmpa910_i2s *i2s)
++{
++ int dma_ch = i2s->dma_rx_ch;
++ unsigned int addr, size;
++
++ addr = DMA_DEST_ADDR(dma_ch);
++ size = addr - i2s->dma_rx_buf;
++
++ //printk("size[%d]", size);
++
++ return size;
++}
++
++static int i2s_check_status(struct tmpa910_i2s *i2s,
++ unsigned int *i2s_stat,
++ unsigned int *rx_stat,
++ unsigned int *tx_stat)
++{
++ int status = 0;
++
++ return status;
++}
++
++static void tx_handler(int dma_ch, void *dev_id)
++{
++ unsigned int tx_stat;
++ struct tmpa910_i2s *i2s = dev_id;
++
++ //printk("+");
++
++ //i2s_printd(KERN_INFO, "%s\n", __FUNCTION__);
++ i2s_check_status(i2s, NULL, NULL, &tx_stat);
++
++ if (i2s->tx_callback)
++ {
++ i2s->tx_callback(i2s->data);
++ }
++}
++
++static void rx_handler(int dma_ch, void *dev_id)
++{
++ unsigned int rx_stat;
++ struct tmpa910_i2s *i2s = dev_id;
++
++ //printk("+");
++
++ //i2s_printd(KERN_INFO, "%s\n", __FUNCTION__);
++ i2s_check_status(i2s, NULL, NULL, &rx_stat);
++
++ if (i2s->rx_callback)
++ {
++ i2s->rx_callback(i2s->data);
++ }
++
++ //printk("handler srcaddr = 0x%02x\n", DMA_SRC_ADDR(dma_ch));
++ //printk("handler dest addr = 0x%02x\n", DMA_DEST_ADDR(dma_ch));
++ //printk("handler lli addr = 0x%02x\n", DMA_LLI(dma_ch));
++ //printk("handler control = 0x%02x\n", DMA_CONTROL(dma_ch));
++}
++
++static void err_handler(int dma_ch, void *dev_id)
++{
++ unsigned int status;
++ struct tmpa910_i2s *i2s = dev_id;
++
++ i2s_printd(KERN_INFO, "%s\n", __FUNCTION__);
++ if (i2s_check_status(i2s, &status, NULL, NULL)) {
++ printk(KERN_ERR "error checking status ??");
++ return;
++ }
++
++ if (i2s->err_callback)
++ i2s->err_callback(i2s->data);
++}
++
++struct tmpa910_i2s *tmpa910_i2s_init(
++ int dma_rx, void (*rx_callback)(void*),
++ int dma_tx, void (*tx_callback)(void*),
++ int err_irq, void (*err_callback)(void*),
++ void *data)
++{
++ struct tmpa910_i2s *i2s;
++
++ i2s = kmalloc(sizeof(struct tmpa910_i2s), GFP_KERNEL);
++
++ if (i2s == NULL) {
++ printk("error test pointer 1");
++ return NULL;
++ }
++ memset(i2s, 0, sizeof(struct tmpa910_i2s));
++
++ i2s->dma_tx_ch = tmpa910_dma_request("I2S TX", 1, tx_handler,
++ err_handler, i2s);
++ if (i2s->dma_tx_ch < 0)
++ {
++ printk(KERN_ERR "unable to tx audio dma 0x%x\n", dma_tx);
++ goto __init_err2;
++ }
++ //printk("dma_tx_ch = %d\n", i2s->dma_tx_ch);
++
++ i2s->dma_rx_ch = tmpa910_dma_request("I2S RX", 2, rx_handler,
++ err_handler, i2s);
++ if (i2s->dma_rx_ch < 0)
++ {
++ printk(KERN_ERR "unable to rx audio dma 0x%x\n", dma_rx);
++ goto __init_err1;
++ }
++ //printk("dma_rx_ch = %d\n", i2s->dma_rx_ch);
++
++ i2s->err_irq = err_irq;
++ i2s->rx_callback = rx_callback;
++ i2s->tx_callback = tx_callback;
++ i2s->err_callback = err_callback;
++ i2s->data = data;
++
++ //i2s_printd(KERN_INFO, "dma tx: %p\n", i2s->dma_tx);
++
++ return i2s;
++
++__init_err1:
++ tmpa910_dma_free(i2s->dma_rx_ch);
++__init_err2:
++ kfree(i2s);
++ return NULL;
++}
++
++void tmpa910_i2s_free(struct tmpa910_i2s *i2s)
++{
++ if (i2s == NULL)
++ return;
++
++ i2s_tx_stop(i2s);
++ i2s_rx_stop(i2s);
++
++ if (i2s->dma_tx_desc)
++ {
++ dma_free_coherent(NULL, i2s->tx_desc_bytes, i2s->dma_tx_desc, 0);
++ }
++ if (i2s->dma_rx_desc)
++ {
++ dma_free_coherent(NULL, i2s->rx_desc_bytes, i2s->dma_rx_desc, 0);
++ }
++
++ tmpa910_dma_free(i2s->dma_tx_ch);
++ tmpa910_dma_free(i2s->dma_rx_ch);
++
++ kfree(i2s);
++}
+diff --git a/sound/arm/tmpa910_i2s.h b/sound/arm/tmpa910_i2s.h
+new file mode 100644
+index 0000000..836fa2d
+--- /dev/null
++++ b/sound/arm/tmpa910_i2s.h
+@@ -0,0 +1,83 @@
++#ifndef __TMPA910_I2S_H__
++#define __TMPA910_I2S_H__
++
++#include <linux/types.h>
++#include <linux/wait.h>
++#include <linux/workqueue.h>
++#include <asm/dma.h>
++
++#define DESC_ELEMENT_COUNT 9
++
++struct scatter_dma_t {
++ unsigned long srcaddr;
++ unsigned long dstaddr;
++ unsigned long lli;
++ unsigned long control;
++};
++
++struct tmpa910_i2s {
++ int i2s_num;
++ int err_irq;
++
++ int dma_tx_ch;
++ int dma_rx_ch;
++
++ /* DMA descriptor ring head of current audio stream*/
++ struct scatter_dma_t *dma_tx_desc;
++ unsigned int tx_desc_bytes;
++ unsigned int dma_tx_phydesc;
++ unsigned int dma_tx_buf;
++ unsigned int tx_run; /* tx is running */
++ struct scatter_dma_t *curr_tx_desc;
++
++ struct scatter_dma_t *dma_rx_desc;
++ unsigned int rx_desc_bytes;
++ unsigned int dma_rx_phydesc;
++ unsigned int dma_rx_buf;
++ unsigned int rx_run; /* tx is running */
++ struct scatter_dma_t *curr_rx_desc;
++
++ void (*rx_callback)(void *data);
++ void (*tx_callback)(void *data);
++ void (*err_callback)(void *data);
++ void *data;
++};
++
++struct tmpa910_i2s* tmpa910_i2s_init(
++ int dma_rx, void (*rx_callback)(void *),
++ int dma_tx, void (*tx_callback)(void *),
++ int err_irq, void (*err_callback)(void *),
++ void *data);
++
++void tmpa910_i2s_free(struct tmpa910_i2s* i2s);
++
++/* first use these ...*/
++
++int tmpa910_i2s_config_rx(struct tmpa910_i2s* i2s);
++
++int tmpa910_i2s_config_tx(struct tmpa910_i2s* i2s);
++
++/* ... then these: */
++
++/* buffer size (in bytes) == fragcount * fragsize_bytes */
++
++/* this is not a very general api, it sets the dma to 2d autobuffer mode */
++
++int tmpa910_i2s_config_tx_dma(struct tmpa910_i2s *i2s,
++ unsigned char *cpu_buf, unsigned int phy_buf,
++ int fragcount, size_t fragsize, size_t size);
++
++int tmpa910_i2s_config_rx_dma(struct tmpa910_i2s *i2s,
++ unsigned char *cpu_buf, unsigned int phy_buf,
++ int fragcount, size_t fragsize, size_t size);
++
++int tmpa910_i2s_tx_start(struct tmpa910_i2s* i2s);
++int tmpa910_i2s_tx_stop(struct tmpa910_i2s* i2s);
++int tmpa910_i2s_rx_start(struct tmpa910_i2s* i2s);
++int tmpa910_i2s_rx_stop(struct tmpa910_i2s* i2s);
++
++/* for use in interrupt handler */
++unsigned int tmpa910_i2s_curr_offset_rx(struct tmpa910_i2s* i2s);
++unsigned int tmpa910_i2s_curr_offset_tx(struct tmpa910_i2s* i2s);
++
++#endif /* TMPA910_I2S_H */
+diff --git a/sound/arm/wm8976.c b/sound/arm/wm8976.c
+new file mode 100644
+index 0000000..fd054a6
+--- /dev/null
++++ b/sound/arm/wm8976.c
+@@ -0,0 +1,822 @@
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
++#include <asm/irq.h>
++#include <asm/delay.h>
++
++
++#include <sound/core.h>
++#include <sound/info.h>
++#include <sound/control.h>
++#include <sound/pcm.h>
++#define SNDRV_GET_ID
++#include <sound/initval.h>
++
++#include <mach/dma.h>
++#include <mach/irqs.h>
++#include <mach/tmpa910_regs.h>
++
++#include "tmpa910_i2s.h"
++#include "wm8976.h"
++
++#define I2S_DMA_RX I2S0
++#define I2S_DMA_TX I2S1
++#define I2S_IRQ_ERR I2S_INT
++
++
++#define snd_printk_marker() printk(KERN_DEBUG "->\n");
++#define i2s_printd(level, format, arg...) printk(level format, arg)
++
++#undef snd_printd
++#define snd_printd printk
++#undef CONFIG_SND_DEBUG_CURRPTR /* causes output every frame! */
++//#define CONFIG_SND_DEBUG_CURRPTR
++
++#undef NOCONTROLS /* define this to omit all the ALSA controls */
++
++#define DRIVER_NAME "WM8976-I2S"
++#define CHIP_NAME "Wolfson WM8976"
++#define PCM_NAME "WM8976_PCM"
++
++/* Only one WM8976 soundcard is supported */
++static struct platform_device *g_device = NULL;
++
++
++/* Chip level */
++#define WM8976_BUF_SZ 0x10000 /* 64kb */
++#define PCM_BUFFER_MAX (WM8976_BUF_SZ / 2)
++
++#define CHANNELS_OUTPUT 2
++#define CHANNELS_INPUT 2
++#define FRAGMENTS_MIN 2
++#define FRAGMENTS_MAX 32
++
++#define AUDIO_RATE_DEFAULT 44100
++
++
++static unsigned char wm8976_for_samplerate[7][6]={
++ {0x00,0x08,0x0C,0x93,0xE9,0x49}, //48000HZ
++ {0x00,0x07,0x21,0x61,0x27,0x49}, //44100HZ
++ {0x02,0x08,0x0C,0x93,0xE9,0x69}, //32000HZ
++ {0x04,0x07,0x21,0x61,0x27,0x89}, //22050HZ
++ {0x05,0x07,0x21,0x61,0x27,0xa9}, //16000HZ
++ {0x08,0x07,0x21,0x61,0x27,0xC9}, //12000HZ
++ {0x0a,0x08,0x0C,0x93,0xE9,0xE9}, //8000HZ
++};
++
++
++typedef struct snd_wm8976 wm8976_t;
++typedef struct snd_pcm_substream snd_pcm_substream_t;
++typedef struct snd_pcm_hardware snd_pcm_hardware_t;
++typedef struct snd_pcm_hw_params snd_pcm_hw_params_t;
++typedef struct snd_pcm_runtime snd_pcm_runtime_t;
++typedef struct snd_pcm_ops snd_pcm_ops_t;
++
++struct snd_wm8976 {
++
++ struct snd_card *card;
++ struct tmpa910_i2s *i2s;
++ spinlock_t wm8976_lock;
++
++ struct snd_pcm *pcm;
++
++ int poll_reg; /* index of the wm8976 register last queried */
++
++ /* if non-null, current subtream running */
++ snd_pcm_substream_t *rx_substream;
++ /* if non-null, current subtream running */
++ snd_pcm_substream_t *tx_substream;
++};
++
++/*======================================================*/
++/* WM8976 I2C INTERFACE DEFINE */
++/*======================================================*/
++#define I2C1SR_BUS_CHECK 0x00000020
++#define I2C1SR_BUS_FREE 0x00000000
++
++#define I2C1SR_ACK_CHECK 0x00000010
++#define I2C1SR_ACK_ENABLE 0x00000000
++static void snd_wm8976_set_samplerate(long rate);
++
++static void i2c_bus_free_chk(void)
++{
++ u32 reg_data;
++ do
++ {
++ reg_data = I2C1SR;
++ }while( (reg_data & I2C1SR_BUS_CHECK) != I2C1SR_BUS_FREE );
++}
++
++static void i2c_ack_wait(void)
++{
++ u32 reg_data;
++ do
++ {
++ reg_data = I2C1SR;
++ }while( (reg_data & I2C1SR_ACK_CHECK) != I2C1SR_ACK_ENABLE );
++}
++
++static void i2c_packet_send(u8 sub_addr, u8 data)
++{
++ //printk("[0x%x] <- 0x%3x\n", sub_addr >> 1, data | ((sub_addr&1) << 8) );
++
++ I2C1DBR = 0x34;
++ I2C1CR2 = 0xf8;
++
++ i2c_ack_wait();
++
++ I2C1DBR = sub_addr;
++ i2c_ack_wait();
++
++ I2C1DBR = data;
++ i2c_ack_wait();
++
++ I2C1CR2 = 0xd8;
++ i2c_bus_free_chk();
++}
++
++static void init_wm8976_i2c(void)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++
++ // GPIOMFR1 = 0x0F; // Config IIS Function Port: I2S1DATO
++ I2SCOMMON = 0x19; // IISSCLK = Fosch(X1), Set SCK/WS/CLKO of Tx and Rx as Common
++ I2STMCON = 0x04; // I2SMCLK = Fosch/4 = 11.2896MHz
++
++ I2SRMCON = 0x04;
++
++ I2STCON = 0x00; // IIS Standard Format
++ I2STFCLR = 0x01; // Clear FIFO
++ I2SRMS = 0x00; // Slave
++ I2STMS = 0x00; // Slave
++/*
++ GPIORDIR |= 0X02;
++ GPIORFR1 &= 0Xfd;
++ GPIORFR2 &= 0Xfd;
++ GPIORDATA &= 0Xfd;
++ GPIOCODE = 0xc0;
++ GPIOCFR1 = 0xc0;
++ GPIOCFR2 = 0x00;
++ GPIOCIE = 0x00;
++
++ GPIOFODE = 0xc0;
++ GPIOFFR1 = 0xc0;
++ GPIOFFR2 = 0x00;
++ GPIOFIE = 0x00;
++*/
++ local_irq_restore(flags);
++ i2c_bus_free_chk();
++ I2C1CR2 = 0xc8;
++ I2C1PRS = 0x19;
++ I2C1CR1 = 0x13;
++
++ i2c_packet_send(0x00,0x00);//R0 0X000
++ i2c_packet_send(0x02,0x3d);//R1 0X02D
++// i2c_packet_send(0x05,0x91);//R2 0X191
++ i2c_packet_send(0x05,0x95);//R2 0X195
++ i2c_packet_send(0x06,0x6F);//R3 0X00F
++ i2c_packet_send(0x08,0x10);//R4 0X010
++ i2c_packet_send(0x0a,0x00);//R5 0X000
++// i2c_packet_send(0x0d,0x49);//R6 0X14d
++
++
++// i2c_packet_send(0x0e,0x00);//R7 0X00A //set sample rate 48khz
++
++ i2c_packet_send(0x14, 0x80); //R10 = 0x080
++ i2c_packet_send(0x17,0xff);//R11 0X1ff
++ i2c_packet_send(0x19,0xff);//R12 0X1ff
++ i2c_packet_send(0x1c,0x00); //R14 = 0x1c01
++ i2c_packet_send(0x1F,0xff);//R15 0X1FF
++ i2c_packet_send(0x30, 0x32); //R24 = 0x032
++// i2c_packet_send(0x48,0x07);//R36 0X017
++// i2c_packet_send(0x4A,0x21);//R37 0X012
++// i2c_packet_send(0x4C,0x61);//R38 0X011
++// i2c_packet_send(0x4E,0x27);//R39 0X096 //set pll 12.288Mhz
++// i2c_packet_send(0x58,0x00);//R44 0X000
++ i2c_packet_send(0x5b,0x3f);//R45 0X000
++ i2c_packet_send(0x56,0x10);//R43 0X010 //add for WM8976 8 ohm speaker
++
++ i2c_packet_send(0x5f,0x55);//R47 0X005
++
++ i2c_packet_send(47<<1 | 1,0xff);//R47 0X1ff
++
++ i2c_packet_send(0x62,0x02);//R49 0X002
++ i2c_packet_send(0x64,0x01);//R50 0X001
++ i2c_packet_send(0x66,0x01);//R51 0X001
++ i2c_packet_send(0x69,0x3f);//R52 0X13f
++ i2c_packet_send(0x6b,0x3f);//R53 0X13f
++
++}
++
++static void release_wm8976_i2c(void)
++{
++}
++
++/*======================================*/
++/* AUDIO CLOCK INTERFACE */
++static void enable_audio_sysclk(void)
++{
++}
++
++static void disable_audio_sysclk(void)
++{
++}
++
++
++/*************************************************************
++ * pcm methods
++ *************************************************************/
++
++static snd_pcm_hardware_t snd_wm8976_playback_hw = {
++ .info = ( SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER ),
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++// .rates = SNDRV_PCM_RATE_44100,
++ .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
++ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
++ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
++ SNDRV_PCM_RATE_KNOT),
++ .rate_min = 8000,
++ .rate_max = 48000,
++ .channels_min = 2,
++ .channels_max = 2,
++ .buffer_bytes_max = PCM_BUFFER_MAX,
++ .period_bytes_min = 0x1000, //4KB
++ .period_bytes_max = 0x3000, //8KB
++ .periods_min = FRAGMENTS_MIN,
++ .periods_max = FRAGMENTS_MAX,
++};
++
++static snd_pcm_hardware_t snd_wm8976_capture_hw = {
++ .info = ( SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER ),
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++// .rates = SNDRV_PCM_RATE_44100,
++ .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
++ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
++ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
++ SNDRV_PCM_RATE_KNOT),
++ .rate_min = 8000,
++ .rate_max = 48000,
++ .channels_min = 1,
++ .channels_max = 2,
++ .buffer_bytes_max = PCM_BUFFER_MAX,
++ .period_bytes_min = 0x1000, //4KB
++ .period_bytes_max = 0x3000, //8KB
++ .periods_min = FRAGMENTS_MIN,
++ .periods_max = FRAGMENTS_MAX,
++/*
++ .rate_min = 44100,
++ .rate_max = 44100,
++ .channels_min = 2,
++ .channels_max = 2,
++ .buffer_bytes_max = 64*1024,
++ .period_bytes_min = 64,
++ .period_bytes_max = 4096,
++ .periods_min = 2,
++ .periods_max = 255,
++*/
++
++};
++
++static int snd_wm8976_playback_open(snd_pcm_substream_t *substream)
++{
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++
++ snd_printk_marker();
++ chip->tx_substream = substream;
++ substream->runtime->hw = snd_wm8976_playback_hw;
++
++ return 0;
++}
++
++static int snd_wm8976_capture_open(snd_pcm_substream_t *substream)
++{
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++
++ snd_printk_marker();
++ substream->runtime->hw = snd_wm8976_capture_hw;
++ chip->rx_substream = substream;
++
++ return 0;
++}
++
++static int snd_wm8976_playback_close(snd_pcm_substream_t *substream)
++{
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++
++ snd_printk_marker();
++ chip->tx_substream = NULL;
++
++ return 0;
++}
++
++static int snd_wm8976_capture_close(snd_pcm_substream_t *substream)
++{
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++
++ snd_printk_marker();
++ chip->rx_substream = NULL;
++ return 0;
++}
++
++//I2S in following
++static int snd_wm8976_hw_params(snd_pcm_substream_t *substream,
++ snd_pcm_hw_params_t *hwparams)
++{
++ snd_printk_marker();
++
++ /*
++ * Allocate all available memory for our DMA buffer.
++ * Necessary because we get a 4x increase in bytes for the 2 channel mode.
++ * (we lie to the ALSA midlayer through the hwparams data)
++ * We're relying on the driver not supporting full duplex mode
++ * to allow us to grab all the memory.
++ */
++ //printk("params_buffer_bytes return %d\n", params_buffer_bytes(hwparams));
++ if( snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hwparams)) < 0 )
++ return -ENOMEM;
++ return 0;
++}
++
++static int snd_wm8976_hw_free(snd_pcm_substream_t * substream)
++{
++ snd_printk_marker();
++ snd_pcm_lib_free_pages(substream);
++ return 0;
++}
++
++static int snd_wm8976_playback_prepare(snd_pcm_substream_t *substream)
++{
++ int err = 0;
++ int word_len = 4;
++
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++ snd_pcm_runtime_t *runtime = substream->runtime;
++
++ int fragsize_bytes = frames_to_bytes(runtime, runtime->period_size);
++ //printk("Playback sample rate = %d.\n",runtime->rate);
++
++ /* set requested samplerate */
++ snd_wm8976_set_samplerate(runtime->rate);
++
++
++ if (substream != chip->tx_substream)
++ return -EINVAL;
++
++ snd_printd(KERN_INFO "%s channels:%d, period_bytes:0x%lx, periods:%d\n",
++ __FUNCTION__, runtime->channels,
++ frames_to_bytes(runtime, runtime->period_size),
++ runtime->periods);
++
++ err = tmpa910_i2s_config_tx_dma(chip->i2s, runtime->dma_area, runtime->dma_addr,
++ runtime->periods, fragsize_bytes, word_len);
++
++ return err;
++}
++
++static int snd_wm8976_capture_prepare(snd_pcm_substream_t *substream)
++{
++ int err = 0;
++ int word_len = 4;
++
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++ snd_pcm_runtime_t *runtime = substream->runtime;
++
++ int fragsize_bytes = frames_to_bytes(runtime, runtime->period_size);
++
++ //printk("Record sample rate = %d.\n",runtime->rate);
++
++ /* set requested samplerate */
++ snd_wm8976_set_samplerate(runtime->rate);
++
++ if (substream != chip->tx_substream)
++ return -EINVAL;
++
++ snd_printd(KERN_INFO "%s channels:%d, period_bytes:0x%lx, periods:%d\n",
++ __FUNCTION__, runtime->channels,
++ frames_to_bytes(runtime, runtime->period_size),
++ runtime->periods);
++
++ err = tmpa910_i2s_config_rx_dma(chip->i2s, runtime->dma_area, runtime->dma_addr,
++ runtime->periods, fragsize_bytes, word_len);
++
++ return err;
++}
++
++static int snd_wm8976_playback_trigger(snd_pcm_substream_t *substream, int cmd)
++{
++ int ret;
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++
++ snd_printk_marker();
++
++ spin_lock(&chip->wm8976_lock);
++ switch (cmd)
++ {
++ case SNDRV_PCM_TRIGGER_START:
++ //printk(" SNDRV_PCM_TRIGGER_START\n");
++ ret = tmpa910_i2s_tx_start(chip->i2s);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ //printk(" SNDRV_PCM_TRIGGER_STOP\n");
++ ret = tmpa910_i2s_tx_stop(chip->i2s);
++ break;
++ default:
++ ret = -1;
++ spin_unlock(&chip->wm8976_lock);
++ return -EINVAL;
++ }
++ spin_unlock(&chip->wm8976_lock);
++
++ snd_printd(KERN_INFO"playback cmd:%s. ret=%d\n", cmd?"start":"stop", ret);
++
++ return 0;
++}
++
++static int snd_wm8976_capture_trigger(snd_pcm_substream_t *substream, int cmd)
++{
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++
++ snd_printk_marker();
++
++ spin_lock(&chip->wm8976_lock);
++
++ if (substream != chip->rx_substream)
++ return -EINVAL;
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ //printk(" SNDRV_PCM_TRIGGER_START\n");
++ tmpa910_i2s_rx_start(chip->i2s);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ //printk(" SNDRV_PCM_TRIGGER_STOP\n");
++ tmpa910_i2s_rx_stop(chip->i2s);
++ break;
++ default:
++ spin_unlock(&chip->wm8976_lock);
++ return -EINVAL;
++ }
++ spin_unlock(&chip->wm8976_lock);
++
++ //snd_printd(KERN_ERR"capture cmd:%s\n", cmd ? "start" : "stop");
++
++ return 0;
++}
++
++static snd_pcm_uframes_t snd_wm8976_playback_pointer(snd_pcm_substream_t *substream)
++{
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++ snd_pcm_runtime_t *runtime = substream->runtime;
++ unsigned int offset;
++
++ offset = tmpa910_i2s_curr_offset_tx(chip->i2s);
++
++ offset = bytes_to_frames(runtime, offset);
++ if (offset >= runtime->buffer_size)
++ offset = 0;
++
++ return offset;
++}
++
++static snd_pcm_uframes_t snd_wm8976_capture_pointer(snd_pcm_substream_t *substream)
++{
++ wm8976_t *chip = snd_pcm_substream_chip(substream);
++ snd_pcm_runtime_t *runtime = substream->runtime;
++ unsigned int offset;
++
++ offset = tmpa910_i2s_curr_offset_rx(chip->i2s);
++
++ offset = bytes_to_frames(runtime, offset);
++
++// printk("offset=0x%02x\n",offset); //wym
++// printk("handler srcaddr = 0x%02x\n", DMA_SRC_ADDR(2));
++// printk("handler dest addr = 0x%02x\n", DMA_DEST_ADDR(2));
++// printk("handler lli addr = 0x%02x\n", DMA_LLI(2));
++// printk("handler control = 0x%02x\n", DMA_CONTROL(2));
++
++// printk("VICIRQSTATUS is 0x%02x.\n",VICIRQSTATUS);
++// printk("VICINTENABLE is 0x%02x.\n",VICINTENABLE);
++ if (offset >= runtime->buffer_size)
++ offset = 0;
++
++ return offset;
++}
++
++/* pcm method tables */
++static snd_pcm_ops_t snd_wm8976_playback_ops = {
++ .open = snd_wm8976_playback_open,
++ .close = snd_wm8976_playback_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = snd_wm8976_hw_params,
++ .hw_free = snd_wm8976_hw_free,
++ .prepare = snd_wm8976_playback_prepare,
++ .trigger = snd_wm8976_playback_trigger,
++ .pointer = snd_wm8976_playback_pointer,
++};
++
++static snd_pcm_ops_t snd_wm8976_capture_ops = {
++ .open = snd_wm8976_capture_open,
++ .close = snd_wm8976_capture_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = snd_wm8976_hw_params,
++ .hw_free = snd_wm8976_hw_free,
++ .prepare = snd_wm8976_capture_prepare,
++ .trigger = snd_wm8976_capture_trigger,
++ .pointer = snd_wm8976_capture_pointer,
++};
++
++/*************************************************************
++ * card and device
++ *************************************************************/
++static int snd_wm8976_stop(struct snd_wm8976 *chip)
++{
++ snd_printk_marker();
++
++ return 0;
++}
++
++static int snd_wm8976_dev_free(struct snd_device *device)
++{
++ struct snd_wm8976 *chip = (wm8976_t *)device->device_data;
++
++ snd_printk_marker();
++
++ return snd_wm8976_stop(chip);
++}
++
++static struct snd_device_ops snd_wm8976_ops = {
++ .dev_free = snd_wm8976_dev_free,
++};
++
++static int snd_bf53x_wm8976_reset(wm8976_t *chip)
++{
++ return 0;
++}
++
++static int snd_wm8976_configure(wm8976_t *chip)
++{
++ int err = 0;
++ struct tmpa910_i2s *i2s= chip->i2s;
++
++ snd_printk_marker();
++
++ snd_bf53x_wm8976_reset(chip);
++
++ err = err || tmpa910_i2s_config_tx(i2s);
++
++ if (err)
++ {
++ snd_printk(KERN_ERR "Unable to set i2s configuration\n");
++ }
++
++ return err;
++}
++
++static void snd_wm8976_dma_rx(void *data)
++{
++ struct snd_wm8976 *wm8976 = data;
++
++ snd_printk_marker();
++
++
++ if (wm8976->rx_substream) {
++ snd_pcm_period_elapsed(wm8976->rx_substream);
++
++/* printk("WM8976->rx_substream=0x%02x\n",wm8976->rx_substream); //wym
++ printk("handler srcaddr = 0x%02x\n", DMA_SRC_ADDR(2));
++ printk("handler dest addr = 0x%02x\n", DMA_DEST_ADDR(2));
++ printk("handler lli addr = 0x%02x\n", DMA_LLI(2));
++ printk("handler control = 0x%02x\n", DMA_CONTROL(2));
++ printk("VICIRQSTATUS is 0x%02x.\n",VICIRQSTATUS);
++ printk("VICINTENABLE is 0x%02x.\n",VICINTENABLE);
++*/ }
++// VICINTENABLE |= 0x20000;
++}
++
++static void snd_wm8976_dma_tx(void *data)
++{
++ struct snd_wm8976 *wm8976 = data;
++
++ snd_printk_marker();
++
++ if (wm8976->tx_substream) {
++ snd_pcm_period_elapsed(wm8976->tx_substream);
++/*
++ printk("handler srcaddr = 0x%02x\n", DMA_SRC_ADDR(1));
++ printk("handler dest addr = 0x%02x\n", DMA_DEST_ADDR(1));
++ printk("handler lli addr = 0x%02x\n", DMA_LLI(1));
++ printk("handler control = 0x%02x\n", DMA_CONTROL(1));
++ printk("VICIRQSTATUS is 0x%02x.\n",VICIRQSTATUS);
++ printk("VICINTENABLE is 0x%02x.\n",VICINTENABLE);
++*/ }
++}
++
++static void snd_wm8976_i2s_err(void *data)
++{
++ printk(KERN_ERR DRIVER_NAME ":%s: err happened on i2s\n", __FUNCTION__);
++}
++
++static int __devinit snd_wm8976_pcm(struct snd_wm8976 *wm8976)
++{
++ struct snd_pcm *pcm;
++ int err = 0;
++
++ snd_printk_marker();
++
++ /* 1 playback and 1 capture substream, of 2-8 channels each */
++ if((err = snd_pcm_new(wm8976->card, PCM_NAME, 0, 1, 1, &pcm)) < 0)
++ {
++ return err;
++ }
++
++ /*
++ * this sets up our initial buffers and sets the dma_type to isa.
++ * isa works but I'm not sure why (or if) it's the right choice
++ * this may be too large, trying it for now
++ */
++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
++ snd_dma_isa_data(), WM8976_BUF_SZ, WM8976_BUF_SZ);
++
++
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wm8976_playback_ops);
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wm8976_capture_ops);
++ wm8976->pcm = pcm;
++ pcm->info_flags = 0;
++
++ strcpy(pcm->name, PCM_NAME);
++ pcm->private_data = wm8976;
++
++ return 0;
++}
++
++static int __devinit snd_wm8976_probe(struct platform_device *pdev)
++{
++ int err = 0;
++ struct snd_card *card = NULL;
++ struct snd_wm8976 *wm8976;
++ struct tmpa910_i2s *i2s;
++ char *id = "ID string for TMPA910 + WM8976 soundcard.";
++
++ snd_printk_marker();
++
++ if (g_device != NULL)
++ return -ENOENT;
++
++ snd_card_create(-1, id, THIS_MODULE, sizeof(struct snd_wm8976), &card);
++ if (card == NULL) {
++ snd_printdd(KERN_DEBUG "%s: snd_card_new() failed\n", __FUNCTION__);
++ return -ENOMEM;
++ }
++
++ wm8976 = card->private_data;
++ wm8976->card = card;
++ //wm8976->samplerate = AUDIO_RATE_DEFAULT;
++ if ((i2s = tmpa910_i2s_init(I2S_DMA_RX, snd_wm8976_dma_rx, I2S_DMA_TX, snd_wm8976_dma_tx,
++ I2S_IRQ_ERR, snd_wm8976_i2s_err, wm8976)) == NULL)
++ {
++ printk(KERN_ERR DRIVER_NAME ": Failed to find device on i2s\n");
++ err = -ENODEV;
++ goto __i2s_err;
++ }
++
++ wm8976->i2s = i2s;
++
++ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, wm8976, &snd_wm8976_ops);
++ if (err)
++ {
++ goto __nodev;
++ }
++
++ if ((err = snd_wm8976_pcm(wm8976)) < 0)
++ {
++ goto __nodev;
++ }
++
++ if ((err = snd_wm8976_configure(wm8976)) < 0)
++ {
++ printk("snd_wm8976_configure faild.\n");
++ goto __nodev;
++ }
++
++ strcpy(card->driver, DRIVER_NAME);
++ strcpy(card->shortname, CHIP_NAME);
++ sprintf(card->longname, "%s at I2S rx/tx dma %d/%d err irq %d",
++ card->shortname,
++ I2S_DMA_RX, I2S_DMA_TX, I2S_IRQ_ERR);
++
++ snd_card_set_dev(card, &pdev->dev);
++
++ if ((err = snd_card_register(card)) < 0)
++ {
++ printk("snd_card_register faild.\n");
++ goto __nodev;
++ }
++
++ //printk("platform_set_drvdata card=%p\n", card);
++ platform_set_drvdata(pdev, card);
++
++ g_device = pdev;
++
++ return 0;
++
++__nodev:
++ tmpa910_i2s_free(i2s);
++__i2s_err:
++ snd_card_free(card);
++ return err;
++}
++
++static int __devexit snd_wm8976_remove(struct platform_device *pdev)
++{
++ struct snd_card *card;
++ struct snd_wm8976 *wm8976;
++
++ card = platform_get_drvdata(pdev);
++ wm8976 = card->private_data;
++
++ snd_wm8976_stop(wm8976);
++ tmpa910_i2s_free(wm8976->i2s);
++
++ snd_card_free(card);
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++#define TMPA910_WM8976_DRIVER "tmpa910_wm8976"
++static struct platform_driver snd_wm8976_driver = {
++ .probe = snd_wm8976_probe,
++ .remove = __devexit_p(snd_wm8976_remove),
++ .driver = {
++ .name = DRIVER_NAME,
++ },
++};
++
++static int __init snd_wm8976_init(void)
++{
++ int err;
++
++ init_wm8976_i2c();
++ enable_audio_sysclk();
++
++ if ((err = platform_driver_register(&snd_wm8976_driver)) < 0) {
++ printk("platform_driver_register failed. ret=%d\n", err);
++ return err;
++ }
++
++ return 0;
++}
++
++static void __exit snd_wm8976_exit(void)
++{
++ if (g_device)
++ {
++ platform_device_unregister(g_device);
++ platform_driver_unregister(&snd_wm8976_driver);
++ release_wm8976_i2c();
++ disable_audio_sysclk();
++ }
++
++ g_device = NULL;
++}
++
++
++static void snd_wm8976_set_samplerate(long rate)
++{
++ /* wait for any frame to complete */
++ udelay(125);
++
++ if (rate >= 48000)
++ rate = 0;
++ else if (rate >= 44100)
++ rate = 1;
++ else if (rate >= 32000)
++ rate = 2;
++ else if (rate >= 22050)
++ rate = 3;
++ else if (rate >= 16000)
++ rate = 4;
++ else if (rate >= 12000)
++ rate = 5;
++ else
++ rate = 6;
++
++ i2c_packet_send(0x0d, wm8976_for_samplerate[rate][5]); //R6
++ i2c_packet_send(0x0e, wm8976_for_samplerate[rate][0]); //R7
++ i2c_packet_send(0x48, wm8976_for_samplerate[rate][1]); //R36
++ i2c_packet_send(0x4a, wm8976_for_samplerate[rate][2]); //R37
++ i2c_packet_send(0x4d, wm8976_for_samplerate[rate][3]); //R38
++ i2c_packet_send(0x4e, wm8976_for_samplerate[rate][4]); //R39
++}
++
++
++MODULE_AUTHOR("TOSHIBA <tmpa910 at toshiba.com>");
++MODULE_DESCRIPTION("TMPA910/WM8976");
++MODULE_LICENSE("GPL");
++
++module_init(snd_wm8976_init);
++module_exit(snd_wm8976_exit);
+diff --git a/sound/arm/wm8976.h b/sound/arm/wm8976.h
+new file mode 100644
+index 0000000..95ee447
+--- /dev/null
++++ b/sound/arm/wm8976.h
+@@ -0,0 +1,5 @@
++#ifndef __WM8976_H__
++#define __WM8976_H__
++
++
++#endif
+diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
+index 7f4d744..34c7d48 100644
+--- a/sound/core/hrtimer.c
++++ b/sound/core/hrtimer.c
+@@ -37,22 +37,14 @@ static unsigned int resolution;
+ struct snd_hrtimer {
+ struct snd_timer *timer;
+ struct hrtimer hrt;
+- atomic_t running;
+ };
+
+ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
+ {
+ struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
+ struct snd_timer *t = stime->timer;
+-
+- if (!atomic_read(&stime->running))
+- return HRTIMER_NORESTART;
+-
+ hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
+ snd_timer_interrupt(stime->timer, t->sticks);
+-
+- if (!atomic_read(&stime->running))
+- return HRTIMER_NORESTART;
+ return HRTIMER_RESTART;
+ }
+
+@@ -66,7 +58,6 @@ static int snd_hrtimer_open(struct snd_timer *t)
+ hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ stime->timer = t;
+ stime->hrt.function = snd_hrtimer_callback;
+- atomic_set(&stime->running, 0);
+ t->private_data = stime;
+ return 0;
+ }
+@@ -87,18 +78,16 @@ static int snd_hrtimer_start(struct snd_timer *t)
+ {
+ struct snd_hrtimer *stime = t->private_data;
+
+- atomic_set(&stime->running, 0);
+- hrtimer_cancel(&stime->hrt);
+ hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
+ HRTIMER_MODE_REL);
+- atomic_set(&stime->running, 1);
+ return 0;
+ }
+
+ static int snd_hrtimer_stop(struct snd_timer *t)
+ {
+ struct snd_hrtimer *stime = t->private_data;
+- atomic_set(&stime->running, 0);
++
++ hrtimer_cancel(&stime->hrt);
+ return 0;
+ }
+
+diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
+index f1d9d16..8691f4c 100644
+--- a/sound/mips/sgio2audio.c
++++ b/sound/mips/sgio2audio.c
+@@ -609,7 +609,7 @@ static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream,
+ /* alloc virtual 'dma' area */
+ if (runtime->dma_area)
+ vfree(runtime->dma_area);
+- runtime->dma_area = vmalloc_user(size);
++ runtime->dma_area = vmalloc(size);
+ if (runtime->dma_area == NULL)
+ return -ENOMEM;
+ runtime->dma_bytes = size;
+diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
+index 67ca440..7337abd 100644
+--- a/sound/pci/ac97/ac97_patch.c
++++ b/sound/pci/ac97/ac97_patch.c
+@@ -1870,7 +1870,6 @@ static unsigned int ad1981_jacks_blacklist[] = {
+ 0x10140554, /* Thinkpad T42p/R50p */
+ 0x10140567, /* Thinkpad T43p 2668-G7U */
+ 0x10140581, /* Thinkpad X41-2527 */
+- 0x10280160, /* Dell Dimension 2400 */
+ 0x104380b0, /* Asus A7V8X-MX */
+ 0x11790241, /* Toshiba Satellite A-15 S127 */
+ 0x144dc01a, /* Samsung NP-X20C004/SEG */
+diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
+index 42b4fbb..d6752df 100644
+--- a/sound/pci/atiixp.c
++++ b/sound/pci/atiixp.c
+@@ -297,7 +297,6 @@ static struct pci_device_id snd_atiixp_ids[] = {
+ MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
+
+ static struct snd_pci_quirk atiixp_quirks[] __devinitdata = {
+- SND_PCI_QUIRK(0x105b, 0x0c81, "Foxconn RC4107MA-RS2", 0),
+ SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0),
+ { } /* terminator */
+ };
+diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
+index cb1f533..7545464 100644
+--- a/sound/pci/ctxfi/ctatc.c
++++ b/sound/pci/ctxfi/ctatc.c
+@@ -166,7 +166,18 @@ static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
+
+ static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
+ {
+- return atc->vm->get_ptp_phys(atc->vm, index);
++ struct ct_vm *vm;
++ void *kvirt_addr;
++ unsigned long phys_addr;
++
++ vm = atc->vm;
++ kvirt_addr = vm->get_ptp_virt(vm, index);
++ if (kvirt_addr == NULL)
++ phys_addr = (~0UL);
++ else
++ phys_addr = virt_to_phys(kvirt_addr);
++
++ return phys_addr;
+ }
+
+ static unsigned int convert_format(snd_pcm_format_t snd_format)
+@@ -1658,7 +1669,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
+ }
+
+ /* Set up device virtual memory management object */
+- err = ct_vm_create(&atc->vm, pci);
++ err = ct_vm_create(&atc->vm);
+ if (err < 0)
+ goto error1;
+
+diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
+index 65da6e4..6b78752 100644
+--- a/sound/pci/ctxfi/ctvmem.c
++++ b/sound/pci/ctxfi/ctvmem.c
+@@ -138,7 +138,7 @@ ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size)
+ return NULL;
+ }
+
+- ptp = (unsigned long *)vm->ptp[0].area;
++ ptp = vm->ptp[0];
+ pte_start = (block->addr >> CT_PAGE_SHIFT);
+ pages = block->size >> CT_PAGE_SHIFT;
+ for (i = 0; i < pages; i++) {
+@@ -158,25 +158,25 @@ static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block)
+ }
+
+ /* *
+- * return the host physical addr of the @index-th device
+- * page table page on success, or ~0UL on failure.
+- * The first returned ~0UL indicates the termination.
++ * return the host (kmalloced) addr of the @index-th device
++ * page talbe page on success, or NULL on failure.
++ * The first returned NULL indicates the termination.
+ * */
+-static dma_addr_t
+-ct_get_ptp_phys(struct ct_vm *vm, int index)
++static void *
++ct_get_ptp_virt(struct ct_vm *vm, int index)
+ {
+- dma_addr_t addr;
++ void *addr;
+
+- addr = (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr;
++ addr = (index >= CT_PTP_NUM) ? NULL : vm->ptp[index];
+
+ return addr;
+ }
+
+-int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci)
++int ct_vm_create(struct ct_vm **rvm)
+ {
+ struct ct_vm *vm;
+ struct ct_vm_block *block;
+- int i, err = 0;
++ int i;
+
+ *rvm = NULL;
+
+@@ -188,21 +188,23 @@ int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci)
+
+ /* Allocate page table pages */
+ for (i = 0; i < CT_PTP_NUM; i++) {
+- err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+- snd_dma_pci_data(pci),
+- PAGE_SIZE, &vm->ptp[i]);
+- if (err < 0)
++ vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL);
++ if (!vm->ptp[i])
+ break;
+ }
+- if (err < 0) {
++ if (!i) {
+ /* no page table pages are allocated */
+- ct_vm_destroy(vm);
++ kfree(vm);
+ return -ENOMEM;
+ }
+ vm->size = CT_ADDRS_PER_PAGE * i;
++ /* Initialise remaining ptps */
++ for (; i < CT_PTP_NUM; i++)
++ vm->ptp[i] = NULL;
++
+ vm->map = ct_vm_map;
+ vm->unmap = ct_vm_unmap;
+- vm->get_ptp_phys = ct_get_ptp_phys;
++ vm->get_ptp_virt = ct_get_ptp_virt;
+ INIT_LIST_HEAD(&vm->unused);
+ INIT_LIST_HEAD(&vm->used);
+ block = kzalloc(sizeof(*block), GFP_KERNEL);
+@@ -240,7 +242,7 @@ void ct_vm_destroy(struct ct_vm *vm)
+
+ /* free allocated page table pages */
+ for (i = 0; i < CT_PTP_NUM; i++)
+- snd_dma_free_pages(&vm->ptp[i]);
++ kfree(vm->ptp[i]);
+
+ vm->size = 0;
+
+diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h
+index b23adfc..01e4fd0 100644
+--- a/sound/pci/ctxfi/ctvmem.h
++++ b/sound/pci/ctxfi/ctvmem.h
+@@ -22,8 +22,6 @@
+
+ #include <linux/mutex.h>
+ #include <linux/list.h>
+-#include <linux/pci.h>
+-#include <sound/memalloc.h>
+
+ /* The chip can handle the page table of 4k pages
+ * (emu20k1 can handle even 8k pages, but we don't use it right now)
+@@ -43,7 +41,7 @@ struct snd_pcm_substream;
+
+ /* Virtual memory management object for card device */
+ struct ct_vm {
+- struct snd_dma_buffer ptp[CT_PTP_NUM]; /* Device page table pages */
++ void *ptp[CT_PTP_NUM]; /* Device page table pages */
+ unsigned int size; /* Available addr space in bytes */
+ struct list_head unused; /* List of unused blocks */
+ struct list_head used; /* List of used blocks */
+@@ -54,10 +52,10 @@ struct ct_vm {
+ int size);
+ /* Unmap device logical addr area. */
+ void (*unmap)(struct ct_vm *, struct ct_vm_block *block);
+- dma_addr_t (*get_ptp_phys)(struct ct_vm *vm, int index);
++ void *(*get_ptp_virt)(struct ct_vm *vm, int index);
+ };
+
+-int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci);
++int ct_vm_create(struct ct_vm **rvm);
+ void ct_vm_destroy(struct ct_vm *vm);
+
+ #endif /* CTVMEM_H */
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index fec8724..6517f58 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -1858,9 +1858,6 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
+
+ if (!bdl_pos_adj[chip->dev_index])
+ return 1; /* no delayed ack */
+- if (WARN_ONCE(!azx_dev->period_bytes,
+- "hda-intel: zero azx_dev->period_bytes"))
+- return 0; /* this shouldn't happen! */
+ if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
+ return 0; /* NG - it's below the period boundary */
+ return 1; /* OK, it's fine */
+@@ -2439,11 +2436,6 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
+ }
+ }
+
+- /* disable 64bit DMA address for Teradici */
+- /* it does not work with device 6549:1200 subsys e4a2:040b */
+- if (chip->driver_type == AZX_DRIVER_TERA)
+- gcap &= ~ICH6_GCAP_64OK;
+-
+ /* allow 64bit DMA address if supported by H/W */
+ if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
+@@ -2697,9 +2689,6 @@ static struct pci_device_id azx_ids[] = {
+ { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
+ { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
+ { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
+- { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA },
+- { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA },
+- { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA },
+ { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
+ { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
+ { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
+diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
+index 7c23016..01a18ed 100644
+--- a/sound/pci/hda/patch_intelhdmi.c
++++ b/sound/pci/hda/patch_intelhdmi.c
+@@ -684,7 +684,7 @@ static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
+ { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
+ { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
+ { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
+- { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi_ibexpeak },
++ { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
+ { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi_ibexpeak },
+ { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
+ {} /* terminator */
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 911dd1f..7058371 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -2401,8 +2401,6 @@ static const char *alc_slave_sws[] = {
+ "Speaker Playback Switch",
+ "Mono Playback Switch",
+ "IEC958 Playback Switch",
+- "Line-Out Playback Switch",
+- "PCM Playback Switch",
+ NULL,
+ };
+
+@@ -7042,8 +7040,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
+ HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
+ HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
+- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
+- HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
++ HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
++ HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
+@@ -7430,7 +7428,6 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
+- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ /* Front Mic pin: input vref at 80% */
+ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+@@ -7555,27 +7552,6 @@ static void alc885_mbp3_setup(struct hda_codec *codec)
+ spec->autocfg.speaker_pins[0] = 0x14;
+ }
+
+-static void alc885_mb5_automute(struct hda_codec *codec)
+-{
+- unsigned int present;
+-
+- present = snd_hda_codec_read(codec, 0x14, 0,
+- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+- snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
+- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+- snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
+- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+-
+-}
+-
+-static void alc885_mb5_unsol_event(struct hda_codec *codec,
+- unsigned int res)
+-{
+- /* Headphone insertion or removal. */
+- if ((res >> 26) == ALC880_HP_EVENT)
+- alc885_mb5_automute(codec);
+-}
+-
+
+ static struct hda_verb alc882_targa_verbs[] = {
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+@@ -8863,7 +8839,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
+ SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
+ SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
+ SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
+- SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
++ SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
+ SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
+ SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
+ SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
+@@ -9018,8 +8994,6 @@ static struct alc_config_preset alc882_presets[] = {
+ .input_mux = &mb5_capture_source,
+ .dig_out_nid = ALC882_DIGOUT_NID,
+ .dig_in_nid = ALC882_DIGIN_NID,
+- .unsol_event = alc885_mb5_unsol_event,
+- .init_hook = alc885_mb5_automute,
+ },
+ [ALC885_MACPRO] = {
+ .mixers = { alc882_macpro_mixer },
+@@ -9167,8 +9141,6 @@ static struct alc_config_preset alc882_presets[] = {
+ .dac_nids = alc883_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
+ .adc_nids = alc889_adc_nids,
+- .capsrc_nids = alc889_capsrc_nids,
+- .capsrc_nids = alc889_capsrc_nids,
+ .dig_out_nid = ALC883_DIGOUT_NID,
+ .dig_in_nid = ALC883_DIGIN_NID,
+ .slave_dig_outs = alc883_slave_dig_outs,
+@@ -9215,7 +9187,6 @@ static struct alc_config_preset alc882_presets[] = {
+ .dac_nids = alc883_dac_nids,
+ .adc_nids = alc883_adc_nids_alt,
+ .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
+- .capsrc_nids = alc883_capsrc_nids,
+ .dig_out_nid = ALC883_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+ .channel_mode = alc883_3ST_2ch_modes,
+@@ -9362,7 +9333,6 @@ static struct alc_config_preset alc882_presets[] = {
+ .dac_nids = alc883_dac_nids,
+ .adc_nids = alc883_adc_nids_alt,
+ .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
+- .capsrc_nids = alc883_capsrc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
+ .channel_mode = alc883_sixstack_modes,
+ .input_mux = &alc883_capture_source,
+@@ -9424,7 +9394,6 @@ static struct alc_config_preset alc882_presets[] = {
+ .dac_nids = alc883_dac_nids,
+ .adc_nids = alc883_adc_nids_alt,
+ .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
+- .capsrc_nids = alc883_capsrc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+ .channel_mode = alc883_3ST_2ch_modes,
+ .input_mux = &alc883_lenovo_101e_capture_source,
+@@ -9604,7 +9573,6 @@ static struct alc_config_preset alc882_presets[] = {
+ alc880_gpio1_init_verbs },
+ .adc_nids = alc883_adc_nids,
+ .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+- .capsrc_nids = alc883_capsrc_nids,
+ .dac_nids = alc883_dac_nids,
+ .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+ .channel_mode = alc889A_mb31_6ch_modes,
+@@ -10178,7 +10146,7 @@ static void alc262_hp_t5735_setup(struct hda_codec *codec)
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x15;
+- spec->autocfg.speaker_pins[0] = 0x14;
++ spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
+ }
+
+ static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
+@@ -11612,9 +11580,9 @@ static struct alc_config_preset alc262_presets[] = {
+ .num_channel_mode = ARRAY_SIZE(alc262_modes),
+ .channel_mode = alc262_modes,
+ .input_mux = &alc262_capture_source,
+- .unsol_event = alc_sku_unsol_event,
++ .unsol_event = alc_automute_amp_unsol_event,
+ .setup = alc262_hp_t5735_setup,
+- .init_hook = alc_inithook,
++ .init_hook = alc_automute_amp,
+ },
+ [ALC262_HP_RP5700] = {
+ .mixers = { alc262_hp_rp5700_mixer },
+@@ -14711,8 +14679,6 @@ static int patch_alc861(struct hda_codec *codec)
+ spec->stream_digital_playback = &alc861_pcm_digital_playback;
+ spec->stream_digital_capture = &alc861_pcm_digital_capture;
+
+- if (!spec->cap_mixer)
+- set_capture_mixer(codec);
+ set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
+
+ spec->vmaster_nid = 0x03;
+@@ -15351,7 +15317,7 @@ static struct alc_config_preset alc861vd_presets[] = {
+ static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
+ const struct auto_pin_cfg *cfg)
+ {
+- return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0);
++ return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
+ }
+
+
+diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
+index f5020ad..fd948bf 100644
+--- a/sound/pci/ice1712/juli.c
++++ b/sound/pci/ice1712/juli.c
+@@ -504,31 +504,6 @@ static int __devinit juli_add_controls(struct snd_ice1712 *ice)
+ }
+
+ /*
+- * suspend/resume
+- * */
+-
+-#ifdef CONFIG_PM
+-static int juli_resume(struct snd_ice1712 *ice)
+-{
+- struct snd_akm4xxx *ak = ice->akm;
+- struct juli_spec *spec = ice->spec;
+- /* akm4358 un-reset, un-mute */
+- snd_akm4xxx_reset(ak, 0);
+- /* reinit ak4114 */
+- snd_ak4114_reinit(spec->ak4114);
+- return 0;
+-}
+-
+-static int juli_suspend(struct snd_ice1712 *ice)
+-{
+- struct snd_akm4xxx *ak = ice->akm;
+- /* akm4358 reset and soft-mute */
+- snd_akm4xxx_reset(ak, 1);
+- return 0;
+-}
+-#endif
+-
+-/*
+ * initialize the chip
+ */
+
+@@ -671,13 +646,6 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
+ ice->set_spdif_clock = juli_set_spdif_clock;
+
+ ice->spdif.ops.open = juli_spdif_in_open;
+-
+-#ifdef CONFIG_PM
+- ice->pm_resume = juli_resume;
+- ice->pm_suspend = juli_suspend;
+- ice->pm_suspend_enabled = 1;
+-#endif
+-
+ return 0;
+ }
+
+diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+index 5cfa608..d057e64 100644
+--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
++++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+@@ -51,7 +51,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s
+ return 0; /* already enough large */
+ vfree(runtime->dma_area);
+ }
+- runtime->dma_area = vmalloc_32_user(size);
++ runtime->dma_area = vmalloc_32(size);
+ if (! runtime->dma_area)
+ return -ENOMEM;
+ runtime->dma_bytes = size;
+diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
+index 2089fe7..593d5b9 100644
+--- a/sound/soc/codecs/wm8350.c
++++ b/sound/soc/codecs/wm8350.c
+@@ -925,7 +925,7 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+ iface |= 0x3 << 8;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+- iface |= 0x3 << 8 | WM8350_AIF_LRCLK_INV;
++ iface |= 0x3 << 8; /* lg not sure which mode */
+ break;
+ default:
+ return -EINVAL;
+diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
+index 8db62e2..060d5d0 100644
+--- a/sound/soc/codecs/wm8510.c
++++ b/sound/soc/codecs/wm8510.c
+@@ -425,23 +425,23 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
+
+ /* filter coefficient */
+ switch (params_rate(params)) {
+- case 8000:
++ case SNDRV_PCM_RATE_8000:
+ adn |= 0x5 << 1;
+ break;
+- case 11025:
++ case SNDRV_PCM_RATE_11025:
+ adn |= 0x4 << 1;
+ break;
+- case 16000:
++ case SNDRV_PCM_RATE_16000:
+ adn |= 0x3 << 1;
+ break;
+- case 22050:
++ case SNDRV_PCM_RATE_22050:
+ adn |= 0x2 << 1;
+ break;
+- case 32000:
++ case SNDRV_PCM_RATE_32000:
+ adn |= 0x1 << 1;
+ break;
+- case 44100:
+- case 48000:
++ case SNDRV_PCM_RATE_44100:
++ case SNDRV_PCM_RATE_48000:
+ break;
+ }
+
+diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
+index eedf33c..fe1307b 100644
+--- a/sound/soc/codecs/wm8903.c
++++ b/sound/soc/codecs/wm8903.c
+@@ -1506,7 +1506,7 @@ static int wm8903_resume(struct platform_device *pdev)
+ struct i2c_client *i2c = codec->control_data;
+ int i;
+ u16 *reg_cache = codec->reg_cache;
+- u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults),
++ u16 *tmp_cache = kmemdup(codec->reg_cache, sizeof(wm8903_reg_defaults),
+ GFP_KERNEL);
+
+ /* Bring the codec back up to standby first to minimise pop/clicks */
+@@ -1518,7 +1518,6 @@ static int wm8903_resume(struct platform_device *pdev)
+ for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
+ if (tmp_cache[i] != reg_cache[i])
+ snd_soc_write(codec, i, tmp_cache[i]);
+- kfree(tmp_cache);
+ } else {
+ dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
+ }
+diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
+index 63bc2ae..1ef2454 100644
+--- a/sound/soc/codecs/wm8940.c
++++ b/sound/soc/codecs/wm8940.c
+@@ -379,23 +379,23 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
+ iface |= (1 << 9);
+
+ switch (params_rate(params)) {
+- case 8000:
++ case SNDRV_PCM_RATE_8000:
+ addcntrl |= (0x5 << 1);
+ break;
+- case 11025:
++ case SNDRV_PCM_RATE_11025:
+ addcntrl |= (0x4 << 1);
+ break;
+- case 16000:
++ case SNDRV_PCM_RATE_16000:
+ addcntrl |= (0x3 << 1);
+ break;
+- case 22050:
++ case SNDRV_PCM_RATE_22050:
+ addcntrl |= (0x2 << 1);
+ break;
+- case 32000:
++ case SNDRV_PCM_RATE_32000:
+ addcntrl |= (0x1 << 1);
+ break;
+- case 44100:
+- case 48000:
++ case SNDRV_PCM_RATE_44100:
++ case SNDRV_PCM_RATE_48000:
+ break;
+ }
+ ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl);
+diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
+index 0dbf6fe..98d663a 100644
+--- a/sound/soc/codecs/wm8974.c
++++ b/sound/soc/codecs/wm8974.c
+@@ -47,7 +47,7 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
+ };
+
+ #define WM8974_POWER1_BIASEN 0x08
+-#define WM8974_POWER1_BUFIOEN 0x04
++#define WM8974_POWER1_BUFIOEN 0x10
+
+ struct wm8974_priv {
+ struct snd_soc_codec codec;
+@@ -480,23 +480,23 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
+
+ /* filter coefficient */
+ switch (params_rate(params)) {
+- case 8000:
++ case SNDRV_PCM_RATE_8000:
+ adn |= 0x5 << 1;
+ break;
+- case 11025:
++ case SNDRV_PCM_RATE_11025:
+ adn |= 0x4 << 1;
+ break;
+- case 16000:
++ case SNDRV_PCM_RATE_16000:
+ adn |= 0x3 << 1;
+ break;
+- case 22050:
++ case SNDRV_PCM_RATE_22050:
+ adn |= 0x2 << 1;
+ break;
+- case 32000:
++ case SNDRV_PCM_RATE_32000:
+ adn |= 0x1 << 1;
+ break;
+- case 44100:
+- case 48000:
++ case SNDRV_PCM_RATE_44100:
++ case SNDRV_PCM_RATE_48000:
+ break;
+ }
+
+diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
+index e9123f5..1fd4e88 100644
+--- a/sound/soc/codecs/wm9712.c
++++ b/sound/soc/codecs/wm9712.c
+@@ -464,8 +464,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
+ {
+ u16 *cache = codec->reg_cache;
+
+- if (reg < 0x7c)
+- soc_ac97_ops.write(codec->ac97, reg, val);
++ soc_ac97_ops.write(codec->ac97, reg, val);
+ reg = reg >> 1;
+ if (reg < (ARRAY_SIZE(wm9712_reg)))
+ cache[reg] = val;
+diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
+index f26a125..8db0374 100644
+--- a/sound/usb/usbaudio.c
++++ b/sound/usb/usbaudio.c
+@@ -752,7 +752,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s
+ return 0; /* already large enough */
+ vfree(runtime->dma_area);
+ }
+- runtime->dma_area = vmalloc_user(size);
++ runtime->dma_area = vmalloc(size);
+ if (!runtime->dma_area)
+ return -ENOMEM;
+ runtime->dma_bytes = size;
+@@ -1936,7 +1936,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
+ struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
+ struct snd_usb_substream *subs = &as->substream[direction];
+
+- if (!as->chip->shutdown && subs->interface >= 0) {
++ if (subs->interface >= 0) {
+ usb_set_interface(subs->dev, subs->interface, 0);
+ subs->interface = -1;
+ }
+diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
+index 4101afe..e8a510d 100644
+--- a/tools/perf/builtin-timechart.c
++++ b/tools/perf/builtin-timechart.c
+@@ -275,7 +275,7 @@ static u64 cpus_pstate_state[MAX_CPUS];
+ static int
+ process_comm_event(event_t *event)
+ {
+- pid_set_comm(event->comm.tid, event->comm.comm);
++ pid_set_comm(event->comm.pid, event->comm.comm);
+ return 0;
+ }
+ static int
+diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
+index 251282c..bb4ebd8 100644
+--- a/virt/kvm/eventfd.c
++++ b/virt/kvm/eventfd.c
+@@ -168,7 +168,7 @@ irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
+ static int
+ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
+ {
+- struct _irqfd *irqfd, *tmp;
++ struct _irqfd *irqfd;
+ struct file *file = NULL;
+ struct eventfd_ctx *eventfd = NULL;
+ int ret;
+@@ -205,20 +205,9 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
+ init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup);
+ init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc);
+
+- spin_lock_irq(&kvm->irqfds.lock);
+-
+- ret = 0;
+- list_for_each_entry(tmp, &kvm->irqfds.items, list) {
+- if (irqfd->eventfd != tmp->eventfd)
+- continue;
+- /* This fd is used for another irq already. */
+- ret = -EBUSY;
+- spin_unlock_irq(&kvm->irqfds.lock);
+- goto fail;
+- }
+-
+ events = file->f_op->poll(file, &irqfd->pt);
+
++ spin_lock_irq(&kvm->irqfds.lock);
+ list_add_tail(&irqfd->list, &kvm->irqfds.items);
+ spin_unlock_irq(&kvm->irqfds.lock);
+
+diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
+index 5288885..001663f 100644
+--- a/virt/kvm/irq_comm.c
++++ b/virt/kvm/irq_comm.c
+@@ -205,17 +205,16 @@ int kvm_request_irq_source_id(struct kvm *kvm)
+ int irq_source_id;
+
+ mutex_lock(&kvm->irq_lock);
+- irq_source_id = find_first_zero_bit(bitmap, BITS_PER_LONG);
++ irq_source_id = find_first_zero_bit(bitmap,
++ sizeof(kvm->arch.irq_sources_bitmap));
+
+- if (irq_source_id >= BITS_PER_LONG) {
++ if (irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
+ printk(KERN_WARNING "kvm: exhaust allocatable IRQ sources!\n");
+- irq_source_id = -EFAULT;
+- goto unlock;
++ return -EFAULT;
+ }
+
+ ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
+ set_bit(irq_source_id, bitmap);
+-unlock:
+ mutex_unlock(&kvm->irq_lock);
+
+ return irq_source_id;
+@@ -229,17 +228,13 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
+
+ mutex_lock(&kvm->irq_lock);
+ if (irq_source_id < 0 ||
+- irq_source_id >= BITS_PER_LONG) {
++ irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
+ printk(KERN_ERR "kvm: IRQ source ID out of range!\n");
+- goto unlock;
++ return;
+ }
+- clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap);
+- if (!irqchip_in_kernel(kvm))
+- goto unlock;
+-
+ for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++)
+ clear_bit(irq_source_id, &kvm->arch.irq_states[i]);
+-unlock:
++ clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap);
+ mutex_unlock(&kvm->irq_lock);
+ }
+
diff --git a/recipes/linux/linux_2.6.26.bb b/recipes/linux/linux_2.6.26.bb
index 6089f47..8eccea3 100644
--- a/recipes/linux/linux_2.6.26.bb
+++ b/recipes/linux/linux_2.6.26.bb
@@ -7,7 +7,7 @@ DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_boc01 = "1"
DEFAULT_PREFERENCE_mpc8313e-rdb = "1"
DEFAULT_PREFERENCE_canyonlands = "1"
-DEFAULT_PREFERENCE_topas910 = "1"
+DEFAULT_PREFERENCE_topas910 = "-1"
SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.26.tar.bz2;name=kernel \
diff --git a/recipes/linux/linux_2.6.32.bb b/recipes/linux/linux_2.6.32.bb
index 009ba43..76eb0e0 100644
--- a/recipes/linux/linux_2.6.32.bb
+++ b/recipes/linux/linux_2.6.32.bb
@@ -1,6 +1,6 @@
require linux.inc
-PR = "r10"
+PR = "r11"
S = "${WORKDIR}/linux-${PV}"
@@ -10,6 +10,7 @@ DEFAULT_PREFERENCE_ion = "1"
DEFAULT_PREFERENCE_simone = "1"
DEFAULT_PREFERENCE_eee701 = "1"
DEFAULT_PREFERENCE_at91sam9g45ek = "1"
+DEFAULT_PREFERENCE_topas910 = "1"
DEFAULT_PREFERENCE_akita = "-1"
DEFAULT_PREFERENCE_c7x0 = "-1"
@@ -36,6 +37,9 @@ SRC_URI_append_at91sam9g45ek = " \
file://at91/linux-2.6.32-002-sam9g20-proper-reset.patch;patch=1 \
"
+SRC_URI_append_topas910 = " \
+ file://linux-2.6.32.9_topas910.patch;patch=1 \
+ "
# part of 2.6.24.7 patchset from Sim.One project
# other patches needs work
--
1.6.3.3
More information about the Openembedded-devel
mailing list