All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/3] topas910: Add BSP patch against 2.6.32.9 and make it default.
@ 2010-04-26 22:41 Matthias Günther
  2010-04-26 22:41 ` [PATCH v2 2/3] topas910: Add u-boot support Matthias Günther
  0 siblings, 1 reply; 3+ messages in thread
From: Matthias Günther @ 2010-04-26 22:41 UTC (permalink / raw)
  To: openembedded-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1748500 bytes --]

---
 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@linux.intel.com>
++M:	Sarah Sharp <sarah.a.sharp@intel.com>
+ L:	linux-usb@vger.kernel.org
+ S:	Supported
+-F:	drivers/usb/host/xhci*
+-F:	drivers/usb/host/pci-quirks*
+ 
+ USB ZC0301 DRIVER
+ M:	Luca Risolia <luca.risolia@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(&current->mm->mmap_sem);
++	ret = do_mmap(file, addr, len, prot, flags, off);
++	up_write(&current->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@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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
++	up_write(&current->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@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@kernelconcepts.de>
++ *
++ * Based on mach-ep93xx/gpio.c
++ * Copyright (c) 2008 Ryan Mallon <ryan@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@minirl.com)
++ *  Copyright (C) 2006 Jochen Karrer (jk06@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@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@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@kernelconcepts.de>
++ *
++ *  Based on mach-mx1ads/irq.c, which is:
++ *    Copyright (C) 1999 ARM Limited
++ *    Copyright (C) 2002 Shane Nay (shane@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@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@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@minirl.com)
++ *  Copyright (C) 2006 Jochen Karrer (jk06@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@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@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@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@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@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@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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, offset);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++        error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++        up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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 *) &current->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(&current->mm->mmap_sem);
++	ret = do_mmap_pgoff(file, addr, len, prot, flags, off);
++	up_write(&current->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(&current->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(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&current->mm->mmap_sem);
++	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
++	up_write(&current->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(&current->mm->mmap_sem);
++	retval = do_mmap(file, addr, len, prot, flags, off);
++	up_write(&current->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(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&regs->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, &reg_min, &reg_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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
++	up_write(&current->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(&current->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(&current->mm->mmap_sem);
++	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	up_write(&current->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(&copy, 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, &reg);
+ 	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, &reg);
+ 	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, &reg);
+ 	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@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, &reg);
+ 	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, &reg);
+ 	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@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@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(&notify_lock);
++	list_for_each_entry(ent, &notify_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(&notify_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(&notify_lock);
++		list_for_each_entry_safe(ent, n, &notify_list, notify_entry) {
++			if (cn_ctl_msg_equals(ent->msg, ctl)) {
++				list_del(&ent->notify_entry);
++				kfree(ent);
++			}
++		}
++		mutex_unlock(&notify_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(&notify_lock);
++	list_add(&ent->notify_entry, &notify_list);
++	mutex_unlock(&notify_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, &reg4a);
+ 			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@telia.com>
+  * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
+  * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
+- * Copyright (c) 2009 Sebastian Kapfer <sebastian_kapfer@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@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@saout.de>
+  * Copyright (C) 2004 Clemens Fruhwirth <clemens@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@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, &reg);
+-		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, &reg);
+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, &region, 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@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@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@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, &regs->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, &regs->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, &regs->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,
++				&regs->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, &regs->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, &regs->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, &regs->intrdisable);
++	spin_unlock (&ohci->lock);
++
++	if (HC_IS_RUNNING(hcd->state)) {
++		ohci_writel (ohci, ints, &regs->intrstatus);
++		ohci_writel (ohci, OHCI_INTR_MIE, &regs->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@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@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@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@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@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(&current->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@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++, &sect);
++		unsigned char *data = read_dev_sector(bdev, lba++, &sect);
+ 		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, &current->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@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 = &sect_attrs->attrs[0];
+ 	gattr = &sect_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 = &notes_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(&current->mm->mmap_sem);
+-	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+-	up_write(&current->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@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@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




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 2/3] topas910: Add u-boot support.
  2010-04-26 22:41 [PATCH v2 1/3] topas910: Add BSP patch against 2.6.32.9 and make it default Matthias Günther
@ 2010-04-26 22:41 ` Matthias Günther
  2010-04-26 22:41   ` [PATCH v2 3/3] topas910: linux_2.6.26 fix line break Matthias Günther
  0 siblings, 1 reply; 3+ messages in thread
From: Matthias Günther @ 2010-04-26 22:41 UTC (permalink / raw)
  To: openembedded-devel

---
 recipes/u-boot/u-boot-topas_git.bb |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 recipes/u-boot/u-boot-topas_git.bb

diff --git a/recipes/u-boot/u-boot-topas_git.bb b/recipes/u-boot/u-boot-topas_git.bb
new file mode 100644
index 0000000..d7ce94c
--- /dev/null
+++ b/recipes/u-boot/u-boot-topas_git.bb
@@ -0,0 +1,23 @@
+require u-boot.inc
+
+PV = "2008.10+${PR}+git"
+PR ="r2"
+PE = "1"
+
+SRC_URI = "git://git.labs.kernelconcepts.de/u-boot-topas.git/;protocol=git;tag=ca81d0245469af242e9a73360e46e99235eaadbf \
+          "
+
+UBOOT_MACHINE_topas910 = "topas910_config"
+
+S = "${WORKDIR}/git/u-boot-topas910/"
+
+do_compile () {
+        unset LDFLAGS
+        unset CFLAGS
+        unset CPPFLAGS
+        oe_runmake ${UBOOT_MACHINE}
+        oe_runmake all
+#        oe_runmake tools env
+        oe_runmake tools
+}
+
-- 
1.6.3.3




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 3/3] topas910: linux_2.6.26 fix line break
  2010-04-26 22:41 ` [PATCH v2 2/3] topas910: Add u-boot support Matthias Günther
@ 2010-04-26 22:41   ` Matthias Günther
  0 siblings, 0 replies; 3+ messages in thread
From: Matthias Günther @ 2010-04-26 22:41 UTC (permalink / raw)
  To: openembedded-devel

---
 recipes/linux/linux_2.6.26.bb |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/recipes/linux/linux_2.6.26.bb b/recipes/linux/linux_2.6.26.bb
index 8eccea3..4c66c11 100644
--- a/recipes/linux/linux_2.6.26.bb
+++ b/recipes/linux/linux_2.6.26.bb
@@ -1,6 +1,6 @@
 require linux.inc
 
-PR = "r10"
+PR = "r11"
 
 # Mark archs/machines that this kernel supports
 DEFAULT_PREFERENCE = "-1"
@@ -37,7 +37,9 @@ SRC_URI_append_mpc8313e-rdb = "\
 	file://mpc8313e-rdb-eth-fixed.patch;patch=1 \
 	"
 
-SRC_URI_append_topas910 = "http://www.bplan-gmbh.org/data/toshiba/topas/linux/2.6.26.5/patch_2.6.26.5_topas910.bz2;patch=1;name=topaspatch"
+SRC_URI_append_topas910 = " \
+	http://www.bplan-gmbh.org/data/toshiba/topas/linux/2.6.26.5/patch_2.6.26.5_topas910.bz2;patch=1;name=topaspatch \
+	"
 
 # see http://bugzilla.kernel.org/show_bug.cgi?id=11143
 do_install_append() {
-- 
1.6.3.3




^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-04-26 22:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-26 22:41 [PATCH v2 1/3] topas910: Add BSP patch against 2.6.32.9 and make it default Matthias Günther
2010-04-26 22:41 ` [PATCH v2 2/3] topas910: Add u-boot support Matthias Günther
2010-04-26 22:41   ` [PATCH v2 3/3] topas910: linux_2.6.26 fix line break Matthias Günther

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.