diff -ru 2.2/arch/arm/configs/ep93xx_defconfig 3.4/arch/arm/configs/ep93xx_defconfig
--- 2.2/arch/arm/configs/ep93xx_defconfig	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/configs/ep93xx_defconfig	2006-12-22 01:57:07.000000000 +0100
@@ -1,14 +1,18 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1-git9
-# Sat Jul 15 15:08:10 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:24 2006
 #
 CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -28,18 +32,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -48,12 +56,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -71,7 +79,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -103,7 +114,9 @@
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP23XX is not set
@@ -127,6 +140,7 @@
 #
 CONFIG_MACH_ADSSPHERE=y
 CONFIG_MACH_EDB9302=y
+CONFIG_MACH_EDB9302A=y
 CONFIG_MACH_EDB9312=y
 CONFIG_MACH_EDB9315=y
 CONFIG_MACH_EDB9315A=y
@@ -138,12 +152,14 @@
 #
 CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
-CONFIG_CPU_32v4=y
+CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
 CONFIG_CPU_CACHE_V4WT=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_COPY_V4WB=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
@@ -230,6 +246,7 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_NET_KEY=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -250,13 +267,29 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
@@ -283,7 +316,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -330,7 +362,7 @@
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
 # CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
 
 #
@@ -342,6 +374,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -430,7 +463,7 @@
 #
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -442,6 +475,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 # CONFIG_SCSI_PROC_FS is not set
 
 #
@@ -460,23 +495,29 @@
 # 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
 
 #
-# SCSI Transport Attributes
+# 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_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
 # CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -513,6 +554,7 @@
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+CONFIG_EP93XX_ETH=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
 
@@ -607,17 +649,12 @@
 # CONFIG_NVRAM is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -645,7 +682,7 @@
 #
 # CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_DS1374 is not set
-# CONFIG_SENSORS_EEPROM is not set
+CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -664,6 +701,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -697,12 +735,15 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -711,6 +752,7 @@
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # LED devices
@@ -729,7 +771,6 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -742,6 +783,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -763,6 +805,7 @@
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 CONFIG_USB_DYNAMIC_MINORS=y
+# CONFIG_USB_MULTITHREAD_PROBE is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -797,12 +840,12 @@
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
-# CONFIG_USB_HID is not set
 
 #
 # USB HID Boot Protocol drivers
@@ -821,6 +864,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 CONFIG_USB_RTL8150=y
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 # CONFIG_USB_MON is not set
 
@@ -834,8 +878,8 @@
 CONFIG_USB_SERIAL=y
 CONFIG_USB_SERIAL_CONSOLE=y
 # CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
 # CONFIG_USB_SERIAL_AIRPRIME is not set
-# CONFIG_USB_SERIAL_ANYDATA is not set
 # CONFIG_USB_SERIAL_ARK3116 is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
@@ -857,6 +901,8 @@
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=y
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -867,12 +913,14 @@
 # CONFIG_USB_SERIAL_XIRCOM is not set
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
 
 #
 # USB Miscellaneous drivers
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -880,11 +928,12 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -908,6 +957,7 @@
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
 CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
 # RTC interfaces
@@ -921,7 +971,7 @@
 # RTC drivers
 #
 # CONFIG_RTC_DRV_X1205 is not set
-# CONFIG_RTC_DRV_DS1307 is not set
+CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_ISL1208 is not set
 # CONFIG_RTC_DRV_DS1672 is not set
@@ -943,12 +993,14 @@
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -980,8 +1032,10 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -1102,6 +1156,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1110,8 +1169,11 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1128,10 +1190,9 @@
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
@@ -1151,12 +1212,9 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1164,3 +1222,4 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff -ru 2.2/arch/arm/configs/iop13xx_defconfig 3.4/arch/arm/configs/iop13xx_defconfig
--- 2.2/arch/arm/configs/iop13xx_defconfig	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/configs/iop13xx_defconfig	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19
-# Fri Dec  1 10:51:01 2006
+# Linux kernel version: 2.6.20-rc1-git5
+# Tue Dec 19 21:38:01 2006
 #
 CONFIG_ARM=y
 # CONFIG_GENERIC_TIME is not set
@@ -11,6 +11,8 @@
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -39,6 +41,7 @@
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -77,7 +80,9 @@
 # Block layer
 #
 CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -154,11 +159,13 @@
 CONFIG_ARM_THUMB=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_IWMMXT is not set
 
 #
 # Bus support
 #
 CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -259,9 +266,23 @@
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_IPV6 is not set
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
@@ -433,7 +454,7 @@
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=2
@@ -448,6 +469,7 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
@@ -467,6 +489,7 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
 
 #
 # SCSI Transports
@@ -510,6 +533,7 @@
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
 
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -605,6 +629,7 @@
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -711,10 +736,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -820,6 +841,7 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
@@ -830,6 +852,7 @@
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -883,6 +906,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -970,6 +998,7 @@
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+CONFIG_ECRYPT_FS=y
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1092,6 +1121,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1103,28 +1137,68 @@
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_FS is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_USER=y
 
 #
 # Security options
 #
-# CONFIG_KEYS is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1132,3 +1206,4 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff -ru 2.2/arch/arm/configs/iop32x_defconfig 3.4/arch/arm/configs/iop32x_defconfig
--- 2.2/arch/arm/configs/iop32x_defconfig	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/configs/iop32x_defconfig	2006-12-22 01:57:07.000000000 +0100
@@ -1,15 +1,18 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc7
-# Tue Sep 19 00:30:18 2006
+# Linux kernel version: 2.6.20-rc1-git5
+# Tue Dec 19 21:37:52 2006
 #
 CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -29,18 +32,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -49,12 +56,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -72,7 +79,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -106,6 +116,7 @@
 # CONFIG_ARCH_IMX is not set
 CONFIG_ARCH_IOP32X=y
 # CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP23XX is not set
@@ -141,17 +152,22 @@
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
 #
 # CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_IWMMXT is not set
 CONFIG_XSCALE_PMU=y
 
 #
 # Bus support
 #
 CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -225,6 +241,7 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -246,13 +263,29 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
@@ -279,7 +312,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -338,6 +370,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -419,9 +452,11 @@
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
@@ -440,6 +475,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -458,14 +495,16 @@
 # 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
 
 #
-# SCSI Transport Attributes
+# 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_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -478,26 +517,84 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -512,6 +609,7 @@
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
 # CONFIG_DM_CRYPT is not set
 # CONFIG_DM_SNAPSHOT is not set
 # CONFIG_DM_MIRROR is not set
@@ -612,6 +710,7 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -620,6 +719,7 @@
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -654,6 +754,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -725,10 +826,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -736,7 +833,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -801,6 +897,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -834,15 +931,18 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -851,6 +951,8 @@
 #
 # Misc devices
 #
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 
 #
 # LED devices
@@ -869,12 +971,12 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
@@ -895,6 +997,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -909,6 +1016,7 @@
 # CONFIG_USB_DEVICEFS is not set
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -946,6 +1054,7 @@
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -984,6 +1093,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1001,6 +1111,7 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -1008,12 +1119,13 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB DSL modem support
@@ -1045,6 +1157,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1056,6 +1169,7 @@
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1084,8 +1198,10 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -1095,6 +1211,7 @@
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+CONFIG_ECRYPT_FS=y
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1129,7 +1246,7 @@
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -1172,6 +1289,11 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1180,8 +1302,11 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1197,10 +1322,9 @@
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
@@ -1211,13 +1335,48 @@
 #
 # Security options
 #
-# CONFIG_KEYS is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Hardware crypto devices
@@ -1226,10 +1385,12 @@
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff -ru 2.2/arch/arm/configs/iop33x_defconfig 3.4/arch/arm/configs/iop33x_defconfig
--- 2.2/arch/arm/configs/iop33x_defconfig	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/configs/iop33x_defconfig	2006-12-22 01:57:07.000000000 +0100
@@ -1,15 +1,18 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc7
-# Tue Sep 19 00:30:42 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:34 2006
 #
 CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -29,18 +32,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -49,12 +56,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -72,7 +79,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -106,6 +116,7 @@
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_IOP32X is not set
 CONFIG_ARCH_IOP33X=y
+# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP23XX is not set
@@ -139,17 +150,22 @@
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
 #
 # CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_IWMMXT is not set
 CONFIG_XSCALE_PMU=y
 
 #
 # Bus support
 #
 CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -223,6 +239,7 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -244,13 +261,29 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
@@ -277,7 +310,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -336,6 +368,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -423,7 +456,7 @@
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -443,6 +476,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -461,14 +496,16 @@
 # 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
 
 #
-# SCSI Transport Attributes
+# 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_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -481,26 +518,34 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -515,6 +560,7 @@
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
 # CONFIG_DM_CRYPT is not set
 # CONFIG_DM_SNAPSHOT is not set
 # CONFIG_DM_MIRROR is not set
@@ -580,6 +626,7 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -588,6 +635,7 @@
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -622,6 +670,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -693,10 +742,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -704,7 +749,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -769,6 +813,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -802,15 +847,18 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -819,6 +867,8 @@
 #
 # Misc devices
 #
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 
 #
 # LED devices
@@ -837,7 +887,6 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -863,6 +912,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -900,6 +954,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -911,6 +966,7 @@
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -939,8 +995,10 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -1019,6 +1077,11 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1027,8 +1090,11 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1044,10 +1110,9 @@
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
@@ -1067,10 +1132,6 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
@@ -1078,3 +1139,4 @@
 # CONFIG_CRC32 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff -ru 2.2/arch/arm/configs/ixp2000_defconfig 3.4/arch/arm/configs/ixp2000_defconfig
--- 2.2/arch/arm/configs/ixp2000_defconfig	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/configs/ixp2000_defconfig	2006-12-22 01:57:07.000000000 +0100
@@ -1,14 +1,18 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Sun Jul  9 15:28:50 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:39 2006
 #
 CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -28,17 +32,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -47,12 +56,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -70,7 +79,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -102,7 +114,9 @@
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_IXP23XX is not set
@@ -143,24 +157,28 @@
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
 #
 # CONFIG_ARM_THUMB is not set
 CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_IWMMXT is not set
 CONFIG_XSCALE_PMU=y
 
 #
 # Bus support
 #
 CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # Kernel Features
@@ -228,6 +246,7 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -248,13 +267,29 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
@@ -281,7 +316,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -308,7 +342,6 @@
 #
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
@@ -340,6 +373,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -422,11 +456,12 @@
 # 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_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -436,6 +471,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -501,8 +542,8 @@
 # CONFIG_FORCEDETH is not set
 CONFIG_CS89x0=y
 # CONFIG_DGRS is not set
-CONFIG_EEPRO100=y
-# CONFIG_E100 is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -532,6 +573,7 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -540,6 +582,7 @@
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -555,7 +598,6 @@
 # Wan interfaces
 #
 CONFIG_WAN=y
-# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 CONFIG_HDLC=y
 CONFIG_HDLC_RAW=y
@@ -571,6 +613,7 @@
 # CONFIG_WANXL is not set
 # CONFIG_PC300 is not set
 # CONFIG_FARSYNC is not set
+# CONFIG_DSCC4 is not set
 CONFIG_DLCI=y
 CONFIG_DLCI_COUNT=24
 CONFIG_DLCI_MAX=8
@@ -592,6 +635,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -673,10 +717,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -684,7 +724,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -749,6 +788,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -782,15 +822,18 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -799,6 +842,8 @@
 #
 # Misc devices
 #
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 
 #
 # LED devices
@@ -817,7 +862,6 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -829,6 +873,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -836,6 +881,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -875,6 +925,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -882,6 +933,7 @@
 # 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_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -910,8 +962,10 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -961,7 +1015,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -994,6 +1047,11 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1002,8 +1060,11 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1019,10 +1080,9 @@
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
@@ -1042,12 +1102,9 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1055,3 +1112,4 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff -ru 2.2/arch/arm/configs/ixp23xx_defconfig 3.4/arch/arm/configs/ixp23xx_defconfig
--- 2.2/arch/arm/configs/ixp23xx_defconfig	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/configs/ixp23xx_defconfig	2006-12-22 01:57:07.000000000 +0100
@@ -1,14 +1,18 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Sun Jul  9 14:13:35 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:45 2006
 #
 CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -28,17 +32,22 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -47,12 +56,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -70,7 +79,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -102,7 +114,9 @@
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 CONFIG_ARCH_IXP23XX=y
@@ -137,6 +151,8 @@
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 CONFIG_IO_36=y
 
 #
@@ -144,11 +160,15 @@
 #
 # CONFIG_ARM_THUMB is not set
 CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_IWMMXT is not set
 
 #
 # Bus support
 #
 CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -222,6 +242,7 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -242,13 +263,29 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
@@ -275,7 +312,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -334,6 +370,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -418,12 +455,13 @@
 # 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_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -432,6 +470,7 @@
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -455,7 +494,6 @@
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 # CONFIG_IDEDMA_PCI_AUTO is not set
@@ -469,6 +507,7 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
 # CONFIG_BLK_DEV_IT821X is not set
@@ -477,6 +516,7 @@
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SL82C105 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
@@ -491,6 +531,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -509,14 +551,16 @@
 # 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
 
 #
-# SCSI Transport Attributes
+# 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_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -529,26 +573,34 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -649,6 +701,7 @@
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -657,6 +710,7 @@
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -672,7 +726,6 @@
 # Wan interfaces
 #
 CONFIG_WAN=y
-# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 CONFIG_HDLC=y
 CONFIG_HDLC_RAW=y
@@ -688,6 +741,7 @@
 # CONFIG_WANXL is not set
 # CONFIG_PC300 is not set
 # CONFIG_FARSYNC is not set
+# CONFIG_DSCC4 is not set
 CONFIG_DLCI=y
 CONFIG_DLCI_COUNT=24
 CONFIG_DLCI_MAX=8
@@ -710,6 +764,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -795,10 +850,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -806,7 +857,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -870,6 +920,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -903,15 +954,18 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -920,6 +974,8 @@
 #
 # Misc devices
 #
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 
 #
 # LED devices
@@ -938,7 +994,6 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -951,6 +1006,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -958,6 +1014,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -972,6 +1033,7 @@
 # CONFIG_USB_DEVICEFS is not set
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -1012,6 +1074,7 @@
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -1050,6 +1113,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1067,19 +1131,21 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
-# CONFIG_USB_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB DSL modem support
@@ -1113,6 +1179,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1120,6 +1187,7 @@
 # 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_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1150,8 +1218,10 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -1201,7 +1271,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1273,6 +1342,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1281,8 +1355,11 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1298,10 +1375,9 @@
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
@@ -1321,12 +1397,9 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1334,3 +1407,4 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff -ru 2.2/arch/arm/configs/lpd270_defconfig 3.4/arch/arm/configs/lpd270_defconfig
--- 2.2/arch/arm/configs/lpd270_defconfig	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/configs/lpd270_defconfig	2006-12-22 01:57:07.000000000 +0100
@@ -1,14 +1,18 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Sun Jul  9 14:15:23 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:51 2006
 #
 CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_ARCH_MTD_XIP=y
@@ -29,16 +33,21 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -47,12 +56,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -69,7 +78,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -101,7 +113,9 @@
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP23XX is not set
@@ -125,7 +139,6 @@
 # CONFIG_PXA_SHARPSL is not set
 # CONFIG_MACH_TRIZEPS4 is not set
 CONFIG_PXA27x=y
-CONFIG_IWMMXT=y
 
 #
 # Processor Type
@@ -136,11 +149,15 @@
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
 #
 # CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_IWMMXT=y
 CONFIG_XSCALE_PMU=y
 
 #
@@ -217,6 +234,7 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -237,13 +255,29 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
@@ -270,7 +304,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -329,6 +362,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -410,7 +444,7 @@
 #
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -447,6 +481,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -526,6 +566,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -548,6 +589,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -600,17 +642,12 @@
 # CONFIG_NVRAM is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -626,6 +663,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -634,11 +672,14 @@
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # LED devices
@@ -657,7 +698,6 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -679,6 +719,7 @@
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_PXA=y
 # CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -725,7 +766,6 @@
 # Generic devices
 #
 CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_AC97_BUS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
 # CONFIG_SND_SERIAL_U16550 is not set
@@ -741,6 +781,12 @@
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+
+#
+# HID Devices
+#
+CONFIG_HID=y
 
 #
 # USB support
@@ -777,10 +823,12 @@
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -811,6 +859,7 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -860,7 +909,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -917,6 +965,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -925,8 +978,11 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -942,10 +998,9 @@
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
@@ -965,12 +1020,9 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -978,3 +1030,4 @@
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff -ru 2.2/arch/arm/configs/onearm_defconfig 3.4/arch/arm/configs/onearm_defconfig
--- 2.2/arch/arm/configs/onearm_defconfig	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/configs/onearm_defconfig	2006-12-22 01:57:07.000000000 +0100
@@ -1,14 +1,18 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Sun Jul  9 14:16:20 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:18 2006
 #
 CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -28,16 +32,21 @@
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -46,12 +55,12 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -69,7 +78,10 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -101,7 +113,9 @@
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP23XX is not set
@@ -118,10 +132,6 @@
 #
 # Atmel AT91 System-on-Chip
 #
-
-#
-# Atmel AT91 Processors
-#
 CONFIG_ARCH_AT91RM9200=y
 # CONFIG_ARCH_AT91SAM9260 is not set
 # CONFIG_ARCH_AT91SAM9261 is not set
@@ -140,6 +150,10 @@
 # CONFIG_MACH_KAFA is not set
 
 #
+# AT91 Board Options
+#
+
+#
 # AT91 Feature Selections
 #
 CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
@@ -149,12 +163,14 @@
 #
 CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
-CONFIG_CPU_32v4=y
+CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
 CONFIG_CPU_CACHE_V4WT=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_COPY_V4WB=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
@@ -251,6 +267,7 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -271,13 +288,29 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
@@ -304,7 +337,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -360,6 +392,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -438,11 +471,12 @@
 #
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -457,6 +491,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -541,6 +581,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -619,10 +660,6 @@
 # CONFIG_R3964 is not set
 
 #
-# Ftape, the floppy tape device driver
-#
-
-#
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
@@ -634,7 +671,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -652,6 +688,7 @@
 #
 # I2C Hardware Bus support
 #
+# CONFIG_I2C_AT91 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
@@ -681,6 +718,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -714,12 +752,15 @@
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -728,6 +769,7 @@
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # LED devices
@@ -746,7 +788,6 @@
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -759,6 +800,7 @@
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -766,6 +808,11 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -780,6 +827,7 @@
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -804,7 +852,6 @@
 #
 # may also be needed; see USB_STORAGE Help for more information
 #
-# CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -842,6 +889,7 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -859,18 +907,20 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
-# CONFIG_USB_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -897,6 +947,7 @@
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
 
 #
 # MMC/SD Card support
@@ -904,7 +955,8 @@
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 CONFIG_MMC_BLOCK=y
-CONFIG_MMC_AT91RM9200=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_TIFM_SD is not set
 
 #
 # Real Time Clock
@@ -919,10 +971,12 @@
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -951,8 +1005,10 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -995,7 +1051,6 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1013,6 +1068,11 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 # CONFIG_PROFILING is not set
@@ -1021,8 +1081,11 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1038,10 +1101,9 @@
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
@@ -1061,15 +1123,13 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff -ru 2.2/arch/arm/kernel/calls.S 3.4/arch/arm/kernel/calls.S
--- 2.2/arch/arm/kernel/calls.S	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/arch/arm/kernel/calls.S	2006-12-22 01:57:07.000000000 +0100
@@ -110,7 +110,7 @@
 		CALL(sys_ni_syscall)		/* was sys_profil */
 		CALL(sys_statfs)
 /* 100 */	CALL(sys_fstatfs)
-		CALL(sys_ni_syscall)
+		CALL(sys_ni_syscall)		/* sys_ioperm */
 		CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
 		CALL(sys_syslog)
 		CALL(sys_setitimer)
@@ -132,7 +132,7 @@
 /* 120 */	CALL(sys_clone_wrapper)
 		CALL(sys_setdomainname)
 		CALL(sys_newuname)
-		CALL(sys_ni_syscall)
+		CALL(sys_ni_syscall)		/* modify_ldt */
 		CALL(sys_adjtimex)
 /* 125 */	CALL(sys_mprotect)
 		CALL(sys_sigprocmask)
@@ -146,7 +146,7 @@
 		CALL(sys_bdflush)
 /* 135 */	CALL(sys_sysfs)
 		CALL(sys_personality)
-		CALL(sys_ni_syscall)		/* CALL(_sys_afs_syscall) */
+		CALL(sys_ni_syscall)		/* reserved for afs_syscall */
 		CALL(sys_setfsuid16)
 		CALL(sys_setfsgid16)
 /* 140 */	CALL(sys_llseek)
@@ -175,7 +175,7 @@
 		CALL(sys_arm_mremap)
 		CALL(sys_setresuid16)
 /* 165 */	CALL(sys_getresuid16)
-		CALL(sys_ni_syscall)
+		CALL(sys_ni_syscall)		/* vm86 */
 		CALL(sys_ni_syscall)		/* was sys_query_module */
 		CALL(sys_poll)
 		CALL(sys_nfsservctl)
@@ -197,8 +197,8 @@
 /* 185 */	CALL(sys_capset)
 		CALL(sys_sigaltstack_wrapper)
 		CALL(sys_sendfile)
-		CALL(sys_ni_syscall)
-		CALL(sys_ni_syscall)
+		CALL(sys_ni_syscall)		/* getpmsg */
+		CALL(sys_ni_syscall)		/* putpmsg */
 /* 190 */	CALL(sys_vfork_wrapper)
 		CALL(sys_getrlimit)
 		CALL(sys_mmap2)
@@ -344,6 +344,18 @@
 		CALL(sys_readlinkat)
 		CALL(sys_fchmodat)
 		CALL(sys_faccessat)
+/* 335 */	CALL(sys_ni_syscall)		/* eventually pselect6 */
+		CALL(sys_ni_syscall)		/* eventually ppoll */
+		CALL(sys_unshare)
+		CALL(sys_set_robust_list)
+		CALL(sys_get_robust_list)
+/* 340 */	CALL(sys_splice)
+		CALL(sys_arm_sync_file_range)
+		CALL(sys_tee)
+		CALL(sys_vmsplice)
+		CALL(sys_move_pages)
+/* 345 */	CALL(sys_getcpu)
+		CALL(sys_ni_syscall)		/* eventually epoll_pwait */
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
diff -ru 2.2/arch/arm/kernel/setup.c 3.4/arch/arm/kernel/setup.c
--- 2.2/arch/arm/kernel/setup.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/arch/arm/kernel/setup.c	2006-12-22 01:57:07.000000000 +0100
@@ -855,6 +855,7 @@
 	"edsp",
 	"java",
 	"iwmmxt",
+	"crunch",
 	NULL
 };
 
diff -ru 2.2/arch/arm/kernel/sys_arm.c 3.4/arch/arm/kernel/sys_arm.c
--- 2.2/arch/arm/kernel/sys_arm.c	2006-10-02 19:14:46.000000000 +0200
+++ 3.4/arch/arm/kernel/sys_arm.c	2006-12-22 01:57:07.000000000 +0100
@@ -328,3 +328,16 @@
 {
 	return sys_fadvise64_64(fd, offset, len, advice);
 }
+
+/*
+ * Yet more syscall fsckage - we can't fit sys_sync_file_range's
+ * arguments into the available registers with EABI.  So, let's
+ * create an ARM specific syscall for this which has _sane_
+ * arguments.  (This incidentally also has an ABI-independent
+ * argument layout.)
+ */
+asmlinkage long sys_arm_sync_file_range(int fd, unsigned int flags,
+					loff_t offset, loff_t nbytes)
+{
+	return sys_sync_file_range(fd, offset, nbytes, flags);
+}
diff -ru 2.2/arch/arm/mach-ep93xx/core.c 3.4/arch/arm/mach-ep93xx/core.c
--- 2.2/arch/arm/mach-ep93xx/core.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-ep93xx/core.c	2006-12-22 01:57:07.000000000 +0100
@@ -477,4 +477,8 @@
 
 	platform_device_register(&ep93xx_rtc_device);
 	platform_device_register(&ep93xx_ohci_device);
+
+#ifdef CONFIG_CRUNCH
+	elf_hwcap |= HWCAP_CRUNCH;
+#endif
 }
diff -ru 2.2/arch/arm/mach-iop13xx/iq81340mc.c 3.4/arch/arm/mach-iop13xx/iq81340mc.c
--- 2.2/arch/arm/mach-iop13xx/iq81340mc.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-iop13xx/iq81340mc.c	2006-12-22 01:57:07.000000000 +0100
@@ -88,11 +88,11 @@
 
 MACHINE_START(IQ81340MC, "Intel IQ81340MC")
 	/* Maintainer: Dan Williams <dan.j.williams@intel.com> */
-	.phys_io        = PHYS_IO,
-	.io_pg_offst    = IO_PG_OFFSET,
+	.phys_io        = IOP13XX_PMMR_PHYS_MEM_BASE,
+	.io_pg_offst    = (IOP13XX_PMMR_VIRT_MEM_BASE >> 18) & 0xfffc,
+	.boot_params    = 0x00000100,
 	.map_io         = iop13xx_map_io,
 	.init_irq       = iop13xx_init_irq,
 	.timer          = &iq81340mc_timer,
-	.boot_params    = BOOT_PARAM_OFFSET,
 	.init_machine   = iq81340mc_init,
 MACHINE_END
diff -ru 2.2/arch/arm/mach-iop13xx/iq81340sc.c 3.4/arch/arm/mach-iop13xx/iq81340sc.c
--- 2.2/arch/arm/mach-iop13xx/iq81340sc.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-iop13xx/iq81340sc.c	2006-12-22 01:57:07.000000000 +0100
@@ -90,11 +90,11 @@
 
 MACHINE_START(IQ81340SC, "Intel IQ81340SC")
 	/* Maintainer: Dan Williams <dan.j.williams@intel.com> */
-	.phys_io        = PHYS_IO,
-	.io_pg_offst    = IO_PG_OFFSET,
+	.phys_io	= IOP13XX_PMMR_PHYS_MEM_BASE,
+	.io_pg_offst	= (IOP13XX_PMMR_VIRT_MEM_BASE >> 18) & 0xfffc,
+	.boot_params    = 0x00000100,
 	.map_io         = iop13xx_map_io,
 	.init_irq       = iop13xx_init_irq,
 	.timer          = &iq81340sc_timer,
-	.boot_params    = BOOT_PARAM_OFFSET,
 	.init_machine   = iq81340sc_init,
 MACHINE_END
diff -ru 2.2/arch/arm/mach-iop13xx/irq.c 3.4/arch/arm/mach-iop13xx/irq.c
--- 2.2/arch/arm/mach-iop13xx/irq.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-iop13xx/irq.c	2006-12-22 01:57:07.000000000 +0100
@@ -222,25 +222,29 @@
 	iop13xx_cp6_restore(cp_flags);
 }
 
-static struct irqchip iop13xx_irqchip0 = {
+static struct irq_chip iop13xx_irqchip1 = {
+	.name	= "IOP13xx-1",
 	.ack    = iop13xx_irq_mask0,
 	.mask   = iop13xx_irq_mask0,
 	.unmask = iop13xx_irq_unmask0,
 };
 
-static struct irqchip iop13xx_irqchip1 = {
+static struct irq_chip iop13xx_irqchip2 = {
+	.name	= "IOP13xx-2",
 	.ack    = iop13xx_irq_mask1,
 	.mask   = iop13xx_irq_mask1,
 	.unmask = iop13xx_irq_unmask1,
 };
 
-static struct irqchip iop13xx_irqchip2 = {
+static struct irq_chip iop13xx_irqchip3 = {
+	.name	= "IOP13xx-3",
 	.ack    = iop13xx_irq_mask2,
 	.mask   = iop13xx_irq_mask2,
 	.unmask = iop13xx_irq_unmask2,
 };
 
-static struct irqchip iop13xx_irqchip3 = {
+static struct irq_chip iop13xx_irqchip4 = {
+	.name	= "IOP13xx-4",
 	.ack    = iop13xx_irq_mask3,
 	.mask   = iop13xx_irq_mask3,
 	.unmask = iop13xx_irq_unmask3,
@@ -270,15 +274,15 @@
 
 	for(i = 0; i < NR_IOP13XX_IRQS; i++) {
 		if (i < 32)
-			set_irq_chip(i, &iop13xx_irqchip0);
-		else if (i < 64)
 			set_irq_chip(i, &iop13xx_irqchip1);
-		else if (i < 96)
+		else if (i < 64)
 			set_irq_chip(i, &iop13xx_irqchip2);
-		else
+		else if (i < 96)
 			set_irq_chip(i, &iop13xx_irqchip3);
+		else
+			set_irq_chip(i, &iop13xx_irqchip4);
 
-		set_irq_handler(i, do_level_IRQ);
+		set_irq_handler(i, handle_level_irq);
 		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
 	}
 
diff -ru 2.2/arch/arm/mach-iop13xx/setup.c 3.4/arch/arm/mach-iop13xx/setup.c
--- 2.2/arch/arm/mach-iop13xx/setup.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-iop13xx/setup.c	2006-12-22 01:57:07.000000000 +0100
@@ -337,7 +337,7 @@
 
 #ifdef CONFIG_MTD_PHYSMAP
 	iq8134x_flash_resource.end = iq8134x_flash_resource.start +
-				iq8134x_probe_flash_size();
+				iq8134x_probe_flash_size() - 1;
 	if (iq8134x_flash_resource.end > iq8134x_flash_resource.start)
 		iop13xx_devices[plat_idx++] = &iq8134x_flash;
 	else
diff -ru 2.2/arch/arm/mach-s3c2410/cpu.c 3.4/arch/arm/mach-s3c2410/cpu.c
--- 2.2/arch/arm/mach-s3c2410/cpu.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/cpu.c	2006-12-22 01:57:07.000000000 +0100
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/hardware.h>
diff -ru 2.2/arch/arm/mach-s3c2410/devs.c 3.4/arch/arm/mach-s3c2410/devs.c
--- 2.2/arch/arm/mach-s3c2410/devs.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/devs.c	2006-12-22 01:57:07.000000000 +0100
@@ -17,6 +17,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
diff -ru 2.2/arch/arm/mach-s3c2410/dma.c 3.4/arch/arm/mach-s3c2410/dma.c
--- 2.2/arch/arm/mach-s3c2410/dma.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-s3c2410/dma.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/dma.c
  *
- * (c) 2003-2005,2006 Simtec Electronics
+ * Copyright (c) 2003-2005,2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 DMA core
diff -ru 2.2/arch/arm/mach-s3c2410/irq.h 3.4/arch/arm/mach-s3c2410/irq.h
--- 2.2/arch/arm/mach-s3c2410/irq.h	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-s3c2410/irq.h	2006-12-22 01:57:07.000000000 +0100
@@ -8,8 +8,6 @@
  * 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.
- *
- * Modifications:
 */
 
 #define irqdbf(x...)
diff -ru 2.2/arch/arm/mach-s3c2410/Kconfig 3.4/arch/arm/mach-s3c2410/Kconfig
--- 2.2/arch/arm/mach-s3c2410/Kconfig	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-s3c2410/Kconfig	2006-12-22 01:57:07.000000000 +0100
@@ -5,6 +5,7 @@
 config MACH_AML_M5900
 	bool "AML M5900 Series"
 	select CPU_S3C2410
+	select PM_SIMTEC if PM
 	help
 	   Say Y here if you are using the American Microsystems M5900 Series
            <http://www.amltd.com>
@@ -12,6 +13,7 @@
 config MACH_ANUBIS
 	bool "Simtec Electronics ANUBIS"
 	select CPU_S3C2440
+	select PM_SIMTEC if PM
 	help
 	  Say Y here if you are using the Simtec Electronics ANUBIS
 	  development system
@@ -19,6 +21,7 @@
 config MACH_OSIRIS
 	bool "Simtec IM2440D20 (OSIRIS) module"
 	select CPU_S3C2440
+	select PM_SIMTEC if PM
 	help
 	  Say Y here if you are using the Simtec IM2440D20 module, also
 	  known as the Osiris.
@@ -26,6 +29,7 @@
 config ARCH_BAST
 	bool "Simtec Electronics BAST (EB2410ITX)"
 	select CPU_S3C2410
+	select PM_SIMTEC if PM
 	select ISA
 	help
 	  Say Y here if you are using the Simtec Electronics EB2410ITX
@@ -43,14 +47,13 @@
 
 config PM_H1940
 	bool
-	depends on PM
 	help
 	  Internal node for H1940 and related PM
 
 config ARCH_H1940
 	bool "IPAQ H1940"
 	select CPU_S3C2410
-	select PM_H1940
+	select PM_H1940 if PM
 	help
 	  Say Y here if you are using the HP IPAQ H1940
 
@@ -112,6 +115,7 @@
 
 config MACH_VR1000
 	bool "Thorcom VR1000"
+	select PM_SIMTEC if PM
 	select CPU_S3C2410
 	help
 	  Say Y here if you are using the Thorcom VR1000 board.
@@ -122,7 +126,7 @@
 config MACH_RX3715
 	bool "HP iPAQ rx3715"
 	select CPU_S3C2440
-	select PM_H1940
+	select PM_H1940 if PM
 	help
 	  Say Y here if you are using the HP iPAQ rx3715.
 
@@ -156,7 +160,6 @@
 
 config S3C2410_PM
 	bool
-	depends on CONFIG_PM
 	help
 	  Power Management code common to S3C2410 and better
 
@@ -171,7 +174,7 @@
 	bool
 	depends on ARCH_S3C2410
 	select S3C2410_CLOCK
-	select S3C2410_PM
+	select S3C2410_PM if PM
 	help
 	  Support for S3C2410 and S3C2410A family from the S3C24XX line
 	  of Samsung Mobile CPUs.
@@ -186,14 +189,13 @@
 
 config S3C2412_PM
 	bool
-	default y if PM
-	depends on CPU_S3C2412
 	help
 	  Internal config node to apply S3C2412 power management
 
 config CPU_S3C2412
 	bool
 	depends on ARCH_S3C2410
+	select S3C2412_PM if PM
 	help
 	  Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
 
@@ -207,7 +209,7 @@
 	bool
 	depends on ARCH_S3C2410
 	select S3C2410_CLOCK
-	select S3C2410_PM
+	select S3C2410_PM if PM
 	select CPU_S3C244X
 	help
 	  Support for S3C2440 Samsung Mobile CPU based systems.
@@ -216,7 +218,7 @@
 	bool
 	depends on ARCH_S3C2420
 	select S3C2410_CLOCK
-	select S3C2410_PM
+	select S3C2410_PM if PM
 	select CPU_S3C244X
 	help
 	  Support for S3C2442 Samsung Mobile CPU based systems.
@@ -300,8 +302,9 @@
 
 config PM_SIMTEC
 	bool
-	depends on PM && (ARCH_BAST || MACH_VR1000 || MACH_AML_M5900)
-	default y
+	help
+	  Common power management code for systems that are
+	  compatible with the Simtec style of power management
 
 config S3C2410_LOWLEVEL_UART_PORT
 	int "S3C2410 UART to use for low-level messages"
diff -ru 2.2/arch/arm/mach-s3c2410/mach-anubis.c 3.4/arch/arm/mach-s3c2410/mach-anubis.c
--- 2.2/arch/arm/mach-s3c2410/mach-anubis.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/mach-anubis.c	2006-12-22 01:57:07.000000000 +0100
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
diff -ru 2.2/arch/arm/mach-s3c2410/mach-bast.c 3.4/arch/arm/mach-s3c2410/mach-bast.c
--- 2.2/arch/arm/mach-s3c2410/mach-bast.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/mach-bast.c	2006-12-22 01:57:07.000000000 +0100
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/dm9000.h>
 
diff -ru 2.2/arch/arm/mach-s3c2410/mach-h1940.c 3.4/arch/arm/mach-s3c2410/mach-h1940.c
--- 2.2/arch/arm/mach-s3c2410/mach-h1940.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-s3c2410/mach-h1940.c	2006-12-22 01:57:07.000000000 +0100
@@ -17,6 +17,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
@@ -37,8 +38,6 @@
 #include <asm/arch/h1940-latch.h>
 #include <asm/arch/fb.h>
 
-#include <linux/serial_core.h>
-
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
diff -ru 2.2/arch/arm/mach-s3c2410/mach-n30.c 3.4/arch/arm/mach-s3c2410/mach-n30.c
--- 2.2/arch/arm/mach-s3c2410/mach-n30.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/mach-n30.c	2006-12-22 01:57:07.000000000 +0100
@@ -20,6 +20,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/kthread.h>
 
@@ -37,8 +38,6 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/iic.h>
 
-#include <linux/serial_core.h>
-
 #include "s3c2410.h"
 #include "clock.h"
 #include "devs.h"
diff -ru 2.2/arch/arm/mach-s3c2410/mach-nexcoder.c 3.4/arch/arm/mach-s3c2410/mach-nexcoder.c
--- 2.2/arch/arm/mach-s3c2410/mach-nexcoder.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/mach-nexcoder.c	2006-12-22 01:57:07.000000000 +0100
@@ -19,6 +19,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <linux/mtd/map.h>
diff -ru 2.2/arch/arm/mach-s3c2410/mach-osiris.c 3.4/arch/arm/mach-s3c2410/mach-osiris.c
--- 2.2/arch/arm/mach-s3c2410/mach-osiris.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-s3c2410/mach-osiris.c	2006-12-22 01:57:07.000000000 +0100
@@ -16,6 +16,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/serial_core.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff -ru 2.2/arch/arm/mach-s3c2410/mach-otom.c 3.4/arch/arm/mach-s3c2410/mach-otom.c
--- 2.2/arch/arm/mach-s3c2410/mach-otom.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/mach-otom.c	2006-12-22 01:57:07.000000000 +0100
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
diff -ru 2.2/arch/arm/mach-s3c2410/mach-smdk2410.c 3.4/arch/arm/mach-s3c2410/mach-smdk2410.c
--- 2.2/arch/arm/mach-s3c2410/mach-smdk2410.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/mach-smdk2410.c	2006-12-22 01:57:07.000000000 +0100
@@ -35,6 +35,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
diff -ru 2.2/arch/arm/mach-s3c2410/mach-smdk2413.c 3.4/arch/arm/mach-s3c2410/mach-smdk2413.c
--- 2.2/arch/arm/mach-s3c2410/mach-smdk2413.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/mach-smdk2413.c	2006-12-22 01:57:07.000000000 +0100
@@ -17,6 +17,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
diff -ru 2.2/arch/arm/mach-s3c2410/mach-smdk2440.c 3.4/arch/arm/mach-s3c2410/mach-smdk2440.c
--- 2.2/arch/arm/mach-s3c2410/mach-smdk2440.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/mach-smdk2440.c	2006-12-22 01:57:07.000000000 +0100
@@ -19,6 +19,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
diff -ru 2.2/arch/arm/mach-s3c2410/mach-vr1000.c 3.4/arch/arm/mach-s3c2410/mach-vr1000.c
--- 2.2/arch/arm/mach-s3c2410/mach-vr1000.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-s3c2410/mach-vr1000.c	2006-12-22 01:57:07.000000000 +0100
@@ -352,7 +352,7 @@
 
 static struct platform_device vr1000_led3 = {
 	.name		= "s3c24xx_led",
-	.id		= 1,
+	.id		= 3,
 	.dev		= {
 		.platform_data	= &vr1000_led3_pdata,
 	},
diff -ru 2.2/arch/arm/mach-s3c2410/mach-vstms.c 3.4/arch/arm/mach-s3c2410/mach-vstms.c
--- 2.2/arch/arm/mach-s3c2410/mach-vstms.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/mach-vstms.c	2006-12-22 01:57:07.000000000 +0100
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <linux/mtd/mtd.h>
diff -ru 2.2/arch/arm/mach-s3c2410/pm.c 3.4/arch/arm/mach-s3c2410/pm.c
--- 2.2/arch/arm/mach-s3c2410/pm.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/pm.c	2006-12-22 01:57:07.000000000 +0100
@@ -34,6 +34,7 @@
 #include <linux/crc32.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
+#include <linux/serial_core.h>
 
 #include <asm/cacheflush.h>
 #include <asm/hardware.h>
diff -ru 2.2/arch/arm/mach-s3c2410/pm-simtec.c 3.4/arch/arm/mach-s3c2410/pm-simtec.c
--- 2.2/arch/arm/mach-s3c2410/pm-simtec.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/pm-simtec.c	2006-12-22 01:57:07.000000000 +0100
@@ -27,7 +27,6 @@
 #include <asm/io.h>
 
 #include <asm/arch/map.h>
-#include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-mem.h>
 
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2410.c 3.4/arch/arm/mach-s3c2410/s3c2410.c
--- 2.2/arch/arm/mach-s3c2410/s3c2410.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2410.c	2006-12-22 01:57:07.000000000 +0100
@@ -17,6 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
@@ -38,11 +39,9 @@
 /* Initial IO mappings */
 
 static struct map_desc s3c2410_iodesc[] __initdata = {
-	IODESC_ENT(USBHOST),
 	IODESC_ENT(CLKPWR),
 	IODESC_ENT(LCD),
 	IODESC_ENT(TIMER),
-	IODESC_ENT(ADC),
 	IODESC_ENT(WATCHDOG),
 };
 
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2410-clock.c 3.4/arch/arm/mach-s3c2410/s3c2410-clock.c
--- 2.2/arch/arm/mach-s3c2410/s3c2410-clock.c	2006-10-04 18:55:36.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2410-clock.c	2006-12-22 01:57:07.000000000 +0100
@@ -30,13 +30,18 @@
 #include <linux/clk.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
 
+#include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-gpio.h>
 
+#include "s3c2410.h"
 #include "clock.h"
 #include "cpu.h"
 
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2410-dma.c 3.4/arch/arm/mach-s3c2410/s3c2410-dma.c
--- 2.2/arch/arm/mach-s3c2410/s3c2410-dma.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2410-dma.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/s3c2410-dma.c
  *
- * (c) 2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 DMA selection
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/serial_core.h>
 
 #include <asm/dma.h>
 #include <asm/arch/dma.h>
@@ -131,6 +132,7 @@
 	return s3c24xx_dma_init_map(&s3c2410_dma_sel);
 }
 
+#if defined(CONFIG_CPU_S3C2410)
 static struct sysdev_driver s3c2410_dma_driver = {
 	.add	= s3c2410_dma_add,
 };
@@ -141,9 +143,10 @@
 }
 
 arch_initcall(s3c2410_dma_init);
+#endif
 
+#if defined(CONFIG_CPU_S3C2442)
 /* S3C2442 DMA contains the same selection table as the S3C2410 */
-
 static struct sysdev_driver s3c2442_dma_driver = {
 	.add	= s3c2410_dma_add,
 };
@@ -154,5 +157,5 @@
 }
 
 arch_initcall(s3c2442_dma_init);
-
+#endif
 
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2410-pm.c 3.4/arch/arm/mach-s3c2410/s3c2410-pm.c
--- 2.2/arch/arm/mach-s3c2410/s3c2410-pm.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/arm/mach-s3c2410/s3c2410-pm.c	2006-12-22 01:57:07.000000000 +0100
@@ -87,7 +87,7 @@
 
 }
 
-int s3c2410_pm_resume(struct sys_device *dev)
+static int s3c2410_pm_resume(struct sys_device *dev)
 {
 	unsigned long tmp;
 
@@ -111,6 +111,7 @@
 	return 0;
 }
 
+#if defined(CONFIG_CPU_S3C2410)
 static struct sysdev_driver s3c2410_pm_driver = {
 	.add		= s3c2410_pm_add,
 	.resume		= s3c2410_pm_resume,
@@ -124,7 +125,9 @@
 }
 
 arch_initcall(s3c2410_pm_drvinit);
+#endif
 
+#if defined(CONFIG_CPU_S3C2440)
 static struct sysdev_driver s3c2440_pm_driver = {
 	.add		= s3c2410_pm_add,
 	.resume		= s3c2410_pm_resume,
@@ -136,7 +139,9 @@
 }
 
 arch_initcall(s3c2440_pm_drvinit);
+#endif
 
+#if defined(CONFIG_CPU_S3C2442)
 static struct sysdev_driver s3c2442_pm_driver = {
 	.add		= s3c2410_pm_add,
 	.resume		= s3c2410_pm_resume,
@@ -148,3 +153,4 @@
 }
 
 arch_initcall(s3c2442_pm_drvinit);
+#endif
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2412.c 3.4/arch/arm/mach-s3c2410/s3c2412.c
--- 2.2/arch/arm/mach-s3c2410/s3c2412.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2412.c	2006-12-22 01:57:07.000000000 +0100
@@ -17,6 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
@@ -60,7 +61,6 @@
 	IODESC_ENT(CLKPWR),
 	IODESC_ENT(LCD),
 	IODESC_ENT(TIMER),
-	IODESC_ENT(ADC),
 	IODESC_ENT(WATCHDOG),
 };
 
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2412-clock.c 3.4/arch/arm/mach-s3c2410/s3c2412-clock.c
--- 2.2/arch/arm/mach-s3c2410/s3c2412-clock.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2412-clock.c	2006-12-22 01:57:07.000000000 +0100
@@ -30,13 +30,18 @@
 #include <linux/clk.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
 
+#include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-gpio.h>
 
+#include "s3c2412.h"
 #include "clock.h"
 #include "cpu.h"
 
@@ -49,7 +54,7 @@
  * set the correct muxing at initialisation
 */
 
-int s3c2412_clkcon_enable(struct clk *clk, int enable)
+static int s3c2412_clkcon_enable(struct clk *clk, int enable)
 {
 	unsigned int clocks = clk->ctrlbit;
 	unsigned long clkcon;
@@ -556,7 +561,7 @@
 	struct clk	*src_1;
 };
 
-struct clk_init clks_src[] __initdata = {
+static struct clk_init clks_src[] __initdata = {
 	{
 		.clk	= &clk_usysclk,
 		.bit	= S3C2412_CLKSRC_USBCLK_HCLK,
@@ -619,7 +624,7 @@
 
 /* clocks to add straight away */
 
-struct clk *clks[] __initdata = {
+static struct clk *clks[] __initdata = {
 	&clk_ext,
 	&clk_usb_bus,
 	&clk_erefclk,
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2412-dma.c 3.4/arch/arm/mach-s3c2410/s3c2412-dma.c
--- 2.2/arch/arm/mach-s3c2410/s3c2412-dma.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2412-dma.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/s3c2412-dma.c
  *
- * (c) 2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2412 DMA selection
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/serial_core.h>
 
 #include <asm/dma.h>
 #include <asm/arch/dma.h>
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2440.c 3.4/arch/arm/mach-s3c2410/s3c2440.c
--- 2.2/arch/arm/mach-s3c2410/s3c2440.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2440.c	2006-12-22 01:57:07.000000000 +0100
@@ -17,6 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/serial_core.h>
 #include <linux/sysdev.h>
 #include <linux/clk.h>
 
@@ -28,17 +29,9 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-gpioj.h>
-#include <asm/arch/regs-dsc.h>
-
 #include "s3c2440.h"
-#include "clock.h"
 #include "devs.h"
 #include "cpu.h"
-#include "pm.h"
 
 static struct sys_device s3c2440_sysdev = {
 	.cls		= &s3c2440_sysclass,
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2440-clock.c 3.4/arch/arm/mach-s3c2410/s3c2440-clock.c
--- 2.2/arch/arm/mach-s3c2410/s3c2440-clock.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2440-clock.c	2006-12-22 01:57:07.000000000 +0100
@@ -113,18 +113,18 @@
 {
 	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
 	unsigned long clkdivn;
-	struct clk *clk_h;
-	struct clk *clk_p;
-	struct clk *clk_upll;
+	struct clk *clock_h;
+	struct clk *clock_p;
+	struct clk *clock_upll;
 
 	printk("S3C2440: Clock Support, DVS %s\n",
 	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
 
-	clk_p = clk_get(NULL, "pclk");
-	clk_h = clk_get(NULL, "hclk");
-	clk_upll = clk_get(NULL, "upll");
+	clock_p = clk_get(NULL, "pclk");
+	clock_h = clk_get(NULL, "hclk");
+	clock_upll = clk_get(NULL, "upll");
 
-	if (IS_ERR(clk_p) || IS_ERR(clk_h) || IS_ERR(clk_upll)) {
+	if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
 		printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
 		return -EINVAL;
 	}
@@ -132,8 +132,8 @@
 	/* check rate of UPLL, and if it is near 96MHz, then change
 	 * to using half the UPLL rate for the system */
 
-	if (clk_get_rate(clk_upll) > (94 * MHZ)) {
-		clk_usb_bus.rate = clk_get_rate(clk_upll) / 2;
+	if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+		clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
 
 		mutex_lock(&clocks_mutex);
 
@@ -144,9 +144,9 @@
 		mutex_unlock(&clocks_mutex);
 	}
 
-	s3c2440_clk_cam.parent = clk_h;
-	s3c2440_clk_ac97.parent = clk_p;
-	s3c2440_clk_cam_upll.parent = clk_upll;
+	s3c2440_clk_cam.parent = clock_h;
+	s3c2440_clk_ac97.parent = clock_p;
+	s3c2440_clk_cam_upll.parent = clock_upll;
 
 	s3c24xx_register_clock(&s3c2440_clk_ac97);
 	s3c24xx_register_clock(&s3c2440_clk_cam);
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2440-dma.c 3.4/arch/arm/mach-s3c2410/s3c2440-dma.c
--- 2.2/arch/arm/mach-s3c2410/s3c2440-dma.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2440-dma.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/s3c2440-dma.c
  *
- * (c) 2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2440 DMA selection
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/serial_core.h>
 
 #include <asm/dma.h>
 #include <asm/arch/dma.h>
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2440.h 3.4/arch/arm/mach-s3c2410/s3c2440.h
--- 2.2/arch/arm/mach-s3c2410/s3c2440.h	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2440.h	2006-12-22 01:57:07.000000000 +0100
@@ -8,28 +8,10 @@
  * 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.
- *
- * Modifications:
- *	24-Aug-2004 BJD  Start of S3C2440 CPU support
- *	04-Nov-2004 BJD  Added s3c2440_init_uarts()
- *	04-Jan-2005 BJD  Moved uart init to cpu code
- *	10-Jan-2005 BJD  Moved 2440 specific init here
- *	14-Jan-2005 BJD  Split the clock initialisation code
 */
 
 #ifdef CONFIG_CPU_S3C2440
-
 extern  int s3c2440_init(void);
-
-extern void s3c2440_map_io(struct map_desc *mach_desc, int size);
-
-extern void s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2440_init_clocks(int xtal);
-
 #else
-#define s3c2440_init_clocks NULL
-#define s3c2440_init_uarts NULL
-#define s3c2440_map_io NULL
 #define s3c2440_init NULL
 #endif
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2442.c 3.4/arch/arm/mach-s3c2410/s3c2442.c
--- 2.2/arch/arm/mach-s3c2410/s3c2442.c	2006-10-04 18:55:36.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2442.c	2006-12-22 01:57:07.000000000 +0100
@@ -16,29 +16,11 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
-#include <linux/platform_device.h>
+#include <linux/serial_core.h>
 #include <linux/sysdev.h>
-#include <linux/clk.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-gpioj.h>
-#include <asm/arch/regs-dsc.h>
 
 #include "s3c2442.h"
-#include "clock.h"
-#include "devs.h"
 #include "cpu.h"
-#include "pm.h"
 
 static struct sys_device s3c2442_sysdev = {
 	.cls		= &s3c2442_sysclass,
diff -ru 2.2/arch/arm/mach-s3c2410/s3c2442-clock.c 3.4/arch/arm/mach-s3c2410/s3c2442-clock.c
--- 2.2/arch/arm/mach-s3c2410/s3c2442-clock.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c2442-clock.c	2006-12-22 01:57:07.000000000 +0100
@@ -117,18 +117,18 @@
 {
 	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
 	unsigned long clkdivn;
-	struct clk *clk_h;
-	struct clk *clk_p;
-	struct clk *clk_upll;
+	struct clk *clock_h;
+	struct clk *clock_p;
+	struct clk *clock_upll;
 
 	printk("S3C2442: Clock Support, DVS %s\n",
 	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
 
-	clk_p = clk_get(NULL, "pclk");
-	clk_h = clk_get(NULL, "hclk");
-	clk_upll = clk_get(NULL, "upll");
+	clock_p = clk_get(NULL, "pclk");
+	clock_h = clk_get(NULL, "hclk");
+	clock_upll = clk_get(NULL, "upll");
 
-	if (IS_ERR(clk_p) || IS_ERR(clk_h) || IS_ERR(clk_upll)) {
+	if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
 		printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
 		return -EINVAL;
 	}
@@ -136,8 +136,8 @@
 	/* check rate of UPLL, and if it is near 96MHz, then change
 	 * to using half the UPLL rate for the system */
 
-	if (clk_get_rate(clk_upll) > (94 * MHZ)) {
-		clk_usb_bus.rate = clk_get_rate(clk_upll) / 2;
+	if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+		clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
 
 		mutex_lock(&clocks_mutex);
 
@@ -148,8 +148,8 @@
 		mutex_unlock(&clocks_mutex);
 	}
 
-	s3c2442_clk_cam.parent = clk_h;
-	s3c2442_clk_cam_upll.parent = clk_upll;
+	s3c2442_clk_cam.parent = clock_h;
+	s3c2442_clk_cam_upll.parent = clock_upll;
 
 	s3c24xx_register_clock(&s3c2442_clk_cam);
 	s3c24xx_register_clock(&s3c2442_clk_cam_upll);
diff -ru 2.2/arch/arm/mach-s3c2410/s3c244x.c 3.4/arch/arm/mach-s3c2410/s3c244x.c
--- 2.2/arch/arm/mach-s3c2410/s3c244x.c	2006-10-02 17:39:10.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/s3c244x.c	2006-12-22 01:57:07.000000000 +0100
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/clk.h>
@@ -47,8 +48,6 @@
 	IODESC_ENT(TIMER),
 	IODESC_ENT(WATCHDOG),
 	IODESC_ENT(LCD),
-	IODESC_ENT(ADC),
-	IODESC_ENT(USBHOST),
 };
 
 /* uart initialisation */
diff -ru 2.2/arch/arm/mach-s3c2410/usb-simtec.h 3.4/arch/arm/mach-s3c2410/usb-simtec.h
--- 2.2/arch/arm/mach-s3c2410/usb-simtec.h	2006-10-04 18:55:36.000000000 +0200
+++ 3.4/arch/arm/mach-s3c2410/usb-simtec.h	2006-12-22 01:57:07.000000000 +0100
@@ -10,9 +10,6 @@
  * 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.
- *
- * Modifications:
- *	20-Aug-2004 BJD  Created
 */
 
 extern int usb_simtec_init(void);
diff -ru 2.2/arch/arm/mm/ioremap.c 3.4/arch/arm/mm/ioremap.c
--- 2.2/arch/arm/mm/ioremap.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/arch/arm/mm/ioremap.c	2006-12-22 01:57:07.000000000 +0100
@@ -292,6 +292,8 @@
 	if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
 		return NULL;
 
+	size = PAGE_ALIGN(size);
+
  	area = get_vm_area(size, VM_IOREMAP);
  	if (!area)
  		return NULL;
diff -ru 2.2/arch/arm/mm/mmu.c 3.4/arch/arm/mm/mmu.c
--- 2.2/arch/arm/mm/mmu.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/arch/arm/mm/mmu.c	2006-12-22 01:57:07.000000000 +0100
@@ -154,6 +154,26 @@
 }
 __setup("noalign", noalign_setup);
 
+#ifndef CONFIG_SMP
+void adjust_cr(unsigned long mask, unsigned long set)
+{
+	unsigned long flags;
+
+	mask &= ~CR_A;
+
+	set &= mask;
+
+	local_irq_save(flags);
+
+	cr_no_alignment = (cr_no_alignment & ~mask) | set;
+	cr_alignment = (cr_alignment & ~mask) | set;
+
+	set_cr((get_cr() & ~mask) | set);
+
+	local_irq_restore(flags);
+}
+#endif
+
 struct mem_types {
 	unsigned int	prot_pte;
 	unsigned int	prot_l1;
diff -ru 2.2/arch/arm/mm/proc-xsc3.S 3.4/arch/arm/mm/proc-xsc3.S
--- 2.2/arch/arm/mm/proc-xsc3.S	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/arch/arm/mm/proc-xsc3.S	2006-12-22 01:57:07.000000000 +0100
@@ -2,7 +2,7 @@
  * linux/arch/arm/mm/proc-xsc3.S
  *
  * Original Author: Matthew Gilbert
- * Current Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ * Current Maintainer: Lennert Buytenhek <buytenh@wantstofly.org>
  *
  * Copyright 2004 (C) Intel Corp.
  * Copyright 2005 (c) MontaVista Software, Inc.
diff -ru 2.2/arch/i386/kernel/acpi/boot.c 3.4/arch/i386/kernel/acpi/boot.c
--- 2.2/arch/i386/kernel/acpi/boot.c	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/arch/i386/kernel/acpi/boot.c	2006-12-23 16:57:57.000000000 +0100
@@ -1327,3 +1327,25 @@
 	return 0;
 }
 early_param("acpi_sci", setup_acpi_sci);
+
+int __acpi_acquire_global_lock(unsigned int *lock)
+{
+	unsigned int old, new, val;
+	do {
+		old = *lock;
+		new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
+		val = cmpxchg(lock, old, new);
+	} while (unlikely (val != old));
+	return (new < 3) ? -1 : 0;
+}
+
+int __acpi_release_global_lock(unsigned int *lock)
+{
+	unsigned int old, new, val;
+	do {
+		old = *lock;
+		new = old & ~0x3;
+		val = cmpxchg(lock, old, new);
+	} while (unlikely (val != old));
+	return old & 0x1;
+}
diff -ru 2.2/arch/i386/kernel/apm.c 3.4/arch/i386/kernel/apm.c
--- 2.2/arch/i386/kernel/apm.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/arch/i386/kernel/apm.c	2006-12-23 01:11:19.000000000 +0100
@@ -785,7 +785,11 @@
 	polling = !!(current_thread_info()->status & TS_POLLING);
 	if (polling) {
 		current_thread_info()->status &= ~TS_POLLING;
-		smp_mb__after_clear_bit();
+		/*
+		 * TS_POLLING-cleared state must be visible before we
+		 * test NEED_RESCHED:
+		 */
+		smp_mb();
 	}
 	if (!need_resched()) {
 		idled = 1;
diff -ru 2.2/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 3.4/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
--- 2.2/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	2006-12-13 18:28:46.000000000 +0100
+++ 3.4/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	2006-12-18 04:27:33.000000000 +0100
@@ -126,27 +126,6 @@
 	}
 }
 
-static void wrport(u16 port, u8 bit_width, u32 value)
-{
-	if (bit_width <= 8)
-		outb(value, port);
-	else if (bit_width <= 16)
-		outw(value, port);
-	else if (bit_width <= 32)
-		outl(value, port);
-}
-
-static void rdport(u16 port, u8 bit_width, u32 * ret)
-{
-	*ret = 0;
-	if (bit_width <= 8)
-		*ret = inb(port);
-	else if (bit_width <= 16)
-		*ret = inw(port);
-	else if (bit_width <= 32)
-		*ret = inl(port);
-}
-
 struct msr_addr {
 	u32 reg;
 };
@@ -177,7 +156,9 @@
 		rdmsr(cmd->addr.msr.reg, cmd->val, h);
 		break;
 	case SYSTEM_IO_CAPABLE:
-		rdport(cmd->addr.io.port, cmd->addr.io.bit_width, &cmd->val);
+		acpi_os_read_port((acpi_io_address)cmd->addr.io.port,
+				&cmd->val,
+				(u32)cmd->addr.io.bit_width);
 		break;
 	default:
 		break;
@@ -193,7 +174,9 @@
 		wrmsr(cmd->addr.msr.reg, cmd->val, h);
 		break;
 	case SYSTEM_IO_CAPABLE:
-		wrport(cmd->addr.io.port, cmd->addr.io.bit_width, cmd->val);
+		acpi_os_write_port((acpi_io_address)cmd->addr.io.port,
+				cmd->val,
+				(u32)cmd->addr.io.bit_width);
 		break;
 	default:
 		break;
@@ -699,14 +682,14 @@
 	if (result)
 		goto err_freqfree;
 
-	switch (data->cpu_feature) {
+	switch (perf->control_register.space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 		/* Current speed is unknown and not detectable by IO port */
 		policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
 		break;
 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
 		acpi_cpufreq_driver.get = get_cur_freq_on_cpu;
-		get_cur_freq_on_cpu(cpu);
+		policy->cur = get_cur_freq_on_cpu(cpu);
 		break;
 	default:
 		break;
diff -ru 2.2/arch/i386/kernel/cpu/cpufreq/longhaul.c 3.4/arch/i386/kernel/cpu/cpufreq/longhaul.c
--- 2.2/arch/i386/kernel/cpu/cpufreq/longhaul.c	2006-12-13 18:28:46.000000000 +0100
+++ 3.4/arch/i386/kernel/cpu/cpufreq/longhaul.c	2006-12-18 04:27:33.000000000 +0100
@@ -787,8 +787,10 @@
 	switch (c->x86_model) {
 	case 6 ... 9:
 		return cpufreq_register_driver(&longhaul_driver);
+	case 10:
+		printk(KERN_ERR PFX "Use acpi-cpufreq driver for VIA C7\n");
 	default:
-		printk (KERN_INFO PFX "Unknown VIA CPU. Contact davej@codemonkey.org.uk\n");
+		;;
 	}
 
 	return -ENODEV;
diff -ru 2.2/arch/i386/kernel/e820.c 3.4/arch/i386/kernel/e820.c
--- 2.2/arch/i386/kernel/e820.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/i386/kernel/e820.c	2006-12-23 01:11:19.000000000 +0100
@@ -668,7 +668,7 @@
 	}
 }
 
-void __init register_memory(void)
+void __init e820_register_memory(void)
 {
 	unsigned long gapstart, gapsize, round;
 	unsigned long long last;
diff -ru 2.2/arch/i386/kernel/microcode.c 3.4/arch/i386/kernel/microcode.c
--- 2.2/arch/i386/kernel/microcode.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/arch/i386/kernel/microcode.c	2006-12-23 01:11:19.000000000 +0100
@@ -722,7 +722,7 @@
 	return NOTIFY_OK;
 }
 
-static struct notifier_block mc_cpu_notifier = {
+static struct notifier_block __cpuinitdata mc_cpu_notifier = {
 	.notifier_call = mc_cpu_callback,
 };
 
diff -ru 2.2/arch/i386/kernel/process.c 3.4/arch/i386/kernel/process.c
--- 2.2/arch/i386/kernel/process.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/i386/kernel/process.c	2006-12-23 01:11:19.000000000 +0100
@@ -102,7 +102,12 @@
 {
 	if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
 		current_thread_info()->status &= ~TS_POLLING;
-		smp_mb__after_clear_bit();
+		/*
+		 * TS_POLLING-cleared state must be visible before we
+		 * test NEED_RESCHED:
+		 */
+		smp_mb();
+
 		local_irq_disable();
 		if (!need_resched())
 			safe_halt();	/* enables interrupts racelessly */
diff -ru 2.2/arch/i386/kernel/ptrace.c 3.4/arch/i386/kernel/ptrace.c
--- 2.2/arch/i386/kernel/ptrace.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/i386/kernel/ptrace.c	2006-12-23 01:11:19.000000000 +0100
@@ -45,7 +45,7 @@
 /*
  * Offset of eflags on child stack..
  */
-#define EFL_OFFSET ((EFL-2)*4-sizeof(struct pt_regs))
+#define EFL_OFFSET offsetof(struct pt_regs, eflags)
 
 static inline struct pt_regs *get_child_regs(struct task_struct *task)
 {
@@ -54,24 +54,24 @@
 }
 
 /*
- * this routine will get a word off of the processes privileged stack. 
- * the offset is how far from the base addr as stored in the TSS.  
- * this routine assumes that all the privileged stacks are in our
+ * This routine will get a word off of the processes privileged stack.
+ * the offset is bytes into the pt_regs structure on the stack.
+ * This routine assumes that all the privileged stacks are in our
  * data space.
  */   
 static inline int get_stack_long(struct task_struct *task, int offset)
 {
 	unsigned char *stack;
 
-	stack = (unsigned char *)task->thread.esp0;
+	stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs);
 	stack += offset;
 	return (*((int *)stack));
 }
 
 /*
- * this routine will put a word on the processes privileged stack. 
- * the offset is how far from the base addr as stored in the TSS.  
- * this routine assumes that all the privileged stacks are in our
+ * This routine will put a word on the processes privileged stack.
+ * the offset is bytes into the pt_regs structure on the stack.
+ * This routine assumes that all the privileged stacks are in our
  * data space.
  */
 static inline int put_stack_long(struct task_struct *task, int offset,
@@ -79,7 +79,7 @@
 {
 	unsigned char * stack;
 
-	stack = (unsigned char *) task->thread.esp0;
+	stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs);
 	stack += offset;
 	*(unsigned long *) stack = data;
 	return 0;
@@ -114,7 +114,7 @@
 	}
 	if (regno > ES*4)
 		regno -= 1*4;
-	put_stack_long(child, regno - sizeof(struct pt_regs), value);
+	put_stack_long(child, regno, value);
 	return 0;
 }
 
@@ -137,7 +137,6 @@
 		default:
 			if (regno > ES*4)
 				regno -= 1*4;
-			regno = regno - sizeof(struct pt_regs);
 			retval &= get_stack_long(child, regno);
 	}
 	return retval;
diff -ru 2.2/arch/i386/kernel/setup.c 3.4/arch/i386/kernel/setup.c
--- 2.2/arch/i386/kernel/setup.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/i386/kernel/setup.c	2006-12-23 01:11:19.000000000 +0100
@@ -639,7 +639,7 @@
 		get_smp_config();
 #endif
 
-	register_memory();
+	e820_register_memory();
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
diff -ru 2.2/arch/i386/mm/discontig.c 3.4/arch/i386/mm/discontig.c
--- 2.2/arch/i386/mm/discontig.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/i386/mm/discontig.c	2006-12-23 01:11:19.000000000 +0100
@@ -405,3 +405,31 @@
 	totalram_pages += totalhigh_pages;
 #endif
 }
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+int paddr_to_nid(u64 addr)
+{
+	int nid;
+	unsigned long pfn = PFN_DOWN(addr);
+
+	for_each_node(nid)
+		if (node_start_pfn[nid] <= pfn &&
+		    pfn < node_end_pfn[nid])
+			return nid;
+
+	return -1;
+}
+
+/*
+ * This function is used to ask node id BEFORE memmap and mem_section's
+ * initialization (pfn_to_nid() can't be used yet).
+ * If _PXM is not defined on ACPI's DSDT, node id must be found by this.
+ */
+int memory_add_physaddr_to_nid(u64 addr)
+{
+	int nid = paddr_to_nid(addr);
+	return (nid >= 0) ? nid : 0;
+}
+
+EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
+#endif
diff -ru 2.2/arch/i386/mm/init.c 3.4/arch/i386/mm/init.c
--- 2.2/arch/i386/mm/init.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/i386/mm/init.c	2006-12-23 01:11:19.000000000 +0100
@@ -673,16 +673,10 @@
 #endif
 }
 
-/*
- * this is for the non-NUMA, single node SMP system case.
- * Specifically, in the case of x86, we will always add
- * memory to the highmem for now.
- */
 #ifdef CONFIG_MEMORY_HOTPLUG
-#ifndef CONFIG_NEED_MULTIPLE_NODES
 int arch_add_memory(int nid, u64 start, u64 size)
 {
-	struct pglist_data *pgdata = &contig_page_data;
+	struct pglist_data *pgdata = NODE_DATA(nid);
 	struct zone *zone = pgdata->node_zones + ZONE_HIGHMEM;
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
@@ -694,7 +688,7 @@
 {
 	return -EINVAL;
 }
-#endif
+EXPORT_SYMBOL_GPL(remove_memory);
 #endif
 
 struct kmem_cache *pgd_cache;
diff -ru 2.2/arch/i386/pci/fixup.c 3.4/arch/i386/pci/fixup.c
--- 2.2/arch/i386/pci/fixup.c	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/arch/i386/pci/fixup.c	2006-12-22 01:57:07.000000000 +0100
@@ -115,7 +115,7 @@
 #define VIA_8363_KL133_REVISION_ID 0x81
 #define VIA_8363_KM133_REVISION_ID 0x84
 
-static void __devinit pci_fixup_via_northbridge_bug(struct pci_dev *d)
+static void pci_fixup_via_northbridge_bug(struct pci_dev *d)
 {
 	u8 v;
 	u8 revision;
@@ -151,6 +151,10 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug);
 
 /*
  * For some reasons Intel decided that certain parts of their
@@ -181,7 +185,7 @@
  * issue another HALT within 80 ns of the initial HALT, the failure condition
  * is avoided.
  */
-static void __init pci_fixup_nforce2(struct pci_dev *dev)
+static void pci_fixup_nforce2(struct pci_dev *dev)
 {
 	u32 val;
 
@@ -204,6 +208,7 @@
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
 
 /* Max PCI Express root ports */
 #define MAX_PCIEROOT	6
@@ -419,7 +424,7 @@
  * Prevent the BIOS trapping accesses to the Cyrix CS5530A video device
  * configuration space.
  */
-static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev)
+static void pci_early_fixup_cyrix_5530(struct pci_dev *dev)
 {
 	u8 r;
 	/* clear 'F4 Video Configuration Trap' bit */
@@ -429,3 +434,5 @@
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
 			pci_early_fixup_cyrix_5530);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
+			pci_early_fixup_cyrix_5530);
diff -ru 2.2/arch/i386/pci/mmconfig.c 3.4/arch/i386/pci/mmconfig.c
--- 2.2/arch/i386/pci/mmconfig.c	2006-11-09 19:26:57.000000000 +0100
+++ 3.4/arch/i386/pci/mmconfig.c	2006-12-24 16:38:17.000000000 +0100
@@ -26,6 +26,7 @@
 
 /* The base address of the last MMCONFIG device accessed */
 static u32 mmcfg_last_accessed_device;
+static int mmcfg_last_accessed_cpu;
 
 static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32);
 
@@ -73,8 +74,11 @@
 static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 {
 	u32 dev_base = base | (bus << 20) | (devfn << 12);
-	if (dev_base != mmcfg_last_accessed_device) {
+	int cpu = smp_processor_id();
+	if (dev_base != mmcfg_last_accessed_device ||
+	    cpu != mmcfg_last_accessed_cpu) {
 		mmcfg_last_accessed_device = dev_base;
+		mmcfg_last_accessed_cpu = cpu;
 		set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
 	}
 }
diff -ru 2.2/arch/ia64/kernel/cpufreq/acpi-cpufreq.c 3.4/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
--- 2.2/arch/ia64/kernel/cpufreq/acpi-cpufreq.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/ia64/kernel/cpufreq/acpi-cpufreq.c	2006-12-23 16:57:57.000000000 +0100
@@ -276,12 +276,10 @@
 
 	dprintk("acpi_cpufreq_cpu_init\n");
 
-	data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
+	data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
 	if (!data)
 		return (-ENOMEM);
 
-	memset(data, 0, sizeof(struct cpufreq_acpi_io));
-
 	acpi_io_data[cpu] = data;
 
 	result = acpi_processor_register_performance(&data->acpi_data, cpu);
diff -ru 2.2/arch/ia64/kernel/process.c 3.4/arch/ia64/kernel/process.c
--- 2.2/arch/ia64/kernel/process.c	2006-10-02 19:14:46.000000000 +0200
+++ 3.4/arch/ia64/kernel/process.c	2006-12-23 01:11:19.000000000 +0100
@@ -268,10 +268,16 @@
 
 	/* endless idle loop with no priority at all */
 	while (1) {
-		if (can_do_pal_halt)
+		if (can_do_pal_halt) {
 			current_thread_info()->status &= ~TS_POLLING;
-		else
+			/*
+			 * TS_POLLING-cleared state must be visible before we
+			 * test NEED_RESCHED:
+			 */
+			smp_mb();
+		} else {
 			current_thread_info()->status |= TS_POLLING;
+		}
 
 		if (!need_resched()) {
 			void (*idle)(void);
diff -ru 2.2/arch/powerpc/boot/Makefile 3.4/arch/powerpc/boot/Makefile
--- 2.2/arch/powerpc/boot/Makefile	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/arch/powerpc/boot/Makefile	2006-12-22 01:57:07.000000000 +0100
@@ -152,6 +152,9 @@
 $(obj)/zImage.ps3: vmlinux
 	$(STRIP) -s -R .comment $< -o $@
 
+$(obj)/zImage.initrd.ps3: vmlinux
+	@echo "  WARNING zImage.initrd.ps3 not supported (yet)"
+
 $(obj)/uImage: vmlinux $(wrapperbits)
 	$(call cmd,wrap,uboot)
 
diff -ru 2.2/arch/powerpc/configs/cell_defconfig 3.4/arch/powerpc/configs/cell_defconfig
--- 2.2/arch/powerpc/configs/cell_defconfig	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/arch/powerpc/configs/cell_defconfig	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc6
-# Wed Nov 22 15:33:04 2006
+# Linux kernel version: 2.6.20-rc1
+# Tue Dec 19 14:59:53 2006
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -10,6 +10,8 @@
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_ARCH_HAS_ILOG2_U64=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -23,6 +25,7 @@
 CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
 # CONFIG_DEFAULT_UIMAGE is not set
 
 #
@@ -66,6 +69,7 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CPUSETS=y
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -128,14 +132,16 @@
 # CONFIG_APUS is not set
 # CONFIG_PPC_PSERIES is not set
 # CONFIG_PPC_ISERIES is not set
+# CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
 # CONFIG_PPC_PASEMI is not set
 CONFIG_PPC_CELL=y
 CONFIG_PPC_CELL_NATIVE=y
 CONFIG_PPC_IBM_CELL_BLADE=y
-CONFIG_UDBG_RTAS_CONSOLE=y
 CONFIG_PPC_PS3=y
+CONFIG_PPC_NATIVE=y
+CONFIG_UDBG_RTAS_CONSOLE=y
 # CONFIG_U3_DART is not set
 CONFIG_PPC_RTAS=y
 # CONFIG_RTAS_ERROR_LOGGING is not set
@@ -177,12 +183,14 @@
 CONFIG_PS3_HTAB_SIZE=20
 # CONFIG_PS3_DYNAMIC_DMA is not set
 CONFIG_PS3_USE_LPAR_ADDR=y
+CONFIG_PS3_VUART=y
 
 #
 # Kernel options
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_PREEMPT_NONE=y
@@ -237,6 +245,7 @@
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCIEPORTBUS=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -270,7 +279,10 @@
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
+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
@@ -289,6 +301,7 @@
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 
 #
 # IP: Virtual Server Configuration
@@ -317,31 +330,67 @@
 #
 # Core Netfilter Configuration
 #
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NETFILTER_XTABLES is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=y
-# CONFIG_IP_NF_CT_ACCT is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-CONFIG_IP_NF_CT_PROTO_SCTP=y
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
-# CONFIG_IP_NF_H323 is not set
-# CONFIG_IP_NF_SIP is not set
 CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
 
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
 
 #
 # DCCP Configuration (EXPERIMENTAL)
@@ -373,6 +422,7 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -428,6 +478,7 @@
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=131072
@@ -457,6 +508,7 @@
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 
 #
@@ -468,7 +520,6 @@
 # CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_BLK_DEV_GENERIC=y
 # CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
@@ -492,6 +543,7 @@
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SL82C105 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
@@ -505,8 +557,74 @@
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
+CONFIG_SCSI=m
+# 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=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# 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
+
+#
+# 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_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
 
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -538,6 +656,9 @@
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -552,6 +673,7 @@
 #
 # Macintosh device drivers
 #
+# CONFIG_MAC_EMUMOUSEBTN is not set
 # CONFIG_WINDFARM is not set
 
 #
@@ -559,7 +681,7 @@
 #
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
-CONFIG_BONDING=y
+CONFIG_BONDING=m
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=y
 
@@ -604,11 +726,11 @@
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 CONFIG_SKGE=m
-# CONFIG_SKY2 is not set
+CONFIG_SKY2=m
 # CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
+CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
-CONFIG_SPIDER_NET=m
+CONFIG_SPIDER_NET=y
 # CONFIG_QLA3XXX is not set
 
 #
@@ -618,6 +740,7 @@
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -637,6 +760,7 @@
 # CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -703,6 +827,7 @@
 # CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+# CONFIG_MOXA_SMARTIO_NEW is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
 # CONFIG_SYNCLINKMP is not set
@@ -729,6 +854,7 @@
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_HVC_DRIVER=y
@@ -756,16 +882,17 @@
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -855,12 +982,14 @@
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
 #
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
 
 #
 # Console display driver support
@@ -875,18 +1004,145 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=m
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -912,7 +1168,7 @@
 #
 # InfiniBand support
 #
-CONFIG_INFINIBAND=y
+CONFIG_INFINIBAND=m
 CONFIG_INFINIBAND_USER_MAD=m
 CONFIG_INFINIBAND_USER_ACCESS=m
 CONFIG_INFINIBAND_ADDR_TRANS=y
@@ -922,6 +1178,8 @@
 CONFIG_INFINIBAND_IPOIB=m
 CONFIG_INFINIBAND_IPOIB_DEBUG=y
 CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+# CONFIG_INFINIBAND_SRP is not set
+# CONFIG_INFINIBAND_ISER is not set
 
 #
 # EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
@@ -946,6 +1204,10 @@
 #
 
 #
+# Virtualization
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1028,23 +1290,18 @@
 #
 # Network File Systems
 #
-CONFIG_NFS_FS=m
+CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V2_ACL=y
-CONFIG_NFSD_V3=y
-CONFIG_NFSD_V3_ACL=y
-# CONFIG_NFSD_V4 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=m
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_ACL_SUPPORT=y
 CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
+CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1120,8 +1377,14 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1130,7 +1393,10 @@
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_TEXTSEARCH=y
 CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
 
 #
 # Instrumentation Support
@@ -1146,6 +1412,8 @@
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=15
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1159,12 +1427,11 @@
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_FORCED_INLINING is not set
-# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1191,6 +1458,7 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
@@ -1199,8 +1467,10 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_DES=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
diff -ru 2.2/arch/powerpc/kernel/of_platform.c 3.4/arch/powerpc/kernel/of_platform.c
--- 2.2/arch/powerpc/kernel/of_platform.c	2006-12-12 05:42:34.000000000 +0100
+++ 3.4/arch/powerpc/kernel/of_platform.c	2006-12-22 01:57:07.000000000 +0100
@@ -50,6 +50,7 @@
 	{ .type = "plb5", },
 	{ .type = "plb4", },
 	{ .type = "opb", },
+	{ .type = "ebc", },
 	{},
 };
 
diff -ru 2.2/arch/powerpc/kernel/pci_64.c 3.4/arch/powerpc/kernel/pci_64.c
--- 2.2/arch/powerpc/kernel/pci_64.c	2006-12-12 05:42:34.000000000 +0100
+++ 3.4/arch/powerpc/kernel/pci_64.c	2006-12-22 01:57:07.000000000 +0100
@@ -360,6 +360,7 @@
 	DBG("    class: 0x%x\n", dev->class);
 
 	dev->current_state = 4;		/* unknown power state */
+	dev->error_state = pci_channel_io_normal;
 
 	if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
 		/* a PCI-PCI bridge */
diff -ru 2.2/arch/powerpc/kernel/prom_parse.c 3.4/arch/powerpc/kernel/prom_parse.c
--- 2.2/arch/powerpc/kernel/prom_parse.c	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/arch/powerpc/kernel/prom_parse.c	2006-12-22 01:57:07.000000000 +0100
@@ -920,9 +920,20 @@
 
 	/*
 	 * Old machines just have a list of interrupt numbers
-	 * and no interrupt-controller nodes.
+	 * and no interrupt-controller nodes. We also have dodgy
+	 * cases where the APPL,interrupts property is completely
+	 * missing behind pci-pci bridges and we have to get it
+	 * from the parent (the bridge itself, as apple just wired
+	 * everything together on these)
 	 */
-	ints = get_property(device, "AAPL,interrupts", &intlen);
+	while (device) {
+		ints = get_property(device, "AAPL,interrupts", &intlen);
+		if (ints != NULL)
+			break;
+		device = device->parent;
+		if (device && strcmp(device->type, "pci") != 0)
+			break;
+	}
 	if (ints == NULL)
 		return -EINVAL;
 	intlen /= sizeof(u32);
diff -ru 2.2/arch/powerpc/kernel/signal_32.c 3.4/arch/powerpc/kernel/signal_32.c
--- 2.2/arch/powerpc/kernel/signal_32.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/powerpc/kernel/signal_32.c	2006-12-22 01:57:07.000000000 +0100
@@ -835,11 +835,21 @@
 		return -EINVAL;
 
 	if (old_ctx != NULL) {
+		struct mcontext __user *mctx;
+
+		/*
+		 * old_ctx might not be 16-byte aligned, in which
+		 * case old_ctx->uc_mcontext won't be either.
+		 * Because we have the old_ctx->uc_pad2 field
+		 * before old_ctx->uc_mcontext, we need to round down
+		 * from &old_ctx->uc_mcontext to a 16-byte boundary.
+		 */
+		mctx = (struct mcontext __user *)
+			((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
 		if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
-		    || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
+		    || save_user_regs(regs, mctx, 0)
 		    || put_sigset_t(&old_ctx->uc_sigmask, &current->blocked)
-		    || __put_user(to_user_ptr(&old_ctx->uc_mcontext),
-			    &old_ctx->uc_regs))
+		    || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
 			return -EFAULT;
 	}
 	if (new_ctx == NULL)
diff -ru 2.2/arch/powerpc/platforms/cell/io-workarounds.c 3.4/arch/powerpc/platforms/cell/io-workarounds.c
--- 2.2/arch/powerpc/platforms/cell/io-workarounds.c	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/arch/powerpc/platforms/cell/io-workarounds.c	2006-12-22 01:57:07.000000000 +0100
@@ -37,7 +37,7 @@
  */
 #define SPIDER_DISABLE_PREFETCH
 
-#define MAX_SPIDERS	2
+#define MAX_SPIDERS	3
 
 static struct spider_pci_bus {
 	void __iomem	*regs;
diff -ru 2.2/arch/powerpc/platforms/cell/spu_priv1_mmio.c 3.4/arch/powerpc/platforms/cell/spu_priv1_mmio.c
--- 2.2/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/arch/powerpc/platforms/cell/spu_priv1_mmio.c	2006-12-22 01:57:07.000000000 +0100
@@ -37,8 +37,9 @@
 #include "interrupt.h"
 #include "spu_priv1_mmio.h"
 
+static DEFINE_MUTEX(add_spumem_mutex);
+
 struct spu_pdata {
-	int nid;
 	struct device_node *devnode;
 	struct spu_priv1 __iomem *priv1;
 };
@@ -56,20 +57,9 @@
 
 EXPORT_SYMBOL_GPL(spu_devnode);
 
-static int __init find_spu_node_id(struct device_node *spe)
-{
-	const unsigned int *id;
-	struct device_node *cpu;
-	cpu = spe->parent->parent;
-	id = get_property(cpu, "node-id", NULL);
-	return id ? *id : 0;
-}
-
 static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
 		const char *prop)
 {
-	static DEFINE_MUTEX(add_spumem_mutex);
-
 	const struct address_prop {
 		unsigned long address;
 		unsigned int len;
@@ -87,7 +77,7 @@
 	start_pfn = p->address >> PAGE_SHIFT;
 	nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
 
-	pgdata = NODE_DATA(spu_get_pdata(spu)->nid);
+	pgdata = NODE_DATA(spu->node);
 	zone = pgdata->node_zones;
 
 	/* XXX rethink locking here */
@@ -140,6 +130,7 @@
 {
 	unsigned int isrc;
 	const u32 *tmp;
+	int nid;
 
 	/* Get the interrupt source unit from the device-tree */
 	tmp = get_property(np, "isrc", NULL);
@@ -147,8 +138,15 @@
 		return -ENODEV;
 	isrc = tmp[0];
 
+	tmp = get_property(np->parent->parent, "node-id", NULL);
+	if (!tmp) {
+		printk(KERN_WARNING "%s: can't find node-id\n", __FUNCTION__);
+		nid = spu->node;
+	} else
+		nid = tmp[0];
+
 	/* Add the node number */
-	isrc |= spu->node << IIC_IRQ_NODE_SHIFT;
+	isrc |= nid << IIC_IRQ_NODE_SHIFT;
 
 	/* Now map interrupts of all 3 classes */
 	spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc);
@@ -237,70 +235,88 @@
 	return ret;
 }
 
-static int spu_map_resource(struct device_node *node, int nr,
-		void __iomem** virt, unsigned long *phys)
+static int spu_map_resource(struct spu *spu, int nr,
+			    void __iomem** virt, unsigned long *phys)
 {
+	struct device_node *np = spu_get_pdata(spu)->devnode;
+	unsigned long start_pfn, nr_pages;
+	struct pglist_data *pgdata;
+	struct zone *zone;
 	struct resource resource = { };
+	unsigned long len;
 	int ret;
 
-	ret = of_address_to_resource(node, nr, &resource);
+	ret = of_address_to_resource(np, nr, &resource);
 	if (ret)
 		goto out;
 
 	if (phys)
 		*phys = resource.start;
-	*virt = ioremap(resource.start, resource.end - resource.start);
+	len = resource.end - resource.start + 1;
+	*virt = ioremap(resource.start, len);
 	if (!*virt)
 		ret = -EINVAL;
 
+	start_pfn = resource.start >> PAGE_SHIFT;
+	nr_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+	pgdata = NODE_DATA(spu->node);
+	zone = pgdata->node_zones;
+
+	/* XXX rethink locking here */
+	mutex_lock(&add_spumem_mutex);
+	ret = __add_pages(zone, start_pfn, nr_pages);
+	mutex_unlock(&add_spumem_mutex);
+
 out:
 	return ret;
 }
 
-static int __init spu_map_device(struct spu *spu, struct device_node *node)
+static int __init spu_map_device(struct spu *spu)
 {
+	struct device_node *np = spu_get_pdata(spu)->devnode;
 	int ret = -ENODEV;
-	spu->name = get_property(node, "name", NULL);
+
+	spu->name = get_property(np, "name", NULL);
 	if (!spu->name)
 		goto out;
 
-	ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store,
-					&spu->local_store_phys);
+	ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store,
+			       &spu->local_store_phys);
 	if (ret) {
 		pr_debug("spu_new: failed to map %s resource 0\n",
-			 node->full_name);
+			 np->full_name);
 		goto out;
 	}
-	ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem,
-					&spu->problem_phys);
+	ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem,
+			       &spu->problem_phys);
 	if (ret) {
 		pr_debug("spu_new: failed to map %s resource 1\n",
-			 node->full_name);
+			 np->full_name);
 		goto out_unmap;
 	}
-	ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2,
-					NULL);
+	ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL);
 	if (ret) {
 		pr_debug("spu_new: failed to map %s resource 2\n",
-			 node->full_name);
+			 np->full_name);
 		goto out_unmap;
 	}
 	if (!firmware_has_feature(FW_FEATURE_LPAR))
-		ret = spu_map_resource(node, 3,
-			(void __iomem**)&spu_get_pdata(spu)->priv1, NULL);
+		ret = spu_map_resource(spu, 3,
+			       (void __iomem**)&spu_get_pdata(spu)->priv1, NULL);
 	if (ret) {
 		pr_debug("spu_new: failed to map %s resource 3\n",
-			 node->full_name);
+			 np->full_name);
 		goto out_unmap;
 	}
-	pr_debug("spu_new: %s maps:\n", node->full_name);
+	pr_debug("spu_new: %s maps:\n", np->full_name);
 	pr_debug("  local store   : 0x%016lx -> 0x%p\n",
 		 spu->local_store_phys, spu->local_store);
 	pr_debug("  problem state : 0x%016lx -> 0x%p\n",
 		 spu->problem_phys, spu->problem);
 	pr_debug("  priv2         :                       0x%p\n", spu->priv2);
 	pr_debug("  priv1         :                       0x%p\n",
-						spu_get_pdata(spu)->priv1);
+		 spu_get_pdata(spu)->priv1);
 
 	return 0;
 
@@ -340,8 +356,9 @@
 		ret = -ENOMEM;
 		goto out;
 	}
+	spu_get_pdata(spu)->devnode = of_node_get(spe);
 
-	spu->node = find_spu_node_id(spe);
+	spu->node = of_node_to_nid(spe);
 	if (spu->node >= MAX_NUMNODES) {
 		printk(KERN_WARNING "SPE %s on node %d ignored,"
 		       " node number too big\n", spe->full_name, spu->node);
@@ -350,11 +367,7 @@
 		goto out_free;
 	}
 
-	spu_get_pdata(spu)->nid = of_node_to_nid(spe);
-	if (spu_get_pdata(spu)->nid == -1)
-		spu_get_pdata(spu)->nid = 0;
-
-	ret = spu_map_device(spu, spe);
+	ret = spu_map_device(spu);
 	/* try old method */
 	if (ret)
 		ret = spu_map_device_old(spu, spe);
@@ -367,8 +380,6 @@
 	if (ret)
 		goto out_unmap;
 
-	spu_get_pdata(spu)->devnode = of_node_get(spe);
-
 	pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", spu->name,
 		spu->local_store, spu->problem, spu_get_pdata(spu)->priv1,
 		spu->priv2, spu->number);
diff -ru 2.2/arch/powerpc/platforms/iseries/Kconfig 3.4/arch/powerpc/platforms/iseries/Kconfig
--- 2.2/arch/powerpc/platforms/iseries/Kconfig	2006-10-02 17:39:11.000000000 +0200
+++ 3.4/arch/powerpc/platforms/iseries/Kconfig	2006-12-22 01:57:07.000000000 +0100
@@ -31,5 +31,5 @@
 
 config VIOPATH
 	bool
-	depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
+	depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || ISERIES_VETH
 	default y
diff -ru 2.2/arch/powerpc/platforms/Makefile 3.4/arch/powerpc/platforms/Makefile
--- 2.2/arch/powerpc/platforms/Makefile	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/arch/powerpc/platforms/Makefile	2006-12-22 01:57:07.000000000 +0100
@@ -5,9 +5,9 @@
 obj-$(CONFIG_PPC_PMAC)		+= powermac/
 endif
 endif
+obj-$(CONFIG_PPC_MPC52xx)	+= 52xx/
 obj-$(CONFIG_PPC_CHRP)		+= chrp/
 obj-$(CONFIG_4xx)		+= 4xx/
-obj-$(CONFIG_PPC_MPC52xx)	+= 52xx/
 obj-$(CONFIG_PPC_83xx)		+= 83xx/
 obj-$(CONFIG_PPC_85xx)		+= 85xx/
 obj-$(CONFIG_PPC_86xx)		+= 86xx/
diff -ru 2.2/arch/powerpc/sysdev/mpic.c 3.4/arch/powerpc/sysdev/mpic.c
--- 2.2/arch/powerpc/sysdev/mpic.c	2006-12-07 02:52:09.000000000 +0100
+++ 3.4/arch/powerpc/sysdev/mpic.c	2006-12-22 01:57:07.000000000 +0100
@@ -390,7 +390,7 @@
 		u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
 		if (id == PCI_CAP_ID_HT) {
 			id = readb(devbase + pos + 3);
-			if (id == HT_CAPTYPE_IRQ)
+			if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_IRQ)
 				break;
 		}
 	}
diff -ru 2.2/arch/sparc/defconfig 3.4/arch/sparc/defconfig
--- 2.2/arch/sparc/defconfig	2006-10-02 17:39:11.000000000 +0200
+++ 3.4/arch/sparc/defconfig	2006-12-18 04:27:33.000000000 +0100
@@ -1,41 +1,59 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20-rc1
+# Sun Dec 17 14:20:47 2006
 #
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_HIGHMEM=y
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -43,17 +61,36 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
-# General setup
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# General machine setup
 #
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
 # CONFIG_SMP is not set
+CONFIG_SPARC=y
 CONFIG_SPARC32=y
 CONFIG_SBUS=y
 CONFIG_SBUSCHAR=y
@@ -61,73 +98,170 @@
 CONFIG_SUN_AUXIO=y
 CONFIG_SUN_IO=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_SUN_PM=y
 # CONFIG_SUN4 is not set
 CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_PCI_DEBUG is not set
 CONFIG_SUN_OPENPROMFS=m
+# CONFIG_SPARC_LED is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_MISC=m
 CONFIG_SUNOS_EMUL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
-# Parallel port support
+# Networking
 #
-# CONFIG_PARPORT is not set
+CONFIG_NET=y
 
 #
-# Generic Driver Options
+# Networking options
 #
-# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# 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 is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+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=m
+CONFIG_IPV6_PRIVACY=y
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
 
 #
-# Graphics support
+# DCCP Configuration (EXPERIMENTAL)
 #
-# CONFIG_FB is not set
+# CONFIG_IP_DCCP is not set
 
 #
-# Console display driver support
+# SCTP Configuration (EXPERIMENTAL)
 #
-# CONFIG_MDA_CONSOLE is not set
-# CONFIG_PROM_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+CONFIG_SCTP_DBG_OBJCNT=y
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
 
 #
-# Memory Technology Devices (MTD)
+# TIPC Configuration (EXPERIMENTAL)
 #
-# CONFIG_MTD is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
 
 #
-# Serial drivers
+# QoS and/or fair queueing
 #
-# CONFIG_SERIAL_8250 is not set
+# CONFIG_NET_SCHED is not set
 
 #
-# Non-8250 serial port support
+# Network testing
 #
-CONFIG_SERIAL_SUNCORE=y
-CONFIG_SERIAL_SUNZILOG=y
-CONFIG_SERIAL_SUNZILOG_CONSOLE=y
-CONFIG_SERIAL_SUNSU=y
-CONFIG_SERIAL_SUNSU_CONSOLE=y
-# CONFIG_SERIAL_SUNSAB is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
-# Misc Linux/SPARC drivers
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
 #
-CONFIG_SUN_OPENPROMIO=m
-CONFIG_SUN_MOSTEK_RTC=m
-# CONFIG_SUN_BPP is not set
-# CONFIG_SUN_VIDEOPIX is not set
-# CONFIG_SUN_AURORA is not set
-# CONFIG_TADPOLE_TS102_UCTRL is not set
-# CONFIG_SUN_JSFLASH is not set
-CONFIG_APM_RTC_IS_GMT=y
-CONFIG_RTC=m
 
 #
 # Block devices
@@ -137,28 +271,37 @@
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 
 #
-# ATA/ATAPI/MFM/RLL support
+# Misc devices
 #
-# CONFIG_IDE is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 
 #
-# ISDN subsystem
+# ATA/ATAPI/MFM/RLL support
 #
-# CONFIG_ISDN is not set
+# CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -170,6 +313,7 @@
 CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -177,57 +321,58 @@
 # 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
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=m
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLOGICPTI=m
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SCSI_SUNESP=y
+# CONFIG_SCSI_SRP is not set
 
 #
-# Fibre Channel support
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
 #
-# CONFIG_FC4 is not set
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -235,85 +380,31 @@
 # CONFIG_MD is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Fusion MPT device support
 #
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_AH=y
-CONFIG_INET_ESP=y
-CONFIG_INET_IPCOMP=y
-CONFIG_IPV6=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
-# SCTP Configuration (EXPERIMENTAL)
+# IEEE 1394 (FireWire) support
 #
-CONFIG_IP_SCTP=m
-# CONFIG_SCTP_DBG_MSG is not set
-CONFIG_SCTP_DBG_OBJCNT=y
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
+# CONFIG_IEEE1394 is not set
 
 #
-# QoS and/or fair queueing
+# I2O device support
 #
-# CONFIG_NET_SCHED is not set
+# CONFIG_I2O is not set
 
 #
-# Network testing
+# Network device support
 #
-CONFIG_NET_PKTGEN=m
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
 
 #
 # ARCnet devices
@@ -321,6 +412,11 @@
 # CONFIG_ARCNET is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
@@ -330,6 +426,7 @@
 CONFIG_SUNBMAC=m
 CONFIG_SUNQE=m
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 
 #
@@ -350,14 +447,22 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -380,17 +485,24 @@
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
-# Unix98 PTY support
+# ISDN subsystem
 #
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
 
 #
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -405,17 +517,6 @@
 CONFIG_INPUT_EVBUG=m
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -424,6 +525,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_SERIAL=m
@@ -433,29 +535,239 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SUNCORE=y
+CONFIG_SERIAL_SUNZILOG=y
+CONFIG_SERIAL_SUNZILOG_CONSOLE=y
+CONFIG_SERIAL_SUNSU=y
+CONFIG_SERIAL_SUNSU_CONSOLE=y
+# CONFIG_SERIAL_SUNSAB is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+CONFIG_RTC=m
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_PROM_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Virtualization
+#
+
+#
+# Misc Linux/SPARC drivers
+#
+CONFIG_SUN_OPENPROMIO=m
+CONFIG_SUN_MOSTEK_RTC=m
+# CONFIG_SUN_BPP is not set
+# CONFIG_SUN_VIDEOPIX is not set
+# CONFIG_TADPOLE_TS102_UCTRL is not set
+# CONFIG_SUN_JSFLASH is not set
+
+#
+# Unix98 PTY support
+#
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
-CONFIG_XFS_RT=y
 CONFIG_XFS_QUOTA=y
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -468,7 +780,8 @@
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
 # CONFIG_NTFS_FS is not set
 
 #
@@ -476,13 +789,12 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-# CONFIG_DEVPTS_FS_SECURITY is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -512,17 +824,23 @@
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=m
 CONFIG_RPCSEC_GSS_KRB5=m
+# 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 is not set
+# CONFIG_CIFS_XATTR is not set
+# 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=m
 CONFIG_RXRPC=m
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -559,6 +877,7 @@
 # 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 is not set
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -575,70 +894,104 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
+# Distributed Lock Manager
 #
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
+# CONFIG_DLM is not set
 
 #
-# Watchdog Cards
+# Instrumentation Support
 #
-# CONFIG_WATCHDOG is not set
+# CONFIG_PROFILING is not set
 
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
+# CONFIG_CRYPTO_TEA is not set
 CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff -ru 2.2/arch/sparc/kernel/sparc_ksyms.c 3.4/arch/sparc/kernel/sparc_ksyms.c
--- 2.2/arch/sparc/kernel/sparc_ksyms.c	2006-10-09 14:51:46.000000000 +0200
+++ 3.4/arch/sparc/kernel/sparc_ksyms.c	2006-12-18 04:27:33.000000000 +0100
@@ -83,9 +83,6 @@
 /* Private functions with odd calling conventions. */
 extern void ___atomic24_add(void);
 extern void ___atomic24_sub(void);
-extern void ___set_bit(void);
-extern void ___clear_bit(void);
-extern void ___change_bit(void);
 extern void ___rw_read_enter(void);
 extern void ___rw_read_try(void);
 extern void ___rw_read_exit(void);
@@ -125,11 +122,6 @@
 EXPORT_SYMBOL(___atomic24_add);
 EXPORT_SYMBOL(___atomic24_sub);
 
-/* Bit operations. */
-EXPORT_SYMBOL(___set_bit);
-EXPORT_SYMBOL(___clear_bit);
-EXPORT_SYMBOL(___change_bit);
-
 /* Per-CPU information table */
 EXPORT_PER_CPU_SYMBOL(__cpu_data);
 
diff -ru 2.2/arch/sparc/kernel/time.c 3.4/arch/sparc/kernel/time.c
--- 2.2/arch/sparc/kernel/time.c	2006-10-18 15:21:02.000000000 +0200
+++ 3.4/arch/sparc/kernel/time.c	2006-12-18 04:27:33.000000000 +0100
@@ -78,7 +78,6 @@
 	extern char __copy_user_begin[], __copy_user_end[];
 	extern char __atomic_begin[], __atomic_end[];
 	extern char __bzero_begin[], __bzero_end[];
-	extern char __bitops_begin[], __bitops_end[];
 
 	unsigned long pc = regs->pc;
 
@@ -88,9 +87,7 @@
 	    (pc >= (unsigned long) __atomic_begin &&
 	     pc < (unsigned long) __atomic_end) ||
 	    (pc >= (unsigned long) __bzero_begin &&
-	     pc < (unsigned long) __bzero_end) ||
-	    (pc >= (unsigned long) __bitops_begin &&
-	     pc < (unsigned long) __bitops_end))
+	     pc < (unsigned long) __bzero_end))
 		pc = regs->u_regs[UREG_RETPC];
 	return pc;
 }
diff -ru 2.2/arch/sparc/lib/atomic32.c 3.4/arch/sparc/lib/atomic32.c
--- 2.2/arch/sparc/lib/atomic32.c	2006-10-02 17:39:11.000000000 +0200
+++ 3.4/arch/sparc/lib/atomic32.c	2006-12-18 04:27:33.000000000 +0100
@@ -76,3 +76,42 @@
 	spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
 }
 EXPORT_SYMBOL(atomic_set);
+
+unsigned long ___set_bit(unsigned long *addr, unsigned long mask)
+{
+	unsigned long old, flags;
+
+	spin_lock_irqsave(ATOMIC_HASH(addr), flags);
+	old = *addr;
+	*addr = old | mask;
+	spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);
+
+	return old & mask;
+}
+EXPORT_SYMBOL(___set_bit);
+
+unsigned long ___clear_bit(unsigned long *addr, unsigned long mask)
+{
+	unsigned long old, flags;
+
+	spin_lock_irqsave(ATOMIC_HASH(addr), flags);
+	old = *addr;
+	*addr = old & ~mask;
+	spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);
+
+	return old & mask;
+}
+EXPORT_SYMBOL(___clear_bit);
+
+unsigned long ___change_bit(unsigned long *addr, unsigned long mask)
+{
+	unsigned long old, flags;
+
+	spin_lock_irqsave(ATOMIC_HASH(addr), flags);
+	old = *addr;
+	*addr = old ^ mask;
+	spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);
+
+	return old & mask;
+}
+EXPORT_SYMBOL(___change_bit);
Only in 2.2/arch/sparc/lib: bitops.S
diff -ru 2.2/arch/sparc/lib/Makefile 3.4/arch/sparc/lib/Makefile
--- 2.2/arch/sparc/lib/Makefile	2006-10-02 17:39:11.000000000 +0200
+++ 3.4/arch/sparc/lib/Makefile	2006-12-18 04:27:33.000000000 +0100
@@ -7,7 +7,7 @@
 lib-y := mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \
          strlen.o checksum.o blockops.o memscan.o memcmp.o strncmp.o \
 	 strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \
-	 copy_user.o locks.o atomic.o atomic32.o bitops.o \
+	 copy_user.o locks.o atomic.o \
 	 lshrdi3.o ashldi3.o rwsem.o muldi3.o bitext.o
 
-obj-y += iomap.o
+obj-y += iomap.o atomic32.o
diff -ru 2.2/arch/sparc64/kernel/head.S 3.4/arch/sparc64/kernel/head.S
--- 2.2/arch/sparc64/kernel/head.S	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/arch/sparc64/kernel/head.S	2006-12-18 04:27:33.000000000 +0100
@@ -78,11 +78,7 @@
 
 	/* PROM cif handler code address is in %o4.  */
 sparc64_boot:
-1:	rd	%pc, %g7
-	set	1b, %g1
-	cmp	%g1, %g7
-	be,pn	%xcc, sparc64_boot_after_remap
-	 mov	%o4, %l7
+	mov	%o4, %l7
 
 	/* We need to remap the kernel.  Use position independant
 	 * code to remap us to KERNBASE.
@@ -295,7 +291,6 @@
 
 	add	%sp, (192 + 128), %sp
 
-sparc64_boot_after_remap:
 	sethi	%hi(prom_root_compatible), %g1
 	or	%g1, %lo(prom_root_compatible), %g1
 	sethi	%hi(prom_sun4v_name), %g7
diff -ru 2.2/arch/sparc64/kernel/irq.c 3.4/arch/sparc64/kernel/irq.c
--- 2.2/arch/sparc64/kernel/irq.c	2006-10-11 15:48:10.000000000 +0200
+++ 3.4/arch/sparc64/kernel/irq.c	2006-12-18 04:27:33.000000000 +0100
@@ -372,14 +372,14 @@
 	}
 }
 
-static struct hw_interrupt_type sun4u_irq = {
+static struct irq_chip sun4u_irq = {
 	.typename	= "sun4u",
 	.enable		= sun4u_irq_enable,
 	.disable	= sun4u_irq_disable,
 	.end		= sun4u_irq_end,
 };
 
-static struct hw_interrupt_type sun4u_irq_ack = {
+static struct irq_chip sun4u_irq_ack = {
 	.typename	= "sun4u+ack",
 	.enable		= sun4u_irq_enable,
 	.disable	= sun4u_irq_disable,
@@ -387,14 +387,14 @@
 	.end		= sun4u_irq_end,
 };
 
-static struct hw_interrupt_type sun4v_irq = {
+static struct irq_chip sun4v_irq = {
 	.typename	= "sun4v",
 	.enable		= sun4v_irq_enable,
 	.disable	= sun4v_irq_disable,
 	.end		= sun4v_irq_end,
 };
 
-static struct hw_interrupt_type sun4v_irq_ack = {
+static struct irq_chip sun4v_irq_ack = {
 	.typename	= "sun4v+ack",
 	.enable		= sun4v_irq_enable,
 	.disable	= sun4v_irq_disable,
@@ -493,22 +493,6 @@
 	return bucket->virt_irq;
 }
 
-void hw_resend_irq(struct hw_interrupt_type *handler, unsigned int virt_irq)
-{
-	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
-	unsigned long pstate;
-	unsigned int *ent;
-
-	__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
-	__asm__ __volatile__("wrpr %0, %1, %%pstate"
-			     : : "r" (pstate), "i" (PSTATE_IE));
-	ent = irq_work(smp_processor_id());
-	bucket->irq_chain = *ent;
-	*ent = __irq(bucket);
-	set_softint(1 << PIL_DEVICE_IRQ);
-	__asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
-}
-
 void ack_bad_irq(unsigned int virt_irq)
 {
 	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
diff -ru 2.2/arch/sparc64/kernel/smp.c 3.4/arch/sparc64/kernel/smp.c
--- 2.2/arch/sparc64/kernel/smp.c	2006-10-09 14:51:47.000000000 +0200
+++ 3.4/arch/sparc64/kernel/smp.c	2006-12-18 04:27:33.000000000 +0100
@@ -1447,11 +1447,8 @@
 	char *ptr;
 
 	/* Copy section for each CPU (we discard the original) */
-	goal = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
-#ifdef CONFIG_MODULES
-	if (goal < PERCPU_ENOUGH_ROOM)
-		goal = PERCPU_ENOUGH_ROOM;
-#endif
+	goal = PERCPU_ENOUGH_ROOM;
+
 	__per_cpu_shift = 0;
 	for (size = 1UL; size < goal; size <<= 1UL)
 		__per_cpu_shift++;
diff -ru 2.2/arch/x86_64/Kconfig 3.4/arch/x86_64/Kconfig
--- 2.2/arch/x86_64/Kconfig	2006-12-12 05:42:34.000000000 +0100
+++ 3.4/arch/x86_64/Kconfig	2006-12-22 01:57:07.000000000 +0100
@@ -480,14 +480,13 @@
 
 config CALGARY_IOMMU_ENABLED_BY_DEFAULT
 	bool "Should Calgary be enabled by default?"
-	default y
 	depends on CALGARY_IOMMU
 	help
-	  Should Calgary be enabled by default? if you choose 'y', Calgary
+	  Should Calgary be enabled by default? If you choose 'y', Calgary
 	  will be used (if it exists). If you choose 'n', Calgary will not be
 	  used even if it exists. If you choose 'n' and would like to use
 	  Calgary anyway, pass 'iommu=calgary' on the kernel command line.
-	  If unsure, say Y.
+	  If unsure, say N.
 
 # need this always selected by IOMMU for the VIA workaround
 config SWIOTLB
diff -ru 2.2/arch/x86_64/kernel/pci-calgary.c 3.4/arch/x86_64/kernel/pci-calgary.c
--- 2.2/arch/x86_64/kernel/pci-calgary.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/x86_64/kernel/pci-calgary.c	2006-12-22 01:57:07.000000000 +0100
@@ -1052,7 +1052,7 @@
 	void *tbl;
 	int calgary_found = 0;
 	unsigned long ptr;
-	int offset;
+	unsigned int offset, prev_offset;
 	int ret;
 
 	/*
@@ -1071,15 +1071,20 @@
 	ptr = (unsigned long)phys_to_virt(get_bios_ebda());
 
 	rio_table_hdr = NULL;
+	prev_offset = 0;
 	offset = 0x180;
-	while (offset) {
+	/*
+	 * The next offset is stored in the 1st word.
+	 * Only parse up until the offset increases:
+	 */
+	while (offset > prev_offset) {
 		/* The block id is stored in the 2nd word */
 		if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){
 			/* set the pointer past the offset & block id */
 			rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
 			break;
 		}
-		/* The next offset is stored in the 1st word. 0 means no more */
+		prev_offset = offset;
 		offset = *((unsigned short *)(ptr + offset));
 	}
 	if (!rio_table_hdr) {
diff -ru 2.2/arch/x86_64/kernel/process.c 3.4/arch/x86_64/kernel/process.c
--- 2.2/arch/x86_64/kernel/process.c	2006-12-08 04:50:55.000000000 +0100
+++ 3.4/arch/x86_64/kernel/process.c	2006-12-23 01:11:19.000000000 +0100
@@ -109,7 +109,11 @@
 static void default_idle(void)
 {
 	current_thread_info()->status &= ~TS_POLLING;
-	smp_mb__after_clear_bit();
+	/*
+	 * TS_POLLING-cleared state must be visible before we
+	 * test NEED_RESCHED:
+	 */
+	smp_mb();
 	local_irq_disable();
 	if (!need_resched()) {
 		/* Enables interrupts one instruction before HLT.
diff -ru 2.2/block/cfq-iosched.c 3.4/block/cfq-iosched.c
--- 2.2/block/cfq-iosched.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/block/cfq-iosched.c	2006-12-23 01:11:19.000000000 +0100
@@ -568,6 +568,33 @@
 	cfq_remove_request(next);
 }
 
+static int cfq_allow_merge(request_queue_t *q, struct request *rq,
+			   struct bio *bio)
+{
+	struct cfq_data *cfqd = q->elevator->elevator_data;
+	const int rw = bio_data_dir(bio);
+	struct cfq_queue *cfqq;
+	pid_t key;
+
+	/*
+	 * Disallow merge, if bio and rq aren't both sync or async
+	 */
+	if (!!bio_sync(bio) != !!rq_is_sync(rq))
+		return 0;
+
+	/*
+	 * Lookup the cfqq that this bio will be queued with. Allow
+	 * merge only if rq is queued there.
+	 */
+	key = cfq_queue_pid(current, rw, bio_sync(bio));
+	cfqq = cfq_find_cfq_hash(cfqd, key, current->ioprio);
+
+	if (cfqq == RQ_CFQQ(rq))
+		return 1;
+
+	return 1;
+}
+
 static inline void
 __cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
@@ -2125,6 +2152,7 @@
 		.elevator_merge_fn = 		cfq_merge,
 		.elevator_merged_fn =		cfq_merged_request,
 		.elevator_merge_req_fn =	cfq_merged_requests,
+		.elevator_allow_merge_fn =	cfq_allow_merge,
 		.elevator_dispatch_fn =		cfq_dispatch_requests,
 		.elevator_add_req_fn =		cfq_insert_request,
 		.elevator_activate_req_fn =	cfq_activate_request,
diff -ru 2.2/block/elevator.c 3.4/block/elevator.c
--- 2.2/block/elevator.c	2006-12-07 02:52:09.000000000 +0100
+++ 3.4/block/elevator.c	2006-12-23 01:11:19.000000000 +0100
@@ -51,6 +51,21 @@
 #define ELV_ON_HASH(rq)		(!hlist_unhashed(&(rq)->hash))
 
 /*
+ * Query io scheduler to see if the current process issuing bio may be
+ * merged with rq.
+ */
+static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
+{
+	request_queue_t *q = rq->q;
+	elevator_t *e = q->elevator;
+
+	if (e->ops->elevator_allow_merge_fn)
+		return e->ops->elevator_allow_merge_fn(q, rq, bio);
+
+	return 1;
+}
+
+/*
  * can we safely merge with this request?
  */
 inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
@@ -65,12 +80,15 @@
 		return 0;
 
 	/*
-	 * same device and no special stuff set, merge is ok
+	 * must be same device and not a special request
 	 */
-	if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special)
-		return 1;
+	if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
+		return 0;
 
-	return 0;
+	if (!elv_iosched_allow_merge(rq, bio))
+		return 0;
+
+	return 1;
 }
 EXPORT_SYMBOL(elv_rq_merge_ok);
 
diff -ru 2.2/block/ioctl.c 3.4/block/ioctl.c
--- 2.2/block/ioctl.c	2006-12-08 19:05:36.000000000 +0100
+++ 3.4/block/ioctl.c	2006-12-19 14:47:35.000000000 +0100
@@ -61,7 +61,7 @@
 				}
 			}
 			/* all seems OK */
-			add_partition(disk, part, start, length);
+			add_partition(disk, part, start, length, ADDPART_FLAG_NONE);
 			mutex_unlock(&bdev->bd_mutex);
 			return 0;
 		case BLKPG_DEL_PARTITION:
diff -ru 2.2/block/ll_rw_blk.c 3.4/block/ll_rw_blk.c
--- 2.2/block/ll_rw_blk.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/block/ll_rw_blk.c	2006-12-23 01:11:19.000000000 +0100
@@ -1405,8 +1405,7 @@
 	return 1;
 }
 
-static int ll_back_merge_fn(request_queue_t *q, struct request *req, 
-			    struct bio *bio)
+int ll_back_merge_fn(request_queue_t *q, struct request *req, struct bio *bio)
 {
 	unsigned short max_sectors;
 	int len;
@@ -1442,6 +1441,7 @@
 
 	return ll_new_hw_segment(q, req, bio);
 }
+EXPORT_SYMBOL(ll_back_merge_fn);
 
 static int ll_front_merge_fn(request_queue_t *q, struct request *req, 
 			     struct bio *bio)
@@ -1912,9 +1912,6 @@
 	}
 
 	q->request_fn		= rfn;
-	q->back_merge_fn       	= ll_back_merge_fn;
-	q->front_merge_fn      	= ll_front_merge_fn;
-	q->merge_requests_fn	= ll_merge_requests_fn;
 	q->prep_rq_fn		= NULL;
 	q->unplug_fn		= generic_unplug_device;
 	q->queue_flags		= (1 << QUEUE_FLAG_CLUSTER);
@@ -2350,40 +2347,29 @@
 	else
 		bio = bio_copy_user(q, uaddr, len, reading);
 
-	if (IS_ERR(bio)) {
+	if (IS_ERR(bio))
 		return PTR_ERR(bio);
-	}
 
 	orig_bio = bio;
 	blk_queue_bounce(q, &bio);
+
 	/*
 	 * We link the bounce buffer in and could have to traverse it
 	 * later so we have to get a ref to prevent it from being freed
 	 */
 	bio_get(bio);
 
-	/*
-	 * for most (all? don't know of any) queues we could
-	 * skip grabbing the queue lock here. only drivers with
-	 * funky private ->back_merge_fn() function could be
-	 * problematic.
-	 */
-	spin_lock_irq(q->queue_lock);
 	if (!rq->bio)
 		blk_rq_bio_prep(q, rq, bio);
-	else if (!q->back_merge_fn(q, rq, bio)) {
+	else if (!ll_back_merge_fn(q, rq, bio)) {
 		ret = -EINVAL;
-		spin_unlock_irq(q->queue_lock);
 		goto unmap_bio;
 	} else {
 		rq->biotail->bi_next = bio;
 		rq->biotail = bio;
 
-		rq->nr_sectors += bio_sectors(bio);
-		rq->hard_nr_sectors = rq->nr_sectors;
 		rq->data_len += bio->bi_size;
 	}
-	spin_unlock_irq(q->queue_lock);
 
 	return bio->bi_size;
 
@@ -2419,6 +2405,7 @@
 		    unsigned long len)
 {
 	unsigned long bytes_read = 0;
+	struct bio *bio = NULL;
 	int ret;
 
 	if (len > (q->max_hw_sectors << 9))
@@ -2445,6 +2432,8 @@
 		ret = __blk_rq_map_user(q, rq, ubuf, map_len);
 		if (ret < 0)
 			goto unmap_rq;
+		if (!bio)
+			bio = rq->bio;
 		bytes_read += ret;
 		ubuf += ret;
 	}
@@ -2452,7 +2441,7 @@
 	rq->buffer = rq->data = NULL;
 	return 0;
 unmap_rq:
-	blk_rq_unmap_user(rq);
+	blk_rq_unmap_user(bio);
 	return ret;
 }
 
@@ -2464,6 +2453,7 @@
  * @rq:		request to map data to
  * @iov:	pointer to the iovec
  * @iov_count:	number of elements in the iovec
+ * @len:	I/O byte count
  *
  * Description:
  *    Data will be mapped directly for zero copy io, if possible. Otherwise
@@ -2509,27 +2499,33 @@
 
 /**
  * blk_rq_unmap_user - unmap a request with user data
- * @rq:		rq to be unmapped
+ * @bio:	       start of bio list
  *
  * Description:
- *    Unmap a rq previously mapped by blk_rq_map_user().
- *    rq->bio must be set to the original head of the request.
- */
-int blk_rq_unmap_user(struct request *rq)
-{
-	struct bio *bio, *mapped_bio;
-
-	while ((bio = rq->bio)) {
-		if (bio_flagged(bio, BIO_BOUNCED))
+ *    Unmap a rq previously mapped by blk_rq_map_user(). The caller must
+ *    supply the original rq->bio from the blk_rq_map_user() return, since
+ *    the io completion may have changed rq->bio.
+ */
+int blk_rq_unmap_user(struct bio *bio)
+{
+	struct bio *mapped_bio;
+	int ret = 0, ret2;
+
+	while (bio) {
+		mapped_bio = bio;
+		if (unlikely(bio_flagged(bio, BIO_BOUNCED)))
 			mapped_bio = bio->bi_private;
-		else
-			mapped_bio = bio;
 
-		__blk_rq_unmap_user(mapped_bio);
-		rq->bio = bio->bi_next;
-		bio_put(bio);
+		ret2 = __blk_rq_unmap_user(mapped_bio);
+		if (ret2 && !ret)
+			ret = ret2;
+
+		mapped_bio = bio;
+		bio = bio->bi_next;
+		bio_put(mapped_bio);
 	}
-	return 0;
+
+	return ret;
 }
 
 EXPORT_SYMBOL(blk_rq_unmap_user);
@@ -2822,7 +2818,7 @@
 	 * will have updated segment counts, update sector
 	 * counts here.
 	 */
-	if (!q->merge_requests_fn(q, req, next))
+	if (!ll_merge_requests_fn(q, req, next))
 		return 0;
 
 	/*
@@ -2939,7 +2935,7 @@
 		case ELEVATOR_BACK_MERGE:
 			BUG_ON(!rq_mergeable(req));
 
-			if (!q->back_merge_fn(q, req, bio))
+			if (!ll_back_merge_fn(q, req, bio))
 				break;
 
 			blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE);
@@ -2956,7 +2952,7 @@
 		case ELEVATOR_FRONT_MERGE:
 			BUG_ON(!rq_mergeable(req));
 
-			if (!q->front_merge_fn(q, req, bio))
+			if (!ll_front_merge_fn(q, req, bio))
 				break;
 
 			blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE);
diff -ru 2.2/block/scsi_ioctl.c 3.4/block/scsi_ioctl.c
--- 2.2/block/scsi_ioctl.c	2006-12-13 18:28:54.000000000 +0100
+++ 3.4/block/scsi_ioctl.c	2006-12-22 01:57:11.000000000 +0100
@@ -333,8 +333,7 @@
 			hdr->sb_len_wr = len;
 	}
 
-	rq->bio = bio;
-	if (blk_rq_unmap_user(rq))
+	if (blk_rq_unmap_user(bio))
 		ret = -EFAULT;
 
 	/* may not have succeeded, but output values written to control
Only in 2.2/debian/abi: 2.6.20-1.1
Only in 3.4/debian/abi: 2.6.20-2.2
diff -ru 2.2/debian/changelog 3.4/debian/changelog
--- 2.2/debian/changelog	2006-12-16 04:57:17.000000000 +0100
+++ 3.4/debian/changelog	2006-12-26 00:24:16.000000000 +0100
@@ -1,3 +1,438 @@
+linux-source-2.6.20 (2.6.20-3.4) feisty; urgency=low
+
+  * Fix FTBFS due to changes in kernel-wedge.
+
+  [Ben Collins]
+
+  * ubuntu/media/usbvideo: Add USB Video Class driver (iSight)
+    - GIT-SHA a948310ffdeb5d8dddff193aa31da63039d985d5
+  * ubuntu/media: Add usbvideo to build.
+    - GIT-SHA 545ee922c0c492929eaa0a4c675c0f6d3dbc4cfd
+  * prism2: Fix incorrect conversion of work queue.
+    - GIT-SHA 44e61605e7d160397082028780da4f749c13db00
+    - Bug #76220
+  * uvcvideo: Fix usb urb callback prototypes.
+    - GIT-SHA 4aea9254ec30b7422ca59a617f6a59d951e0769e
+  * debian/config: Disable speedstep_centrino in favor of acpi_cpufreq.
+    - GIT-SHA 2a0e7ef37fb8db5953f4c467219552835d7dddd8
+  * Fix compile breakage. Patch taken from lkml (will be reverted).
+    - GIT-SHA 93a714f337c0636b72d605400f41347c4465a344
+  * Add ivtv firmware.
+    - GIT-SHA 9ed1a41d11cffb205f425cc71e7f6c605b284d25
+  * sata_svw: Check for error from ata_device_ata()
+    - GIT-SHA 4b0e1e03cb077b5659d656d8b869c11e2ae47f94
+    - Bug #76391
+  * pmu-backlight: Fixup for change in backlight_register.
+    - GIT-SHA c4f21571091b0b7eb798b1e76956b53475bcb5d8
+
+  [Upstream Kernel Changes]
+
+  * ACPI: Remove unnecessary from/to-void* and to-void casts in
+    drivers/acpi
+  * ACPI: avoid gcc warnings in ACPI mutex debug code
+  * ACPI: uninline ACPI global locking functions
+  * ACPI: acpi-cpufreq: remove unused data when !CONFIG_SMP
+  * ACPI: ibm_acpi: Add support for the generic backlight device
+  * ACPI: asus_acpi: Add support for the generic backlight device
+  * ACPI: toshiba_acpi: Add support for the generic backlight device
+  * ACPI: make ec_transaction not extern
+  * ACPI: optimize pci_rootbridge search
+  * ACPI: dock: use mutex instead of spinlock
+  * ACPI: S4: Use "platform" rather than "shutdown" mode by default
+  * ACPI: Get rid of 'unused variable' warning in
+    acpi_ev_global_lock_handler()
+  * ACPI: update comment
+  * ACPI: button: register with input layer
+  * ACPI: ibm-acpi: new ibm-acpi maintainer
+  * ACPI: ibm-acpi: do not use / in driver names
+  * ACPI: ibm-acpi: trivial Lindent cleanups
+  * ACPI: ibm-acpi: Use a enum to select the thermal sensor reading
+    strategy
+  * ACPI: ibm-acpi: Implement direct-ec-access thermal reading modes for up
+    to 16 sensors
+  * ACPI: ibm-acpi: document thermal sensor locations for the A31
+  * ACPI: ibm-acpi: prepare to cleanup fan_read and fan_write
+  * ACPI: ibm-acpi: clean up fan_read
+  * ACPI: ibm-acpi: break fan_read into separate functions
+  * ACPI: ibm-acpi: cleanup fan_write
+  * ACPI: ibm-acpi: document fan control
+  * ACPI: ibm-acpi: extend fan status functions
+  * ACPI: ibm-acpi: fix and extend fan enable
+  * ACPI: ibm-acpi: fix and extend fan control functions
+  * ACPI: ibm-acpi: store embedded controller firmware version for matching
+  * ACPI: ibm-acpi: workaround for EC 0x2f initialization bug
+  * ACPI: ibm-acpi: implement fan watchdog command
+  * ACPI: ibm-acpi: add support for the ultrabay on the T60,X60
+  * ACPI: ibm-acpi: make non-generic bay support optional
+  * ACPI: ibm-acpi: backlight device cleanup
+  * ACPI: ibm-acpi: style fixes and cruft removal
+  * ACPI: ibm-acpi: update version and copyright
+  * ACPI: dock: Make the dock station driver a platform device driver.
+  * ACPI: dock: fix build warning
+  * ACPI: dock: Add a docked sysfs file to the dock driver.
+  * ACPI: dock: Fix symbol conflict between acpiphp and dock
+  * ACPI: ec: Allow for write semantics in any command.
+  * ACPI: ec: Enable EC GPE at beginning of transaction
+  * ACPI: ec: Increase timeout from 50 to 500 ms to handle old slow
+    machines.
+  * ACPI: ec: Read status register from check_status() function
+  * ACPI: ec: Remove expect_event and all races around it.
+  * ACPI: ec: Remove calls to clear_gpe() and enable_gpe(), as these are
+    handled at
+  * ACPI: ec: Query only single query at a time.
+  * ACPI: ec: Change semaphore to mutex.
+  * ACPI: ec: Rename gpe_bit to gpe
+  * ACPI: ec: Drop udelay() from poll mode. Loop by reading status field
+    instead.
+  * ACPI: ec: Acquire Global Lock under EC mutex.
+  * ACPI: ec: Style changes.
+  * ACPI: ec: Change #define to enums there possible.
+  * ACPI: ec: Lindent once again
+  * drm: fix return value check
+  * DRM: handle pci_enable_device failure
+  * i915_vblank_tasklet: Try harder to avoid tearing.
+  * [CPUFREQ] fixes typo in cpufreq.c
+  * [CPUFREQ] Trivial cleanup for acpi read/write port in acpi-cpufreq.c
+  * Generic HID layer - build: USB_HID should select HID
+  * input/hid: Supporting more keys from the HUT Consumer Page
+  * Generic HID layer - update MAINTAINERS
+  * ACPI: dock: add uevent to indicate change in device status
+  * drm: Unify radeon offset checking.
+  * [DLM] fix compile warning
+  * [GFS2] Fix Kconfig
+  * IB: Fix ib_dma_alloc_coherent() wrapper
+  * IB/srp: Fix FMR mapping for 32-bit kernels and addresses above 4G
+  * Fix "delayed_work_pending()" macro expansion
+  * IB/mthca: Add HCA profile module parameters
+  * IB/mthca: Use DEFINE_MUTEX() instead of mutex_init()
+  * Pull ec into test branch
+  * Pull dock into test branch
+  * Pull button into test branch
+  * Pull platform-drivers into test branch
+  * ACPI: ibm_acpi: respond to workqueue update
+  * Pull trivial into test branch
+  * ACPI: fix git automerge failure
+  * Pull bugfix into test branch
+  * Pull style into test branch
+  * ata_piix: IDE mode SATA patch for Intel ICH9
+  * ata_piix: use piix_host_stop() in ich_pata_ops
+  * [libata] use kmap_atomic(KM_IRQ0) in SCSI simulator
+  * [libata] sata_svw: Disable ATAPI DMA on current boards (errata
+    workaround)
+  * libata: don't initialize sg in ata_exec_internal() if DMA_NONE (take
+    #2)
+  * ahci: do not mangle saved HOST_CAP while resetting controller
+  * ata: fix platform_device_register_simple() error check
+  * initializer entry defined twice in pata_rz1000
+  * Fix help text for CONFIG_ATA_PIIX
+  * pata_via: Cable detect error
+  * Fix incorrect user space access locking in mincore()
+  * Make workqueue bit operations work on "atomic_long_t"
+  * Fix up mm/mincore.c error value cases
+  * m68k trivial build fixes
+  * sys_mincore: s/max/min/
+  * [ARM] Add more syscalls
+  * [SPARC64]: Kill no-remapping-needed code in head.S
+  * [SPARC64]: Minor irq handling cleanups.
+  * [DocBook]: Fix two typos in generic IRQ docs.
+  * [SUNKBD]: Fix sunkbd_enable(sunkbd, 0); obvious.
+  * [SPARC64]: Mirror x86_64's PERCPU_ENOUGH_ROOM definition.
+  * [SPARC]: Update defconfig.
+  * [CPUFREQ] set policy->curfreq on initialization
+  * [ARM] Fix BUG()s in ioremap() code
+  * [ARM] 4034/1: pxafb: Fix compile errors
+  * [ARM] 4035/1: fix collie compilation
+  * [ARM] 4038/1: S3C24XX: Fix copyrights in include/asm-arm/arch-s3c2410
+    (core)
+  * [ARM] 4039/1: S3C24XX: Fix copyrights in include/asm-arm/arch-s3c2410
+    (mach)
+  * [ARM] 4040/1: S3C24XX: Fix copyrights in arch/arm/mach-s3c2410
+  * [ARM] 4041/1: S3C24XX: Fix sparse errors from VA addresses
+  * [ARM] 4042/1: H1940: Fix sparse errors from VA addresses
+  * [ARM] 4043/1: S3C24XX: fix sparse warnings in
+    arch/arm/mach-s3c2410/s3c2440-clock.c
+  * [ARM] 4044/1: S3C24XX: fix sparse warnings in
+    arch/arm/mach-s3c2410/s3c2442-clock.c
+  * [ARM] 4045/1: S3C24XX: remove old VA for non-shared areas
+  * [ARM] 4046/1: S3C24XX: fix sparse errors arch/arm/mach-s3c2410
+  * [ARM] 4048/1: S3C24XX: make s3c2410_pm_resume() static
+  * [ARM] 4049/1: S3C24XX: fix sparse warning due to upf_t in regs-serial.h
+  * [ARM] 4050/1: S3C24XX: remove old changelogs in arch/arm/mach-s3c2410
+  * [ARM] 4051/1: S3C24XX: clean includes in S3C2440 and S3C2442 support
+  * [CPUFREQ] Advise not to use longhaul on VIA C7.
+  * [CPUFREQ] longhaul compile fix.
+  * [ARM] Fix warnings from asm/system.h
+  * [ARM] 4052/1: S3C24XX: Fix PM in arch/arm/mach-s3c2410/Kconfig
+  * [ARM] 4054/1: ep93xx: add HWCAP_CRUNCH
+  * [ARM] 4055/1: iop13xx: fix phys_io/io_pg_offst for iq81340mc/sc
+  * [ARM] 4056/1: iop13xx: fix resource.end off-by-one in flash setup
+  * [ARM] 4057/1: ixp23xx: unconditionally enable hardware coherency
+  * [ARM] 4015/1: s3c2410 cpu ifdefs
+  * [SPARC]: Make bitops use same spinlocks as atomics.
+  * more work_struct fixes: tas300x sound drivers
+  * [TG3]: replace kmalloc+memset with kzalloc
+  * [AX.25]: Mark all kmalloc users __must_check
+  * [AX.25]: Fix unchecked ax25_protocol_register uses.
+  * [AX.25]: Fix unchecked ax25_listen_register uses
+  * [AX.25]: Fix unchecked nr_add_node uses.
+  * [AX.25]: Fix unchecked ax25_linkfail_register uses
+  * [AX.25]: Fix unchecked rose_add_loopback_node uses
+  * [AX.25]: Fix unchecked rose_add_loopback_neigh uses
+  * [BNX2]: Fix panic in bnx2_tx_int().
+  * [BNX2]: Fix bug in bnx2_nvram_write().
+  * [BNX2]: Fix minor loopback problem.
+  * [NETFILTER] IPV6: Fix dependencies.
+  * [TG3]: Assign tp->link_config.orig_* values.
+  * [TG3]: Fix race condition when calling register_netdev().
+  * [TG3]: Power down/up 5906 PHY correctly.
+  * [TG3]: Update version and reldate.
+  * [CONNECTOR]: Fix compilation breakage introduced recently.
+  * [TCP]: Fix oops caused by tcp_v4_md5_do_del
+  * [TCP]: Trivial fix to message in tcp_v4_inbound_md5_hash
+  * [IPV4]: Fix BUG of ip_rt_send_redirect()
+  * [CONNECTOR]: Replace delayed work with usual work queue.
+  * cciss: set default raid level when reading geometry fails
+  * cciss: fix XFER_READ/XFER_WRITE in do_cciss_request
+  * drm: savage: compat fix from drm git.
+  * drm: fixup comment header style
+  * drm: make kernel context switch same as for drm git tree.
+  * drm: r128: comment aligment with drm git
+  * drm: Stop defining pci_pretty_name
+  * ->nr_sectors and ->hard_nr_sectors are not used for BLOCK_PC requests
+  * Remove queue merging hooks
+  * __blk_rq_map_user() doesn't need to grab the queue_lock
+  * __blk_rq_unmap_user() fails to return error
+  * Fixup blk_rq_unmap_user() API
+  * [PARTITION]: Add whole_disk attribute.
+  * [POWERPC] cell: update cell_defconfig
+  * [POWERPC] cell: add forward struct declarations to spu.h
+  * [POWERPC] cell: Enable spider workarounds on all PCI buses
+  * [POWERPC] cell: Fix spufs with "new style" device-tree
+  * [POWERPC] spufs: fix assignment of node numbers
+  * [POWERPC] powerpc: add scanning of ebc bus to of_platform
+  * [ARM] 4022/1: iop13xx: generic irq fixups
+  * [ARM] 4059/1: VR1000: fix LED3's platform device number
+  * [ARM] 4061/1: xsc3: change of maintainer
+  * [ARM] 4060/1: update several ARM defconfigs
+  * [ARM] 4062/1: S3C24XX: Anubis and Osiris shuld have CONFIG_PM_SIMTEC
+  * ACPI: ibm_acpi: allow clean removal
+  * ACPI: fix single linked list manipulation
+  * ACPI: prevent processor module from loading on failures
+  * [POWERPC] Workaround oldworld OF bug with IRQs & P2P bridges
+  * [POWERPC] iSeries: fix viodasd init
+  * [POWERPC] iSeries: fix viotape init
+  * [POWERPC] iSeries: fix iseries_veth init
+  * [POWERPC] iSeries: fix viocd init
+  * [POWERPC] iSeries: fix viocons init
+  * [POWERPC] iSeries: fix CONFIG_VIOPATH dependency
+  * [POWERPC] Fix build of cell zImage.initrd
+  * [POWERPC] Probe Efika platform before CHRP.
+  * [POWERPC] Update MTD OF documentation
+  * [POWERPC] Fix PCI device channel state initialization
+  * [POWERPC] Fix register save area alignment for swapcontext syscall
+  * ACPI: make drivers/acpi/ec.c:ec_ecdt static
+  * ACPI: fix NULL check in drivers/acpi/osl.c
+  * ACPI: Kconfig - depend on PM rather than selecting it
+  * ACPI: Implement acpi_video_get_next_level()
+  * ACPI: video: Add dev argument for backlight_device_register
+  * fbdev: update after backlight argument change
+  * ACPI: Add support for acpi_load_table/acpi_unload_table_id
+  * Pull platform-drivers into test branch
+  * Pull ec into test branch
+  * Pull bugfix into test branch
+  * merge linus into test branch
+  * Pull sgi into test branch
+  * [ALSA] via82xx: add __devinitdata
+  * [ALSA] sound/usb/usbaudio: Handle return value of usb_register()
+  * [ALSA] sound: Don't include i2c-dev.h
+  * [ALSA] ac97_codec (ALC655): add EAPD hack for MSI L725 laptop
+  * [ALSA] use the ALIGN macro
+  * [ALSA] use the roundup macro
+  * [ALSA] ymfpci: fix swap_rear for S/PDIF passthrough
+  * [ALSA] hda-codec - Fix wrong error checks in patch_{realtek,analog}.c
+  * [ALSA] hda-codec - Don't return error at initialization of modem codec
+  * [ALSA] hdsp: precise_ptr control switched off by default
+  * [ALSA] hda-codec - Fix a typo
+  * [ALSA] pcm core: fix silence_start calculations
+  * [ALSA] hda-codec - Add model for HP q965
+  * [ALSA] sound/core/control.c: remove dead code
+  * [ALSA] hda-codec - Fix model for ASUS V1j laptop
+  * [ALSA] hda-codec - Fix detection of supported sample rates
+  * [ALSA] hda-codec - Verbose proc output for PCM parameters
+  * [ALSA] ac97 - Fix potential negative array index
+  * [ALSA] hda-codec - fix typo in PCI IDs
+  * [ALSA] Fix races in PCM OSS emulation
+  * [ALSA] Fix invalid assignment of PCI revision
+  * [ALSA] Remove IRQF_DISABLED for shared PCI irqs
+  * [ALSA] snd_hda_intel 3stack mode for ASUS P5P-L2
+  * [ALSA] sound: initialize rawmidi substream list
+  * [ALSA] sound: fix PCM substream list
+  * [ALSA] snd-ca0106: Add new card variant.
+  * [ALSA] snd-ca0106: Fix typos.
+  * [ALSA] ac97_codec - trivial fix for bit update functions
+  * [ALSA] ac97: Identify CMI9761 chips.
+  * [ALSA] version 1.0.14rc1
+  * cfq-iosched: don't allow sync merges across queues
+  * block: document io scheduler allow_merge_fn hook
+  * [libata] pata_cs5530: suspend/resume support tweak
+  * [libata] pata_via: suspend/resume support fix
+  * USB: Fix oops in PhidgetServo
+  * USB: fix transvibrator disconnect race
+  * USB: airprime: add device id for dell wireless 5500 hsdpa card
+  * USB: ftdi_sio - MachX product ID added
+  * USB: removing ifdefed code from gl620a
+  * usb serial: Eliminate bogus ioctl code
+  * USB: mutexification of usblp
+  * Add Baltech Reader ID to CP2101 driver
+  * USB: Prevent the funsoft serial device from entering raw mode
+  * USB: fix ohci.h over-use warnings
+  * USB: rtl8150 new device id
+  * usb-storage: Ignore the virtual cd-drive of the Huawei E220 USB Modem
+  * usb-gsm-driver: Added VendorId and ProductId for Huawei E220 USB Modem
+  * USB: fix Wacom Intuos3 4x6 bugs
+  * USB AUERSWALD: replace kmalloc+memset with kzalloc
+  * USB: Nokia E70 is an unusual device
+  * UHCI: module parameter to ignore overcurrent changes
+  * USB: gadget driver unbind() is optional; section fixes; misc
+  * USB: MAINTAINERS update, EHCI and OHCI
+  * USB: ohci whitespace/comment fixups
+  * USB: ohci at91 warning fix
+  * USB: ohci handles hardware faults during root port resets
+  * USB: OHCI support for PNX8550
+  * USB: at91 udc, support at91sam926x addresses
+  * USB: at91_udc, misc fixes
+  * USB: u132-hcd/ftdi-elan: add support for Option GT 3G Quad card
+  * USB: at91_udc: allow drivers that support high speed
+  * USB: at91_udc: Cleanup variables after failure in
+    usb_gadget_register_driver()
+  * USB: at91_udc: Additional checks
+  * USB: fix to usbfs_snoop logging of user defined control urbs
+  * PCI: use /sys/bus/pci/drivers/<driver>/new_id first
+  * pci: add class codes for Wireless RF controllers
+  * PCI quirks: remove redundant check
+  * rpaphp: compiler warning cleanup
+  * PCI: pcieport-driver: remove invalid warning message
+  * pci: Introduce pci_find_present
+  * PCI: Create __pci_bus_find_cap_start() from __pci_bus_find_cap()
+  * PCI: Add pci_find_ht_capability() for finding Hypertransport
+    capabilities
+  * PCI: Use pci_find_ht_capability() in drivers/pci/htirq.c
+  * PCI: Add #defines for Hypertransport MSI fields
+  * PCI: Use pci_find_ht_capability() in drivers/pci/quirks.c
+  * PCI: Only check the HT capability bits in mpic.c
+  * PCI: Fix multiple problems with VIA hardware
+  * PCI: Be a bit defensive in quirk_nvidia_ck804() so we don't risk
+    dereferencing a NULL pdev.
+  * PCI: don't export device IDs to userspace
+  * PCI legacy resource fix
+  * PCI: ATI sb600 sata quirk
+  * shpchp: remove unnecessary struct php_ctlr
+  * shpchp: cleanup struct controller
+  * shpchp: remove shpchprm_get_physical_slot_number
+  * shpchp: cleanup shpchp.h
+  * acpiphp: Link-time error for PCI Hotplug
+  * kref refcnt and false positives
+  * kobject: kobject_uevent() returns manageable value
+  * Driver core: proper prototype for drivers/base/init.c:driver_init()
+  * [libata] Move some PCI IDs from sata_nv to ahci
+  * libata: clean up variable name usage in xlat related functions
+  * libata: kill @cdb argument from xlat methods
+  * libata: take scmd->cmd_len into account when translating SCSI commands
+  * USB: Nokia E70 is an unusual device
+  * usb serial: add support for Novatel S720/U720 CDMA/EV-DO modems
+  * bluetooth: add support for another Kensington dongle
+  * [libata] sata_svw, sata_vsc: kill iomem warnings
+  * USB Storage: remove duplicate Nokia entry in unusual_devs.h
+  * ACPI: replace kmalloc+memset with kzalloc
+  * __set_irq_handler bogus space
+  * x86_64: fix boot hang caused by CALGARY_IOMMU_ENABLED_BY_DEFAULT
+  * x86_64: fix boot time hang in detect_calgary()
+  * sched: improve efficiency of sched_fork()
+  * fix leaks on pipe(2) failure exits
+  * workqueue: fix schedule_on_each_cpu()
+  * Clean up and make try_to_free_buffers() not race with dirty pages
+  * VM: Remove "clear_page_dirty()" and "test_clear_page_dirty()" functions
+  * Fix JFS after clear_page_dirty() removal
+  * fuse: remove clear_page_dirty() call
+  * Fix XFS after clear_page_dirty() removal
+  * elevator: fixup typo in merge logic
+  * truncate: dirty memory accounting fix
+  * KVM: add valid_vcpu() helper
+  * KVM: AMD SVM: handle MSR_STAR in 32-bit mode
+  * KVM: AMD SVM: Save and restore the floating point unit state
+  * KVM: Use more traditional error handling in kvm_mmu_init()
+  * KVM: Do not export unsupported msrs to userspace
+  * KVM: Force real-mode cs limit to 64K
+  * KVM: Handle p5 mce msrs
+  * KVM: API versioning
+  * CONFIG_VM_EVENT_COUNTER comment decrustify
+  * Conditionally check expected_preempt_count in __resched_legal()
+  * Fix for shmem_truncate_range() BUG_ON()
+  * rtc warning fix
+  * slab: fix kmem_ptr_validate definition
+  * fix kernel-doc warnings in 2.6.20-rc1
+  * make kernel/printk.c:ignore_loglevel_setup() static
+  * fs/sysv/: proper prototypes for 2 functions
+  * Fix swapped parameters in mm/vmscan.c
+  * Add cscope generated files to .gitignore
+  * sched: remove __cpuinitdata anotation to cpu_isolated_map
+  * fix vm_events_fold_cpu() build breakage
+  * genirq: fix irq flow handler uninstall
+  * smc911x: fix netpoll compilation faliure
+  * smc911 workqueue fixes
+  * fsstack: Remove inode copy
+  * lock debugging: fix DEBUG_LOCKS_WARN_ON() & debug_locks_silent
+  * Make JFFS depend on CONFIG_BROKEN
+  * Add a new section to CodingStyle, promoting include/linux/kernel.h
+  * fix aoe without scatter-gather [Bug 7662]
+  * mm: more rmap debugging
+  * handle SLOB with sparsemen
+  * compile error of register_memory()
+  * audit: fix kstrdup() error check
+  * gss_spkm3: fix error handling in module init
+  * schedule_timeout(): improve warning message
+  * microcode: fix mc_cpu_notifier section warning
+  * MAINTAINERS: fix email for S3C2410 and S3C2440
+  * tlclk: delete unnecessary sysfs_remove_group
+  * gxt4500: Fix colormap and PLL setting, support GXT6000P
+  * fdtable: Provide free_fdtable() wrapper
+  * kernel-doc: allow unnamed structs/unions
+  * kernel-doc: remove Martin from MAINTAINERS
+  * mips: if_fddi.h: Add a missing inclusion
+  * memory hotplug: fix compile error for i386 with NUMA config
+  * ptrace: Fix EFL_OFFSET value according to i386 pda changes
+  * relay: remove inlining
+  * increase CARDBUS_MEM_SIZE
+  * md: fix a few problems with the interface (sysfs and ioctl) to md
+  * fix s3c24xx gpio driver (include linux/workqueue.h)
+  * jbd: wait for already submitted t_sync_datalist buffer to complete
+  * sched: fix bad missed wakeups in the i386, x86_64, ia64, ACPI and APM
+    idle code
+  * build compile.h earlier
+  * Fix reparenting to the same thread group. (take 2)
+  * serial/uartlite: Only enable port if request_port succeeded
+  * Fix up page_mkclean_one(): virtual caches, s390
+  * NetLabel: perform input validation earlier on CIPSOv4 DOI add ops
+  * NetLabel: correctly fill in unused CIPSOv4 level and category mappings
+  * [ATM]: Remove dead ATM_TNETA1570 option.
+  * [ATM] drivers/atm/fore200e.c: Cleanups.
+  * [TCP]: Fix ambiguity in the `before' relation.
+  * [SCTP]: Don't export include/linux/sctp.h to userspace.
+  * [SCTP]: Fix typo adaption -> adaptation as per the latest API draft.
+  * [SCTP]: make 2 functions static
+  * [IPV6]: Dumb typo in generic csum_ipv6_magic()
+  * [UDP]: Fix reversed logic in udp_get_port().
+  * cfq-iosched: tighten allow merge criteria
+  * Call init_timer() for ISDN PPP CCP reset state timer
+  * Clean up and export cancel_dirty_page() to modules
+  * Fix reiserfs after "test_clear_page_dirty()" removal
+  * suspend: fix suspend on single-CPU systems
+  * arch/i386/pci/mmconfig.c tlb flush fix
+  * Fix up CIFS for "test_clear_page_dirty()" removal
+  * Linux 2.6.20-rc2
+
+ -- Ben Collins <bcollins@ubuntu.com>  Sat, 16 Dec 2006 01:56:51 -0500
+
 linux-source-2.6.20 (2.6.20-2.2) feisty; urgency=low
 
   [Ben Collins]
diff -ru 2.2/debian/config/amd64/config 3.4/debian/config/amd64/config
--- 2.2/debian/config/amd64/config	2006-12-14 05:14:06.000000000 +0100
+++ 3.4/debian/config/amd64/config	2006-12-25 20:43:05.000000000 +0100
@@ -1147,9 +1147,6 @@
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_JFFS2_SUMMARY is not set
 CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS_FS=m
-CONFIG_JFFS_FS_VERBOSE=0
-CONFIG_JFFS_PROC_FS=y
 # CONFIG_JFS_DEBUG is not set
 CONFIG_JFS_FS=m
 CONFIG_JFS_POSIX_ACL=y
@@ -2210,7 +2207,6 @@
 # CONFIG_SQUASHFS_VMALLOC is not set
 CONFIG_SSFDC=m
 CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_STACK_UNWIND=y
 CONFIG_STALDRV=y
 CONFIG_STANDALONE=y
 CONFIG_STOP_MACHINE=y
@@ -2298,7 +2294,6 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_UNUSED_SYMBOLS=y
-CONFIG_UNWIND_INFO=y
 CONFIG_USB=m
 CONFIG_USBPCWATCHDOG=m
 CONFIG_USB_ACECAD=m
@@ -2496,6 +2491,7 @@
 CONFIG_USB_USBNET=m
 CONFIG_USB_USBNET_MII=m
 CONFIG_USB_USS720=m
+CONFIG_USB_UVCCAM=m
 CONFIG_USB_VICAM=m
 CONFIG_USB_W9968CF=m
 CONFIG_USB_WACOM=m
@@ -2658,8 +2654,7 @@
 CONFIG_X86_PM_TIMER=y
 CONFIG_X86_POWERNOW_K8=m
 CONFIG_X86_POWERNOW_K8_ACPI=y
-CONFIG_X86_SPEEDSTEP_CENTRINO=m
-CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
 # CONFIG_X86_SPEEDSTEP_LIB is not set
 CONFIG_X86_TSC=y
 # CONFIG_X86_VSMP is not set
diff -ru 2.2/debian/config/i386/config 3.4/debian/config/i386/config
--- 2.2/debian/config/i386/config	2006-12-14 05:14:05.000000000 +0100
+++ 3.4/debian/config/i386/config	2006-12-25 20:43:03.000000000 +0100
@@ -1243,9 +1243,6 @@
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_JFFS2_SUMMARY is not set
 CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS_FS=m
-CONFIG_JFFS_FS_VERBOSE=0
-CONFIG_JFFS_PROC_FS=y
 # CONFIG_JFS_DEBUG is not set
 CONFIG_JFS_FS=m
 CONFIG_JFS_POSIX_ACL=y
@@ -2464,7 +2461,6 @@
 # CONFIG_SQUASHFS_VMALLOC is not set
 CONFIG_SSFDC=m
 CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_STACK_UNWIND=y
 CONFIG_STALDRV=y
 CONFIG_STANDALONE=y
 CONFIG_STRIP=m
@@ -2555,7 +2551,6 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_UNUSED_SYMBOLS=y
-CONFIG_UNWIND_INFO=y
 CONFIG_USB=m
 CONFIG_USBPCWATCHDOG=m
 CONFIG_USB_ACECAD=m
@@ -2753,6 +2748,7 @@
 CONFIG_USB_USBNET=m
 CONFIG_USB_USBNET_MII=m
 CONFIG_USB_USS720=m
+CONFIG_USB_UVCCAM=m
 CONFIG_USB_VICAM=m
 CONFIG_USB_W9968CF=m
 CONFIG_USB_WACOM=m
@@ -2936,9 +2932,7 @@
 CONFIG_X86_POWERNOW_K8_ACPI=y
 CONFIG_X86_PPRO_FENCE=y
 CONFIG_X86_REBOOTFIXUPS=y
-CONFIG_X86_SPEEDSTEP_CENTRINO=m
-CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
-CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
 CONFIG_X86_SPEEDSTEP_ICH=m
 CONFIG_X86_SPEEDSTEP_LIB=m
 CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y
diff -ru 2.2/debian/config/i386/vars.386 3.4/debian/config/i386/vars.386
--- 2.2/debian/config/i386/vars.386	2006-12-13 19:00:40.000000000 +0100
+++ 3.4/debian/config/i386/vars.386	2006-12-16 06:39:06.000000000 +0100
@@ -2,4 +2,4 @@
 target="Geared toward desktop systems."
 desc="i386"
 bootloader="lilo (>= 19.1) | grub"
-provides="ndiswrapper-modules-1.9"
+provides="ndiswrapper-modules-1.9, ivtv-modules"
diff -ru 2.2/debian/config/i386/vars.server-bigiron 3.4/debian/config/i386/vars.server-bigiron
--- 2.2/debian/config/i386/vars.server-bigiron	2006-12-13 19:00:40.000000000 +0100
+++ 3.4/debian/config/i386/vars.server-bigiron	2006-12-16 06:39:08.000000000 +0100
@@ -2,4 +2,4 @@
 target="Geared toward large server systems."
 desc="BigIron Server Equipment"
 bootloader="lilo (>= 19.1) | grub"
-provides="rhcs-modules2-1, ndiswrapper-modules-1.9"
+provides="rhcs-modules2-1, ndiswrapper-modules-1.9, ivtv-modules"
diff -ru 2.2/debian/config/ia64/config 3.4/debian/config/ia64/config
--- 2.2/debian/config/ia64/config	2006-12-14 05:14:06.000000000 +0100
+++ 3.4/debian/config/ia64/config	2006-12-25 20:43:06.000000000 +0100
@@ -977,9 +977,6 @@
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_JFFS2_SUMMARY is not set
 CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS_FS=m
-CONFIG_JFFS_FS_VERBOSE=0
-CONFIG_JFFS_PROC_FS=y
 CONFIG_JFS_DEBUG=y
 CONFIG_JFS_FS=m
 CONFIG_JFS_POSIX_ACL=y
@@ -2170,6 +2167,7 @@
 CONFIG_USB_USBNET=m
 CONFIG_USB_USBNET_MII=m
 CONFIG_USB_USS720=m
+CONFIG_USB_UVCCAM=m
 CONFIG_USB_VICAM=m
 CONFIG_USB_W9968CF=m
 CONFIG_USB_WACOM=m
diff -ru 2.2/debian/config/powerpc/config 3.4/debian/config/powerpc/config
--- 2.2/debian/config/powerpc/config	2006-12-14 05:14:08.000000000 +0100
+++ 3.4/debian/config/powerpc/config	2006-12-25 20:43:09.000000000 +0100
@@ -952,9 +952,6 @@
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_JFFS2_SUMMARY is not set
 CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS_FS=m
-CONFIG_JFFS_FS_VERBOSE=0
-CONFIG_JFFS_PROC_FS=y
 # CONFIG_JFS_DEBUG is not set
 CONFIG_JFS_FS=m
 CONFIG_JFS_POSIX_ACL=y
@@ -2202,6 +2199,7 @@
 CONFIG_USB_USBNET=m
 CONFIG_USB_USBNET_MII=m
 CONFIG_USB_USS720=m
+CONFIG_USB_UVCCAM=m
 CONFIG_USB_VICAM=m
 CONFIG_USB_W9968CF=m
 CONFIG_USB_WACOM=m
diff -ru 2.2/debian/config/sparc/config 3.4/debian/config/sparc/config
--- 2.2/debian/config/sparc/config	2006-12-14 05:14:09.000000000 +0100
+++ 3.4/debian/config/sparc/config	2006-12-25 20:43:10.000000000 +0100
@@ -1538,7 +1538,6 @@
 CONFIG_UNIX98_PTYS=y
 # CONFIG_UNIXWARE_DISKLABEL is not set
 CONFIG_UNUSED_SYMBOLS=y
-# CONFIG_UNWIND_INFO is not set
 CONFIG_USB=y
 CONFIG_USB_ACECAD=m
 # CONFIG_USB_ACM is not set
diff -ru 2.2/debian/config/vars.generic 3.4/debian/config/vars.generic
--- 2.2/debian/config/vars.generic	2006-12-07 02:52:09.000000000 +0100
+++ 3.4/debian/config/vars.generic	2006-12-16 06:34:39.000000000 +0100
@@ -3,4 +3,4 @@
 target="Geared toward desktop systems."
 desc="x86/x86_64"
 bootloader="lilo (>= 19.1) | grub"
-provides="ndiswrapper-modules-1.9"
+provides="ndiswrapper-modules-1.9, ivtv-modules"
diff -ru 2.2/debian/config/vars.lowlatency 3.4/debian/config/vars.lowlatency
--- 2.2/debian/config/vars.lowlatency	2006-12-07 02:52:09.000000000 +0100
+++ 3.4/debian/config/vars.lowlatency	2006-12-16 06:34:44.000000000 +0100
@@ -3,6 +3,6 @@
 target="Optimized for low latency requirements."
 desc="x86/x86_64"
 bootloader="lilo (>= 19.1) | grub"
-provides="ndiswrapper-modules-1.9"
+provides="ndiswrapper-modules-1.9, ivtv-modules"
 section_image="universe/admin"
 section_headers="devel"
diff -ru 2.2/debian/config/vars.server 3.4/debian/config/vars.server
--- 2.2/debian/config/vars.server	2006-12-07 02:52:09.000000000 +0100
+++ 3.4/debian/config/vars.server	2006-12-16 06:34:47.000000000 +0100
@@ -3,4 +3,4 @@
 target="Geared toward server systems."
 desc="x86/x86_64"
 bootloader="lilo (>= 19.1) | grub"
-provides="rhcs-modules2-1, ndiswrapper-modules-1.9"
+provides="rhcs-modules2-1, ndiswrapper-modules-1.9, ivtv-modules"
diff -ru 2.2/debian/control 3.4/debian/control
--- 2.2/debian/control	2006-12-16 05:38:15.000000000 +0100
+++ 3.4/debian/control	2006-12-26 00:27:06.000000000 +0100
@@ -59,7 +59,7 @@
  information about the problems, which may result by upgrading your
  kernel.
 
-Package: linux-headers-2.6.20-2
+Package: linux-headers-2.6.20-3
 Architecture: amd64 i386 powerpc sparc ia64 hppa
 Section: devel
 Priority: optional
@@ -68,7 +68,7 @@
 Description: Header files related to Linux kernel version 2.6.20
  This package provides kernel header files for version 2.6.20, for sites
  that want the latest kernel headers. Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details
 
 Package: linux-libc-dev
 Architecture: amd64 i386 powerpc sparc ia64 hppa
@@ -96,7 +96,7 @@
  Please read the information in /usr/share/doc/linux-image-kdump/
  for how to setup this kernel.
 
-Package: linux-image-2.6.20-2-hppa32
+Package: linux-image-2.6.20-3-hppa32
 Architecture: hppa
 Section: base
 Priority: optional
@@ -121,20 +121,20 @@
  the linux-hppa32 meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-hppa32
+Package: linux-headers-2.6.20-3-hppa32
 Architecture: hppa
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 32-bit HP PA-RISC SMP
  This package provides kernel header files for version 2.6.20 on
  32-bit HP PA-RISC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-hppa32
+Package: linux-image-debug-2.6.20-3-hppa32
 Architecture: hppa
 Section: devel
 Priority: optional
@@ -148,7 +148,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-hppa64
+Package: linux-image-2.6.20-3-hppa64
 Architecture: hppa
 Section: base
 Priority: optional
@@ -173,20 +173,20 @@
  the linux-hppa64 meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-hppa64
+Package: linux-headers-2.6.20-3-hppa64
 Architecture: hppa
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 64-bit HP PA-RISC SMP
  This package provides kernel header files for version 2.6.20 on
  64-bit HP PA-RISC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-hppa64
+Package: linux-image-debug-2.6.20-3-hppa64
 Architecture: hppa
 Section: devel
 Priority: optional
@@ -200,11 +200,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-386
+Package: linux-image-2.6.20-3-386
 Architecture: i386
 Section: base
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -225,20 +225,20 @@
  the linux-386 meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-386
+Package: linux-headers-2.6.20-3-386
 Architecture: i386
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on i386
  This package provides kernel header files for version 2.6.20 on
  i386.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-386
+Package: linux-image-debug-2.6.20-3-386
 Architecture: i386
 Section: devel
 Priority: optional
@@ -252,11 +252,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-server-bigiron
+Package: linux-image-2.6.20-3-server-bigiron
 Architecture: i386
 Section: base
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -277,20 +277,20 @@
  the linux-server-bigiron meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-server-bigiron
+Package: linux-headers-2.6.20-3-server-bigiron
 Architecture: i386
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on BigIron Server Equipment
  This package provides kernel header files for version 2.6.20 on
  BigIron Server Equipment.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-server-bigiron
+Package: linux-image-debug-2.6.20-3-server-bigiron
 Architecture: i386
 Section: devel
 Priority: optional
@@ -304,7 +304,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-itanium
+Package: linux-image-2.6.20-3-itanium
 Architecture: ia64
 Section: base
 Priority: optional
@@ -329,20 +329,20 @@
  the linux-itanium meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-itanium
+Package: linux-headers-2.6.20-3-itanium
 Architecture: ia64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on Itanium SMP
  This package provides kernel header files for version 2.6.20 on
  Itanium SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-itanium
+Package: linux-image-debug-2.6.20-3-itanium
 Architecture: ia64
 Section: devel
 Priority: optional
@@ -356,7 +356,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-mckinley
+Package: linux-image-2.6.20-3-mckinley
 Architecture: ia64
 Section: base
 Priority: optional
@@ -381,20 +381,20 @@
  the linux-mckinley meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-mckinley
+Package: linux-headers-2.6.20-3-mckinley
 Architecture: ia64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on Itanium II SMP
  This package provides kernel header files for version 2.6.20 on
  Itanium II SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-mckinley
+Package: linux-image-debug-2.6.20-3-mckinley
 Architecture: ia64
 Section: devel
 Priority: optional
@@ -408,7 +408,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-powerpc
+Package: linux-image-2.6.20-3-powerpc
 Architecture: powerpc
 Section: base
 Priority: optional
@@ -433,20 +433,20 @@
  the linux-powerpc meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-powerpc
+Package: linux-headers-2.6.20-3-powerpc
 Architecture: powerpc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 32-bit PowerPC
  This package provides kernel header files for version 2.6.20 on
  32-bit PowerPC.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-powerpc
+Package: linux-image-debug-2.6.20-3-powerpc
 Architecture: powerpc
 Section: devel
 Priority: optional
@@ -460,7 +460,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-powerpc-smp
+Package: linux-image-2.6.20-3-powerpc-smp
 Architecture: powerpc
 Section: base
 Priority: optional
@@ -485,20 +485,20 @@
  the linux-powerpc-smp meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-powerpc-smp
+Package: linux-headers-2.6.20-3-powerpc-smp
 Architecture: powerpc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 32-bit PowerPC SMP
  This package provides kernel header files for version 2.6.20 on
  32-bit PowerPC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-powerpc-smp
+Package: linux-image-debug-2.6.20-3-powerpc-smp
 Architecture: powerpc
 Section: devel
 Priority: optional
@@ -512,7 +512,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-powerpc64-smp
+Package: linux-image-2.6.20-3-powerpc64-smp
 Architecture: powerpc
 Section: base
 Priority: optional
@@ -537,20 +537,20 @@
  the linux-powerpc64-smp meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-powerpc64-smp
+Package: linux-headers-2.6.20-3-powerpc64-smp
 Architecture: powerpc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 64-bit PowerPC SMP
  This package provides kernel header files for version 2.6.20 on
  64-bit PowerPC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-powerpc64-smp
+Package: linux-image-debug-2.6.20-3-powerpc64-smp
 Architecture: powerpc
 Section: devel
 Priority: optional
@@ -564,7 +564,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-sparc64
+Package: linux-image-2.6.20-3-sparc64
 Architecture: sparc
 Section: base
 Priority: optional
@@ -589,20 +589,20 @@
  the linux-sparc64 meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-sparc64
+Package: linux-headers-2.6.20-3-sparc64
 Architecture: sparc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 64-bit UltraSPARC
  This package provides kernel header files for version 2.6.20 on
  64-bit UltraSPARC.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-sparc64
+Package: linux-image-debug-2.6.20-3-sparc64
 Architecture: sparc
 Section: devel
 Priority: optional
@@ -616,7 +616,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-sparc64-smp
+Package: linux-image-2.6.20-3-sparc64-smp
 Architecture: sparc
 Section: base
 Priority: optional
@@ -641,20 +641,20 @@
  the linux-sparc64-smp meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-sparc64-smp
+Package: linux-headers-2.6.20-3-sparc64-smp
 Architecture: sparc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 64-bit UltraSPARC SMP
  This package provides kernel header files for version 2.6.20 on
  64-bit UltraSPARC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-sparc64-smp
+Package: linux-image-debug-2.6.20-3-sparc64-smp
 Architecture: sparc
 Section: devel
 Priority: optional
@@ -668,11 +668,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-generic
+Package: linux-image-2.6.20-3-generic
 Architecture: i386 amd64
 Section: base
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -693,20 +693,20 @@
  the linux-generic meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-generic
+Package: linux-headers-2.6.20-3-generic
 Architecture: i386 amd64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on x86/x86_64
  This package provides kernel header files for version 2.6.20 on
  x86/x86_64.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-generic
+Package: linux-image-debug-2.6.20-3-generic
 Architecture: i386 amd64
 Section: devel
 Priority: optional
@@ -720,11 +720,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-lowlatency
+Package: linux-image-2.6.20-3-lowlatency
 Architecture: i386 amd64
 Section: universe/admin
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -745,20 +745,20 @@
  the linux-lowlatency meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-lowlatency
+Package: linux-headers-2.6.20-3-lowlatency
 Architecture: i386 amd64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on x86/x86_64
  This package provides kernel header files for version 2.6.20 on
  x86/x86_64.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-lowlatency
+Package: linux-image-debug-2.6.20-3-lowlatency
 Architecture: i386 amd64
 Section: devel
 Priority: optional
@@ -772,11 +772,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-server
+Package: linux-image-2.6.20-3-server
 Architecture: i386 amd64
 Section: base
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -797,20 +797,20 @@
  the linux-server meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-server
+Package: linux-headers-2.6.20-3-server
 Architecture: i386 amd64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on x86/x86_64
  This package provides kernel header files for version 2.6.20 on
  x86/x86_64.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-server
+Package: linux-image-debug-2.6.20-3-server
 Architecture: i386 amd64
 Section: devel
 Priority: optional
diff -ru 2.2/debian/control.stub 3.4/debian/control.stub
--- 2.2/debian/control.stub	2006-12-16 05:38:14.000000000 +0100
+++ 3.4/debian/control.stub	2006-12-26 00:27:03.000000000 +0100
@@ -59,7 +59,7 @@
  information about the problems, which may result by upgrading your
  kernel.
 
-Package: linux-headers-2.6.20-2
+Package: linux-headers-2.6.20-3
 Architecture: amd64 i386 powerpc sparc ia64 hppa
 Section: devel
 Priority: optional
@@ -68,7 +68,7 @@
 Description: Header files related to Linux kernel version 2.6.20
  This package provides kernel header files for version 2.6.20, for sites
  that want the latest kernel headers. Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details
 
 Package: linux-libc-dev
 Architecture: amd64 i386 powerpc sparc ia64 hppa
@@ -96,7 +96,7 @@
  Please read the information in /usr/share/doc/linux-image-kdump/
  for how to setup this kernel.
 
-Package: linux-image-2.6.20-2-hppa32
+Package: linux-image-2.6.20-3-hppa32
 Architecture: hppa
 Section: base
 Priority: optional
@@ -121,20 +121,20 @@
  the linux-hppa32 meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-hppa32
+Package: linux-headers-2.6.20-3-hppa32
 Architecture: hppa
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 32-bit HP PA-RISC SMP
  This package provides kernel header files for version 2.6.20 on
  32-bit HP PA-RISC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-hppa32
+Package: linux-image-debug-2.6.20-3-hppa32
 Architecture: hppa
 Section: devel
 Priority: optional
@@ -148,7 +148,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-hppa64
+Package: linux-image-2.6.20-3-hppa64
 Architecture: hppa
 Section: base
 Priority: optional
@@ -173,20 +173,20 @@
  the linux-hppa64 meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-hppa64
+Package: linux-headers-2.6.20-3-hppa64
 Architecture: hppa
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 64-bit HP PA-RISC SMP
  This package provides kernel header files for version 2.6.20 on
  64-bit HP PA-RISC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-hppa64
+Package: linux-image-debug-2.6.20-3-hppa64
 Architecture: hppa
 Section: devel
 Priority: optional
@@ -200,11 +200,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-386
+Package: linux-image-2.6.20-3-386
 Architecture: i386
 Section: base
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -225,20 +225,20 @@
  the linux-386 meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-386
+Package: linux-headers-2.6.20-3-386
 Architecture: i386
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on i386
  This package provides kernel header files for version 2.6.20 on
  i386.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-386
+Package: linux-image-debug-2.6.20-3-386
 Architecture: i386
 Section: devel
 Priority: optional
@@ -252,11 +252,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-server-bigiron
+Package: linux-image-2.6.20-3-server-bigiron
 Architecture: i386
 Section: base
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -277,20 +277,20 @@
  the linux-server-bigiron meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-server-bigiron
+Package: linux-headers-2.6.20-3-server-bigiron
 Architecture: i386
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on BigIron Server Equipment
  This package provides kernel header files for version 2.6.20 on
  BigIron Server Equipment.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-server-bigiron
+Package: linux-image-debug-2.6.20-3-server-bigiron
 Architecture: i386
 Section: devel
 Priority: optional
@@ -304,7 +304,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-itanium
+Package: linux-image-2.6.20-3-itanium
 Architecture: ia64
 Section: base
 Priority: optional
@@ -329,20 +329,20 @@
  the linux-itanium meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-itanium
+Package: linux-headers-2.6.20-3-itanium
 Architecture: ia64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on Itanium SMP
  This package provides kernel header files for version 2.6.20 on
  Itanium SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-itanium
+Package: linux-image-debug-2.6.20-3-itanium
 Architecture: ia64
 Section: devel
 Priority: optional
@@ -356,7 +356,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-mckinley
+Package: linux-image-2.6.20-3-mckinley
 Architecture: ia64
 Section: base
 Priority: optional
@@ -381,20 +381,20 @@
  the linux-mckinley meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-mckinley
+Package: linux-headers-2.6.20-3-mckinley
 Architecture: ia64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on Itanium II SMP
  This package provides kernel header files for version 2.6.20 on
  Itanium II SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-mckinley
+Package: linux-image-debug-2.6.20-3-mckinley
 Architecture: ia64
 Section: devel
 Priority: optional
@@ -408,7 +408,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-powerpc
+Package: linux-image-2.6.20-3-powerpc
 Architecture: powerpc
 Section: base
 Priority: optional
@@ -433,20 +433,20 @@
  the linux-powerpc meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-powerpc
+Package: linux-headers-2.6.20-3-powerpc
 Architecture: powerpc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 32-bit PowerPC
  This package provides kernel header files for version 2.6.20 on
  32-bit PowerPC.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-powerpc
+Package: linux-image-debug-2.6.20-3-powerpc
 Architecture: powerpc
 Section: devel
 Priority: optional
@@ -460,7 +460,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-powerpc-smp
+Package: linux-image-2.6.20-3-powerpc-smp
 Architecture: powerpc
 Section: base
 Priority: optional
@@ -485,20 +485,20 @@
  the linux-powerpc-smp meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-powerpc-smp
+Package: linux-headers-2.6.20-3-powerpc-smp
 Architecture: powerpc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 32-bit PowerPC SMP
  This package provides kernel header files for version 2.6.20 on
  32-bit PowerPC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-powerpc-smp
+Package: linux-image-debug-2.6.20-3-powerpc-smp
 Architecture: powerpc
 Section: devel
 Priority: optional
@@ -512,7 +512,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-powerpc64-smp
+Package: linux-image-2.6.20-3-powerpc64-smp
 Architecture: powerpc
 Section: base
 Priority: optional
@@ -537,20 +537,20 @@
  the linux-powerpc64-smp meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-powerpc64-smp
+Package: linux-headers-2.6.20-3-powerpc64-smp
 Architecture: powerpc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 64-bit PowerPC SMP
  This package provides kernel header files for version 2.6.20 on
  64-bit PowerPC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-powerpc64-smp
+Package: linux-image-debug-2.6.20-3-powerpc64-smp
 Architecture: powerpc
 Section: devel
 Priority: optional
@@ -564,7 +564,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-sparc64
+Package: linux-image-2.6.20-3-sparc64
 Architecture: sparc
 Section: base
 Priority: optional
@@ -589,20 +589,20 @@
  the linux-sparc64 meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-sparc64
+Package: linux-headers-2.6.20-3-sparc64
 Architecture: sparc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 64-bit UltraSPARC
  This package provides kernel header files for version 2.6.20 on
  64-bit UltraSPARC.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-sparc64
+Package: linux-image-debug-2.6.20-3-sparc64
 Architecture: sparc
 Section: devel
 Priority: optional
@@ -616,7 +616,7 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-sparc64-smp
+Package: linux-image-2.6.20-3-sparc64-smp
 Architecture: sparc
 Section: base
 Priority: optional
@@ -641,20 +641,20 @@
  the linux-sparc64-smp meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-sparc64-smp
+Package: linux-headers-2.6.20-3-sparc64-smp
 Architecture: sparc
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on 64-bit UltraSPARC SMP
  This package provides kernel header files for version 2.6.20 on
  64-bit UltraSPARC SMP.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-sparc64-smp
+Package: linux-image-debug-2.6.20-3-sparc64-smp
 Architecture: sparc
 Section: devel
 Priority: optional
@@ -668,11 +668,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-generic
+Package: linux-image-2.6.20-3-generic
 Architecture: i386 amd64
 Section: base
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -693,20 +693,20 @@
  the linux-generic meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-generic
+Package: linux-headers-2.6.20-3-generic
 Architecture: i386 amd64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on x86/x86_64
  This package provides kernel header files for version 2.6.20 on
  x86/x86_64.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-generic
+Package: linux-image-debug-2.6.20-3-generic
 Architecture: i386 amd64
 Section: devel
 Priority: optional
@@ -720,11 +720,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-lowlatency
+Package: linux-image-2.6.20-3-lowlatency
 Architecture: i386 amd64
 Section: universe/admin
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -745,20 +745,20 @@
  the linux-lowlatency meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-lowlatency
+Package: linux-headers-2.6.20-3-lowlatency
 Architecture: i386 amd64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on x86/x86_64
  This package provides kernel header files for version 2.6.20 on
  x86/x86_64.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-lowlatency
+Package: linux-image-debug-2.6.20-3-lowlatency
 Architecture: i386 amd64
 Section: devel
 Priority: optional
@@ -772,11 +772,11 @@
  The kernel image contained in this package is NOT meant to boot from. It
  is uncompressed, and unstripped.
 
-Package: linux-image-2.6.20-2-server
+Package: linux-image-2.6.20-3-server
 Architecture: i386 amd64
 Section: base
 Priority: optional
-Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ndiswrapper-modules-1.9
+Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ndiswrapper-modules-1.9, ivtv-modules
 Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1)
 Conflicts: hotplug (<< 0.0.20040105-1)
 Recommends: lilo (>= 19.1) | grub
@@ -797,20 +797,20 @@
  the linux-server meta-package, which will ensure that upgrades work
  correctly, and that supporting packages are also installed.
 
-Package: linux-headers-2.6.20-2-server
+Package: linux-headers-2.6.20-3-server
 Architecture: i386 amd64
 Section: devel
 Priority: optional
-Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-2, ${shlibs:Depends}
+Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.20-3, ${shlibs:Depends}
 Provides: linux-headers, linux-headers-2.6
 Description: Linux kernel headers for version 2.6.20 on x86/x86_64
  This package provides kernel header files for version 2.6.20 on
  x86/x86_64.
  .
  This is for sites that want the latest kernel headers.  Please read
- /usr/share/doc/linux-headers-2.6.20-2/debian.README.gz for details.
+ /usr/share/doc/linux-headers-2.6.20-3/debian.README.gz for details.
 
-Package: linux-image-debug-2.6.20-2-server
+Package: linux-image-debug-2.6.20-3-server
 Architecture: i386 amd64
 Section: devel
 Priority: optional
diff -ru 2.2/debian/d-i/kernel-versions 3.4/debian/d-i/kernel-versions
--- 2.2/debian/d-i/kernel-versions	2006-12-16 05:38:13.000000000 +0100
+++ 3.4/debian/d-i/kernel-versions	2006-12-26 00:27:03.000000000 +0100
@@ -1,15 +1,15 @@
 # arch	version		flavour		installedname			suffix	bdep
-amd64	2.6.20-2	generic		2.6.20-2-generic		-	
+amd64	2.6.20-3	generic		2.6.20-3-generic		-	
 
-hppa	2.6.20-2	hppa32		2.6.20-2-hppa32		y	
-hppa	2.6.20-2	hppa64		2.6.20-2-hppa64		y	
+hppa	2.6.20-3	hppa32		2.6.20-3-hppa32		y	
+hppa	2.6.20-3	hppa64		2.6.20-3-hppa64		y	
 
-i386	2.6.20-2	386		2.6.20-2-386		-	
-i386	2.6.20-2	generic		2.6.20-2-generic		-	
+i386	2.6.20-3	386		2.6.20-3-386		-	
+i386	2.6.20-3	generic		2.6.20-3-generic		-	
 
-ia64	2.6.20-2	itanium		2.6.20-2-itanium		-	
+ia64	2.6.20-3	itanium		2.6.20-3-itanium		-	
 
-powerpc	2.6.20-2	powerpc		2.6.20-2-powerpc		-	
-powerpc	2.6.20-2	powerpc64-smp	2.6.20-2-powerpc64-smp	-	
+powerpc	2.6.20-3	powerpc		2.6.20-3-powerpc		-	
+powerpc	2.6.20-3	powerpc64-smp	2.6.20-3-powerpc64-smp	-	
 
-sparc	2.6.20-2	sparc64		2.6.20-2-sparc64		-	
+sparc	2.6.20-3	sparc64		2.6.20-3-sparc64		-	
Only in 3.4/debian/firmware: ivtv
diff -ru 2.2/debian/rules 3.4/debian/rules
--- 2.2/debian/rules	2006-12-13 06:30:13.000000000 +0100
+++ 3.4/debian/rules	2006-12-25 23:21:43.000000000 +0100
@@ -468,8 +468,6 @@
 	  dpkg -x $$(ls debian/build/$(stem)-image-$$i\_*${arch}.deb) debian/d-i-${arch}; \
 	done
 
-	kernel-wedge make-links
-
 	export SOURCEDIR=debian/d-i-${arch} && \
 	  kernel-wedge install-files && \
 	  kernel-wedge check
@@ -508,6 +506,9 @@
 	@echo "  help            : If you are kernel hacking, you need the professional"
 	@echo "                    version of this"
 	@echo
+	@echo "Environment variables:"
+	@echo
+	@echo "  NOKERNLOG       : Do not add upstream kernel commits to changelog"
 
 updateconfigs:
 	dh_testdir
diff -ru 2.2/Documentation/block/biodoc.txt 3.4/Documentation/block/biodoc.txt
--- 2.2/Documentation/block/biodoc.txt	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/Documentation/block/biodoc.txt	2006-12-22 01:57:07.000000000 +0100
@@ -946,6 +946,13 @@
 				scheduler for example, to reposition the request
 				if its sorting order has changed.
 
+elevator_allow_merge_fn		called whenever the block layer determines
+				that a bio can be merged into an existing
+				request safely. The io scheduler may still
+				want to stop a merge at this point if it
+				results in some sort of conflict internally,
+				this hook allows it to do that.
+
 elevator_dispatch_fn		fills the dispatch queue with ready requests.
 				I/O schedulers are free to postpone requests by
 				not filling the dispatch queue unless @force
diff -ru 2.2/Documentation/CodingStyle 3.4/Documentation/CodingStyle
--- 2.2/Documentation/CodingStyle	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/Documentation/CodingStyle	2006-12-23 01:11:19.000000000 +0100
@@ -682,6 +682,24 @@
 NULL or the ERR_PTR mechanism to report failure.
 
 
+		Chapter 17:  Don't re-invent the kernel macros
+
+The header file include/linux/kernel.h contains a number of macros that
+you should use, rather than explicitly coding some variant of them yourself.
+For example, if you need to calculate the length of an array, take advantage
+of the macro
+
+  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+Similarly, if you need to calculate the size of some structure member, use
+
+  #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+
+There are also min() and max() macros that do strict type checking if you
+need them.  Feel free to peruse that header file to see what else is already
+defined that you shouldn't reproduce in your code.
+
+
 
 		Appendix I: References
 
diff -ru 2.2/Documentation/DocBook/genericirq.tmpl 3.4/Documentation/DocBook/genericirq.tmpl
--- 2.2/Documentation/DocBook/genericirq.tmpl	2006-10-02 17:39:09.000000000 +0200
+++ 3.4/Documentation/DocBook/genericirq.tmpl	2006-12-18 04:27:33.000000000 +0100
@@ -303,10 +303,10 @@
 do {
 	if (desc->status &amp; masked)
 		desc->chip->enable();
-	desc-status &amp;= ~pending;
+	desc->status &amp;= ~pending;
 	handle_IRQ_event(desc->action);
 } while (status &amp; pending);
-desc-status &amp;= ~running;
+desc->status &amp;= ~running;
 desc->chip->end();
 		</programlisting>
 		</para>
diff -ru 2.2/Documentation/ibm-acpi.txt 3.4/Documentation/ibm-acpi.txt
--- 2.2/Documentation/ibm-acpi.txt	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/Documentation/ibm-acpi.txt	2006-12-23 16:57:57.000000000 +0100
@@ -398,25 +398,67 @@
 
 Most ThinkPads include six or more separate temperature sensors but
 only expose the CPU temperature through the standard ACPI methods.
-This feature shows readings from up to eight different sensors. Some
-readings may not be valid, e.g. may show large negative values. For
-example, on the X40, a typical output may be:
+This feature shows readings from up to eight different sensors on older
+ThinkPads, and it has experimental support for up to sixteen different
+sensors on newer ThinkPads.  Readings from sensors that are not available
+return -128.
 
+No commands can be written to this file.
+
+EXPERIMENTAL: The 16-sensors feature is marked EXPERIMENTAL because the
+implementation directly accesses hardware registers and may not work as
+expected. USE WITH CAUTION! To use this feature, you need to supply the
+experimental=1 parameter when loading the module.  When EXPERIMENTAL
+mode is enabled, reading the first 8 sensors on newer ThinkPads will
+also use an new experimental thermal sensor access mode.
+
+For example, on the X40, a typical output may be:
 temperatures:   42 42 45 41 36 -128 33 -128
 
-Thomas Gruber took his R51 apart and traced all six active sensors in
-his laptop (the location of sensors may vary on other models):
+EXPERIMENTAL: On the T43/p, a typical output may be:
+temperatures:   48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128
+
+The mapping of thermal sensors to physical locations varies depending on
+system-board model (and thus, on ThinkPad model).
+
+http://thinkwiki.org/wiki/Thermal_Sensors is a public wiki page that
+tries to track down these locations for various models.
+
+Most (newer?) models seem to follow this pattern:
 
 1:  CPU
-2:  Mini PCI Module
-3:  HDD
+2:  (depends on model)
+3:  (depends on model)
 4:  GPU
-5:  Battery
-6:  N/A
-7:  Battery
-8:  N/A
+5:  Main battery: main sensor
+6:  Bay battery: main sensor
+7:  Main battery: secondary sensor
+8:  Bay battery: secondary sensor
+9-15: (depends on model)
+
+For the R51 (source: Thomas Gruber):
+2:  Mini-PCI
+3:  Internal HDD
+
+For the T43, T43/p (source: Shmidoax/Thinkwiki.org)
+http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p
+2:  System board, left side (near PCMCIA slot), reported as HDAPS temp
+3:  PCMCIA slot
+9:  MCH (northbridge) to DRAM Bus
+10: ICH (southbridge), under Mini-PCI card, under touchpad
+11: Power regulator, underside of system board, below F2 key
+
+The A31 has a very atypical layout for the thermal sensors
+(source: Milos Popovic, http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_A31)
+1:  CPU
+2:  Main Battery: main sensor
+3:  Power Converter
+4:  Bay Battery: main sensor
+5:  MCH (northbridge)
+6:  PCMCIA/ambient
+7:  Main Battery: secondary sensor
+8:  Bay Battery: secondary sensor
 
-No commands can be written to this file.
 
 EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump
 ------------------------------------------------------------------------
@@ -529,27 +571,57 @@
 WITH CAUTION! To use this feature, you need to supply the
 experimental=1 parameter when loading the module.
 
-This feature attempts to show the current fan speed. The speed is read
-directly from the hardware registers of the embedded controller. This
-is known to work on later R, T and X series ThinkPads but may show a
-bogus value on other models.
+This feature attempts to show the current fan speed, control mode and
+other fan data that might be available.  The speed is read directly
+from the hardware registers of the embedded controller.  This is known
+to work on later R, T and X series ThinkPads but may show a bogus
+value on other models.
+
+Most ThinkPad fans work in "levels".  Level 0 stops the fan.  The higher
+the level, the higher the fan speed, although adjacent levels often map
+to the same fan speed.  7 is the highest level, where the fan reaches
+the maximum recommended speed.  Level "auto" means the EC changes the
+fan level according to some internal algorithm, usually based on
+readings from the thermal sensors.  Level "disengaged" means the EC
+disables the speed-locked closed-loop fan control, and drives the fan as
+fast as it can go, which might exceed hardware limits, so use this level
+with caution.
+
+The fan usually ramps up or down slowly from one speed to another,
+and it is normal for the EC to take several seconds to react to fan
+commands.
 
 The fan may be enabled or disabled with the following commands:
 
 	echo enable  >/proc/acpi/ibm/fan
 	echo disable >/proc/acpi/ibm/fan
 
+Placing a fan on level 0 is the same as disabling it.  Enabling a fan
+will try to place it in a safe level if it is too slow or disabled.
+
 WARNING WARNING WARNING: do not leave the fan disabled unless you are
-monitoring the temperature sensor readings and you are ready to enable
-it if necessary to avoid overheating.
+monitoring all of the temperature sensor readings and you are ready to
+enable it if necessary to avoid overheating.
+
+An enabled fan in level "auto" may stop spinning if the EC decides the
+ThinkPad is cool enough and doesn't need the extra airflow.  This is
+normal, and the EC will spin the fan up if the varios thermal readings
+rise too much.
+
+On the X40, this seems to depend on the CPU and HDD temperatures.
+Specifically, the fan is turned on when either the CPU temperature
+climbs to 56 degrees or the HDD temperature climbs to 46 degrees.  The
+fan is turned off when the CPU temperature drops to 49 degrees and the
+HDD temperature drops to 41 degrees.  These thresholds cannot
+currently be controlled.
+
+The fan level can be controlled with the command:
+
+	echo 'level <level>' > /proc/acpi/ibm/thermal
 
-The fan only runs if it's enabled *and* the various temperature
-sensors which control it read high enough. On the X40, this seems to
-depend on the CPU and HDD temperatures. Specifically, the fan is
-turned on when either the CPU temperature climbs to 56 degrees or the
-HDD temperature climbs to 46 degrees. The fan is turned off when the
-CPU temperature drops to 49 degrees and the HDD temperature drops to
-41 degrees. These thresholds cannot currently be controlled.
+Where <level> is an integer from 0 to 7, or one of the words "auto"
+or "disengaged" (without the quotes).  Not all ThinkPads support the
+"auto" and "disengaged" levels.
 
 On the X31 and X40 (and ONLY on those models), the fan speed can be
 controlled to a certain degree. Once the fan is running, it can be
@@ -562,12 +634,9 @@
 any effect or the fan speed eventually settles somewhere in that
 range. The fan cannot be stopped or started with this command.
 
-On the 570, temperature readings are not available through this
-feature and the fan control works a little differently. The fan speed
-is reported in levels from 0 (off) to 7 (max) and can be controlled
-with the following command:
-
-	echo 'level <level>' > /proc/acpi/ibm/thermal
+The ThinkPad's ACPI DSDT code will reprogram the fan on its own when
+certain conditions are met.  It will override any fan programming done
+through ibm-acpi.
 
 EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
 ---------------------------------------
@@ -601,6 +670,26 @@
 
 	modprobe ibm_acpi hotkey=enable,0xffff video=auto_disable
 
+The ibm-acpi kernel driver can be programmed to revert the fan level
+to a safe setting if userspace does not issue one of the fan commands:
+"enable", "disable", "level" or "watchdog" within a configurable
+ammount of time.  To do this, use the "watchdog" command.
+
+	echo 'watchdog <interval>' > /proc/acpi/ibm/fan
+
+Interval is the ammount of time in seconds to wait for one of the
+above mentioned fan commands before reseting the fan level to a safe
+one.  If set to zero, the watchdog is disabled (default).  When the
+watchdog timer runs out, it does the exact equivalent of the "enable"
+fan command.
+
+Note that the watchdog timer stops after it enables the fan.  It will
+be rearmed again automatically (using the same interval) when one of
+the above mentioned fan commands is received.  The fan watchdog is,
+therefore, not suitable to protect against fan mode changes made
+through means other than the "enable", "disable", and "level" fan
+commands.
+
 
 Example Configuration
 ---------------------
diff -ru 2.2/Documentation/kernel-parameters.txt 3.4/Documentation/kernel-parameters.txt
--- 2.2/Documentation/kernel-parameters.txt	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/Documentation/kernel-parameters.txt	2006-12-22 01:57:07.000000000 +0100
@@ -1714,6 +1714,14 @@
 	uart6850=	[HW,OSS]
 			Format: <io>,<irq>
 
+	uhci-hcd.ignore_oc=
+			[USB] Ignore overcurrent events (default N).
+			Some badly-designed motherboards generate lots of
+			bogus events, for ports that aren't wired to
+			anything.  Set this parameter to avoid log spamming.
+			Note that genuine overcurrent events won't be
+			reported either.
+
 	usbhid.mousepoll=
 			[USBHID] The interval which mice are to be polled at.
 
diff -ru 2.2/Documentation/powerpc/booting-without-of.txt 3.4/Documentation/powerpc/booting-without-of.txt
--- 2.2/Documentation/powerpc/booting-without-of.txt	2006-12-07 02:52:08.000000000 +0100
+++ 3.4/Documentation/powerpc/booting-without-of.txt	2006-12-22 01:57:07.000000000 +0100
@@ -1703,29 +1703,32 @@
     Required properties:
 
      - device_type : has to be "rom"
-     - compatible : Should specify what this ROM device is compatible with
-       (i.e. "onenand"). Currently, this is most likely to be "direct-mapped"
-       (which corresponds to the MTD physmap mapping driver).
-     - regs : Offset and length of the register set (or memory mapping) for
+     - compatible : Should specify what this flash device is compatible with.
+       Currently, this is most likely to be "direct-mapped" (which
+       corresponds to the MTD physmap mapping driver).
+     - reg : Offset and length of the register set (or memory mapping) for
        the device.
+     - bank-width : Width of the flash data bus in bytes. Required
+       for the NOR flashes (compatible == "direct-mapped" and others) ONLY.
 
     Recommended properties :
 
-     - bank-width : Width of the flash data bus in bytes. Required
-       for the NOR flashes (compatible == "direct-mapped" and others) ONLY.
      - partitions : Several pairs of 32-bit values where the first value is
        partition's offset from the start of the device and the second one is
        partition size in bytes with LSB used to signify a read only
-       partititon (so, the parition size should always be an even number).
+       partition (so, the parition size should always be an even number).
      - partition-names : The list of concatenated zero terminated strings
        representing the partition names.
+     - probe-type : The type of probe which should be done for the chip
+       (JEDEC vs CFI actually). Valid ONLY for NOR flashes.
 
    Example:
 
  	flash@ff000000 {
  		device_type = "rom";
  		compatible = "direct-mapped";
- 		regs = <ff000000 01000000>;
+ 		probe-type = "CFI";
+ 		reg = <ff000000 01000000>;
  		bank-width = <4>;
  		partitions = <00000000 00f80000
  			      00f80000 00080001>;
diff -ru 2.2/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl 3.4/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
--- 2.2/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	2006-10-04 18:55:36.000000000 +0200
+++ 3.4/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	2006-12-22 01:57:07.000000000 +0100
@@ -927,7 +927,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  struct mychip *chip = (struct mychip *)card->private_data;
+  struct mychip *chip = card->private_data;
 ]]>
             </programlisting>
           </informalexample>
@@ -1095,7 +1095,7 @@
 
           /* release the irq */
           if (chip->irq >= 0)
-                  free_irq(chip->irq, (void *)chip);
+                  free_irq(chip->irq, chip);
           /* release the i/o ports & memory */
           pci_release_regions(chip->pci);
           /* disable the PCI entry */
@@ -1148,7 +1148,7 @@
           }
           chip->port = pci_resource_start(pci, 0);
           if (request_irq(pci->irq, snd_mychip_interrupt,
-                          IRQF_DISABLED|IRQF_SHARED, "My Chip", chip)) {
+                          IRQF_SHARED, "My Chip", chip)) {
                   printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
                   snd_mychip_free(chip);
                   return -EBUSY;
@@ -1387,7 +1387,7 @@
           <programlisting>
 <![CDATA[
   if (chip->irq >= 0)
-          free_irq(chip->irq, (void *)chip);
+          free_irq(chip->irq, chip);
 ]]>
           </programlisting>
         </informalexample>
Only in 2.2/: .dotest
diff -ru 2.2/drivers/acpi/ac.c 3.4/drivers/acpi/ac.c
--- 2.2/drivers/acpi/ac.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/ac.c	2006-12-23 16:57:57.000000000 +0100
@@ -109,7 +109,7 @@
 
 static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_ac *ac = (struct acpi_ac *)seq->private;
+	struct acpi_ac *ac = seq->private;
 
 
 	if (!ac)
@@ -187,7 +187,7 @@
 
 static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_ac *ac = (struct acpi_ac *)data;
+	struct acpi_ac *ac = data;
 	struct acpi_device *device = NULL;
 
 
@@ -221,10 +221,9 @@
 	if (!device)
 		return -EINVAL;
 
-	ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL);
+	ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
 	if (!ac)
 		return -ENOMEM;
-	memset(ac, 0, sizeof(struct acpi_ac));
 
 	ac->device = device;
 	strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
@@ -269,7 +268,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	ac = (struct acpi_ac *)acpi_driver_data(device);
+	ac = acpi_driver_data(device);
 
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_ALL_NOTIFY, acpi_ac_notify);
diff -ru 2.2/drivers/acpi/acpi_memhotplug.c 3.4/drivers/acpi/acpi_memhotplug.c
--- 2.2/drivers/acpi/acpi_memhotplug.c	2006-10-20 23:43:44.000000000 +0200
+++ 3.4/drivers/acpi/acpi_memhotplug.c	2006-12-23 16:57:57.000000000 +0100
@@ -395,10 +395,9 @@
 	if (!device)
 		return -EINVAL;
 
-	mem_device = kmalloc(sizeof(struct acpi_memory_device), GFP_KERNEL);
+	mem_device = kzalloc(sizeof(struct acpi_memory_device), GFP_KERNEL);
 	if (!mem_device)
 		return -ENOMEM;
-	memset(mem_device, 0, sizeof(struct acpi_memory_device));
 
 	INIT_LIST_HEAD(&mem_device->res_list);
 	mem_device->device = device;
@@ -429,7 +428,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	mem_device = (struct acpi_memory_device *)acpi_driver_data(device);
+	mem_device = acpi_driver_data(device);
 	kfree(mem_device);
 
 	return 0;
diff -ru 2.2/drivers/acpi/asus_acpi.c 3.4/drivers/acpi/asus_acpi.c
--- 2.2/drivers/acpi/asus_acpi.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/acpi/asus_acpi.c	2006-12-23 16:57:57.000000000 +0100
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
+#include <linux/backlight.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 #include <asm/uaccess.h>
@@ -402,6 +403,8 @@
 /* procdir we use */
 static struct proc_dir_entry *asus_proc_dir;
 
+static struct backlight_device *asus_backlight_device;
+
 /*
  * This header is made available to allow proper configuration given model,
  * revision number , ... this info cannot go in struct asus_hotk because it is
@@ -779,7 +782,7 @@
 	return rv;
 }
 
-static int read_brightness(void)
+static int read_brightness(struct backlight_device *bd)
 {
 	int value;
 
@@ -801,9 +804,10 @@
 /*
  * Change the brightness level
  */
-static void set_brightness(int value)
+static int set_brightness(int value)
 {
 	acpi_status status = 0;
+	int ret = 0;
 
 	/* SPLV laptop */
 	if (hotk->methods->brightness_set) {
@@ -811,11 +815,12 @@
 				    value, NULL))
 			printk(KERN_WARNING
 			       "Asus ACPI: Error changing brightness\n");
-		return;
+			ret = -EIO;
+		goto out;
 	}
 
 	/* No SPLV method if we are here, act as appropriate */
-	value -= read_brightness();
+	value -= read_brightness(NULL);
 	while (value != 0) {
 		status = acpi_evaluate_object(NULL, (value > 0) ?
 					      hotk->methods->brightness_up :
@@ -825,15 +830,22 @@
 		if (ACPI_FAILURE(status))
 			printk(KERN_WARNING
 			       "Asus ACPI: Error changing brightness\n");
+			ret = -EIO;
 	}
-	return;
+out:
+	return ret;
+}
+
+static int set_brightness_status(struct backlight_device *bd)
+{
+	return set_brightness(bd->props->brightness);
 }
 
 static int
 proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
 	      void *data)
 {
-	return sprintf(page, "%d\n", read_brightness());
+	return sprintf(page, "%d\n", read_brightness(NULL));
 }
 
 static int
@@ -1134,7 +1146,7 @@
 	if (ACPI_FAILURE(status))
 		printk(KERN_WARNING "  Couldn't get the DSDT table header\n");
 	else
-		asus_info = (struct acpi_table_header *)dsdt.pointer;
+		asus_info = dsdt.pointer;
 
 	/* We have to write 0 on init this far for all ASUS models */
 	if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
@@ -1156,7 +1168,7 @@
 	 * asus_model_match() and try something completely different.
 	 */
 	if (buffer.pointer) {
-		model = (union acpi_object *)buffer.pointer;
+		model = buffer.pointer;
 		switch (model->type) {
 		case ACPI_TYPE_STRING:
 			string = model->string.pointer;
@@ -1252,11 +1264,9 @@
 	printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
 	       ASUS_ACPI_VERSION);
 
-	hotk =
-	    (struct asus_hotk *)kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
+	hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL);
 	if (!hotk)
 		return -ENOMEM;
-	memset(hotk, 0, sizeof(struct asus_hotk));
 
 	hotk->handle = device->handle;
 	strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME);
@@ -1333,6 +1343,26 @@
 	return 0;
 }
 
+static struct backlight_properties asus_backlight_data = {
+        .owner          = THIS_MODULE,
+        .get_brightness = read_brightness,
+        .update_status  = set_brightness_status,
+        .max_brightness = 15,
+};
+
+static void __exit asus_acpi_exit(void)
+{
+	if (asus_backlight_device)
+		backlight_device_unregister(asus_backlight_device);
+
+	acpi_bus_unregister_driver(&asus_hotk_driver);
+	remove_proc_entry(PROC_ASUS, acpi_root_dir);
+
+	kfree(asus_info);
+
+	return;
+}
+
 static int __init asus_acpi_init(void)
 {
 	int result;
@@ -1370,17 +1400,15 @@
 		return result;
 	}
 
-	return 0;
-}
-
-static void __exit asus_acpi_exit(void)
-{
-	acpi_bus_unregister_driver(&asus_hotk_driver);
-	remove_proc_entry(PROC_ASUS, acpi_root_dir);
-
-	kfree(asus_info);
+	asus_backlight_device = backlight_device_register("asus",NULL,NULL,
+							  &asus_backlight_data);
+        if (IS_ERR(asus_backlight_device)) {
+		printk(KERN_ERR "Could not register asus backlight device\n");
+		asus_backlight_device = NULL;
+		asus_acpi_exit();
+	}
 
-	return;
+	return 0;
 }
 
 module_init(asus_acpi_init);
diff -ru 2.2/drivers/acpi/battery.c 3.4/drivers/acpi/battery.c
--- 2.2/drivers/acpi/battery.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/acpi/battery.c	2006-12-23 16:57:57.000000000 +0100
@@ -149,7 +149,7 @@
 		return -ENODEV;
 	}
 
-	package = (union acpi_object *)buffer.pointer;
+	package = buffer.pointer;
 
 	/* Extract Package Data */
 
@@ -160,12 +160,11 @@
 		goto end;
 	}
 
-	data.pointer = kmalloc(data.length, GFP_KERNEL);
+	data.pointer = kzalloc(data.length, GFP_KERNEL);
 	if (!data.pointer) {
 		result = -ENOMEM;
 		goto end;
 	}
-	memset(data.pointer, 0, data.length);
 
 	status = acpi_extract_package(package, &format, &data);
 	if (ACPI_FAILURE(status)) {
@@ -179,7 +178,7 @@
 	kfree(buffer.pointer);
 
 	if (!result)
-		(*bif) = (struct acpi_battery_info *)data.pointer;
+		(*bif) = data.pointer;
 
 	return result;
 }
@@ -209,7 +208,7 @@
 		return -ENODEV;
 	}
 
-	package = (union acpi_object *)buffer.pointer;
+	package = buffer.pointer;
 
 	/* Extract Package Data */
 
@@ -220,12 +219,11 @@
 		goto end;
 	}
 
-	data.pointer = kmalloc(data.length, GFP_KERNEL);
+	data.pointer = kzalloc(data.length, GFP_KERNEL);
 	if (!data.pointer) {
 		result = -ENOMEM;
 		goto end;
 	}
-	memset(data.pointer, 0, data.length);
 
 	status = acpi_extract_package(package, &format, &data);
 	if (ACPI_FAILURE(status)) {
@@ -239,7 +237,7 @@
 	kfree(buffer.pointer);
 
 	if (!result)
-		(*bst) = (struct acpi_battery_status *)data.pointer;
+		(*bst) = data.pointer;
 
 	return result;
 }
@@ -334,7 +332,7 @@
 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 {
 	int result = 0;
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct acpi_battery *battery = seq->private;
 	struct acpi_battery_info *bif = NULL;
 	char *units = "?";
 
@@ -418,7 +416,7 @@
 static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 {
 	int result = 0;
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct acpi_battery *battery = seq->private;
 	struct acpi_battery_status *bst = NULL;
 	char *units = "?";
 
@@ -494,7 +492,7 @@
 
 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
 {
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct acpi_battery *battery = seq->private;
 	char *units = "?";
 
 
@@ -531,8 +529,8 @@
 {
 	int result = 0;
 	char alarm_string[12] = { '\0' };
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_battery *battery = (struct acpi_battery *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_battery *battery = m->private;
 
 
 	if (!battery || (count > sizeof(alarm_string) - 1))
@@ -658,7 +656,7 @@
 
 static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_battery *battery = (struct acpi_battery *)data;
+	struct acpi_battery *battery = data;
 	struct acpi_device *device = NULL;
 
 
@@ -694,10 +692,9 @@
 	if (!device)
 		return -EINVAL;
 
-	battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL);
+	battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
 	if (!battery)
 		return -ENOMEM;
-	memset(battery, 0, sizeof(struct acpi_battery));
 
 	battery->device = device;
 	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
@@ -742,7 +739,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	battery = (struct acpi_battery *)acpi_driver_data(device);
+	battery = acpi_driver_data(device);
 
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_ALL_NOTIFY,
diff -ru 2.2/drivers/acpi/button.c 3.4/drivers/acpi/button.c
--- 2.2/drivers/acpi/button.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/button.c	2006-12-23 16:57:57.000000000 +0100
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/input.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -62,7 +63,7 @@
 #define _COMPONENT		ACPI_BUTTON_COMPONENT
 ACPI_MODULE_NAME("acpi_button")
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME);
 MODULE_LICENSE("GPL");
 
@@ -78,12 +79,14 @@
 	.ops = {
 		.add = acpi_button_add,
 		.remove = acpi_button_remove,
-		},
+	},
 };
 
 struct acpi_button {
 	struct acpi_device *device;	/* Fixed button kludge */
-	u8 type;
+	unsigned int type;
+	struct input_dev *input;
+	char phys[32];			/* for input device */
 	unsigned long pushed;
 };
 
@@ -109,8 +112,7 @@
 
 static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_button *button = (struct acpi_button *)seq->private;
-
+	struct acpi_button *button = seq->private;
 
 	if (!button || !button->device)
 		return 0;
@@ -128,22 +130,17 @@
 
 static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_button *button = (struct acpi_button *)seq->private;
+	struct acpi_button *button = seq->private;
 	acpi_status status;
 	unsigned long state;
 
-
 	if (!button || !button->device)
 		return 0;
 
 	status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state);
-	if (ACPI_FAILURE(status)) {
-		seq_printf(seq, "state:      unsupported\n");
-	} else {
-		seq_printf(seq, "state:      %s\n",
-			   (state ? "open" : "closed"));
-	}
-
+	seq_printf(seq, "state:      %s\n",
+		   ACPI_FAILURE(status) ? "unsupported" :
+			(state ? "open" : "closed"));
 	return 0;
 }
 
@@ -159,8 +156,7 @@
 static int acpi_button_add_fs(struct acpi_device *device)
 {
 	struct proc_dir_entry *entry = NULL;
-	struct acpi_button *button = NULL;
-
+	struct acpi_button *button;
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
@@ -228,10 +224,8 @@
 
 static int acpi_button_remove_fs(struct acpi_device *device)
 {
-	struct acpi_button *button = NULL;
+	struct acpi_button *button = acpi_driver_data(device);
 
-
-	button = acpi_driver_data(device);
 	if (acpi_device_dir(device)) {
 		if (button->type == ACPI_BUTTON_TYPE_LID)
 			remove_proc_entry(ACPI_BUTTON_FILE_STATE,
@@ -253,14 +247,34 @@
 
 static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_button *button = (struct acpi_button *)data;
-
+	struct acpi_button *button = data;
+	struct input_dev *input;
 
 	if (!button || !button->device)
 		return;
 
 	switch (event) {
 	case ACPI_BUTTON_NOTIFY_STATUS:
+		input = button->input;
+
+		if (button->type == ACPI_BUTTON_TYPE_LID) {
+			struct acpi_handle *handle = button->device->handle;
+			unsigned long state;
+
+			if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
+								NULL, &state)))
+				input_report_switch(input, SW_LID, !state);
+
+		} else {
+			int keycode = test_bit(KEY_SLEEP, input->keybit) ?
+						KEY_SLEEP : KEY_POWER;
+
+			input_report_key(input, keycode, 1);
+			input_sync(input);
+			input_report_key(input, keycode, 0);
+		}
+		input_sync(input);
+
 		acpi_bus_generate_event(button->device, event,
 					++button->pushed);
 		break;
@@ -275,8 +289,7 @@
 
 static acpi_status acpi_button_notify_fixed(void *data)
 {
-	struct acpi_button *button = (struct acpi_button *)data;
-
+	struct acpi_button *button = data;
 
 	if (!button)
 		return AE_BAD_PARAMETER;
@@ -286,24 +299,75 @@
 	return AE_OK;
 }
 
-static int acpi_button_add(struct acpi_device *device)
+static int acpi_button_install_notify_handlers(struct acpi_button *button)
 {
-	int result = 0;
-	acpi_status status = AE_OK;
-	struct acpi_button *button = NULL;
+	acpi_status status;
+
+	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWERF:
+		status =
+		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+						     acpi_button_notify_fixed,
+						     button);
+		break;
+	case ACPI_BUTTON_TYPE_SLEEPF:
+		status =
+		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+						     acpi_button_notify_fixed,
+						     button);
+		break;
+	default:
+		status = acpi_install_notify_handler(button->device->handle,
+						     ACPI_DEVICE_NOTIFY,
+						     acpi_button_notify,
+						     button);
+		break;
+	}
+
+	return ACPI_FAILURE(status) ? -ENODEV : 0;
+}
+
+static void acpi_button_remove_notify_handlers(struct acpi_button *button)
+{
+	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWERF:
+		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+						acpi_button_notify_fixed);
+		break;
+	case ACPI_BUTTON_TYPE_SLEEPF:
+		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+						acpi_button_notify_fixed);
+		break;
+	default:
+		acpi_remove_notify_handler(button->device->handle,
+					   ACPI_DEVICE_NOTIFY,
+					   acpi_button_notify);
+		break;
+	}
+}
 
+static int acpi_button_add(struct acpi_device *device)
+{
+	int error;
+	struct acpi_button *button;
+	struct input_dev *input;
 
 	if (!device)
 		return -EINVAL;
 
-	button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL);
+	button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
 	if (!button)
 		return -ENOMEM;
-	memset(button, 0, sizeof(struct acpi_button));
 
 	button->device = device;
 	acpi_driver_data(device) = button;
 
+	button->input = input = input_allocate_device();
+	if (!input) {
+		error = -ENOMEM;
+		goto err_free_button;
+	}
+
 	/*
 	 * Determine the button type (via hid), as fixed-feature buttons
 	 * need to be handled a bit differently than generic-space.
@@ -338,39 +402,48 @@
 	} else {
 		printk(KERN_ERR PREFIX "Unsupported hid [%s]\n",
 			    acpi_device_hid(device));
-		result = -ENODEV;
-		goto end;
+		error = -ENODEV;
+		goto err_free_input;
 	}
 
-	result = acpi_button_add_fs(device);
-	if (result)
-		goto end;
+	error = acpi_button_add_fs(device);
+	if (error)
+		goto err_free_input;
+
+	error = acpi_button_install_notify_handlers(button);
+	if (error)
+		goto err_remove_fs;
+
+	snprintf(button->phys, sizeof(button->phys),
+		 "%s/button/input0", acpi_device_hid(device));
+
+	input->name = acpi_device_name(device);
+	input->phys = button->phys;
+	input->id.bustype = BUS_HOST;
+	input->id.product = button->type;
 
 	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWER:
 	case ACPI_BUTTON_TYPE_POWERF:
-		status =
-		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						     acpi_button_notify_fixed,
-						     button);
+		input->evbit[0] = BIT(EV_KEY);
+		set_bit(KEY_POWER, input->keybit);
 		break;
+
+	case ACPI_BUTTON_TYPE_SLEEP:
 	case ACPI_BUTTON_TYPE_SLEEPF:
-		status =
-		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						     acpi_button_notify_fixed,
-						     button);
+		input->evbit[0] = BIT(EV_KEY);
+		set_bit(KEY_SLEEP, input->keybit);
 		break;
-	default:
-		status = acpi_install_notify_handler(device->handle,
-						     ACPI_DEVICE_NOTIFY,
-						     acpi_button_notify,
-						     button);
+
+	case ACPI_BUTTON_TYPE_LID:
+		input->evbit[0] = BIT(EV_SW);
+		set_bit(SW_LID, input->swbit);
 		break;
 	}
 
-	if (ACPI_FAILURE(status)) {
-		result = -ENODEV;
-		goto end;
-	}
+	error = input_register_device(input);
+	if (error)
+		goto err_remove_handlers;
 
 	if (device->wakeup.flags.valid) {
 		/* Button's GPE is run-wake GPE */
@@ -385,47 +458,31 @@
 	printk(KERN_INFO PREFIX "%s [%s]\n",
 	       acpi_device_name(device), acpi_device_bid(device));
 
-      end:
-	if (result) {
-		acpi_button_remove_fs(device);
-		kfree(button);
-	}
+	return 0;
 
-	return result;
+ err_remove_handlers:
+	acpi_button_remove_notify_handlers(button);
+ err_remove_fs:
+	acpi_button_remove_fs(device);
+ err_free_input:
+	input_free_device(input);
+ err_free_button:
+	kfree(button);
+	return error;
 }
 
 static int acpi_button_remove(struct acpi_device *device, int type)
 {
-	acpi_status status = 0;
-	struct acpi_button *button = NULL;
-
+	struct acpi_button *button;
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
 	button = acpi_driver_data(device);
 
-	/* Unregister for device notifications. */
-	switch (button->type) {
-	case ACPI_BUTTON_TYPE_POWERF:
-		status =
-		    acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						    acpi_button_notify_fixed);
-		break;
-	case ACPI_BUTTON_TYPE_SLEEPF:
-		status =
-		    acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						    acpi_button_notify_fixed);
-		break;
-	default:
-		status = acpi_remove_notify_handler(device->handle,
-						    ACPI_DEVICE_NOTIFY,
-						    acpi_button_notify);
-		break;
-	}
-
+	acpi_button_remove_notify_handlers(button);
 	acpi_button_remove_fs(device);
-
+	input_unregister_device(button->input);
 	kfree(button);
 
 	return 0;
@@ -433,8 +490,7 @@
 
 static int __init acpi_button_init(void)
 {
-	int result = 0;
-
+	int result;
 
 	acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
 	if (!acpi_button_dir)
@@ -451,7 +507,6 @@
 
 static void __exit acpi_button_exit(void)
 {
-
 	acpi_bus_unregister_driver(&acpi_button_driver);
 
 	if (acpi_power_dir)
@@ -461,8 +516,6 @@
 	if (acpi_lid_dir)
 		remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
 	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
-
-	return;
 }
 
 module_init(acpi_button_init);
diff -ru 2.2/drivers/acpi/container.c 3.4/drivers/acpi/container.c
--- 2.2/drivers/acpi/container.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/container.c	2006-12-23 16:57:57.000000000 +0100
@@ -96,11 +96,10 @@
 		return -EINVAL;
 	}
 
-	container = kmalloc(sizeof(struct acpi_container), GFP_KERNEL);
+	container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL);
 	if (!container)
 		return -ENOMEM;
 
-	memset(container, 0, sizeof(struct acpi_container));
 	container->handle = device->handle;
 	strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
@@ -117,7 +116,7 @@
 	acpi_status status = AE_OK;
 	struct acpi_container *pc = NULL;
 
-	pc = (struct acpi_container *)acpi_driver_data(device);
+	pc = acpi_driver_data(device);
 	kfree(pc);
 	return status;
 }
diff -ru 2.2/drivers/acpi/dock.c 3.4/drivers/acpi/dock.c
--- 2.2/drivers/acpi/dock.c	2006-12-07 02:52:09.000000000 +0100
+++ 3.4/drivers/acpi/dock.c	2006-12-23 16:57:57.000000000 +0100
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/notifier.h>
+#include <linux/platform_device.h>
 #include <linux/jiffies.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -39,13 +40,15 @@
 MODULE_LICENSE("GPL");
 
 static struct atomic_notifier_head dock_notifier_list;
+static struct platform_device dock_device;
+static char dock_device_name[] = "dock";
 
 struct dock_station {
 	acpi_handle handle;
 	unsigned long last_dock_time;
 	u32 flags;
 	spinlock_t dd_lock;
-	spinlock_t hp_lock;
+	struct mutex hp_lock;
 	struct list_head dependent_devices;
 	struct list_head hotplug_devices;
 };
@@ -115,9 +118,9 @@
 dock_add_hotplug_device(struct dock_station *ds,
 			struct dock_dependent_device *dd)
 {
-	spin_lock(&ds->hp_lock);
+	mutex_lock(&ds->hp_lock);
 	list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
-	spin_unlock(&ds->hp_lock);
+	mutex_unlock(&ds->hp_lock);
 }
 
 /**
@@ -131,9 +134,9 @@
 dock_del_hotplug_device(struct dock_station *ds,
 			struct dock_dependent_device *dd)
 {
-	spin_lock(&ds->hp_lock);
+	mutex_lock(&ds->hp_lock);
 	list_del(&dd->hotplug_list);
-	spin_unlock(&ds->hp_lock);
+	mutex_unlock(&ds->hp_lock);
 }
 
 /**
@@ -296,7 +299,7 @@
 {
 	struct dock_dependent_device *dd;
 
-	spin_lock(&ds->hp_lock);
+	mutex_lock(&ds->hp_lock);
 
 	/*
 	 * First call driver specific hotplug functions
@@ -318,15 +321,17 @@
 		else
 			dock_create_acpi_device(dd->handle);
 	}
-	spin_unlock(&ds->hp_lock);
+	mutex_unlock(&ds->hp_lock);
 }
 
 static void dock_event(struct dock_station *ds, u32 event, int num)
 {
+	struct device *dev = &dock_device.dev;
 	/*
-	 * we don't do events until someone tells me that
-	 * they would like to have them.
+	 * Indicate that the status of the dock station has
+	 * changed.
 	 */
+	kobject_uevent(&dev->kobj, KOBJ_CHANGE);
 }
 
 /**
@@ -441,6 +446,9 @@
  */
 int register_dock_notifier(struct notifier_block *nb)
 {
+	if (!dock_station)
+		return -ENODEV;
+
 	return atomic_notifier_chain_register(&dock_notifier_list, nb);
 }
 
@@ -452,6 +460,9 @@
  */
 void unregister_dock_notifier(struct notifier_block *nb)
 {
+	if (!dock_station)
+		return;
+
 	atomic_notifier_chain_unregister(&dock_notifier_list, nb);
 }
 
@@ -512,6 +523,37 @@
 EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
 
 /**
+ * handle_eject_request - handle an undock request checking for error conditions
+ *
+ * Check to make sure the dock device is still present, then undock and
+ * hotremove all the devices that may need removing.
+ */
+static int handle_eject_request(struct dock_station *ds, u32 event)
+{
+	if (!dock_present(ds))
+		return -ENODEV;
+
+	if (dock_in_progress(ds))
+		return -EBUSY;
+
+	/*
+	 * here we need to generate the undock
+	 * event prior to actually doing the undock
+	 * so that the device struct still exists.
+	 */
+	dock_event(ds, event, UNDOCK_EVENT);
+	hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
+	undock(ds);
+	eject_dock(ds);
+	if (dock_present(ds)) {
+		printk(KERN_ERR PREFIX "Unable to undock!\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+/**
  * dock_notify - act upon an acpi dock notification
  * @handle: the dock station handle
  * @event: the acpi event
@@ -519,13 +561,11 @@
  *
  * If we are notified to dock, then check to see if the dock is
  * present and then dock.  Notify all drivers of the dock event,
- * and then hotplug and devices that may need hotplugging.  For undock
- * check to make sure the dock device is still present, then undock
- * and hotremove all the devices that may need removing.
+ * and then hotplug and devices that may need hotplugging.
  */
 static void dock_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct dock_station *ds = (struct dock_station *)data;
+	struct dock_station *ds = data;
 
 	switch (event) {
 	case ACPI_NOTIFY_BUS_CHECK:
@@ -553,19 +593,7 @@
 	 * to the driver who wish to hotplug.
          */
 	case ACPI_NOTIFY_EJECT_REQUEST:
-		if (!dock_in_progress(ds) && dock_present(ds)) {
-			/*
-			 * here we need to generate the undock
-			 * event prior to actually doing the undock
-			 * so that the device struct still exists.
-			 */
-			dock_event(ds, event, UNDOCK_EVENT);
-			hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
-			undock(ds);
-			eject_dock(ds);
-			if (dock_present(ds))
-				printk(KERN_ERR PREFIX "Unable to undock!\n");
-		}
+		handle_eject_request(ds, event);
 		break;
 	default:
 		printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
@@ -588,7 +616,7 @@
 {
 	acpi_status status;
 	acpi_handle tmp;
-	struct dock_station *ds = (struct dock_station *)context;
+	struct dock_station *ds = context;
 	struct dock_dependent_device *dd;
 
 	status = acpi_bus_get_ejd(handle, &tmp);
@@ -604,6 +632,33 @@
 	return AE_OK;
 }
 
+/*
+ * show_docked - read method for "docked" file in sysfs
+ */
+static ssize_t show_docked(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
+
+}
+DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
+
+/*
+ * write_undock - write method for "undock" file in sysfs
+ */
+static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	int ret;
+
+	if (!count)
+		return -EINVAL;
+
+	ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST);
+	return ret ? ret: count;
+}
+DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);
+
 /**
  * dock_add - add a new dock station
  * @handle: the dock station handle
@@ -626,9 +681,33 @@
 	INIT_LIST_HEAD(&dock_station->dependent_devices);
 	INIT_LIST_HEAD(&dock_station->hotplug_devices);
 	spin_lock_init(&dock_station->dd_lock);
-	spin_lock_init(&dock_station->hp_lock);
+	mutex_init(&dock_station->hp_lock);
 	ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
 
+	/* initialize platform device stuff */
+	dock_device.name = dock_device_name;
+	ret = platform_device_register(&dock_device);
+	if (ret) {
+		printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret);
+		kfree(dock_station);
+		return ret;
+	}
+	ret = device_create_file(&dock_device.dev, &dev_attr_docked);
+	if (ret) {
+		printk("Error %d adding sysfs file\n", ret);
+		platform_device_unregister(&dock_device);
+		kfree(dock_station);
+		return ret;
+	}
+	ret = device_create_file(&dock_device.dev, &dev_attr_undock);
+	if (ret) {
+		printk("Error %d adding sysfs file\n", ret);
+		device_remove_file(&dock_device.dev, &dev_attr_docked);
+		platform_device_unregister(&dock_device);
+		kfree(dock_station);
+		return ret;
+	}
+
 	/* Find dependent devices */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX, find_dock_devices, dock_station,
@@ -638,7 +717,8 @@
 	dd = alloc_dock_dependent_device(handle);
 	if (!dd) {
 		kfree(dock_station);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto dock_add_err_unregister;
 	}
 	add_dock_dependent_device(dock_station, dd);
 
@@ -658,8 +738,12 @@
 	return 0;
 
 dock_add_err:
-	kfree(dock_station);
 	kfree(dd);
+dock_add_err_unregister:
+	device_remove_file(&dock_device.dev, &dev_attr_docked);
+	device_remove_file(&dock_device.dev, &dev_attr_undock);
+	platform_device_unregister(&dock_device);
+	kfree(dock_station);
 	return ret;
 }
 
@@ -686,6 +770,11 @@
 	if (ACPI_FAILURE(status))
 		printk(KERN_ERR "Error removing notify handler\n");
 
+	/* cleanup sysfs */
+	device_remove_file(&dock_device.dev, &dev_attr_docked);
+	device_remove_file(&dock_device.dev, &dev_attr_undock);
+	platform_device_unregister(&dock_device);
+
 	/* free dock station memory */
 	kfree(dock_station);
 	return 0;
@@ -703,7 +792,7 @@
 static acpi_status
 find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
-	int *count = (int *)context;
+	int *count = context;
 	acpi_status status = AE_OK;
 
 	if (is_dock(handle)) {
@@ -726,7 +815,7 @@
 			    ACPI_UINT32_MAX, find_dock, &num, NULL);
 
 	if (!num)
-		return -ENODEV;
+		printk(KERN_INFO "No dock devices found.\n");
 
 	return 0;
 }
diff -ru 2.2/drivers/acpi/ec.c 3.4/drivers/acpi/ec.c
--- 2.2/drivers/acpi/ec.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/acpi/ec.c	2006-12-23 16:57:57.000000000 +0100
@@ -45,35 +45,34 @@
 #define ACPI_EC_DRIVER_NAME		"ACPI Embedded Controller Driver"
 #define ACPI_EC_DEVICE_NAME		"Embedded Controller"
 #define ACPI_EC_FILE_INFO		"info"
-
+#undef PREFIX
+#define PREFIX				"ACPI: EC: "
 /* EC status register */
 #define ACPI_EC_FLAG_OBF	0x01	/* Output buffer full */
 #define ACPI_EC_FLAG_IBF	0x02	/* Input buffer full */
 #define ACPI_EC_FLAG_BURST	0x10	/* burst mode */
 #define ACPI_EC_FLAG_SCI	0x20	/* EC-SCI occurred */
-
 /* EC commands */
-#define ACPI_EC_COMMAND_READ	0x80
-#define ACPI_EC_COMMAND_WRITE	0x81
-#define ACPI_EC_BURST_ENABLE	0x82
-#define ACPI_EC_BURST_DISABLE	0x83
-#define ACPI_EC_COMMAND_QUERY	0x84
-
+enum ec_command {
+	ACPI_EC_COMMAND_READ = 0x80,
+	ACPI_EC_COMMAND_WRITE = 0x81,
+	ACPI_EC_BURST_ENABLE = 0x82,
+	ACPI_EC_BURST_DISABLE = 0x83,
+	ACPI_EC_COMMAND_QUERY = 0x84,
+};
 /* EC events */
-enum {
+enum ec_event {
 	ACPI_EC_EVENT_OBF_1 = 1,	/* Output buffer full */
-	ACPI_EC_EVENT_IBF_0,		/* Input buffer empty */
+	ACPI_EC_EVENT_IBF_0,	/* Input buffer empty */
 };
 
-#define ACPI_EC_DELAY		50	/* Wait 50ms max. during EC ops */
+#define ACPI_EC_DELAY		500	/* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
-#define ACPI_EC_UDELAY         100	/* Poll @ 100us increments */
-#define ACPI_EC_UDELAY_COUNT   1000	/* Wait 10ms max. during EC ops */
 
-enum {
-	EC_INTR = 1,	/* Output buffer full */
-	EC_POLL,	/* Input buffer empty */
-};
+static enum ec_mode {
+	EC_INTR = 1,		/* Output buffer full */
+	EC_POLL,		/* Input buffer empty */
+} acpi_ec_mode = EC_INTR;
 
 static int acpi_ec_remove(struct acpi_device *device, int type);
 static int acpi_ec_start(struct acpi_device *device);
@@ -93,22 +92,21 @@
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
-struct acpi_ec {
+static struct acpi_ec {
 	acpi_handle handle;
 	unsigned long uid;
-	unsigned long gpe_bit;
+	unsigned long gpe;
 	unsigned long command_addr;
 	unsigned long data_addr;
 	unsigned long global_lock;
-	struct semaphore sem;
-	unsigned int expect_event;
+	struct mutex lock;
+	atomic_t query_pending;
 	atomic_t leaving_burst;	/* 0 : No, 1 : Yes, 2: abort */
 	wait_queue_head_t wait;
 } *ec_ecdt;
 
 /* External interfaces use first EC only, so remember */
 static struct acpi_device *first_ec;
-static int acpi_ec_mode = EC_INTR;
 
 /* --------------------------------------------------------------------------
                              Transaction Management
@@ -134,54 +132,41 @@
 	outb(data, ec->data_addr);
 }
 
-static int acpi_ec_check_status(u8 status, u8 event)
+static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
 {
-	switch (event) {
-	case ACPI_EC_EVENT_OBF_1:
+	u8 status = acpi_ec_read_status(ec);
+
+	if (event == ACPI_EC_EVENT_OBF_1) {
 		if (status & ACPI_EC_FLAG_OBF)
 			return 1;
-		break;
-	case ACPI_EC_EVENT_IBF_0:
+	} else if (event == ACPI_EC_EVENT_IBF_0) {
 		if (!(status & ACPI_EC_FLAG_IBF))
 			return 1;
-		break;
-	default:
-		break;
 	}
 
 	return 0;
 }
 
-static int acpi_ec_wait(struct acpi_ec *ec, u8 event)
+static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event)
 {
-	int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0;
-	long time_left;
-
-	ec->expect_event = event;
-	if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
-		ec->expect_event = 0;
-		return 0;
-	}
-
-	do {
-		if (acpi_ec_mode == EC_POLL) {
-			udelay(ACPI_EC_UDELAY);
-		} else {
-			time_left = wait_event_timeout(ec->wait,
-				    !ec->expect_event,
-				    msecs_to_jiffies(ACPI_EC_DELAY));
-			if (time_left > 0) {
-				ec->expect_event = 0;
+	if (acpi_ec_mode == EC_POLL) {
+		unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+		while (time_before(jiffies, delay)) {
+			if (acpi_ec_check_status(ec, event))
 				return 0;
-			}
 		}
-		if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
-			ec->expect_event = 0;
+	} else {
+		if (wait_event_timeout(ec->wait,
+				       acpi_ec_check_status(ec, event),
+				       msecs_to_jiffies(ACPI_EC_DELAY)) ||
+		    acpi_ec_check_status(ec, event)) {
 			return 0;
+		} else {
+			printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
+			       " status = %d, expect_event = %d\n",
+			       acpi_ec_read_status(ec), event);
 		}
-	} while (--i > 0);
-
-	ec->expect_event = 0;
+	}
 
 	return -ETIME;
 }
@@ -196,7 +181,6 @@
 	u8 tmp = 0;
 	u8 status = 0;
 
-
 	status = acpi_ec_read_status(ec);
 	if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
 		status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
@@ -212,7 +196,7 @@
 
 	atomic_set(&ec->leaving_burst, 0);
 	return 0;
-  end:
+      end:
 	ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode"));
 	return -1;
 }
@@ -221,58 +205,68 @@
 {
 	u8 status = 0;
 
-
 	status = acpi_ec_read_status(ec);
-	if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){
+	if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) {
 		status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
-		if(status)
+		if (status)
 			goto end;
 		acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE);
 		acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
 	}
 	atomic_set(&ec->leaving_burst, 1);
 	return 0;
-  end:
+      end:
 	ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"));
 	return -1;
 }
-#endif /* ACPI_FUTURE_USAGE */
+#endif				/* ACPI_FUTURE_USAGE */
 
 static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
-					const u8 *wdata, unsigned wdata_len,
-					u8 *rdata, unsigned rdata_len)
+					const u8 * wdata, unsigned wdata_len,
+					u8 * rdata, unsigned rdata_len)
 {
-	int result;
+	int result = 0;
 
 	acpi_ec_write_cmd(ec, command);
 
-	for (; wdata_len > 0; wdata_len --) {
+	for (; wdata_len > 0; --wdata_len) {
 		result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
-		if (result)
-			return result;
+		if (result) {
+			printk(KERN_ERR PREFIX
+			       "write_cmd timeout, command = %d\n", command);
+			goto end;
+		}
 		acpi_ec_write_data(ec, *(wdata++));
 	}
 
-	if (command == ACPI_EC_COMMAND_WRITE) {
+	if (!rdata_len) {
 		result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
-		if (result)
-			return result;
+		if (result) {
+			printk(KERN_ERR PREFIX
+			       "finish-write timeout, command = %d\n", command);
+			goto end;
+		}
+	} else if (command == ACPI_EC_COMMAND_QUERY) {
+		atomic_set(&ec->query_pending, 0);
 	}
 
-	for (; rdata_len > 0; rdata_len --) {
+	for (; rdata_len > 0; --rdata_len) {
 		result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
-		if (result)
-			return result;
+		if (result) {
+			printk(KERN_ERR PREFIX "read timeout, command = %d\n",
+			       command);
+			goto end;
+		}
 
 		*(rdata++) = acpi_ec_read_data(ec);
 	}
-
-	return 0;
+      end:
+	return result;
 }
 
 static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
-				const u8 *wdata, unsigned wdata_len,
-				u8 *rdata, unsigned rdata_len)
+			       const u8 * wdata, unsigned wdata_len,
+			       u8 * rdata, unsigned rdata_len)
 {
 	int status;
 	u32 glk;
@@ -280,36 +274,40 @@
 	if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
 		return -EINVAL;
 
-        if (rdata)
-                memset(rdata, 0, rdata_len);
+	if (rdata)
+		memset(rdata, 0, rdata_len);
 
+	mutex_lock(&ec->lock);
 	if (ec->global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
 			return -ENODEV;
 	}
-	down(&ec->sem);
+
+	/* Make sure GPE is enabled before doing transaction */
+	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
 	if (status) {
-		printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
+		printk(KERN_DEBUG PREFIX
+		       "input buffer is not empty, aborting transaction\n");
 		goto end;
 	}
 
-        status = acpi_ec_transaction_unlocked(ec, command,
-                                              wdata, wdata_len,
-                                              rdata, rdata_len);
+	status = acpi_ec_transaction_unlocked(ec, command,
+					      wdata, wdata_len,
+					      rdata, rdata_len);
 
-end:
-	up(&ec->sem);
+      end:
 
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
+	mutex_unlock(&ec->lock);
 
 	return status;
 }
 
-static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
+static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
 {
 	int result;
 	u8 d;
@@ -322,15 +320,15 @@
 
 static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
 {
-        u8 wdata[2] = { address, data };
-        return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
+	u8 wdata[2] = { address, data };
+	return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
 				   wdata, 2, NULL, 0);
 }
 
 /*
  * Externally callable EC access functions. For now, assume 1 EC only
  */
-int ec_read(u8 addr, u8 *val)
+int ec_read(u8 addr, u8 * val)
 {
 	struct acpi_ec *ec;
 	int err;
@@ -369,9 +367,9 @@
 
 EXPORT_SYMBOL(ec_write);
 
-extern int ec_transaction(u8 command,
-                          const u8 *wdata, unsigned wdata_len,
-                          u8 *rdata, unsigned rdata_len)
+int ec_transaction(u8 command,
+			  const u8 * wdata, unsigned wdata_len,
+			  u8 * rdata, unsigned rdata_len)
 {
 	struct acpi_ec *ec;
 
@@ -386,65 +384,49 @@
 
 EXPORT_SYMBOL(ec_transaction);
 
-static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
+static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
 {
 	int result;
-        u8 d;
+	u8 d;
 
-        if (!ec || !data)
-                return -EINVAL;
+	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(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1);
-        if (result)
-                return result;
+	/*
+	 * 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(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1);
+	if (result)
+		return result;
 
-        if (!d)
-                return -ENODATA;
+	if (!d)
+		return -ENODATA;
 
-        *data = d;
-        return 0;
+	*data = d;
+	return 0;
 }
 
 /* --------------------------------------------------------------------------
                                 Event Management
    -------------------------------------------------------------------------- */
 
-struct acpi_ec_query_data {
-	acpi_handle handle;
-	u8 data;
-};
-
 static void acpi_ec_gpe_query(void *ec_cxt)
 {
 	struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
 	u8 value = 0;
-	static char object_name[8];
+	char object_name[8];
 
-	if (!ec)
-		goto end;
-
-	value = acpi_ec_read_status(ec);
-
-	if (!(value & ACPI_EC_FLAG_SCI))
-		goto end;
-
-	if (acpi_ec_query(ec, &value))
-		goto end;
+	if (!ec || acpi_ec_query(ec, &value))
+		return;
 
 	snprintf(object_name, 8, "_Q%2.2X", value);
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
+	printk(KERN_INFO PREFIX "evaluating %s\n", object_name);
 
 	acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
-
-      end:
-	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 }
 
 static u32 acpi_ec_gpe_handler(void *data)
@@ -453,22 +435,18 @@
 	u8 value;
 	struct acpi_ec *ec = (struct acpi_ec *)data;
 
-	acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
-	value = acpi_ec_read_status(ec);
-
 	if (acpi_ec_mode == EC_INTR) {
-		if (acpi_ec_check_status(value, ec->expect_event)) {
-			ec->expect_event = 0;
-			wake_up(&ec->wait);
-		}
+		wake_up(&ec->wait);
 	}
 
-	if (value & ACPI_EC_FLAG_SCI) {
-		status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
-		return status == AE_OK ?
-		    ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
+	value = acpi_ec_read_status(ec);
+	if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
+		atomic_set(&ec->query_pending, 1);
+		status =
+		    acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query,
+				    ec);
 	}
-	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
+
 	return status == AE_OK ?
 	    ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 }
@@ -504,7 +482,6 @@
 	acpi_integer f_v = 0;
 	int i = 0;
 
-
 	if ((address > 0xFF) || !value || !handler_context)
 		return AE_BAD_PARAMETER;
 
@@ -518,7 +495,7 @@
 	switch (function) {
 	case ACPI_READ:
 		temp = 0;
-		result = acpi_ec_read(ec, (u8) address, (u8 *) &temp);
+		result = acpi_ec_read(ec, (u8) address, (u8 *) & temp);
 		break;
 	case ACPI_WRITE:
 		result = acpi_ec_write(ec, (u8) address, (u8) temp);
@@ -571,18 +548,15 @@
 {
 	struct acpi_ec *ec = (struct acpi_ec *)seq->private;
 
-
 	if (!ec)
 		goto end;
 
-	seq_printf(seq, "gpe bit:                 0x%02x\n",
-		   (u32) ec->gpe_bit);
+	seq_printf(seq, "gpe:                 0x%02x\n", (u32) ec->gpe);
 	seq_printf(seq, "ports:                   0x%02x, 0x%02x\n",
-		   (u32) ec->command_addr,
-		   (u32) ec->data_addr);
+		   (u32) ec->command_addr, (u32) ec->data_addr);
 	seq_printf(seq, "use global lock:         %s\n",
 		   ec->global_lock ? "yes" : "no");
-	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 
       end:
 	return 0;
@@ -605,7 +579,6 @@
 {
 	struct proc_dir_entry *entry = NULL;
 
-
 	if (!acpi_device_dir(device)) {
 		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
 						     acpi_ec_dir);
@@ -648,18 +621,17 @@
 	acpi_status status = AE_OK;
 	struct acpi_ec *ec = NULL;
 
-
 	if (!device)
 		return -EINVAL;
 
-	ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
 	if (!ec)
 		return -ENOMEM;
-	memset(ec, 0, sizeof(struct acpi_ec));
 
 	ec->handle = device->handle;
 	ec->uid = -1;
-	init_MUTEX(&ec->sem);
+	mutex_init(&ec->lock);
+	atomic_set(&ec->query_pending, 0);
 	if (acpi_ec_mode == EC_INTR) {
 		atomic_set(&ec->leaving_burst, 1);
 		init_waitqueue_head(&ec->wait);
@@ -669,8 +641,7 @@
 	acpi_driver_data(device) = ec;
 
 	/* Use the global lock for all EC transactions? */
-	acpi_evaluate_integer(ec->handle, "_GLK", NULL,
-			      &ec->global_lock);
+	acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
 
 	/* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
 	   http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
@@ -679,7 +650,7 @@
 						  ACPI_ADR_SPACE_EC,
 						  &acpi_ec_space_handler);
 
-		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
+		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe,
 					&acpi_ec_gpe_handler);
 
 		kfree(ec_ecdt);
@@ -687,11 +658,10 @@
 
 	/* Get GPE bit assignment (EC events). */
 	/* TODO: Add support for _GPE returning a package */
-	status =
-	    acpi_evaluate_integer(ec->handle, "_GPE", NULL,
-				  &ec->gpe_bit);
+	status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe);
 	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment"));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Obtaining GPE bit assignment"));
 		result = -ENODEV;
 		goto end;
 	}
@@ -701,13 +671,13 @@
 		goto end;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
-	       acpi_device_name(device), acpi_device_bid(device),
-	       (u32) ec->gpe_bit));
+			  acpi_device_name(device), acpi_device_bid(device),
+			  (u32) ec->gpe));
 
 	if (!first_ec)
 		first_ec = device;
 
-  end:
+      end:
 	if (result)
 		kfree(ec);
 
@@ -718,7 +688,6 @@
 {
 	struct acpi_ec *ec = NULL;
 
-
 	if (!device)
 		return -EINVAL;
 
@@ -761,7 +730,6 @@
 	acpi_status status = AE_OK;
 	struct acpi_ec *ec = NULL;
 
-
 	if (!device)
 		return -EINVAL;
 
@@ -782,27 +750,26 @@
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
-			  ec->gpe_bit, ec->command_addr, ec->data_addr));
+			  ec->gpe, ec->command_addr, ec->data_addr));
 
 	/*
 	 * Install GPE handler
 	 */
-	status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
+	status = acpi_install_gpe_handler(NULL, ec->gpe,
 					  ACPI_GPE_EDGE_TRIGGERED,
 					  &acpi_ec_gpe_handler, ec);
 	if (ACPI_FAILURE(status)) {
 		return -ENODEV;
 	}
-	acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
-	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+	acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
+	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 
 	status = acpi_install_address_space_handler(ec->handle,
 						    ACPI_ADR_SPACE_EC,
 						    &acpi_ec_space_handler,
 						    &acpi_ec_space_setup, ec);
 	if (ACPI_FAILURE(status)) {
-		acpi_remove_gpe_handler(NULL, ec->gpe_bit,
-					&acpi_ec_gpe_handler);
+		acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
 		return -ENODEV;
 	}
 
@@ -814,7 +781,6 @@
 	acpi_status status = AE_OK;
 	struct acpi_ec *ec = NULL;
 
-
 	if (!device)
 		return -EINVAL;
 
@@ -826,9 +792,7 @@
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
-	status =
-	    acpi_remove_gpe_handler(NULL, ec->gpe_bit,
-				    &acpi_ec_gpe_handler);
+	status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
@@ -841,7 +805,7 @@
 {
 	acpi_status status;
 
-	init_MUTEX(&ec_ecdt->sem);
+	mutex_init(&ec_ecdt->lock);
 	if (acpi_ec_mode == EC_INTR) {
 		init_waitqueue_head(&ec_ecdt->wait);
 	}
@@ -853,16 +817,15 @@
 	ec_ecdt->uid = -1;
 	acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
 
-	status =
-	    acpi_evaluate_integer(handle, "_GPE", NULL,
-				  &ec_ecdt->gpe_bit);
+	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe);
 	if (ACPI_FAILURE(status))
 		return status;
 	ec_ecdt->global_lock = TRUE;
 	ec_ecdt->handle = handle;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
-	       ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr));
+			  ec_ecdt->gpe, ec_ecdt->command_addr,
+			  ec_ecdt->data_addr));
 
 	return AE_CTRL_TERMINATE;
 }
@@ -884,12 +847,11 @@
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT"));
 
-	ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
 	if (!ec_ecdt) {
 		ret = -ENOMEM;
 		goto error;
 	}
-	memset(ec_ecdt, 0, sizeof(struct acpi_ec));
 
 	status = acpi_get_devices(ACPI_EC_HID,
 				  acpi_fake_ecdt_callback, NULL, NULL);
@@ -901,7 +863,7 @@
 		goto error;
 	}
 	return 0;
-  error:
+      error:
 	return ret;
 }
 
@@ -921,30 +883,28 @@
 	/*
 	 * Generate a temporary ec context to use until the namespace is scanned
 	 */
-	ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
 	if (!ec_ecdt)
 		return -ENOMEM;
-	memset(ec_ecdt, 0, sizeof(struct acpi_ec));
 
-	init_MUTEX(&ec_ecdt->sem);
+	mutex_init(&ec_ecdt->lock);
 	if (acpi_ec_mode == EC_INTR) {
 		init_waitqueue_head(&ec_ecdt->wait);
 	}
 	ec_ecdt->command_addr = ecdt_ptr->ec_control.address;
 	ec_ecdt->data_addr = ecdt_ptr->ec_data.address;
-	ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
+	ec_ecdt->gpe = ecdt_ptr->gpe_bit;
 	/* use the GL just to be safe */
 	ec_ecdt->global_lock = TRUE;
 	ec_ecdt->uid = ecdt_ptr->uid;
 
-	status =
-	    acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
+	status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
 	if (ACPI_FAILURE(status)) {
 		goto error;
 	}
 
 	return 0;
-  error:
+      error:
 	ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
 	kfree(ec_ecdt);
 	ec_ecdt = NULL;
@@ -970,14 +930,14 @@
 	/*
 	 * Install GPE handler
 	 */
-	status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
+	status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe,
 					  ACPI_GPE_EDGE_TRIGGERED,
 					  &acpi_ec_gpe_handler, ec_ecdt);
 	if (ACPI_FAILURE(status)) {
 		goto error;
 	}
-	acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
-	acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
+	acpi_set_gpe_type(NULL, ec_ecdt->gpe, ACPI_GPE_TYPE_RUNTIME);
+	acpi_enable_gpe(NULL, ec_ecdt->gpe, ACPI_NOT_ISR);
 
 	status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
 						    ACPI_ADR_SPACE_EC,
@@ -985,7 +945,7 @@
 						    &acpi_ec_space_setup,
 						    ec_ecdt);
 	if (ACPI_FAILURE(status)) {
-		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
+		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe,
 					&acpi_ec_gpe_handler);
 		goto error;
 	}
@@ -1004,7 +964,6 @@
 {
 	int result = 0;
 
-
 	if (acpi_disabled)
 		return 0;
 
@@ -1057,7 +1016,8 @@
 		acpi_ec_mode = EC_POLL;
 	}
 	acpi_ec_driver.ops.add = acpi_ec_add;
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling"));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n",
+			  intr ? "interrupt" : "polling"));
 
 	return 1;
 }
diff -ru 2.2/drivers/acpi/events/evmisc.c 3.4/drivers/acpi/events/evmisc.c
--- 2.2/drivers/acpi/events/evmisc.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/acpi/events/evmisc.c	2006-12-23 16:57:57.000000000 +0100
@@ -331,7 +331,6 @@
 static u32 acpi_ev_global_lock_handler(void *context)
 {
 	u8 acquired = FALSE;
-	acpi_status status;
 
 	/*
 	 * Attempt to get the lock
diff -ru 2.2/drivers/acpi/executer/exmutex.c 3.4/drivers/acpi/executer/exmutex.c
--- 2.2/drivers/acpi/executer/exmutex.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/executer/exmutex.c	2006-12-23 16:57:57.000000000 +0100
@@ -266,10 +266,10 @@
 	     walk_state->thread->thread_id)
 	    && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) {
 		ACPI_ERROR((AE_INFO,
-			    "Thread %X cannot release Mutex [%4.4s] acquired by thread %X",
-			    (u32) walk_state->thread->thread_id,
+			    "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
+			    (unsigned long)walk_state->thread->thread_id,
 			    acpi_ut_get_node_name(obj_desc->mutex.node),
-			    (u32) obj_desc->mutex.owner_thread->thread_id));
+			    (unsigned long)obj_desc->mutex.owner_thread->thread_id));
 		return_ACPI_STATUS(AE_AML_NOT_OWNER);
 	}
 
diff -ru 2.2/drivers/acpi/fan.c 3.4/drivers/acpi/fan.c
--- 2.2/drivers/acpi/fan.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/fan.c	2006-12-23 16:57:57.000000000 +0100
@@ -99,8 +99,8 @@
 		     size_t count, loff_t * ppos)
 {
 	int result = 0;
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_fan *fan = (struct acpi_fan *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_fan *fan = m->private;
 	char state_string[12] = { '\0' };
 
 
@@ -186,10 +186,9 @@
 	if (!device)
 		return -EINVAL;
 
-	fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL);
+	fan = kzalloc(sizeof(struct acpi_fan), GFP_KERNEL);
 	if (!fan)
 		return -ENOMEM;
-	memset(fan, 0, sizeof(struct acpi_fan));
 
 	fan->device = device;
 	strcpy(acpi_device_name(device), "Fan");
@@ -229,7 +228,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	fan = (struct acpi_fan *)acpi_driver_data(device);
+	fan = acpi_driver_data(device);
 
 	acpi_fan_remove_fs(device);
 
diff -ru 2.2/drivers/acpi/glue.c 3.4/drivers/acpi/glue.c
--- 2.2/drivers/acpi/glue.c	2006-12-07 02:52:09.000000000 +0100
+++ 3.4/drivers/acpi/glue.c	2006-12-23 16:57:57.000000000 +0100
@@ -96,7 +96,7 @@
 static acpi_status
 do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
 {
-	unsigned long *busnr = (unsigned long *)data;
+	unsigned long *busnr = data;
 	struct acpi_resource_address64 address;
 
 	if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
@@ -189,8 +189,12 @@
 	bus = tmp;
 
 	if (seg == find->seg && bus == find->bus)
+	{
 		find->handle = handle;
-	status = AE_OK;
+		status = AE_CTRL_TERMINATE;
+	}
+	else
+		status = AE_OK;
       exit:
 	kfree(buffer.pointer);
 	return status;
@@ -217,7 +221,7 @@
 	acpi_status status;
 	struct acpi_device_info *info;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	struct acpi_find_child *find = (struct acpi_find_child *)context;
+	struct acpi_find_child *find = context;
 
 	status = acpi_get_object_info(handle, &buffer);
 	if (ACPI_SUCCESS(status)) {
diff -ru 2.2/drivers/acpi/hotkey.c 3.4/drivers/acpi/hotkey.c
--- 2.2/drivers/acpi/hotkey.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/hotkey.c	2006-12-23 16:57:57.000000000 +0100
@@ -265,8 +265,7 @@
 
 static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_polling_hotkey *poll_hotkey =
-	    (struct acpi_polling_hotkey *)seq->private;
+	struct acpi_polling_hotkey *poll_hotkey = seq->private;
 	char *buf;
 
 
@@ -577,7 +576,7 @@
 	if (ACPI_FAILURE(status))
 		goto do_fail_zero;
 	key->poll_hotkey.poll_result =
-	    (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	    kmalloc(sizeof(union acpi_object), GFP_KERNEL);
 	if (!key->poll_hotkey.poll_result)
 		goto do_fail_zero;
 	return AE_OK;
diff -ru 2.2/drivers/acpi/i2c_ec.c 3.4/drivers/acpi/i2c_ec.c
--- 2.2/drivers/acpi/i2c_ec.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/i2c_ec.c	2006-12-23 16:57:57.000000000 +0100
@@ -309,18 +309,16 @@
 		return -EINVAL;
 	}
 
-	ec_hc = kmalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL);
+	ec_hc = kzalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL);
 	if (!ec_hc) {
 		return -ENOMEM;
 	}
-	memset(ec_hc, 0, sizeof(struct acpi_ec_hc));
 
-	smbus = kmalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL);
+	smbus = kzalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL);
 	if (!smbus) {
 		kfree(ec_hc);
 		return -ENOMEM;
 	}
-	memset(smbus, 0, sizeof(struct acpi_ec_smbus));
 
 	ec_hc->handle = device->handle;
 	strcpy(acpi_device_name(device), ACPI_EC_HC_DEVICE_NAME);
@@ -393,7 +391,7 @@
 
 struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device)
 {
-	return ((struct acpi_ec_hc *)acpi_driver_data(device->parent));
+	return acpi_driver_data(device->parent);
 }
 
 EXPORT_SYMBOL(acpi_get_ec_hc);
diff -ru 2.2/drivers/acpi/ibm_acpi.c 3.4/drivers/acpi/ibm_acpi.c
--- 2.2/drivers/acpi/ibm_acpi.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/acpi/ibm_acpi.c	2006-12-23 16:57:57.000000000 +0100
@@ -3,6 +3,7 @@
  *
  *
  *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
+ *  Copyright (C) 2006 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
  *
  *  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
@@ -19,10 +20,14 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define IBM_VERSION "0.12a"
+#define IBM_VERSION "0.13"
 
 /*
  *  Changelog:
+ *
+ *  2006-11-22	0.13	new maintainer
+ *  			changelog now lives in git commit history, and will
+ *  			not be updated further in-file.
  *  
  *  2005-08-17  0.12	fix compilation on 2.6.13-rc kernels
  *  2005-03-17	0.11	support for 600e, 770x
@@ -77,9 +82,16 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/string.h>
+
 #include <linux/proc_fs.h>
+#include <linux/backlight.h>
 #include <asm/uaccess.h>
 
+#include <linux/dmi.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+
 #include <acpi/acpi_drivers.h>
 #include <acpi/acnamesp.h>
 
@@ -88,7 +100,7 @@
 #define IBM_FILE "ibm_acpi"
 #define IBM_URL "http://ibm-acpi.sf.net/"
 
-MODULE_AUTHOR("Borislav Deianov");
+MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
 MODULE_DESCRIPTION(IBM_DESC);
 MODULE_VERSION(IBM_VERSION);
 MODULE_LICENSE("GPL");
@@ -116,28 +128,6 @@
 	static char        *object##_path;			\
 	static char        *object##_paths[] = { paths }
 
-/*
- * The following models are supported to various degrees:
- *
- * 570, 600e, 600x, 770e, 770x
- * A20m, A21e, A21m, A21p, A22p, A30, A30p, A31, A31p
- * G40, G41
- * R30, R31, R32, R40, R40e, R50, R50e, R50p, R51
- * T20, T21, T22, T23, T30, T40, T40p, T41, T41p, T42, T42p, T43
- * X20, X21, X22, X23, X24, X30, X31, X40
- *
- * The following models have no supported features:
- *
- * 240, 240x, i1400
- *
- * Still missing DSDTs for the following models:
- *
- * A20p, A22e, A22m
- * R52
- * S31
- * T43p
- */
-
 IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0",	/* 240, 240x */
 	   "\\_SB.PCI.ISA.EC",	/* 570 */
 	   "\\_SB.PCI0.ISA0.EC0",	/* 600e/x, 770e, 770x */
@@ -167,8 +157,10 @@
 	   "\\_SB.PCI.ISA.SLCE",	/* 570 */
     );				/* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",	/* 570 */
 	   "\\_SB.PCI0.IDE0.IDES.IDSM",	/* 600e/x, 770e, 770x */
+	   "\\_SB.PCI0.SATA.SCND.MSTR",	/* T60, X60, Z60 */ 
 	   "\\_SB.PCI0.IDE0.SCND.MSTR",	/* all others */
     );				/* A21e, R30, R31 */
 
@@ -183,6 +175,7 @@
 IBM_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
 	   "_EJ0",		/* 770x */
     );				/* all others */
+#endif
 
 /* don't list other alternatives as we install a notify handler on the 570 */
 IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
@@ -203,7 +196,7 @@
 IBM_HANDLE(beep, ec, "BEEP");	/* all except R30, R31 */
 IBM_HANDLE(ecrd, ec, "ECRD");	/* 570 */
 IBM_HANDLE(ecwr, ec, "ECWR");	/* 570 */
-IBM_HANDLE(fans, ec, "FANS");	/* X31, X40 */
+IBM_HANDLE(fans, ec, "FANS");	/* X31, X40, X41 */
 
 IBM_HANDLE(gfan, ec, "GFAN",	/* 570 */
 	   "\\FSPD",		/* 600e/x, 770e, 770x */
@@ -216,6 +209,152 @@
 #define IBM_HKEY_HID	"IBM0068"
 #define IBM_PCI_HID	"PNP0A03"
 
+enum thermal_access_mode {
+	IBMACPI_THERMAL_NONE = 0,	/* No thermal support */
+	IBMACPI_THERMAL_ACPI_TMP07,	/* Use ACPI TMP0-7 */
+	IBMACPI_THERMAL_ACPI_UPDT,	/* Use ACPI TMP0-7 with UPDT */
+	IBMACPI_THERMAL_TPEC_8,		/* Use ACPI EC regs, 8 sensors */
+	IBMACPI_THERMAL_TPEC_16,	/* Use ACPI EC regs, 16 sensors */
+};
+
+#define IBMACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
+struct ibm_thermal_sensors_struct {
+	s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
+};
+
+/*
+ * FAN ACCESS MODES
+ *
+ * IBMACPI_FAN_RD_ACPI_GFAN:
+ * 	ACPI GFAN method: returns fan level
+ *
+ * 	see IBMACPI_FAN_WR_ACPI_SFAN
+ * 	EC 0x2f not available if GFAN exists
+ *
+ * IBMACPI_FAN_WR_ACPI_SFAN:
+ * 	ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
+ *
+ * 	EC 0x2f might be available *for reading*, but never for writing.
+ *
+ * IBMACPI_FAN_WR_TPEC:
+ * 	ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported
+ * 	on almost all ThinkPads
+ *
+ * 	Fan speed changes of any sort (including those caused by the
+ * 	disengaged mode) are usually done slowly by the firmware as the
+ * 	maximum ammount of fan duty cycle change per second seems to be
+ * 	limited.
+ *
+ * 	Reading is not available if GFAN exists.
+ * 	Writing is not available if SFAN exists.
+ *
+ * 	Bits
+ *	 7	automatic mode engaged;
+ *  		(default operation mode of the ThinkPad)
+ * 		fan level is ignored in this mode.
+ *	 6	disengage mode (takes precedence over bit 7);
+ *		not available on all thinkpads.  May disable
+ *		the tachometer, and speeds up fan to 100% duty-cycle,
+ *		which speeds it up far above the standard RPM
+ *		levels.  It is not impossible that it could cause
+ *		hardware damage.
+ *	5-3	unused in some models.  Extra bits for fan level
+ *		in others, but still useless as all values above
+ *		7 map to the same speed as level 7 in these models.
+ *	2-0	fan level (0..7 usually)
+ *			0x00 = stop
+ * 			0x07 = max (set when temperatures critical)
+ * 		Some ThinkPads may have other levels, see
+ * 		IBMACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
+ *
+ *	FIRMWARE BUG: on some models, EC 0x2f might not be initialized at
+ *	boot. Apparently the EC does not intialize it, so unless ACPI DSDT
+ *	does so, its initial value is meaningless (0x07).
+ *
+ *	For firmware bugs, refer to:
+ *	http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
+ *
+ * 	----
+ *
+ *	ThinkPad EC register 0x84 (LSB), 0x85 (MSB):
+ *	Main fan tachometer reading (in RPM)
+ *
+ *	This register is present on all ThinkPads with a new-style EC, and
+ *	it is known not to be present on the A21m/e, and T22, as there is
+ *	something else in offset 0x84 according to the ACPI DSDT.  Other
+ *	ThinkPads from this same time period (and earlier) probably lack the
+ *	tachometer as well.
+ *
+ *	Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
+ *	was never fixed by IBM to report the EC firmware version string
+ *	probably support the tachometer (like the early X models), so
+ *	detecting it is quite hard.  We need more data to know for sure.
+ *
+ *	FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings
+ *	might result.
+ *
+ *	FIRMWARE BUG: when EC 0x2f bit 6 is set (disengaged mode), this
+ *	register is not invalidated in ThinkPads that disable tachometer
+ *	readings.  Thus, the tachometer readings go stale.
+ *
+ *	For firmware bugs, refer to:
+ *	http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
+ *
+ * IBMACPI_FAN_WR_ACPI_FANS:
+ *	ThinkPad X31, X40, X41.  Not available in the X60.
+ *
+ *	FANS ACPI handle: takes three arguments: low speed, medium speed,
+ *	high speed.  ACPI DSDT seems to map these three speeds to levels
+ *	as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH
+ *	(this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3")
+ *
+ * 	The speeds are stored on handles
+ * 	(FANA:FAN9), (FANC:FANB), (FANE:FAND).
+ *
+ * 	There are three default speed sets, acessible as handles:
+ * 	FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
+ *
+ * 	ACPI DSDT switches which set is in use depending on various
+ * 	factors.
+ *
+ * 	IBMACPI_FAN_WR_TPEC is also available and should be used to
+ * 	command the fan.  The X31/X40/X41 seems to have 8 fan levels,
+ * 	but the ACPI tables just mention level 7.
+ */
+
+enum fan_status_access_mode {
+	IBMACPI_FAN_NONE = 0,		/* No fan status or control */
+	IBMACPI_FAN_RD_ACPI_GFAN,	/* Use ACPI GFAN */
+	IBMACPI_FAN_RD_TPEC,		/* Use ACPI EC regs 0x2f, 0x84-0x85 */
+};
+
+enum fan_control_access_mode {
+	IBMACPI_FAN_WR_NONE = 0,	/* No fan control */
+	IBMACPI_FAN_WR_ACPI_SFAN,	/* Use ACPI SFAN */
+	IBMACPI_FAN_WR_TPEC,		/* Use ACPI EC reg 0x2f */
+	IBMACPI_FAN_WR_ACPI_FANS,	/* Use ACPI FANS and EC reg 0x2f */
+};
+
+enum fan_control_commands {
+	IBMACPI_FAN_CMD_SPEED 	= 0x0001,	/* speed command */
+	IBMACPI_FAN_CMD_LEVEL 	= 0x0002,	/* level command  */
+	IBMACPI_FAN_CMD_ENABLE	= 0x0004,	/* enable/disable cmd,
+						 * and also watchdog cmd */
+};
+
+enum {					/* Fan control constants */
+	fan_status_offset = 0x2f,	/* EC register 0x2f */
+	fan_rpm_offset = 0x84,		/* EC register 0x84: LSB, 0x85 MSB (RPM)
+					 * 0x84 must be read before 0x85 */
+
+	IBMACPI_FAN_EC_DISENGAGED 	= 0x40,	/* EC mode: tachometer
+						 * disengaged */
+	IBMACPI_FAN_EC_AUTO		= 0x80, /* EC mode: auto fan
+						 * control */
+};
+
+static char *ibm_thinkpad_ec_found = NULL;
+
 struct ibm_struct {
 	char *name;
 	char param[32];
@@ -243,6 +382,8 @@
 
 static struct proc_dir_entry *proc_dir = NULL;
 
+static struct backlight_device *ibm_backlight_device = NULL;
+
 #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
 #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
 #define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
@@ -352,7 +493,7 @@
 	return start;
 }
 
-static int driver_init(void)
+static int ibm_acpi_driver_init(void)
 {
 	printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
 	printk(IBM_INFO "%s\n", IBM_URL);
@@ -581,8 +722,7 @@
 {
 	int status;
 
-	if (!wan_supported ||
-	    !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
+	if (!wan_supported || !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
 		status = 0;
 
 	return status;
@@ -630,12 +770,15 @@
 	return 0;
 }
 
-static int video_supported;
-static int video_orig_autosw;
+enum video_access_mode {
+	IBMACPI_VIDEO_NONE = 0,
+	IBMACPI_VIDEO_570,	/* 570 */
+	IBMACPI_VIDEO_770,	/* 600e/x, 770e, 770x */
+	IBMACPI_VIDEO_NEW,	/* all others */
+};
 
-#define VIDEO_570 1
-#define VIDEO_770 2
-#define VIDEO_NEW 3
+static enum video_access_mode video_supported;
+static int video_orig_autosw;
 
 static int video_init(void)
 {
@@ -647,16 +790,16 @@
 
 	if (!vid_handle)
 		/* video switching not supported on R30, R31 */
-		video_supported = 0;
+		video_supported = IBMACPI_VIDEO_NONE;
 	else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
 		/* 570 */
-		video_supported = VIDEO_570;
+		video_supported = IBMACPI_VIDEO_570;
 	else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
 		/* 600e/x, 770e, 770x */
-		video_supported = VIDEO_770;
+		video_supported = IBMACPI_VIDEO_770;
 	else
 		/* all others */
-		video_supported = VIDEO_NEW;
+		video_supported = IBMACPI_VIDEO_NEW;
 
 	return 0;
 }
@@ -666,15 +809,15 @@
 	int status = 0;
 	int i;
 
-	if (video_supported == VIDEO_570) {
+	if (video_supported == IBMACPI_VIDEO_570) {
 		if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87))
 			status = i & 3;
-	} else if (video_supported == VIDEO_770) {
+	} else if (video_supported == IBMACPI_VIDEO_770) {
 		if (acpi_evalf(NULL, &i, "\\VCDL", "d"))
 			status |= 0x01 * i;
 		if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
 			status |= 0x02 * i;
-	} else if (video_supported == VIDEO_NEW) {
+	} else if (video_supported == IBMACPI_VIDEO_NEW) {
 		acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1);
 		if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
 			status |= 0x02 * i;
@@ -693,9 +836,10 @@
 {
 	int autosw = 0;
 
-	if (video_supported == VIDEO_570)
+	if (video_supported == IBMACPI_VIDEO_570)
 		acpi_evalf(vid_handle, &autosw, "SWIT", "d");
-	else if (video_supported == VIDEO_770 || video_supported == VIDEO_NEW)
+	else if (video_supported == IBMACPI_VIDEO_770 ||
+		 video_supported == IBMACPI_VIDEO_NEW)
 		acpi_evalf(vid_handle, &autosw, "^VDEE", "d");
 
 	return autosw & 1;
@@ -715,12 +859,12 @@
 	len += sprintf(p + len, "status:\t\tsupported\n");
 	len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
 	len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
-	if (video_supported == VIDEO_NEW)
+	if (video_supported == IBMACPI_VIDEO_NEW)
 		len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
 	len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
 	len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
 	len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
-	if (video_supported == VIDEO_NEW)
+	if (video_supported == IBMACPI_VIDEO_NEW)
 		len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
 	len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
 	len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
@@ -735,7 +879,7 @@
 
 	if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
 		return -EIO;
-	ret = video_supported == VIDEO_570 ?
+	ret = video_supported == IBMACPI_VIDEO_570 ?
 	    acpi_evalf(ec_handle, NULL, "_Q16", "v") :
 	    acpi_evalf(vid_handle, NULL, "VSWT", "v");
 	acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw);
@@ -745,9 +889,9 @@
 
 static int video_expand(void)
 {
-	if (video_supported == VIDEO_570)
+	if (video_supported == IBMACPI_VIDEO_570)
 		return acpi_evalf(ec_handle, NULL, "_Q17", "v");
-	else if (video_supported == VIDEO_770)
+	else if (video_supported == IBMACPI_VIDEO_770)
 		return acpi_evalf(vid_handle, NULL, "VEXP", "v");
 	else
 		return acpi_evalf(NULL, NULL, "\\VEXP", "v");
@@ -757,10 +901,10 @@
 {
 	int ret;
 
-	if (video_supported == VIDEO_570) {
+	if (video_supported == IBMACPI_VIDEO_570) {
 		ret = acpi_evalf(NULL, NULL,
 				 "\\_SB.PHS2", "vdd", 0x8b, status | 0x80);
-	} else if (video_supported == VIDEO_770) {
+	} else if (video_supported == IBMACPI_VIDEO_770) {
 		int autosw = video_autosw();
 		if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
 			return -EIO;
@@ -796,10 +940,10 @@
 			enable |= 0x02;
 		} else if (strlencmp(cmd, "crt_disable") == 0) {
 			disable |= 0x02;
-		} else if (video_supported == VIDEO_NEW &&
+		} else if (video_supported == IBMACPI_VIDEO_NEW &&
 			   strlencmp(cmd, "dvi_enable") == 0) {
 			enable |= 0x08;
-		} else if (video_supported == VIDEO_NEW &&
+		} else if (video_supported == IBMACPI_VIDEO_NEW &&
 			   strlencmp(cmd, "dvi_disable") == 0) {
 			disable |= 0x08;
 		} else if (strlencmp(cmd, "auto_enable") == 0) {
@@ -898,6 +1042,7 @@
 	return 0;
 }
 
+#if defined(CONFIG_ACPI_IBM_DOCK) || defined(CONFIG_ACPI_IBM_BAY)
 static int _sta(acpi_handle handle)
 {
 	int status;
@@ -907,6 +1052,7 @@
 
 	return status;
 }
+#endif
 #ifdef CONFIG_ACPI_IBM_DOCK
 #define dock_docked() (_sta(dock_handle) & 1)
 
@@ -972,6 +1118,7 @@
 }
 #endif
 
+#ifdef CONFIG_ACPI_IBM_BAY
 static int bay_status_supported;
 static int bay_status2_supported;
 static int bay_eject_supported;
@@ -1047,6 +1194,7 @@
 {
 	acpi_bus_generate_event(ibm->device, event, 0);
 }
+#endif
 
 static int cmos_read(char *p)
 {
@@ -1094,26 +1242,28 @@
 	return 0;
 }
 
-static int led_supported;
-
-#define LED_570 1
-#define LED_OLD 2
-#define LED_NEW 3
+enum led_access_mode {
+	IBMACPI_LED_NONE = 0,
+	IBMACPI_LED_570,	/* 570 */
+	IBMACPI_LED_OLD,	/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
+	IBMACPI_LED_NEW,	/* all others */
+};
+static enum led_access_mode led_supported;
 
 static int led_init(void)
 {
 	if (!led_handle)
 		/* led not supported on R30, R31 */
-		led_supported = 0;
+		led_supported = IBMACPI_LED_NONE;
 	else if (strlencmp(led_path, "SLED") == 0)
 		/* 570 */
-		led_supported = LED_570;
+		led_supported = IBMACPI_LED_570;
 	else if (strlencmp(led_path, "SYSL") == 0)
 		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
-		led_supported = LED_OLD;
+		led_supported = IBMACPI_LED_OLD;
 	else
 		/* all others */
-		led_supported = LED_NEW;
+		led_supported = IBMACPI_LED_NEW;
 
 	return 0;
 }
@@ -1130,7 +1280,7 @@
 	}
 	len += sprintf(p + len, "status:\t\tsupported\n");
 
-	if (led_supported == LED_570) {
+	if (led_supported == IBMACPI_LED_570) {
 		/* 570 */
 		int i, status;
 		for (i = 0; i < 8; i++) {
@@ -1179,13 +1329,13 @@
 		} else
 			return -EINVAL;
 
-		if (led_supported == LED_570) {
+		if (led_supported == IBMACPI_LED_570) {
 			/* 570 */
 			led = 1 << led;
 			if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
 					led, led_sled_arg1[ind]))
 				return -EIO;
-		} else if (led_supported == LED_OLD) {
+		} else if (led_supported == IBMACPI_LED_OLD) {
 			/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
 			led = 1 << led;
 			ret = ec_write(EC_HLMS, led);
@@ -1272,50 +1422,142 @@
 	return 1;
 }
 
-static int thermal_tmp_supported;
-static int thermal_updt_supported;
+static enum thermal_access_mode thermal_read_mode;
 
 static int thermal_init(void)
 {
-	/* temperatures not supported on 570, G4x, R30, R31, R32 */
-	thermal_tmp_supported = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
+	u8 t, ta1, ta2;
+	int i;
+	int acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
 
-	/* 600e/x, 770e, 770x */
-	thermal_updt_supported = acpi_evalf(ec_handle, NULL, "UPDT", "qv");
+	if (ibm_thinkpad_ec_found && experimental) {
+		/*
+		 * Direct EC access mode: sensors at registers
+		 * 0x78-0x7F, 0xC0-0xC7.  Registers return 0x00 for
+		 * non-implemented, thermal sensors return 0x80 when
+		 * not available
+		 */
+
+		ta1 = ta2 = 0;
+		for (i = 0; i < 8; i++) {
+			if (likely(acpi_ec_read(0x78 + i, &t))) {
+				ta1 |= t;
+			} else {
+				ta1 = 0;
+				break;
+			}
+			if (likely(acpi_ec_read(0xC0 + i, &t))) {
+				ta2 |= t;
+			} else {
+				ta1 = 0;
+				break;
+			}
+		}
+		if (ta1 == 0) {
+			/* This is sheer paranoia, but we handle it anyway */
+			if (acpi_tmp7) {
+				printk(IBM_ERR
+				       "ThinkPad ACPI EC access misbehaving, "
+				       "falling back to ACPI TMPx access mode\n");
+				thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
+			} else {
+				printk(IBM_ERR
+				       "ThinkPad ACPI EC access misbehaving, "
+				       "disabling thermal sensors access\n");
+				thermal_read_mode = IBMACPI_THERMAL_NONE;
+			}
+		} else {
+			thermal_read_mode =
+			    (ta2 != 0) ?
+			    IBMACPI_THERMAL_TPEC_16 : IBMACPI_THERMAL_TPEC_8;
+		}
+	} else if (acpi_tmp7) {
+		if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
+			/* 600e/x, 770e, 770x */
+			thermal_read_mode = IBMACPI_THERMAL_ACPI_UPDT;
+		} else {
+			/* Standard ACPI TMPx access, max 8 sensors */
+			thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
+		}
+	} else {
+		/* temperatures not supported on 570, G4x, R30, R31, R32 */
+		thermal_read_mode = IBMACPI_THERMAL_NONE;
+	}
 
 	return 0;
 }
 
-static int thermal_read(char *p)
+static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
 {
-	int len = 0;
+	int i, t;
+	s8 tmp;
+	char tmpi[] = "TMPi";
 
-	if (!thermal_tmp_supported)
-		len += sprintf(p + len, "temperatures:\tnot supported\n");
-	else {
-		int i, t;
-		char tmpi[] = "TMPi";
-		s8 tmp[8];
+	if (!s)
+		return -EINVAL;
 
-		if (thermal_updt_supported)
-			if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
+	switch (thermal_read_mode) {
+#if IBMACPI_MAX_THERMAL_SENSORS >= 16
+	case IBMACPI_THERMAL_TPEC_16:
+		for (i = 0; i < 8; i++) {
+			if (!acpi_ec_read(0xC0 + i, &tmp))
 				return -EIO;
+			s->temp[i + 8] = tmp * 1000;
+		}
+		/* fallthrough */
+#endif
+	case IBMACPI_THERMAL_TPEC_8:
+		for (i = 0; i < 8; i++) {
+			if (!acpi_ec_read(0x78 + i, &tmp))
+				return -EIO;
+			s->temp[i] = tmp * 1000;
+		}
+		return (thermal_read_mode == IBMACPI_THERMAL_TPEC_16) ? 16 : 8;
 
+	case IBMACPI_THERMAL_ACPI_UPDT:
+		if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
+			return -EIO;
 		for (i = 0; i < 8; i++) {
 			tmpi[3] = '0' + i;
 			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
 				return -EIO;
-			if (thermal_updt_supported)
-				tmp[i] = (t - 2732 + 5) / 10;
-			else
-				tmp[i] = t;
+			s->temp[i] = (t - 2732) * 100;
 		}
+		return 8;
 
-		len += sprintf(p + len,
-			       "temperatures:\t%d %d %d %d %d %d %d %d\n",
-			       tmp[0], tmp[1], tmp[2], tmp[3],
-			       tmp[4], tmp[5], tmp[6], tmp[7]);
+	case IBMACPI_THERMAL_ACPI_TMP07:
+		for (i = 0; i < 8; i++) {
+			tmpi[3] = '0' + i;
+			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
+				return -EIO;
+			s->temp[i] = t * 1000;
+		}
+		return 8;
+
+	case IBMACPI_THERMAL_NONE:
+	default:
+		return 0;
 	}
+}
+
+static int thermal_read(char *p)
+{
+	int len = 0;
+	int n, i;
+	struct ibm_thermal_sensors_struct t;
+
+	n = thermal_get_sensors(&t);
+	if (unlikely(n < 0))
+		return n;
+
+	len += sprintf(p + len, "temperatures:\t");
+
+	if (n > 0) {
+		for (i = 0; i < (n - 1); i++)
+			len += sprintf(p + len, "%d ", t.temp[i] / 1000);
+		len += sprintf(p + len, "%d\n", t.temp[i] / 1000);
+	} else
+		len += sprintf(p + len, "not supported\n");
 
 	return len;
 }
@@ -1381,12 +1623,23 @@
 
 static int brightness_offset = 0x31;
 
+static int brightness_get(struct backlight_device *bd)
+{
+	u8 level;
+	if (!acpi_ec_read(brightness_offset, &level))
+		return -EIO;
+
+	level &= 0x7;
+
+	return level;
+}
+
 static int brightness_read(char *p)
 {
 	int len = 0;
-	u8 level;
+	int level;
 
-	if (!acpi_ec_read(brightness_offset, &level)) {
+	if ((level = brightness_get(NULL)) < 0) {
 		len += sprintf(p + len, "level:\t\tunreadable\n");
 	} else {
 		len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
@@ -1401,16 +1654,34 @@
 #define BRIGHTNESS_UP	4
 #define BRIGHTNESS_DOWN	5
 
-static int brightness_write(char *buf)
+static int brightness_set(int value)
 {
 	int cmos_cmd, inc, i;
-	u8 level;
+	int current_value = brightness_get(NULL);
+
+	value &= 7;
+
+	cmos_cmd = value > current_value ? BRIGHTNESS_UP : BRIGHTNESS_DOWN;
+	inc = value > current_value ? 1 : -1;
+	for (i = current_value; i != value; i += inc) {
+		if (!cmos_eval(cmos_cmd))
+			return -EIO;
+		if (!acpi_ec_write(brightness_offset, i + inc))
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static int brightness_write(char *buf)
+{
+	int level;
 	int new_level;
 	char *cmd;
 
 	while ((cmd = next_cmd(&buf))) {
-		if (!acpi_ec_read(brightness_offset, &level))
-			return -EIO;
+		if ((level = brightness_get(NULL)) < 0)
+			return level;
 		level &= 7;
 
 		if (strlencmp(cmd, "up") == 0) {
@@ -1423,19 +1694,44 @@
 		} else
 			return -EINVAL;
 
-		cmos_cmd = new_level > level ? BRIGHTNESS_UP : BRIGHTNESS_DOWN;
-		inc = new_level > level ? 1 : -1;
-		for (i = level; i != new_level; i += inc) {
-			if (!cmos_eval(cmos_cmd))
-				return -EIO;
-			if (!acpi_ec_write(brightness_offset, i + inc))
-				return -EIO;
-		}
+		brightness_set(new_level);
+	}
+
+	return 0;
+}
+
+static int brightness_update_status(struct backlight_device *bd)
+{
+	return brightness_set(bd->props->brightness);
+}
+
+static struct backlight_properties ibm_backlight_data = {
+        .owner          = THIS_MODULE,
+        .get_brightness = brightness_get,
+        .update_status  = brightness_update_status,
+        .max_brightness = 7,
+};
+
+static int brightness_init(void)
+{
+	ibm_backlight_device = backlight_device_register("ibm", NULL, NULL,
+							 &ibm_backlight_data);
+	if (IS_ERR(ibm_backlight_device)) {
+		printk(IBM_ERR "Could not register backlight device\n");
+		return PTR_ERR(ibm_backlight_device);
 	}
 
 	return 0;
 }
 
+static void brightness_exit(void)
+{
+	if (ibm_backlight_device) {
+		backlight_device_unregister(ibm_backlight_device);
+		ibm_backlight_device = NULL;
+	}
+}
+
 static int volume_offset = 0x30;
 
 static int volume_read(char *p)
@@ -1522,90 +1818,486 @@
 	return 0;
 }
 
-static int fan_status_offset = 0x2f;
-static int fan_rpm_offset = 0x84;
+static enum fan_status_access_mode fan_status_access_mode;
+static enum fan_control_access_mode fan_control_access_mode;
+static enum fan_control_commands fan_control_commands;
+
+static int fan_control_status_known;
+static u8 fan_control_initial_status;
+
+static void fan_watchdog_fire(struct work_struct *ignored);
+static int fan_watchdog_maxinterval;
+static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
+
+static int fan_init(void)
+{
+	fan_status_access_mode = IBMACPI_FAN_NONE;
+	fan_control_access_mode = IBMACPI_FAN_WR_NONE;
+	fan_control_commands = 0;
+	fan_control_status_known = 1;
+	fan_watchdog_maxinterval = 0;
+
+	if (gfan_handle) {
+		/* 570, 600e/x, 770e, 770x */
+		fan_status_access_mode = IBMACPI_FAN_RD_ACPI_GFAN;
+	} else {
+		/* all other ThinkPads: note that even old-style
+		 * ThinkPad ECs supports the fan control register */
+		if (likely(acpi_ec_read(fan_status_offset,
+					&fan_control_initial_status))) {
+			fan_status_access_mode = IBMACPI_FAN_RD_TPEC;
+
+			/* In some ThinkPads, neither the EC nor the ACPI
+			 * DSDT initialize the fan status, and it ends up
+			 * being set to 0x07 when it *could* be either
+			 * 0x07 or 0x80.
+			 *
+			 * Enable for TP-1Y (T43), TP-78 (R51e),
+			 * TP-76 (R52), TP-70 (T43, R52), which are known
+			 * to be buggy. */
+			if (fan_control_initial_status == 0x07 &&
+			    ibm_thinkpad_ec_found &&
+			    ((ibm_thinkpad_ec_found[0] == '1' &&
+			      ibm_thinkpad_ec_found[1] == 'Y') ||
+			     (ibm_thinkpad_ec_found[0] == '7' &&
+			      (ibm_thinkpad_ec_found[1] == '6' ||
+			       ibm_thinkpad_ec_found[1] == '8' ||
+			       ibm_thinkpad_ec_found[1] == '0'))
+			    )) {
+				printk(IBM_NOTICE
+				       "fan_init: initial fan status is "
+				       "unknown, assuming it is in auto "
+				       "mode\n");
+				fan_control_status_known = 0;
+			}
+		} else {
+			printk(IBM_ERR
+			       "ThinkPad ACPI EC access misbehaving, "
+			       "fan status and control unavailable\n");
+			return 0;
+		}
+	}
+
+	if (sfan_handle) {
+		/* 570, 770x-JL */
+		fan_control_access_mode = IBMACPI_FAN_WR_ACPI_SFAN;
+		fan_control_commands |=
+		    IBMACPI_FAN_CMD_LEVEL | IBMACPI_FAN_CMD_ENABLE;
+	} else {
+		if (!gfan_handle) {
+			/* gfan without sfan means no fan control */
+			/* all other models implement TP EC 0x2f control */
+
+			if (fans_handle) {
+				/* X31, X40, X41 */
+				fan_control_access_mode =
+				    IBMACPI_FAN_WR_ACPI_FANS;
+				fan_control_commands |=
+				    IBMACPI_FAN_CMD_SPEED |
+				    IBMACPI_FAN_CMD_LEVEL |
+				    IBMACPI_FAN_CMD_ENABLE;
+			} else {
+				fan_control_access_mode = IBMACPI_FAN_WR_TPEC;
+				fan_control_commands |=
+				    IBMACPI_FAN_CMD_LEVEL |
+				    IBMACPI_FAN_CMD_ENABLE;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int fan_get_status(u8 *status)
+{
+	u8 s;
+
+	/* TODO:
+	 * Add IBMACPI_FAN_RD_ACPI_FANS ? */
+
+	switch (fan_status_access_mode) {
+	case IBMACPI_FAN_RD_ACPI_GFAN:
+		/* 570, 600e/x, 770e, 770x */
+
+		if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
+			return -EIO;
+
+		if (likely(status))
+			*status = s & 0x07;
+
+		break;
+
+	case IBMACPI_FAN_RD_TPEC:
+		/* all except 570, 600e/x, 770e, 770x */
+		if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
+			return -EIO;
+
+		if (likely(status))
+			*status = s;
+
+		break;
+
+	default:
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int fan_get_speed(unsigned int *speed)
+{
+	u8 hi, lo;
+
+	switch (fan_status_access_mode) {
+	case IBMACPI_FAN_RD_TPEC:
+		/* all except 570, 600e/x, 770e, 770x */
+		if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
+			     !acpi_ec_read(fan_rpm_offset + 1, &hi)))
+			return -EIO;
+
+		if (likely(speed))
+			*speed = (hi << 8) | lo;
+
+		break;
+
+	default:
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static void fan_exit(void)
+{
+	cancel_delayed_work(&fan_watchdog_task);
+	flush_scheduled_work();
+}
+
+static void fan_watchdog_reset(void)
+{
+	static int fan_watchdog_active = 0;
+
+	if (fan_watchdog_active)
+		cancel_delayed_work(&fan_watchdog_task);
+
+	if (fan_watchdog_maxinterval > 0) {
+		fan_watchdog_active = 1;
+		if (!schedule_delayed_work(&fan_watchdog_task,
+				msecs_to_jiffies(fan_watchdog_maxinterval
+						 * 1000))) {
+			printk(IBM_ERR "failed to schedule the fan watchdog, "
+			       "watchdog will not trigger\n");
+		}
+	} else
+		fan_watchdog_active = 0;
+}
 
 static int fan_read(char *p)
 {
 	int len = 0;
-	int s;
-	u8 lo, hi, status;
+	int rc;
+	u8 status;
+	unsigned int speed = 0;
 
-	if (gfan_handle) {
+	switch (fan_status_access_mode) {
+	case IBMACPI_FAN_RD_ACPI_GFAN:
 		/* 570, 600e/x, 770e, 770x */
-		if (!acpi_evalf(gfan_handle, &s, NULL, "d"))
-			return -EIO;
+		if ((rc = fan_get_status(&status)) < 0)
+			return rc;
 
-		len += sprintf(p + len, "level:\t\t%d\n", s);
-	} else {
+		len += sprintf(p + len, "status:\t\t%s\n"
+			       "level:\t\t%d\n",
+			       (status != 0) ? "enabled" : "disabled", status);
+		break;
+
+	case IBMACPI_FAN_RD_TPEC:
 		/* all except 570, 600e/x, 770e, 770x */
-		if (!acpi_ec_read(fan_status_offset, &status))
-			len += sprintf(p + len, "status:\t\tunreadable\n");
-		else
-			len += sprintf(p + len, "status:\t\t%s\n",
-				       enabled(status, 7));
+		if ((rc = fan_get_status(&status)) < 0)
+			return rc;
+
+		if (unlikely(!fan_control_status_known)) {
+			if (status != fan_control_initial_status)
+				fan_control_status_known = 1;
+			else
+				/* Return most likely status. In fact, it
+				 * might be the only possible status */
+				status = IBMACPI_FAN_EC_AUTO;
+		}
 
-		if (!acpi_ec_read(fan_rpm_offset, &lo) ||
-		    !acpi_ec_read(fan_rpm_offset + 1, &hi))
-			len += sprintf(p + len, "speed:\t\tunreadable\n");
+		len += sprintf(p + len, "status:\t\t%s\n",
+			       (status != 0) ? "enabled" : "disabled");
+
+		/* No ThinkPad boots on disengaged mode, we can safely
+		 * assume the tachometer is online if fan control status
+		 * was unknown */
+		if ((rc = fan_get_speed(&speed)) < 0)
+			return rc;
+
+		len += sprintf(p + len, "speed:\t\t%d\n", speed);
+
+		if (status & IBMACPI_FAN_EC_DISENGAGED)
+			/* Disengaged mode takes precedence */
+			len += sprintf(p + len, "level:\t\tdisengaged\n");
+		else if (status & IBMACPI_FAN_EC_AUTO)
+			len += sprintf(p + len, "level:\t\tauto\n");
 		else
-			len += sprintf(p + len, "speed:\t\t%d\n",
-				       (hi << 8) + lo);
+			len += sprintf(p + len, "level:\t\t%d\n", status);
+		break;
+
+	case IBMACPI_FAN_NONE:
+	default:
+		len += sprintf(p + len, "status:\t\tnot supported\n");
 	}
 
-	if (sfan_handle)
-		/* 570, 770x-JL */
-		len += sprintf(p + len, "commands:\tlevel <level>"
-			       " (<level> is 0-7)\n");
-	if (!gfan_handle)
-		/* all except 570, 600e/x, 770e, 770x */
-		len += sprintf(p + len, "commands:\tenable, disable\n");
-	if (fans_handle)
-		/* X31, X40 */
+	if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) {
+		len += sprintf(p + len, "commands:\tlevel <level>");
+
+		switch (fan_control_access_mode) {
+		case IBMACPI_FAN_WR_ACPI_SFAN:
+			len += sprintf(p + len, " (<level> is 0-7)\n");
+			break;
+
+		default:
+			len += sprintf(p + len, " (<level> is 0-7, "
+				       "auto, disengaged)\n");
+			break;
+		}
+	}
+
+	if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE)
+		len += sprintf(p + len, "commands:\tenable, disable\n"
+			       "commands:\twatchdog <timeout> (<timeout> is 0 (off), "
+			       "1-120 (seconds))\n");
+
+	if (fan_control_commands & IBMACPI_FAN_CMD_SPEED)
 		len += sprintf(p + len, "commands:\tspeed <speed>"
 			       " (<speed> is 0-65535)\n");
 
 	return len;
 }
 
-static int fan_write(char *buf)
+static int fan_set_level(int level)
 {
-	char *cmd;
-	int level, speed;
-
-	while ((cmd = next_cmd(&buf))) {
-		if (sfan_handle &&
-		    sscanf(cmd, "level %d", &level) == 1 &&
-		    level >= 0 && level <= 7) {
-			/* 570, 770x-JL */
+	switch (fan_control_access_mode) {
+	case IBMACPI_FAN_WR_ACPI_SFAN:
+		if (level >= 0 && level <= 7) {
 			if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
 				return -EIO;
-		} else if (!gfan_handle && strlencmp(cmd, "enable") == 0) {
-			/* all except 570, 600e/x, 770e, 770x */
-			if (!acpi_ec_write(fan_status_offset, 0x80))
-				return -EIO;
-		} else if (!gfan_handle && strlencmp(cmd, "disable") == 0) {
-			/* all except 570, 600e/x, 770e, 770x */
-			if (!acpi_ec_write(fan_status_offset, 0x00))
-				return -EIO;
-		} else if (fans_handle &&
-			   sscanf(cmd, "speed %d", &speed) == 1 &&
-			   speed >= 0 && speed <= 65535) {
-			/* X31, X40 */
+		} else
+			return -EINVAL;
+		break;
+
+	case IBMACPI_FAN_WR_ACPI_FANS:
+	case IBMACPI_FAN_WR_TPEC:
+		if ((level != IBMACPI_FAN_EC_AUTO) &&
+		    (level != IBMACPI_FAN_EC_DISENGAGED) &&
+		    ((level < 0) || (level > 7)))
+			return -EINVAL;
+
+		if (!acpi_ec_write(fan_status_offset, level))
+			return -EIO;
+		else
+			fan_control_status_known = 1;
+		break;
+
+	default:
+		return -ENXIO;
+	}
+	return 0;
+}
+
+static int fan_set_enable(void)
+{
+	u8 s;
+	int rc;
+
+	switch (fan_control_access_mode) {
+	case IBMACPI_FAN_WR_ACPI_FANS:
+	case IBMACPI_FAN_WR_TPEC:
+		if ((rc = fan_get_status(&s)) < 0)
+			return rc;
+
+		/* Don't go out of emergency fan mode */
+		if (s != 7)
+			s = IBMACPI_FAN_EC_AUTO;
+
+		if (!acpi_ec_write(fan_status_offset, s))
+			return -EIO;
+		else
+			fan_control_status_known = 1;
+		break;
+
+	case IBMACPI_FAN_WR_ACPI_SFAN:
+		if ((rc = fan_get_status(&s)) < 0)
+			return rc;
+
+		s &= 0x07;
+
+		/* Set fan to at least level 4 */
+		if (s < 4)
+			s = 4;
+
+		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
+			return -EIO;
+		break;
+
+	default:
+		return -ENXIO;
+	}
+	return 0;
+}
+
+static int fan_set_disable(void)
+{
+	switch (fan_control_access_mode) {
+	case IBMACPI_FAN_WR_ACPI_FANS:
+	case IBMACPI_FAN_WR_TPEC:
+		if (!acpi_ec_write(fan_status_offset, 0x00))
+			return -EIO;
+		else
+			fan_control_status_known = 1;
+		break;
+
+	case IBMACPI_FAN_WR_ACPI_SFAN:
+		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
+			return -EIO;
+		break;
+
+	default:
+		return -ENXIO;
+	}
+	return 0;
+}
+
+static int fan_set_speed(int speed)
+{
+	switch (fan_control_access_mode) {
+	case IBMACPI_FAN_WR_ACPI_FANS:
+		if (speed >= 0 && speed <= 65535) {
 			if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
 					speed, speed, speed))
 				return -EIO;
 		} else
 			return -EINVAL;
-	}
+		break;
 
+	default:
+		return -ENXIO;
+	}
 	return 0;
 }
 
+static int fan_write_cmd_level(const char *cmd, int *rc)
+{
+	int level;
+
+	if (strlencmp(cmd, "level auto") == 0)
+		level = IBMACPI_FAN_EC_AUTO;
+	else if (strlencmp(cmd, "level disengaged") == 0)
+		level = IBMACPI_FAN_EC_DISENGAGED;
+	else if (sscanf(cmd, "level %d", &level) != 1)
+		return 0;
+
+	if ((*rc = fan_set_level(level)) == -ENXIO)
+		printk(IBM_ERR "level command accepted for unsupported "
+		       "access mode %d", fan_control_access_mode);
+
+	return 1;
+}
+
+static int fan_write_cmd_enable(const char *cmd, int *rc)
+{
+	if (strlencmp(cmd, "enable") != 0)
+		return 0;
+
+	if ((*rc = fan_set_enable()) == -ENXIO)
+		printk(IBM_ERR "enable command accepted for unsupported "
+		       "access mode %d", fan_control_access_mode);
+
+	return 1;
+}
+
+static int fan_write_cmd_disable(const char *cmd, int *rc)
+{
+	if (strlencmp(cmd, "disable") != 0)
+		return 0;
+
+	if ((*rc = fan_set_disable()) == -ENXIO)
+		printk(IBM_ERR "disable command accepted for unsupported "
+		       "access mode %d", fan_control_access_mode);
+
+	return 1;
+}
+
+static int fan_write_cmd_speed(const char *cmd, int *rc)
+{
+	int speed;
+
+	/* TODO:
+	 * Support speed <low> <medium> <high> ? */
+
+	if (sscanf(cmd, "speed %d", &speed) != 1)
+		return 0;
+
+	if ((*rc = fan_set_speed(speed)) == -ENXIO)
+		printk(IBM_ERR "speed command accepted for unsupported "
+		       "access mode %d", fan_control_access_mode);
+
+	return 1;
+}
+
+static int fan_write_cmd_watchdog(const char *cmd, int *rc)
+{
+	int interval;
+
+	if (sscanf(cmd, "watchdog %d", &interval) != 1)
+		return 0;
+
+	if (interval < 0 || interval > 120)
+		*rc = -EINVAL;
+	else
+		fan_watchdog_maxinterval = interval;
+
+	return 1;
+}
+
+static int fan_write(char *buf)
+{
+	char *cmd;
+	int rc = 0;
+
+	while (!rc && (cmd = next_cmd(&buf))) {
+		if (!((fan_control_commands & IBMACPI_FAN_CMD_LEVEL) &&
+		      fan_write_cmd_level(cmd, &rc)) &&
+		    !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) &&
+		      (fan_write_cmd_enable(cmd, &rc) ||
+		       fan_write_cmd_disable(cmd, &rc) ||
+		       fan_write_cmd_watchdog(cmd, &rc))) &&
+		    !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) &&
+		      fan_write_cmd_speed(cmd, &rc))
+		    )
+			rc = -EINVAL;
+		else if (!rc)
+			fan_watchdog_reset();
+	}
+
+	return rc;
+}
+
+static void fan_watchdog_fire(struct work_struct *ignored)
+{
+	printk(IBM_NOTICE "fan watchdog: enabling fan\n");
+	if (fan_set_enable()) {
+		printk(IBM_ERR "fan watchdog: error while enabling fan\n");
+		/* reschedule for later */
+		fan_watchdog_reset();
+	}
+}
+
 static struct ibm_struct ibms[] = {
 	{
 	 .name = "driver",
-	 .init = driver_init,
+	 .init = ibm_acpi_driver_init,
 	 .read = driver_read,
 	 },
 	{
@@ -1662,6 +2354,7 @@
 	 .type = ACPI_SYSTEM_NOTIFY,
 	 },
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 	{
 	 .name = "bay",
 	 .init = bay_init,
@@ -1671,6 +2364,7 @@
 	 .handle = &bay_handle,
 	 .type = ACPI_SYSTEM_NOTIFY,
 	 },
+#endif
 	{
 	 .name = "cmos",
 	 .read = cmos_read,
@@ -1702,6 +2396,8 @@
 	 .name = "brightness",
 	 .read = brightness_read,
 	 .write = brightness_write,
+	 .init = brightness_init,
+	 .exit = brightness_exit,
 	 },
 	{
 	 .name = "volume",
@@ -1712,6 +2408,8 @@
 	 .name = "fan",
 	 .read = fan_read,
 	 .write = fan_write,
+	 .init = fan_init,
+	 .exit = fan_exit,
 	 .experimental = 1,
 	 },
 };
@@ -1719,7 +2417,7 @@
 static int dispatch_read(char *page, char **start, off_t off, int count,
 			 int *eof, void *data)
 {
-	struct ibm_struct *ibm = (struct ibm_struct *)data;
+	struct ibm_struct *ibm = data;
 	int len;
 
 	if (!ibm || !ibm->read)
@@ -1744,7 +2442,7 @@
 static int dispatch_write(struct file *file, const char __user * userbuf,
 			  unsigned long count, void *data)
 {
-	struct ibm_struct *ibm = (struct ibm_struct *)data;
+	struct ibm_struct *ibm = data;
 	char *kernbuf;
 	int ret;
 
@@ -1773,7 +2471,7 @@
 
 static void dispatch_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct ibm_struct *ibm = (struct ibm_struct *)data;
+	struct ibm_struct *ibm = data;
 
 	if (!ibm || !ibm->notify)
 		return;
@@ -1805,7 +2503,7 @@
 		       ibm->name, status);
 		return -ENODEV;
 	}
-
+	ibm->notify_installed = 1;
 	return 0;
 }
 
@@ -1818,14 +2516,13 @@
 {
 	int ret;
 
-	ibm->driver = kmalloc(sizeof(struct acpi_driver), GFP_KERNEL);
+	ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
 	if (!ibm->driver) {
 		printk(IBM_ERR "kmalloc(ibm->driver) failed\n");
 		return -1;
 	}
 
-	memset(ibm->driver, 0, sizeof(struct acpi_driver));
-	sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
+	sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
 	ibm->driver->ids = ibm->hid;
 	ibm->driver->ops.add = &ibm_device_add;
 
@@ -1882,7 +2579,6 @@
 		ret = setup_notify(ibm);
 		if (ret < 0)
 			return ret;
-		ibm->notify_installed = 1;
 	}
 
 	return 0;
@@ -1954,7 +2650,9 @@
 #ifdef CONFIG_ACPI_IBM_DOCK
 IBM_PARAM(dock);
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 IBM_PARAM(bay);
+#endif
 IBM_PARAM(cmos);
 IBM_PARAM(led);
 IBM_PARAM(beep);
@@ -1971,6 +2669,33 @@
 		ibm_exit(&ibms[i]);
 
 	remove_proc_entry(IBM_DIR, acpi_root_dir);
+
+	if (ibm_thinkpad_ec_found)
+		kfree(ibm_thinkpad_ec_found);
+}
+
+static char* __init check_dmi_for_ec(void)
+{
+	struct dmi_device *dev = NULL;
+	char ec_fw_string[18];
+
+	/*
+	 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
+	 * X32 or newer, all Z series;  Some models must have an
+	 * up-to-date BIOS or they will not be detected.
+	 *
+	 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
+	 */
+	while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
+		if (sscanf(dev->name,
+			   "IBM ThinkPad Embedded Controller -[%17c",
+			   ec_fw_string) == 1) {
+			ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
+			ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
+			return kstrdup(ec_fw_string, GFP_KERNEL);
+		}
+	}
+	return NULL;
 }
 
 static int __init acpi_ibm_init(void)
@@ -1992,6 +2717,12 @@
 		return -ENODEV;
 	}
 
+	/* Models with newer firmware report the EC in DMI */
+	ibm_thinkpad_ec_found = check_dmi_for_ec();
+	if (ibm_thinkpad_ec_found)
+		printk(IBM_INFO "ThinkPad EC firmware %s\n",
+		       ibm_thinkpad_ec_found);
+
 	/* these handles are not required */
 	IBM_HANDLE_INIT(vid);
 	IBM_HANDLE_INIT(vid2);
@@ -2004,12 +2735,14 @@
 	IBM_HANDLE_INIT(dock);
 #endif
 	IBM_HANDLE_INIT(pci);
+#ifdef CONFIG_ACPI_IBM_BAY
 	IBM_HANDLE_INIT(bay);
 	if (bay_handle)
 		IBM_HANDLE_INIT(bay_ej);
 	IBM_HANDLE_INIT(bay2);
 	if (bay2_handle)
 		IBM_HANDLE_INIT(bay2_ej);
+#endif
 	IBM_HANDLE_INIT(beep);
 	IBM_HANDLE_INIT(ecrd);
 	IBM_HANDLE_INIT(ecwr);
diff -ru 2.2/drivers/acpi/Kconfig 3.4/drivers/acpi/Kconfig
--- 2.2/drivers/acpi/Kconfig	2006-12-12 06:41:13.000000000 +0100
+++ 3.4/drivers/acpi/Kconfig	2006-12-23 16:57:57.000000000 +0100
@@ -11,7 +11,7 @@
 	bool "ACPI Support"
 	depends on IA64 || X86
 	depends on PCI
-	select PM
+	depends on PM
 	default y
 	---help---
 	  Advanced Configuration and Power Interface (ACPI) support for 
@@ -97,6 +97,7 @@
 
 config ACPI_BUTTON
 	tristate "Button"
+	depends on INPUT
 	default y
 	help
 	  This driver handles events on the power, sleep and lid buttons.
@@ -172,6 +173,7 @@
 config ACPI_ASUS
         tristate "ASUS/Medion Laptop Extras"
 	depends on X86
+	select BACKLIGHT_CLASS_DEVICE
         ---help---
           This driver provides support for extra features of ACPI-compatible
           ASUS laptops. As some of Medion laptops are made by ASUS, it may also
@@ -200,6 +202,7 @@
 config ACPI_IBM
 	tristate "IBM ThinkPad Laptop Extras"
 	depends on X86
+	select BACKLIGHT_CLASS_DEVICE
 	---help---
 	  This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
 	  support for Fn-Fx key combinations, Bluetooth control, video
@@ -222,9 +225,21 @@
 
 	  If you are not sure, say N here.
 
+config ACPI_IBM_BAY
+	bool "Legacy Removable Bay Support"
+	depends on ACPI_IBM
+	depends on ACPI_BAY=n
+	default n
+	---help---
+	  Allows the ibm_acpi driver to handle removable bays.
+	  This support is obsoleted by CONFIG_ACPI_BAY.
+
+	  If you are not sure, say N here.
+
 config ACPI_TOSHIBA
 	tristate "Toshiba Laptop Extras"
 	depends on X86
+	select BACKLIGHT_CLASS_DEVICE
 	---help---
 	  This driver adds support for access to certain system settings
 	  on "legacy free" Toshiba laptops.  These laptops can be recognized by
diff -ru 2.2/drivers/acpi/namespace/nsxfobj.c 3.4/drivers/acpi/namespace/nsxfobj.c
--- 2.2/drivers/acpi/namespace/nsxfobj.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/namespace/nsxfobj.c	2006-12-23 16:57:57.000000000 +0100
@@ -50,6 +50,50 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_get_id
+ *
+ * PARAMETERS:  Handle          - Handle of object whose id is desired
+ *              ret_id          - Where the id will be placed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This routine returns the owner id associated with a handle
+ *
+ ******************************************************************************/
+acpi_status acpi_get_id(acpi_handle handle, acpi_owner_id * ret_id)
+{
+	struct acpi_namespace_node *node;
+	acpi_status status;
+
+	/* Parameter Validation */
+
+	if (!ret_id) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Convert and validate the handle */
+
+	node = acpi_ns_map_handle_to_node(handle);
+	if (!node) {
+		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+		return (AE_BAD_PARAMETER);
+	}
+
+	*ret_id = node->owner_id;
+
+	status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+	return (status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_get_id)
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_get_type
  *
  * PARAMETERS:  Handle          - Handle of object whose type is desired
diff -ru 2.2/drivers/acpi/numa.c 3.4/drivers/acpi/numa.c
--- 2.2/drivers/acpi/numa.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/numa.c	2006-12-23 16:57:57.000000000 +0100
@@ -248,7 +248,7 @@
 		handle = phandle;
 		status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);
 		if (ACPI_SUCCESS(status))
-			return (int)pxm;
+			return pxm;
 		status = acpi_get_parent(handle, &phandle);
 	} while (ACPI_SUCCESS(status));
 	return -1;
diff -ru 2.2/drivers/acpi/osl.c 3.4/drivers/acpi/osl.c
--- 2.2/drivers/acpi/osl.c	2006-12-12 06:41:13.000000000 +0100
+++ 3.4/drivers/acpi/osl.c	2006-12-23 16:57:57.000000000 +0100
@@ -568,6 +568,7 @@
 static void acpi_os_execute_deferred(struct work_struct *work)
 {
 	struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
+
 	if (!dpc) {
 		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
 		return;
@@ -1031,7 +1032,7 @@
 acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
 {
 	*cache = kmem_cache_create(name, size, 0, 0, NULL, NULL);
-	if (cache == NULL)
+	if (*cache == NULL)
 		return AE_ERROR;
 	else
 		return AE_OK;
@@ -1051,7 +1052,7 @@
 
 acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
 {
-	(void)kmem_cache_shrink(cache);
+	kmem_cache_shrink(cache);
 	return (AE_OK);
 }
 
diff -ru 2.2/drivers/acpi/pci_bind.c 3.4/drivers/acpi/pci_bind.c
--- 2.2/drivers/acpi/pci_bind.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/pci_bind.c	2006-12-23 16:57:57.000000000 +0100
@@ -122,19 +122,17 @@
 	if (!device || !device->parent)
 		return -EINVAL;
 
-	pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
 	if (!pathname)
 		return -ENOMEM;
-	memset(pathname, 0, ACPI_PATHNAME_MAX);
 	buffer.length = ACPI_PATHNAME_MAX;
 	buffer.pointer = pathname;
 
-	data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
+	data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
 	if (!data) {
 		kfree(pathname);
 		return -ENOMEM;
 	}
-	memset(data, 0, sizeof(struct acpi_pci_data));
 
 	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n",
@@ -281,10 +279,9 @@
 	if (!device || !device->parent)
 		return -EINVAL;
 
-	pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
 	if (!pathname)
 		return -ENOMEM;
-	memset(pathname, 0, ACPI_PATHNAME_MAX);
 
 	buffer.length = ACPI_PATHNAME_MAX;
 	buffer.pointer = pathname;
@@ -331,11 +328,9 @@
 	char *pathname = NULL;
 	struct acpi_buffer buffer = { 0, NULL };
 
-
-	pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
 	if (!pathname)
 		return -ENOMEM;
-	memset(pathname, 0, ACPI_PATHNAME_MAX);
 
 	buffer.length = ACPI_PATHNAME_MAX;
 	buffer.pointer = pathname;
@@ -345,12 +340,11 @@
 		return -EINVAL;
 	}
 
-	data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
+	data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
 	if (!data) {
 		kfree(pathname);
 		return -ENOMEM;
 	}
-	memset(data, 0, sizeof(struct acpi_pci_data));
 
 	data->id = *id;
 	data->bus = bus;
diff -ru 2.2/drivers/acpi/pci_irq.c 3.4/drivers/acpi/pci_irq.c
--- 2.2/drivers/acpi/pci_irq.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/pci_irq.c	2006-12-23 16:57:57.000000000 +0100
@@ -89,10 +89,9 @@
 	if (!prt)
 		return -EINVAL;
 
-	entry = kmalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
+	entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
 	if (!entry)
 		return -ENOMEM;
-	memset(entry, 0, sizeof(struct acpi_prt_entry));
 
 	entry->id.segment = segment;
 	entry->id.bus = bus;
@@ -161,10 +160,9 @@
 	static int first_time = 1;
 
 
-	pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
 	if (!pathname)
 		return -ENOMEM;
-	memset(pathname, 0, ACPI_PATHNAME_MAX);
 
 	if (first_time) {
 		acpi_prt.count = 0;
@@ -198,11 +196,10 @@
 		return -ENODEV;
 	}
 
-	prt = kmalloc(buffer.length, GFP_KERNEL);
+	prt = kzalloc(buffer.length, GFP_KERNEL);
 	if (!prt) {
 		return -ENOMEM;
 	}
-	memset(prt, 0, buffer.length);
 	buffer.pointer = prt;
 
 	status = acpi_get_irq_routing_table(handle, &buffer);
diff -ru 2.2/drivers/acpi/pci_link.c 3.4/drivers/acpi/pci_link.c
--- 2.2/drivers/acpi/pci_link.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/acpi/pci_link.c	2006-12-23 16:57:57.000000000 +0100
@@ -103,7 +103,7 @@
 static acpi_status
 acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
 {
-	struct acpi_pci_link *link = (struct acpi_pci_link *)context;
+	struct acpi_pci_link *link = context;
 	u32 i = 0;
 
 
@@ -307,11 +307,10 @@
 	if (!link || !irq)
 		return -EINVAL;
 
-	resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
+	resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
 	if (!resource)
 		return -ENOMEM;
 
-	memset(resource, 0, sizeof(*resource) + 1);
 	buffer.length = sizeof(*resource) + 1;
 	buffer.pointer = resource;
 
@@ -613,7 +612,7 @@
 		return -1;
 	}
 
-	link = (struct acpi_pci_link *)acpi_driver_data(device);
+	link = acpi_driver_data(device);
 	if (!link) {
 		printk(KERN_ERR PREFIX "Invalid link context\n");
 		return -1;
@@ -668,7 +667,7 @@
 		return -1;
 	}
 
-	link = (struct acpi_pci_link *)acpi_driver_data(device);
+	link = acpi_driver_data(device);
 	if (!link) {
 		printk(KERN_ERR PREFIX "Invalid link context\n");
 		return -1;
@@ -718,10 +717,9 @@
 	if (!device)
 		return -EINVAL;
 
-	link = kmalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
+	link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
 	if (!link)
 		return -ENOMEM;
-	memset(link, 0, sizeof(struct acpi_pci_link));
 
 	link->device = device;
 	strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);
@@ -808,7 +806,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	link = (struct acpi_pci_link *)acpi_driver_data(device);
+	link = acpi_driver_data(device);
 
 	mutex_lock(&acpi_link_lock);
 	list_del(&link->node);
diff -ru 2.2/drivers/acpi/pci_root.c 3.4/drivers/acpi/pci_root.c
--- 2.2/drivers/acpi/pci_root.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/pci_root.c	2006-12-23 16:57:57.000000000 +0100
@@ -98,11 +98,12 @@
 
 	struct acpi_pci_driver **pptr = &sub_driver;
 	while (*pptr) {
-		if (*pptr != driver)
-			continue;
-		*pptr = (*pptr)->next;
-		break;
+		if (*pptr == driver)
+			break;
+		pptr = &(*pptr)->next;
 	}
+	BUG_ON(!*pptr);
+	*pptr = (*pptr)->next;
 
 	if (!driver->remove)
 		return;
@@ -119,7 +120,7 @@
 static acpi_status
 get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
 {
-	int *busnr = (int *)data;
+	int *busnr = data;
 	struct acpi_resource_address64 address;
 
 	if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
@@ -164,10 +165,9 @@
 	if (!device)
 		return -EINVAL;
 
-	root = kmalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
+	root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
 	if (!root)
 		return -ENOMEM;
-	memset(root, 0, sizeof(struct acpi_pci_root));
 	INIT_LIST_HEAD(&root->node);
 
 	root->device = device;
@@ -331,7 +331,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	root = (struct acpi_pci_root *)acpi_driver_data(device);
+	root = acpi_driver_data(device);
 
 	kfree(root);
 
diff -ru 2.2/drivers/acpi/power.c 3.4/drivers/acpi/power.c
--- 2.2/drivers/acpi/power.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/acpi/power.c	2006-12-23 16:57:57.000000000 +0100
@@ -108,7 +108,7 @@
 		return result;
 	}
 
-	*resource = (struct acpi_power_resource *)acpi_driver_data(device);
+	*resource = acpi_driver_data(device);
 	if (!resource)
 		return -ENODEV;
 
@@ -442,7 +442,7 @@
 	struct acpi_power_resource *resource = NULL;
 
 
-	resource = (struct acpi_power_resource *)seq->private;
+	resource = seq->private;
 
 	if (!resource)
 		goto end;
@@ -532,10 +532,9 @@
 	if (!device)
 		return -EINVAL;
 
-	resource = kmalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
+	resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
 	if (!resource)
 		return -ENOMEM;
-	memset(resource, 0, sizeof(struct acpi_power_resource));
 
 	resource->device = device;
 	strcpy(resource->name, device->pnp.bus_id);
@@ -590,7 +589,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	resource = (struct acpi_power_resource *)acpi_driver_data(device);
+	resource = acpi_driver_data(device);
 
 	acpi_power_remove_fs(device);
 
diff -ru 2.2/drivers/acpi/processor_core.c 3.4/drivers/acpi/processor_core.c
--- 2.2/drivers/acpi/processor_core.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/acpi/processor_core.c	2006-12-23 16:57:57.000000000 +0100
@@ -277,7 +277,7 @@
 
 static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+	struct acpi_processor *pr = seq->private;
 
 
 	if (!pr)
@@ -542,12 +542,12 @@
 	 * Don't trust it blindly
 	 */
 	if (processor_device_array[pr->id] != NULL &&
-	    processor_device_array[pr->id] != (void *)device) {
+	    processor_device_array[pr->id] != device) {
 		printk(KERN_WARNING "BIOS reported wrong ACPI id"
 			"for the processor\n");
 		return -ENODEV;
 	}
-	processor_device_array[pr->id] = (void *)device;
+	processor_device_array[pr->id] = device;
 
 	processors[pr->id] = pr;
 
@@ -578,7 +578,7 @@
 
 static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_processor *pr = (struct acpi_processor *)data;
+	struct acpi_processor *pr = data;
 	struct acpi_device *device = NULL;
 
 
@@ -615,10 +615,9 @@
 	if (!device)
 		return -EINVAL;
 
-	pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL);
+	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
 	if (!pr)
 		return -ENOMEM;
-	memset(pr, 0, sizeof(struct acpi_processor));
 
 	pr->handle = device->handle;
 	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
@@ -637,7 +636,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	pr = (struct acpi_processor *)acpi_driver_data(device);
+	pr = acpi_driver_data(device);
 
 	if (pr->id >= NR_CPUS) {
 		kfree(pr);
@@ -901,13 +900,13 @@
 
 	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
 	if (!acpi_processor_dir)
-		return 0;
+		return -ENOMEM;
 	acpi_processor_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&acpi_processor_driver);
 	if (result < 0) {
 		remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-		return 0;
+		return result;
 	}
 
 	acpi_processor_install_hotplug_notify();
diff -ru 2.2/drivers/acpi/processor_idle.c 3.4/drivers/acpi/processor_idle.c
--- 2.2/drivers/acpi/processor_idle.c	2006-10-20 23:43:44.000000000 +0200
+++ 3.4/drivers/acpi/processor_idle.c	2006-12-23 16:57:57.000000000 +0100
@@ -211,7 +211,11 @@
 static void acpi_safe_halt(void)
 {
 	current_thread_info()->status &= ~TS_POLLING;
-	smp_mb__after_clear_bit();
+	/*
+	 * TS_POLLING-cleared state must be visible before we
+	 * test NEED_RESCHED:
+	 */
+	smp_mb();
 	if (!need_resched())
 		safe_halt();
 	current_thread_info()->status |= TS_POLLING;
@@ -345,7 +349,11 @@
 	 */
 	if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
 		current_thread_info()->status &= ~TS_POLLING;
-		smp_mb__after_clear_bit();
+		/*
+		 * TS_POLLING-cleared state must be visible before we
+		 * test NEED_RESCHED:
+		 */
+		smp_mb();
 		if (need_resched()) {
 			current_thread_info()->status |= TS_POLLING;
 			local_irq_enable();
@@ -673,7 +681,7 @@
 		return -ENODEV;
 	}
 
-	cst = (union acpi_object *)buffer.pointer;
+	cst = buffer.pointer;
 
 	/* There must be at least 2 elements */
 	if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) {
@@ -702,14 +710,14 @@
 
 		memset(&cx, 0, sizeof(cx));
 
-		element = (union acpi_object *)&(cst->package.elements[i]);
+		element = &(cst->package.elements[i]);
 		if (element->type != ACPI_TYPE_PACKAGE)
 			continue;
 
 		if (element->package.count != 4)
 			continue;
 
-		obj = (union acpi_object *)&(element->package.elements[0]);
+		obj = &(element->package.elements[0]);
 
 		if (obj->type != ACPI_TYPE_BUFFER)
 			continue;
@@ -721,7 +729,7 @@
 			continue;
 
 		/* There should be an easy way to extract an integer... */
-		obj = (union acpi_object *)&(element->package.elements[1]);
+		obj = &(element->package.elements[1]);
 		if (obj->type != ACPI_TYPE_INTEGER)
 			continue;
 
@@ -754,13 +762,13 @@
 			}
 		}
 
-		obj = (union acpi_object *)&(element->package.elements[2]);
+		obj = &(element->package.elements[2]);
 		if (obj->type != ACPI_TYPE_INTEGER)
 			continue;
 
 		cx.latency = obj->integer.value;
 
-		obj = (union acpi_object *)&(element->package.elements[3]);
+		obj = &(element->package.elements[3]);
 		if (obj->type != ACPI_TYPE_INTEGER)
 			continue;
 
@@ -1029,7 +1037,7 @@
 
 static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+	struct acpi_processor *pr = seq->private;
 	unsigned int i;
 
 
diff -ru 2.2/drivers/acpi/processor_perflib.c 3.4/drivers/acpi/processor_perflib.c
--- 2.2/drivers/acpi/processor_perflib.c	2006-11-24 18:40:27.000000000 +0100
+++ 3.4/drivers/acpi/processor_perflib.c	2006-12-23 16:57:57.000000000 +0100
@@ -236,7 +236,7 @@
 		return -ENODEV;
 	}
 
-	pss = (union acpi_object *)buffer.pointer;
+	pss = buffer.pointer;
 	if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
 		printk(KERN_ERR PREFIX "Invalid _PSS data\n");
 		result = -EFAULT;
@@ -410,7 +410,7 @@
 
 static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+	struct acpi_processor *pr = seq->private;
 	int i;
 
 
@@ -451,8 +451,8 @@
 				 size_t count, loff_t * data)
 {
 	int result = 0;
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_processor *pr = (struct acpi_processor *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_processor *pr = m->private;
 	struct acpi_processor_performance *perf;
 	char state_string[12] = { '\0' };
 	unsigned int new_state = 0;
@@ -551,7 +551,7 @@
 		return -ENODEV;
 	}
 
-	psd = (union acpi_object *) buffer.pointer;
+	psd = buffer.pointer;
 	if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
 		result = -EFAULT;
diff -ru 2.2/drivers/acpi/processor_thermal.c 3.4/drivers/acpi/processor_thermal.c
--- 2.2/drivers/acpi/processor_thermal.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/processor_thermal.c	2006-12-23 16:57:57.000000000 +0100
@@ -208,7 +208,7 @@
 	if (result)
 		return result;
 
-	pr = (struct acpi_processor *)acpi_driver_data(device);
+	pr = acpi_driver_data(device);
 	if (!pr)
 		return -ENODEV;
 
@@ -348,8 +348,8 @@
 					  size_t count, loff_t * data)
 {
 	int result = 0;
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_processor *pr = (struct acpi_processor *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_processor *pr = m->private;
 	char limit_string[25] = { '\0' };
 	int px = 0;
 	int tx = 0;
diff -ru 2.2/drivers/acpi/processor_throttling.c 3.4/drivers/acpi/processor_throttling.c
--- 2.2/drivers/acpi/processor_throttling.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/processor_throttling.c	2006-12-23 16:57:57.000000000 +0100
@@ -259,7 +259,7 @@
 static int acpi_processor_throttling_seq_show(struct seq_file *seq,
 					      void *offset)
 {
-	struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+	struct acpi_processor *pr = seq->private;
 	int i = 0;
 	int result = 0;
 
@@ -307,8 +307,8 @@
 					       size_t count, loff_t * data)
 {
 	int result = 0;
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_processor *pr = (struct acpi_processor *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_processor *pr = m->private;
 	char state_string[12] = { '\0' };
 
 
diff -ru 2.2/drivers/acpi/sbs.c 3.4/drivers/acpi/sbs.c
--- 2.2/drivers/acpi/sbs.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/acpi/sbs.c	2006-12-23 16:57:57.000000000 +0100
@@ -923,7 +923,7 @@
 
 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 {
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct acpi_battery *battery = seq->private;
 	int cscale;
 	int result = 0;
 
@@ -1076,7 +1076,7 @@
 
 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
 {
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct acpi_battery *battery = seq->private;
 	int result = 0;
 	int cscale;
 
@@ -1125,8 +1125,8 @@
 acpi_battery_write_alarm(struct file *file, const char __user * buffer,
 			 size_t count, loff_t * ppos)
 {
-	struct seq_file *seq = (struct seq_file *)file->private_data;
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct seq_file *seq = file->private_data;
+	struct acpi_battery *battery = seq->private;
 	char alarm_string[12] = { '\0' };
 	int result, old_alarm, new_alarm;
 
@@ -1160,14 +1160,14 @@
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "acpi_battery_set_alarm() failed\n"));
-		(void)acpi_battery_set_alarm(battery, old_alarm);
+		acpi_battery_set_alarm(battery, old_alarm);
 		goto end;
 	}
 	result = acpi_battery_get_alarm(battery);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "acpi_battery_get_alarm() failed\n"));
-		(void)acpi_battery_set_alarm(battery, old_alarm);
+		acpi_battery_set_alarm(battery, old_alarm);
 		goto end;
 	}
 
@@ -1217,7 +1217,7 @@
 
 static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 {
-	struct acpi_sbs *sbs = (struct acpi_sbs *)seq->private;
+	struct acpi_sbs *sbs = seq->private;
 	int result;
 
 	if (sbs->zombie) {
@@ -1302,7 +1302,7 @@
 		battery->init_state = 1;
 	}
 
-	(void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+	sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
 
 	result = acpi_sbs_generic_add_fs(&battery->battery_entry,
 					 acpi_battery_dir,
@@ -1485,7 +1485,7 @@
 		}
 
 		if (old_battery_present != new_battery_present) {
-			(void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+			sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
 			result = acpi_sbs_generate_event(sbs->device,
 							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
 							 new_battery_present,
@@ -1498,7 +1498,7 @@
 			}
 		}
 		if (old_remaining_capacity != battery->state.remaining_capacity) {
-			(void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+			sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
 			result = acpi_sbs_generate_event(sbs->device,
 							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
 							 new_battery_present,
@@ -1576,12 +1576,11 @@
 	int id, cnt;
 	acpi_status status = AE_OK;
 
-	sbs = kmalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
+	sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
 	if (!sbs) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n"));
 		return -ENOMEM;
 	}
-	memset(sbs, 0, sizeof(struct acpi_sbs));
 
 	cnt = 0;
 	while (cnt < 10) {
@@ -1659,7 +1658,7 @@
 	init_timer(&sbs->update_timer);
 	if (update_mode == QUEUE_UPDATE_MODE) {
 		status = acpi_os_execute(OSL_GPE_HANDLER,
-					 acpi_sbs_update_queue, (void *)sbs);
+					 acpi_sbs_update_queue, sbs);
 		if (status != AE_OK) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 					  "acpi_os_execute() failed\n"));
@@ -1685,7 +1684,7 @@
 
 int acpi_sbs_remove(struct acpi_device *device, int type)
 {
-	struct acpi_sbs *sbs = NULL;
+	struct acpi_sbs *sbs;
 	int id;
 
 	if (!device) {
diff -ru 2.2/drivers/acpi/scan.c 3.4/drivers/acpi/scan.c
--- 2.2/drivers/acpi/scan.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/scan.c	2006-12-23 16:57:57.000000000 +0100
@@ -984,12 +984,11 @@
 	if (!child)
 		return -EINVAL;
 
-	device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL);
+	device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
 	if (!device) {
 		printk(KERN_ERR PREFIX "Memory allocation error\n");
 		return -ENOMEM;
 	}
-	memset(device, 0, sizeof(struct acpi_device));
 
 	device->handle = handle;
 	device->parent = parent;
diff -ru 2.2/drivers/acpi/sleep/wakeup.c 3.4/drivers/acpi/sleep/wakeup.c
--- 2.2/drivers/acpi/sleep/wakeup.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/sleep/wakeup.c	2006-12-23 16:57:57.000000000 +0100
@@ -183,11 +183,11 @@
 #endif
 
 /*
- * Disable all wakeup GPEs before power off.
- * 
+ * Disable all wakeup GPEs before entering requested sleep state.
+ *	@sleep_state:	ACPI state
  * Since acpi_enter_sleep_state() will disable all
  * RUNTIME GPEs, we simply mark all GPES that
- * are not enabled for wakeup from S5 as RUNTIME.
+ * are not enabled for wakeup from requested state as RUNTIME.
  */
 void acpi_gpe_sleep_prepare(u32 sleep_state)
 {
diff -ru 2.2/drivers/acpi/tables/tbxface.c 3.4/drivers/acpi/tables/tbxface.c
--- 2.2/drivers/acpi/tables/tbxface.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/tables/tbxface.c	2006-12-23 16:57:57.000000000 +0100
@@ -123,7 +123,6 @@
 
 ACPI_EXPORT_SYMBOL(acpi_load_tables)
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_load_table
@@ -221,6 +220,59 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_unload_table_id
+ *
+ * PARAMETERS:  table_type    - Type of table to be unloaded
+ *              id            - Owner ID of the table to be removed.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This routine is used to force the unload of a table (by id)
+ *
+ ******************************************************************************/
+acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id)
+{
+	struct acpi_table_desc *table_desc;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(acpi_unload_table);
+
+	/* Parameter validation */
+	if (table_type > ACPI_TABLE_ID_MAX)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	/* Find table from the requested type list */
+	table_desc = acpi_gbl_table_lists[table_type].next;
+	while (table_desc && table_desc->owner_id != id)
+		table_desc = table_desc->next;
+
+	if (!table_desc)
+		return_ACPI_STATUS(AE_NOT_EXIST);
+
+	/*
+	 * Delete all namespace objects owned by this table. Note that these
+	 * objects can appear anywhere in the namespace by virtue of the AML
+	 * "Scope" operator. Thus, we need to track ownership by an ID, not
+	 * simply a position within the hierarchy
+	 */
+	acpi_ns_delete_namespace_by_owner(table_desc->owner_id);
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(status);
+
+	(void)acpi_tb_uninstall_table(table_desc);
+
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
+
+#ifdef ACPI_FUTURE_USAGE
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_unload_table
  *
  * PARAMETERS:  table_type    - Type of table to be unloaded
diff -ru 2.2/drivers/acpi/tables.c 3.4/drivers/acpi/tables.c
--- 2.2/drivers/acpi/tables.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/tables.c	2006-12-23 16:57:57.000000000 +0100
@@ -228,7 +228,7 @@
 static int
 acpi_table_compute_checksum(void *table_pointer, unsigned long length)
 {
-	u8 *p = (u8 *) table_pointer;
+	u8 *p = table_pointer;
 	unsigned long remains = length;
 	unsigned long sum = 0;
 
diff -ru 2.2/drivers/acpi/thermal.c 3.4/drivers/acpi/thermal.c
--- 2.2/drivers/acpi/thermal.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/thermal.c	2006-12-23 16:57:57.000000000 +0100
@@ -663,7 +663,7 @@
 static void acpi_thermal_check(void *data)
 {
 	int result = 0;
-	struct acpi_thermal *tz = (struct acpi_thermal *)data;
+	struct acpi_thermal *tz = data;
 	unsigned long sleep_time = 0;
 	int i = 0;
 	struct acpi_thermal_state state;
@@ -778,7 +778,7 @@
 
 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+	struct acpi_thermal *tz = seq->private;
 
 
 	if (!tz)
@@ -813,7 +813,7 @@
 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
 {
 	int result = 0;
-	struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+	struct acpi_thermal *tz = seq->private;
 
 
 	if (!tz)
@@ -837,7 +837,7 @@
 
 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+	struct acpi_thermal *tz = seq->private;
 	int i = 0;
 	int j = 0;
 
@@ -893,8 +893,8 @@
 			       const char __user * buffer,
 			       size_t count, loff_t * ppos)
 {
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_thermal *tz = m->private;
 
 	char *limit_string;
 	int num, critical, hot, passive;
@@ -902,12 +902,10 @@
 	int i = 0;
 
 
-	limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
+	limit_string = kzalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
 	if (!limit_string)
 		return -ENOMEM;
 
-	memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN);
-
 	active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL);
 	if (!active) {
 		kfree(limit_string);
@@ -953,7 +951,7 @@
 
 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+	struct acpi_thermal *tz = seq->private;
 
 
 	if (!tz)
@@ -984,8 +982,8 @@
 				const char __user * buffer,
 				size_t count, loff_t * ppos)
 {
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_thermal *tz = m->private;
 	int result = 0;
 	char mode_string[12] = { '\0' };
 
@@ -1014,7 +1012,7 @@
 
 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+	struct acpi_thermal *tz = seq->private;
 
 
 	if (!tz)
@@ -1043,8 +1041,8 @@
 			   const char __user * buffer,
 			   size_t count, loff_t * ppos)
 {
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_thermal *tz = m->private;
 	int result = 0;
 	char polling_string[12] = { '\0' };
 	int seconds = 0;
@@ -1170,7 +1168,7 @@
 
 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_thermal *tz = (struct acpi_thermal *)data;
+	struct acpi_thermal *tz = data;
 	struct acpi_device *device = NULL;
 
 
@@ -1271,10 +1269,9 @@
 	if (!device)
 		return -EINVAL;
 
-	tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
+	tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
 	if (!tz)
 		return -ENOMEM;
-	memset(tz, 0, sizeof(struct acpi_thermal));
 
 	tz->device = device;
 	strcpy(tz->name, device->pnp.bus_id);
@@ -1324,7 +1321,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	tz = (struct acpi_thermal *)acpi_driver_data(device);
+	tz = acpi_driver_data(device);
 
 	/* avoid timer adding new defer task */
 	tz->zombie = 1;
@@ -1364,7 +1361,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	tz = (struct acpi_thermal *)acpi_driver_data(device);
+	tz = acpi_driver_data(device);
 
 	acpi_thermal_get_temperature(tz);
 
diff -ru 2.2/drivers/acpi/toshiba_acpi.c 3.4/drivers/acpi/toshiba_acpi.c
--- 2.2/drivers/acpi/toshiba_acpi.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/toshiba_acpi.c	2006-12-23 16:57:57.000000000 +0100
@@ -41,6 +41,8 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
+#include <linux/backlight.h>
+
 #include <asm/uaccess.h>
 
 #include <acpi/acpi_drivers.h>
@@ -210,6 +212,7 @@
 }
 
 static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
+static struct backlight_device *toshiba_backlight_device;
 static int force_fan;
 static int last_key_event;
 static int key_event_valid;
@@ -271,14 +274,23 @@
 	return result;
 }
 
-static char *read_lcd(char *p)
+static int get_lcd(struct backlight_device *bd)
 {
 	u32 hci_result;
 	u32 value;
 
 	hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result);
 	if (hci_result == HCI_SUCCESS) {
-		value = value >> HCI_LCD_BRIGHTNESS_SHIFT;
+		return (value >> HCI_LCD_BRIGHTNESS_SHIFT);
+	} else
+		return -EFAULT;
+}
+
+static char *read_lcd(char *p)
+{
+	int value = get_lcd(NULL);
+
+	if (value >= 0) {
 		p += sprintf(p, "brightness:              %d\n", value);
 		p += sprintf(p, "brightness_levels:       %d\n",
 			     HCI_LCD_BRIGHTNESS_LEVELS);
@@ -289,22 +301,34 @@
 	return p;
 }
 
+static int set_lcd(int value)
+{
+	u32 hci_result;
+
+	value = value << HCI_LCD_BRIGHTNESS_SHIFT;
+	hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result);
+	if (hci_result != HCI_SUCCESS)
+		return -EFAULT;
+
+	return 0;
+}
+
+static int set_lcd_status(struct backlight_device *bd)
+{
+	return set_lcd(bd->props->brightness);
+}
+
 static unsigned long write_lcd(const char *buffer, unsigned long count)
 {
 	int value;
-	u32 hci_result;
+	int ret = count;
 
 	if (sscanf(buffer, " brightness : %i", &value) == 1 &&
-	    value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
-		value = value << HCI_LCD_BRIGHTNESS_SHIFT;
-		hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result);
-		if (hci_result != HCI_SUCCESS)
-			return -EFAULT;
-	} else {
-		return -EINVAL;
-	}
-
-	return count;
+	    value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS)
+		ret = set_lcd(value);
+	else
+		ret = -EINVAL;
+	return ret;
 }
 
 static char *read_video(char *p)
@@ -506,6 +530,26 @@
 	return AE_OK;
 }
 
+static struct backlight_properties toshiba_backlight_data = {
+        .owner          = THIS_MODULE,
+        .get_brightness = get_lcd,
+        .update_status  = set_lcd_status,
+        .max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1,
+};
+
+static void __exit toshiba_acpi_exit(void)
+{
+	if (toshiba_backlight_device)
+		backlight_device_unregister(toshiba_backlight_device);
+
+	remove_device();
+
+	if (toshiba_proc_dir)
+		remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
+
+	return;
+}
+
 static int __init toshiba_acpi_init(void)
 {
 	acpi_status status = AE_OK;
@@ -546,17 +590,16 @@
 			remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
 	}
 
-	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
-}
-
-static void __exit toshiba_acpi_exit(void)
-{
-	remove_device();
-
-	if (toshiba_proc_dir)
-		remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
+	toshiba_backlight_device = backlight_device_register("toshiba",NULL,
+						NULL,
+						&toshiba_backlight_data);
+        if (IS_ERR(toshiba_backlight_device)) {
+		printk(KERN_ERR "Could not register toshiba backlight device\n");
+		toshiba_backlight_device = NULL;
+		toshiba_acpi_exit();
+	}
 
-	return;
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
 }
 
 module_init(toshiba_acpi_init);
diff -ru 2.2/drivers/acpi/utilities/utdebug.c 3.4/drivers/acpi/utilities/utdebug.c
--- 2.2/drivers/acpi/utilities/utdebug.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/utilities/utdebug.c	2006-12-23 16:57:57.000000000 +0100
@@ -180,8 +180,9 @@
 	if (thread_id != acpi_gbl_prev_thread_id) {
 		if (ACPI_LV_THREADS & acpi_dbg_level) {
 			acpi_os_printf
-			    ("\n**** Context Switch from TID %X to TID %X ****\n\n",
-			     (u32) acpi_gbl_prev_thread_id, (u32) thread_id);
+			    ("\n**** Context Switch from TID %lX to TID %lX ****\n\n",
+			     (unsigned long) acpi_gbl_prev_thread_id,
+			     (unsigned long) thread_id);
 		}
 
 		acpi_gbl_prev_thread_id = thread_id;
diff -ru 2.2/drivers/acpi/utilities/utmutex.c 3.4/drivers/acpi/utilities/utmutex.c
--- 2.2/drivers/acpi/utilities/utmutex.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/utilities/utmutex.c	2006-12-23 16:57:57.000000000 +0100
@@ -243,23 +243,24 @@
 #endif
 
 	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
-			  "Thread %X attempting to acquire Mutex [%s]\n",
-			  (u32) this_thread_id, acpi_ut_get_mutex_name(mutex_id)));
+			  "Thread %lX attempting to acquire Mutex [%s]\n",
+			  (unsigned long) this_thread_id,
+			  acpi_ut_get_mutex_name(mutex_id)));
 
 	status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
 				       ACPI_WAIT_FOREVER);
 	if (ACPI_SUCCESS(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
-				  "Thread %X acquired Mutex [%s]\n",
-				  (u32) this_thread_id,
+				  "Thread %lX acquired Mutex [%s]\n",
+				  (unsigned long) this_thread_id,
 				  acpi_ut_get_mutex_name(mutex_id)));
 
 		acpi_gbl_mutex_info[mutex_id].use_count++;
 		acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
 	} else {
 		ACPI_EXCEPTION((AE_INFO, status,
-				"Thread %X could not acquire Mutex [%X]",
-				(u32) this_thread_id, mutex_id));
+				"Thread %lX could not acquire Mutex [%X]",
+				(unsigned long) this_thread_id, mutex_id));
 	}
 
 	return (status);
@@ -285,7 +286,8 @@
 
 	this_thread_id = acpi_os_get_thread_id();
 	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
-			  "Thread %X releasing Mutex [%s]\n", (u32) this_thread_id,
+			  "Thread %lX releasing Mutex [%s]\n",
+			  (unsigned long) this_thread_id,
 			  acpi_ut_get_mutex_name(mutex_id)));
 
 	if (mutex_id > ACPI_MAX_MUTEX) {
diff -ru 2.2/drivers/acpi/utils.c 3.4/drivers/acpi/utils.c
--- 2.2/drivers/acpi/utils.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/utils.c	2006-12-23 16:57:57.000000000 +0100
@@ -83,7 +83,7 @@
 		return AE_BAD_DATA;
 	}
 
-	format_string = (char *)format->pointer;
+	format_string = format->pointer;
 
 	/*
 	 * Calculate size_required.
@@ -262,11 +262,10 @@
 	if (!data)
 		return AE_BAD_PARAMETER;
 
-	element = kmalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
+	element = kzalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
 	if (!element)
 		return AE_NO_MEMORY;
 
-	memset(element, 0, sizeof(union acpi_object));
 	buffer.length = sizeof(union acpi_object);
 	buffer.pointer = element;
 	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
@@ -321,12 +320,11 @@
 		return AE_BAD_DATA;
 	}
 
-	*data = kmalloc(element->string.length + 1, GFP_KERNEL);
+	*data = kzalloc(element->string.length + 1, GFP_KERNEL);
 	if (!data) {
 		printk(KERN_ERR PREFIX "Memory allocation\n");
 		return -ENOMEM;
 	}
-	memset(*data, 0, element->string.length + 1);
 
 	memcpy(*data, element->string.pointer, element->string.length);
 
@@ -361,7 +359,7 @@
 	if (ACPI_FAILURE(status))
 		goto end;
 
-	package = (union acpi_object *)buffer.pointer;
+	package = buffer.pointer;
 
 	if ((buffer.length == 0) || !package) {
 		printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n",
diff -ru 2.2/drivers/acpi/video.c 3.4/drivers/acpi/video.c
--- 2.2/drivers/acpi/video.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/acpi/video.c	2006-12-23 16:57:57.000000000 +0100
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
  *  Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
+ *  Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
@@ -47,11 +48,11 @@
 #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT	0x83
 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT	0x84
 
-#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS	0x82
-#define	ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS	0x83
-#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS	0x84
-#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS	0x85
-#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF		0x86
+#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS	0x85
+#define	ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS	0x86
+#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS	0x87
+#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS	0x88
+#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF		0x89
 
 #define ACPI_VIDEO_HEAD_INVALID		(~0u - 1)
 #define ACPI_VIDEO_HEAD_END		(~0u)
@@ -386,7 +387,7 @@
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
-	obj = (union acpi_object *)buffer.pointer;
+	obj = buffer.pointer;
 
 	if (obj && obj->type == ACPI_TYPE_BUFFER)
 		*edid = obj;
@@ -532,11 +533,10 @@
 		int count = 0;
 		union acpi_object *o;
 
-		br = kmalloc(sizeof(*br), GFP_KERNEL);
+		br = kzalloc(sizeof(*br), GFP_KERNEL);
 		if (!br) {
 			printk(KERN_ERR "can't allocate memory\n");
 		} else {
-			memset(br, 0, sizeof(*br));
 			br->levels = kmalloc(obj->package.count *
 					     sizeof *(br->levels), GFP_KERNEL);
 			if (!br->levels)
@@ -654,8 +654,7 @@
 
 static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_video_device *dev =
-	    (struct acpi_video_device *)seq->private;
+	struct acpi_video_device *dev = seq->private;
 
 
 	if (!dev)
@@ -688,8 +687,7 @@
 static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
 {
 	int status;
-	struct acpi_video_device *dev =
-	    (struct acpi_video_device *)seq->private;
+	struct acpi_video_device *dev = seq->private;
 	unsigned long state;
 
 
@@ -727,8 +725,8 @@
 			      size_t count, loff_t * data)
 {
 	int status;
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_video_device *dev = (struct acpi_video_device *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_video_device *dev = m->private;
 	char str[12] = { 0 };
 	u32 state = 0;
 
@@ -754,8 +752,7 @@
 static int
 acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_video_device *dev =
-	    (struct acpi_video_device *)seq->private;
+	struct acpi_video_device *dev = seq->private;
 	int i;
 
 
@@ -784,8 +781,8 @@
 				   const char __user * buffer,
 				   size_t count, loff_t * data)
 {
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_video_device *dev = (struct acpi_video_device *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_video_device *dev = m->private;
 	char str[4] = { 0 };
 	unsigned int level = 0;
 	int i;
@@ -817,8 +814,7 @@
 
 static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_video_device *dev =
-	    (struct acpi_video_device *)seq->private;
+	struct acpi_video_device *dev = seq->private;
 	int status;
 	int i;
 	union acpi_object *edid = NULL;
@@ -866,7 +862,7 @@
 	if (!device)
 		return -ENODEV;
 
-	vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
+	vid_dev = acpi_driver_data(device);
 	if (!vid_dev)
 		return -ENODEV;
 
@@ -931,7 +927,7 @@
 {
 	struct acpi_video_device *vid_dev;
 
-	vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
+	vid_dev = acpi_driver_data(device);
 	if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
 		return -ENODEV;
 
@@ -950,7 +946,7 @@
 /* video bus */
 static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+	struct acpi_video_bus *video = seq->private;
 
 
 	if (!video)
@@ -975,7 +971,7 @@
 
 static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+	struct acpi_video_bus *video = seq->private;
 
 
 	if (!video)
@@ -995,7 +991,7 @@
 
 static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+	struct acpi_video_bus *video = seq->private;
 	unsigned long options;
 	int status;
 
@@ -1033,7 +1029,7 @@
 
 static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+	struct acpi_video_bus *video = seq->private;
 	int status;
 	unsigned long id;
 
@@ -1054,7 +1050,7 @@
 
 static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+	struct acpi_video_bus *video = seq->private;
 
 
 	seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
@@ -1079,8 +1075,8 @@
 			  size_t count, loff_t * data)
 {
 	int status;
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_video_bus *video = (struct acpi_video_bus *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_video_bus *video = m->private;
 	char str[12] = { 0 };
 	unsigned long opt, options;
 
@@ -1119,8 +1115,8 @@
 			 size_t count, loff_t * data)
 {
 	int status;
-	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct acpi_video_bus *video = (struct acpi_video_bus *)m->private;
+	struct seq_file *m = file->private_data;
+	struct acpi_video_bus *video = m->private;
 	char str[12] = { 0 };
 	unsigned long opt;
 
@@ -1150,7 +1146,7 @@
 	struct acpi_video_bus *video;
 
 
-	video = (struct acpi_video_bus *)acpi_driver_data(device);
+	video = acpi_driver_data(device);
 
 	if (!acpi_device_dir(device)) {
 		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
@@ -1226,7 +1222,7 @@
 	struct acpi_video_bus *video;
 
 
-	video = (struct acpi_video_bus *)acpi_driver_data(device);
+	video = acpi_driver_data(device);
 
 	if (acpi_device_dir(device)) {
 		remove_proc_entry("info", acpi_device_dir(device));
@@ -1263,12 +1259,10 @@
 	    acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
 	if (ACPI_SUCCESS(status)) {
 
-		data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
+		data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
 		if (!data)
 			return -ENOMEM;
 
-		memset(data, 0, sizeof(struct acpi_video_device));
-
 		strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
 		strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
 		acpi_driver_data(device) = data;
@@ -1403,7 +1397,7 @@
 		return status;
 	}
 
-	dod = (union acpi_object *)buffer.pointer;
+	dod = buffer.pointer;
 	if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
 		ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
 		status = -EFAULT;
@@ -1426,7 +1420,7 @@
 
 	count = 0;
 	for (i = 0; i < dod->package.count; i++) {
-		obj = (union acpi_object *)&dod->package.elements[i];
+		obj = &dod->package.elements[i];
 
 		if (obj->type != ACPI_TYPE_INTEGER) {
 			printk(KERN_ERR PREFIX "Invalid _DOD data\n");
@@ -1509,8 +1503,34 @@
 acpi_video_get_next_level(struct acpi_video_device *device,
 			  u32 level_current, u32 event)
 {
-	/*Fix me */
-	return level_current;
+	int min, max, min_above, max_below, i, l;
+	max = max_below = 0;
+	min = min_above = 255;
+	for (i = 0; i < device->brightness->count; i++) {
+		l = device->brightness->levels[i];
+		if (l < min)
+			min = l;
+		if (l > max)
+			max = l;
+		if (l < min_above && l > level_current)
+			min_above = l;
+		if (l > max_below && l < level_current)
+			max_below = l;
+	}
+
+	switch (event) {
+	case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
+		return (level_current < max) ? min_above : min;
+	case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
+		return (level_current < max) ? min_above : max;
+	case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
+		return (level_current > min) ? max_below : min;
+	case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
+	case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
+		return 0;
+	default:
+		return level_current;
+	}
 }
 
 static void
@@ -1612,7 +1632,7 @@
 
 static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_video_bus *video = (struct acpi_video_bus *)data;
+	struct acpi_video_bus *video = data;
 	struct acpi_device *device = NULL;
 
 	printk("video bus notify\n");
@@ -1654,8 +1674,7 @@
 
 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_video_device *video_device =
-	    (struct acpi_video_device *)data;
+	struct acpi_video_device *video_device = data;
 	struct acpi_device *device = NULL;
 
 
@@ -1696,10 +1715,9 @@
 	if (!device)
 		return -EINVAL;
 
-	video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
+	video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
 	if (!video)
 		return -ENOMEM;
-	memset(video, 0, sizeof(struct acpi_video_bus));
 
 	video->device = device;
 	strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
@@ -1757,7 +1775,7 @@
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	video = (struct acpi_video_bus *)acpi_driver_data(device);
+	video = acpi_driver_data(device);
 
 	acpi_video_bus_stop_devices(video);
 
diff -ru 2.2/drivers/ata/ahci.c 3.4/drivers/ata/ahci.c
--- 2.2/drivers/ata/ahci.c	2006-12-07 02:52:09.000000000 +0100
+++ 3.4/drivers/ata/ahci.c	2006-12-22 01:57:07.000000000 +0100
@@ -402,6 +402,14 @@
 	{ PCI_VDEVICE(NVIDIA, 0x044d), board_ahci },		/* MCP65 */
 	{ PCI_VDEVICE(NVIDIA, 0x044e), board_ahci },		/* MCP65 */
 	{ PCI_VDEVICE(NVIDIA, 0x044f), board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x045c), board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x045d), board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x045e), board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x045f), board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x0550), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0551), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0552), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0553), board_ahci },		/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci },		/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci },		/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci },		/* MCP67 */
@@ -645,8 +653,6 @@
 	u32 cap_save, impl_save, tmp;
 
 	cap_save = readl(mmio + HOST_CAP);
-	cap_save &= ( (1<<28) | (1<<17) );
-	cap_save |= (1 << 27);
 	impl_save = readl(mmio + HOST_PORTS_IMPL);
 
 	/* global controller reset */
diff -ru 2.2/drivers/ata/ata_piix.c 3.4/drivers/ata/ata_piix.c
--- 2.2/drivers/ata/ata_piix.c	2006-12-15 18:16:22.000000000 +0100
+++ 3.4/drivers/ata/ata_piix.c	2006-12-16 22:22:59.000000000 +0100
@@ -226,14 +226,26 @@
 	{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
 	/* 2801GBM/GHM (ICH7M, identical to ICH6M) */
 	{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
-	/* Enterprise Southbridge 2 (where's the datasheet?) */
+	/* Enterprise Southbridge 2 (631xESB/632xESB) */
 	{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
-	/* SATA Controller 1 IDE (ICH8, no datasheet yet) */
+	/* SATA Controller 1 IDE (ICH8) */
 	{ 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
-	/* SATA Controller 2 IDE (ICH8, ditto) */
+	/* SATA Controller 2 IDE (ICH8) */
 	{ 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
-	/* Mobile SATA Controller IDE (ICH8M, ditto) */
+	/* Mobile SATA Controller IDE (ICH8M) */
 	{ 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+	/* SATA Controller IDE (ICH9) */
+	{ 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+	/* SATA Controller IDE (ICH9) */
+	{ 0x8086, 0x2921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+	/* SATA Controller IDE (ICH9) */
+	{ 0x8086, 0x2926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+	/* SATA Controller IDE (ICH9M) */
+	{ 0x8086, 0x2928, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+	/* SATA Controller IDE (ICH9M) */
+	{ 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+	/* SATA Controller IDE (ICH9M) */
+	{ 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
 
 	{ }	/* terminate list */
 };
@@ -330,7 +342,7 @@
 
 	.port_start		= ata_port_start,
 	.port_stop		= ata_port_stop,
-	.host_stop		= ata_host_stop,
+	.host_stop		= piix_host_stop,
 };
 
 static const struct ata_port_operations piix_sata_ops = {
diff -ru 2.2/drivers/ata/Kconfig 3.4/drivers/ata/Kconfig
--- 2.2/drivers/ata/Kconfig	2006-12-07 02:52:09.000000000 +0100
+++ 3.4/drivers/ata/Kconfig	2006-12-16 22:22:59.000000000 +0100
@@ -40,9 +40,9 @@
 	tristate "Intel PIIX/ICH SATA support"
 	depends on PCI
 	help
-	  This option enables support for ICH5/6/7/8 Serial ATA.
-	  If PATA support was enabled previously, this enables
-	  support for select Intel PIIX/ICH PATA host controllers.
+	  This option enables support for ICH5/6/7/8 Serial ATA
+	  and support for PATA on the Intel PIIX3/PIIX4/ICH series
+	  PATA host controllers.
 
 	  If unsure, say N.
 
diff -ru 2.2/drivers/ata/libata-core.c 3.4/drivers/ata/libata-core.c
--- 2.2/drivers/ata/libata-core.c	2006-12-12 21:59:05.000000000 +0100
+++ 3.4/drivers/ata/libata-core.c	2006-12-16 22:23:00.000000000 +0100
@@ -1332,7 +1332,7 @@
 }
 
 /**
- *	ata_exec_internal_sg - execute libata internal command
+ *	ata_exec_internal - execute libata internal command
  *	@dev: Device to which the command is sent
  *	@tf: Taskfile registers for the command and the result
  *	@cdb: CDB for packet command
@@ -1353,11 +1353,17 @@
 			   struct ata_taskfile *tf, const u8 *cdb,
 			   int dma_dir, void *buf, unsigned int buflen)
 {
-	struct scatterlist sg;
+	struct scatterlist *psg = NULL, sg;
+	unsigned int n_elem = 0;
 
-	sg_init_one(&sg, buf, buflen);
+	if (dma_dir != DMA_NONE) {
+		WARN_ON(!buf);
+		sg_init_one(&sg, buf, buflen);
+		psg = &sg;
+		n_elem++;
+	}
 
-	return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1);
+	return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem);
 }
 
 /**
diff -ru 2.2/drivers/ata/libata-scsi.c 3.4/drivers/ata/libata-scsi.c
--- 2.2/drivers/ata/libata-scsi.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/ata/libata-scsi.c	2006-12-22 01:57:07.000000000 +0100
@@ -51,7 +51,7 @@
 
 #define SECTOR_SIZE	512
 
-typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
+typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc);
 
 static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap,
 					const struct scsi_device *scsidev);
@@ -935,7 +935,6 @@
 /**
  *	ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
  *	@qc: Storage for translated ATA taskfile
- *	@scsicmd: SCSI command to translate
  *
  *	Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY
  *	(to start). Perhaps these commands should be preceded by
@@ -948,22 +947,25 @@
  *	RETURNS:
  *	Zero on success, non-zero on error.
  */
-
-static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
-					     const u8 *scsicmd)
+static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
 {
+	struct scsi_cmnd *scmd = qc->scsicmd;
 	struct ata_taskfile *tf = &qc->tf;
+	const u8 *cdb = scmd->cmnd;
+
+	if (scmd->cmd_len < 5)
+		goto invalid_fld;
 
 	tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
 	tf->protocol = ATA_PROT_NODATA;
-	if (scsicmd[1] & 0x1) {
+	if (cdb[1] & 0x1) {
 		;	/* ignore IMMED bit, violates sat-r05 */
 	}
-	if (scsicmd[4] & 0x2)
+	if (cdb[4] & 0x2)
 		goto invalid_fld;       /* LOEJ bit set not supported */
-	if (((scsicmd[4] >> 4) & 0xf) != 0)
+	if (((cdb[4] >> 4) & 0xf) != 0)
 		goto invalid_fld;       /* power conditions not supported */
-	if (scsicmd[4] & 0x1) {
+	if (cdb[4] & 0x1) {
 		tf->nsect = 1;	/* 1 sector, lba=0 */
 
 		if (qc->dev->flags & ATA_DFLAG_LBA) {
@@ -996,7 +998,7 @@
 	return 0;
 
 invalid_fld:
-	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+	ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
 	/* "Invalid field in cbd" */
 	return 1;
 }
@@ -1005,7 +1007,6 @@
 /**
  *	ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
  *	@qc: Storage for translated ATA taskfile
- *	@scsicmd: SCSI command to translate (ignored)
  *
  *	Sets up an ATA taskfile to issue FLUSH CACHE or
  *	FLUSH CACHE EXT.
@@ -1016,8 +1017,7 @@
  *	RETURNS:
  *	Zero on success, non-zero on error.
  */
-
-static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc)
 {
 	struct ata_taskfile *tf = &qc->tf;
 
@@ -1034,7 +1034,7 @@
 
 /**
  *	scsi_6_lba_len - Get LBA and transfer length
- *	@scsicmd: SCSI command to translate
+ *	@cdb: SCSI command to translate
  *
  *	Calculate LBA and transfer length for 6-byte commands.
  *
@@ -1042,18 +1042,17 @@
  *	@plba: the LBA
  *	@plen: the transfer length
  */
-
-static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
 {
 	u64 lba = 0;
 	u32 len = 0;
 
 	VPRINTK("six-byte command\n");
 
-	lba |= ((u64)scsicmd[2]) << 8;
-	lba |= ((u64)scsicmd[3]);
+	lba |= ((u64)cdb[2]) << 8;
+	lba |= ((u64)cdb[3]);
 
-	len |= ((u32)scsicmd[4]);
+	len |= ((u32)cdb[4]);
 
 	*plba = lba;
 	*plen = len;
@@ -1061,7 +1060,7 @@
 
 /**
  *	scsi_10_lba_len - Get LBA and transfer length
- *	@scsicmd: SCSI command to translate
+ *	@cdb: SCSI command to translate
  *
  *	Calculate LBA and transfer length for 10-byte commands.
  *
@@ -1069,21 +1068,20 @@
  *	@plba: the LBA
  *	@plen: the transfer length
  */
-
-static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
 {
 	u64 lba = 0;
 	u32 len = 0;
 
 	VPRINTK("ten-byte command\n");
 
-	lba |= ((u64)scsicmd[2]) << 24;
-	lba |= ((u64)scsicmd[3]) << 16;
-	lba |= ((u64)scsicmd[4]) << 8;
-	lba |= ((u64)scsicmd[5]);
+	lba |= ((u64)cdb[2]) << 24;
+	lba |= ((u64)cdb[3]) << 16;
+	lba |= ((u64)cdb[4]) << 8;
+	lba |= ((u64)cdb[5]);
 
-	len |= ((u32)scsicmd[7]) << 8;
-	len |= ((u32)scsicmd[8]);
+	len |= ((u32)cdb[7]) << 8;
+	len |= ((u32)cdb[8]);
 
 	*plba = lba;
 	*plen = len;
@@ -1091,7 +1089,7 @@
 
 /**
  *	scsi_16_lba_len - Get LBA and transfer length
- *	@scsicmd: SCSI command to translate
+ *	@cdb: SCSI command to translate
  *
  *	Calculate LBA and transfer length for 16-byte commands.
  *
@@ -1099,27 +1097,26 @@
  *	@plba: the LBA
  *	@plen: the transfer length
  */
-
-static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
 {
 	u64 lba = 0;
 	u32 len = 0;
 
 	VPRINTK("sixteen-byte command\n");
 
-	lba |= ((u64)scsicmd[2]) << 56;
-	lba |= ((u64)scsicmd[3]) << 48;
-	lba |= ((u64)scsicmd[4]) << 40;
-	lba |= ((u64)scsicmd[5]) << 32;
-	lba |= ((u64)scsicmd[6]) << 24;
-	lba |= ((u64)scsicmd[7]) << 16;
-	lba |= ((u64)scsicmd[8]) << 8;
-	lba |= ((u64)scsicmd[9]);
-
-	len |= ((u32)scsicmd[10]) << 24;
-	len |= ((u32)scsicmd[11]) << 16;
-	len |= ((u32)scsicmd[12]) << 8;
-	len |= ((u32)scsicmd[13]);
+	lba |= ((u64)cdb[2]) << 56;
+	lba |= ((u64)cdb[3]) << 48;
+	lba |= ((u64)cdb[4]) << 40;
+	lba |= ((u64)cdb[5]) << 32;
+	lba |= ((u64)cdb[6]) << 24;
+	lba |= ((u64)cdb[7]) << 16;
+	lba |= ((u64)cdb[8]) << 8;
+	lba |= ((u64)cdb[9]);
+
+	len |= ((u32)cdb[10]) << 24;
+	len |= ((u32)cdb[11]) << 16;
+	len |= ((u32)cdb[12]) << 8;
+	len |= ((u32)cdb[13]);
 
 	*plba = lba;
 	*plen = len;
@@ -1128,7 +1125,6 @@
 /**
  *	ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
  *	@qc: Storage for translated ATA taskfile
- *	@scsicmd: SCSI command to translate
  *
  *	Converts SCSI VERIFY command to an ATA READ VERIFY command.
  *
@@ -1138,23 +1134,28 @@
  *	RETURNS:
  *	Zero on success, non-zero on error.
  */
-
-static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
 {
+	struct scsi_cmnd *scmd = qc->scsicmd;
 	struct ata_taskfile *tf = &qc->tf;
 	struct ata_device *dev = qc->dev;
 	u64 dev_sectors = qc->dev->n_sectors;
+	const u8 *cdb = scmd->cmnd;
 	u64 block;
 	u32 n_block;
 
 	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 	tf->protocol = ATA_PROT_NODATA;
 
-	if (scsicmd[0] == VERIFY)
-		scsi_10_lba_len(scsicmd, &block, &n_block);
-	else if (scsicmd[0] == VERIFY_16)
-		scsi_16_lba_len(scsicmd, &block, &n_block);
-	else
+	if (cdb[0] == VERIFY) {
+		if (scmd->cmd_len < 10)
+			goto invalid_fld;
+		scsi_10_lba_len(cdb, &block, &n_block);
+	} else if (cdb[0] == VERIFY_16) {
+		if (scmd->cmd_len < 16)
+			goto invalid_fld;
+		scsi_16_lba_len(cdb, &block, &n_block);
+	} else
 		goto invalid_fld;
 
 	if (!n_block)
@@ -1229,24 +1230,23 @@
 	return 0;
 
 invalid_fld:
-	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+	ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
 	/* "Invalid field in cbd" */
 	return 1;
 
 out_of_range:
-	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+	ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
 	/* "Logical Block Address out of range" */
 	return 1;
 
 nothing_to_do:
-	qc->scsicmd->result = SAM_STAT_GOOD;
+	scmd->result = SAM_STAT_GOOD;
 	return 1;
 }
 
 /**
  *	ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
  *	@qc: Storage for translated ATA taskfile
- *	@scsicmd: SCSI command to translate
  *
  *	Converts any of six SCSI read/write commands into the
  *	ATA counterpart, including starting sector (LBA),
@@ -1262,29 +1262,33 @@
  *	RETURNS:
  *	Zero on success, non-zero on error.
  */
-
-static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
 {
+	struct scsi_cmnd *scmd = qc->scsicmd;
+	const u8 *cdb = scmd->cmnd;
 	unsigned int tf_flags = 0;
 	u64 block;
 	u32 n_block;
 	int rc;
 
-	if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
-	    scsicmd[0] == WRITE_16)
+	if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16)
 		tf_flags |= ATA_TFLAG_WRITE;
 
 	/* Calculate the SCSI LBA, transfer length and FUA. */
-	switch (scsicmd[0]) {
+	switch (cdb[0]) {
 	case READ_10:
 	case WRITE_10:
-		scsi_10_lba_len(scsicmd, &block, &n_block);
-		if (unlikely(scsicmd[1] & (1 << 3)))
+		if (unlikely(scmd->cmd_len < 10))
+			goto invalid_fld;
+		scsi_10_lba_len(cdb, &block, &n_block);
+		if (unlikely(cdb[1] & (1 << 3)))
 			tf_flags |= ATA_TFLAG_FUA;
 		break;
 	case READ_6:
 	case WRITE_6:
-		scsi_6_lba_len(scsicmd, &block, &n_block);
+		if (unlikely(scmd->cmd_len < 6))
+			goto invalid_fld;
+		scsi_6_lba_len(cdb, &block, &n_block);
 
 		/* for 6-byte r/w commands, transfer length 0
 		 * means 256 blocks of data, not 0 block.
@@ -1294,8 +1298,10 @@
 		break;
 	case READ_16:
 	case WRITE_16:
-		scsi_16_lba_len(scsicmd, &block, &n_block);
-		if (unlikely(scsicmd[1] & (1 << 3)))
+		if (unlikely(scmd->cmd_len < 16))
+			goto invalid_fld;
+		scsi_16_lba_len(cdb, &block, &n_block);
+		if (unlikely(cdb[1] & (1 << 3)))
 			tf_flags |= ATA_TFLAG_FUA;
 		break;
 	default:
@@ -1326,17 +1332,17 @@
 		goto out_of_range;
 	/* treat all other errors as -EINVAL, fall through */
 invalid_fld:
-	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+	ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
 	/* "Invalid field in cbd" */
 	return 1;
 
 out_of_range:
-	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+	ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
 	/* "Logical Block Address out of range" */
 	return 1;
 
 nothing_to_do:
-	qc->scsicmd->result = SAM_STAT_GOOD;
+	scmd->result = SAM_STAT_GOOD;
 	return 1;
 }
 
@@ -1456,7 +1462,6 @@
 			      ata_xlat_func_t xlat_func)
 {
 	struct ata_queued_cmd *qc;
-	u8 *scsicmd = cmd->cmnd;
 	int is_io = xlat_func == ata_scsi_rw_xlat;
 
 	VPRINTK("ENTER\n");
@@ -1488,7 +1493,7 @@
 
 	qc->complete_fn = ata_scsi_qc_complete;
 
-	if (xlat_func(qc, scsicmd))
+	if (xlat_func(qc))
 		goto early_finish;
 
 	/* select device, send command to hardware */
@@ -1539,7 +1544,7 @@
 		struct scatterlist *sg;
 
 		sg = (struct scatterlist *) cmd->request_buffer;
-		buf = kmap_atomic(sg->page, KM_USER0) + sg->offset;
+		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
 		buflen = sg->length;
 	} else {
 		buf = cmd->request_buffer;
@@ -1567,7 +1572,7 @@
 		struct scatterlist *sg;
 
 		sg = (struct scatterlist *) cmd->request_buffer;
-		kunmap_atomic(buf - sg->offset, KM_USER0);
+		kunmap_atomic(buf - sg->offset, KM_IRQ0);
 	}
 }
 
@@ -2344,7 +2349,6 @@
 /**
  *	atapi_xlat - Initialize PACKET taskfile
  *	@qc: command structure to be initialized
- *	@scsicmd: SCSI CDB associated with this PACKET command
  *
  *	LOCKING:
  *	spin_lock_irqsave(host lock)
@@ -2352,25 +2356,25 @@
  *	RETURNS:
  *	Zero on success, non-zero on failure.
  */
-
-static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
 {
-	struct scsi_cmnd *cmd = qc->scsicmd;
+	struct scsi_cmnd *scmd = qc->scsicmd;
 	struct ata_device *dev = qc->dev;
 	int using_pio = (dev->flags & ATA_DFLAG_PIO);
-	int nodata = (cmd->sc_data_direction == DMA_NONE);
+	int nodata = (scmd->sc_data_direction == DMA_NONE);
 
 	if (!using_pio)
 		/* Check whether ATAPI DMA is safe */
 		if (ata_check_atapi_dma(qc))
 			using_pio = 1;
 
-	memcpy(&qc->cdb, scsicmd, dev->cdb_len);
+	memset(qc->cdb, 0, dev->cdb_len);
+	memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
 
 	qc->complete_fn = atapi_qc_complete;
 
 	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-	if (cmd->sc_data_direction == DMA_TO_DEVICE) {
+	if (scmd->sc_data_direction == DMA_TO_DEVICE) {
 		qc->tf.flags |= ATA_TFLAG_WRITE;
 		DPRINTK("direction: write\n");
 	}
@@ -2392,12 +2396,12 @@
 		qc->tf.protocol = ATA_PROT_ATAPI_DMA;
 		qc->tf.feature |= ATAPI_PKT_DMA;
 
-		if (atapi_dmadir && (cmd->sc_data_direction != DMA_TO_DEVICE))
+		if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE))
 			/* some SATA bridges need us to indicate data xfer direction */
 			qc->tf.feature |= ATAPI_DMADIR;
 	}
 
-	qc->nbytes = cmd->request_bufflen;
+	qc->nbytes = scmd->request_bufflen;
 
 	return 0;
 }
@@ -2517,28 +2521,27 @@
 /**
  *	ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
  *	@qc: command structure to be initialized
- *	@scsicmd: SCSI command to convert
  *
  *	Handles either 12 or 16-byte versions of the CDB.
  *
  *	RETURNS:
  *	Zero on success, non-zero on failure.
  */
-static unsigned int
-ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
 {
 	struct ata_taskfile *tf = &(qc->tf);
-	struct scsi_cmnd *cmd = qc->scsicmd;
+	struct scsi_cmnd *scmd = qc->scsicmd;
 	struct ata_device *dev = qc->dev;
+	const u8 *cdb = scmd->cmnd;
 
-	if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
+	if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN)
 		goto invalid_fld;
 
 	/* We may not issue DMA commands if no DMA mode is set */
 	if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
 		goto invalid_fld;
 
-	if (scsicmd[1] & 0xe0)
+	if (cdb[1] & 0xe0)
 		/* PIO multi not supported yet */
 		goto invalid_fld;
 
@@ -2546,18 +2549,18 @@
 	 * 12 and 16 byte CDBs use different offsets to
 	 * provide the various register values.
 	 */
-	if (scsicmd[0] == ATA_16) {
+	if (cdb[0] == ATA_16) {
 		/*
 		 * 16-byte CDB - may contain extended commands.
 		 *
 		 * If that is the case, copy the upper byte register values.
 		 */
-		if (scsicmd[1] & 0x01) {
-			tf->hob_feature = scsicmd[3];
-			tf->hob_nsect = scsicmd[5];
-			tf->hob_lbal = scsicmd[7];
-			tf->hob_lbam = scsicmd[9];
-			tf->hob_lbah = scsicmd[11];
+		if (cdb[1] & 0x01) {
+			tf->hob_feature = cdb[3];
+			tf->hob_nsect = cdb[5];
+			tf->hob_lbal = cdb[7];
+			tf->hob_lbam = cdb[9];
+			tf->hob_lbah = cdb[11];
 			tf->flags |= ATA_TFLAG_LBA48;
 		} else
 			tf->flags &= ~ATA_TFLAG_LBA48;
@@ -2565,26 +2568,26 @@
 		/*
 		 * Always copy low byte, device and command registers.
 		 */
-		tf->feature = scsicmd[4];
-		tf->nsect = scsicmd[6];
-		tf->lbal = scsicmd[8];
-		tf->lbam = scsicmd[10];
-		tf->lbah = scsicmd[12];
-		tf->device = scsicmd[13];
-		tf->command = scsicmd[14];
+		tf->feature = cdb[4];
+		tf->nsect = cdb[6];
+		tf->lbal = cdb[8];
+		tf->lbam = cdb[10];
+		tf->lbah = cdb[12];
+		tf->device = cdb[13];
+		tf->command = cdb[14];
 	} else {
 		/*
 		 * 12-byte CDB - incapable of extended commands.
 		 */
 		tf->flags &= ~ATA_TFLAG_LBA48;
 
-		tf->feature = scsicmd[3];
-		tf->nsect = scsicmd[4];
-		tf->lbal = scsicmd[5];
-		tf->lbam = scsicmd[6];
-		tf->lbah = scsicmd[7];
-		tf->device = scsicmd[8];
-		tf->command = scsicmd[9];
+		tf->feature = cdb[3];
+		tf->nsect = cdb[4];
+		tf->lbal = cdb[5];
+		tf->lbam = cdb[6];
+		tf->lbah = cdb[7];
+		tf->device = cdb[8];
+		tf->command = cdb[9];
 	}
 	/*
 	 * If slave is possible, enforce correct master/slave bit
@@ -2611,7 +2614,7 @@
 	 */
 	tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE);
 
-	if (cmd->sc_data_direction == DMA_TO_DEVICE)
+	if (scmd->sc_data_direction == DMA_TO_DEVICE)
 		tf->flags |= ATA_TFLAG_WRITE;
 
 	/*
@@ -2620,7 +2623,7 @@
 	 * TODO: find out if we need to do more here to
 	 *       cover scatter/gather case.
 	 */
-	qc->nsect = cmd->request_bufflen / ATA_SECT_SIZE;
+	qc->nsect = scmd->request_bufflen / ATA_SECT_SIZE;
 
 	/* request result TF */
 	qc->flags |= ATA_QCFLAG_RESULT_TF;
@@ -2628,7 +2631,7 @@
 	return 0;
 
  invalid_fld:
-	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00);
+	ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
 	/* "Invalid field in cdb" */
 	return 1;
 }
@@ -2701,22 +2704,29 @@
 #endif
 }
 
-static inline int __ata_scsi_queuecmd(struct scsi_cmnd *cmd,
+static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
 				      void (*done)(struct scsi_cmnd *),
 				      struct ata_device *dev)
 {
 	int rc = 0;
 
+	if (unlikely(!scmd->cmd_len)) {
+		ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n");
+		scmd->result = DID_ERROR << 16;
+		done(scmd);
+		return 0;
+	}
+
 	if (dev->class == ATA_DEV_ATA) {
 		ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
-							      cmd->cmnd[0]);
+							      scmd->cmnd[0]);
 
 		if (xlat_func)
-			rc = ata_scsi_translate(dev, cmd, done, xlat_func);
+			rc = ata_scsi_translate(dev, scmd, done, xlat_func);
 		else
-			ata_scsi_simulate(dev, cmd, done);
+			ata_scsi_simulate(dev, scmd, done);
 	} else
-		rc = ata_scsi_translate(dev, cmd, done, atapi_xlat);
+		rc = ata_scsi_translate(dev, scmd, done, atapi_xlat);
 
 	return rc;
 }
diff -ru 2.2/drivers/ata/pata_cs5530.c 3.4/drivers/ata/pata_cs5530.c
--- 2.2/drivers/ata/pata_cs5530.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/ata/pata_cs5530.c	2006-12-22 01:57:07.000000000 +0100
@@ -372,7 +372,8 @@
 static int cs5530_reinit_one(struct pci_dev *pdev)
 {
 	/* If we fail on resume we are doomed */
-	BUG_ON(cs5530_init_chip());
+	if (cs5530_init_chip())
+		BUG();
 	return ata_pci_device_resume(pdev);
 }
 	
diff -ru 2.2/drivers/ata/pata_legacy.c 3.4/drivers/ata/pata_legacy.c
--- 2.2/drivers/ata/pata_legacy.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/ata/pata_legacy.c	2006-12-16 22:22:59.000000000 +0100
@@ -698,8 +698,10 @@
 		goto fail_io;
 
 	pdev = platform_device_register_simple(DRV_NAME, nr_legacy_host, NULL, 0);
-	if (pdev == NULL)
+	if (IS_ERR(pdev)) {
+		ret = PTR_ERR(pdev);
 		goto fail_dev;
+	}
 
 	if (ht6560a & mask) {
 		ops = &ht6560a_port_ops;
diff -ru 2.2/drivers/ata/pata_qdi.c 3.4/drivers/ata/pata_qdi.c
--- 2.2/drivers/ata/pata_qdi.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/ata/pata_qdi.c	2006-12-16 22:22:59.000000000 +0100
@@ -247,8 +247,8 @@
 	 */
 
 	pdev = platform_device_register_simple(DRV_NAME, nr_qdi_host, NULL, 0);
-	if (pdev == NULL)
-		return -ENOMEM;
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
 
 	memset(&ae, 0, sizeof(struct ata_probe_ent));
 	INIT_LIST_HEAD(&ae.node);
diff -ru 2.2/drivers/ata/pata_rz1000.c 3.4/drivers/ata/pata_rz1000.c
--- 2.2/drivers/ata/pata_rz1000.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/ata/pata_rz1000.c	2006-12-16 22:22:59.000000000 +0100
@@ -105,8 +105,6 @@
 	.exec_command	= ata_exec_command,
 	.dev_select 	= ata_std_dev_select,
 
-	.error_handler	= rz1000_error_handler,
-
 	.bmdma_setup 	= ata_bmdma_setup,
 	.bmdma_start 	= ata_bmdma_start,
 	.bmdma_stop	= ata_bmdma_stop,
diff -ru 2.2/drivers/ata/pata_via.c 3.4/drivers/ata/pata_via.c
--- 2.2/drivers/ata/pata_via.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/ata/pata_via.c	2006-12-22 01:57:07.000000000 +0100
@@ -161,10 +161,15 @@
 			return -ENOENT;
 	}
 
-	if ((config->flags & VIA_UDMA) >= VIA_UDMA_66)
+	if ((config->flags & VIA_UDMA) >= VIA_UDMA_100)
 		ap->cbl = via_cable_detect(ap);
-	else
+	/* The UDMA66 series has no cable detect so do drive side detect */
+	else if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
 		ap->cbl = ATA_CBL_PATA40;
+	else
+		ap->cbl = ATA_CBL_PATA_UNK;
+		
+
 	return ata_std_prereset(ap);
 }
 
@@ -390,7 +395,7 @@
 	enable &= 3;
 	
 	if (flags & VIA_SET_FIFO) {
-		u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
+		static const u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
 		u8 fifo;
 
 		pci_read_config_byte(pdev, 0x43, &fifo);
diff -ru 2.2/drivers/ata/pata_winbond.c 3.4/drivers/ata/pata_winbond.c
--- 2.2/drivers/ata/pata_winbond.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/ata/pata_winbond.c	2006-12-16 22:22:59.000000000 +0100
@@ -206,8 +206,8 @@
 			 */
 
 			pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
-			if (pdev == NULL)
-				return -ENOMEM;
+			if (IS_ERR(pdev))
+				return PTR_ERR(pdev);
 
 			memset(&ae, 0, sizeof(struct ata_probe_ent));
 			INIT_LIST_HEAD(&ae.node);
diff -ru 2.2/drivers/ata/sata_nv.c 3.4/drivers/ata/sata_nv.c
--- 2.2/drivers/ata/sata_nv.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/ata/sata_nv.c	2006-12-22 01:57:07.000000000 +0100
@@ -270,14 +270,6 @@
 	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
 	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
 	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
-	{ PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */
-	{ PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */
-	{ PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */
-	{ PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */
-	{ PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */
 	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
 		PCI_ANY_ID, PCI_ANY_ID,
 		PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
diff -ru 2.2/drivers/ata/sata_svw.c 3.4/drivers/ata/sata_svw.c
--- 2.2/drivers/ata/sata_svw.c	2006-10-11 15:48:10.000000000 +0200
+++ 3.4/drivers/ata/sata_svw.c	2006-12-22 01:57:11.000000000 +0100
@@ -56,6 +56,8 @@
 #define DRV_VERSION	"2.0"
 
 enum {
+	K2_FLAG_NO_ATAPI_DMA		= (1 << 29),
+
 	/* Taskfile registers offsets */
 	K2_SATA_TF_CMD_OFFSET		= 0x00,
 	K2_SATA_TF_DATA_OFFSET		= 0x00,
@@ -83,11 +85,33 @@
 
 	/* Port stride */
 	K2_SATA_PORT_OFFSET		= 0x100,
+
+	board_svw4			= 0,
+	board_svw8			= 1,
+};
+
+static const struct k2_board_info {
+	unsigned int		n_ports;
+	unsigned long		port_flags;
+} k2_board_info[] = {
+	/* board_svw4 */
+	{ 4, K2_FLAG_NO_ATAPI_DMA },
+
+	/* board_svw8 */
+	{ 8, K2_FLAG_NO_ATAPI_DMA },
 };
 
 static u8 k2_stat_check_status(struct ata_port *ap);
 
 
+static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+	if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
+		return -1;	/* ATAPI DMA not supported */
+
+	return 0;
+}
+
 static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
 {
 	if (sc_reg > SCR_CONTROL)
@@ -111,26 +135,31 @@
 	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
 
 	if (tf->ctl != ap->last_ctl) {
-		writeb(tf->ctl, ioaddr->ctl_addr);
+		writeb(tf->ctl, (void __iomem *) ioaddr->ctl_addr);
 		ap->last_ctl = tf->ctl;
 		ata_wait_idle(ap);
 	}
 	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-		writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr);
-		writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr);
-		writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr);
-		writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr);
-		writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr);
+		writew(tf->feature | (((u16)tf->hob_feature) << 8),
+		       (void __iomem *) ioaddr->feature_addr);
+		writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
+		       (void __iomem *) ioaddr->nsect_addr);
+		writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
+		       (void __iomem *) ioaddr->lbal_addr);
+		writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
+		       (void __iomem *) ioaddr->lbam_addr);
+		writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
+		       (void __iomem *) ioaddr->lbah_addr);
 	} else if (is_addr) {
-		writew(tf->feature, ioaddr->feature_addr);
-		writew(tf->nsect, ioaddr->nsect_addr);
-		writew(tf->lbal, ioaddr->lbal_addr);
-		writew(tf->lbam, ioaddr->lbam_addr);
-		writew(tf->lbah, ioaddr->lbah_addr);
+		writew(tf->feature, (void __iomem *) ioaddr->feature_addr);
+		writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
+		writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
+		writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
+		writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
 	}
 
 	if (tf->flags & ATA_TFLAG_DEVICE)
-		writeb(tf->device, ioaddr->device_addr);
+		writeb(tf->device, (void __iomem *) ioaddr->device_addr);
 
 	ata_wait_idle(ap);
 }
@@ -142,12 +171,12 @@
 	u16 nsect, lbal, lbam, lbah, feature;
 
 	tf->command = k2_stat_check_status(ap);
-	tf->device = readw(ioaddr->device_addr);
-	feature = readw(ioaddr->error_addr);
-	nsect = readw(ioaddr->nsect_addr);
-	lbal = readw(ioaddr->lbal_addr);
-	lbam = readw(ioaddr->lbam_addr);
-	lbah = readw(ioaddr->lbah_addr);
+	tf->device = readw((void __iomem *)ioaddr->device_addr);
+	feature = readw((void __iomem *)ioaddr->error_addr);
+	nsect = readw((void __iomem *)ioaddr->nsect_addr);
+	lbal = readw((void __iomem *)ioaddr->lbal_addr);
+	lbam = readw((void __iomem *)ioaddr->lbam_addr);
+	lbah = readw((void __iomem *)ioaddr->lbah_addr);
 
 	tf->feature = feature;
 	tf->nsect = nsect;
@@ -313,6 +342,7 @@
 	.check_status		= k2_stat_check_status,
 	.exec_command		= ata_exec_command,
 	.dev_select		= ata_std_dev_select,
+	.check_atapi_dma	= k2_sata_check_atapi_dma,
 	.bmdma_setup		= k2_bmdma_setup_mmio,
 	.bmdma_start		= k2_bmdma_start_mmio,
 	.bmdma_stop		= ata_bmdma_stop,
@@ -359,6 +389,8 @@
 	struct ata_probe_ent *probe_ent = NULL;
 	unsigned long base;
 	void __iomem *mmio_base;
+	const struct k2_board_info *board_info =
+			&k2_board_info[ent->driver_data];
 	int pci_dev_busy = 0;
 	int rc;
 	int i;
@@ -424,7 +456,7 @@
 
 	probe_ent->sht = &k2_sata_sht;
 	probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				ATA_FLAG_MMIO;
+				ATA_FLAG_MMIO | board_info->port_flags;
 	probe_ent->port_ops = &k2_sata_ops;
 	probe_ent->n_ports = 4;
 	probe_ent->irq = pdev->irq;
@@ -441,16 +473,16 @@
 	/* different controllers have different number of ports - currently 4 or 8 */
 	/* All ports are on the same function. Multi-function device is no
 	 * longer available. This should not be seen in any system. */
-	for (i = 0; i < ent->driver_data; i++)
+	for (i = 0; i < board_info->n_ports; i++)
 		k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET);
 
 	pci_set_master(pdev);
 
-	/* FIXME: check ata_device_add return value */
-	ata_device_add(probe_ent);
-	kfree(probe_ent);
+	if (ata_device_add(probe_ent))
+		return 0;
 
-	return 0;
+	/* Failed to add, no device present */
+	rc = -ENODEV;
 
 err_out_free_ent:
 	kfree(probe_ent);
@@ -469,11 +501,11 @@
  * controller
  * */
 static const struct pci_device_id k2_sata_pci_tbl[] = {
-	{ PCI_VDEVICE(SERVERWORKS, 0x0240), 4 },
-	{ PCI_VDEVICE(SERVERWORKS, 0x0241), 4 },
-	{ PCI_VDEVICE(SERVERWORKS, 0x0242), 8 },
-	{ PCI_VDEVICE(SERVERWORKS, 0x024a), 4 },
-	{ PCI_VDEVICE(SERVERWORKS, 0x024b), 4 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 },
+	{ PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 },
 
 	{ }
 };
diff -ru 2.2/drivers/ata/sata_vsc.c 3.4/drivers/ata/sata_vsc.c
--- 2.2/drivers/ata/sata_vsc.c	2006-10-09 14:51:47.000000000 +0200
+++ 3.4/drivers/ata/sata_vsc.c	2006-12-22 01:57:07.000000000 +0100
@@ -149,21 +149,26 @@
 		vsc_intr_mask_update(ap, tf->ctl & ATA_NIEN);
 	}
 	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-		writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr);
-		writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr);
-		writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr);
-		writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr);
-		writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr);
+		writew(tf->feature | (((u16)tf->hob_feature) << 8),
+		       (void __iomem *) ioaddr->feature_addr);
+		writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
+		       (void __iomem *) ioaddr->nsect_addr);
+		writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
+		       (void __iomem *) ioaddr->lbal_addr);
+		writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
+		       (void __iomem *) ioaddr->lbam_addr);
+		writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
+		       (void __iomem *) ioaddr->lbah_addr);
 	} else if (is_addr) {
-		writew(tf->feature, ioaddr->feature_addr);
-		writew(tf->nsect, ioaddr->nsect_addr);
-		writew(tf->lbal, ioaddr->lbal_addr);
-		writew(tf->lbam, ioaddr->lbam_addr);
-		writew(tf->lbah, ioaddr->lbah_addr);
+		writew(tf->feature, (void __iomem *) ioaddr->feature_addr);
+		writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
+		writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
+		writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
+		writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
 	}
 
 	if (tf->flags & ATA_TFLAG_DEVICE)
-		writeb(tf->device, ioaddr->device_addr);
+		writeb(tf->device, (void __iomem *) ioaddr->device_addr);
 
 	ata_wait_idle(ap);
 }
@@ -175,12 +180,12 @@
 	u16 nsect, lbal, lbam, lbah, feature;
 
 	tf->command = ata_check_status(ap);
-	tf->device = readw(ioaddr->device_addr);
-	feature = readw(ioaddr->error_addr);
-	nsect = readw(ioaddr->nsect_addr);
-	lbal = readw(ioaddr->lbal_addr);
-	lbam = readw(ioaddr->lbam_addr);
-	lbah = readw(ioaddr->lbah_addr);
+	tf->device = readw((void __iomem *) ioaddr->device_addr);
+	feature = readw((void __iomem *) ioaddr->error_addr);
+	nsect = readw((void __iomem *) ioaddr->nsect_addr);
+	lbal = readw((void __iomem *) ioaddr->lbal_addr);
+	lbam = readw((void __iomem *) ioaddr->lbam_addr);
+	lbah = readw((void __iomem *) ioaddr->lbah_addr);
 
 	tf->feature = feature;
 	tf->nsect = nsect;
@@ -327,8 +332,8 @@
 	port->ctl_addr		= base + VSC_SATA_TF_CTL_OFFSET;
 	port->bmdma_addr	= base + VSC_SATA_DMA_CMD_OFFSET;
 	port->scr_addr		= base + VSC_SATA_SCR_STATUS_OFFSET;
-	writel(0, base + VSC_SATA_UP_DESCRIPTOR_OFFSET);
-	writel(0, base + VSC_SATA_UP_DATA_BUFFER_OFFSET);
+	writel(0, (void __iomem *) base + VSC_SATA_UP_DESCRIPTOR_OFFSET);
+	writel(0, (void __iomem *) base + VSC_SATA_UP_DATA_BUFFER_OFFSET);
 }
 
 
diff -ru 2.2/drivers/atm/fore200e.c 3.4/drivers/atm/fore200e.c
--- 2.2/drivers/atm/fore200e.c	2006-10-09 14:51:47.000000000 +0200
+++ 3.4/drivers/atm/fore200e.c	2006-12-23 01:11:19.000000000 +0100
@@ -172,25 +172,6 @@
 }
 
 
-static void*
-fore200e_kmalloc(int size, gfp_t flags)
-{
-    void *chunk = kzalloc(size, flags);
-
-    if (!chunk)
-	printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n",			size, flags);
-    
-    return chunk;
-}
-
-
-static void
-fore200e_kfree(void* chunk)
-{
-    kfree(chunk);
-}
-
-
 /* allocate and align a chunk of memory intended to hold the data behing exchanged
    between the driver and the adapter (using streaming DVMA) */
 
@@ -206,7 +187,7 @@
     chunk->align_size = size;
     chunk->direction  = direction;
 
-    chunk->alloc_addr = fore200e_kmalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA);
+    chunk->alloc_addr = kzalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA);
     if (chunk->alloc_addr == NULL)
 	return -ENOMEM;
 
@@ -228,7 +209,7 @@
 {
     fore200e->bus->dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size, chunk->direction);
 
-    fore200e_kfree(chunk->alloc_addr);
+    kfree(chunk->alloc_addr);
 }
 
 
@@ -882,7 +863,7 @@
 	return NULL;
     }
 
-    fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL);
+    fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
     if (fore200e == NULL)
 	return NULL;
 
@@ -1505,7 +1486,7 @@
 
     spin_unlock_irqrestore(&fore200e->q_lock, flags);
 
-    fore200e_vcc = fore200e_kmalloc(sizeof(struct fore200e_vcc), GFP_ATOMIC);
+    fore200e_vcc = kzalloc(sizeof(struct fore200e_vcc), GFP_ATOMIC);
     if (fore200e_vcc == NULL) {
 	vc_map->vcc = NULL;
 	return -ENOMEM;
@@ -1526,7 +1507,7 @@
 	if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
 	    up(&fore200e->rate_sf);
 
-	    fore200e_kfree(fore200e_vcc);
+	    kfree(fore200e_vcc);
 	    vc_map->vcc = NULL;
 	    return -EAGAIN;
 	}
@@ -1554,7 +1535,7 @@
 
 	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
 
-	fore200e_kfree(fore200e_vcc);
+	kfree(fore200e_vcc);
 	return -EINVAL;
     }
     
@@ -1630,7 +1611,7 @@
     clear_bit(ATM_VF_PARTIAL,&vcc->flags);
 
     ASSERT(fore200e_vcc);
-    fore200e_kfree(fore200e_vcc);
+    kfree(fore200e_vcc);
 }
 
 
@@ -1831,7 +1812,7 @@
     u32                     stats_dma_addr;
 
     if (fore200e->stats == NULL) {
-	fore200e->stats = fore200e_kmalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA);
+	fore200e->stats = kzalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA);
 	if (fore200e->stats == NULL)
 	    return -ENOMEM;
     }
@@ -2002,17 +1983,6 @@
 }
 
 
-static inline unsigned int
-fore200e_swap(unsigned int in)
-{
-#if defined(__LITTLE_ENDIAN)
-    return swab32(in);
-#else
-    return in;
-#endif
-}
-
-
 static int
 fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
 {
@@ -2021,19 +1991,19 @@
     if (fore200e_getstats(fore200e) < 0)
 	return -EIO;
 
-    tmp.section_bip = fore200e_swap(fore200e->stats->oc3.section_bip8_errors);
-    tmp.line_bip    = fore200e_swap(fore200e->stats->oc3.line_bip24_errors);
-    tmp.path_bip    = fore200e_swap(fore200e->stats->oc3.path_bip8_errors);
-    tmp.line_febe   = fore200e_swap(fore200e->stats->oc3.line_febe_errors);
-    tmp.path_febe   = fore200e_swap(fore200e->stats->oc3.path_febe_errors);
-    tmp.corr_hcs    = fore200e_swap(fore200e->stats->oc3.corr_hcs_errors);
-    tmp.uncorr_hcs  = fore200e_swap(fore200e->stats->oc3.ucorr_hcs_errors);
-    tmp.tx_cells    = fore200e_swap(fore200e->stats->aal0.cells_transmitted)  +
-	              fore200e_swap(fore200e->stats->aal34.cells_transmitted) +
-	              fore200e_swap(fore200e->stats->aal5.cells_transmitted);
-    tmp.rx_cells    = fore200e_swap(fore200e->stats->aal0.cells_received)     +
-	              fore200e_swap(fore200e->stats->aal34.cells_received)    +
-	              fore200e_swap(fore200e->stats->aal5.cells_received);
+    tmp.section_bip = cpu_to_be32(fore200e->stats->oc3.section_bip8_errors);
+    tmp.line_bip    = cpu_to_be32(fore200e->stats->oc3.line_bip24_errors);
+    tmp.path_bip    = cpu_to_be32(fore200e->stats->oc3.path_bip8_errors);
+    tmp.line_febe   = cpu_to_be32(fore200e->stats->oc3.line_febe_errors);
+    tmp.path_febe   = cpu_to_be32(fore200e->stats->oc3.path_febe_errors);
+    tmp.corr_hcs    = cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors);
+    tmp.uncorr_hcs  = cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors);
+    tmp.tx_cells    = cpu_to_be32(fore200e->stats->aal0.cells_transmitted)  +
+	              cpu_to_be32(fore200e->stats->aal34.cells_transmitted) +
+	              cpu_to_be32(fore200e->stats->aal5.cells_transmitted);
+    tmp.rx_cells    = cpu_to_be32(fore200e->stats->aal0.cells_received)     +
+	              cpu_to_be32(fore200e->stats->aal34.cells_received)    +
+	              cpu_to_be32(fore200e->stats->aal5.cells_received);
 
     if (arg)
 	return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;	
@@ -2146,7 +2116,7 @@
 static int __devinit
 fore200e_get_esi(struct fore200e* fore200e)
 {
-    struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA);
+    struct prom_data* prom = kzalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA);
     int ok, i;
 
     if (!prom)
@@ -2154,7 +2124,7 @@
 
     ok = fore200e->bus->prom_read(fore200e, prom);
     if (ok < 0) {
-	fore200e_kfree(prom);
+	kfree(prom);
 	return -EBUSY;
     }
 	
@@ -2169,7 +2139,7 @@
 	fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
     }
     
-    fore200e_kfree(prom);
+    kfree(prom);
 
     return 0;
 }
@@ -2194,7 +2164,7 @@
 	    DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn);
 
 	    /* allocate the array of receive buffers */
-	    buffer = bsq->buffer = fore200e_kmalloc(nbr * sizeof(struct buffer), GFP_KERNEL);
+	    buffer = bsq->buffer = kzalloc(nbr * sizeof(struct buffer), GFP_KERNEL);
 
 	    if (buffer == NULL)
 		return -ENOMEM;
@@ -2217,7 +2187,7 @@
 		    
 		    while (i > 0)
 			fore200e_chunk_free(fore200e, &buffer[ --i ].data);
-		    fore200e_kfree(buffer);
+		    kfree(buffer);
 		    
 		    return -ENOMEM;
 		}
@@ -2736,7 +2706,7 @@
 	goto out;
     }
     
-    fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL);
+    fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
     if (fore200e == NULL) {
 	err = -ENOMEM;
 	goto out_disable;
@@ -2999,8 +2969,8 @@
 		       "  4b5b:\n"
 		       "     crc_header_errors:\t\t%10u\n"
 		       "     framing_errors:\t\t%10u\n",
-		       fore200e_swap(fore200e->stats->phy.crc_header_errors),
-		       fore200e_swap(fore200e->stats->phy.framing_errors));
+		       cpu_to_be32(fore200e->stats->phy.crc_header_errors),
+		       cpu_to_be32(fore200e->stats->phy.framing_errors));
     
     if (!left--)
 	return sprintf(page, "\n"
@@ -3012,13 +2982,13 @@
 		       "     path_febe_errors:\t\t%10u\n"
 		       "     corr_hcs_errors:\t\t%10u\n"
 		       "     ucorr_hcs_errors:\t\t%10u\n",
-		       fore200e_swap(fore200e->stats->oc3.section_bip8_errors),
-		       fore200e_swap(fore200e->stats->oc3.path_bip8_errors),
-		       fore200e_swap(fore200e->stats->oc3.line_bip24_errors),
-		       fore200e_swap(fore200e->stats->oc3.line_febe_errors),
-		       fore200e_swap(fore200e->stats->oc3.path_febe_errors),
-		       fore200e_swap(fore200e->stats->oc3.corr_hcs_errors),
-		       fore200e_swap(fore200e->stats->oc3.ucorr_hcs_errors));
+		       cpu_to_be32(fore200e->stats->oc3.section_bip8_errors),
+		       cpu_to_be32(fore200e->stats->oc3.path_bip8_errors),
+		       cpu_to_be32(fore200e->stats->oc3.line_bip24_errors),
+		       cpu_to_be32(fore200e->stats->oc3.line_febe_errors),
+		       cpu_to_be32(fore200e->stats->oc3.path_febe_errors),
+		       cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors),
+		       cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors));
 
     if (!left--)
 	return sprintf(page,"\n"
@@ -3029,12 +2999,12 @@
 		       "     vpi no conn:\t\t%10u\n"
 		       "     vci out of range:\t\t%10u\n"
 		       "     vci no conn:\t\t%10u\n",
-		       fore200e_swap(fore200e->stats->atm.cells_transmitted),
-		       fore200e_swap(fore200e->stats->atm.cells_received),
-		       fore200e_swap(fore200e->stats->atm.vpi_bad_range),
-		       fore200e_swap(fore200e->stats->atm.vpi_no_conn),
-		       fore200e_swap(fore200e->stats->atm.vci_bad_range),
-		       fore200e_swap(fore200e->stats->atm.vci_no_conn));
+		       cpu_to_be32(fore200e->stats->atm.cells_transmitted),
+		       cpu_to_be32(fore200e->stats->atm.cells_received),
+		       cpu_to_be32(fore200e->stats->atm.vpi_bad_range),
+		       cpu_to_be32(fore200e->stats->atm.vpi_no_conn),
+		       cpu_to_be32(fore200e->stats->atm.vci_bad_range),
+		       cpu_to_be32(fore200e->stats->atm.vci_no_conn));
     
     if (!left--)
 	return sprintf(page,"\n"
@@ -3042,9 +3012,9 @@
 		       "     TX:\t\t\t%10u\n"
 		       "     RX:\t\t\t%10u\n"
 		       "     dropped:\t\t\t%10u\n",
-		       fore200e_swap(fore200e->stats->aal0.cells_transmitted),
-		       fore200e_swap(fore200e->stats->aal0.cells_received),
-		       fore200e_swap(fore200e->stats->aal0.cells_dropped));
+		       cpu_to_be32(fore200e->stats->aal0.cells_transmitted),
+		       cpu_to_be32(fore200e->stats->aal0.cells_received),
+		       cpu_to_be32(fore200e->stats->aal0.cells_dropped));
     
     if (!left--)
 	return sprintf(page,"\n"
@@ -3060,15 +3030,15 @@
 		       "       RX:\t\t\t%10u\n"
 		       "       dropped:\t\t\t%10u\n"
 		       "       protocol errors:\t\t%10u\n",
-		       fore200e_swap(fore200e->stats->aal34.cells_transmitted),
-		       fore200e_swap(fore200e->stats->aal34.cells_received),
-		       fore200e_swap(fore200e->stats->aal34.cells_dropped),
-		       fore200e_swap(fore200e->stats->aal34.cells_crc_errors),
-		       fore200e_swap(fore200e->stats->aal34.cells_protocol_errors),
-		       fore200e_swap(fore200e->stats->aal34.cspdus_transmitted),
-		       fore200e_swap(fore200e->stats->aal34.cspdus_received),
-		       fore200e_swap(fore200e->stats->aal34.cspdus_dropped),
-		       fore200e_swap(fore200e->stats->aal34.cspdus_protocol_errors));
+		       cpu_to_be32(fore200e->stats->aal34.cells_transmitted),
+		       cpu_to_be32(fore200e->stats->aal34.cells_received),
+		       cpu_to_be32(fore200e->stats->aal34.cells_dropped),
+		       cpu_to_be32(fore200e->stats->aal34.cells_crc_errors),
+		       cpu_to_be32(fore200e->stats->aal34.cells_protocol_errors),
+		       cpu_to_be32(fore200e->stats->aal34.cspdus_transmitted),
+		       cpu_to_be32(fore200e->stats->aal34.cspdus_received),
+		       cpu_to_be32(fore200e->stats->aal34.cspdus_dropped),
+		       cpu_to_be32(fore200e->stats->aal34.cspdus_protocol_errors));
     
     if (!left--)
 	return sprintf(page,"\n"
@@ -3084,15 +3054,15 @@
 		       "       dropped:\t\t\t%10u\n"
 		       "       CRC errors:\t\t%10u\n"
 		       "       protocol errors:\t\t%10u\n",
-		       fore200e_swap(fore200e->stats->aal5.cells_transmitted),
-		       fore200e_swap(fore200e->stats->aal5.cells_received),
-		       fore200e_swap(fore200e->stats->aal5.cells_dropped),
-		       fore200e_swap(fore200e->stats->aal5.congestion_experienced),
-		       fore200e_swap(fore200e->stats->aal5.cspdus_transmitted),
-		       fore200e_swap(fore200e->stats->aal5.cspdus_received),
-		       fore200e_swap(fore200e->stats->aal5.cspdus_dropped),
-		       fore200e_swap(fore200e->stats->aal5.cspdus_crc_errors),
-		       fore200e_swap(fore200e->stats->aal5.cspdus_protocol_errors));
+		       cpu_to_be32(fore200e->stats->aal5.cells_transmitted),
+		       cpu_to_be32(fore200e->stats->aal5.cells_received),
+		       cpu_to_be32(fore200e->stats->aal5.cells_dropped),
+		       cpu_to_be32(fore200e->stats->aal5.congestion_experienced),
+		       cpu_to_be32(fore200e->stats->aal5.cspdus_transmitted),
+		       cpu_to_be32(fore200e->stats->aal5.cspdus_received),
+		       cpu_to_be32(fore200e->stats->aal5.cspdus_dropped),
+		       cpu_to_be32(fore200e->stats->aal5.cspdus_crc_errors),
+		       cpu_to_be32(fore200e->stats->aal5.cspdus_protocol_errors));
     
     if (!left--)
 	return sprintf(page,"\n"
@@ -3103,11 +3073,11 @@
 		       "     large b2:\t\t\t%10u\n"
 		       "     RX PDUs:\t\t\t%10u\n"
 		       "     TX PDUs:\t\t\t%10lu\n",
-		       fore200e_swap(fore200e->stats->aux.small_b1_failed),
-		       fore200e_swap(fore200e->stats->aux.large_b1_failed),
-		       fore200e_swap(fore200e->stats->aux.small_b2_failed),
-		       fore200e_swap(fore200e->stats->aux.large_b2_failed),
-		       fore200e_swap(fore200e->stats->aux.rpd_alloc_failed),
+		       cpu_to_be32(fore200e->stats->aux.small_b1_failed),
+		       cpu_to_be32(fore200e->stats->aux.large_b1_failed),
+		       cpu_to_be32(fore200e->stats->aux.small_b2_failed),
+		       cpu_to_be32(fore200e->stats->aux.large_b2_failed),
+		       cpu_to_be32(fore200e->stats->aux.rpd_alloc_failed),
 		       fore200e->tx_sat);
     
     if (!left--)
diff -ru 2.2/drivers/atm/Kconfig 3.4/drivers/atm/Kconfig
--- 2.2/drivers/atm/Kconfig	2006-12-08 19:06:17.000000000 +0100
+++ 3.4/drivers/atm/Kconfig	2006-12-23 01:11:22.000000000 +0100
@@ -167,10 +167,6 @@
 	  Note that extended debugging may create certain race conditions
 	  itself. Enable this ONLY if you suspect problems with the driver.
 
-#   bool 'Rolfs TI TNETA1570' CONFIG_ATM_TNETA1570 y
-#   if [ "$CONFIG_ATM_TNETA1570" = "y" ]; then
-#      bool '  Enable extended debugging' CONFIG_ATM_TNETA1570_DEBUG n
-#   fi
 config ATM_NICSTAR
 	tristate "IDT 77201 (NICStAR) (ForeRunnerLE)"
 	depends on PCI && ATM && !64BIT
diff -ru 2.2/drivers/base/firmware_class.c 3.4/drivers/base/firmware_class.c
--- 2.2/drivers/base/firmware_class.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/base/firmware_class.c	2006-12-23 01:11:19.000000000 +0100
@@ -127,6 +127,7 @@
 /**
  * firmware_loading_store - set value in the 'loading' control file
  * @dev: device pointer
+ * @attr: device attribute pointer
  * @buf: buffer to scan for loading control value
  * @count: number of bytes in @buf
  *
diff -ru 2.2/drivers/block/aoe/aoecmd.c 3.4/drivers/block/aoe/aoecmd.c
--- 2.2/drivers/block/aoe/aoecmd.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/block/aoe/aoecmd.c	2006-12-23 01:11:19.000000000 +0100
@@ -30,8 +30,6 @@
 		skb->nh.raw = skb->mac.raw = skb->data;
 		skb->protocol = __constant_htons(ETH_P_AOE);
 		skb->priority = 0;
-		skb_put(skb, len);
-		memset(skb->head, 0, len);
 		skb->next = skb->prev = NULL;
 
 		/* tell the network layer not to perform IP checksums
@@ -122,8 +120,8 @@
 	skb = f->skb;
 	h = (struct aoe_hdr *) skb->mac.raw;
 	ah = (struct aoe_atahdr *) (h+1);
-	skb->len = sizeof *h + sizeof *ah;
-	memset(h, 0, ETH_ZLEN);
+	skb_put(skb, sizeof *h + sizeof *ah);
+	memset(h, 0, skb->len);
 	f->tag = aoehdr_atainit(d, h);
 	f->waited = 0;
 	f->buf = buf;
@@ -149,7 +147,6 @@
 		skb->len += bcnt;
 		skb->data_len = bcnt;
 	} else {
-		skb->len = ETH_ZLEN;
 		writebit = 0;
 	}
 
@@ -206,6 +203,7 @@
 			printk(KERN_INFO "aoe: skb alloc failure\n");
 			continue;
 		}
+		skb_put(skb, sizeof *h + sizeof *ch);
 		skb->dev = ifp;
 		if (sl_tail == NULL)
 			sl_tail = skb;
@@ -243,6 +241,7 @@
 			continue;
 		if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) {
 			skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
+			skb_trim(f->skb, 0);
 			return f;
 		}
 		n++;
@@ -698,8 +697,8 @@
 	skb = f->skb;
 	h = (struct aoe_hdr *) skb->mac.raw;
 	ah = (struct aoe_atahdr *) (h+1);
-	skb->len = ETH_ZLEN;
-	memset(h, 0, ETH_ZLEN);
+	skb_put(skb, sizeof *h + sizeof *ah);
+	memset(h, 0, skb->len);
 	f->tag = aoehdr_atainit(d, h);
 	f->waited = 0;
 
diff -ru 2.2/drivers/block/cciss.c 3.4/drivers/block/cciss.c
--- 2.2/drivers/block/cciss.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/block/cciss.c	2006-12-22 01:57:07.000000000 +0100
@@ -1907,6 +1907,7 @@
 			       "does not support reading geometry\n");
 			drv->heads = 255;
 			drv->sectors = 32;	// Sectors per track
+			drv->raid_level = RAID_UNKNOWN;
 		} else {
 			drv->heads = inq_buff->data_byte[6];
 			drv->sectors = inq_buff->data_byte[7];
@@ -2491,7 +2492,7 @@
 	c->Request.Type.Type = TYPE_CMD;	// It is a command.
 	c->Request.Type.Attribute = ATTR_SIMPLE;
 	c->Request.Type.Direction =
-	    (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
+	    (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE;
 	c->Request.Timeout = 0;	// Don't time out
 	c->Request.CDB[0] =
 	    (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
diff -ru 2.2/drivers/block/viodasd.c 3.4/drivers/block/viodasd.c
--- 2.2/drivers/block/viodasd.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/block/viodasd.c	2006-12-22 01:57:07.000000000 +0100
@@ -49,6 +49,7 @@
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/hv_lp_config.h>
 #include <asm/iseries/vio.h>
+#include <asm/firmware.h>
 
 MODULE_DESCRIPTION("iSeries Virtual DASD");
 MODULE_AUTHOR("Dave Boutcher");
@@ -769,6 +770,11 @@
 {
 	int rc;
 
+	if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
+		rc = -ENODEV;
+		goto early_fail;
+	}
+
 	/* Try to open to our host lp */
 	if (viopath_hostLp == HvLpIndexInvalid)
 		vio_set_hostlp();
diff -ru 2.2/drivers/bluetooth/hci_usb.c 3.4/drivers/bluetooth/hci_usb.c
--- 2.2/drivers/bluetooth/hci_usb.c	2006-10-20 23:43:44.000000000 +0200
+++ 3.4/drivers/bluetooth/hci_usb.c	2006-12-22 01:57:07.000000000 +0100
@@ -126,6 +126,7 @@
 
 	/* Kensington Bluetooth USB adapter */
 	{ USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
+	{ USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_WRONG_SCO_MTU },
 
 	/* ISSC Bluetooth Adapter v3.1 */
 	{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
diff -ru 2.2/drivers/cdrom/cdrom.c 3.4/drivers/cdrom/cdrom.c
--- 2.2/drivers/cdrom/cdrom.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/cdrom/cdrom.c	2006-12-22 01:57:07.000000000 +0100
@@ -2139,8 +2139,7 @@
 			cdi->last_sense = s->sense_key;
 		}
 
-		rq->bio = bio;
-		if (blk_rq_unmap_user(rq))
+		if (blk_rq_unmap_user(bio))
 			ret = -EFAULT;
 
 		if (ret)
diff -ru 2.2/drivers/cdrom/viocd.c 3.4/drivers/cdrom/viocd.c
--- 2.2/drivers/cdrom/viocd.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/cdrom/viocd.c	2006-12-22 01:57:07.000000000 +0100
@@ -47,6 +47,7 @@
 #include <asm/iseries/hv_types.h>
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/vio.h>
+#include <asm/firmware.h>
 
 #define VIOCD_DEVICE			"iseries/vcd"
 
@@ -748,6 +749,9 @@
 	struct proc_dir_entry *e;
 	int ret = 0;
 
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -ENODEV;
+
 	if (viopath_hostLp == HvLpIndexInvalid) {
 		vio_set_hostlp();
 		/* If we don't have a host, bail out */
diff -ru 2.2/drivers/char/drm/drm_lock.c 3.4/drivers/char/drm/drm_lock.c
--- 2.2/drivers/char/drm/drm_lock.c	2006-12-10 05:32:05.000000000 +0100
+++ 3.4/drivers/char/drm/drm_lock.c	2006-12-22 01:57:07.000000000 +0100
@@ -182,7 +182,7 @@
 	 * modules but is required by the Sparc driver.
 	 */
 	if (dev->driver->kernel_context_switch_unlock)
-		dev->driver->kernel_context_switch_unlock(dev, &lock);
+		dev->driver->kernel_context_switch_unlock(dev);
 	else {
 		drm_lock_transfer(dev, &dev->lock.hw_lock->lock,
 				  DRM_KERNEL_CONTEXT);
diff -ru 2.2/drivers/char/drm/drmP.h 3.4/drivers/char/drm/drmP.h
--- 2.2/drivers/char/drm/drmP.h	2006-12-10 05:32:05.000000000 +0100
+++ 3.4/drivers/char/drm/drmP.h	2006-12-22 01:57:07.000000000 +0100
@@ -561,8 +561,7 @@
 	int (*context_dtor) (struct drm_device * dev, int context);
 	int (*kernel_context_switch) (struct drm_device * dev, int old,
 				      int new);
-	void (*kernel_context_switch_unlock) (struct drm_device * dev,
-					      drm_lock_t *lock);
+	void (*kernel_context_switch_unlock) (struct drm_device * dev);
 	int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
 	int (*vblank_wait2) (struct drm_device * dev, unsigned int *sequence);
 	int (*dri_library_name) (struct drm_device *dev, char *buf);
@@ -1143,9 +1142,5 @@
 extern unsigned long drm_core_get_map_ofs(drm_map_t * map);
 extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
 
-#ifndef pci_pretty_name
-#define pci_pretty_name(dev) ""
-#endif
-
 #endif				/* __KERNEL__ */
 #endif
diff -ru 2.2/drivers/char/drm/drm_stub.c 3.4/drivers/char/drm/drm_stub.c
--- 2.2/drivers/char/drm/drm_stub.c	2006-12-10 05:32:05.000000000 +0100
+++ 3.4/drivers/char/drm/drm_stub.c	2006-12-22 01:57:07.000000000 +0100
@@ -211,14 +211,16 @@
 	if (!dev)
 		return -ENOMEM;
 
-	pci_enable_device(pdev);
+	ret = pci_enable_device(pdev);
+	if (ret)
+		goto err_g1;
 
 	if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
 		printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
-		goto err_g1;
+		goto err_g2;
 	}
 	if ((ret = drm_get_head(dev, &dev->primary)))
-		goto err_g1;
+		goto err_g2;
 	
 	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
 		 driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -226,7 +228,9 @@
 
 	return 0;
 
-      err_g1:
+err_g2:
+	pci_disable_device(pdev);
+err_g1:
 	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
 	return ret;
 }
diff -ru 2.2/drivers/char/drm/drm_sysfs.c 3.4/drivers/char/drm/drm_sysfs.c
--- 2.2/drivers/char/drm/drm_sysfs.c	2006-10-26 16:21:09.000000000 +0200
+++ 3.4/drivers/char/drm/drm_sysfs.c	2006-12-22 01:57:07.000000000 +0100
@@ -45,8 +45,8 @@
 	int err;
 
 	class = class_create(owner, name);
-	if (!class) {
-		err = -ENOMEM;
+	if (IS_ERR(class)) {
+		err = PTR_ERR(class);
 		goto err_out;
 	}
 
@@ -113,8 +113,8 @@
 					MKDEV(DRM_MAJOR, head->minor),
 					&(head->dev->pdev)->dev,
 					"card%d", head->minor);
-	if (!class_dev) {
-		err = -ENOMEM;
+	if (IS_ERR(class_dev)) {
+		err = PTR_ERR(class_dev);
 		goto err_out;
 	}
 
diff -ru 2.2/drivers/char/drm/i915_irq.c 3.4/drivers/char/drm/i915_irq.c
--- 2.2/drivers/char/drm/i915_irq.c	2006-12-10 05:32:05.000000000 +0100
+++ 3.4/drivers/char/drm/i915_irq.c	2006-12-22 01:57:07.000000000 +0100
@@ -46,88 +46,167 @@
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long irqflags;
-	struct list_head *list, *tmp;
+	struct list_head *list, *tmp, hits, *hit;
+	int nhits, nrects, slice[2], upper[2], lower[2], i;
+	unsigned counter[2] = { atomic_read(&dev->vbl_received),
+				atomic_read(&dev->vbl_received2) };
+	drm_drawable_info_t *drw;
+	drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
+	u32 cpp = dev_priv->cpp;
+	u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
+				XY_SRC_COPY_BLT_WRITE_ALPHA |
+				XY_SRC_COPY_BLT_WRITE_RGB)
+			     : XY_SRC_COPY_BLT_CMD;
+	u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) |
+			  (cpp << 23) | (1 << 24);
+	RING_LOCALS;
 
 	DRM_DEBUG("\n");
 
+	INIT_LIST_HEAD(&hits);
+
+	nhits = nrects = 0;
+
 	spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
 
+	/* Find buffer swaps scheduled for this vertical blank */
 	list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
 		drm_i915_vbl_swap_t *vbl_swap =
 			list_entry(list, drm_i915_vbl_swap_t, head);
-		atomic_t *counter = vbl_swap->pipe ? &dev->vbl_received2 :
-			&dev->vbl_received;
 
-		if ((atomic_read(counter) - vbl_swap->sequence) <= (1<<23)) {
-			drm_drawable_info_t *drw;
+		if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
+			continue;
 
-			spin_unlock(&dev_priv->swaps_lock);
+		list_del(list);
+		dev_priv->swaps_pending--;
 
-			spin_lock(&dev->drw_lock);
-
-			drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
-				
-			if (drw) {
-				int i, num_rects = drw->num_rects;
-				drm_clip_rect_t *rect = drw->rects;
-				drm_i915_sarea_t *sarea_priv =
-				    dev_priv->sarea_priv;
-				u32 cpp = dev_priv->cpp;
-				u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
-							XY_SRC_COPY_BLT_WRITE_ALPHA |
-							XY_SRC_COPY_BLT_WRITE_RGB)
-						     : XY_SRC_COPY_BLT_CMD;
-				u32 pitchropcpp = (sarea_priv->pitch * cpp) |
-						  (0xcc << 16) | (cpp << 23) |
-						  (1 << 24);
-				RING_LOCALS;
-
-				i915_kernel_lost_context(dev);
-
-				BEGIN_LP_RING(6);
-
-				OUT_RING(GFX_OP_DRAWRECT_INFO);
-				OUT_RING(0);
-				OUT_RING(0);
-				OUT_RING(sarea_priv->width |
-					 sarea_priv->height << 16);
-				OUT_RING(sarea_priv->width |
-					 sarea_priv->height << 16);
-				OUT_RING(0);
+		spin_unlock(&dev_priv->swaps_lock);
+		spin_lock(&dev->drw_lock);
 
-				ADVANCE_LP_RING();
+		drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
 
-				sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
+		if (!drw) {
+			spin_unlock(&dev->drw_lock);
+			drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
+			spin_lock(&dev_priv->swaps_lock);
+			continue;
+		}
 
-				for (i = 0; i < num_rects; i++, rect++) {
-					BEGIN_LP_RING(8);
+		list_for_each(hit, &hits) {
+			drm_i915_vbl_swap_t *swap_cmp =
+				list_entry(hit, drm_i915_vbl_swap_t, head);
+			drm_drawable_info_t *drw_cmp =
+				drm_get_drawable_info(dev, swap_cmp->drw_id);
+
+			if (drw_cmp &&
+			    drw_cmp->rects[0].y1 > drw->rects[0].y1) {
+				list_add_tail(list, hit);
+				break;
+			}
+		}
 
-					OUT_RING(cmd);
-					OUT_RING(pitchropcpp);
-					OUT_RING((rect->y1 << 16) | rect->x1);
-					OUT_RING((rect->y2 << 16) | rect->x2);
-					OUT_RING(sarea_priv->front_offset);
-					OUT_RING((rect->y1 << 16) | rect->x1);
-					OUT_RING(pitchropcpp & 0xffff);
-					OUT_RING(sarea_priv->back_offset);
+		spin_unlock(&dev->drw_lock);
 
-					ADVANCE_LP_RING();
-				}
-			}
+		/* List of hits was empty, or we reached the end of it */
+		if (hit == &hits)
+			list_add_tail(list, hits.prev);
 
-			spin_unlock(&dev->drw_lock);
+		nhits++;
 
-			spin_lock(&dev_priv->swaps_lock);
+		spin_lock(&dev_priv->swaps_lock);
+	}
 
-			list_del(list);
+	if (nhits == 0) {
+		spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
+		return;
+	}
 
-			drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
+	spin_unlock(&dev_priv->swaps_lock);
+
+	i915_kernel_lost_context(dev);
 
-			dev_priv->swaps_pending--;
+	BEGIN_LP_RING(6);
+
+	OUT_RING(GFX_OP_DRAWRECT_INFO);
+	OUT_RING(0);
+	OUT_RING(0);
+	OUT_RING(sarea_priv->width | sarea_priv->height << 16);
+	OUT_RING(sarea_priv->width | sarea_priv->height << 16);
+	OUT_RING(0);
+
+	ADVANCE_LP_RING();
+
+	sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
+
+	upper[0] = upper[1] = 0;
+	slice[0] = max(sarea_priv->pipeA_h / nhits, 1);
+	slice[1] = max(sarea_priv->pipeB_h / nhits, 1);
+	lower[0] = sarea_priv->pipeA_y + slice[0];
+	lower[1] = sarea_priv->pipeB_y + slice[0];
+
+	spin_lock(&dev->drw_lock);
+
+	/* Emit blits for buffer swaps, partitioning both outputs into as many
+	 * slices as there are buffer swaps scheduled in order to avoid tearing
+	 * (based on the assumption that a single buffer swap would always
+	 * complete before scanout starts).
+	 */
+	for (i = 0; i++ < nhits;
+	     upper[0] = lower[0], lower[0] += slice[0],
+	     upper[1] = lower[1], lower[1] += slice[1]) {
+		if (i == nhits)
+			lower[0] = lower[1] = sarea_priv->height;
+
+		list_for_each(hit, &hits) {
+			drm_i915_vbl_swap_t *swap_hit =
+				list_entry(hit, drm_i915_vbl_swap_t, head);
+			drm_clip_rect_t *rect;
+			int num_rects, pipe;
+			unsigned short top, bottom;
+
+			drw = drm_get_drawable_info(dev, swap_hit->drw_id);
+
+			if (!drw)
+				continue;
+
+			rect = drw->rects;
+			pipe = swap_hit->pipe;
+			top = upper[pipe];
+			bottom = lower[pipe];
+
+			for (num_rects = drw->num_rects; num_rects--; rect++) {
+				int y1 = max(rect->y1, top);
+				int y2 = min(rect->y2, bottom);
+
+				if (y1 >= y2)
+					continue;
+
+				BEGIN_LP_RING(8);
+
+				OUT_RING(cmd);
+				OUT_RING(pitchropcpp);
+				OUT_RING((y1 << 16) | rect->x1);
+				OUT_RING((y2 << 16) | rect->x2);
+				OUT_RING(sarea_priv->front_offset);
+				OUT_RING((y1 << 16) | rect->x1);
+				OUT_RING(pitchropcpp & 0xffff);
+				OUT_RING(sarea_priv->back_offset);
+
+				ADVANCE_LP_RING();
+			}
 		}
 	}
 
-	spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
+	spin_unlock_irqrestore(&dev->drw_lock, irqflags);
+
+	list_for_each_safe(hit, tmp, &hits) {
+		drm_i915_vbl_swap_t *swap_hit =
+			list_entry(hit, drm_i915_vbl_swap_t, head);
+
+		list_del(hit);
+
+		drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
+	}
 }
 
 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
diff -ru 2.2/drivers/char/drm/r128_drm.h 3.4/drivers/char/drm/r128_drm.h
--- 2.2/drivers/char/drm/r128_drm.h	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/char/drm/r128_drm.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,8 @@
 /* r128_drm.h -- Public header for the r128 driver -*- linux-c -*-
  * Created: Wed Apr  5 19:24:19 2000 by kevin@precisioninsight.com
  */
-/* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
+/*
+ * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  * All rights reserved.
  *
diff -ru 2.2/drivers/char/drm/r128_drv.h 3.4/drivers/char/drm/r128_drv.h
--- 2.2/drivers/char/drm/r128_drv.h	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/char/drm/r128_drv.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,8 @@
 /* r128_drv.h -- Private header for r128 driver -*- linux-c -*-
  * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com
  */
-/* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+/*
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  * All rights reserved.
  *
diff -ru 2.2/drivers/char/drm/r128_state.c 3.4/drivers/char/drm/r128_state.c
--- 2.2/drivers/char/drm/r128_state.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/char/drm/r128_state.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,8 @@
 /* r128_state.c -- State support for r128 -*- linux-c -*-
  * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com
  */
-/* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+/*
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
diff -ru 2.2/drivers/char/drm/r300_cmdbuf.c 3.4/drivers/char/drm/r300_cmdbuf.c
--- 2.2/drivers/char/drm/r300_cmdbuf.c	2006-10-26 16:21:09.000000000 +0200
+++ 3.4/drivers/char/drm/r300_cmdbuf.c	2006-12-22 01:57:07.000000000 +0100
@@ -242,26 +242,6 @@
 	return 0;
 }
 
-/*
- * we expect offsets passed to the framebuffer to be either within video 
- * memory or within AGP space 
- */
-static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
-					u32 offset)
-{
-	/* we realy want to check against end of video aperture
-	   but this value is not being kept.
-	   This code is correct for now (does the same thing as the
-	   code that sets MC_FB_LOCATION) in radeon_cp.c */
-	if (offset >= dev_priv->fb_location &&
-	    offset < (dev_priv->fb_location + dev_priv->fb_size))
-		return 0;
-	if (offset >= dev_priv->gart_vm_start &&
-	    offset < (dev_priv->gart_vm_start + dev_priv->gart_size))
-		return 0;
-	return 1;
-}
-
 static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
 							  dev_priv,
 							  drm_radeon_kcmd_buffer_t
@@ -290,7 +270,7 @@
 		case MARK_SAFE:
 			break;
 		case MARK_CHECK_OFFSET:
-			if (r300_check_offset(dev_priv, (u32) values[i])) {
+			if (!radeon_check_offset(dev_priv, (u32) values[i])) {
 				DRM_ERROR
 				    ("Offset failed range check (reg=%04x sz=%d)\n",
 				     reg, sz);
@@ -452,7 +432,7 @@
 	i = 1;
 	while ((k < narrays) && (i < (count + 1))) {
 		i++;		/* skip attribute field */
-		if (r300_check_offset(dev_priv, payload[i])) {
+		if (!radeon_check_offset(dev_priv, payload[i])) {
 			DRM_ERROR
 			    ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
 			     k, i);
@@ -463,7 +443,7 @@
 		if (k == narrays)
 			break;
 		/* have one more to process, they come in pairs */
-		if (r300_check_offset(dev_priv, payload[i])) {
+		if (!radeon_check_offset(dev_priv, payload[i])) {
 			DRM_ERROR
 			    ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
 			     k, i);
@@ -508,7 +488,7 @@
 		if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL 
 			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
 			offset = cmd[2] << 10;
-			ret = r300_check_offset(dev_priv, offset);
+			ret = !radeon_check_offset(dev_priv, offset);
 			if (ret) {
 				DRM_ERROR("Invalid bitblt first offset is %08X\n", offset);
 				return DRM_ERR(EINVAL);
@@ -518,7 +498,7 @@
 		if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
 		    (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
 			offset = cmd[3] << 10;
-			ret = r300_check_offset(dev_priv, offset);
+			ret = !radeon_check_offset(dev_priv, offset);
 			if (ret) {
 				DRM_ERROR("Invalid bitblt second offset is %08X\n", offset);
 				return DRM_ERR(EINVAL);
@@ -551,7 +531,7 @@
 		DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
 		return DRM_ERR(EINVAL);
 	}
-	ret = r300_check_offset(dev_priv, cmd[2]);
+	ret = !radeon_check_offset(dev_priv, cmd[2]);
 	if (ret) {
 		DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
 		return DRM_ERR(EINVAL);
diff -ru 2.2/drivers/char/drm/radeon_drv.h 3.4/drivers/char/drm/radeon_drv.h
--- 2.2/drivers/char/drm/radeon_drv.h	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/char/drm/radeon_drv.h	2006-12-22 01:57:07.000000000 +0100
@@ -303,6 +303,21 @@
 extern drm_ioctl_desc_t radeon_ioctls[];
 extern int radeon_max_ioctl;
 
+/* Check whether the given hardware address is inside the framebuffer or the
+ * GART area.
+ */
+static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
+					  u64 off)
+{
+	u32 fb_start = dev_priv->fb_location;
+	u32 fb_end = fb_start + dev_priv->fb_size - 1;
+	u32 gart_start = dev_priv->gart_vm_start;
+	u32 gart_end = gart_start + dev_priv->gart_size - 1;
+
+	return ((off >= fb_start && off <= fb_end) ||
+		(off >= gart_start && off <= gart_end));
+}
+
 				/* radeon_cp.c */
 extern int radeon_cp_init(DRM_IOCTL_ARGS);
 extern int radeon_cp_start(DRM_IOCTL_ARGS);
diff -ru 2.2/drivers/char/drm/radeon_irq.c 3.4/drivers/char/drm/radeon_irq.c
--- 2.2/drivers/char/drm/radeon_irq.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/char/drm/radeon_irq.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,5 +1,5 @@
-/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*-
- *
+/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */
+/*
  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
  *
  * The Weather Channel (TM) funded Tungsten Graphics to develop the
diff -ru 2.2/drivers/char/drm/radeon_mem.c 3.4/drivers/char/drm/radeon_mem.c
--- 2.2/drivers/char/drm/radeon_mem.c	2006-10-02 17:39:12.000000000 +0200
+++ 3.4/drivers/char/drm/radeon_mem.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,5 +1,5 @@
-/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*-
- *
+/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */
+/*
  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
  *
  * The Weather Channel (TM) funded Tungsten Graphics to develop the
diff -ru 2.2/drivers/char/drm/radeon_state.c 3.4/drivers/char/drm/radeon_state.c
--- 2.2/drivers/char/drm/radeon_state.c	2006-10-26 16:21:09.000000000 +0200
+++ 3.4/drivers/char/drm/radeon_state.c	2006-12-22 01:57:07.000000000 +0100
@@ -43,10 +43,7 @@
 						    u32 *offset)
 {
 	u64 off = *offset;
-	u32 fb_start = dev_priv->fb_location;
-	u32 fb_end = fb_start + dev_priv->fb_size - 1;
-	u32 gart_start = dev_priv->gart_vm_start;
-	u32 gart_end = gart_start + dev_priv->gart_size - 1;
+	u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1;
 	struct drm_radeon_driver_file_fields *radeon_priv;
 
 	/* Hrm ... the story of the offset ... So this function converts
@@ -66,8 +63,7 @@
 	/* First, the best case, the offset already lands in either the
 	 * framebuffer or the GART mapped space
 	 */
-	if ((off >= fb_start && off <= fb_end) ||
-	    (off >= gart_start && off <= gart_end))
+	if (radeon_check_offset(dev_priv, off))
 		return 0;
 
 	/* Ok, that didn't happen... now check if we have a zero based
@@ -81,11 +77,10 @@
 
 	/* Finally, assume we aimed at a GART offset if beyond the fb */
 	if (off > fb_end)
-		off = off - fb_end - 1 + gart_start;
+		off = off - fb_end - 1 + dev_priv->gart_vm_start;
 
 	/* Now recheck and fail if out of bounds */
-	if ((off >= fb_start && off <= fb_end) ||
-	    (off >= gart_start && off <= gart_end)) {
+	if (radeon_check_offset(dev_priv, off)) {
 		DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
 		*offset = off;
 		return 0;
diff -ru 2.2/drivers/char/drm/savage_bci.c 3.4/drivers/char/drm/savage_bci.c
--- 2.2/drivers/char/drm/savage_bci.c	2006-10-26 16:21:09.000000000 +0200
+++ 3.4/drivers/char/drm/savage_bci.c	2006-12-22 01:57:07.000000000 +0100
@@ -963,8 +963,8 @@
 
 	event.count = savage_bci_emit_event(dev_priv, event.flags);
 	event.count |= dev_priv->event_wrap << 16;
-	DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *) data)->
-			       count, event.count, sizeof(event.count));
+	DRM_COPY_TO_USER_IOCTL((drm_savage_event_emit_t __user *) data,
+			       event, sizeof(event));
 	return 0;
 }
 
diff -ru 2.2/drivers/char/rtc.c 3.4/drivers/char/rtc.c
--- 2.2/drivers/char/rtc.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/char/rtc.c	2006-12-23 01:11:19.000000000 +0100
@@ -113,7 +113,12 @@
 #define hpet_set_rtc_irq_bit(arg) 		0
 #define hpet_rtc_timer_init() 			do { } while (0)
 #define hpet_rtc_dropped_irq() 			0
-static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) {return 0;}
+#ifdef RTC_IRQ
+static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
+{
+	return 0;
+}
+#endif
 #else
 extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
 #endif
diff -ru 2.2/drivers/char/tlclk.c 3.4/drivers/char/tlclk.c
--- 2.2/drivers/char/tlclk.c	2006-11-26 17:26:08.000000000 +0100
+++ 3.4/drivers/char/tlclk.c	2006-12-23 01:11:19.000000000 +0100
@@ -807,8 +807,6 @@
 			&tlclk_attribute_group);
 	if (ret) {
 		printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n");
-		sysfs_remove_group(&tlclk_device->dev.kobj,
-			&tlclk_attribute_group);
 		goto out5;
 	}
 
diff -ru 2.2/drivers/char/viocons.c 3.4/drivers/char/viocons.c
--- 2.2/drivers/char/viocons.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/char/viocons.c	2006-12-22 01:57:07.000000000 +0100
@@ -42,6 +42,7 @@
 #include <linux/tty_flip.h>
 #include <linux/sysrq.h>
 
+#include <asm/firmware.h>
 #include <asm/iseries/vio.h>
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/hv_call_event.h>
@@ -1060,6 +1061,9 @@
 	atomic_t wait_flag;
 	int rc;
 
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -ENODEV;
+
 	/* +2 for fudge */
 	rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
 			viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
@@ -1145,6 +1149,9 @@
 {
 	int i;
 
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -ENODEV;
+
 	printk(VIOCONS_KERN_INFO "registering console\n");
 	for (i = 0; i < VTTY_PORTS; i++) {
 		port_info[i].lp = HvLpIndexInvalid;
diff -ru 2.2/drivers/char/viotape.c 3.4/drivers/char/viotape.c
--- 2.2/drivers/char/viotape.c	2006-12-08 19:05:36.000000000 +0100
+++ 3.4/drivers/char/viotape.c	2006-12-22 01:57:07.000000000 +0100
@@ -49,7 +49,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
-
+#include <asm/firmware.h>
 #include <asm/vio.h>
 #include <asm/iseries/vio.h>
 #include <asm/iseries/hv_lp_event.h>
@@ -997,6 +997,9 @@
 	int ret;
 	struct proc_dir_entry *e;
 
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -ENODEV;
+
 	op_struct_list = NULL;
 	if ((ret = add_op_structs(VIOTAPE_MAXREQ)) < 0) {
 		printk(VIOTAPE_KERN_WARN "couldn't allocate op structs\n");
diff -ru 2.2/drivers/connector/cn_queue.c 3.4/drivers/connector/cn_queue.c
--- 2.2/drivers/connector/cn_queue.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/connector/cn_queue.c	2006-12-22 01:57:07.000000000 +0100
@@ -34,7 +34,7 @@
 void cn_queue_wrapper(struct work_struct *work)
 {
 	struct cn_callback_entry *cbq =
-		container_of(work, struct cn_callback_entry, work.work);
+		container_of(work, struct cn_callback_entry, work);
 	struct cn_callback_data *d = &cbq->data;
 
 	d->callback(d->callback_priv);
@@ -59,13 +59,12 @@
 	memcpy(&cbq->id.id, id, sizeof(struct cb_id));
 	cbq->data.callback = callback;
 	
-	INIT_DELAYED_WORK(&cbq->work, &cn_queue_wrapper);
+	INIT_WORK(&cbq->work, &cn_queue_wrapper);
 	return cbq;
 }
 
 static void cn_queue_free_callback(struct cn_callback_entry *cbq)
 {
-	cancel_delayed_work(&cbq->work);
 	flush_workqueue(cbq->pdev->cn_queue);
 
 	kfree(cbq);
diff -ru 2.2/drivers/connector/connector.c 3.4/drivers/connector/connector.c
--- 2.2/drivers/connector/connector.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/connector/connector.c	2006-12-22 01:57:07.000000000 +0100
@@ -135,17 +135,15 @@
 	spin_lock_bh(&dev->cbdev->queue_lock);
 	list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
 		if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
-			if (likely(!test_bit(WORK_STRUCT_PENDING,
-					     &__cbq->work.work.management) &&
+			if (likely(!work_pending(&__cbq->work) &&
 					__cbq->data.ddata == NULL)) {
 				__cbq->data.callback_priv = msg;
 
 				__cbq->data.ddata = data;
 				__cbq->data.destruct_data = destruct_data;
 
-				if (queue_delayed_work(
-					    dev->cbdev->cn_queue,
-					    &__cbq->work, 0))
+				if (queue_work(dev->cbdev->cn_queue,
+							&__cbq->work))
 					err = 0;
 			} else {
 				struct cn_callback_data *d;
@@ -159,12 +157,11 @@
 					d->destruct_data = destruct_data;
 					d->free = __cbq;
 
-					INIT_DELAYED_WORK(&__cbq->work,
-							  &cn_queue_wrapper);
+					INIT_WORK(&__cbq->work,
+							&cn_queue_wrapper);
 					
-					if (queue_delayed_work(
-						    dev->cbdev->cn_queue,
-						    &__cbq->work, 0))
+					if (queue_work(dev->cbdev->cn_queue,
+						    &__cbq->work))
 						err = 0;
 					else {
 						kfree(__cbq);
diff -ru 2.2/drivers/cpufreq/cpufreq.c 3.4/drivers/cpufreq/cpufreq.c
--- 2.2/drivers/cpufreq/cpufreq.c	2006-12-13 18:28:47.000000000 +0100
+++ 3.4/drivers/cpufreq/cpufreq.c	2006-12-18 04:27:33.000000000 +0100
@@ -959,7 +959,7 @@
 
 
 /**
- * cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur
+ * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
  * @cpu: CPU number
  *
  * This is the last known freq, without actually getting it from the driver.
diff -ru 2.2/drivers/hid/hid-input.c 3.4/drivers/hid/hid-input.c
--- 2.2/drivers/hid/hid-input.c	2006-12-10 05:32:07.000000000 +0100
+++ 3.4/drivers/hid/hid-input.c	2006-12-22 01:57:07.000000000 +0100
@@ -415,12 +415,31 @@
 				case 0x000: goto ignore;
 				case 0x034: map_key_clear(KEY_SLEEP);		break;
 				case 0x036: map_key_clear(BTN_MISC);		break;
+				case 0x040: map_key_clear(KEY_MENU);		break;
 				case 0x045: map_key_clear(KEY_RADIO);		break;
+
+				case 0x088: map_key_clear(KEY_PC);		break;
+				case 0x089: map_key_clear(KEY_TV);		break;
 				case 0x08a: map_key_clear(KEY_WWW);		break;
+				case 0x08b: map_key_clear(KEY_DVD);		break;
+				case 0x08c: map_key_clear(KEY_PHONE);		break;
 				case 0x08d: map_key_clear(KEY_PROGRAM);		break;
+				case 0x08e: map_key_clear(KEY_VIDEOPHONE);	break;
+				case 0x08f: map_key_clear(KEY_GAMES);		break;
+				case 0x090: map_key_clear(KEY_MEMO);		break;
+				case 0x091: map_key_clear(KEY_CD);		break;
+				case 0x092: map_key_clear(KEY_VCR);		break;
+				case 0x093: map_key_clear(KEY_TUNER);		break;
+				case 0x094: map_key_clear(KEY_EXIT);		break;
 				case 0x095: map_key_clear(KEY_HELP);		break;
+				case 0x096: map_key_clear(KEY_TAPE);		break;
+				case 0x097: map_key_clear(KEY_TV2);		break;
+				case 0x098: map_key_clear(KEY_SAT);		break;
+
 				case 0x09c: map_key_clear(KEY_CHANNELUP);	break;
 				case 0x09d: map_key_clear(KEY_CHANNELDOWN);	break;
+				case 0x0a0: map_key_clear(KEY_VCR2);		break;
+
 				case 0x0b0: map_key_clear(KEY_PLAY);		break;
 				case 0x0b1: map_key_clear(KEY_PAUSE);		break;
 				case 0x0b2: map_key_clear(KEY_RECORD);		break;
@@ -430,6 +449,7 @@
 				case 0x0b6: map_key_clear(KEY_PREVIOUSSONG);	break;
 				case 0x0b7: map_key_clear(KEY_STOPCD);		break;
 				case 0x0b8: map_key_clear(KEY_EJECTCD);		break;
+
 				case 0x0cd: map_key_clear(KEY_PLAYPAUSE);	break;
 			        case 0x0e0: map_abs_clear(ABS_VOLUME);		break;
 				case 0x0e2: map_key_clear(KEY_MUTE);		break;
@@ -437,11 +457,30 @@
 				case 0x0e9: map_key_clear(KEY_VOLUMEUP);	break;
 				case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);	break;
 				case 0x183: map_key_clear(KEY_CONFIG);		break;
+				case 0x184: map_key_clear(KEY_WORDPROCESSOR);	break;
+				case 0x185: map_key_clear(KEY_EDITOR);		break;
+				case 0x186: map_key_clear(KEY_SPREADSHEET);	break;
+				case 0x187: map_key_clear(KEY_GRAPHICSEDITOR);	break;
+				case 0x188: map_key_clear(KEY_PRESENTATION);	break;
+				case 0x189: map_key_clear(KEY_DATABASE);	break;
 				case 0x18a: map_key_clear(KEY_MAIL);		break;
+				case 0x18b: map_key_clear(KEY_NEWS);		break;
+				case 0x18c: map_key_clear(KEY_VOICEMAIL);	break;
+				case 0x18d: map_key_clear(KEY_ADDRESSBOOK);	break;
+				case 0x18e: map_key_clear(KEY_CALENDAR);	break;
+				case 0x191: map_key_clear(KEY_FINANCE);		break;
 				case 0x192: map_key_clear(KEY_CALC);		break;
 				case 0x194: map_key_clear(KEY_FILE);		break;
+				case 0x196: map_key_clear(KEY_WWW);		break;
+				case 0x19e: map_key_clear(KEY_COFFEE);		break;
+				case 0x1a6: map_key_clear(KEY_HELP);		break;
 				case 0x1a7: map_key_clear(KEY_DOCUMENTS);	break;
+				case 0x1bc: map_key_clear(KEY_MESSENGER);	break;
+				case 0x1bd: map_key_clear(KEY_INFO);		break;
 				case 0x201: map_key_clear(KEY_NEW);		break;
+				case 0x202: map_key_clear(KEY_OPEN);		break;
+				case 0x203: map_key_clear(KEY_CLOSE);		break;
+				case 0x204: map_key_clear(KEY_EXIT);		break;
 				case 0x207: map_key_clear(KEY_SAVE);		break;
 				case 0x208: map_key_clear(KEY_PRINT);		break;
 				case 0x209: map_key_clear(KEY_PROPS);		break;
@@ -456,10 +495,15 @@
 				case 0x226: map_key_clear(KEY_STOP);		break;
 				case 0x227: map_key_clear(KEY_REFRESH);		break;
 				case 0x22a: map_key_clear(KEY_BOOKMARKS);	break;
+				case 0x22d: map_key_clear(KEY_ZOOMIN);		break;
+				case 0x22e: map_key_clear(KEY_ZOOMOUT);		break;
+				case 0x22f: map_key_clear(KEY_ZOOMRESET);	break;
 				case 0x233: map_key_clear(KEY_SCROLLUP);	break;
 				case 0x234: map_key_clear(KEY_SCROLLDOWN);	break;
 				case 0x238: map_rel(REL_HWHEEL);		break;
+				case 0x25f: map_key_clear(KEY_CANCEL);		break;
 				case 0x279: map_key_clear(KEY_REDO);		break;
+
 				case 0x289: map_key_clear(KEY_REPLY);		break;
 				case 0x28b: map_key_clear(KEY_FORWARDMAIL);	break;
 				case 0x28c: map_key_clear(KEY_SEND);		break;
diff -ru 2.2/drivers/ide/pci/atiixp.c 3.4/drivers/ide/pci/atiixp.c
--- 2.2/drivers/ide/pci/atiixp.c	2006-10-04 21:18:04.000000000 +0200
+++ 3.4/drivers/ide/pci/atiixp.c	2006-12-22 01:57:07.000000000 +0100
@@ -368,7 +368,6 @@
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, PCI_ANY_ID, PCI_ANY_ID, (PCI_CLASS_STORAGE_IDE<<8)|0x8a, 0xffff05, 1},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff -ru 2.2/drivers/infiniband/hw/mthca/mthca_main.c 3.4/drivers/infiniband/hw/mthca/mthca_main.c
--- 2.2/drivers/infiniband/hw/mthca/mthca_main.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/infiniband/hw/mthca/mthca_main.c	2006-12-18 04:27:33.000000000 +0100
@@ -80,24 +80,61 @@
 module_param(tune_pci, int, 0444);
 MODULE_PARM_DESC(tune_pci, "increase PCI burst from the default set by BIOS if nonzero");
 
-struct mutex mthca_device_mutex;
+DEFINE_MUTEX(mthca_device_mutex);
+
+#define MTHCA_DEFAULT_NUM_QP            (1 << 16)
+#define MTHCA_DEFAULT_RDB_PER_QP        (1 << 2)
+#define MTHCA_DEFAULT_NUM_CQ            (1 << 16)
+#define MTHCA_DEFAULT_NUM_MCG           (1 << 13)
+#define MTHCA_DEFAULT_NUM_MPT           (1 << 17)
+#define MTHCA_DEFAULT_NUM_MTT           (1 << 20)
+#define MTHCA_DEFAULT_NUM_UDAV          (1 << 15)
+#define MTHCA_DEFAULT_NUM_RESERVED_MTTS (1 << 18)
+#define MTHCA_DEFAULT_NUM_UARC_SIZE     (1 << 18)
+
+static struct mthca_profile hca_profile = {
+	.num_qp             = MTHCA_DEFAULT_NUM_QP,
+	.rdb_per_qp         = MTHCA_DEFAULT_RDB_PER_QP,
+	.num_cq             = MTHCA_DEFAULT_NUM_CQ,
+	.num_mcg            = MTHCA_DEFAULT_NUM_MCG,
+	.num_mpt            = MTHCA_DEFAULT_NUM_MPT,
+	.num_mtt            = MTHCA_DEFAULT_NUM_MTT,
+	.num_udav           = MTHCA_DEFAULT_NUM_UDAV,          /* Tavor only */
+	.fmr_reserved_mtts  = MTHCA_DEFAULT_NUM_RESERVED_MTTS, /* Tavor only */
+	.uarc_size          = MTHCA_DEFAULT_NUM_UARC_SIZE,     /* Arbel only */
+};
+
+module_param_named(num_qp, hca_profile.num_qp, int, 0444);
+MODULE_PARM_DESC(num_qp, "maximum number of QPs per HCA");
+
+module_param_named(rdb_per_qp, hca_profile.rdb_per_qp, int, 0444);
+MODULE_PARM_DESC(rdb_per_qp, "number of RDB buffers per QP");
+
+module_param_named(num_cq, hca_profile.num_cq, int, 0444);
+MODULE_PARM_DESC(num_cq, "maximum number of CQs per HCA");
+
+module_param_named(num_mcg, hca_profile.num_mcg, int, 0444);
+MODULE_PARM_DESC(num_mcg, "maximum number of multicast groups per HCA");
+
+module_param_named(num_mpt, hca_profile.num_mpt, int, 0444);
+MODULE_PARM_DESC(num_mpt,
+		"maximum number of memory protection table entries per HCA");
+
+module_param_named(num_mtt, hca_profile.num_mtt, int, 0444);
+MODULE_PARM_DESC(num_mtt,
+		 "maximum number of memory translation table segments per HCA");
+
+module_param_named(num_udav, hca_profile.num_udav, int, 0444);
+MODULE_PARM_DESC(num_udav, "maximum number of UD address vectors per HCA");
+
+module_param_named(fmr_reserved_mtts, hca_profile.fmr_reserved_mtts, int, 0444);
+MODULE_PARM_DESC(fmr_reserved_mtts,
+		 "number of memory translation table segments reserved for FMR");
 
 static const char mthca_version[] __devinitdata =
 	DRV_NAME ": Mellanox InfiniBand HCA driver v"
 	DRV_VERSION " (" DRV_RELDATE ")\n";
 
-static struct mthca_profile default_profile = {
-	.num_qp		   = 1 << 16,
-	.rdb_per_qp	   = 4,
-	.num_cq		   = 1 << 16,
-	.num_mcg	   = 1 << 13,
-	.num_mpt	   = 1 << 17,
-	.num_mtt	   = 1 << 20,
-	.num_udav	   = 1 << 15,	/* Tavor only */
-	.fmr_reserved_mtts = 1 << 18,	/* Tavor only */
-	.uarc_size	   = 1 << 18,	/* Arbel only */
-};
-
 static int mthca_tune_pci(struct mthca_dev *mdev)
 {
 	int cap;
@@ -303,7 +340,7 @@
 		goto err_disable;
 	}
 
-	profile = default_profile;
+	profile = hca_profile;
 	profile.num_uar   = dev_lim.uar_size / PAGE_SIZE;
 	profile.uarc_size = 0;
 	if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
@@ -621,7 +658,7 @@
 		goto err_stop_fw;
 	}
 
-	profile = default_profile;
+	profile = hca_profile;
 	profile.num_uar  = dev_lim.uar_size / PAGE_SIZE;
 	profile.num_udav = 0;
 	if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
@@ -1278,11 +1315,55 @@
 	.remove		= __devexit_p(mthca_remove_one)
 };
 
+static void __init __mthca_check_profile_val(const char *name, int *pval,
+					     int pval_default)
+{
+	/* value must be positive and power of 2 */
+	int old_pval = *pval;
+
+	if (old_pval <= 0)
+		*pval = pval_default;
+	else
+		*pval = roundup_pow_of_two(old_pval);
+
+	if (old_pval != *pval) {
+		printk(KERN_WARNING PFX "Invalid value %d for %s in module parameter.\n",
+		       old_pval, name);
+		printk(KERN_WARNING PFX "Corrected %s to %d.\n", name, *pval);
+	}
+}
+
+#define mthca_check_profile_val(name, default)				\
+	__mthca_check_profile_val(#name, &hca_profile.name, default)
+
+static void __init mthca_validate_profile(void)
+{
+	mthca_check_profile_val(num_qp,            MTHCA_DEFAULT_NUM_QP);
+	mthca_check_profile_val(rdb_per_qp,        MTHCA_DEFAULT_RDB_PER_QP);
+	mthca_check_profile_val(num_cq,            MTHCA_DEFAULT_NUM_CQ);
+	mthca_check_profile_val(num_mcg, 	   MTHCA_DEFAULT_NUM_MCG);
+	mthca_check_profile_val(num_mpt, 	   MTHCA_DEFAULT_NUM_MPT);
+	mthca_check_profile_val(num_mtt, 	   MTHCA_DEFAULT_NUM_MTT);
+	mthca_check_profile_val(num_udav,          MTHCA_DEFAULT_NUM_UDAV);
+	mthca_check_profile_val(fmr_reserved_mtts, MTHCA_DEFAULT_NUM_RESERVED_MTTS);
+
+	if (hca_profile.fmr_reserved_mtts >= hca_profile.num_mtt) {
+		printk(KERN_WARNING PFX "Invalid fmr_reserved_mtts module parameter %d.\n",
+		       hca_profile.fmr_reserved_mtts);
+		printk(KERN_WARNING PFX "(Must be smaller than num_mtt %d)\n",
+		       hca_profile.num_mtt);
+		hca_profile.fmr_reserved_mtts = hca_profile.num_mtt / 2;
+		printk(KERN_WARNING PFX "Corrected fmr_reserved_mtts to %d.\n",
+		       hca_profile.fmr_reserved_mtts);
+	}
+}
+
 static int __init mthca_init(void)
 {
 	int ret;
 
-	mutex_init(&mthca_device_mutex);
+	mthca_validate_profile();
+
 	ret = mthca_catas_init();
 	if (ret)
 		return ret;
diff -ru 2.2/drivers/infiniband/ulp/srp/ib_srp.c 3.4/drivers/infiniband/ulp/srp/ib_srp.c
--- 2.2/drivers/infiniband/ulp/srp/ib_srp.c	2006-12-13 18:28:47.000000000 +0100
+++ 3.4/drivers/infiniband/ulp/srp/ib_srp.c	2006-12-18 04:27:33.000000000 +0100
@@ -1898,7 +1898,7 @@
 	 */
 	srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1);
 	srp_dev->fmr_page_size  = 1 << srp_dev->fmr_page_shift;
-	srp_dev->fmr_page_mask  = ~((unsigned long) srp_dev->fmr_page_size - 1);
+	srp_dev->fmr_page_mask  = ~((u64) srp_dev->fmr_page_size - 1);
 
 	INIT_LIST_HEAD(&srp_dev->dev_list);
 
diff -ru 2.2/drivers/infiniband/ulp/srp/ib_srp.h 3.4/drivers/infiniband/ulp/srp/ib_srp.h
--- 2.2/drivers/infiniband/ulp/srp/ib_srp.h	2006-12-13 18:28:47.000000000 +0100
+++ 3.4/drivers/infiniband/ulp/srp/ib_srp.h	2006-12-18 04:27:33.000000000 +0100
@@ -87,7 +87,7 @@
 	struct ib_fmr_pool     *fmr_pool;
 	int			fmr_page_shift;
 	int			fmr_page_size;
-	unsigned long		fmr_page_mask;
+	u64			fmr_page_mask;
 };
 
 struct srp_host {
diff -ru 2.2/drivers/input/keyboard/amikbd.c 3.4/drivers/input/keyboard/amikbd.c
--- 2.2/drivers/input/keyboard/amikbd.c	2006-12-08 14:37:38.000000000 +0100
+++ 3.4/drivers/input/keyboard/amikbd.c	2006-12-18 04:27:33.000000000 +0100
@@ -187,7 +187,7 @@
 
 static int __init amikbd_init(void)
 {
-	int i, j;
+	int i, j, err;
 
 	if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
 		return -ENODEV;
diff -ru 2.2/drivers/input/keyboard/sunkbd.c 3.4/drivers/input/keyboard/sunkbd.c
--- 2.2/drivers/input/keyboard/sunkbd.c	2006-12-08 14:37:38.000000000 +0100
+++ 3.4/drivers/input/keyboard/sunkbd.c	2006-12-18 04:27:33.000000000 +0100
@@ -225,7 +225,7 @@
 static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
 {
 	serio_pause_rx(sunkbd->serio);
-	sunkbd->enabled = 1;
+	sunkbd->enabled = enable;
 	serio_continue_rx(sunkbd->serio);
 }
 
diff -ru 2.2/drivers/isdn/i4l/isdn_ppp.c 3.4/drivers/isdn/i4l/isdn_ppp.c
--- 2.2/drivers/isdn/i4l/isdn_ppp.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/isdn/i4l/isdn_ppp.c	2006-12-23 01:11:19.000000000 +0100
@@ -2339,6 +2339,7 @@
 		rs->state = CCPResetIdle;
 		rs->is = is;
 		rs->id = id;
+		init_timer(&rs->timer);
 		rs->timer.data = (unsigned long)rs;
 		rs->timer.function = isdn_ppp_ccp_timer_callback;
 		is->reset->rs[id] = rs;
diff -ru 2.2/drivers/kvm/kvm_main.c 3.4/drivers/kvm/kvm_main.c
--- 2.2/drivers/kvm/kvm_main.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/kvm/kvm_main.c	2006-12-23 01:11:19.000000000 +0100
@@ -113,6 +113,11 @@
 }
 EXPORT_SYMBOL_GPL(segment_base);
 
+static inline int valid_vcpu(int n)
+{
+	return likely(n >= 0 && n < KVM_MAX_VCPUS);
+}
+
 int kvm_read_guest(struct kvm_vcpu *vcpu,
 			     gva_t addr,
 			     unsigned long size,
@@ -494,7 +499,7 @@
 	struct kvm_vcpu *vcpu;
 
 	r = -EINVAL;
-	if (n < 0 || n >= KVM_MAX_VCPUS)
+	if (!valid_vcpu(n))
 		goto out;
 
 	vcpu = &kvm->vcpus[n];
@@ -1179,7 +1184,7 @@
 	struct kvm_vcpu *vcpu;
 	int r;
 
-	if (kvm_run->vcpu < 0 || kvm_run->vcpu >= KVM_MAX_VCPUS)
+	if (!valid_vcpu(kvm_run->vcpu))
 		return -EINVAL;
 
 	vcpu = vcpu_load(kvm, kvm_run->vcpu);
@@ -1208,7 +1213,7 @@
 {
 	struct kvm_vcpu *vcpu;
 
-	if (regs->vcpu < 0 || regs->vcpu >= KVM_MAX_VCPUS)
+	if (!valid_vcpu(regs->vcpu))
 		return -EINVAL;
 
 	vcpu = vcpu_load(kvm, regs->vcpu);
@@ -1254,7 +1259,7 @@
 {
 	struct kvm_vcpu *vcpu;
 
-	if (regs->vcpu < 0 || regs->vcpu >= KVM_MAX_VCPUS)
+	if (!valid_vcpu(regs->vcpu))
 		return -EINVAL;
 
 	vcpu = vcpu_load(kvm, regs->vcpu);
@@ -1301,7 +1306,7 @@
 	struct kvm_vcpu *vcpu;
 	struct descriptor_table dt;
 
-	if (sregs->vcpu < 0 || sregs->vcpu >= KVM_MAX_VCPUS)
+	if (!valid_vcpu(sregs->vcpu))
 		return -EINVAL;
 	vcpu = vcpu_load(kvm, sregs->vcpu);
 	if (!vcpu)
@@ -1353,7 +1358,7 @@
 	int i;
 	struct descriptor_table dt;
 
-	if (sregs->vcpu < 0 || sregs->vcpu >= KVM_MAX_VCPUS)
+	if (!valid_vcpu(sregs->vcpu))
 		return -EINVAL;
 	vcpu = vcpu_load(kvm, sregs->vcpu);
 	if (!vcpu)
@@ -1412,6 +1417,9 @@
 /*
  * List of msr numbers which we expose to userspace through KVM_GET_MSRS
  * 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.
  */
 static u32 msrs_to_save[] = {
 	MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
@@ -1422,6 +1430,22 @@
 	MSR_IA32_TIME_STAMP_COUNTER,
 };
 
+static unsigned num_msrs_to_save;
+
+static __init void kvm_init_msr_list(void)
+{
+	u32 dummy[2];
+	unsigned i, j;
+
+	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)
+			msrs_to_save[j] = msrs_to_save[i];
+		j++;
+	}
+	num_msrs_to_save = j;
+}
 
 /*
  * Adapt set_msr() to msr_io()'s calling convention
@@ -1444,7 +1468,7 @@
 	struct kvm_vcpu *vcpu;
 	int i;
 
-	if (msrs->vcpu < 0 || msrs->vcpu >= KVM_MAX_VCPUS)
+	if (!valid_vcpu(msrs->vcpu))
 		return -EINVAL;
 
 	vcpu = vcpu_load(kvm, msrs->vcpu);
@@ -1537,7 +1561,7 @@
 {
 	struct kvm_vcpu *vcpu;
 
-	if (irq->vcpu < 0 || irq->vcpu >= KVM_MAX_VCPUS)
+	if (!valid_vcpu(irq->vcpu))
 		return -EINVAL;
 	if (irq->irq < 0 || irq->irq >= 256)
 		return -EINVAL;
@@ -1559,7 +1583,7 @@
 	struct kvm_vcpu *vcpu;
 	int r;
 
-	if (dbg->vcpu < 0 || dbg->vcpu >= KVM_MAX_VCPUS)
+	if (!valid_vcpu(dbg->vcpu))
 		return -EINVAL;
 	vcpu = vcpu_load(kvm, dbg->vcpu);
 	if (!vcpu)
@@ -1579,6 +1603,9 @@
 	int r = -EINVAL;
 
 	switch (ioctl) {
+	case KVM_GET_API_VERSION:
+		r = KVM_API_VERSION;
+		break;
 	case KVM_CREATE_VCPU: {
 		r = kvm_dev_ioctl_create_vcpu(kvm, arg);
 		if (r)
@@ -1730,15 +1757,15 @@
 		if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list))
 			goto out;
 		n = msr_list.nmsrs;
-		msr_list.nmsrs = ARRAY_SIZE(msrs_to_save);
+		msr_list.nmsrs = num_msrs_to_save;
 		if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list))
 			goto out;
 		r = -E2BIG;
-		if (n < ARRAY_SIZE(msrs_to_save))
+		if (n < num_msrs_to_save)
 			goto out;
 		r = -EFAULT;
 		if (copy_to_user(user_msr_list->indices, &msrs_to_save,
-				 sizeof msrs_to_save))
+				 num_msrs_to_save * sizeof(u32)))
 			goto out;
 		r = 0;
 	}
@@ -1889,6 +1916,8 @@
 
 	kvm_init_debug();
 
+	kvm_init_msr_list();
+
 	if ((bad_page = alloc_page(GFP_KERNEL)) == NULL) {
 		r = -ENOMEM;
 		goto out;
diff -ru 2.2/drivers/kvm/mmu.c 3.4/drivers/kvm/mmu.c
--- 2.2/drivers/kvm/mmu.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/kvm/mmu.c	2006-12-23 01:11:19.000000000 +0100
@@ -647,14 +647,20 @@
 	ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa));
 	ASSERT(list_empty(&vcpu->free_pages));
 
-	if ((r = alloc_mmu_pages(vcpu)))
-		return r;
+	r = alloc_mmu_pages(vcpu);
+	if (r)
+		goto out;
+
+	r = init_kvm_mmu(vcpu);
+	if (r)
+		goto out_free_pages;
 
-	if ((r = init_kvm_mmu(vcpu))) {
-		free_mmu_pages(vcpu);
-		return r;
-	}
 	return 0;
+
+out_free_pages:
+	free_mmu_pages(vcpu);
+out:
+	return r;
 }
 
 void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
diff -ru 2.2/drivers/kvm/svm.c 3.4/drivers/kvm/svm.c
--- 2.2/drivers/kvm/svm.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/kvm/svm.c	2006-12-23 01:11:19.000000000 +0100
@@ -402,11 +402,11 @@
 	set_msr_interception(msrpm_va, MSR_GS_BASE, 1, 1);
 	set_msr_interception(msrpm_va, MSR_FS_BASE, 1, 1);
 	set_msr_interception(msrpm_va, MSR_KERNEL_GS_BASE, 1, 1);
-	set_msr_interception(msrpm_va, MSR_STAR, 1, 1);
 	set_msr_interception(msrpm_va, MSR_LSTAR, 1, 1);
 	set_msr_interception(msrpm_va, MSR_CSTAR, 1, 1);
 	set_msr_interception(msrpm_va, MSR_SYSCALL_MASK, 1, 1);
 #endif
+	set_msr_interception(msrpm_va, MSR_K6_STAR, 1, 1);
 	set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_CS, 1, 1);
 	set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_ESP, 1, 1);
 	set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_EIP, 1, 1);
@@ -575,6 +575,8 @@
 	memset(vcpu->svm->db_regs, 0, sizeof(vcpu->svm->db_regs));
 	init_vmcb(vcpu->svm->vmcb);
 
+	fx_init(vcpu);
+
 	return 0;
 
 out2:
@@ -1071,6 +1073,8 @@
 static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
 {
 	switch (ecx) {
+	case MSR_IA32_P5_MC_ADDR:
+	case MSR_IA32_P5_MC_TYPE:
 	case MSR_IA32_MC0_CTL:
 	case MSR_IA32_MCG_STATUS:
 	case MSR_IA32_MCG_CAP:
@@ -1098,10 +1102,10 @@
 	case MSR_IA32_APICBASE:
 		*data = vcpu->apic_base;
 		break;
-#ifdef CONFIG_X86_64
-	case MSR_STAR:
+	case MSR_K6_STAR:
 		*data = vcpu->svm->vmcb->save.star;
 		break;
+#ifdef CONFIG_X86_64
 	case MSR_LSTAR:
 		*data = vcpu->svm->vmcb->save.lstar;
 		break;
@@ -1173,10 +1177,10 @@
 	case MSR_IA32_APICBASE:
 		vcpu->apic_base = data;
 		break;
-#ifdef CONFIG_X86_64_
-	case MSR_STAR:
+	case MSR_K6_STAR:
 		vcpu->svm->vmcb->save.star = data;
 		break;
+#ifdef CONFIG_X86_64_
 	case MSR_LSTAR:
 		vcpu->svm->vmcb->save.lstar = data;
 		break;
@@ -1387,6 +1391,10 @@
 		save_db_regs(vcpu->svm->host_db_regs);
 		load_db_regs(vcpu->svm->db_regs);
 	}
+
+	fx_save(vcpu->host_fx_image);
+	fx_restore(vcpu->guest_fx_image);
+
 	asm volatile (
 #ifdef CONFIG_X86_64
 		"push %%rbx; push %%rcx; push %%rdx;"
@@ -1496,6 +1504,9 @@
 #endif
 		: "cc", "memory" );
 
+	fx_save(vcpu->guest_fx_image);
+	fx_restore(vcpu->host_fx_image);
+
 	if ((vcpu->svm->vmcb->save.dr7 & 0xff))
 		load_db_regs(vcpu->svm->host_db_regs);
 
diff -ru 2.2/drivers/kvm/vmx.c 3.4/drivers/kvm/vmx.c
--- 2.2/drivers/kvm/vmx.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/kvm/vmx.c	2006-12-23 01:11:19.000000000 +0100
@@ -359,6 +359,8 @@
 	case MSR_IA32_SYSENTER_ESP:
 		data = vmcs_read32(GUEST_SYSENTER_ESP);
 		break;
+	case MSR_IA32_P5_MC_ADDR:
+	case MSR_IA32_P5_MC_TYPE:
 	case MSR_IA32_MC0_CTL:
 	case MSR_IA32_MCG_STATUS:
 	case MSR_IA32_MCG_CAP:
@@ -726,6 +728,7 @@
 	vmcs_write32(GUEST_SS_AR_BYTES, 0xf3);
 
 	vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
+	vmcs_write32(GUEST_CS_LIMIT, 0xffff);
 	vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
 
 	fix_rmode_seg(VCPU_SREG_ES, &vcpu->rmode.es);
diff -ru 2.2/drivers/macintosh/via-pmu-backlight.c 3.4/drivers/macintosh/via-pmu-backlight.c
--- 2.2/drivers/macintosh/via-pmu-backlight.c	2006-10-02 17:39:13.000000000 +0200
+++ 3.4/drivers/macintosh/via-pmu-backlight.c	2006-12-24 17:41:43.000000000 +0100
@@ -147,7 +147,7 @@
 
 	snprintf(name, sizeof(name), "pmubl");
 
-	bd = backlight_device_register(name, NULL, &pmu_backlight_data);
+	bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data);
 	if (IS_ERR(bd)) {
 		printk("pmubl: Backlight registration failed\n");
 		goto error;
diff -ru 2.2/drivers/md/md.c 3.4/drivers/md/md.c
--- 2.2/drivers/md/md.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/drivers/md/md.c	2006-12-23 01:11:19.000000000 +0100
@@ -1792,7 +1792,8 @@
 		else {
 			mddev_t *mddev = rdev->mddev;
 			kick_rdev_from_array(rdev);
-			md_update_sb(mddev, 1);
+			if (mddev->pers)
+				md_update_sb(mddev, 1);
 			md_new_event(mddev);
 			err = 0;
 		}
@@ -2004,6 +2005,7 @@
 
 	rdev->desc_nr = -1;
 	rdev->saved_raid_disk = -1;
+	rdev->raid_disk = -1;
 	rdev->flags = 0;
 	rdev->data_offset = 0;
 	rdev->sb_events = 0;
@@ -2233,7 +2235,6 @@
 static ssize_t
 raid_disks_store(mddev_t *mddev, const char *buf, size_t len)
 {
-	/* can only set raid_disks if array is not yet active */
 	char *e;
 	int rv = 0;
 	unsigned long n = simple_strtoul(buf, &e, 10);
@@ -2631,7 +2632,7 @@
 		return -EINVAL;
 	buf = e+1;
 	minor = simple_strtoul(buf, &e, 10);
-	if (e==buf || *e != '\n')
+	if (e==buf || (*e && *e != '\n') )
 		return -EINVAL;
 	if (major >= sizeof(super_types)/sizeof(super_types[0]) ||
 	    super_types[major].name == NULL)
@@ -3980,6 +3981,7 @@
 		mddev->major_version = info->major_version;
 		mddev->minor_version = info->minor_version;
 		mddev->patch_version = info->patch_version;
+		mddev->persistent = !info->not_persistent;
 		return 0;
 	}
 	mddev->major_version = MD_MAJOR_VERSION;
@@ -4304,9 +4306,10 @@
 	 * Commands querying/configuring an existing array:
 	 */
 	/* if we are not initialised yet, only ADD_NEW_DISK, STOP_ARRAY,
-	 * RUN_ARRAY, and SET_BITMAP_FILE are allowed */
+	 * RUN_ARRAY, and GET_ and SET_BITMAP_FILE are allowed */
 	if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY
-			&& cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE) {
+			&& cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE
+	    		&& cmd != GET_BITMAP_FILE) {
 		err = -ENODEV;
 		goto abort_unlock;
 	}
diff -ru 2.2/drivers/message/i2o/exec-osm.c 3.4/drivers/message/i2o/exec-osm.c
--- 2.2/drivers/message/i2o/exec-osm.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/message/i2o/exec-osm.c	2006-12-23 01:11:19.000000000 +0100
@@ -367,7 +367,7 @@
 
 /**
  *	i2o_exec_lct_modified - Called on LCT NOTIFY reply
- *	@work: work struct for a specific controller
+ *	@_work: work struct for a specific controller
  *
  *	This function handles asynchronus LCT NOTIFY replies. It parses the
  *	new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
diff -ru 2.2/drivers/misc/msi-laptop.c 3.4/drivers/misc/msi-laptop.c
--- 2.2/drivers/misc/msi-laptop.c	2006-10-16 02:24:40.000000000 +0200
+++ 3.4/drivers/misc/msi-laptop.c	2006-12-23 16:57:57.000000000 +0100
@@ -317,7 +317,8 @@
 
 	/* Register backlight stuff */
 
-	msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props);
+	msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL,
+						&msibl_props);
 	if (IS_ERR(msibl_device))
 		return PTR_ERR(msibl_device);
 
diff -ru 2.2/drivers/net/bnx2.c 3.4/drivers/net/bnx2.c
--- 2.2/drivers/net/bnx2.c	2006-12-10 05:32:05.000000000 +0100
+++ 3.4/drivers/net/bnx2.c	2006-12-22 01:57:07.000000000 +0100
@@ -57,8 +57,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.5.1"
-#define DRV_MODULE_RELDATE	"November 15, 2006"
+#define DRV_MODULE_VERSION	"1.5.2"
+#define DRV_MODULE_RELDATE	"December 13, 2006"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -217,9 +217,16 @@
 	u32 diff;
 
 	smp_mb();
-	diff = TX_RING_IDX(bp->tx_prod) - TX_RING_IDX(bp->tx_cons);
-	if (diff > MAX_TX_DESC_CNT)
-		diff = (diff & MAX_TX_DESC_CNT) - 1;
+
+	/* The ring uses 256 indices for 255 entries, one of them
+	 * needs to be skipped.
+	 */
+	diff = bp->tx_prod - bp->tx_cons;
+	if (unlikely(diff >= TX_DESC_CNT)) {
+		diff &= 0xffff;
+		if (diff == TX_DESC_CNT)
+			diff = MAX_TX_DESC_CNT;
+	}
 	return (bp->tx_ring_size - diff);
 }
 
@@ -3089,7 +3096,7 @@
 
 	if ((align_start = (offset32 & 3))) {
 		offset32 &= ~3;
-		len32 += align_start;
+		len32 += (4 - align_start);
 		if ((rc = bnx2_nvram_read(bp, offset32, start, 4)))
 			return rc;
 	}
@@ -3107,7 +3114,7 @@
 
 	if (align_start || align_end) {
 		buf = kmalloc(len32, GFP_KERNEL);
-		if (buf == 0)
+		if (buf == NULL)
 			return -ENOMEM;
 		if (align_start) {
 			memcpy(buf, start, 4);
@@ -3998,7 +4005,7 @@
 	if (!skb)
 		return -ENOMEM;
 	packet = skb_put(skb, pkt_size);
-	memcpy(packet, bp->mac_addr, 6);
+	memcpy(packet, bp->dev->dev_addr, 6);
 	memset(packet + 6, 0x0, 8);
 	for (i = 14; i < pkt_size; i++)
 		packet[i] = (unsigned char) (i & 0xff);
diff -ru 2.2/drivers/net/iseries_veth.c 3.4/drivers/net/iseries_veth.c
--- 2.2/drivers/net/iseries_veth.c	2006-12-07 02:52:10.000000000 +0100
+++ 3.4/drivers/net/iseries_veth.c	2006-12-22 01:57:07.000000000 +0100
@@ -73,7 +73,7 @@
 #include <asm/abs_addr.h>
 #include <asm/iseries/mf.h>
 #include <asm/uaccess.h>
-
+#include <asm/firmware.h>
 #include <asm/iseries/hv_lp_config.h>
 #include <asm/iseries/hv_types.h>
 #include <asm/iseries/hv_lp_event.h>
@@ -1668,7 +1668,7 @@
  * Module initialization/cleanup
  */
 
-void __exit veth_module_cleanup(void)
+static void __exit veth_module_cleanup(void)
 {
 	int i;
 	struct veth_lpar_connection *cnx;
@@ -1697,11 +1697,14 @@
 }
 module_exit(veth_module_cleanup);
 
-int __init veth_module_init(void)
+static int __init veth_module_init(void)
 {
 	int i;
 	int rc;
 
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -ENODEV;
+
 	this_lp = HvLpConfig_getLpIndex_outline();
 
 	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
diff -ru 2.2/drivers/net/smc911x.c 3.4/drivers/net/smc911x.c
--- 2.2/drivers/net/smc911x.c	2006-10-09 14:51:59.000000000 +0200
+++ 3.4/drivers/net/smc911x.c	2006-12-23 01:11:19.000000000 +0100
@@ -148,6 +148,8 @@
 	int tx_throttle;
 	spinlock_t lock;
 
+	struct net_device *netdev;
+
 #ifdef SMC_USE_DMA
 	/* DMA needs the physical address of the chip */
 	u_long physaddr;
@@ -948,10 +950,11 @@
  * of autonegotiation.)  If the RPC ANEG bit is cleared, the selection
  * is controlled by the RPC SPEED and RPC DPLX bits.
  */
-static void smc911x_phy_configure(void *data)
+static void smc911x_phy_configure(struct work_struct *work)
 {
-	struct net_device *dev = data;
-	struct smc911x_local *lp = netdev_priv(dev);
+	struct smc911x_local *lp = container_of(work, struct smc911x_local,
+						phy_configure);
+	struct net_device *dev = lp->netdev;
 	unsigned long ioaddr = dev->base_addr;
 	int phyaddr = lp->mii.phy_id;
 	int my_phy_caps; /* My PHY capabilities */
@@ -1331,7 +1334,7 @@
 static void smc911x_poll_controller(struct net_device *dev)
 {
 	disable_irq(dev->irq);
-	smc911x_interrupt(dev->irq, dev, NULL);
+	smc911x_interrupt(dev->irq, dev);
 	enable_irq(dev->irq);
 }
 #endif
@@ -1495,6 +1498,8 @@
 static int
 smc911x_open(struct net_device *dev)
 {
+	struct smc911x_local *lp = netdev_priv(dev);
+
 	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
 
 	/*
@@ -1511,7 +1516,7 @@
 	smc911x_reset(dev);
 
 	/* Configure the PHY, initialize the link state */
-	smc911x_phy_configure(dev);
+	smc911x_phy_configure(&lp->phy_configure);
 
 	/* Turn on Tx + Rx */
 	smc911x_enable(dev);
@@ -2060,7 +2065,7 @@
 	dev->poll_controller = smc911x_poll_controller;
 #endif
 
-	INIT_WORK(&lp->phy_configure, smc911x_phy_configure, dev);
+	INIT_WORK(&lp->phy_configure, smc911x_phy_configure);
 	lp->mii.phy_id_mask = 0x1f;
 	lp->mii.reg_num_mask = 0x1f;
 	lp->mii.force_media = 0;
@@ -2154,6 +2159,7 @@
 {
 	struct net_device *ndev;
 	struct resource *res;
+	struct smc911x_local *lp;
 	unsigned int *addr;
 	int ret;
 
@@ -2183,6 +2189,8 @@
 
 	ndev->dma = (unsigned char)-1;
 	ndev->irq = platform_get_irq(pdev, 0);
+	lp = netdev_priv(ndev);
+	lp->netdev = ndev;
 
 	addr = ioremap(res->start, SMC911X_IO_EXTENT);
 	if (!addr) {
@@ -2204,7 +2212,6 @@
 	}
 #ifdef SMC_USE_DMA
 	else {
-		struct smc911x_local *lp = netdev_priv(ndev);
 		lp->physaddr = res->start;
 		lp->dev = &pdev->dev;
 	}
@@ -2275,7 +2282,7 @@
 			smc911x_reset(ndev);
 			smc911x_enable(ndev);
 			if (lp->phy_type != 0)
-				smc911x_phy_configure(ndev);
+				smc911x_phy_configure(&lp->phy_configure);
 			netif_device_attach(ndev);
 		}
 	}
diff -ru 2.2/drivers/net/tg3.c 3.4/drivers/net/tg3.c
--- 2.2/drivers/net/tg3.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/net/tg3.c	2006-12-22 01:57:07.000000000 +0100
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.70"
-#define DRV_MODULE_RELDATE	"December 1, 2006"
+#define DRV_MODULE_VERSION	"3.71"
+#define DRV_MODULE_RELDATE	"December 15, 2006"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -959,6 +959,13 @@
 	u32 phy_status;
 	int err;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+		u32 val;
+
+		val = tr32(GRC_MISC_CFG);
+		tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ);
+		udelay(40);
+	}
 	err  = tg3_readphy(tp, MII_BMSR, &phy_status);
 	err |= tg3_readphy(tp, MII_BMSR, &phy_status);
 	if (err != 0)
@@ -1170,7 +1177,15 @@
 	if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
 		return;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+		u32 val;
+
+		tg3_bmcr_reset(tp);
+		val = tr32(GRC_MISC_CFG);
+		tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
+		udelay(40);
+		return;
+	} else {
 		tg3_writephy(tp, MII_TG3_EXT_CTRL,
 			     MII_TG3_EXT_CTRL_FORCE_LED_OFF);
 		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
@@ -4426,7 +4441,7 @@
  */
 static int tg3_alloc_consistent(struct tg3 *tp)
 {
-	tp->rx_std_buffers = kmalloc((sizeof(struct ring_info) *
+	tp->rx_std_buffers = kzalloc((sizeof(struct ring_info) *
 				      (TG3_RX_RING_SIZE +
 				       TG3_RX_JUMBO_RING_SIZE)) +
 				     (sizeof(struct tx_ring_info) *
@@ -4435,13 +4450,6 @@
 	if (!tp->rx_std_buffers)
 		return -ENOMEM;
 
-	memset(tp->rx_std_buffers, 0,
-	       (sizeof(struct ring_info) *
-		(TG3_RX_RING_SIZE +
-		 TG3_RX_JUMBO_RING_SIZE)) +
-	       (sizeof(struct tx_ring_info) *
-		TG3_TX_RING_SIZE));
-
 	tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE];
 	tp->tx_buffers = (struct tx_ring_info *)
 		&tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE];
@@ -6988,6 +6996,8 @@
 	struct tg3 *tp = netdev_priv(dev);
 	int err;
 
+	netif_carrier_off(tp->dev);
+
 	tg3_full_lock(tp, 0);
 
 	err = tg3_set_power_state(tp, PCI_D0);
@@ -7981,6 +7991,10 @@
 		tp->link_config.duplex = cmd->duplex;
   	}
 
+	tp->link_config.orig_speed = tp->link_config.speed;
+	tp->link_config.orig_duplex = tp->link_config.duplex;
+	tp->link_config.orig_autoneg = tp->link_config.autoneg;
+
 	if (netif_running(dev))
 		tg3_setup_phy(tp, 1);
 
@@ -11923,6 +11937,8 @@
 	 */
 	pci_save_state(tp->pdev);
 
+	pci_set_drvdata(pdev, dev);
+
 	err = register_netdev(dev);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot register net device, "
@@ -11930,8 +11946,6 @@
 		goto err_out_iounmap;
 	}
 
-	pci_set_drvdata(pdev, dev);
-
 	printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ",
 	       dev->name,
 	       tp->board_part_number,
@@ -11962,8 +11976,6 @@
 	       (pdev->dma_mask == DMA_32BIT_MASK) ? 32 :
 	        (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64));
 
-	netif_carrier_off(tp->dev);
-
 	return 0;
 
 err_out_iounmap:
diff -ru 2.2/drivers/net/tg3.h 3.4/drivers/net/tg3.h
--- 2.2/drivers/net/tg3.h	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/net/tg3.h	2006-12-22 01:57:07.000000000 +0100
@@ -1350,6 +1350,7 @@
 #define  GRC_MISC_CFG_BOARD_ID_5788	0x00010000
 #define  GRC_MISC_CFG_BOARD_ID_5788M	0x00018000
 #define  GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
+#define  GRC_MISC_CFG_EPHY_IDDQ		0x00200000
 #define  GRC_MISC_CFG_KEEP_GPHY_POWER	0x04000000
 #define GRC_LOCAL_CTRL			0x00006808
 #define  GRC_LCLCTRL_INT_ACTIVE		0x00000001
diff -ru 2.2/drivers/pci/hotplug/acpiphp_glue.c 3.4/drivers/pci/hotplug/acpiphp_glue.c
--- 2.2/drivers/pci/hotplug/acpiphp_glue.c	2006-12-07 02:52:12.000000000 +0100
+++ 3.4/drivers/pci/hotplug/acpiphp_glue.c	2006-12-22 01:57:07.000000000 +0100
@@ -1682,7 +1682,7 @@
  *
  * This function frees all data allocated in acpiphp_glue_init()
  */
-void __exit acpiphp_glue_exit(void)
+void  acpiphp_glue_exit(void)
 {
 	acpi_pci_unregister_driver(&acpi_pci_hp_driver);
 }
diff -ru 2.2/drivers/pci/hotplug/acpiphp_ibm.c 3.4/drivers/pci/hotplug/acpiphp_ibm.c
--- 2.2/drivers/pci/hotplug/acpiphp_ibm.c	2006-10-19 07:38:22.000000000 +0200
+++ 3.4/drivers/pci/hotplug/acpiphp_ibm.c	2006-12-23 16:57:57.000000000 +0100
@@ -319,13 +319,12 @@
 	if (bufp == NULL)
 		goto read_table_done;
 
-	lbuf = kmalloc(size, GFP_KERNEL);
+	lbuf = kzalloc(size, GFP_KERNEL);
 	dbg("%s: element count: %i, ASL table size: %i, &table = 0x%p\n",
 			__FUNCTION__, package->package.count, size, lbuf);
 
 	if (lbuf) {
 		*bufp = lbuf;
-		memset(lbuf, 0, size);
 	} else {
 		size = -ENOMEM;
 		goto read_table_done;
diff -ru 2.2/drivers/pci/hotplug/rpaphp_slot.c 3.4/drivers/pci/hotplug/rpaphp_slot.c
--- 2.2/drivers/pci/hotplug/rpaphp_slot.c	2006-10-02 17:39:15.000000000 +0200
+++ 3.4/drivers/pci/hotplug/rpaphp_slot.c	2006-12-22 01:57:07.000000000 +0100
@@ -47,21 +47,11 @@
 	return retval;
 }
 
-static struct hotplug_slot_attribute hotplug_slot_attr_location = {
+static struct hotplug_slot_attribute php_attr_location = {
 	.attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO},
 	.show = location_read_file,
 };
 
-static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot)
-{
-	sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr);
-}
-
-static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot)
-{
-	sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr);
-}
-
 /* free up the memory used by a slot */
 static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
 {
@@ -145,7 +135,7 @@
 	list_del(&slot->rpaphp_slot_list);
 	
 	/* remove "phy_location" file */
-	rpaphp_sysfs_remove_attr_location(php_slot);
+	sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr);
 
 	retval = pci_hp_deregister(php_slot);
 	if (retval)
@@ -160,36 +150,45 @@
 
 int rpaphp_register_slot(struct slot *slot)
 {
+	struct hotplug_slot *php_slot = slot->hotplug_slot;
 	int retval;
 
 	dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", 
 		__FUNCTION__, slot->dn->full_name, slot->index, slot->name, 
 		slot->power_domain, slot->type);
+
 	/* should not try to register the same slot twice */
-	if (is_registered(slot)) { /* should't be here */
+	if (is_registered(slot)) {
 		err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name);
-		rpaphp_release_slot(slot->hotplug_slot);
-		return -EAGAIN;
+		retval = -EAGAIN;
+		goto register_fail;
 	}	
-	retval = pci_hp_register(slot->hotplug_slot);
+
+	retval = pci_hp_register(php_slot);
 	if (retval) {
 		err("pci_hp_register failed with error %d\n", retval);
-		rpaphp_release_slot(slot->hotplug_slot);
-		return retval;
+		goto register_fail;
 	}
-	
-	/* create "phy_locatoin" file */
-	rpaphp_sysfs_add_attr_location(slot->hotplug_slot);	
 
-	/* add slot to our internal list */
-	dbg("%s adding slot[%s] to rpaphp_slot_list\n",
-	    __FUNCTION__, slot->name);
+	/* create "phy_location" file */
+	retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr);
+	if (retval) {
+		err("sysfs_create_file failed with error %d\n", retval);
+		goto sysfs_fail;
+	}
 
+	/* add slot to our internal list */
 	list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
 	info("Slot [%s](PCI location=%s) registered\n", slot->name,
 			slot->location);
 	num_slots++;
 	return 0;
+
+sysfs_fail:
+	pci_hp_deregister(php_slot);
+register_fail:
+	rpaphp_release_slot(php_slot);
+	return retval;
 }
 
 int rpaphp_get_power_status(struct slot *slot, u8 * value)
diff -ru 2.2/drivers/pci/hotplug/shpchp_core.c 3.4/drivers/pci/hotplug/shpchp_core.c
--- 2.2/drivers/pci/hotplug/shpchp_core.c	2006-12-07 02:52:13.000000000 +0100
+++ 3.4/drivers/pci/hotplug/shpchp_core.c	2006-12-22 01:57:07.000000000 +0100
@@ -104,23 +104,6 @@
 		 slot->bus, slot->number);
 }
 
-
-
-
-static int
-shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun,
-				u8 busnum, u8 devnum)
-{
-	int offset = devnum - ctrl->slot_device_offset;
-
-	dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__,
-			ctrl->slot_num_inc, offset);
-	*sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
-	return 0;
-}
-
-
-
 static int init_slots(struct controller *ctrl)
 {
 	struct slot *slot;
@@ -128,7 +111,6 @@
 	struct hotplug_slot_info *info;
 	int retval = -ENOMEM;
 	int i;
-	u32 sun;
 
 	for (i = 0; i < ctrl->num_slots; i++) {
 		slot = kzalloc(sizeof(*slot), GFP_KERNEL);
@@ -149,16 +131,11 @@
 
 		slot->hp_slot = i;
 		slot->ctrl = ctrl;
-		slot->bus = ctrl->slot_bus;
+		slot->bus = ctrl->pci_dev->subordinate->number;
 		slot->device = ctrl->slot_device_offset + i;
 		slot->hpc_ops = ctrl->hpc_ops;
+		slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i);
 		mutex_init(&slot->lock);
-
-		if (shpchprm_get_physical_slot_number(ctrl, &sun,
-						      slot->bus, slot->device))
-			goto error_info;
-
-		slot->number = sun;
 		INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work);
 
 		/* register this slot with the hotplug pci core */
@@ -211,42 +188,12 @@
 	}
 }
 
-static int get_ctlr_slot_config(struct controller *ctrl)
-{
-	int num_ctlr_slots;
-	int first_device_num;
-	int physical_slot_num;
-	int updown;
-	int rc;
-	int flags;
-
-	rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots,
-				       &first_device_num, &physical_slot_num,
-				       &updown, &flags);
-	if (rc) {
-		err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n",
-		    __FUNCTION__, ctrl->bus, ctrl->device);
-		return -1;
-	}
-
-	ctrl->num_slots = num_ctlr_slots;
-	ctrl->slot_device_offset = first_device_num;
-	ctrl->first_slot = physical_slot_num;
-	ctrl->slot_num_inc = updown;		/* either -1 or 1 */
-
-	dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d "
-	    "(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num,
-	    physical_slot_num, updown, ctrl->bus, ctrl->device);
-
-	return 0;
-}
-
 /*
  * set_attention_status - Turns the Amber LED for a slot on, off or blink
  */
 static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
@@ -258,7 +205,7 @@
 
 static int enable_slot (struct hotplug_slot *hotplug_slot)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
@@ -267,7 +214,7 @@
 
 static int disable_slot (struct hotplug_slot *hotplug_slot)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
@@ -276,7 +223,7 @@
 
 static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 	int retval;
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -290,7 +237,7 @@
 
 static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 	int retval;
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -304,7 +251,7 @@
 
 static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 	int retval;
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -318,7 +265,7 @@
 
 static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 	int retval;
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -332,7 +279,7 @@
 
 static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 	struct pci_bus *bus = slot->ctrl->pci_dev->subordinate;
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -344,7 +291,7 @@
 
 static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 	int retval;
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -358,7 +305,7 @@
 
 static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	struct slot *slot = get_slot(hotplug_slot);
 	int retval;
 
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -385,9 +332,6 @@
 {
 	int rc;
 	struct controller *ctrl;
-	struct slot *t_slot;
-	int first_device_num;	/* first PCI device number */
-	int num_ctlr_slots;	/* number of slots implemented */
 
 	if (!is_shpc_capable(pdev))
 		return -ENODEV;
@@ -408,47 +352,13 @@
 
 	pci_set_drvdata(pdev, ctrl);
 
-	ctrl->bus = pdev->bus->number;
-	ctrl->slot_bus = pdev->subordinate->number;
-	ctrl->device = PCI_SLOT(pdev->devfn);
-	ctrl->function = PCI_FUNC(pdev->devfn);
-
-	dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n",
-	    ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
-
-	/*
-	 * Save configuration headers for this and subordinate PCI buses
-	 */
-	rc = get_ctlr_slot_config(ctrl);
-	if (rc) {
-		err(msg_initialization_err, rc);
-		goto err_out_release_ctlr;
-	}
-	first_device_num = ctrl->slot_device_offset;
-	num_ctlr_slots = ctrl->num_slots;
-
-	ctrl->add_support = 1;
-
 	/* Setup the slot information structures */
 	rc = init_slots(ctrl);
 	if (rc) {
-		err(msg_initialization_err, 6);
+		err("%s: slot initialization failed\n", SHPC_MODULE_NAME);
 		goto err_out_release_ctlr;
 	}
 
-	/* Now hpc_functions (slot->hpc_ops->functions) are ready  */
-	t_slot = shpchp_find_slot(ctrl, first_device_num);
-
-	/* Check for operation bus speed */
-	rc = t_slot->hpc_ops->get_cur_bus_speed(t_slot, &ctrl->speed);
-	dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot);
-
-	if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) {
-		err(SHPC_MODULE_NAME ": Can't get current bus speed. "
-		    "Set to 33MHz PCI.\n");
-		ctrl->speed = PCI_SPEED_33MHz;
-	}
-
 	rc = shpchp_create_ctrl_files(ctrl);
 	if (rc)
 		goto err_cleanup_slots;
diff -ru 2.2/drivers/pci/hotplug/shpchp_ctrl.c 3.4/drivers/pci/hotplug/shpchp_ctrl.c
--- 2.2/drivers/pci/hotplug/shpchp_ctrl.c	2006-12-07 02:52:13.000000000 +0100
+++ 3.4/drivers/pci/hotplug/shpchp_ctrl.c	2006-12-22 01:57:07.000000000 +0100
@@ -57,9 +57,8 @@
 	return 0;
 }
 
-u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
 {
-	struct controller *ctrl = (struct controller *) inst_id;
 	struct slot *p_slot;
 	u32 event_type;
 
@@ -81,9 +80,8 @@
 
 }
 
-u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
 {
-	struct controller *ctrl = (struct controller *) inst_id;
 	struct slot *p_slot;
 	u8 getstatus;
 	u32 event_type;
@@ -120,9 +118,8 @@
 	return 1;
 }
 
-u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
 {
-	struct controller *ctrl = (struct controller *) inst_id;
 	struct slot *p_slot;
 	u32 event_type;
 
@@ -154,9 +151,8 @@
 	return 1;
 }
 
-u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
 {
-	struct controller *ctrl = (struct controller *) inst_id;
 	struct slot *p_slot;
 	u32 event_type;
 
@@ -497,10 +493,12 @@
 		p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
 		if (getstatus) {
 			p_slot->state = BLINKINGOFF_STATE;
-			info(msg_button_off, p_slot->name);
+			info("PCI slot #%s - powering off due to button "
+			     "press.\n", p_slot->name);
 		} else {
 			p_slot->state = BLINKINGON_STATE;
-			info(msg_button_on, p_slot->name);
+			info("PCI slot #%s - powering on due to button "
+			     "press.\n", p_slot->name);
 		}
 		/* blink green LED and turn off amber */
 		p_slot->hpc_ops->green_led_blink(p_slot);
@@ -523,7 +521,8 @@
 		else
 			p_slot->hpc_ops->green_led_off(p_slot);
 		p_slot->hpc_ops->set_attention_status(p_slot, 0);
-		info(msg_button_cancel, p_slot->name);
+		info("PCI slot #%s - action canceled due to button press\n",
+		     p_slot->name);
 		p_slot->state = STATIC_STATE;
 		break;
 	case POWEROFF_STATE:
diff -ru 2.2/drivers/pci/hotplug/shpchp.h 3.4/drivers/pci/hotplug/shpchp.h
--- 2.2/drivers/pci/hotplug/shpchp.h	2006-12-07 02:52:13.000000000 +0100
+++ 3.4/drivers/pci/hotplug/shpchp.h	2006-12-22 01:57:07.000000000 +0100
@@ -47,11 +47,17 @@
 extern int shpchp_debug;
 extern struct workqueue_struct *shpchp_wq;
 
-/*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
-#define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+#define dbg(format, arg...)						\
+	do {								\
+		if (shpchp_debug)					\
+			printk("%s: " format, MY_NAME , ## arg);	\
+	} while (0)
+#define err(format, arg...)						\
+	printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
+#define info(format, arg...)						\
+	printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+#define warn(format, arg...)						\
+	printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
 #define SLOT_NAME_SIZE 10
 struct slot {
@@ -83,34 +89,27 @@
 struct controller {
 	struct mutex crit_sect;		/* critical section mutex */
 	struct mutex cmd_lock;		/* command lock */
-	struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
 	int num_slots;			/* Number of slots on ctlr */
 	int slot_num_inc;		/* 1 or -1 */
 	struct pci_dev *pci_dev;
 	struct list_head slot_list;
 	struct hpc_ops *hpc_ops;
 	wait_queue_head_t queue;	/* sleep & wake process */
-	u8 bus;
-	u8 device;
-	u8 function;
 	u8 slot_device_offset;
-	u8 add_support;
 	u32 pcix_misc2_reg;	/* for amd pogo errata */
-	enum pci_bus_speed speed;
 	u32 first_slot;		/* First physical slot number */
-	u8 slot_bus;		/* Bus where the slots handled by this controller sit */
 	u32 cap_offset;
 	unsigned long mmio_base;
 	unsigned long mmio_size;
+	void __iomem *creg;
+	struct timer_list poll_timer;
 };
 
-
 /* Define AMD SHPC ID  */
 #define PCI_DEVICE_ID_AMD_GOLAM_7450	0x7450 
 #define PCI_DEVICE_ID_AMD_POGO_7458	0x7458
 
 /* AMD PCIX bridge registers */
-
 #define PCIX_MEM_BASE_LIMIT_OFFSET	0x1C
 #define PCIX_MISCII_OFFSET		0x48
 #define PCIX_MISC_BRIDGE_ERRORS_OFFSET	0x80
@@ -145,8 +144,6 @@
 #define POWERON_STATE			3
 #define POWEROFF_STATE			4
 
-#define PCI_TO_PCI_BRIDGE_CLASS		0x00060400
-
 /* Error messages */
 #define INTERLOCK_OPEN			0x00000002
 #define ADD_NOT_SUPPORTED		0x00000003
@@ -158,50 +155,32 @@
 #define WRONG_BUS_FREQUENCY		0x0000000D
 #define POWER_FAILURE			0x0000000E
 
-#define REMOVE_NOT_SUPPORTED		0x00000003
-
-#define DISABLE_CARD			1
-
-/*
- * error Messages
- */
-#define msg_initialization_err	"Initialization failure, error=%d\n"
-#define msg_button_on		"PCI slot #%s - powering on due to button press.\n"
-#define msg_button_off		"PCI slot #%s - powering off due to button press.\n"
-#define msg_button_cancel	"PCI slot #%s - action canceled due to button press.\n"
-
-/* sysfs functions for the hotplug controller info */
 extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl);
-
-extern int	shpchp_sysfs_enable_slot(struct slot *slot);
-extern int	shpchp_sysfs_disable_slot(struct slot *slot);
-
-extern u8	shpchp_handle_attention_button(u8 hp_slot, void *inst_id);
-extern u8	shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
-extern u8	shpchp_handle_presence_change(u8 hp_slot, void *inst_id);
-extern u8	shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
-
-/* pci functions */
-extern int	shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
-extern int	shpchp_configure_device(struct slot *p_slot);
-extern int	shpchp_unconfigure_device(struct slot *p_slot);
-extern void	shpchp_remove_ctrl_files(struct controller *ctrl);
-extern void	cleanup_slots(struct controller *ctrl);
-extern void	queue_pushbutton_work(struct work_struct *work);
-
+extern void shpchp_remove_ctrl_files(struct controller *ctrl);
+extern int shpchp_sysfs_enable_slot(struct slot *slot);
+extern int shpchp_sysfs_disable_slot(struct slot *slot);
+extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl);
+extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl);
+extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl);
+extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl);
+extern int shpchp_configure_device(struct slot *p_slot);
+extern int shpchp_unconfigure_device(struct slot *p_slot);
+extern void cleanup_slots(struct controller *ctrl);
+extern void queue_pushbutton_work(struct work_struct *work);
+extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
 
 #ifdef CONFIG_ACPI
 static inline int get_hp_params_from_firmware(struct pci_dev *dev,
-			struct hotplug_params *hpp)
+					      struct hotplug_params *hpp)
 {
 	if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
 			return -ENODEV;
 	return 0;
 }
-#define get_hp_hw_control_from_firmware(pdev) \
-	do { \
-		if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \
-			acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \
+#define get_hp_hw_control_from_firmware(pdev)				\
+	do {								\
+		if (DEVICE_ACPI_HANDLE(&(pdev->dev)))			\
+			acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev)));\
 	} while (0)
 #else
 #define get_hp_params_from_firmware(dev, hpp) (-ENODEV)
@@ -222,108 +201,40 @@
 	volatile u32 serr_loc;
 	volatile u32 serr_intr_enable;
 	volatile u32 slot1;
-	volatile u32 slot2;
-	volatile u32 slot3;
-	volatile u32 slot4;
-	volatile u32 slot5;
-	volatile u32 slot6;
-	volatile u32 slot7;
-	volatile u32 slot8;
-	volatile u32 slot9;
-	volatile u32 slot10;
-	volatile u32 slot11;
-	volatile u32 slot12;
 } __attribute__ ((packed));
 
 /* offsets to the controller registers based on the above structure layout */
 enum ctrl_offsets {
-	BASE_OFFSET =	offsetof(struct ctrl_reg, base_offset),
-	SLOT_AVAIL1 =	offsetof(struct ctrl_reg, slot_avail1),
-	SLOT_AVAIL2	=	offsetof(struct ctrl_reg, slot_avail2),
-	SLOT_CONFIG =	offsetof(struct ctrl_reg, slot_config),
-	SEC_BUS_CONFIG =	offsetof(struct ctrl_reg, sec_bus_config),
-	MSI_CTRL	=	offsetof(struct ctrl_reg, msi_ctrl),
-	PROG_INTERFACE =	offsetof(struct ctrl_reg, prog_interface),
-	CMD		=	offsetof(struct ctrl_reg, cmd),
-	CMD_STATUS	=	offsetof(struct ctrl_reg, cmd_status),
-	INTR_LOC	= 	offsetof(struct ctrl_reg, intr_loc),
-	SERR_LOC	= 	offsetof(struct ctrl_reg, serr_loc),
-	SERR_INTR_ENABLE =	offsetof(struct ctrl_reg, serr_intr_enable),
-	SLOT1 =		offsetof(struct ctrl_reg, slot1),
-	SLOT2 =		offsetof(struct ctrl_reg, slot2),
-	SLOT3 =		offsetof(struct ctrl_reg, slot3),
-	SLOT4 =		offsetof(struct ctrl_reg, slot4),
-	SLOT5 =		offsetof(struct ctrl_reg, slot5),
-	SLOT6 =		offsetof(struct ctrl_reg, slot6),		
-	SLOT7 =		offsetof(struct ctrl_reg, slot7),
-	SLOT8 =		offsetof(struct ctrl_reg, slot8),
-	SLOT9 =		offsetof(struct ctrl_reg, slot9),
-	SLOT10 =	offsetof(struct ctrl_reg, slot10),
-	SLOT11 =	offsetof(struct ctrl_reg, slot11),
-	SLOT12 =	offsetof(struct ctrl_reg, slot12),
+	BASE_OFFSET 	 = offsetof(struct ctrl_reg, base_offset),
+	SLOT_AVAIL1 	 = offsetof(struct ctrl_reg, slot_avail1),
+	SLOT_AVAIL2	 = offsetof(struct ctrl_reg, slot_avail2),
+	SLOT_CONFIG 	 = offsetof(struct ctrl_reg, slot_config),
+	SEC_BUS_CONFIG	 = offsetof(struct ctrl_reg, sec_bus_config),
+	MSI_CTRL	 = offsetof(struct ctrl_reg, msi_ctrl),
+	PROG_INTERFACE 	 = offsetof(struct ctrl_reg, prog_interface),
+	CMD		 = offsetof(struct ctrl_reg, cmd),
+	CMD_STATUS	 = offsetof(struct ctrl_reg, cmd_status),
+	INTR_LOC	 = offsetof(struct ctrl_reg, intr_loc),
+	SERR_LOC	 = offsetof(struct ctrl_reg, serr_loc),
+	SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable),
+	SLOT1		 = offsetof(struct ctrl_reg, slot1),
 };
-typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
-struct php_ctlr_state_s {
-	struct php_ctlr_state_s *pnext;
-	struct pci_dev *pci_dev;
-	unsigned int irq;
-	unsigned long flags;	/* spinlock's */
-	u32 slot_device_offset;
-	u32 num_slots;
-    	struct timer_list	int_poll_timer;	/* Added for poll event */
-	php_intr_callback_t attention_button_callback;
-	php_intr_callback_t switch_change_callback;
-	php_intr_callback_t presence_change_callback;
-	php_intr_callback_t power_fault_callback;
-	void *callback_instance_id;
-	void __iomem *creg;			/* Ptr to controller register space */
-};
-/* Inline functions */
 
-
-/* Inline functions to check the sanity of a pointer that is passed to us */
-static inline int slot_paranoia_check (struct slot *slot, const char *function)
-{
-	if (!slot) {
-		dbg("%s - slot == NULL", function);
-		return -1;
-	}
-	if (!slot->hotplug_slot) {
-		dbg("%s - slot->hotplug_slot == NULL!", function);
-		return -1;
-	}
-	return 0;
-}
-
-static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
+static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot)
 { 
-	struct slot *slot;
-
-	if (!hotplug_slot) {
-		dbg("%s - hotplug_slot == NULL\n", function);
-		return NULL;
-	}
-
-	slot = (struct slot *)hotplug_slot->private;
-	if (slot_paranoia_check (slot, function))
-                return NULL;
-	return slot;
+	return hotplug_slot->private;
 }
 
-static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
+static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device)
 {
 	struct slot *slot;
 
-	if (!ctrl)
-		return NULL;
-
 	list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
 		if (slot->device == device)
 			return slot;
 	}
 
 	err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device);
-
 	return NULL;
 }
 
@@ -400,44 +311,27 @@
 	pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp);
 }
 
-enum php_ctlr_type {
-	PCI,
-	ISA,
-	ACPI
-};
-
-int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
-
-int shpc_get_ctlr_slot_config( struct controller *ctrl,
-		int *num_ctlr_slots,
-		int *first_device_num,
-		int *physical_slot_num,
-		int *updown,
-		int *flags);
-
 struct hpc_ops {
-	int	(*power_on_slot )		(struct slot *slot);
-	int	(*slot_enable )			(struct slot *slot);
-	int	(*slot_disable )		(struct slot *slot);
-	int	(*set_bus_speed_mode)	(struct slot *slot, enum pci_bus_speed speed);
-	int	(*get_power_status)		(struct slot *slot, u8 *status);
-	int	(*get_attention_status)	(struct slot *slot, u8 *status);
-	int	(*set_attention_status)	(struct slot *slot, u8 status);
-	int	(*get_latch_status)		(struct slot *slot, u8 *status);
-	int	(*get_adapter_status)	(struct slot *slot, u8 *status);
-
-	int	(*get_max_bus_speed)	(struct slot *slot, enum pci_bus_speed *speed);
-	int	(*get_cur_bus_speed)	(struct slot *slot, enum pci_bus_speed *speed);
-	int	(*get_adapter_speed)	(struct slot *slot, enum pci_bus_speed *speed);
-	int	(*get_mode1_ECC_cap)	(struct slot *slot, u8 *mode);
-	int	(*get_prog_int)			(struct slot *slot, u8 *prog_int);
-
-	int	(*query_power_fault)	(struct slot *slot);
-	void	(*green_led_on)		(struct slot *slot);
-	void	(*green_led_off)	(struct slot *slot);
-	void	(*green_led_blink)	(struct slot *slot);
-	void	(*release_ctlr)		(struct controller *ctrl);
-	int (*check_cmd_status)		(struct controller *ctrl);
+	int (*power_on_slot)(struct slot *slot);
+	int (*slot_enable)(struct slot *slot);
+	int (*slot_disable)(struct slot *slot);
+	int (*set_bus_speed_mode)(struct slot *slot, enum pci_bus_speed speed);
+	int (*get_power_status)(struct slot *slot, u8 *status);
+	int (*get_attention_status)(struct slot *slot, u8 *status);
+	int (*set_attention_status)(struct slot *slot, u8 status);
+	int (*get_latch_status)(struct slot *slot, u8 *status);
+	int (*get_adapter_status)(struct slot *slot, u8 *status);
+	int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
+	int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
+	int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed);
+	int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode);
+	int (*get_prog_int)(struct slot *slot, u8 *prog_int);
+	int (*query_power_fault)(struct slot *slot);
+	void (*green_led_on)(struct slot *slot);
+	void (*green_led_off)(struct slot *slot);
+	void (*green_led_blink)(struct slot *slot);
+	void (*release_ctlr)(struct controller *ctrl);
+	int (*check_cmd_status)(struct controller *ctrl);
 };
 
 #endif				/* _SHPCHP_H */
diff -ru 2.2/drivers/pci/hotplug/shpchp_hpc.c 3.4/drivers/pci/hotplug/shpchp_hpc.c
--- 2.2/drivers/pci/hotplug/shpchp_hpc.c	2006-10-19 07:38:22.000000000 +0200
+++ 3.4/drivers/pci/hotplug/shpchp_hpc.c	2006-12-22 01:57:07.000000000 +0100
@@ -212,44 +212,40 @@
 #define SLOT_SERR_INT_MASK	0x3
 
 DEFINE_DBG_BUFFER		/* Debug string buffer for entire HPC defined here */
-static struct php_ctlr_state_s *php_ctlr_list_head;	/* HPC state linked list */
-static int ctlr_seq_num = 0;	/* Controller sequenc # */
-static spinlock_t list_lock;
-
 static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
 
 static irqreturn_t shpc_isr(int irq, void *dev_id);
-static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec);
+static void start_int_poll_timer(struct controller *ctrl, int sec);
 static int hpc_check_cmd_status(struct controller *ctrl);
 
 static inline u8 shpc_readb(struct controller *ctrl, int reg)
 {
-	return readb(ctrl->hpc_ctlr_handle->creg + reg);
+	return readb(ctrl->creg + reg);
 }
 
 static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val)
 {
-	writeb(val, ctrl->hpc_ctlr_handle->creg + reg);
+	writeb(val, ctrl->creg + reg);
 }
 
 static inline u16 shpc_readw(struct controller *ctrl, int reg)
 {
-	return readw(ctrl->hpc_ctlr_handle->creg + reg);
+	return readw(ctrl->creg + reg);
 }
 
 static inline void shpc_writew(struct controller *ctrl, int reg, u16 val)
 {
-	writew(val, ctrl->hpc_ctlr_handle->creg + reg);
+	writew(val, ctrl->creg + reg);
 }
 
 static inline u32 shpc_readl(struct controller *ctrl, int reg)
 {
-	return readl(ctrl->hpc_ctlr_handle->creg + reg);
+	return readl(ctrl->creg + reg);
 }
 
 static inline void shpc_writel(struct controller *ctrl, int reg, u32 val)
 {
-	writel(val, ctrl->hpc_ctlr_handle->creg + reg);
+	writel(val, ctrl->creg + reg);
 }
 
 static inline int shpc_indirect_read(struct controller *ctrl, int index,
@@ -268,21 +264,20 @@
 /*
  * This is the interrupt polling timeout function.
  */
-static void int_poll_timeout(unsigned long lphp_ctlr)
+static void int_poll_timeout(unsigned long data)
 {
-	struct php_ctlr_state_s *php_ctlr =
-		(struct php_ctlr_state_s *)lphp_ctlr;
+	struct controller *ctrl = (struct controller *)data;
 
 	DBG_ENTER_ROUTINE
 
 	/* Poll for interrupt events.  regs == NULL => polling */
-	shpc_isr(0, php_ctlr->callback_instance_id);
+	shpc_isr(0, ctrl);
 
-	init_timer(&php_ctlr->int_poll_timer);
+	init_timer(&ctrl->poll_timer);
 	if (!shpchp_poll_time)
 		shpchp_poll_time = 2; /* default polling interval is 2 sec */
 
-	start_int_poll_timer(php_ctlr, shpchp_poll_time);
+	start_int_poll_timer(ctrl, shpchp_poll_time);
 
 	DBG_LEAVE_ROUTINE
 }
@@ -290,16 +285,16 @@
 /*
  * This function starts the interrupt polling timer.
  */
-static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec)
+static void start_int_poll_timer(struct controller *ctrl, int sec)
 {
 	/* Clamp to sane value */
 	if ((sec <= 0) || (sec > 60))
 		sec = 2;
 
-	php_ctlr->int_poll_timer.function = &int_poll_timeout;
-	php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr;
-	php_ctlr->int_poll_timer.expires = jiffies + sec * HZ;
-	add_timer(&php_ctlr->int_poll_timer);
+	ctrl->poll_timer.function = &int_poll_timeout;
+	ctrl->poll_timer.data = (unsigned long)ctrl;
+	ctrl->poll_timer.expires = jiffies + sec * HZ;
+	add_timer(&ctrl->poll_timer);
 }
 
 static inline int is_ctrl_busy(struct controller *ctrl)
@@ -666,33 +661,8 @@
 	shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK);
 }
 
-int shpc_get_ctlr_slot_config(struct controller *ctrl,
-	int *num_ctlr_slots,	/* number of slots in this HPC			*/
-	int *first_device_num,	/* PCI dev num of the first slot in this SHPC	*/
-	int *physical_slot_num,	/* phy slot num of the first slot in this SHPC	*/
-	int *updown,		/* physical_slot_num increament: 1 or -1	*/
-	int *flags)
-{
-	u32 slot_config;
-
-	DBG_ENTER_ROUTINE 
-
-	slot_config = shpc_readl(ctrl, SLOT_CONFIG);
-	*first_device_num = (slot_config & FIRST_DEV_NUM) >> 8;
-	*num_ctlr_slots = slot_config & SLOT_NUM;
-	*physical_slot_num = (slot_config & PSN) >> 16;
-	*updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
-
-	dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num);
-
-	DBG_LEAVE_ROUTINE 
-	return 0;
-}
-
 static void hpc_release_ctlr(struct controller *ctrl)
 {
-	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
-	struct php_ctlr_state_s *p, *p_prev;
 	int i;
 	u32 slot_reg, serr_int;
 
@@ -722,40 +692,15 @@
 	serr_int &= ~SERR_INTR_RSVDZ_MASK;
 	shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
 
-	if (shpchp_poll_mode) {
-	    del_timer(&php_ctlr->int_poll_timer);
-	} else {	
-		if (php_ctlr->irq) {
-			free_irq(php_ctlr->irq, ctrl);
-			php_ctlr->irq = 0;
-			pci_disable_msi(php_ctlr->pci_dev);
-		}
-	}
-
-	if (php_ctlr->pci_dev) {
-		iounmap(php_ctlr->creg);
-		release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
-		php_ctlr->pci_dev = NULL;
-	}
-
-	spin_lock(&list_lock);
-	p = php_ctlr_list_head;
-	p_prev = NULL;
-	while (p) {
-		if (p == php_ctlr) {
-			if (p_prev)
-				p_prev->pnext = p->pnext;
-			else
-				php_ctlr_list_head = p->pnext;
-			break;
-		} else {
-			p_prev = p;
-			p = p->pnext;
-		}
+	if (shpchp_poll_mode)
+		del_timer(&ctrl->poll_timer);
+	else {
+		free_irq(ctrl->pci_dev->irq, ctrl);
+		pci_disable_msi(ctrl->pci_dev);
 	}
-	spin_unlock(&list_lock);
 
-	kfree(php_ctlr);
+	iounmap(ctrl->creg);
+	release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
 
 	/*
 	 * If this is the last controller to be released, destroy the
@@ -764,8 +709,7 @@
 	if (atomic_dec_and_test(&shpchp_num_controllers))
 		destroy_workqueue(shpchp_wq);
 
-DBG_LEAVE_ROUTINE
-			  
+	DBG_LEAVE_ROUTINE
 }
 
 static int hpc_power_on_slot(struct slot * slot)
@@ -891,7 +835,6 @@
 static irqreturn_t shpc_isr(int irq, void *dev_id)
 {
 	struct controller *ctrl = (struct controller *)dev_id;
-	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
 	u32 serr_int, slot_reg, intr_loc, intr_loc2;
 	int hp_slot;
 
@@ -942,20 +885,16 @@
 		    __FUNCTION__, hp_slot, slot_reg);
 
 		if (slot_reg & MRL_CHANGE_DETECTED)
-			php_ctlr->switch_change_callback(
-				hp_slot, php_ctlr->callback_instance_id);
+			shpchp_handle_switch_change(hp_slot, ctrl);
 
 		if (slot_reg & BUTTON_PRESS_DETECTED)
-			php_ctlr->attention_button_callback(
-				hp_slot, php_ctlr->callback_instance_id);
+			shpchp_handle_attention_button(hp_slot, ctrl);
 
 		if (slot_reg & PRSNT_CHANGE_DETECTED)
-			php_ctlr->presence_change_callback(
-				hp_slot , php_ctlr->callback_instance_id);
+			shpchp_handle_presence_change(hp_slot, ctrl);
 
 		if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED))
-			php_ctlr->power_fault_callback(
-				hp_slot, php_ctlr->callback_instance_id);
+			shpchp_handle_power_fault(hp_slot, ctrl);
 
 		/* Clear all slot events */
 		slot_reg &= ~SLOT_REG_RSVDZ_MASK;
@@ -1114,10 +1053,8 @@
 	.release_ctlr			= hpc_release_ctlr,
 };
 
-int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
+int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
 {
-	struct php_ctlr_state_s *php_ctlr, *p;
-	void *instance_id = ctrl;
 	int rc = -1, num_slots = 0;
 	u8 hp_slot;
 	u32 shpc_base_offset;
@@ -1128,16 +1065,6 @@
 
 	ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */
 
-	spin_lock_init(&list_lock);
-	php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL);
-
-	if (!php_ctlr) {	/* allocate controller state data */
-		err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
-		goto abort;
-	}
-
-	php_ctlr->pci_dev = pdev;	/* save pci_dev in context */
-
 	if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
 				PCI_DEVICE_ID_AMD_GOLAM_7450)) {
 		/* amd shpc driver doesn't use Base Offset; assume 0 */
@@ -1147,20 +1074,20 @@
 		ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC);
 		if (!ctrl->cap_offset) {
 			err("%s : cap_offset == 0\n", __FUNCTION__);
-			goto abort_free_ctlr;
+			goto abort;
 		}
 		dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset);
 
 		rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset);
 		if (rc) {
 			err("%s: cannot read base_offset\n", __FUNCTION__);
-			goto abort_free_ctlr;
+			goto abort;
 		}
 
 		rc = shpc_indirect_read(ctrl, 3, &tempdword);
 		if (rc) {
 			err("%s: cannot read slot config\n", __FUNCTION__);
-			goto abort_free_ctlr;
+			goto abort;
 		}
 		num_slots = tempdword & SLOT_NUM;
 		dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots);
@@ -1170,7 +1097,7 @@
 			if (rc) {
 				err("%s: cannot read creg (index = %d)\n",
 				    __FUNCTION__, i);
-				goto abort_free_ctlr;
+				goto abort;
 			}
 			dbg("%s: offset %d: value %x\n", __FUNCTION__,i,
 					tempdword);
@@ -1187,24 +1114,24 @@
 	rc = pci_enable_device(pdev);
 	if (rc) {
 		err("%s: pci_enable_device failed\n", __FUNCTION__);
-		goto abort_free_ctlr;
+		goto abort;
 	}
 
 	if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {
 		err("%s: cannot reserve MMIO region\n", __FUNCTION__);
 		rc = -1;
-		goto abort_free_ctlr;
+		goto abort;
 	}
 
-	php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
-	if (!php_ctlr->creg) {
+	ctrl->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
+	if (!ctrl->creg) {
 		err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__,
 		    ctrl->mmio_size, ctrl->mmio_base);
 		release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
 		rc = -1;
-		goto abort_free_ctlr;
+		goto abort;
 	}
-	dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
+	dbg("%s: ctrl->creg %p\n", __FUNCTION__, ctrl->creg);
 
 	mutex_init(&ctrl->crit_sect);
 	mutex_init(&ctrl->cmd_lock);
@@ -1212,23 +1139,14 @@
 	/* Setup wait queue */
 	init_waitqueue_head(&ctrl->queue);
 
-	/* Find the IRQ */
-	php_ctlr->irq = pdev->irq;
-	php_ctlr->attention_button_callback = shpchp_handle_attention_button,
-	php_ctlr->switch_change_callback = shpchp_handle_switch_change;
-	php_ctlr->presence_change_callback = shpchp_handle_presence_change;
-	php_ctlr->power_fault_callback = shpchp_handle_power_fault;
-	php_ctlr->callback_instance_id = instance_id;
-
-	ctrl->hpc_ctlr_handle = php_ctlr;
 	ctrl->hpc_ops = &shpchp_hpc_ops;
 
 	/* Return PCI Controller Info */
 	slot_config = shpc_readl(ctrl, SLOT_CONFIG);
-	php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
-	php_ctlr->num_slots = slot_config & SLOT_NUM;
-	dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset);
-	dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots);
+	ctrl->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
+	ctrl->num_slots = slot_config & SLOT_NUM;
+	ctrl->first_slot = (slot_config & PSN) >> 16;
+	ctrl->slot_num_inc = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
 
 	/* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
 	tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
@@ -1243,7 +1161,7 @@
 	/* Mask the MRL sensor SERR Mask of individual slot in
 	 * Slot SERR-INT Mask & clear all the existing event if any
 	 */
-	for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
+	for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
 		slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
 		dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
 			hp_slot, slot_reg);
@@ -1255,24 +1173,27 @@
 		shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
 	}
 	
-	if (shpchp_poll_mode)  {/* Install interrupt polling code */
-		/* Install and start the interrupt polling timer */
-		init_timer(&php_ctlr->int_poll_timer);
-		start_int_poll_timer( php_ctlr, 10 );   /* start with 10 second delay */
+	if (shpchp_poll_mode) {
+		/* Install interrupt polling timer. Start with 10 sec delay */
+		init_timer(&ctrl->poll_timer);
+		start_int_poll_timer(ctrl, 10);
 	} else {
 		/* Installs the interrupt handler */
 		rc = pci_enable_msi(pdev);
 		if (rc) {
 			info("Can't get msi for the hotplug controller\n");
 			info("Use INTx for the hotplug controller\n");
-		} else
-			php_ctlr->irq = pdev->irq;
+		}
 		
-		rc = request_irq(php_ctlr->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *) ctrl);
-		dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
+		rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED,
+				 MY_NAME, (void *)ctrl);
+		dbg("%s: request_irq %d for hpc%d (returns %d)\n",
+		    __FUNCTION__, ctrl->pci_dev->irq,
+		    atomic_read(&shpchp_num_controllers), rc);
 		if (rc) {
-			err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
-			goto abort_free_ctlr;
+			err("Can't get irq %d for the hotplug controller\n",
+			    ctrl->pci_dev->irq);
+			goto abort_iounmap;
 		}
 	}
 	dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__,
@@ -1280,24 +1201,6 @@
 			PCI_FUNC(pdev->devfn), pdev->irq);
 	get_hp_hw_control_from_firmware(pdev);
 
-	/*  Add this HPC instance into the HPC list */
-	spin_lock(&list_lock);
-	if (php_ctlr_list_head == 0) {
-		php_ctlr_list_head = php_ctlr;
-		p = php_ctlr_list_head;
-		p->pnext = NULL;
-	} else {
-		p = php_ctlr_list_head;
-
-		while (p->pnext)
-			p = p->pnext;
-
-		p->pnext = php_ctlr;
-	}
-	spin_unlock(&list_lock);
-
-	ctlr_seq_num++;
-
 	/*
 	 * If this is the first controller to be initialized,
 	 * initialize the shpchpd work queue
@@ -1306,14 +1209,14 @@
 		shpchp_wq = create_singlethread_workqueue("shpchpd");
 		if (!shpchp_wq) {
 			rc = -ENOMEM;
-			goto abort_free_ctlr;
+			goto abort_iounmap;
 		}
 	}
 
 	/*
 	 * Unmask all event interrupts of all slots
 	 */
-	for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
+	for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
 		slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
 		dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
 			hp_slot, slot_reg);
@@ -1336,10 +1239,8 @@
 	return 0;
 
 	/* We end up here for the many possible ways to fail this API.  */
-abort_free_ctlr:
-	if (php_ctlr->creg)
-		iounmap(php_ctlr->creg);
-	kfree(php_ctlr);
+abort_iounmap:
+	iounmap(ctrl->creg);
 abort:
 	DBG_LEAVE_ROUTINE
 	return rc;
diff -ru 2.2/drivers/pci/htirq.c 3.4/drivers/pci/htirq.c
--- 2.2/drivers/pci/htirq.c	2006-11-09 19:26:57.000000000 +0100
+++ 3.4/drivers/pci/htirq.c	2006-12-22 01:57:07.000000000 +0100
@@ -99,14 +99,7 @@
 	int pos;
 	int irq;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_HT);
-	while (pos) {
-		u8 subtype;
-		pci_read_config_byte(dev, pos + 3, &subtype);
-		if (subtype == HT_CAPTYPE_IRQ)
-			break;
-		pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT);
-	}
+	pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
 	if (!pos)
 		return -EINVAL;
 
diff -ru 2.2/drivers/pci/pci.c 3.4/drivers/pci/pci.c
--- 2.2/drivers/pci/pci.c	2006-12-07 02:52:13.000000000 +0100
+++ 3.4/drivers/pci/pci.c	2006-12-22 01:57:07.000000000 +0100
@@ -68,12 +68,14 @@
 
 #endif  /*  0  */
 
-static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)
+#define PCI_FIND_CAP_TTL	48
+
+static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
+				   u8 pos, int cap, int *ttl)
 {
 	u8 id;
-	int ttl = 48;
 
-	while (ttl--) {
+	while ((*ttl)--) {
 		pci_bus_read_config_byte(bus, devfn, pos, &pos);
 		if (pos < 0x40)
 			break;
@@ -89,6 +91,14 @@
 	return 0;
 }
 
+static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
+			       u8 pos, int cap)
+{
+	int ttl = PCI_FIND_CAP_TTL;
+
+	return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
+}
+
 int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
 {
 	return __pci_find_next_cap(dev->bus, dev->devfn,
@@ -96,10 +106,10 @@
 }
 EXPORT_SYMBOL_GPL(pci_find_next_capability);
 
-static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
+static int __pci_bus_find_cap_start(struct pci_bus *bus,
+				    unsigned int devfn, u8 hdr_type)
 {
 	u16 status;
-	u8 pos;
 
 	pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
 	if (!(status & PCI_STATUS_CAP_LIST))
@@ -108,15 +118,14 @@
 	switch (hdr_type) {
 	case PCI_HEADER_TYPE_NORMAL:
 	case PCI_HEADER_TYPE_BRIDGE:
-		pos = PCI_CAPABILITY_LIST;
-		break;
+		return PCI_CAPABILITY_LIST;
 	case PCI_HEADER_TYPE_CARDBUS:
-		pos = PCI_CB_CAPABILITY_LIST;
-		break;
+		return PCI_CB_CAPABILITY_LIST;
 	default:
 		return 0;
 	}
-	return __pci_find_next_cap(bus, devfn, pos, cap);
+
+	return 0;
 }
 
 /**
@@ -140,7 +149,13 @@
  */
 int pci_find_capability(struct pci_dev *dev, int cap)
 {
-	return __pci_bus_find_cap(dev->bus, dev->devfn, dev->hdr_type, cap);
+	int pos;
+
+	pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
+	if (pos)
+		pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
+
+	return pos;
 }
 
 /**
@@ -158,11 +173,16 @@
  */
 int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
 {
+	int pos;
 	u8 hdr_type;
 
 	pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
 
-	return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap);
+	pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f);
+	if (pos)
+		pos = __pci_find_next_cap(bus, devfn, pos, cap);
+
+	return pos;
 }
 
 /**
@@ -214,6 +234,74 @@
 }
 EXPORT_SYMBOL_GPL(pci_find_ext_capability);
 
+static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
+{
+	int rc, ttl = PCI_FIND_CAP_TTL;
+	u8 cap, mask;
+
+	if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST)
+		mask = HT_3BIT_CAP_MASK;
+	else
+		mask = HT_5BIT_CAP_MASK;
+
+	pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
+				      PCI_CAP_ID_HT, &ttl);
+	while (pos) {
+		rc = pci_read_config_byte(dev, pos + 3, &cap);
+		if (rc != PCIBIOS_SUCCESSFUL)
+			return 0;
+
+		if ((cap & mask) == ht_cap)
+			return pos;
+
+		pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
+					      PCI_CAP_ID_HT, &ttl);
+	}
+
+	return 0;
+}
+/**
+ * pci_find_next_ht_capability - query a device's Hypertransport capabilities
+ * @dev: PCI device to query
+ * @pos: Position from which to continue searching
+ * @ht_cap: Hypertransport capability code
+ *
+ * To be used in conjunction with pci_find_ht_capability() to search for
+ * all capabilities matching @ht_cap. @pos should always be a value returned
+ * from pci_find_ht_capability().
+ *
+ * NB. To be 100% safe against broken PCI devices, the caller should take
+ * steps to avoid an infinite loop.
+ */
+int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap)
+{
+	return __pci_find_next_ht_cap(dev, pos + PCI_CAP_LIST_NEXT, ht_cap);
+}
+EXPORT_SYMBOL_GPL(pci_find_next_ht_capability);
+
+/**
+ * pci_find_ht_capability - query a device's Hypertransport capabilities
+ * @dev: PCI device to query
+ * @ht_cap: Hypertransport capability code
+ *
+ * Tell if a device supports a given Hypertransport capability.
+ * Returns an address within the device's PCI configuration space
+ * or 0 in case the device does not support the request capability.
+ * The address points to the PCI capability, of type PCI_CAP_ID_HT,
+ * which has a Hypertransport capability matching @ht_cap.
+ */
+int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
+{
+	int pos;
+
+	pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
+	if (pos)
+		pos = __pci_find_next_ht_cap(dev, pos, ht_cap);
+
+	return pos;
+}
+EXPORT_SYMBOL_GPL(pci_find_ht_capability);
+
 /**
  * pci_find_parent_resource - return resource region of parent bus of given region
  * @dev: PCI device structure contains resources to be searched
diff -ru 2.2/drivers/pci/pci-driver.c 3.4/drivers/pci/pci-driver.c
--- 2.2/drivers/pci/pci-driver.c	2006-12-07 02:52:13.000000000 +0100
+++ 3.4/drivers/pci/pci-driver.c	2006-12-22 01:57:07.000000000 +0100
@@ -162,14 +162,9 @@
 const struct pci_device_id *pci_match_device(struct pci_driver *drv,
 					     struct pci_dev *dev)
 {
-	const struct pci_device_id *id;
 	struct pci_dynid *dynid;
 
-	id = pci_match_id(drv->id_table, dev);
-	if (id)
-		return id;
-
-	/* static ids didn't match, lets look at the dynamic ones */
+	/* Look at the dynamic ids first, before the static ones */
 	spin_lock(&drv->dynids.lock);
 	list_for_each_entry(dynid, &drv->dynids.list, node) {
 		if (pci_match_one_device(&dynid->id, dev)) {
@@ -178,7 +173,8 @@
 		}
 	}
 	spin_unlock(&drv->dynids.lock);
-	return NULL;
+
+	return pci_match_id(drv->id_table, dev);
 }
 
 static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
@@ -357,6 +353,8 @@
 	struct pci_dev * pci_dev = to_pci_dev(dev);
 	struct pci_driver * drv = pci_dev->driver;
 
+	pci_fixup_device(pci_fixup_resume, pci_dev);
+
 	if (drv && drv->resume_early)
 		error = drv->resume_early(pci_dev);
 	return error;
diff -ru 2.2/drivers/pci/pcie/portdrv_pci.c 3.4/drivers/pci/pcie/portdrv_pci.c
--- 2.2/drivers/pci/pcie/portdrv_pci.c	2006-10-19 07:38:22.000000000 +0200
+++ 3.4/drivers/pci/pcie/portdrv_pci.c	2006-12-22 01:57:07.000000000 +0100
@@ -90,7 +90,7 @@
 		return -ENODEV;
 	
 	pci_set_master(dev);
-        if (!dev->irq) {
+        if (!dev->irq && dev->pin) {
 		printk(KERN_WARNING 
 		"%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", 
 		__FUNCTION__, dev->device, dev->vendor);
diff -ru 2.2/drivers/pci/probe.c 3.4/drivers/pci/probe.c
--- 2.2/drivers/pci/probe.c	2006-12-08 19:31:48.000000000 +0100
+++ 3.4/drivers/pci/probe.c	2006-12-22 01:57:07.000000000 +0100
@@ -649,6 +649,9 @@
  * Returns 0 on success and -1 if unknown type of device (not normal, bridge
  * or CardBus).
  */
+
+#define LEGACY_IO_RESOURCE	(IORESOURCE_IO | IORESOURCE_PCI_FIXED)
+
 static int pci_setup_device(struct pci_dev * dev)
 {
 	u32 class;
@@ -692,18 +695,18 @@
 			if ((progif & 1) == 0) {
 				dev->resource[0].start = 0x1F0;
 				dev->resource[0].end = 0x1F7;
-				dev->resource[0].flags = IORESOURCE_IO;
+				dev->resource[0].flags = LEGACY_IO_RESOURCE;
 				dev->resource[1].start = 0x3F6;
 				dev->resource[1].end = 0x3F6;
-				dev->resource[1].flags = IORESOURCE_IO;
+				dev->resource[1].flags = LEGACY_IO_RESOURCE;
 			}
 			if ((progif & 4) == 0) {
 				dev->resource[2].start = 0x170;
 				dev->resource[2].end = 0x177;
-				dev->resource[2].flags = IORESOURCE_IO;
+				dev->resource[2].flags = LEGACY_IO_RESOURCE;
 				dev->resource[3].start = 0x376;
 				dev->resource[3].end = 0x376;
-				dev->resource[3].flags = IORESOURCE_IO;
+				dev->resource[3].flags = LEGACY_IO_RESOURCE;
 			}
 		}
 		break;
diff -ru 2.2/drivers/pci/quirks.c 3.4/drivers/pci/quirks.c
--- 2.2/drivers/pci/quirks.c	2006-12-07 02:52:13.000000000 +0100
+++ 3.4/drivers/pci/quirks.c	2006-12-22 01:57:07.000000000 +0100
@@ -36,7 +36,7 @@
 
 /* Deal with broken BIOS'es that neglect to enable passive release,
    which can cause problems in combination with the 82441FX/PPro MTRRs */
-static void __devinit quirk_passive_release(struct pci_dev *dev)
+static void quirk_passive_release(struct pci_dev *dev)
 {
 	struct pci_dev *d = NULL;
 	unsigned char dlc;
@@ -53,6 +53,7 @@
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82441,	quirk_passive_release );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82441,	quirk_passive_release );
 
 /*  The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround
     but VIA don't answer queries. If you happen to have good contacts at VIA
@@ -134,7 +135,7 @@
  *	Updated based on further information from the site and also on
  *	information provided by VIA 
  */
-static void __devinit quirk_vialatency(struct pci_dev *dev)
+static void quirk_vialatency(struct pci_dev *dev)
 {
 	struct pci_dev *p;
 	u8 rev;
@@ -185,6 +186,10 @@
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8363_0,	quirk_vialatency );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8371_1,	quirk_vialatency );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8361,		quirk_vialatency );
+/* Must restore this on a resume from RAM */
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8363_0,	quirk_vialatency );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8371_1,	quirk_vialatency );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8361,		quirk_vialatency );
 
 /*
  *	VIA Apollo VP3 needs ETBF on BT848/878
@@ -532,7 +537,7 @@
  * TODO: When we have device-specific interrupt routers,
  * this code will go away from quirks.
  */
-static void __devinit quirk_via_ioapic(struct pci_dev *dev)
+static void quirk_via_ioapic(struct pci_dev *dev)
 {
 	u8 tmp;
 	
@@ -548,6 +553,7 @@
 	pci_write_config_byte (dev, 0x58, tmp);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686,	quirk_via_ioapic );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686,	quirk_via_ioapic );
 
 /*
  * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit.
@@ -555,7 +561,7 @@
  * Set this bit to get rid of cycle wastage.
  * Otherwise uncritical.
  */
-static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
+static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
 {
 	u8 misc_control2;
 #define BYPASS_APIC_DEASSERT 8
@@ -567,6 +573,7 @@
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237,		quirk_via_vt8237_bypass_apic_deassert);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237,		quirk_via_vt8237_bypass_apic_deassert);
 
 /*
  * The AMD io apic can hang the box when an apic irq is masked.
@@ -600,7 +607,7 @@
 #define AMD8131_revB0        0x11
 #define AMD8131_MISC         0x40
 #define AMD8131_NIOAMODE_BIT 0
-static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) 
+static void quirk_amd_8131_ioapic(struct pci_dev *dev)
 { 
         unsigned char revid, tmp;
         
@@ -616,6 +623,7 @@
         }
 } 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
 #endif /* CONFIG_X86_IO_APIC */
 
 
@@ -641,65 +649,84 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_via_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_via_acpi );
 
+
 /*
- * Via 686A/B:  The PCI_INTERRUPT_LINE register for the on-chip
- * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
- * when written, it makes an internal connection to the PIC.
- * For these devices, this register is defined to be 4 bits wide.
- * Normally this is fine.  However for IO-APIC motherboards, or
- * non-x86 architectures (yes Via exists on PPC among other places),
- * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
- * interrupts delivered properly.
- *
- * Some of the on-chip devices are actually '586 devices' so they are
- * listed here.
+ *	VIA bridges which have VLink
  */
 
-static int via_irq_fixup_needed = -1;
-
-/*
- * As some VIA hardware is available in PCI-card form, we need to restrict
- * this quirk to VIA PCI hardware built onto VIA-based motherboards only.
- * We try to locate a VIA southbridge before deciding whether the quirk
- * should be applied.
- */
-static const struct pci_device_id via_irq_fixup_tbl[] = {
-	{
-		.vendor 	= PCI_VENDOR_ID_VIA,
-		.device		= PCI_ANY_ID,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.class		= PCI_CLASS_BRIDGE_ISA << 8,
-		.class_mask	= 0xffff00,
-	},
+static const struct pci_device_id via_vlink_fixup_tbl[] = {
+	/* Internal devices need IRQ line routing, pre VLink */
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 },
+	/* Devices with VLink */
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17},
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 },
 	{ 0, },
 };
 
-static void quirk_via_irq(struct pci_dev *dev)
+/**
+ *	quirk_via_vlink		-	VIA VLink IRQ number update
+ *	@dev: PCI device
+ *
+ *	If the device we are dealing with is on a PIC IRQ we need to
+ *	ensure that the IRQ line register which usually is not relevant
+ *	for PCI cards, is actually written so that interrupts get sent
+ *	to the right place
+ */
+
+static void quirk_via_vlink(struct pci_dev *dev)
 {
+	const struct pci_device_id *via_vlink_fixup;
+	static int dev_lo = -1, dev_hi = 18;
 	u8 irq, new_irq;
 
-	if (via_irq_fixup_needed == -1)
-		via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl);
+	/* Check if we have VLink and cache the result */
 
-	if (!via_irq_fixup_needed)
+	/* Checked already - no */
+	if (dev_lo == -2)
 		return;
 
+	/* Not checked - see what bridge we have and find the device
+	   ranges */
+
+	if (dev_lo == -1) {
+		via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl);
+		if (via_vlink_fixup == NULL) {
+			dev_lo = -2;
+			return;
+		}
+		dev_lo = via_vlink_fixup->driver_data;
+		/* 82C686 is special - 0/0 */
+		if (dev_lo == 0)
+			dev_hi = 0;
+	}
 	new_irq = dev->irq;
 
 	/* Don't quirk interrupts outside the legacy IRQ range */
 	if (!new_irq || new_irq > 15)
 		return;
 
+	/* Internal device ? */
+	if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi ||
+		PCI_SLOT(dev->devfn) < dev_lo)
+		return;
+
+	/* This is an internal VLink device on a PIC interrupt. The BIOS
+	   ought to have set this but may not have, so we redo it */
+
 	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
 	if (new_irq != irq) {
-		printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n",
+		printk(KERN_INFO "PCI: VIA VLink IRQ fixup for %s, from %d to %d\n",
 			pci_name(dev), irq, new_irq);
 		udelay(15);	/* unknown if delay really needed */
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
 	}
 }
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_vlink);
 
 /*
  * VIA VT82C598 has its device ID settable and many BIOSes
@@ -720,13 +747,14 @@
  * do this even if the Linux CardBus driver is not loaded, because
  * the Linux i82365 driver does not (and should not) handle CardBus.
  */
-static void __devinit quirk_cardbus_legacy(struct pci_dev *dev)
+static void quirk_cardbus_legacy(struct pci_dev *dev)
 {
 	if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class)
 		return;
 	pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
+DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
 
 /*
  * Following the PCI ordering rules is optional on the AMD762. I'm not
@@ -735,7 +763,7 @@
  * To be fair to AMD, it follows the spec by default, its BIOS people
  * who turn it off!
  */
-static void __devinit quirk_amd_ordering(struct pci_dev *dev)
+static void quirk_amd_ordering(struct pci_dev *dev)
 {
 	u32 pcic;
 	pci_read_config_dword(dev, 0x4C, &pcic);
@@ -749,6 +777,7 @@
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );
 
 /*
  *	DreamWorks provided workaround for Dunord I-3000 problem
@@ -784,7 +813,7 @@
  * datasheets found at http://www.national.com/ds/GX for info on what
  * these bits do.  <christer@weinigel.se>
  */
-static void __init quirk_mediagx_master(struct pci_dev *dev)
+static void quirk_mediagx_master(struct pci_dev *dev)
 {
 	u8 reg;
 	pci_read_config_byte(dev, 0x41, &reg);
@@ -795,13 +824,14 @@
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX,	PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX,	PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );
 
 /*
  *	Ensure C0 rev restreaming is off. This is normally done by
  *	the BIOS but in the odd case it is not the results are corruption
  *	hence the presence of a Linux check
  */
-static void __init quirk_disable_pxb(struct pci_dev *pdev)
+static void quirk_disable_pxb(struct pci_dev *pdev)
 {
 	u16 config;
 	u8 rev;
@@ -817,7 +847,25 @@
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454NX,	quirk_disable_pxb );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454NX,	quirk_disable_pxb );
+
+
+static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
+{
+	/* set sb600 sata to ahci mode */
+	if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+		u8 tmp;
 
+		pci_read_config_byte(pdev, 0x40, &tmp);
+		pci_write_config_byte(pdev, 0x40, tmp|1);
+		pci_write_config_byte(pdev, 0x9, 1);
+		pci_write_config_byte(pdev, 0xa, 6);
+		pci_write_config_byte(pdev, 0x40, tmp);
+
+		pdev->class = 0x010601;
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
 
 /*
  *	Serverworks CSB5 IDE does not fully support native mode
@@ -874,7 +922,7 @@
  * runs everywhere at present we suppress the printk output in most
  * irrelevant cases.
  */
-static void __init k8t_sound_hostbridge(struct pci_dev *dev)
+static void k8t_sound_hostbridge(struct pci_dev *dev)
 {
 	unsigned char val;
 
@@ -893,8 +941,8 @@
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
 
-#ifndef CONFIG_ACPI_SLEEP
 /*
  * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge
  * is not activated. The myth is that Asus said that they do not want the
@@ -906,10 +954,6 @@
  * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it 
  * becomes necessary to do this tweak in two steps -- I've chosen the Host
  * bridge as trigger.
- *
- * Actually, leaving it unhidden and not redoing the quirk over suspend2ram
- * will cause thermal management to break down, and causing machine to
- * overheat.
  */
 static int __initdata asus_hides_smbus;
 
@@ -1019,7 +1063,7 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82855GM_HB,	asus_hides_smbus_hostbridge );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge );
 
-static void __init asus_hides_smbus_lpc(struct pci_dev *dev)
+static void asus_hides_smbus_lpc(struct pci_dev *dev)
 {
 	u16 val;
 	
@@ -1042,8 +1086,14 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801CA_12,	asus_hides_smbus_lpc );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801DB_12,	asus_hides_smbus_lpc );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801EB_0,	asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801DB_0,	asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801BA_0,	asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801CA_0,	asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801CA_12,	asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801DB_12,	asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801EB_0,	asus_hides_smbus_lpc );
 
-static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
 {
 	u32 val, rcba;
 	void __iomem *base;
@@ -1059,13 +1109,12 @@
 	printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n");
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH6_1,	asus_hides_smbus_lpc_ich6 );
-
-#endif
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH6_1,	asus_hides_smbus_lpc_ich6 );
 
 /*
  * SiS 96x south bridge: BIOS typically hides SMBus device...
  */
-static void __init quirk_sis_96x_smbus(struct pci_dev *dev)
+static void quirk_sis_96x_smbus(struct pci_dev *dev)
 {
 	u8 val = 0;
 	printk(KERN_INFO "Enabling SiS 96x SMBus.\n");
@@ -1086,7 +1135,7 @@
 
 #define SIS_DETECT_REGISTER 0x40
 
-static void __init quirk_sis_503(struct pci_dev *dev)
+static void quirk_sis_503(struct pci_dev *dev)
 {
 	u8 reg;
 	u16 devid;
@@ -1122,13 +1171,14 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_735,		quirk_sis_96x_compatible );
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_503,		quirk_sis_503 );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_503,		quirk_sis_503 );
 /*
  * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller
  * and MC97 modem controller are disabled when a second PCI soundcard is
  * present. This patch, tweaking the VT8237 ISA bridge, enables them.
  * -- bjd
  */
-static void __init asus_hides_ac97_lpc(struct pci_dev *dev)
+static void asus_hides_ac97_lpc(struct pci_dev *dev)
 {
 	u8 val;
 	int asus_hides_ac97 = 0;
@@ -1159,6 +1209,14 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_963,		quirk_sis_96x_smbus );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_LPC,		quirk_sis_96x_smbus );
 
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc );
+
+
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_961,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_962,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_963,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_LPC,		quirk_sis_96x_smbus );
+
 #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
 
 /*
@@ -1167,7 +1225,7 @@
  *	the PCI scanning.
  */
 
-static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev)
+static void quirk_jmicron_dualfn(struct pci_dev *pdev)
 {
 	u32 conf;
 	u8 hdr;
@@ -1205,6 +1263,7 @@
 }
 
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
 
 #endif
 
@@ -1532,6 +1591,8 @@
 extern struct pci_fixup __end_pci_fixups_final[];
 extern struct pci_fixup __start_pci_fixups_enable[];
 extern struct pci_fixup __end_pci_fixups_enable[];
+extern struct pci_fixup __start_pci_fixups_resume[];
+extern struct pci_fixup __end_pci_fixups_resume[];
 
 
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
@@ -1559,6 +1620,11 @@
 		end = __end_pci_fixups_enable;
 		break;
 
+	case pci_fixup_resume:
+		start = __start_pci_fixups_resume;
+		end = __end_pci_fixups_resume;
+		break;
+
 	default:
 		/* stupid compiler warning, you would think with an enum... */
 		return;
@@ -1596,7 +1662,7 @@
  * Force it to be linked by setting the corresponding control bit in the
  * config space.
  */
-static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
+static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
 {
 	uint8_t b;
 	if (pci_read_config_byte(dev, 0xf41, &b) == 0) {
@@ -1610,6 +1676,8 @@
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
 			quirk_nvidia_ck804_pcie_aer_ext_cap);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
+			quirk_nvidia_ck804_pcie_aer_ext_cap);
 
 #ifdef CONFIG_PCI_MSI
 /* To disable MSI globally */
@@ -1644,19 +1712,23 @@
  * return 1 if a HT MSI capability is found and enabled */
 static int __devinit msi_ht_cap_enabled(struct pci_dev *dev)
 {
-	u8 pos;
-	int ttl;
-	for (pos = pci_find_capability(dev, PCI_CAP_ID_HT), ttl = 48;
-	     pos && ttl;
-	     pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT), ttl--) {
-		u32 cap_hdr;
-		/* MSI mapping section according to Hypertransport spec */
-		if (pci_read_config_dword(dev, pos, &cap_hdr) == 0
-		    && (cap_hdr & 0xf8000000) == 0xa8000000 /* MSI mapping */) {
-			printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n",
-			       pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled");
-			return (cap_hdr & 0x10000) != 0; /* MSI mapping cap enabled */
+	int pos, ttl = 48;
+
+	pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+	while (pos && ttl--) {
+		u8 flags;
+
+		if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+					 &flags) == 0)
+		{
+			printk(KERN_INFO "PCI: Found %s HT MSI Mapping on %s\n",
+				flags & HT_MSI_FLAGS_ENABLE ?
+				"enabled" : "disabled", pci_name(dev));
+			return (flags & HT_MSI_FLAGS_ENABLE) != 0;
 		}
+
+		pos = pci_find_next_ht_capability(dev, pos,
+						  HT_CAPTYPE_MSI_MAPPING);
 	}
 	return 0;
 }
@@ -1688,8 +1760,9 @@
 	 * a single one having MSI is enough to be sure that MSI are supported.
 	 */
 	pdev = pci_get_slot(dev->bus, 0);
-	if (dev->subordinate && !msi_ht_cap_enabled(dev)
-	    && !msi_ht_cap_enabled(pdev)) {
+	if (!pdev)
+		return;
+	if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
 		printk(KERN_WARNING "PCI: MSI quirk detected. "
 		       "MSI disabled on chipset %s.\n",
 		       pci_name(dev));
diff -ru 2.2/drivers/pci/search.c 3.4/drivers/pci/search.c
--- 2.2/drivers/pci/search.c	2006-10-19 07:38:22.000000000 +0200
+++ 3.4/drivers/pci/search.c	2006-12-22 01:57:07.000000000 +0100
@@ -413,6 +413,24 @@
 	return dev;
 }
 
+const struct pci_device_id *pci_find_present(const struct pci_device_id *ids)
+{
+	struct pci_dev *dev;
+	const struct pci_device_id *found = NULL;
+
+	WARN_ON(in_interrupt());
+	down_read(&pci_bus_sem);
+	while (ids->vendor || ids->subvendor || ids->class_mask) {
+		list_for_each_entry(dev, &pci_devices, global_list) {
+			if ((found = pci_match_one_device(ids, dev)) != NULL)
+				break;
+		}
+		ids++;
+	}
+	up_read(&pci_bus_sem);
+	return found;
+}
+
 /**
  * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
  * @ids: A pointer to a null terminated list of struct pci_device_id structures
@@ -426,25 +444,11 @@
  */
 int pci_dev_present(const struct pci_device_id *ids)
 {
-	struct pci_dev *dev;
-	int found = 0;
-
-	WARN_ON(in_interrupt());
-	down_read(&pci_bus_sem);
-	while (ids->vendor || ids->subvendor || ids->class_mask) {
-		list_for_each_entry(dev, &pci_devices, global_list) {
-			if (pci_match_one_device(ids, dev)) {
-				found = 1;
-				goto exit;
-			}
-		}
-		ids++;
-	}
-exit:
-	up_read(&pci_bus_sem);
-	return found;
+	return pci_find_present(ids) == NULL ? 0 : 1;
 }
+
 EXPORT_SYMBOL(pci_dev_present);
+EXPORT_SYMBOL(pci_find_present);
 
 EXPORT_SYMBOL(pci_find_device);
 EXPORT_SYMBOL(pci_find_device_reverse);
diff -ru 2.2/drivers/pci/setup-bus.c 3.4/drivers/pci/setup-bus.c
--- 2.2/drivers/pci/setup-bus.c	2006-10-04 18:55:38.000000000 +0200
+++ 3.4/drivers/pci/setup-bus.c	2006-12-23 01:11:19.000000000 +0100
@@ -41,7 +41,7 @@
  * have a P2P bridge below a cardbus bridge, we need 4K.
  */
 #define CARDBUS_IO_SIZE		(256)
-#define CARDBUS_MEM_SIZE	(32*1024*1024)
+#define CARDBUS_MEM_SIZE	(64*1024*1024)
 
 static void __devinit
 pbus_assign_resources_sorted(struct pci_bus *bus)
diff -ru 2.2/drivers/pci/setup-res.c 3.4/drivers/pci/setup-res.c
--- 2.2/drivers/pci/setup-res.c	2006-12-08 19:31:48.000000000 +0100
+++ 3.4/drivers/pci/setup-res.c	2006-12-22 01:57:07.000000000 +0100
@@ -33,11 +33,22 @@
 	u32 new, check, mask;
 	int reg;
 
-	/* Ignore resources for unimplemented BARs and unused resource slots
-	   for 64 bit BARs. */
+	/*
+	 * Ignore resources for unimplemented BARs and unused resource slots
+	 * for 64 bit BARs.
+	 */
 	if (!res->flags)
 		return;
 
+	/*
+	 * Ignore non-moveable resources.  This might be legacy resources for
+	 * which no functional BAR register exists or another important
+	 * system resource we should better not move around in system address
+	 * space.
+	 */
+	if (res->flags & IORESOURCE_PCI_FIXED)
+		return;
+
 	pcibios_resource_to_bus(dev, &region, res);
 
 	pr_debug("  got res [%llx:%llx] bus [%lx:%lx] flags %lx for "
@@ -212,6 +223,10 @@
 		resource_size_t r_align;
 
 		r = &dev->resource[i];
+
+		if (r->flags & IORESOURCE_PCI_FIXED)
+			continue;
+
 		r_align = r->end - r->start;
 		
 		if (!(r->flags) || r->parent)
diff -ru 2.2/drivers/scsi/scsi_lib.c 3.4/drivers/scsi/scsi_lib.c
--- 2.2/drivers/scsi/scsi_lib.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/scsi/scsi_lib.c	2006-12-22 01:57:07.000000000 +0100
@@ -265,13 +265,11 @@
 
 	if (!rq->bio)
 		blk_rq_bio_prep(q, rq, bio);
-	else if (!q->back_merge_fn(q, rq, bio))
+	else if (!ll_back_merge_fn(q, rq, bio))
 		return -EINVAL;
 	else {
 		rq->biotail->bi_next = bio;
 		rq->biotail = bio;
-		rq->hard_nr_sectors += bio_sectors(bio);
-		rq->nr_sectors = rq->hard_nr_sectors;
 	}
 
 	return 0;
diff -ru 2.2/drivers/scsi/sun3_NCR5380.c 3.4/drivers/scsi/sun3_NCR5380.c
--- 2.2/drivers/scsi/sun3_NCR5380.c	2006-12-10 05:32:05.000000000 +0100
+++ 3.4/drivers/scsi/sun3_NCR5380.c	2006-12-18 04:27:33.000000000 +0100
@@ -266,7 +266,7 @@
 	(struct NCR5380_hostdata *)(in)->hostdata
 #define	HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
 
-#define	NEXT(cmd)	((struct scsi_cmnd *)((cmd)->host_scribble))
+#define	NEXT(cmd)	(*(struct scsi_cmnd **)&((cmd)->host_scribble))
 #define	NEXTADDR(cmd)	((struct scsi_cmnd **)&((cmd)->host_scribble))
 
 #define	HOSTNO		instance->host_no
@@ -650,7 +650,7 @@
 #include <linux/interrupt.h>
 
 static volatile int main_running = 0;
-static DECLARE_WORK(NCR5380_tqueue, (void (*)(void*))NCR5380_main, NULL);
+static DECLARE_WORK(NCR5380_tqueue, NCR5380_main);
 
 static __inline__ void queue_main(void)
 {
@@ -1031,7 +1031,7 @@
  *  reenable them.  This prevents reentrancy and kernel stack overflow.
  */ 	
     
-static void NCR5380_main (void *bl)
+static void NCR5380_main (struct work_struct *bl)
 {
     struct scsi_cmnd *tmp, *prev;
     struct Scsi_Host *instance = first_instance;
diff -ru 2.2/drivers/serial/uartlite.c 3.4/drivers/serial/uartlite.c
--- 2.2/drivers/serial/uartlite.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/serial/uartlite.c	2006-12-23 01:11:19.000000000 +0100
@@ -278,8 +278,8 @@
 
 static void ulite_config_port(struct uart_port *port, int flags)
 {
-	ulite_request_port(port);
-	port->type = PORT_UARTLITE;
+	if (!ulite_request_port(port))
+		port->type = PORT_UARTLITE;
 }
 
 static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
diff -ru 2.2/drivers/spi/spi_s3c24xx_gpio.c 3.4/drivers/spi/spi_s3c24xx_gpio.c
--- 2.2/drivers/spi/spi_s3c24xx_gpio.c	2006-10-04 20:38:33.000000000 +0200
+++ 3.4/drivers/spi/spi_s3c24xx_gpio.c	2006-12-23 01:11:19.000000000 +0100
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#include <linux/workqueue.h>
 #include <linux/platform_device.h>
 
 #include <linux/spi/spi.h>
diff -ru 2.2/drivers/usb/class/usblp.c 3.4/drivers/usb/class/usblp.c
--- 2.2/drivers/usb/class/usblp.c	2006-11-05 21:44:37.000000000 +0100
+++ 3.4/drivers/usb/class/usblp.c	2006-12-22 01:57:07.000000000 +0100
@@ -130,7 +130,7 @@
 
 struct usblp {
 	struct usb_device 	*dev;			/* USB device */
-	struct semaphore	sem;			/* locks this struct, especially "dev" */
+	struct mutex		mut;			/* locks this struct, especially "dev" */
 	char			*writebuf;		/* write transfer_buffer */
 	char			*readbuf;		/* read transfer_buffer */
 	char			*statusbuf;		/* status transfer_buffer */
@@ -465,7 +465,7 @@
 	int twoints[2];
 	int retval = 0;
 
-	down (&usblp->sem);
+	mutex_lock (&usblp->mut);
 	if (!usblp->present) {
 		retval = -ENODEV;
 		goto done;
@@ -644,14 +644,14 @@
 		}
 
 done:
-	up (&usblp->sem);
+	mutex_unlock (&usblp->mut);
 	return retval;
 }
 
 static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
 	struct usblp *usblp = file->private_data;
-	int timeout, rv, err = 0, transfer_length = 0;
+	int timeout, intr, rv, err = 0, transfer_length = 0;
 	size_t writecount = 0;
 
 	while (writecount < count) {
@@ -668,14 +668,16 @@
 			if (rv < 0)
 				return writecount ? writecount : -EINTR;
 		}
-		down (&usblp->sem);
+		intr = mutex_lock_interruptible (&usblp->mut);
+		if (intr)
+			return writecount ? writecount : -EINTR;
 		if (!usblp->present) {
-			up (&usblp->sem);
+			mutex_unlock (&usblp->mut);
 			return -ENODEV;
 		}
 
 		if (usblp->sleeping) {
-			up (&usblp->sem);
+			mutex_unlock (&usblp->mut);
 			return writecount ? writecount : -ENODEV;
 		}
 
@@ -687,10 +689,10 @@
 				err = usblp->writeurb->status;
 			} else
 				err = usblp_check_status(usblp, err);
-			up (&usblp->sem);
+			mutex_unlock (&usblp->mut);
 
 			/* if the fault was due to disconnect, let khubd's
-			 * call to usblp_disconnect() grab usblp->sem ...
+			 * call to usblp_disconnect() grab usblp->mut ...
 			 */
 			schedule ();
 			continue;
@@ -702,7 +704,7 @@
 		 */
 		writecount += transfer_length;
 		if (writecount == count) {
-			up(&usblp->sem);
+			mutex_unlock(&usblp->mut);
 			break;
 		}
 
@@ -714,7 +716,7 @@
 
 		if (copy_from_user(usblp->writeurb->transfer_buffer, 
 				   buffer + writecount, transfer_length)) {
-			up(&usblp->sem);
+			mutex_unlock(&usblp->mut);
 			return writecount ? writecount : -EFAULT;
 		}
 
@@ -727,10 +729,10 @@
 				count = -EIO;
 			else
 				count = writecount ? writecount : -ENOMEM;
-			up (&usblp->sem);
+			mutex_unlock (&usblp->mut);
 			break;
 		}
-		up (&usblp->sem);
+		mutex_unlock (&usblp->mut);
 	}
 
 	return count;
@@ -739,12 +741,14 @@
 static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
 	struct usblp *usblp = file->private_data;
-	int rv;
+	int rv, intr;
 
 	if (!usblp->bidir)
 		return -EINVAL;
 
-	down (&usblp->sem);
+	intr = mutex_lock_interruptible (&usblp->mut);
+	if (intr)
+		return -EINTR;
 	if (!usblp->present) {
 		count = -ENODEV;
 		goto done;
@@ -757,9 +761,9 @@
 			count = -EAGAIN;
 			goto done;
 		}
-		up(&usblp->sem);
+		mutex_unlock(&usblp->mut);
 		rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present);
-		down(&usblp->sem);
+		mutex_lock(&usblp->mut);
 		if (rv < 0) {
 			count = -EINTR;
 			goto done;
@@ -807,7 +811,7 @@
 	}
 
 done:
-	up (&usblp->sem);
+	mutex_unlock (&usblp->mut);
 	return count;
 }
 
@@ -886,7 +890,7 @@
 		goto abort;
 	}
 	usblp->dev = dev;
-	init_MUTEX (&usblp->sem);
+	mutex_init (&usblp->mut);
 	init_waitqueue_head(&usblp->wait);
 	usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
 	usblp->intf = intf;
@@ -1178,7 +1182,7 @@
 	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
 
 	mutex_lock (&usblp_mutex);
-	down (&usblp->sem);
+	mutex_lock (&usblp->mut);
 	usblp->present = 0;
 	usb_set_intfdata (intf, NULL);
 
@@ -1187,7 +1191,7 @@
 			usblp->writebuf, usblp->writeurb->transfer_dma);
 	usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
 			usblp->readbuf, usblp->readurb->transfer_dma);
-	up (&usblp->sem);
+	mutex_unlock (&usblp->mut);
 
 	if (!usblp->used)
 		usblp_cleanup (usblp);
@@ -1200,11 +1204,11 @@
 
 	/* this races against normal access and open */
 	mutex_lock (&usblp_mutex);
-	down (&usblp->sem);
+	mutex_lock (&usblp->mut);
 	/* we take no more IO */
 	usblp->sleeping = 1;
 	usblp_unlink_urbs(usblp);
-	up (&usblp->sem);
+	mutex_unlock (&usblp->mut);
 	mutex_unlock (&usblp_mutex);
 
 	return 0;
@@ -1216,12 +1220,12 @@
 	int r;
 
 	mutex_lock (&usblp_mutex);
-	down (&usblp->sem);
+	mutex_lock (&usblp->mut);
 
 	usblp->sleeping = 0;
 	r = handle_bidir (usblp);
 
-	up (&usblp->sem);
+	mutex_unlock (&usblp->mut);
 	mutex_unlock (&usblp_mutex);
 
 	return r;
diff -ru 2.2/drivers/usb/core/devio.c 3.4/drivers/usb/core/devio.c
--- 2.2/drivers/usb/core/devio.c	2006-12-07 02:52:14.000000000 +0100
+++ 3.4/drivers/usb/core/devio.c	2006-12-22 01:57:07.000000000 +0100
@@ -962,7 +962,11 @@
 			kfree(dr);
 			return -EFAULT;
 		}
-		snoop(&ps->dev->dev, "control urb\n");
+		snoop(&ps->dev->dev, "control urb: bRequest=%02x "
+			"bRrequestType=%02x wValue=%04x "
+			"wIndex=%04x wLength=%04x\n",
+			dr->bRequest, dr->bRequestType, dr->wValue,
+			dr->wIndex, dr->wLength);
 		break;
 
 	case USBDEVFS_URB_TYPE_BULK:
diff -ru 2.2/drivers/usb/gadget/at91_udc.c 3.4/drivers/usb/gadget/at91_udc.c
--- 2.2/drivers/usb/gadget/at91_udc.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/usb/gadget/at91_udc.c	2006-12-22 01:57:07.000000000 +0100
@@ -43,14 +43,16 @@
 #include <linux/usb_gadget.h>
 
 #include <asm/byteorder.h>
+#include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/hardware.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/board.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/at91sam9261_matrix.h>
 
 #include "at91_udc.h"
 
@@ -78,27 +80,11 @@
 static const char driver_name [] = "at91_udc";
 static const char ep0name[] = "ep0";
 
-/*-------------------------------------------------------------------------*/
 
-/*
- * Read from a UDP register.
- */
-static inline unsigned long at91_udp_read(unsigned int reg)
-{
-	void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP;
-
-	return __raw_readl(udp_base + reg);
-}
-
-/*
- * Write to a UDP register.
- */
-static inline void at91_udp_write(unsigned int reg, unsigned long value)
-{
-	void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP;
-
-	__raw_writel(value, udp_base + reg);
-}
+#define at91_udp_read(dev, reg) \
+	__raw_readl((dev)->udp_baseaddr + (reg))
+#define at91_udp_write(dev, reg, val) \
+	__raw_writel((val), (dev)->udp_baseaddr + (reg))
 
 /*-------------------------------------------------------------------------*/
 
@@ -210,13 +196,13 @@
 		return 0;
 	}
 
-	tmp = at91_udp_read(AT91_UDP_FRM_NUM);
+	tmp = at91_udp_read(udc, AT91_UDP_FRM_NUM);
 	seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp,
 		(tmp & AT91_UDP_FRM_OK) ? " ok" : "",
 		(tmp & AT91_UDP_FRM_ERR) ? " err" : "",
 		(tmp & AT91_UDP_NUM));
 
-	tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+	tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
 	seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp,
 		(tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "",
 		(tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "",
@@ -224,13 +210,13 @@
 		(tmp & AT91_UDP_CONFG) ? " confg" : "",
 		(tmp & AT91_UDP_FADDEN) ? " fadden" : "");
 
-	tmp = at91_udp_read(AT91_UDP_FADDR);
+	tmp = at91_udp_read(udc, AT91_UDP_FADDR);
 	seq_printf(s, "faddr   %03x:%s fadd=%d\n", tmp,
 		(tmp & AT91_UDP_FEN) ? " fen" : "",
 		(tmp & AT91_UDP_FADD));
 
-	proc_irq_show(s, "imr   ", at91_udp_read(AT91_UDP_IMR));
-	proc_irq_show(s, "isr   ", at91_udp_read(AT91_UDP_ISR));
+	proc_irq_show(s, "imr   ", at91_udp_read(udc, AT91_UDP_IMR));
+	proc_irq_show(s, "isr   ", at91_udp_read(udc, AT91_UDP_ISR));
 
 	if (udc->enabled && udc->vbus) {
 		proc_ep_show(s, &udc->ep[0]);
@@ -286,6 +272,7 @@
 static void done(struct at91_ep *ep, struct at91_request *req, int status)
 {
 	unsigned	stopped = ep->stopped;
+	struct at91_udc	*udc = ep->udc;
 
 	list_del_init(&req->queue);
 	if (req->req.status == -EINPROGRESS)
@@ -301,7 +288,7 @@
 
 	/* ep0 is always ready; other endpoints need a non-empty queue */
 	if (list_empty(&ep->queue) && ep->int_mask != (1 << 0))
-		at91_udp_write(AT91_UDP_IDR, ep->int_mask);
+		at91_udp_write(udc, AT91_UDP_IDR, ep->int_mask);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -554,8 +541,8 @@
 	 * reset/init endpoint fifo.  NOTE:  leaves fifo_bank alone,
 	 * since endpoint resets don't reset hw pingpong state.
 	 */
-	at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
-	at91_udp_write(AT91_UDP_RST_EP, 0);
+	at91_udp_write(dev, AT91_UDP_RST_EP, ep->int_mask);
+	at91_udp_write(dev, AT91_UDP_RST_EP, 0);
 
 	local_irq_restore(flags);
 	return 0;
@@ -564,6 +551,7 @@
 static int at91_ep_disable (struct usb_ep * _ep)
 {
 	struct at91_ep	*ep = container_of(_ep, struct at91_ep, ep);
+	struct at91_udc	*udc = ep->udc;
 	unsigned long	flags;
 
 	if (ep == &ep->udc->ep[0])
@@ -579,8 +567,8 @@
 
 	/* reset fifos and endpoint */
 	if (ep->udc->clocked) {
-		at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
-		at91_udp_write(AT91_UDP_RST_EP, 0);
+		at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask);
+		at91_udp_write(udc, AT91_UDP_RST_EP, 0);
 		__raw_writel(0, ep->creg);
 	}
 
@@ -695,10 +683,10 @@
 			 * reconfigures the endpoints.
 			 */
 			if (dev->wait_for_config_ack) {
-				tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+				tmp = at91_udp_read(dev, AT91_UDP_GLB_STAT);
 				tmp ^= AT91_UDP_CONFG;
 				VDBG("toggle config\n");
-				at91_udp_write(AT91_UDP_GLB_STAT, tmp);
+				at91_udp_write(dev, AT91_UDP_GLB_STAT, tmp);
 			}
 			if (req->req.length == 0) {
 ep0_in_status:
@@ -727,7 +715,7 @@
 
 	if (req && !status) {
 		list_add_tail (&req->queue, &ep->queue);
-		at91_udp_write(AT91_UDP_IER, ep->int_mask);
+		at91_udp_write(dev, AT91_UDP_IER, ep->int_mask);
 	}
 done:
 	local_irq_restore(flags);
@@ -758,6 +746,7 @@
 static int at91_ep_set_halt(struct usb_ep *_ep, int value)
 {
 	struct at91_ep	*ep = container_of(_ep, struct at91_ep, ep);
+	struct at91_udc	*udc = ep->udc;
 	u32 __iomem	*creg;
 	u32		csr;
 	unsigned long	flags;
@@ -785,8 +774,8 @@
 			csr |= AT91_UDP_FORCESTALL;
 			VDBG("halt %s\n", ep->ep.name);
 		} else {
-			at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
-			at91_udp_write(AT91_UDP_RST_EP, 0);
+			at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask);
+			at91_udp_write(udc, AT91_UDP_RST_EP, 0);
 			csr &= ~AT91_UDP_FORCESTALL;
 		}
 		__raw_writel(csr, creg);
@@ -813,9 +802,11 @@
 
 static int at91_get_frame(struct usb_gadget *gadget)
 {
+	struct at91_udc *udc = to_udc(gadget);
+
 	if (!to_udc(gadget)->clocked)
 		return -EINVAL;
-	return at91_udp_read(AT91_UDP_FRM_NUM) & AT91_UDP_NUM;
+	return at91_udp_read(udc, AT91_UDP_FRM_NUM) & AT91_UDP_NUM;
 }
 
 static int at91_wakeup(struct usb_gadget *gadget)
@@ -833,11 +824,11 @@
 
 	/* NOTE:  some "early versions" handle ESR differently ... */
 
-	glbstate = at91_udp_read(AT91_UDP_GLB_STAT);
+	glbstate = at91_udp_read(udc, AT91_UDP_GLB_STAT);
 	if (!(glbstate & AT91_UDP_ESR))
 		goto done;
 	glbstate |= AT91_UDP_ESR;
-	at91_udp_write(AT91_UDP_GLB_STAT, glbstate);
+	at91_udp_write(udc, AT91_UDP_GLB_STAT, glbstate);
 
 done:
 	local_irq_restore(flags);
@@ -861,6 +852,7 @@
 		ep->stopped = 0;
 		ep->fifo_bank = 0;
 		ep->ep.maxpacket = ep->maxpacket;
+		ep->creg = (void __iomem *) udc->udp_baseaddr + AT91_UDP_CSR(i);
 		// initialiser une queue par endpoint
 		INIT_LIST_HEAD(&ep->queue);
 	}
@@ -915,14 +907,41 @@
 	if (!udc->enabled || !udc->vbus)
 		is_on = 0;
 	DBG("%sactive\n", is_on ? "" : "in");
+
 	if (is_on) {
 		clk_on(udc);
-		at91_udp_write(AT91_UDP_TXVC, 0);
-		at91_set_gpio_value(udc->board.pullup_pin, 1);
-	} else  {
+		at91_udp_write(udc, AT91_UDP_TXVC, 0);
+		if (cpu_is_at91rm9200())
+			at91_set_gpio_value(udc->board.pullup_pin, 1);
+		else if (cpu_is_at91sam9260()) {
+			u32	txvc = at91_udp_read(udc, AT91_UDP_TXVC);
+
+			txvc |= AT91_UDP_TXVC_PUON;
+			at91_udp_write(udc, AT91_UDP_TXVC, txvc);
+		} else if (cpu_is_at91sam9261()) {
+			u32	usbpucr;
+
+			usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
+			usbpucr |= AT91_MATRIX_USBPUCR_PUON;
+			at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr);
+		}
+	} else {
 		stop_activity(udc);
-		at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
-		at91_set_gpio_value(udc->board.pullup_pin, 0);
+		at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
+		if (cpu_is_at91rm9200())
+			at91_set_gpio_value(udc->board.pullup_pin, 0);
+		else if (cpu_is_at91sam9260()) {
+			u32	txvc = at91_udp_read(udc, AT91_UDP_TXVC);
+
+			txvc &= ~AT91_UDP_TXVC_PUON;
+			at91_udp_write(udc, AT91_UDP_TXVC, txvc);
+		} else if (cpu_is_at91sam9261()) {
+			u32	usbpucr;
+
+			usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
+			usbpucr &= ~AT91_MATRIX_USBPUCR_PUON;
+			at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr);
+		}
 		clk_off(udc);
 	}
 }
@@ -936,7 +955,10 @@
 	// VDBG("vbus %s\n", is_active ? "on" : "off");
 	local_irq_save(flags);
 	udc->vbus = (is_active != 0);
-	pullup(udc, is_active);
+	if (udc->driver)
+		pullup(udc, is_active);
+	else
+		pullup(udc, 0);
 	local_irq_restore(flags);
 	return 0;
 }
@@ -1086,7 +1108,7 @@
 
 	case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
 			| USB_REQ_SET_CONFIGURATION:
-		tmp = at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_CONFG;
+		tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_CONFG;
 		if (pkt.r.wValue)
 			udc->wait_for_config_ack = (tmp == 0);
 		else
@@ -1103,7 +1125,7 @@
 	case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
 			| USB_REQ_GET_STATUS:
 		tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED);
-		if (at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_ESR)
+		if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR)
 			tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP);
 		PACKET("get device status\n");
 		__raw_writeb(tmp, dreg);
@@ -1114,17 +1136,17 @@
 			| USB_REQ_SET_FEATURE:
 		if (w_value != USB_DEVICE_REMOTE_WAKEUP)
 			goto stall;
-		tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+		tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
 		tmp |= AT91_UDP_ESR;
-		at91_udp_write(AT91_UDP_GLB_STAT, tmp);
+		at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp);
 		goto succeed;
 	case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
 			| USB_REQ_CLEAR_FEATURE:
 		if (w_value != USB_DEVICE_REMOTE_WAKEUP)
 			goto stall;
-		tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+		tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
 		tmp &= ~AT91_UDP_ESR;
-		at91_udp_write(AT91_UDP_GLB_STAT, tmp);
+		at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp);
 		goto succeed;
 
 	/*
@@ -1206,8 +1228,8 @@
 		} else if (ep->is_in)
 			goto stall;
 
-		at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
-		at91_udp_write(AT91_UDP_RST_EP, 0);
+		at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask);
+		at91_udp_write(udc, AT91_UDP_RST_EP, 0);
 		tmp = __raw_readl(ep->creg);
 		tmp |= CLR_FX;
 		tmp &= ~(SET_FX | AT91_UDP_FORCESTALL);
@@ -1222,7 +1244,10 @@
 #undef w_length
 
 	/* pass request up to the gadget driver */
-	status = udc->driver->setup(&udc->gadget, &pkt.r);
+	if (udc->driver)
+		status = udc->driver->setup(&udc->gadget, &pkt.r);
+	else
+		status = -ENODEV;
 	if (status < 0) {
 stall:
 		VDBG("req %02x.%02x protocol STALL; stat %d\n",
@@ -1300,13 +1325,13 @@
 			if (udc->wait_for_addr_ack) {
 				u32	tmp;
 
-				at91_udp_write(AT91_UDP_FADDR,
+				at91_udp_write(udc, AT91_UDP_FADDR,
 						AT91_UDP_FEN | udc->addr);
-				tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+				tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
 				tmp &= ~AT91_UDP_FADDEN;
 				if (udc->addr)
 					tmp |= AT91_UDP_FADDEN;
-				at91_udp_write(AT91_UDP_GLB_STAT, tmp);
+				at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp);
 
 				udc->wait_for_addr_ack = 0;
 				VDBG("address %d\n", udc->addr);
@@ -1374,28 +1399,28 @@
 	while (rescans--) {
 		u32 status;
 
-		status = at91_udp_read(AT91_UDP_ISR)
-			& at91_udp_read(AT91_UDP_IMR);
+		status = at91_udp_read(udc, AT91_UDP_ISR)
+			& at91_udp_read(udc, AT91_UDP_IMR);
 		if (!status)
 			break;
 
 		/* USB reset irq:  not maskable */
 		if (status & AT91_UDP_ENDBUSRES) {
-			at91_udp_write(AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS);
-			at91_udp_write(AT91_UDP_IER, MINIMUS_INTERRUPTUS);
+			at91_udp_write(udc, AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS);
+			at91_udp_write(udc, AT91_UDP_IER, MINIMUS_INTERRUPTUS);
 			/* Atmel code clears this irq twice */
-			at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
-			at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
+			at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
+			at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
 			VDBG("end bus reset\n");
 			udc->addr = 0;
 			stop_activity(udc);
 
 			/* enable ep0 */
-			at91_udp_write(AT91_UDP_CSR(0),
+			at91_udp_write(udc, AT91_UDP_CSR(0),
 					AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
 			udc->gadget.speed = USB_SPEED_FULL;
 			udc->suspended = 0;
-			at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0));
+			at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_EP(0));
 
 			/*
 			 * NOTE:  this driver keeps clocks off unless the
@@ -1406,9 +1431,9 @@
 
 		/* host initiated suspend (3+ms bus idle) */
 		} else if (status & AT91_UDP_RXSUSP) {
-			at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXSUSP);
-			at91_udp_write(AT91_UDP_IER, AT91_UDP_RXRSM);
-			at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXSUSP);
+			at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXSUSP);
+			at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXRSM);
+			at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXSUSP);
 			// VDBG("bus suspend\n");
 			if (udc->suspended)
 				continue;
@@ -1425,9 +1450,9 @@
 
 		/* host initiated resume */
 		} else if (status & AT91_UDP_RXRSM) {
-			at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXRSM);
-			at91_udp_write(AT91_UDP_IER, AT91_UDP_RXSUSP);
-			at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXRSM);
+			at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM);
+			at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXSUSP);
+			at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM);
 			// VDBG("bus resume\n");
 			if (!udc->suspended)
 				continue;
@@ -1485,8 +1510,6 @@
 		},
 		.udc		= &controller,
 		.maxpacket	= 8,
-		.creg		= (void __iomem *)(AT91_VA_BASE_UDP
-					+ AT91_UDP_CSR(0)),
 		.int_mask	= 1 << 0,
 	},
 	.ep[1] = {
@@ -1497,8 +1520,6 @@
 		.udc		= &controller,
 		.is_pingpong	= 1,
 		.maxpacket	= 64,
-		.creg		= (void __iomem *)(AT91_VA_BASE_UDP
-					+ AT91_UDP_CSR(1)),
 		.int_mask	= 1 << 1,
 	},
 	.ep[2] = {
@@ -1509,8 +1530,6 @@
 		.udc		= &controller,
 		.is_pingpong	= 1,
 		.maxpacket	= 64,
-		.creg		= (void __iomem *)(AT91_VA_BASE_UDP
-					+ AT91_UDP_CSR(2)),
 		.int_mask	= 1 << 2,
 	},
 	.ep[3] = {
@@ -1521,8 +1540,6 @@
 		},
 		.udc		= &controller,
 		.maxpacket	= 8,
-		.creg		= (void __iomem *)(AT91_VA_BASE_UDP
-					+ AT91_UDP_CSR(3)),
 		.int_mask	= 1 << 3,
 	},
 	.ep[4] = {
@@ -1533,8 +1550,6 @@
 		.udc		= &controller,
 		.is_pingpong	= 1,
 		.maxpacket	= 256,
-		.creg		= (void __iomem *)(AT91_VA_BASE_UDP
-					+ AT91_UDP_CSR(4)),
 		.int_mask	= 1 << 4,
 	},
 	.ep[5] = {
@@ -1545,8 +1560,6 @@
 		.udc		= &controller,
 		.is_pingpong	= 1,
 		.maxpacket	= 256,
-		.creg		= (void __iomem *)(AT91_VA_BASE_UDP
-					+ AT91_UDP_CSR(5)),
 		.int_mask	= 1 << 5,
 	},
 	/* ep6 and ep7 are also reserved (custom silicon might use them) */
@@ -1572,9 +1585,8 @@
 	int		retval;
 
 	if (!driver
-			|| driver->speed != USB_SPEED_FULL
+			|| driver->speed < USB_SPEED_FULL
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->setup) {
 		DBG("bad parameter.\n");
 		return -EINVAL;
@@ -1595,6 +1607,10 @@
 	if (retval) {
 		DBG("driver->bind() returned %d\n", retval);
 		udc->driver = NULL;
+		udc->gadget.dev.driver = NULL;
+		udc->gadget.dev.driver_data = NULL;
+		udc->enabled = 0;
+		udc->selfpowered = 0;
 		return retval;
 	}
 
@@ -1611,12 +1627,12 @@
 {
 	struct at91_udc *udc = &controller;
 
-	if (!driver || driver != udc->driver)
+	if (!driver || driver != udc->driver || !driver->unbind)
 		return -EINVAL;
 
 	local_irq_disable();
 	udc->enabled = 0;
-	at91_udp_write(AT91_UDP_IDR, ~0);
+	at91_udp_write(udc, AT91_UDP_IDR, ~0);
 	pullup(udc, 0);
 	local_irq_enable();
 
@@ -1641,6 +1657,7 @@
 	struct device	*dev = &pdev->dev;
 	struct at91_udc	*udc;
 	int		retval;
+	struct resource	*res;
 
 	if (!dev->platform_data) {
 		/* small (so we copy it) but critical! */
@@ -1658,7 +1675,13 @@
 		return -ENODEV;
 	}
 
-	if (!request_mem_region(AT91RM9200_BASE_UDP, SZ_16K, driver_name)) {
+	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;
 	}
@@ -1668,15 +1691,23 @@
 	udc->gadget.dev.parent = dev;
 	udc->board = *(struct at91_udc_data *) dev->platform_data;
 	udc->pdev = pdev;
-	udc_reinit(udc);
 	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;
+	}
+
+	udc_reinit(udc);
+
 	/* get interface and function clocks */
 	udc->iclk = clk_get(dev, "udc_clk");
 	udc->fclk = clk_get(dev, "udpck");
 	if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) {
 		DBG("clocks missing\n");
-		return -ENODEV;
+		retval = -ENODEV;
+		goto fail0;
 	}
 
 	retval = device_register(&udc->gadget.dev);
@@ -1685,8 +1716,10 @@
 
 	/* don't do anything until we have both gadget driver and VBUS */
 	clk_enable(udc->iclk);
-	at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
-	at91_udp_write(AT91_UDP_IDR, 0xffffffff);
+	at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
+	at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff);
+	/* Clear all pending interrupts - UDP may be used by bootloader. */
+	at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff);
 	clk_disable(udc->iclk);
 
 	/* request UDC and maybe VBUS irqs */
@@ -1698,6 +1731,11 @@
 		goto fail1;
 	}
 	if (udc->board.vbus_pin > 0) {
+		/*
+		 * Get the initial state of VBUS - we cannot expect
+		 * a pending interrupt.
+		 */
+		udc->vbus = at91_get_gpio_value(udc->board.vbus_pin);
 		if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
 				IRQF_DISABLED, driver_name, udc)) {
 			DBG("request vbus irq %d failed\n",
@@ -1720,7 +1758,7 @@
 fail1:
 	device_unregister(&udc->gadget.dev);
 fail0:
-	release_mem_region(AT91RM9200_BASE_UDP, SZ_16K);
+	release_mem_region(res->start, res->end - res->start + 1);
 	DBG("%s probe failed, %d\n", driver_name, retval);
 	return retval;
 }
@@ -1728,13 +1766,14 @@
 static int __devexit at91udc_remove(struct platform_device *pdev)
 {
 	struct at91_udc *udc = platform_get_drvdata(pdev);
+	struct resource *res;
 
 	DBG("remove\n");
 
-	pullup(udc, 0);
+	if (udc->driver)
+		return -EBUSY;
 
-	if (udc->driver != 0)
-		usb_gadget_unregister_driver(udc->driver);
+	pullup(udc, 0);
 
 	device_init_wakeup(&pdev->dev, 0);
 	remove_debug_file(udc);
@@ -1742,7 +1781,10 @@
 		free_irq(udc->board.vbus_pin, udc);
 	free_irq(udc->udp_irq, udc);
 	device_unregister(&udc->gadget.dev);
-	release_mem_region(AT91RM9200_BASE_UDP, SZ_16K);
+
+	iounmap(udc->udp_baseaddr);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, res->end - res->start + 1);
 
 	clk_put(udc->iclk);
 	clk_put(udc->fclk);
diff -ru 2.2/drivers/usb/gadget/at91_udc.h 3.4/drivers/usb/gadget/at91_udc.h
--- 2.2/drivers/usb/gadget/at91_udc.h	2006-10-02 17:39:20.000000000 +0200
+++ 3.4/drivers/usb/gadget/at91_udc.h	2006-12-22 01:57:07.000000000 +0100
@@ -51,10 +51,10 @@
 #define     AT91_UDP_EP(n)	(1 << (n))	/* Endpoint Interrupt Status */
 #define     AT91_UDP_RXSUSP	(1 <<  8) 	/* USB Suspend Interrupt Status */
 #define     AT91_UDP_RXRSM	(1 <<  9)	/* USB Resume Interrupt Status */
-#define     AT91_UDP_EXTRSM	(1 << 10)	/* External Resume Interrupt Status */
+#define     AT91_UDP_EXTRSM	(1 << 10)	/* External Resume Interrupt Status [AT91RM9200 only] */
 #define     AT91_UDP_SOFINT	(1 << 11)	/* Start of Frame Interrupt Status */
 #define     AT91_UDP_ENDBUSRES	(1 << 12)	/* End of Bus Reset Interrpt Status */
-#define     AT91_UDP_WAKEUP	(1 << 13)	/* USB Wakeup Interrupt Status */
+#define     AT91_UDP_WAKEUP	(1 << 13)	/* USB Wakeup Interrupt Status [AT91RM9200 only] */
 
 #define AT91_UDP_ICR		0x20		/* Interrupt Clear Register */
 #define AT91_UDP_RST_EP		0x28		/* Reset Endpoint Register */
@@ -84,7 +84,7 @@
 
 #define AT91_UDP_TXVC		0x74		/* Transceiver Control Register */
 #define     AT91_UDP_TXVC_TXVDIS (1 << 8)	/* Transceiver Disable */
-
+#define     AT91_UDP_TXVC_PUON   (1 << 9)	/* PullUp On [AT91SAM9260 only] */
 
 /*-------------------------------------------------------------------------*/
 
@@ -141,6 +141,7 @@
 	struct clk			*iclk, *fclk;
 	struct platform_device		*pdev;
 	struct proc_dir_entry		*pde;
+	void __iomem			*udp_baseaddr;
 	int				udp_irq;
 };
 
diff -ru 2.2/drivers/usb/gadget/dummy_hcd.c 3.4/drivers/usb/gadget/dummy_hcd.c
--- 2.2/drivers/usb/gadget/dummy_hcd.c	2006-10-09 14:52:09.000000000 +0200
+++ 3.4/drivers/usb/gadget/dummy_hcd.c	2006-12-22 01:57:07.000000000 +0100
@@ -779,7 +779,7 @@
 		return -EINVAL;
 	if (dum->driver)
 		return -EBUSY;
-	if (!driver->bind || !driver->unbind || !driver->setup
+	if (!driver->bind || !driver->setup
 			|| driver->speed == USB_SPEED_UNKNOWN)
 		return -EINVAL;
 
@@ -837,7 +837,8 @@
 err_bind_driver:
 	driver_unregister (&driver->driver);
 err_register:
-	driver->unbind (&dum->gadget);
+	if (driver->unbind)
+		driver->unbind (&dum->gadget);
 	spin_lock_irq (&dum->lock);
 	dum->pullup = 0;
 	set_link_state (dum);
@@ -857,7 +858,7 @@
 
 	if (!dum)
 		return -ENODEV;
-	if (!driver || driver != dum->driver)
+	if (!driver || driver != dum->driver || !driver->unbind)
 		return -EINVAL;
 
 	dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n",
diff -ru 2.2/drivers/usb/gadget/file_storage.c 3.4/drivers/usb/gadget/file_storage.c
--- 2.2/drivers/usb/gadget/file_storage.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/usb/gadget/file_storage.c	2006-12-22 01:57:07.000000000 +0100
@@ -4100,7 +4100,7 @@
 #endif
 	.function	= (char *) longname,
 	.bind		= fsg_bind,
-	.unbind		= __exit_p(fsg_unbind),
+	.unbind		= fsg_unbind,
 	.disconnect	= fsg_disconnect,
 	.setup		= fsg_setup,
 	.suspend	= fsg_suspend,
diff -ru 2.2/drivers/usb/gadget/gmidi.c 3.4/drivers/usb/gadget/gmidi.c
--- 2.2/drivers/usb/gadget/gmidi.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/usb/gadget/gmidi.c	2006-12-22 01:57:07.000000000 +0100
@@ -123,7 +123,7 @@
 	struct usb_request	*req;		/* for control responses */
 	u8			config;
 	struct usb_ep		*in_ep, *out_ep;
-	struct snd_card 	*card;
+	struct snd_card		*card;
 	struct snd_rawmidi	*rmidi;
 	struct snd_rawmidi_substream *in_substream;
 	struct snd_rawmidi_substream *out_substream;
@@ -490,7 +490,7 @@
 	int status = req->status;
 
 	switch (status) {
-	case 0: 			/* normal completion */
+	case 0:				/* normal completion */
 		if (ep == dev->out_ep) {
 			/* we received stuff.
 			   req is queued again, below */
@@ -505,7 +505,7 @@
 		break;
 
 	/* this endpoint is normally active while we're configured */
-	case -ECONNABORTED: 		/* hardware forced ep reset */
+	case -ECONNABORTED:		/* hardware forced ep reset */
 	case -ECONNRESET:		/* request dequeued */
 	case -ESHUTDOWN:		/* disconnect from host */
 		VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status,
@@ -656,7 +656,7 @@
 		case USB_SPEED_LOW:	speed = "low"; break;
 		case USB_SPEED_FULL:	speed = "full"; break;
 		case USB_SPEED_HIGH:	speed = "high"; break;
-		default: 		speed = "?"; break;
+		default:		speed = "?"; break;
 		}
 
 		dev->config = number;
@@ -1308,7 +1308,7 @@
 	.speed		= USB_SPEED_FULL,
 	.function	= (char *)longname,
 	.bind		= gmidi_bind,
-	.unbind		= __exit_p(gmidi_unbind),
+	.unbind		= gmidi_unbind,
 
 	.setup		= gmidi_setup,
 	.disconnect	= gmidi_disconnect,
@@ -1316,7 +1316,7 @@
 	.suspend	= gmidi_suspend,
 	.resume		= gmidi_resume,
 
-	.driver 	= {
+	.driver		= {
 		.name		= (char *)shortname,
 		.owner		= THIS_MODULE,
 	},
diff -ru 2.2/drivers/usb/gadget/goku_udc.c 3.4/drivers/usb/gadget/goku_udc.c
--- 2.2/drivers/usb/gadget/goku_udc.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/usb/gadget/goku_udc.c	2006-12-22 01:57:07.000000000 +0100
@@ -1432,7 +1432,6 @@
 	if (!driver
 			|| driver->speed != USB_SPEED_FULL
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->disconnect
 			|| !driver->setup)
 		return -EINVAL;
@@ -1495,7 +1494,7 @@
 
 	if (!dev)
 		return -ENODEV;
-	if (!driver || driver != dev->driver)
+	if (!driver || driver != dev->driver || !driver->unbind)
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev->lock, flags);
@@ -1808,13 +1807,8 @@
 	struct goku_udc		*dev = pci_get_drvdata(pdev);
 
 	DBG(dev, "%s\n", __FUNCTION__);
-	/* start with the driver above us */
-	if (dev->driver) {
-		/* should have been done already by driver model core */
-		WARN(dev, "pci remove, driver '%s' is still registered\n",
-				dev->driver->driver.name);
-		usb_gadget_unregister_driver(dev->driver);
-	}
+
+	BUG_ON(dev->driver);
 
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
 	remove_proc_entry(proc_node_name, NULL);
diff -ru 2.2/drivers/usb/gadget/lh7a40x_udc.c 3.4/drivers/usb/gadget/lh7a40x_udc.c
--- 2.2/drivers/usb/gadget/lh7a40x_udc.c	2006-12-07 02:52:14.000000000 +0100
+++ 3.4/drivers/usb/gadget/lh7a40x_udc.c	2006-12-22 01:57:07.000000000 +0100
@@ -422,9 +422,10 @@
 	DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name);
 
 	if (!driver
-	    || driver->speed != USB_SPEED_FULL
-	    || !driver->bind
-	    || !driver->unbind || !driver->disconnect || !driver->setup)
+			|| driver->speed != USB_SPEED_FULL
+			|| !driver->bind
+			|| !driver->disconnect
+			|| !driver->setup)
 		return -EINVAL;
 	if (!dev)
 		return -ENODEV;
@@ -471,7 +472,7 @@
 
 	if (!dev)
 		return -ENODEV;
-	if (!driver || driver != dev->driver)
+	if (!driver || driver != dev->driver || !driver->unbind)
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev->lock, flags);
@@ -2125,9 +2126,11 @@
 
 	DEBUG("%s: %p\n", __FUNCTION__, pdev);
 
+	if (dev->driver)
+		return -EBUSY;
+
 	udc_disable(dev);
 	remove_proc_files();
-	usb_gadget_unregister_driver(dev->driver);
 
 	free_irq(IRQ_USBINTR, dev);
 
diff -ru 2.2/drivers/usb/gadget/net2280.c 3.4/drivers/usb/gadget/net2280.c
--- 2.2/drivers/usb/gadget/net2280.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/usb/gadget/net2280.c	2006-12-22 01:57:07.000000000 +0100
@@ -2020,7 +2020,6 @@
 	if (!driver
 			|| driver->speed != USB_SPEED_HIGH
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->setup)
 		return -EINVAL;
 	if (!dev)
@@ -2107,7 +2106,7 @@
 
 	if (!dev)
 		return -ENODEV;
-	if (!driver || driver != dev->driver)
+	if (!driver || driver != dev->driver || !driver->unbind)
 		return -EINVAL;
 
 	spin_lock_irqsave (&dev->lock, flags);
@@ -2803,13 +2802,7 @@
 {
 	struct net2280		*dev = pci_get_drvdata (pdev);
 
-	/* start with the driver above us */
-	if (dev->driver) {
-		/* should have been done already by driver model core */
-		WARN (dev, "pci remove, driver '%s' is still registered\n",
-				dev->driver->driver.name);
-		usb_gadget_unregister_driver (dev->driver);
-	}
+	BUG_ON(dev->driver);
 
 	/* then clean up the resources we allocated during probe() */
 	net2280_led_shutdown (dev);
diff -ru 2.2/drivers/usb/gadget/omap_udc.c 3.4/drivers/usb/gadget/omap_udc.c
--- 2.2/drivers/usb/gadget/omap_udc.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/usb/gadget/omap_udc.c	2006-12-22 01:57:07.000000000 +0100
@@ -2043,7 +2043,6 @@
 			// FIXME if otg, check:  driver->is_otg
 			|| driver->speed < USB_SPEED_FULL
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->setup)
 		return -EINVAL;
 
@@ -2087,9 +2086,11 @@
 		status = otg_set_peripheral(udc->transceiver, &udc->gadget);
 		if (status < 0) {
 			ERR("can't bind to transceiver\n");
-			driver->unbind (&udc->gadget);
-			udc->gadget.dev.driver = NULL;
-			udc->driver = NULL;
+			if (driver->unbind) {
+				driver->unbind (&udc->gadget);
+				udc->gadget.dev.driver = NULL;
+				udc->driver = NULL;
+			}
 			goto done;
 		}
 	} else {
@@ -2117,7 +2118,7 @@
 
 	if (!udc)
 		return -ENODEV;
-	if (!driver || driver != udc->driver)
+	if (!driver || driver != udc->driver || !driver->unbind)
 		return -EINVAL;
 
 	if (machine_is_omap_innovator() || machine_is_omap_osk())
@@ -2870,6 +2871,8 @@
 
 	if (!udc)
 		return -ENODEV;
+	if (udc->driver)
+		return -EBUSY;
 
 	udc->done = &done;
 
diff -ru 2.2/drivers/usb/gadget/pxa2xx_udc.c 3.4/drivers/usb/gadget/pxa2xx_udc.c
--- 2.2/drivers/usb/gadget/pxa2xx_udc.c	2006-12-07 02:52:14.000000000 +0100
+++ 3.4/drivers/usb/gadget/pxa2xx_udc.c	2006-12-22 01:57:07.000000000 +0100
@@ -1623,7 +1623,6 @@
 	if (!driver
 			|| driver->speed < USB_SPEED_FULL
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->disconnect
 			|| !driver->setup)
 		return -EINVAL;
@@ -1694,7 +1693,7 @@
 
 	if (!dev)
 		return -ENODEV;
-	if (!driver || driver != dev->driver)
+	if (!driver || driver != dev->driver || !driver->unbind)
 		return -EINVAL;
 
 	local_irq_disable();
@@ -2638,9 +2637,11 @@
 {
 	struct pxa2xx_udc *dev = platform_get_drvdata(pdev);
 
+	if (dev->driver)
+		return -EBUSY;
+
 	udc_disable(dev);
 	remove_proc_files();
-	usb_gadget_unregister_driver(dev->driver);
 
 	if (dev->got_irq) {
 		free_irq(IRQ_USB, dev);
diff -ru 2.2/drivers/usb/gadget/serial.c 3.4/drivers/usb/gadget/serial.c
--- 2.2/drivers/usb/gadget/serial.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/usb/gadget/serial.c	2006-12-22 01:57:07.000000000 +0100
@@ -296,7 +296,7 @@
 #endif /* CONFIG_USB_GADGET_DUALSPEED */
 	.function =		GS_LONG_NAME,
 	.bind =			gs_bind,
-	.unbind =		__exit_p(gs_unbind),
+	.unbind =		gs_unbind,
 	.setup =		gs_setup,
 	.disconnect =		gs_disconnect,
 	.driver = {
diff -ru 2.2/drivers/usb/host/ohci-at91.c 3.4/drivers/usb/host/ohci-at91.c
--- 2.2/drivers/usb/host/ohci-at91.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-at91.c	2006-12-22 01:57:07.000000000 +0100
@@ -187,7 +187,6 @@
 {
 	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	struct usb_device	*root = hcd->self.root_hub;
 	int			ret;
 
 	if ((ret = ohci_init(ohci)) < 0)
@@ -221,7 +220,7 @@
 	 */
 	.start =		ohci_at91_start,
 	.stop =			ohci_stop,
-	.shutdown = 		ohci_shutdown,
+	.shutdown =		ohci_shutdown,
 
 	/*
 	 * managing i/o requests and associated device resources
diff -ru 2.2/drivers/usb/host/ohci-au1xxx.c 3.4/drivers/usb/host/ohci-au1xxx.c
--- 2.2/drivers/usb/host/ohci-au1xxx.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-au1xxx.c	2006-12-22 01:57:07.000000000 +0100
@@ -269,7 +269,7 @@
 	 */
 	.start =		ohci_au1xxx_start,
 	.stop =			ohci_stop,
-	.shutdown = 		ohci_shutdown,
+	.shutdown =		ohci_shutdown,
 
 	/*
 	 * managing i/o requests and associated device resources
@@ -336,7 +336,7 @@
 static struct platform_driver ohci_hcd_au1xxx_driver = {
 	.probe		= ohci_hcd_au1xxx_drv_probe,
 	.remove		= ohci_hcd_au1xxx_drv_remove,
-	.shutdown 	= usb_hcd_platform_shutdown,
+	.shutdown	= usb_hcd_platform_shutdown,
 	/*.suspend	= ohci_hcd_au1xxx_drv_suspend, */
 	/*.resume	= ohci_hcd_au1xxx_drv_resume, */
 	.driver		= {
diff -ru 2.2/drivers/usb/host/ohci-dbg.c 3.4/drivers/usb/host/ohci-dbg.c
--- 2.2/drivers/usb/host/ohci-dbg.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/usb/host/ohci-dbg.c	2006-12-22 01:57:07.000000000 +0100
@@ -16,7 +16,7 @@
 	case PIPE_CONTROL:	temp = "ctrl"; break; \
 	case PIPE_BULK:		temp = "bulk"; break; \
 	case PIPE_INTERRUPT:	temp = "intr"; break; \
-	default: 		temp = "isoc"; break; \
+	default:		temp = "isoc"; break; \
 	}; temp;})
 #define pipestring(pipe) edstring(usb_pipetype(pipe))
 
@@ -205,13 +205,13 @@
 		(temp & RH_PS_PSSC) ? " PSSC" : "", \
 		(temp & RH_PS_PESC) ? " PESC" : "", \
 		(temp & RH_PS_CSC) ? " CSC" : "", \
- 		\
+		\
 		(temp & RH_PS_LSDA) ? " LSDA" : "", \
 		(temp & RH_PS_PPS) ? " PPS" : "", \
 		(temp & RH_PS_PRS) ? " PRS" : "", \
 		(temp & RH_PS_POCI) ? " POCI" : "", \
 		(temp & RH_PS_PSS) ? " PSS" : "", \
- 		\
+		\
 		(temp & RH_PS_PES) ? " PES" : "", \
 		(temp & RH_PS_CCS) ? " CCS" : "" \
 		);
@@ -563,7 +563,7 @@
 					(info & ED_SKIP) ? " K" : "",
 					(ed->hwHeadP &
 						cpu_to_hc32(ohci, ED_H)) ?
- 							" H" : "");
+							" H" : "");
 				size -= temp;
 				next += temp;
 
diff -ru 2.2/drivers/usb/host/ohci-ep93xx.c 3.4/drivers/usb/host/ohci-ep93xx.c
--- 2.2/drivers/usb/host/ohci-ep93xx.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-ep93xx.c	2006-12-22 01:57:07.000000000 +0100
@@ -204,7 +204,7 @@
 static struct platform_driver ohci_hcd_ep93xx_driver = {
 	.probe		= ohci_hcd_ep93xx_drv_probe,
 	.remove		= ohci_hcd_ep93xx_drv_remove,
-	.shutdown 	= usb_hcd_platform_shutdown,
+	.shutdown	= usb_hcd_platform_shutdown,
 #ifdef CONFIG_PM
 	.suspend	= ohci_hcd_ep93xx_drv_suspend,
 	.resume		= ohci_hcd_ep93xx_drv_resume,
diff -ru 2.2/drivers/usb/host/ohci.h 3.4/drivers/usb/host/ohci.h
--- 2.2/drivers/usb/host/ohci.h	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,9 +1,9 @@
 /*
  * OHCI HCD (Host Controller Driver) for USB.
- * 
+ *
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * 
+ *
  * This file is licenced under the GPL.
  */
 
@@ -14,7 +14,7 @@
  */
 typedef __u32 __bitwise __hc32;
 typedef __u16 __bitwise __hc16;
- 
+
 /*
  * OHCI Endpoint Descriptor (ED) ... holds TD queue
  * See OHCI spec, section 4.2
@@ -24,7 +24,7 @@
  */
 struct ed {
 	/* first fields are hardware-specified */
-	__hc32			hwINFO;       	/* endpoint config bitmap */
+	__hc32			hwINFO;      /* endpoint config bitmap */
 	/* info bits defined by hcd */
 #define ED_DEQUEUE	(1 << 27)
 	/* info bits defined by the hardware */
@@ -52,11 +52,11 @@
 	 * usually:  OPER --> UNLINK --> (IDLE | OPER) --> ...
 	 */
 	u8			state;		/* ED_{IDLE,UNLINK,OPER} */
-#define ED_IDLE 	0x00		/* NOT linked to HC */
-#define ED_UNLINK 	0x01		/* being unlinked from hc */
+#define ED_IDLE		0x00		/* NOT linked to HC */
+#define ED_UNLINK	0x01		/* being unlinked from hc */
 #define ED_OPER		0x02		/* IS linked to hc */
 
-	u8			type; 		/* PIPE_{BULK,...} */
+	u8			type;		/* PIPE_{BULK,...} */
 
 	/* periodic scheduling params (for intr and iso) */
 	u8			branch;
@@ -70,7 +70,7 @@
 
 #define ED_MASK	((u32)~0x0f)		/* strip hw status in low addr bits */
 
- 
+
 /*
  * OHCI Transfer Descriptor (TD) ... one per transfer segment
  * See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt)
@@ -107,22 +107,22 @@
 
 	/* (no hwINFO #defines yet for iso tds) */
 
-  	__hc32		hwCBP;		/* Current Buffer Pointer (or 0) */
-  	__hc32		hwNextTD;	/* Next TD Pointer */
-  	__hc32		hwBE;		/* Memory Buffer End Pointer */
+	__hc32		hwCBP;		/* Current Buffer Pointer (or 0) */
+	__hc32		hwNextTD;	/* Next TD Pointer */
+	__hc32		hwBE;		/* Memory Buffer End Pointer */
 
 	/* PSW is only for ISO.  Only 1 PSW entry is used, but on
 	 * big-endian PPC hardware that's the second entry.
 	 */
 #define MAXPSW	2
-  	__hc16		hwPSW [MAXPSW];
+	__hc16		hwPSW [MAXPSW];
 
 	/* rest are purely for the driver's use */
-  	__u8		index;
-  	struct ed	*ed;
-  	struct td	*td_hash;	/* dma-->td hashtable */
-  	struct td	*next_dl_td;
-  	struct urb	*urb;
+	__u8		index;
+	struct ed	*ed;
+	struct td	*td_hash;	/* dma-->td hashtable */
+	struct td	*next_dl_td;
+	struct urb	*urb;
 
 	dma_addr_t	td_dma;		/* addr of this TD */
 	dma_addr_t	data_dma;	/* addr of data it points to */
@@ -152,8 +152,8 @@
 #define TD_NOTACCESSED     0x0F
 
 
-/* map OHCI TD status codes (CC) to errno values */ 
-static const int cc_to_error [16] = { 
+/* map OHCI TD status codes (CC) to errno values */
+static const int cc_to_error [16] = {
 	/* No  Error  */               0,
 	/* CRC Error  */               -EILSEQ,
 	/* Bit Stuff  */               -EPROTO,
@@ -169,7 +169,7 @@
 	/* BufferOver */               -ECOMM,
 	/* BuffUnder  */               -ENOSR,
 	/* (for HCD)  */               -EALREADY,
-	/* (for HCD)  */               -EALREADY 
+	/* (for HCD)  */               -EALREADY
 };
 
 
@@ -182,7 +182,7 @@
 #define NUM_INTS 32
 	__hc32	int_table [NUM_INTS];	/* periodic schedule */
 
-	/* 
+	/*
 	 * OHCI defines u16 frame_no, followed by u16 zero pad.
 	 * Since some processors can't do 16 bit bus accesses,
 	 * portable access must be a 32 bits wide.
@@ -262,10 +262,10 @@
  * HcCommandStatus (cmdstatus) register masks
  */
 #define OHCI_HCR	(1 << 0)	/* host controller reset */
-#define OHCI_CLF  	(1 << 1)	/* control list filled */
-#define OHCI_BLF  	(1 << 2)	/* bulk list filled */
-#define OHCI_OCR  	(1 << 3)	/* ownership change request */
-#define OHCI_SOC  	(3 << 16)	/* scheduling overrun count */
+#define OHCI_CLF	(1 << 1)	/* control list filled */
+#define OHCI_BLF	(1 << 2)	/* bulk list filled */
+#define OHCI_OCR	(1 << 3)	/* ownership change request */
+#define OHCI_SOC	(3 << 16)	/* scheduling overrun count */
 
 /*
  * masks used with interrupt registers:
@@ -285,20 +285,20 @@
 
 
 /* OHCI ROOT HUB REGISTER MASKS */
- 
+
 /* roothub.portstatus [i] bits */
-#define RH_PS_CCS            0x00000001   	/* current connect status */
-#define RH_PS_PES            0x00000002   	/* port enable status*/
-#define RH_PS_PSS            0x00000004   	/* port suspend status */
-#define RH_PS_POCI           0x00000008   	/* port over current indicator */
-#define RH_PS_PRS            0x00000010  	/* port reset status */
-#define RH_PS_PPS            0x00000100   	/* port power status */
-#define RH_PS_LSDA           0x00000200    	/* low speed device attached */
-#define RH_PS_CSC            0x00010000 	/* connect status change */
-#define RH_PS_PESC           0x00020000   	/* port enable status change */
-#define RH_PS_PSSC           0x00040000    	/* port suspend status change */
-#define RH_PS_OCIC           0x00080000    	/* over current indicator change */
-#define RH_PS_PRSC           0x00100000   	/* port reset status change */
+#define RH_PS_CCS            0x00000001		/* current connect status */
+#define RH_PS_PES            0x00000002		/* port enable status*/
+#define RH_PS_PSS            0x00000004		/* port suspend status */
+#define RH_PS_POCI           0x00000008		/* port over current indicator */
+#define RH_PS_PRS            0x00000010		/* port reset status */
+#define RH_PS_PPS            0x00000100		/* port power status */
+#define RH_PS_LSDA           0x00000200		/* low speed device attached */
+#define RH_PS_CSC            0x00010000		/* connect status change */
+#define RH_PS_PESC           0x00020000		/* port enable status change */
+#define RH_PS_PSSC           0x00040000		/* port suspend status change */
+#define RH_PS_OCIC           0x00080000		/* over current indicator change */
+#define RH_PS_PRSC           0x00100000		/* port reset status change */
 
 /* roothub.status bits */
 #define RH_HS_LPS	     0x00000001		/* local power status */
@@ -333,7 +333,7 @@
 } urb_priv_t;
 
 #define TD_HASH_SIZE    64    /* power'o'two */
-// sizeof (struct td) ~= 64 == 2^6 ... 
+// sizeof (struct td) ~= 64 == 2^6 ...
 #define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE)
 
 
@@ -364,11 +364,11 @@
 
 	struct ed		*ed_bulktail;		/* last in bulk list */
 	struct ed		*ed_controltail;	/* last in ctrl list */
- 	struct ed		*periodic [NUM_INTS];	/* shadow int_table */
+	struct ed		*periodic [NUM_INTS];	/* shadow int_table */
 
 	/*
 	 * OTG controllers and transceivers need software interaction;
-	 * other external transceivers should be software-transparent 
+	 * other external transceivers should be software-transparent
 	 */
 	struct otg_transceiver	*transceiver;
 
@@ -385,7 +385,7 @@
 	 */
 	int			num_ports;
 	int			load [NUM_INTS];
-	u32 			hc_control;	/* copy of hc control reg */
+	u32			hc_control;	/* copy of hc control reg */
 	unsigned long		next_statechange;	/* suspend/resume */
 	u32			fminterval;		/* saved register */
 	unsigned		autostop:1;	/* rh auto stopping/stopped */
@@ -598,11 +598,11 @@
 }
 
 #define	FI			0x2edf		/* 12000 bits per frame (-1) */
-#define	FSMP(fi) 		(0x7fff & ((6 * ((fi) - 210)) / 7))
+#define	FSMP(fi)		(0x7fff & ((6 * ((fi) - 210)) / 7))
 #define	FIT			(1 << 31)
 #define LSTHRESH		0x628		/* lowspeed bit threshold */
 
-static void periodic_reinit (struct ohci_hcd *ohci)
+static inline void periodic_reinit (struct ohci_hcd *ohci)
 {
 	u32	fi = ohci->fminterval & 0x03fff;
 	u32	fit = ohci_readl(ohci, &ohci->regs->fminterval) & FIT;
@@ -626,11 +626,11 @@
 			temp = ohci_readl (hc, &hc->regs->roothub.register); \
 	temp; })
 
-static u32 roothub_a (struct ohci_hcd *hc)
+static inline u32 roothub_a (struct ohci_hcd *hc)
 	{ return read_roothub (hc, a, 0xfc0fe000); }
 static inline u32 roothub_b (struct ohci_hcd *hc)
 	{ return ohci_readl (hc, &hc->regs->roothub.b); }
 static inline u32 roothub_status (struct ohci_hcd *hc)
 	{ return ohci_readl (hc, &hc->regs->roothub.status); }
-static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
+static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i)
 	{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }
diff -ru 2.2/drivers/usb/host/ohci-hcd.c 3.4/drivers/usb/host/ohci-hcd.c
--- 2.2/drivers/usb/host/ohci-hcd.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/usb/host/ohci-hcd.c	2006-12-22 01:57:07.000000000 +0100
@@ -3,77 +3,21 @@
  *
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
- * 
+ *
  * [ Initialisation is based on Linus'  ]
  * [ uhci code and gregs ohci fragments ]
  * [ (C) Copyright 1999 Linus Torvalds  ]
  * [ (C) Copyright 1999 Gregory P. Smith]
- * 
- * 
+ *
+ *
  * OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller
  * interfaces (though some non-x86 Intel chips use it).  It supports
  * smarter hardware than UHCI.  A download link for the spec available
  * through the http://www.usb.org website.
  *
- * History:
- * 
- * 2004/03/24 LH7A404 support (Durgesh Pattamatta & Marc Singer)
- * 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net)
- * 2003/02/24 show registers in sysfs (Kevin Brosius)
- *
- * 2002/09/03 get rid of ed hashtables, rework periodic scheduling and
- * 	bandwidth accounting; if debugging, show schedules in driverfs
- * 2002/07/19 fixes to management of ED and schedule state.
- * 2002/06/09 SA-1111 support (Christopher Hoover)
- * 2002/06/01 remember frame when HC won't see EDs any more; use that info
- *	to fix urb unlink races caused by interrupt latency assumptions;
- *	minor ED field and function naming updates
- * 2002/01/18 package as a patch for 2.5.3; this should match the
- *	2.4.17 kernel modulo some bugs being fixed.
- *
- * 2001/10/18 merge pmac cleanup (Benjamin Herrenschmidt) and bugfixes
- *	from post-2.4.5 patches.
- * 2001/09/20 URB_ZERO_PACKET support; hcca_dma portability, OPTi warning
- * 2001/09/07 match PCI PM changes, errnos from Linus' tree
- * 2001/05/05 fork 2.4.5 version into "hcd" framework, cleanup, simplify;
- *	pbook pci quirks gone (please fix pbook pci sw!) (db)
- *
- * 2001/04/08 Identify version on module load (gb)
- * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam);
- 	pci_map_single (db)
- * 2001/03/21 td and dev/ed allocation uses new pci_pool API (db)
- * 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam)
- *
- * 2000/09/26 fixed races in removing the private portion of the urb
- * 2000/09/07 disable bulk and control lists when unlinking the last
- *	endpoint descriptor in order to avoid unrecoverable errors on
- *	the Lucent chips. (rwc@sgi)
- * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some
- *	urb unlink probs, indentation fixes
- * 2000/08/11 various oops fixes mostly affecting iso and cleanup from
- *	device unplugs.
- * 2000/06/28 use PCI hotplug framework, for better power management
- *	and for Cardbus support (David Brownell)
- * 2000/earlier:  fixes for NEC/Lucent chips; suspend/resume handling
- *	when the controller loses power; handle UE; cleanup; ...
- *
- * v5.2 1999/12/07 URB 3rd preview, 
- * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi)
- * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume 
- * 	i386: HUB, Keyboard, Mouse, Printer 
- *
- * v4.3 1999/10/27 multiple HCs, bulk_request
- * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes
- * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl.
- * v4.0 1999/08/18 
- * v3.0 1999/06/25 
- * v2.1 1999/05/09  code clean up
- * v2.0 1999/05/04 
- * v1.0 1999/04/27 initial release
- *
  * This file is licenced under the GPL.
  */
- 
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
@@ -89,7 +33,7 @@
 #include <linux/list.h>
 #include <linux/usb.h>
 #include <linux/usb/otg.h>
-#include <linux/dma-mapping.h> 
+#include <linux/dma-mapping.h>
 #include <linux/dmapool.h>
 #include <linux/reboot.h>
 
@@ -183,11 +127,11 @@
 	int		i, size = 0;
 	unsigned long	flags;
 	int		retval = 0;
-	
+
 #ifdef OHCI_VERBOSE_DEBUG
 	urb_print (urb, "SUB", usb_pipein (pipe));
 #endif
-	
+
 	/* every endpoint has a ed, locate and maybe (re)initialize it */
 	if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval)))
 		return -ENOMEM;
@@ -232,7 +176,7 @@
 	memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *));
 	INIT_LIST_HEAD (&urb_priv->pending);
 	urb_priv->length = size;
-	urb_priv->ed = ed;	
+	urb_priv->ed = ed;
 
 	/* allocate the TDs (deferring hash chain updates) */
 	for (i = 0; i < size; i++) {
@@ -242,7 +186,7 @@
 			urb_free_priv (ohci, urb_priv);
 			return -ENOMEM;
 		}
-	}	
+	}
 
 	spin_lock_irqsave (&ohci->lock, flags);
 
@@ -313,13 +257,13 @@
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
 	unsigned long		flags;
-	
+
 #ifdef OHCI_VERBOSE_DEBUG
 	urb_print (urb, "UNLINK", 1);
-#endif		  
+#endif
 
 	spin_lock_irqsave (&ohci->lock, flags);
- 	if (HC_IS_RUNNING(hcd->state)) {
+	if (HC_IS_RUNNING(hcd->state)) {
 		urb_priv_t  *urb_priv;
 
 		/* Unless an IRQ completed the unlink while it was being
@@ -512,11 +456,11 @@
 
 /* Start an OHCI controller, set the BUS operational
  * resets USB and controller
- * enable interrupts 
+ * enable interrupts
  */
 static int ohci_run (struct ohci_hcd *ohci)
 {
-  	u32			mask, temp;
+	u32			mask, temp;
 	int			first = ohci->fminterval == 0;
 	struct usb_hcd		*hcd = ohci_to_hcd(ohci);
 
@@ -534,7 +478,7 @@
 		/* also: power/overcurrent flags in roothub.a */
 	}
 
-  	/* Reset USB nearly "by the book".  RemoteWakeupConnected was
+	/* Reset USB nearly "by the book".  RemoteWakeupConnected was
 	 * saved if boot firmware (BIOS/SMM/...) told us it's connected,
 	 * or if bus glue did the same (e.g. for PCI add-in cards with
 	 * PCI PM support).
@@ -765,9 +709,9 @@
 		dl_done_list (ohci);
 		spin_unlock (&ohci->lock);
 		if (HC_IS_RUNNING(hcd->state))
-			ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrenable); 
+			ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrenable);
 	}
-  
+
 	/* could track INTR_SO to reduce available PCI/... bandwidth */
 
 	/* handle any pending URB/ED unlinks, leaving INTR_SF enabled
@@ -778,12 +722,12 @@
 		finish_unlinks (ohci, ohci_frame_no(ohci));
 	if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
 			&& HC_IS_RUNNING(hcd->state))
-		ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable);	
+		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);	
+		ohci_writel (ohci, OHCI_INTR_MIE, &regs->intrenable);
 		// flush those writes
 		(void) ohci_readl (ohci, &ohci->regs->control);
 	}
@@ -794,7 +738,7 @@
 /*-------------------------------------------------------------------------*/
 
 static void ohci_stop (struct usb_hcd *hcd)
-{	
+{
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
 
 	ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n",
@@ -812,8 +756,8 @@
 	remove_debug_files (ohci);
 	ohci_mem_cleanup (ohci);
 	if (ohci->hcca) {
-		dma_free_coherent (hcd->self.controller, 
-				sizeof *ohci->hcca, 
+		dma_free_coherent (hcd->self.controller,
+				sizeof *ohci->hcca,
 				ohci->hcca, ohci->hcca_dma);
 		ohci->hcca = NULL;
 		ohci->hcca_dma = 0;
@@ -836,7 +780,7 @@
 	 * recycle any "live" eds/tds (and urbs) right away.
 	 * later, khubd disconnect processing will recycle the other state,
 	 * (either as disconnect/reconnect, or maybe someday as a reset).
-	 */ 
+	 */
 	spin_lock_irq(&ohci->lock);
 	disable (ohci);
 	usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub);
@@ -875,11 +819,11 @@
 	/* empty the interrupt branches */
 	for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0;
 	for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0;
-	
+
 	/* no EDs to remove */
 	ohci->ed_rm_list = NULL;
 
-	/* empty control and bulk lists */	 
+	/* empty control and bulk lists */
 	ohci->ed_controltail = NULL;
 	ohci->ed_bulktail    = NULL;
 
@@ -941,6 +885,10 @@
 #include "ohci-au1xxx.c"
 #endif
 
+#ifdef CONFIG_PNX8550
+#include "ohci-pnx8550.c"
+#endif
+
 #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC
 #include "ohci-ppc-soc.c"
 #endif
diff -ru 2.2/drivers/usb/host/ohci-hub.c 3.4/drivers/usb/host/ohci-hub.c
--- 2.2/drivers/usb/host/ohci-hub.c	2006-12-07 02:52:14.000000000 +0100
+++ 3.4/drivers/usb/host/ohci-hub.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,9 +1,9 @@
 /*
  * OHCI HCD (Host Controller Driver) for USB.
- * 
+ *
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
- * 
+ *
  * This file is licenced under GPL
  */
 
@@ -23,13 +23,13 @@
 		(temp & RH_PS_PSSC) ? " PSSC" : "", \
 		(temp & RH_PS_PESC) ? " PESC" : "", \
 		(temp & RH_PS_CSC) ? " CSC" : "", \
- 		\
+		\
 		(temp & RH_PS_LSDA) ? " LSDA" : "", \
 		(temp & RH_PS_PPS) ? " PPS" : "", \
 		(temp & RH_PS_PRS) ? " PRS" : "", \
 		(temp & RH_PS_POCI) ? " POCI" : "", \
 		(temp & RH_PS_PSS) ? " PSS" : "", \
- 		\
+		\
 		(temp & RH_PS_PES) ? " PES" : "", \
 		(temp & RH_PS_CCS) ? " CCS" : "" \
 		);
@@ -484,7 +484,7 @@
 	temp = 0;
 	if (rh & RH_A_NPS)		/* no power switching? */
 	    temp |= 0x0002;
-	if (rh & RH_A_PSM) 		/* per-port power switching? */
+	if (rh & RH_A_PSM)		/* per-port power switching? */
 	    temp |= 0x0001;
 	if (rh & RH_A_NOCP)		/* no overcurrent reporting? */
 	    temp |= 0x0010;
@@ -555,7 +555,7 @@
 #define tick_before(t1,t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0)
 
 /* called from some task, normally khubd */
-static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port)
+static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)
 {
 	__hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port];
 	u32	temp;
@@ -570,10 +570,13 @@
 		/* spin until any current reset finishes */
 		for (;;) {
 			temp = ohci_readl (ohci, portstat);
+			/* handle e.g. CardBus eject */
+			if (temp == ~(u32)0)
+				return -ESHUTDOWN;
 			if (!(temp & RH_PS_PRS))
 				break;
 			udelay (500);
-		} 
+		}
 
 		if (!(temp & RH_PS_CCS))
 			break;
@@ -586,6 +589,8 @@
 		now = ohci_readl(ohci, &ohci->regs->fmnumber);
 	} while (tick_before(now, reset_done));
 	/* caller synchronizes using PRSC */
+
+	return 0;
 }
 
 static int ohci_hub_control (
@@ -702,7 +707,7 @@
 				&ohci->regs->roothub.portstatus [wIndex]);
 			break;
 		case USB_PORT_FEAT_RESET:
-			root_port_reset (ohci, wIndex);
+			retval = root_port_reset (ohci, wIndex);
 			break;
 		default:
 			goto error;
diff -ru 2.2/drivers/usb/host/ohci-lh7a404.c 3.4/drivers/usb/host/ohci-lh7a404.c
--- 2.2/drivers/usb/host/ohci-lh7a404.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-lh7a404.c	2006-12-22 01:57:07.000000000 +0100
@@ -38,7 +38,7 @@
 	CSC_PWRCNT |= CSC_PWRCNT_USBH_EN; /* Enable clock */
 	udelay(1000);
 	USBH_CMDSTATUS = OHCI_HCR;
-	
+
 	printk(KERN_DEBUG __FILE__
 		   ": Clock to USB host has been enabled \n");
 }
@@ -89,7 +89,7 @@
 		retval = -EBUSY;
 		goto err1;
 	}
-	
+
 	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
 	if (!hcd->regs) {
 		pr_debug("ioremap failed");
@@ -174,7 +174,7 @@
 	 */
 	.start =		ohci_lh7a404_start,
 	.stop =			ohci_stop,
-	.shutdown = 		ohci_shutdown,
+	.shutdown =		ohci_shutdown,
 
 	/*
 	 * managing i/o requests and associated device resources
@@ -242,7 +242,7 @@
 static struct platform_driver ohci_hcd_lh7a404_driver = {
 	.probe		= ohci_hcd_lh7a404_drv_probe,
 	.remove		= ohci_hcd_lh7a404_drv_remove,
-	.shutdown 	= usb_hcd_platform_shutdown,
+	.shutdown	= usb_hcd_platform_shutdown,
 	/*.suspend	= ohci_hcd_lh7a404_drv_suspend, */
 	/*.resume	= ohci_hcd_lh7a404_drv_resume, */
 	.driver		= {
diff -ru 2.2/drivers/usb/host/ohci-mem.c 3.4/drivers/usb/host/ohci-mem.c
--- 2.2/drivers/usb/host/ohci-mem.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-mem.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,24 +1,24 @@
 /*
  * OHCI HCD (Host Controller Driver) for USB.
- * 
+ *
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * 
+ *
  * This file is licenced under the GPL.
  */
 
 /*-------------------------------------------------------------------------*/
 
 /*
- * There's basically three types of memory:
+ * OHCI deals with three types of memory:
  *	- data used only by the HCD ... kmalloc is fine
  *	- async and periodic schedules, shared by HC and HCD ... these
  *	  need to use dma_pool or dma_alloc_coherent
  *	- driver buffers, read/written by HC ... the hcd glue or the
  *	  device driver provides us with dma addresses
  *
- * There's also PCI "register" data, which is memory mapped.
- * No memory seen by this driver is pagable.
+ * There's also "register" data, which is memory mapped.
+ * No memory seen by this driver (or any HCD) may be paged out.
  */
 
 /*-------------------------------------------------------------------------*/
diff -ru 2.2/drivers/usb/host/ohci-omap.c 3.4/drivers/usb/host/ohci-omap.c
--- 2.2/drivers/usb/host/ohci-omap.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-omap.c	2006-12-22 01:57:07.000000000 +0100
@@ -447,7 +447,7 @@
 	.reset =		ohci_omap_init,
 	.start =		ohci_omap_start,
 	.stop =			ohci_omap_stop,
-	.shutdown = 		ohci_shutdown,
+	.shutdown =		ohci_shutdown,
 
 	/*
 	 * managing i/o requests and associated device resources
@@ -533,7 +533,7 @@
 static struct platform_driver ohci_hcd_omap_driver = {
 	.probe		= ohci_hcd_omap_drv_probe,
 	.remove		= ohci_hcd_omap_drv_remove,
-	.shutdown 	= usb_hcd_platform_shutdown,
+	.shutdown	= usb_hcd_platform_shutdown,
 #ifdef	CONFIG_PM
 	.suspend	= ohci_omap_suspend,
 	.resume		= ohci_omap_resume,
diff -ru 2.2/drivers/usb/host/ohci-pci.c 3.4/drivers/usb/host/ohci-pci.c
--- 2.2/drivers/usb/host/ohci-pci.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-pci.c	2006-12-22 01:57:07.000000000 +0100
@@ -3,17 +3,17 @@
  *
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * 
+ *
  * [ Initialisation is based on Linus'  ]
  * [ uhci code and gregs ohci fragments ]
  * [ (C) Copyright 1999 Linus Torvalds  ]
  * [ (C) Copyright 1999 Gregory P. Smith]
- * 
+ *
  * PCI Bus Glue
  *
  * This file is licenced under the GPL.
  */
- 
+
 #ifndef CONFIG_PCI
 #error "This file is PCI bus glue.  CONFIG_PCI must be defined."
 #endif
@@ -83,7 +83,7 @@
 			pci_dev_put(b);
 		}
 
-		/* Check for Compaq's ZFMicro chipset, which needs short 
+		/* Check for Compaq's ZFMicro chipset, which needs short
 		 * delays before control or bulk queues get re-activated
 		 * in finish_unlinks()
 		 */
@@ -238,8 +238,8 @@
 	.shutdown =	usb_hcd_pci_shutdown,
 };
 
- 
-static int __init ohci_hcd_pci_init (void) 
+
+static int __init ohci_hcd_pci_init (void)
 {
 	printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name);
 	if (usb_disabled())
@@ -253,8 +253,8 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void __exit ohci_hcd_pci_cleanup (void) 
-{	
+static void __exit ohci_hcd_pci_cleanup (void)
+{
 	pci_unregister_driver (&ohci_pci_driver);
 }
 module_exit (ohci_hcd_pci_cleanup);
diff -ru 2.2/drivers/usb/host/ohci-pnx4008.c 3.4/drivers/usb/host/ohci-pnx4008.c
--- 2.2/drivers/usb/host/ohci-pnx4008.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/usb/host/ohci-pnx4008.c	2006-12-22 01:57:07.000000000 +0100
@@ -4,7 +4,7 @@
  * driver for Philips PNX4008 USB Host
  *
  * Authors: Dmitry Chigirev <source@mvista.com>
- * 	    Vitaly Wool <vitalywool@gmail.com>
+ *	    Vitaly Wool <vitalywool@gmail.com>
  *
  * register initialization is based on code examples provided by Philips
  * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
@@ -29,7 +29,7 @@
 #include <asm/arch/irqs.h>
 #include <asm/arch/gpio.h>
 
-#define USB_CTRL 	IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64)
+#define USB_CTRL	IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64)
 
 /* USB_CTRL bit defines */
 #define USB_SLAVE_HCLK_EN	(1 << 24)
Only in 3.4/drivers/usb/host: ohci-pnx8550.c
diff -ru 2.2/drivers/usb/host/ohci-ppc-soc.c 3.4/drivers/usb/host/ohci-ppc-soc.c
--- 2.2/drivers/usb/host/ohci-ppc-soc.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-ppc-soc.c	2006-12-22 01:57:07.000000000 +0100
@@ -5,7 +5,7 @@
  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
  * (C) Copyright 2002 Hewlett-Packard Company
  * (C) Copyright 2003-2005 MontaVista Software Inc.
- * 
+ *
  * Bus Glue for PPC On-Chip OHCI driver
  * Tested on Freescale MPC5200 and IBM STB04xxx
  *
@@ -85,7 +85,7 @@
  err2:
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  err1:
- 	usb_put_hcd(hcd);
+	usb_put_hcd(hcd);
 	return retval;
 }
 
@@ -148,7 +148,7 @@
 	 */
 	.start =		ohci_ppc_soc_start,
 	.stop =			ohci_stop,
-	.shutdown = 		ohci_shutdown,
+	.shutdown =		ohci_shutdown,
 
 	/*
 	 * managing i/o requests and associated device resources
@@ -197,7 +197,7 @@
 static struct platform_driver ohci_hcd_ppc_soc_driver = {
 	.probe		= ohci_hcd_ppc_soc_drv_probe,
 	.remove		= ohci_hcd_ppc_soc_drv_remove,
-	.shutdown 	= usb_hcd_platform_shutdown,
+	.shutdown	= usb_hcd_platform_shutdown,
 #ifdef	CONFIG_PM
 	/*.suspend	= ohci_hcd_ppc_soc_drv_suspend,*/
 	/*.resume	= ohci_hcd_ppc_soc_drv_resume,*/
diff -ru 2.2/drivers/usb/host/ohci-pxa27x.c 3.4/drivers/usb/host/ohci-pxa27x.c
--- 2.2/drivers/usb/host/ohci-pxa27x.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-pxa27x.c	2006-12-22 01:57:07.000000000 +0100
@@ -47,7 +47,7 @@
 	switch ( mode ) {
 	case PMM_NPS_MODE:
 		UHCRHDA |= RH_A_NPS;
-		break; 
+		break;
 	case PMM_GLOBAL_MODE:
 		UHCRHDA &= ~(RH_A_NPS & RH_A_PSM);
 		break;
@@ -60,7 +60,7 @@
 		break;
 	default:
 		printk( KERN_ERR
-			"Invalid mode %d, set to non-power switch mode.\n", 
+			"Invalid mode %d, set to non-power switch mode.\n",
 			mode );
 
 		UHCRHDA |= RH_A_NPS;
@@ -270,7 +270,7 @@
 	 */
 	.start =		ohci_pxa27x_start,
 	.stop =			ohci_stop,
-	.shutdown = 		ohci_shutdown,
+	.shutdown =		ohci_shutdown,
 
 	/*
 	 * managing i/o requests and associated device resources
@@ -359,9 +359,9 @@
 static struct platform_driver ohci_hcd_pxa27x_driver = {
 	.probe		= ohci_hcd_pxa27x_drv_probe,
 	.remove		= ohci_hcd_pxa27x_drv_remove,
-	.shutdown 	= usb_hcd_platform_shutdown,
+	.shutdown	= usb_hcd_platform_shutdown,
 #ifdef CONFIG_PM
-	.suspend	= ohci_hcd_pxa27x_drv_suspend, 
+	.suspend	= ohci_hcd_pxa27x_drv_suspend,
 	.resume		= ohci_hcd_pxa27x_drv_resume,
 #endif
 	.driver		= {
diff -ru 2.2/drivers/usb/host/ohci-q.c 3.4/drivers/usb/host/ohci-q.c
--- 2.2/drivers/usb/host/ohci-q.c	2006-10-09 14:52:10.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-q.c	2006-12-22 01:57:07.000000000 +0100
@@ -1,9 +1,9 @@
 /*
  * OHCI HCD (Host Controller Driver) for USB.
- * 
+ *
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * 
+ *
  * This file is licenced under the GPL.
  */
 
@@ -89,7 +89,7 @@
 
 /*-------------------------------------------------------------------------*
  * ED handling functions
- *-------------------------------------------------------------------------*/  
+ *-------------------------------------------------------------------------*/
 
 /* search for the right schedule branch to use for a periodic ed.
  * does some load balancing; returns the branch, or negative errno.
@@ -107,7 +107,6 @@
 	 */
 	for (i = 0; i < interval ; i++) {
 		if (branch < 0 || ohci->load [branch] > ohci->load [i]) {
-#if 1	/* CONFIG_USB_BANDWIDTH */
 			int	j;
 
 			/* usb 1.1 says 90% of one frame */
@@ -117,8 +116,7 @@
 			}
 			if (j < NUM_INTS)
 				continue;
-#endif
-			branch = i; 
+			branch = i;
 		}
 	}
 	return branch;
@@ -171,7 +169,7 @@
 /* link an ed into one of the HC chains */
 
 static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
-{	 
+{
 	int	branch;
 
 	if (ohci_to_hcd(ohci)->state == HC_STATE_QUIESCING)
@@ -248,7 +246,7 @@
 		}
 		ed->branch = branch;
 		periodic_link (ohci, ed);
-	}	 	
+	}
 
 	/* the HC may not see the schedule updates yet, but if it does
 	 * then they'll be properly ordered.
@@ -277,7 +275,7 @@
 			*prev = ed->ed_next;
 		}
 		ohci->load [i] -= ed->load;
-	}	
+	}
 	ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval;
 
 	ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n",
@@ -285,7 +283,7 @@
 		ed, ed->branch, ed->load, ed->interval);
 }
 
-/* unlink an ed from one of the HC chains. 
+/* unlink an ed from one of the HC chains.
  * just the link to the ed is unlinked.
  * the link from the ed still points to another operational ed or 0
  * so the HC can eventually finish the processing of the unlinked ed
@@ -307,7 +305,7 @@
  * When finish_unlinks() runs later, after SOF interrupt, it will often
  * complete one or more URB unlinks before making that state change.
  */
-static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed) 
+static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
 {
 	ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP);
 	wmb ();
@@ -397,7 +395,7 @@
 	unsigned int		pipe,
 	int			interval
 ) {
-	struct ed		*ed; 
+	struct ed		*ed;
 	unsigned long		flags;
 
 	spin_lock_irqsave (&ohci->lock, flags);
@@ -413,9 +411,9 @@
 			goto done;
 		}
 
-  		/* dummy td; end of td list for ed */
+		/* dummy td; end of td list for ed */
 		td = td_alloc (ohci, GFP_ATOMIC);
- 		if (!td) {
+		if (!td) {
 			/* out of memory */
 			ed_free (ohci, ed);
 			ed = NULL;
@@ -462,7 +460,7 @@
 
 done:
 	spin_unlock_irqrestore (&ohci->lock, flags);
-	return ed; 
+	return ed;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -474,7 +472,7 @@
  * and that ed->state is ED_OPER
  */
 static void start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed)
-{    
+{
 	ed->hwINFO |= cpu_to_hc32 (ohci, ED_DEQUEUE);
 	ed_deschedule (ohci, ed);
 
@@ -541,7 +539,7 @@
 	td->ed = urb_priv->ed;
 	td->next_dl_td = NULL;
 	td->index = index;
-	td->urb = urb; 
+	td->urb = urb;
 	td->data_dma = data;
 	if (!len)
 		data = 0;
@@ -553,8 +551,8 @@
 						(data & 0x0FFF) | 0xE000);
 		td->ed->last_iso = info & 0xffff;
 	} else {
-		td->hwCBP = cpu_to_hc32 (ohci, data); 
-	}			
+		td->hwCBP = cpu_to_hc32 (ohci, data);
+	}
 	if (data)
 		td->hwBE = cpu_to_hc32 (ohci, data + len - 1);
 	else
@@ -597,7 +595,7 @@
 	 * use the device toggle bits for resetting, and rely on the fact
 	 * that resetting toggle is meaningless if the endpoint is active.
 	 */
-  	if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) {
+	if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) {
 		usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe),
 			is_out, 1);
 		urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C);
@@ -721,16 +719,16 @@
 	list_del (&td->td_list);
 
 	/* ISO ... drivers see per-TD length/status */
-  	if (tdINFO & TD_ISO) {
- 		u16	tdPSW = ohci_hwPSW (ohci, td, 0);
+	if (tdINFO & TD_ISO) {
+		u16	tdPSW = ohci_hwPSW (ohci, td, 0);
 		int	dlen = 0;
 
 		/* NOTE:  assumes FC in tdINFO == 0, and that
 		 * only the first of 0..MAXPSW psws is used.
 		 */
 
- 		cc = (tdPSW >> 12) & 0xF;
-  		if (tdINFO & TD_CC)	/* hc didn't touch? */
+		cc = (tdPSW >> 12) & 0xF;
+		if (tdINFO & TD_CC)	/* hc didn't touch? */
 			return;
 
 		if (usb_pipeout (urb->pipe))
@@ -758,7 +756,7 @@
 		int	type = usb_pipetype (urb->pipe);
 		u32	tdBE = hc32_to_cpup (ohci, &td->hwBE);
 
-  		cc = TD_CC_GET (tdINFO);
+		cc = TD_CC_GET (tdINFO);
 
 		/* update packet status if needed (short is normally ok) */
 		if (cc == TD_DATAUNDERRUN
@@ -787,7 +785,7 @@
 				urb, td, 1 + td->index, cc,
 				urb->actual_length,
 				urb->transfer_buffer_length);
-  	}
+	}
 }
 
 /*-------------------------------------------------------------------------*/
@@ -795,7 +793,7 @@
 static inline struct td *
 ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
 {
-  	struct urb		*urb = td->urb;
+	struct urb		*urb = td->urb;
 	struct ed		*ed = td->ed;
 	struct list_head	*tmp = td->td_list.next;
 	__hc32			toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C);
@@ -805,7 +803,7 @@
 	 */
 	ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP);
 	wmb ();
-	ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); 
+	ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H);
 
 	/* put any later tds from this urb onto the donelist, after 'td',
 	 * order won't matter here: no errors, and nothing was transferred.
@@ -833,7 +831,7 @@
 		info &= ~cpu_to_hc32 (ohci, TD_CC);
 		next->hwINFO = info;
 
-		next->next_dl_td = rev;	
+		next->next_dl_td = rev;
 		rev = next;
 
 		ed->hwHeadP = next->hwNextTD | toggle;
@@ -881,8 +879,8 @@
 	/* get TD from hc's singly linked list, and
 	 * prepend to ours.  ed->td_list changes later.
 	 */
-	while (td_dma) {		
-	    	int		cc;
+	while (td_dma) {
+		int		cc;
 
 		td = dma_to_td (ohci, td_dma);
 		if (!td) {
@@ -901,10 +899,10 @@
 				&& (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H)))
 			td_rev = ed_halted (ohci, td, cc, td_rev);
 
-		td->next_dl_td = td_rev;	
+		td->next_dl_td = td_rev;
 		td_rev = td;
 		td_dma = hc32_to_cpup (ohci, &td->hwNextTD);
-	}	
+	}
 	return td_rev;
 }
 
@@ -1013,9 +1011,9 @@
 
 		if (modified)
 			goto rescan_all;
-   	}
+	}
 
-	/* maybe reenable control and bulk lists */ 
+	/* maybe reenable control and bulk lists */
 	if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state)
 			&& ohci_to_hcd(ohci)->state != HC_STATE_QUIESCING
 			&& !ohci->ed_rm_list) {
@@ -1041,20 +1039,20 @@
 					&ohci->regs->ed_bulkcurrent);
 			}
 		}
-		
+
 		/* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */
 		if (control) {
 			ohci->hc_control |= control;
 			if (ohci->flags & OHCI_QUIRK_ZFMICRO)
 				mdelay(1);
- 			ohci_writel (ohci, ohci->hc_control,
-					&ohci->regs->control);   
- 		}
+			ohci_writel (ohci, ohci->hc_control,
+					&ohci->regs->control);
+		}
 		if (command) {
 			if (ohci->flags & OHCI_QUIRK_ZFMICRO)
 				mdelay(1);
-			ohci_writel (ohci, command, &ohci->regs->cmdstatus);   
-	 	}
+			ohci_writel (ohci, command, &ohci->regs->cmdstatus);
+		}
 	}
 }
 
@@ -1074,19 +1072,19 @@
 {
 	struct td	*td = dl_reverse_done_list (ohci);
 
-  	while (td) {
+	while (td) {
 		struct td	*td_next = td->next_dl_td;
 		struct urb	*urb = td->urb;
 		urb_priv_t	*urb_priv = urb->hcpriv;
 		struct ed	*ed = td->ed;
 
 		/* update URB's length and status from TD */
-   		td_done (ohci, urb, td);
-  		urb_priv->td_cnt++;
+		td_done (ohci, urb, td);
+		urb_priv->td_cnt++;
 
 		/* If all this urb's TDs are done, call complete() */
-  		if (urb_priv->td_cnt == urb_priv->length)
-  			finish_urb (ohci, urb);
+		if (urb_priv->td_cnt == urb_priv->length)
+			finish_urb (ohci, urb);
 
 		/* clean schedule:  unlink EDs that are no longer busy */
 		if (list_empty (&ed->td_list)) {
@@ -1094,25 +1092,26 @@
 				start_ed_unlink (ohci, ed);
 
 		/* ... reenabling halted EDs only after fault cleanup */
-		} else if ((ed->hwINFO & cpu_to_hc32 (ohci, ED_SKIP | ED_DEQUEUE))
+		} else if ((ed->hwINFO & cpu_to_hc32 (ohci,
+						ED_SKIP | ED_DEQUEUE))
 					== cpu_to_hc32 (ohci, ED_SKIP)) {
 			td = list_entry (ed->td_list.next, struct td, td_list);
- 			if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) {
+			if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) {
 				ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP);
 				/* ... hc may need waking-up */
 				switch (ed->type) {
 				case PIPE_CONTROL:
 					ohci_writel (ohci, OHCI_CLF,
-						&ohci->regs->cmdstatus);   
+						&ohci->regs->cmdstatus);
 					break;
 				case PIPE_BULK:
 					ohci_writel (ohci, OHCI_BLF,
-						&ohci->regs->cmdstatus);   
+						&ohci->regs->cmdstatus);
 					break;
 				}
 			}
 		}
 
-    		td = td_next;
-  	}  
+		td = td_next;
+	}
 }
diff -ru 2.2/drivers/usb/host/ohci-s3c2410.c 3.4/drivers/usb/host/ohci-s3c2410.c
--- 2.2/drivers/usb/host/ohci-s3c2410.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-s3c2410.c	2006-12-22 01:57:07.000000000 +0100
@@ -447,7 +447,7 @@
 	 */
 	.start =		ohci_s3c2410_start,
 	.stop =			ohci_stop,
-	.shutdown = 		ohci_shutdown,
+	.shutdown =		ohci_shutdown,
 
 	/*
 	 * managing i/o requests and associated device resources
@@ -492,7 +492,7 @@
 static struct platform_driver ohci_hcd_s3c2410_driver = {
 	.probe		= ohci_hcd_s3c2410_drv_probe,
 	.remove		= ohci_hcd_s3c2410_drv_remove,
-	.shutdown 	= usb_hcd_platform_shutdown,
+	.shutdown	= usb_hcd_platform_shutdown,
 	/*.suspend	= ohci_hcd_s3c2410_drv_suspend, */
 	/*.resume	= ohci_hcd_s3c2410_drv_resume, */
 	.driver		= {
diff -ru 2.2/drivers/usb/host/ohci-sa1111.c 3.4/drivers/usb/host/ohci-sa1111.c
--- 2.2/drivers/usb/host/ohci-sa1111.c	2006-10-02 17:39:21.000000000 +0200
+++ 3.4/drivers/usb/host/ohci-sa1111.c	2006-12-22 01:57:07.000000000 +0100
@@ -4,7 +4,7 @@
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
  * (C) Copyright 2002 Hewlett-Packard Company
- * 
+ *
  * SA1111 Bus Glue
  *
  * Written by Christopher Hoover <ch@hpl.hp.com>
@@ -12,7 +12,7 @@
  *
  * This file is licenced under the GPL.
  */
- 
+
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/arch/assabet.h>
@@ -31,7 +31,7 @@
 {
 	unsigned int usb_rst = 0;
 
-	printk(KERN_DEBUG __FILE__ 
+	printk(KERN_DEBUG __FILE__
 	       ": starting SA-1111 OHCI USB Controller\n");
 
 #ifdef CONFIG_SA1100_BADGE4
@@ -65,7 +65,7 @@
 static void sa1111_stop_hc(struct sa1111_dev *dev)
 {
 	unsigned int usb_rst;
-	printk(KERN_DEBUG __FILE__ 
+	printk(KERN_DEBUG __FILE__
 	       ": stopping SA-1111 OHCI USB Controller\n");
 
 	/*
diff -ru 2.2/drivers/usb/host/u132-hcd.c 3.4/drivers/usb/host/u132-hcd.c
--- 2.2/drivers/usb/host/u132-hcd.c	2006-12-07 02:52:14.000000000 +0100
+++ 3.4/drivers/usb/host/u132-hcd.c	2006-12-22 01:57:07.000000000 +0100
@@ -40,6 +40,7 @@
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
+#include <linux/pci_ids.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
@@ -210,15 +211,16 @@
 * these cannot be inlines because we need the structure offset!!
 * Does anyone have a better way?????
 */
+#define ftdi_read_pcimem(pdev, member, data) usb_ftdi_elan_read_pcimem(pdev, \
+        offsetof(struct ohci_regs, member), 0, data);
+#define ftdi_write_pcimem(pdev, member, data) usb_ftdi_elan_write_pcimem(pdev, \
+        offsetof(struct ohci_regs, member), 0, data);
 #define u132_read_pcimem(u132, member, data) \
         usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \
         ohci_regs, member), 0, data);
 #define u132_write_pcimem(u132, member, data) \
         usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \
         ohci_regs, member), 0, data);
-#define u132_write_pcimem_byte(u132, member, data) \
-        usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \
-        ohci_regs, member), 0x0e, data);
 static inline struct u132 *udev_to_u132(struct u132_udev *udev)
 {
         u8 udev_number = udev->udev_number;
@@ -1574,59 +1576,12 @@
         return "?";
 }
 
-static int u132_usb_reset(struct u132 *u132)
-{
-        int retval;
-        retval = u132_read_pcimem(u132, control, &u132->hc_control);
-        if (retval)
-                return retval;
-        u132->hc_control &= OHCI_CTRL_RWC;
-        retval = u132_write_pcimem(u132, control, u132->hc_control);
-        if (retval)
-                return retval;
-        return 0;
-}
-
 static int u132_init(struct u132 *u132)
 {
         int retval;
         u32 control;
         u132_disable(u132);
-        u132->next_statechange =
-                jiffies; /* SMM owns the HC? not for long! */  {
-                u32 control;
-                retval = u132_read_pcimem(u132, control, &control);
-                if (retval)
-                        return retval;
-                if (control & OHCI_CTRL_IR) {
-                        u32 temp = 50;
-                        retval = u132_write_pcimem(u132, intrenable,
-                                OHCI_INTR_OC);
-                        if (retval)
-                                return retval;
-                        retval = u132_write_pcimem_byte(u132, cmdstatus,
-                                OHCI_OCR);
-                        if (retval)
-                                return retval;
-                      check:{
-                                retval = u132_read_pcimem(u132, control,
-                                        &control);
-                                if (retval)
-                                        return retval;
-                        }
-                        if (control & OHCI_CTRL_IR) {
-                                msleep(10);
-                                if (--temp == 0) {
-                                        dev_err(&u132->platform_dev->dev, "USB "
-                                                "HC takeover failed!(BIOS/SMM b"
-                                                "ug) control=%08X\n", control);
-                                        return -EBUSY;
-                                }
-                                goto check;
-                        }
-                        u132_usb_reset(u132);
-                }
-        }
+        u132->next_statechange = jiffies;
         retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE);
         if (retval)
                 return retval;
@@ -1725,7 +1680,7 @@
       retry:retval = u132_read_pcimem(u132, cmdstatus, &status);
         if (retval)
                 return retval;
-        retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_HCR);
+        retval = u132_write_pcimem(u132, cmdstatus, OHCI_HCR);
         if (retval)
                 return retval;
       extra:{
@@ -1782,7 +1737,7 @@
         retval = u132_write_pcimem(u132, control, u132->hc_control);
         if (retval)
                 return retval;
-        retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_BLF);
+        retval = u132_write_pcimem(u132, cmdstatus, OHCI_BLF);
         if (retval)
                 return retval;
         retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus);
@@ -1839,8 +1794,8 @@
 {
         struct u132 *u132 = hcd_to_u132(hcd);
         if (u132->going > 1) {
-                dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
-                        , u132->going);
+                dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p) has b"
+                        "een removed %d\n", u132, hcd, u132->going);
         } else if (u132->going > 0) {
                 dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov"
                         "ed\n", hcd);
@@ -2545,8 +2500,9 @@
 {
         struct u132 *u132 = hcd_to_u132(hcd);
         if (u132->going > 2) {
-                dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
-                        , u132->going);
+                dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p hep=%p"
+                        ") has been removed %d\n", u132, hcd, hep,
+                        u132->going);
         } else {
                 struct u132_endp *endp = hep->hcpriv;
                 if (endp)
@@ -2790,7 +2746,6 @@
         } else if (u132->going > 0) {
                 dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov"
                         "ed\n", hcd);
-                dump_stack();
                 return -ESHUTDOWN;
         } else {
                 int i, changed = 0, length = 1;
@@ -3034,12 +2989,15 @@
         struct usb_hcd *hcd = platform_get_drvdata(pdev);
         if (hcd) {
                 struct u132 *u132 = hcd_to_u132(hcd);
-                dump_stack();
                 if (u132->going++ > 1) {
+                        dev_err(&u132->platform_dev->dev, "already being remove"
+				"d\n");
                         return -ENODEV;
                 } else {
                         int rings = MAX_U132_RINGS;
                         int endps = MAX_U132_ENDPS;
+                        dev_err(&u132->platform_dev->dev, "removing device u132"
+				".%d\n", u132->sequence_num);
                         msleep(100);
                         down(&u132->sw_lock);
                         u132_monitor_cancel_work(u132);
@@ -3121,10 +3079,24 @@
 static int __devinit u132_probe(struct platform_device *pdev)
 {
         struct usb_hcd *hcd;
+        int retval;
+        u32 control;
+        u32 rh_a = -1;
+        u32 num_ports;
         msleep(100);
         if (u132_exiting > 0) {
                 return -ENODEV;
-        }                        /* refuse to confuse usbcore */
+        }
+        retval = ftdi_write_pcimem(pdev, intrdisable, OHCI_INTR_MIE);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(pdev, control, &control);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a);
+        if (retval)
+                return retval;
+        num_ports = rh_a & RH_A_NDP;        /* refuse to confuse usbcore */
         if (pdev->dev.dma_mask) {
                 return -EINVAL;
         }
diff -ru 2.2/drivers/usb/host/uhci-hcd.c 3.4/drivers/usb/host/uhci-hcd.c
--- 2.2/drivers/usb/host/uhci-hcd.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/usb/host/uhci-hcd.c	2006-12-22 01:57:07.000000000 +0100
@@ -60,6 +60,11 @@
 Alan Stern"
 #define DRIVER_DESC "USB Universal Host Controller Interface driver"
 
+/* for flakey hardware, ignore overcurrent indicators */
+static int ignore_oc;
+module_param(ignore_oc, bool, S_IRUGO);
+MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications");
+
 /*
  * debug = 0, no debugging messages
  * debug = 1, dump failed URBs except for stalls
@@ -169,6 +174,11 @@
 {
 	int port;
 
+	/* If we have to ignore overcurrent events then almost by definition
+	 * we can't depend on resume-detect interrupts. */
+	if (ignore_oc)
+		return 1;
+
 	switch (to_pci_dev(uhci_dev(uhci))->vendor) {
 	    default:
 		break;
@@ -921,7 +931,8 @@
 {
 	int retval = -ENOMEM;
 
-	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "\n");
+	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n",
+			ignore_oc ? ", overcurrent ignored" : "");
 
 	if (usb_disabled())
 		return -ENODEV;
diff -ru 2.2/drivers/usb/host/uhci-hub.c 3.4/drivers/usb/host/uhci-hub.c
--- 2.2/drivers/usb/host/uhci-hub.c	2006-10-09 14:52:10.000000000 +0200
+++ 3.4/drivers/usb/host/uhci-hub.c	2006-12-22 01:57:07.000000000 +0100
@@ -52,10 +52,20 @@
 static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)
 {
 	int port;
+	int mask = RWC_BITS;
+
+	/* Some boards (both VIA and Intel apparently) report bogus
+	 * overcurrent indications, causing massive log spam unless
+	 * we completely ignore them.  This doesn't seem to be a problem
+	 * with the chipset so much as with the way it is connected on
+	 * the motherboard; if the overcurrent input is left to float
+	 * then it may constantly register false positives. */
+	if (ignore_oc)
+		mask &= ~USBPORTSC_OCC;
 
 	*buf = 0;
 	for (port = 0; port < uhci->rh_numports; ++port) {
-		if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) ||
+		if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & mask) ||
 				test_bit(port, &uhci->port_c_suspend))
 			*buf |= (1 << (port + 1));
 	}
@@ -263,7 +273,7 @@
 			wPortChange |= USB_PORT_STAT_C_CONNECTION;
 		if (status & USBPORTSC_PEC)
 			wPortChange |= USB_PORT_STAT_C_ENABLE;
-		if (status & USBPORTSC_OCC)
+		if ((status & USBPORTSC_OCC) && !ignore_oc)
 			wPortChange |= USB_PORT_STAT_C_OVERCURRENT;
 
 		if (test_bit(port, &uhci->port_c_suspend)) {
diff -ru 2.2/drivers/usb/input/Kconfig 3.4/drivers/usb/input/Kconfig
--- 2.2/drivers/usb/input/Kconfig	2006-12-10 05:32:05.000000000 +0100
+++ 3.4/drivers/usb/input/Kconfig	2006-12-22 01:57:07.000000000 +0100
@@ -7,7 +7,8 @@
 config USB_HID
 	tristate "USB Human Interface Device (full HID) support"
 	default y
-	depends on USB && HID
+	depends on USB
+	select HID
 	---help---
 	  Say Y here if you want full HID support to connect USB keyboards,
 	  mice, joysticks, graphic tablets, or any other HID based devices
diff -ru 2.2/drivers/usb/input/wacom_sys.c 3.4/drivers/usb/input/wacom_sys.c
--- 2.2/drivers/usb/input/wacom_sys.c	2006-12-02 03:35:39.000000000 +0100
+++ 3.4/drivers/usb/input/wacom_sys.c	2006-12-22 01:57:07.000000000 +0100
@@ -159,13 +159,13 @@
 {
 	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
 	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3);
-	input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
+	input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
 }
 
 void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
 	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
-	input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
+	input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
 }
 
 void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
diff -ru 2.2/drivers/usb/input/wacom_wac.c 3.4/drivers/usb/input/wacom_wac.c
--- 2.2/drivers/usb/input/wacom_wac.c	2006-10-18 04:23:16.000000000 +0200
+++ 3.4/drivers/usb/input/wacom_wac.c	2006-12-22 01:57:07.000000000 +0100
@@ -209,13 +209,15 @@
 			wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
 			wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
 		}
-	}
-
-	if (data[1] & 0x10)
 		wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
+	}
 	else
 		wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
-	wacom_report_key(wcombo, wacom->tool[0], data[1] & 0x10);
+
+	if (data[1] & 0x10)  /* only report prox-in when in area */
+		wacom_report_key(wcombo, wacom->tool[0], 1);
+	if (!(data[1] & 0x90))  /* report prox-out when physically out */
+		wacom_report_key(wcombo, wacom->tool[0], 0);
 	wacom_input_sync(wcombo);
 
 	/* send pad data */
@@ -405,7 +407,7 @@
 	if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
                  return 0;
 
-	if (wacom->features->type >= INTUOS3) {
+	if (wacom->features->type >= INTUOS3S) {
 		wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
 		wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
 		wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
@@ -423,7 +425,7 @@
 
 		if (data[1] & 0x02) {
 			/* Rotation packet */
-			if (wacom->features->type >= INTUOS3) {
+			if (wacom->features->type >= INTUOS3S) {
 				/* I3 marker pen rotation reported as wheel
 				 * due to valuator limitation
 				 */
@@ -547,11 +549,11 @@
 	{ "Wacom Graphire3 6x8", 8,  16704, 12064,  511, 63, GRAPHIRE },
 	{ "Wacom Graphire4 4x5", 8,  10208,  7424,  511, 63, WACOM_G4 },
 	{ "Wacom Graphire4 6x8", 8,  16704, 12064,  511, 63, WACOM_G4 },
-	{ "Wacom Volito",        8,   5104,  3712,  511,  0, GRAPHIRE },
-	{ "Wacom PenStation2",   8,   3250,  2320,  255,  0, GRAPHIRE },
-	{ "Wacom Volito2 4x5",   8,   5104,  3712,  511,  0, GRAPHIRE },
-	{ "Wacom Volito2 2x3",   8,   3248,  2320,  511,  0, GRAPHIRE },
-	{ "Wacom PenPartner2",   8,   3250,  2320,  255,  0, GRAPHIRE },
+	{ "Wacom Volito",        8,   5104,  3712,  511, 63, GRAPHIRE },
+	{ "Wacom PenStation2",   8,   3250,  2320,  255, 63, GRAPHIRE },
+	{ "Wacom Volito2 4x5",   8,   5104,  3712,  511, 63, GRAPHIRE },
+	{ "Wacom Volito2 2x3",   8,   3248,  2320,  511, 63, GRAPHIRE },
+	{ "Wacom PenPartner2",   8,   3250,  2320,  255, 63, GRAPHIRE },
 	{ "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 63, INTUOS },
 	{ "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 63, INTUOS },
 	{ "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 63, INTUOS },
@@ -580,7 +582,7 @@
 	{ "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L },
 	{ "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L },
 	{ "Wacom Intuos3 6x11",  10, 54204, 31750, 1023, 63, INTUOS3 },
-	{ "Wacom Intuos3 4x6",   10, 31496, 19685, 1023, 15, INTUOS3S },
+	{ "Wacom Intuos3 4x6",   10, 31496, 19685, 1023, 63, INTUOS3S },
 	{ "Wacom Cintiq 21UX",   10, 87200, 65600, 1023, 63, CINTIQ },
 	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 63, INTUOS },
 	{ }
diff -ru 2.2/drivers/usb/misc/appledisplay.c 3.4/drivers/usb/misc/appledisplay.c
--- 2.2/drivers/usb/misc/appledisplay.c	2006-12-07 02:52:14.000000000 +0100
+++ 3.4/drivers/usb/misc/appledisplay.c	2006-12-23 16:57:57.000000000 +0100
@@ -281,7 +281,7 @@
 	/* Register backlight device */
 	snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
 		atomic_inc_return(&count_displays) - 1);
-	pdata->bd = backlight_device_register(bl_name, pdata,
+	pdata->bd = backlight_device_register(bl_name, NULL, NULL,
 						&appledisplay_bl_data);
 	if (IS_ERR(pdata->bd)) {
 		err("appledisplay: Backlight registration failed");
diff -ru 2.2/drivers/usb/misc/auerswald.c 3.4/drivers/usb/misc/auerswald.c
--- 2.2/drivers/usb/misc/auerswald.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/usb/misc/auerswald.c	2006-12-22 01:57:07.000000000 +0100
@@ -1376,7 +1376,7 @@
 	}
 
 	/* we have access to the device. Now lets allocate memory */
-	ccp = (pauerchar_t) kmalloc(sizeof(auerchar_t), GFP_KERNEL);
+	ccp = kzalloc(sizeof(auerchar_t), GFP_KERNEL);
 	if (ccp == NULL) {
 		err ("out of memory");
 		ret = -ENOMEM;
@@ -1384,7 +1384,6 @@
 	}
 
 	/* Initialize device descriptor */
-	memset( ccp, 0, sizeof(auerchar_t));
 	init_MUTEX( &ccp->mutex);
 	init_MUTEX( &ccp->readmutex);
         auerbuf_init (&ccp->bufctl);
@@ -1912,14 +1911,13 @@
 		return -ENODEV;
 
 	/* allocate memory for our device and initialize it */
-	cp = kmalloc (sizeof(auerswald_t), GFP_KERNEL);
+	cp = kzalloc (sizeof(auerswald_t), GFP_KERNEL);
 	if (cp == NULL) {
 		err ("out of memory");
 		goto pfail;
 	}
 
 	/* Initialize device descriptor */
-	memset (cp, 0, sizeof(auerswald_t));
 	init_MUTEX (&cp->mutex);
 	cp->usbdev = usbdev;
 	auerchain_init (&cp->controlchain);
diff -ru 2.2/drivers/usb/misc/ftdi-elan.c 3.4/drivers/usb/misc/ftdi-elan.c
--- 2.2/drivers/usb/misc/ftdi-elan.c	2006-12-07 02:52:14.000000000 +0100
+++ 3.4/drivers/usb/misc/ftdi-elan.c	2006-12-22 01:57:07.000000000 +0100
@@ -40,6 +40,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/ioctl.h>
+#include <linux/pci_ids.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kref.h>
@@ -51,6 +52,10 @@
 MODULE_DESCRIPTION("FTDI ELAN driver");
 MODULE_LICENSE("GPL");
 #define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444)
+static int distrust_firmware = 1;
+module_param(distrust_firmware, bool, 0);
+MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren"
+        "t setup");
 extern struct platform_driver u132_platform_driver;
 static struct workqueue_struct *status_queue;
 static struct workqueue_struct *command_queue;
@@ -66,7 +71,9 @@
 * end of the global variables protected by ftdi_module_lock
 */
 #include "usb_u132.h"
-#define TD_DEVNOTRESP 5
+#include <asm/io.h>
+#include "../core/hcd.h"
+#include "../host/ohci.h"
 /* Define these values to match your devices*/
 #define USB_FTDI_ELAN_VENDOR_ID 0x0403
 #define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea
@@ -551,7 +558,7 @@
                 } else {
                         dev_err(&ftdi->udev->dev, "initialized failed - trying "
                                 "again in 10 seconds\n");
-                        work_delay_in_msec = 10 *1000;
+                        work_delay_in_msec = 1 *1000;
                 }
         } else if (ftdi->registered == 0) {
                 work_delay_in_msec = 10;
@@ -2288,82 +2295,288 @@
         }
 }
 
-static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
+
+#define ftdi_read_pcimem(ftdi, member, data) ftdi_elan_read_pcimem(ftdi, \
+        offsetof(struct ohci_regs, member), 0, data);
+#define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \
+        offsetof(struct ohci_regs, member), 0, data);
+#define OHCI_QUIRK_AMD756 0x01
+#define OHCI_QUIRK_SUPERIO 0x02
+#define OHCI_QUIRK_INITRESET 0x04
+#define OHCI_BIG_ENDIAN 0x08
+#define OHCI_QUIRK_ZFMICRO 0x10
+#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
+#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
+        OHCI_INTR_WDH)
+static int ftdi_elan_check_controller(struct usb_ftdi *ftdi, int quirk)
+{
+        int devices = 0;
+        int retval;
+        u32 hc_control;
+        int num_ports;
+        u32 control;
+        u32 rh_a = -1;
+        u32 status;
+        u32 fminterval;
+        u32 hc_fminterval;
+        u32 periodicstart;
+        u32 cmdstatus;
+        u32 roothub_a;
+        int mask = OHCI_INTR_INIT;
+        int sleep_time = 0;
+        int reset_timeout = 30;        /* ... allow extra time */
+        int temp;
+        retval = ftdi_write_pcimem(ftdi, intrdisable, OHCI_INTR_MIE);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(ftdi, control, &control);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(ftdi, roothub.a, &rh_a);
+        if (retval)
+                return retval;
+        num_ports = rh_a & RH_A_NDP;
+        retval = ftdi_read_pcimem(ftdi, fminterval, &hc_fminterval);
+        if (retval)
+                return retval;
+        hc_fminterval &= 0x3fff;
+        if (hc_fminterval != FI) {
+        }
+        hc_fminterval |= FSMP(hc_fminterval) << 16;
+        retval = ftdi_read_pcimem(ftdi, control, &hc_control);
+        if (retval)
+                return retval;
+        switch (hc_control & OHCI_CTRL_HCFS) {
+        case OHCI_USB_OPER:
+                sleep_time = 0;
+                break;
+        case OHCI_USB_SUSPEND:
+        case OHCI_USB_RESUME:
+                hc_control &= OHCI_CTRL_RWC;
+                hc_control |= OHCI_USB_RESUME;
+                sleep_time = 10;
+                break;
+        default:
+                hc_control &= OHCI_CTRL_RWC;
+                hc_control |= OHCI_USB_RESET;
+                sleep_time = 50;
+                break;
+        }
+        retval = ftdi_write_pcimem(ftdi, control, hc_control);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(ftdi, control, &control);
+        if (retval)
+                return retval;
+        msleep(sleep_time);
+        retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a);
+        if (retval)
+                return retval;
+        if (!(roothub_a & RH_A_NPS)) {        /* power down each port */
+                for (temp = 0; temp < num_ports; temp++) {
+                        retval = ftdi_write_pcimem(ftdi,
+                                roothub.portstatus[temp], RH_PS_LSDA);
+                        if (retval)
+                                return retval;
+                }
+        }
+        retval = ftdi_read_pcimem(ftdi, control, &control);
+        if (retval)
+                return retval;
+      retry:retval = ftdi_read_pcimem(ftdi, cmdstatus, &status);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_HCR);
+        if (retval)
+                return retval;
+      extra:{
+                retval = ftdi_read_pcimem(ftdi, cmdstatus, &status);
+                if (retval)
+                        return retval;
+                if (0 != (status & OHCI_HCR)) {
+                        if (--reset_timeout == 0) {
+                                dev_err(&ftdi->udev->dev, "USB HC reset timed o"
+                                        "ut!\n");
+                                return -ENODEV;
+                        } else {
+                                msleep(5);
+                                goto extra;
+                        }
+                }
+        }
+        if (quirk & OHCI_QUIRK_INITRESET) {
+                retval = ftdi_write_pcimem(ftdi, control, hc_control);
+                if (retval)
+                        return retval;
+                retval = ftdi_read_pcimem(ftdi, control, &control);
+                if (retval)
+                        return retval;
+        }
+        retval = ftdi_write_pcimem(ftdi, ed_controlhead, 0x00000000);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, ed_bulkhead, 0x11000000);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, hcca, 0x00000000);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, fminterval,
+                ((fminterval & FIT) ^ FIT) | hc_fminterval);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, periodicstart,
+                ((9 *hc_fminterval) / 10) & 0x3fff);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(ftdi, periodicstart, &periodicstart);
+        if (retval)
+                return retval;
+        if (0 == (fminterval & 0x3fff0000) || 0 == periodicstart) {
+                if (!(quirk & OHCI_QUIRK_INITRESET)) {
+                        quirk |= OHCI_QUIRK_INITRESET;
+                        goto retry;
+                } else
+                        dev_err(&ftdi->udev->dev, "init err(%08x %04x)\n",
+                                fminterval, periodicstart);
+        }                        /* start controller operations */
+        hc_control &= OHCI_CTRL_RWC;
+        hc_control |= OHCI_CONTROL_INIT | OHCI_CTRL_BLE | OHCI_USB_OPER;
+        retval = ftdi_write_pcimem(ftdi, control, hc_control);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_BLF);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(ftdi, cmdstatus, &cmdstatus);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(ftdi, control, &control);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_DRWE);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, intrstatus, mask);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, intrdisable,
+                OHCI_INTR_MIE | OHCI_INTR_OC | OHCI_INTR_RHSC | OHCI_INTR_FNO |
+                OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_SF | OHCI_INTR_WDH |
+                OHCI_INTR_SO);
+        if (retval)
+                return retval;        /* handle root hub init quirks ... */
+        retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a);
+        if (retval)
+                return retval;
+        roothub_a &= ~(RH_A_PSM | RH_A_OCPM);
+        if (quirk & OHCI_QUIRK_SUPERIO) {
+                roothub_a |= RH_A_NOCP;
+                roothub_a &= ~(RH_A_POTPGT | RH_A_NPS);
+                retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a);
+                if (retval)
+                        return retval;
+        } else if ((quirk & OHCI_QUIRK_AMD756) || distrust_firmware) {
+                roothub_a |= RH_A_NPS;
+                retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a);
+                if (retval)
+                        return retval;
+        }
+        retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_LPSC);
+        if (retval)
+                return retval;
+        retval = ftdi_write_pcimem(ftdi, roothub.b,
+                (roothub_a & RH_A_NPS) ? 0 : RH_B_PPCM);
+        if (retval)
+                return retval;
+        retval = ftdi_read_pcimem(ftdi, control, &control);
+        if (retval)
+                return retval;
+        mdelay((roothub_a >> 23) & 0x1fe);
+        for (temp = 0; temp < num_ports; temp++) {
+                u32 portstatus;
+                retval = ftdi_read_pcimem(ftdi, roothub.portstatus[temp],
+                        &portstatus);
+                if (retval)
+                        return retval;
+                if (1 & portstatus)
+                        devices += 1;
+        }
+        return devices;
+}
+
+static int ftdi_elan_setup_controller(struct usb_ftdi *ftdi, int fn)
 {
         u32 latence_timer;
-        u32 controlreg;
         int UxxxStatus;
         u32 pcidata;
         int reg = 0;
-        int foundOHCI = 0;
-        u8 fn;
-        int activePCIfn = 0;
-        u32 pciVID = 0;
-        u32 pciPID = 0;
-        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
-        if (UxxxStatus)
-                return UxxxStatus;
-        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L);
-        if (UxxxStatus)
-                return UxxxStatus;
-        msleep(750);
-        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100);
+        int activePCIfn = fn << 8;
+        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800);
         if (UxxxStatus)
                 return UxxxStatus;
-        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500);
+        reg = 16;
+        UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0,
+                0xFFFFFFFF);
         if (UxxxStatus)
                 return UxxxStatus;
-        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+        UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+                &pcidata);
         if (UxxxStatus)
                 return UxxxStatus;
-        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000);
+        UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0,
+                0xF0000000);
         if (UxxxStatus)
                 return UxxxStatus;
-        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000);
+        UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+                &pcidata);
         if (UxxxStatus)
                 return UxxxStatus;
-        msleep(250);
-        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000);
+        reg = 12;
+        UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+                &latence_timer);
         if (UxxxStatus)
                 return UxxxStatus;
-        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+        latence_timer &= 0xFFFF00FF;
+        latence_timer |= 0x00001600;
+        UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00,
+                latence_timer);
         if (UxxxStatus)
                 return UxxxStatus;
-        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800);
+        UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+                &pcidata);
         if (UxxxStatus)
                 return UxxxStatus;
-        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+        reg = 4;
+        UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00,
+                0x06);
         if (UxxxStatus)
                 return UxxxStatus;
-        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+        UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+                &pcidata);
         if (UxxxStatus)
                 return UxxxStatus;
-        msleep(1000);
-        for (fn = 0; (fn < 4) && (!foundOHCI); fn++) {
-                activePCIfn = fn << 8;
-                ftdi->function = fn + 1;
-                UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
-                        &pcidata);
+        for (reg = 0; reg <= 0x54; reg += 4) {
+                UxxxStatus = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
                 if (UxxxStatus)
                         return UxxxStatus;
-                pciVID = pcidata & 0xFFFF;
-                pciPID = (pcidata >> 16) & 0xFFFF;
-                if ((pciVID == 0x1045) && (pciPID == 0xc861)) {
-                        foundOHCI = 1;
-                } else if ((pciVID == 0x1033) && (pciPID == 0x0035)) {
-                        foundOHCI = 1;
-                } else if ((pciVID == 0x10b9) && (pciPID == 0x5237)) {
-                        foundOHCI = 1;
-                } else if ((pciVID == 0x11c1) && (pciPID == 0x5802)) {
-                        foundOHCI = 1;
-                } else if ((pciVID == 0x11AB) && (pciPID == 0x1FA6)) {
-                }
-        }
-        if (foundOHCI == 0) {
-                return -ENXIO;
         }
-        ftdi->platform_data.vendor = pciVID;
-        ftdi->platform_data.device = pciPID;
+        return 0;
+}
+
+static int ftdi_elan_close_controller(struct usb_ftdi *ftdi, int fn)
+{
+        u32 latence_timer;
+        int UxxxStatus;
+        u32 pcidata;
+        int reg = 0;
+        int activePCIfn = fn << 8;
         UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800);
         if (UxxxStatus)
                 return UxxxStatus;
@@ -2377,7 +2590,7 @@
         if (UxxxStatus)
                 return UxxxStatus;
         UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0,
-                0xF0000000);
+                0x00000000);
         if (UxxxStatus)
                 return UxxxStatus;
         UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
@@ -2401,7 +2614,7 @@
                 return UxxxStatus;
         reg = 4;
         UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00,
-                0x06);
+                0x00);
         if (UxxxStatus)
                 return UxxxStatus;
         UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
@@ -2411,159 +2624,139 @@
         return 0;
 }
 
+static int ftdi_elan_found_controller(struct usb_ftdi *ftdi, int fn, int quirk)
+{
+        int result;
+        int UxxxStatus;
+        UxxxStatus = ftdi_elan_setup_controller(ftdi, fn);
+        if (UxxxStatus)
+                return UxxxStatus;
+        result = ftdi_elan_check_controller(ftdi, quirk);
+        UxxxStatus = ftdi_elan_close_controller(ftdi, fn);
+        if (UxxxStatus)
+                return UxxxStatus;
+        return result;
+}
+
+static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
+{
+        u32 controlreg;
+        u8 sensebits;
+        int UxxxStatus;
+        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+        if (UxxxStatus)
+                return UxxxStatus;
+        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L);
+        if (UxxxStatus)
+                return UxxxStatus;
+        msleep(750);
+        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100);
+        if (UxxxStatus)
+                return UxxxStatus;
+        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500);
+        if (UxxxStatus)
+                return UxxxStatus;
+        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+        if (UxxxStatus)
+                return UxxxStatus;
+        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000);
+        if (UxxxStatus)
+                return UxxxStatus;
+        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000);
+        if (UxxxStatus)
+                return UxxxStatus;
+        msleep(250);
+        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000);
+        if (UxxxStatus)
+                return UxxxStatus;
+        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+        if (UxxxStatus)
+                return UxxxStatus;
+        UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800);
+        if (UxxxStatus)
+                return UxxxStatus;
+        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+        if (UxxxStatus)
+                return UxxxStatus;
+        UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+        if (UxxxStatus)
+                return UxxxStatus;
+        msleep(1000);
+        sensebits = (controlreg >> 16) & 0x000F;
+        if (0x0D == sensebits)
+                return 0;
+        else
+		return - ENXIO;
+}
+
 static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi)
 {
+        int UxxxStatus;
         u32 pcidata;
-        int U132Status;
-        int reg;
-        int reset_repeat = 0;
-      do_reset:reg = 8;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x01);
-        if (U132Status)
-                return U132Status;
-      reset_check:{
-                U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-                if (U132Status)
-                        return U132Status;
-                if (pcidata & 1) {
-                        msleep(500);
-                        if (reset_repeat++ > 100) {
-                                reset_repeat = 0;
-                                goto do_reset;
-                        } else
-                                goto reset_check;
+        int reg = 0;
+        u8 fn;
+        int activePCIfn = 0;
+        int max_devices = 0;
+        int controllers = 0;
+        int unrecognized = 0;
+        ftdi->function = 0;
+        for (fn = 0; (fn < 4); fn++) {
+                u32 pciVID = 0;
+                u32 pciPID = 0;
+                int devices = 0;
+                activePCIfn = fn << 8;
+                UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+                        &pcidata);
+                if (UxxxStatus)
+                        return UxxxStatus;
+                pciVID = pcidata & 0xFFFF;
+                pciPID = (pcidata >> 16) & 0xFFFF;
+                if ((pciVID == PCI_VENDOR_ID_OPTI) && (pciPID == 0xc861)) {
+                        devices = ftdi_elan_found_controller(ftdi, fn, 0);
+                        controllers += 1;
+                } else if ((pciVID == PCI_VENDOR_ID_NEC) && (pciPID == 0x0035))
+                        {
+                        devices = ftdi_elan_found_controller(ftdi, fn, 0);
+                        controllers += 1;
+                } else if ((pciVID == PCI_VENDOR_ID_AL) && (pciPID == 0x5237)) {
+                        devices = ftdi_elan_found_controller(ftdi, fn, 0);
+                        controllers += 1;
+                } else if ((pciVID == PCI_VENDOR_ID_ATT) && (pciPID == 0x5802))
+                        {
+                        devices = ftdi_elan_found_controller(ftdi, fn, 0);
+                        controllers += 1;
+                } else if (pciVID == PCI_VENDOR_ID_AMD && pciPID == 0x740c) {
+                        devices = ftdi_elan_found_controller(ftdi, fn,
+                                OHCI_QUIRK_AMD756);
+                        controllers += 1;
+                } else if (pciVID == PCI_VENDOR_ID_COMPAQ && pciPID == 0xa0f8) {
+                        devices = ftdi_elan_found_controller(ftdi, fn,
+                                OHCI_QUIRK_ZFMICRO);
+                        controllers += 1;
+                } else if (0 == pcidata) {
+                } else
+                        unrecognized += 1;
+                if (devices > max_devices) {
+                        max_devices = devices;
+                        ftdi->function = fn + 1;
+                        ftdi->platform_data.vendor = pciVID;
+                        ftdi->platform_data.device = pciPID;
                 }
         }
-        goto dump_regs;
-        msleep(500);
-        reg = 0x28;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x11000000);
-        if (U132Status)
-                return U132Status;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x40;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf);
-        if (U132Status)
-                return U132Status;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x34;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf2edf);
-        if (U132Status)
-                return U132Status;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 4;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0xA0);
-        if (U132Status)
-                return U132Status;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        msleep(250);
-        reg = 8;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x04);
-        if (U132Status)
-                return U132Status;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x28;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 8;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x48;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x00001200);
-        if (U132Status)
-                return U132Status;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x54;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x58;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x34;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x28002edf);
-        if (U132Status)
-                return U132Status;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        msleep(100);
-        reg = 0x50;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10000);
-        if (U132Status)
-                return U132Status;
-        reg = 0x54;
-      power_check:U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        if (!(pcidata & 1)) {
-                msleep(500);
-                goto power_check;
-        }
-        msleep(3000);
-        reg = 0x54;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x58;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x54;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02);
-        if (U132Status)
-                return U132Status;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x54;
-        U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10);
-        if (U132Status)
-                return U132Status;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        msleep(750);
-        reg = 0x54;
-        if (0) {
-                U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02);
-                if (U132Status)
-                        return U132Status;
-        }
-        if (0) {
-                U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-                if (U132Status)
-                        return U132Status;
-        }
-        reg = 0x54;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-        reg = 0x58;
-        U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-        if (U132Status)
-                return U132Status;
-      dump_regs:for (reg = 0; reg <= 0x54; reg += 4) {
-                U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
-                if (U132Status)
-                        return U132Status;
+        if (ftdi->function > 0) {
+                UxxxStatus = ftdi_elan_setup_controller(ftdi,
+                        ftdi->function - 1);
+                if (UxxxStatus)
+                        return UxxxStatus;
+                return 0;
+        } else if (controllers > 0) {
+                return -ENXIO;
+        } else if (unrecognized > 0) {
+                return -ENXIO;
+        } else {
+                ftdi->enumerated = 0;
+                return -ENXIO;
         }
-        return 0;
 }
 
 
@@ -2688,6 +2881,7 @@
                         platform_device_unregister(&ftdi->platform_dev);
                         ftdi->synchronized = 0;
                         ftdi->enumerated = 0;
+                        ftdi->initialized = 0;
                         ftdi->registered = 0;
                 }
                 flush_workqueue(status_queue);
diff -ru 2.2/drivers/usb/misc/phidgetservo.c 3.4/drivers/usb/misc/phidgetservo.c
--- 2.2/drivers/usb/misc/phidgetservo.c	2006-10-02 17:39:22.000000000 +0200
+++ 3.4/drivers/usb/misc/phidgetservo.c	2006-12-22 01:57:07.000000000 +0100
@@ -282,6 +282,7 @@
 		dev->dev = NULL;
 		goto out;
 	}
+	dev_set_drvdata(dev->dev, dev);
 
 	servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1;
 
diff -ru 2.2/drivers/usb/misc/trancevibrator.c 3.4/drivers/usb/misc/trancevibrator.c
--- 2.2/drivers/usb/misc/trancevibrator.c	2006-10-18 04:23:17.000000000 +0200
+++ 3.4/drivers/usb/misc/trancevibrator.c	2006-12-22 01:57:07.000000000 +0100
@@ -120,8 +120,8 @@
 	struct trancevibrator *dev;
 
 	dev = usb_get_intfdata (interface);
-	usb_set_intfdata(interface, NULL);
 	device_remove_file(&interface->dev, &dev_attr_speed);
+	usb_set_intfdata(interface, NULL);
 	usb_put_dev(dev->udev);
 	kfree(dev);
 }
diff -ru 2.2/drivers/usb/net/gl620a.c 3.4/drivers/usb/net/gl620a.c
--- 2.2/drivers/usb/net/gl620a.c	2006-10-09 14:52:11.000000000 +0200
+++ 3.4/drivers/usb/net/gl620a.c	2006-12-22 01:57:07.000000000 +0100
@@ -79,160 +79,6 @@
 	struct gl_packet	packets;
 };
 
-#ifdef	GENELINK_ACK
-
-// FIXME:  this code is incomplete, not debugged; it doesn't
-// handle interrupts correctly; it should use the generic
-// status IRQ code (which didn't exist back in 2001).
-
-struct gl_priv {
-	struct urb	*irq_urb;
-	char		irq_buf [INTERRUPT_BUFSIZE];
-};
-
-static inline int gl_control_write(struct usbnet *dev, u8 request, u16 value)
-{
-	int retval;
-
-	retval = usb_control_msg(dev->udev,
-		      usb_sndctrlpipe(dev->udev, 0),
-		      request,
-		      USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		      value,
-		      0,			// index
-		      0,			// data buffer
-		      0,			// size
-		      USB_CTRL_SET_TIMEOUT);
-	return retval;
-}
-
-static void gl_interrupt_complete(struct urb *urb)
-{
-	int status = urb->status;
-
-	switch (status) {
-	case 0:
-		/* success */
-		break;
-	case -ECONNRESET:
-	case -ENOENT:
-	case -ESHUTDOWN:
-		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-				__FUNCTION__, status);
-		return;
-	default:
-		dbg("%s - nonzero urb status received: %d",
-				__FUNCTION__, urb->status);
-	}
-
-	status = usb_submit_urb(urb, GFP_ATOMIC);
-	if (status)
-		err("%s - usb_submit_urb failed with result %d",
-		     __FUNCTION__, status);
-}
-
-static int gl_interrupt_read(struct usbnet *dev)
-{
-	struct gl_priv	*priv = dev->priv_data;
-	int		retval;
-
-	// issue usb interrupt read
-	if (priv && priv->irq_urb) {
-		// submit urb
-		if ((retval = usb_submit_urb(priv->irq_urb, GFP_KERNEL)) != 0)
-			dbg("gl_interrupt_read: submit fail - %X...", retval);
-		else
-			dbg("gl_interrupt_read: submit success...");
-	}
-
-	return 0;
-}
-
-// check whether another side is connected
-static int genelink_check_connect(struct usbnet *dev)
-{
-	int			retval;
-
-	dbg("genelink_check_connect...");
-
-	// detect whether another side is connected
-	if ((retval = gl_control_write(dev, GENELINK_CONNECT_WRITE, 0)) != 0) {
-		dbg("%s: genelink_check_connect write fail - %X",
-			dev->net->name, retval);
-		return retval;
-	}
-
-	// usb interrupt read to ack another side
-	if ((retval = gl_interrupt_read(dev)) != 0) {
-		dbg("%s: genelink_check_connect read fail - %X",
-			dev->net->name, retval);
-		return retval;
-	}
-
-	dbg("%s: genelink_check_connect read success", dev->net->name);
-	return 0;
-}
-
-// allocate and initialize the private data for genelink
-static int genelink_init(struct usbnet *dev)
-{
-	struct gl_priv *priv;
-
-	// allocate the private data structure
-	if ((priv = kmalloc(sizeof *priv, GFP_KERNEL)) == 0) {
-		dbg("%s: cannot allocate private data per device",
-			dev->net->name);
-		return -ENOMEM;
-	}
-
-	// allocate irq urb
-	if ((priv->irq_urb = usb_alloc_urb(0, GFP_KERNEL)) == 0) {
-		dbg("%s: cannot allocate private irq urb per device",
-			dev->net->name);
-		kfree(priv);
-		return -ENOMEM;
-	}
-
-	// fill irq urb
-	usb_fill_int_urb(priv->irq_urb, dev->udev,
-		usb_rcvintpipe(dev->udev, GENELINK_INTERRUPT_PIPE),
-		priv->irq_buf, INTERRUPT_BUFSIZE,
-		gl_interrupt_complete, 0,
-		GENELINK_INTERRUPT_INTERVAL);
-
-	// set private data pointer
-	dev->priv_data = priv;
-
-	return 0;
-}
-
-// release the private data
-static int genelink_free(struct usbnet *dev)
-{
-	struct gl_priv	*priv = dev->priv_data;
-
-	if (!priv)
-		return 0;
-
-// FIXME:  can't cancel here; it's synchronous, and
-// should have happened earlier in any case (interrupt
-// handling needs to be generic)
-
-	// cancel irq urb first
-	usb_kill_urb(priv->irq_urb);
-
-	// free irq urb
-	usb_free_urb(priv->irq_urb);
-
-	// free the private data structure
-	kfree(priv);
-
-	return 0;
-}
-
-#endif
-
 static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 {
 	struct gl_header	*header;
diff -ru 2.2/drivers/usb/net/rtl8150.c 3.4/drivers/usb/net/rtl8150.c
--- 2.2/drivers/usb/net/rtl8150.c	2006-12-08 04:50:56.000000000 +0100
+++ 3.4/drivers/usb/net/rtl8150.c	2006-12-22 01:57:07.000000000 +0100
@@ -124,10 +124,11 @@
 #define	RX_URB_FAIL		3
 
 /* Define these values to match your device */
-#define VENDOR_ID_REALTEK		0x0bda
+#define	VENDOR_ID_REALTEK		0x0bda
 #define	VENDOR_ID_MELCO			0x0411
-#define VENDOR_ID_MICRONET		0x3980
+#define	VENDOR_ID_MICRONET		0x3980
 #define	VENDOR_ID_LONGSHINE		0x07b8
+#define	VENDOR_ID_OQO			0x1557
 #define	VENDOR_ID_ZYXEL			0x0586
 
 #define PRODUCT_ID_RTL8150		0x8150
@@ -144,6 +145,7 @@
 	{USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)},
 	{USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)},
 	{USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)},
+	{USB_DEVICE(VENDOR_ID_OQO, PRODUCT_ID_RTL8150)},
 	{USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)},
 	{}
 };
diff -ru 2.2/drivers/usb/serial/airprime.c 3.4/drivers/usb/serial/airprime.c
--- 2.2/drivers/usb/serial/airprime.c	2006-12-02 03:35:39.000000000 +0100
+++ 3.4/drivers/usb/serial/airprime.c	2006-12-22 01:57:07.000000000 +0100
@@ -19,8 +19,11 @@
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
 	{ USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
+	{ USB_DEVICE(0x1410, 0x1130) }, /* Novatel Wireless S720 CDMA/EV-DO */
+	{ USB_DEVICE(0x1410, 0x2110) }, /* Novatel Wireless U720 CDMA/EV-DO */
 	{ USB_DEVICE(0x1410, 0x1430) },	/* Novatel Merlin XU870 HSDPA/3G */
 	{ USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */
+	{ USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
diff -ru 2.2/drivers/usb/serial/cp2101.c 3.4/drivers/usb/serial/cp2101.c
--- 2.2/drivers/usb/serial/cp2101.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/usb/serial/cp2101.c	2006-12-22 01:57:07.000000000 +0100
@@ -69,6 +69,7 @@
 	{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
 	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
+	{ USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
 	{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
 	{ } /* Terminating Entry */
 };
diff -ru 2.2/drivers/usb/serial/cypress_m8.c 3.4/drivers/usb/serial/cypress_m8.c
--- 2.2/drivers/usb/serial/cypress_m8.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/usb/serial/cypress_m8.c	2006-12-22 01:57:07.000000000 +0100
@@ -962,21 +962,6 @@
 			cypress_set_termios(port, &priv->tmp_termios);
 			return (0);
 			break;
-		/* these are called when setting baud rate from gpsd */
-		case TCGETS:
-			if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct termios))) {
-				return -EFAULT;
-			}
-			return (0);
-			break;
-		case TCSETS:
-			if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct termios))) {
-				return -EFAULT;
-			}
-			/* here we need to call cypress_set_termios to invoke the new settings */
-			cypress_set_termios(port, &priv->tmp_termios);
-			return (0);
-			break;
 		/* This code comes from drivers/char/serial.c and ftdi_sio.c */
 		case TIOCMIWAIT:
 			while (priv != NULL) {
diff -ru 2.2/drivers/usb/serial/ftdi_sio.c 3.4/drivers/usb/serial/ftdi_sio.c
--- 2.2/drivers/usb/serial/ftdi_sio.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/usb/serial/ftdi_sio.c	2006-12-22 01:57:07.000000000 +0100
@@ -452,6 +452,7 @@
 	{ USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) },
 	{ USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
 	{ USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
 	{ USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
diff -ru 2.2/drivers/usb/serial/ftdi_sio.h 3.4/drivers/usb/serial/ftdi_sio.h
--- 2.2/drivers/usb/serial/ftdi_sio.h	2006-11-20 02:11:27.000000000 +0100
+++ 3.4/drivers/usb/serial/ftdi_sio.h	2006-12-22 01:57:07.000000000 +0100
@@ -312,8 +312,9 @@
 
 /* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */
 /* unit for PIC16's/PIC18's */
-#define FTDI_CCSICDU20_0_PID    0xF9D0     
-#define FTDI_CCSICDU40_1_PID    0xF9D1     
+#define FTDI_CCSICDU20_0_PID    0xF9D0
+#define FTDI_CCSICDU40_1_PID    0xF9D1
+#define FTDI_CCSMACHX_2_PID     0xF9D2
 
 /* Inside Accesso contactless reader (http://www.insidefr.com) */
 #define INSIDE_ACCESSO		0xFAD0
diff -ru 2.2/drivers/usb/serial/funsoft.c 3.4/drivers/usb/serial/funsoft.c
--- 2.2/drivers/usb/serial/funsoft.c	2006-10-02 17:39:22.000000000 +0200
+++ 3.4/drivers/usb/serial/funsoft.c	2006-12-22 01:57:07.000000000 +0100
@@ -14,6 +14,9 @@
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
+#include <asm/uaccess.h>
+
+static int debug;
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(0x1404, 0xcddc) },
@@ -21,6 +24,26 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
+static int funsoft_ioctl(struct usb_serial_port *port, struct file *file,
+			 unsigned int cmd, unsigned long arg)
+{
+	struct termios t;
+
+	dbg("%s - port %d, cmd 0x%04x", __FUNCTION__, port->number, cmd);
+
+	if (cmd == TCSETSF) {
+		if (user_termios_to_kernel_termios(&t, (void __user *)arg))
+			return -EFAULT;
+
+		dbg("%s - iflag:%x oflag:%x cflag:%x lflag:%x", __FUNCTION__,
+		    t.c_iflag, t.c_oflag, t.c_cflag, t.c_lflag);
+
+		if (!(t.c_lflag & ICANON))
+			return -EINVAL;
+	}
+	return -ENOIOCTLCMD;
+}
+
 static struct usb_driver funsoft_driver = {
 	.name =		"funsoft",
 	.probe =	usb_serial_probe,
@@ -39,6 +62,7 @@
 	.num_bulk_in =		NUM_DONT_CARE,
 	.num_bulk_out =		NUM_DONT_CARE,
 	.num_ports =		1,
+	.ioctl =		funsoft_ioctl,
 };
 
 static int __init funsoft_init(void)
@@ -63,3 +87,6 @@
 module_init(funsoft_init);
 module_exit(funsoft_exit);
 MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff -ru 2.2/drivers/usb/serial/kl5kusb105.c 3.4/drivers/usb/serial/kl5kusb105.c
--- 2.2/drivers/usb/serial/kl5kusb105.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/usb/serial/kl5kusb105.c	2006-12-22 01:57:07.000000000 +0100
@@ -87,10 +87,6 @@
 static void klsi_105_read_bulk_callback  (struct urb *urb);
 static void klsi_105_set_termios         (struct usb_serial_port *port,
 					  struct ktermios *old);
-static int  klsi_105_ioctl	         (struct usb_serial_port *port,
-					  struct file * file,
-					  unsigned int cmd,
-					  unsigned long arg);
 static void klsi_105_throttle		 (struct usb_serial_port *port);
 static void klsi_105_unthrottle		 (struct usb_serial_port *port);
 /*
@@ -140,7 +136,6 @@
 	.chars_in_buffer =   klsi_105_chars_in_buffer,
 	.write_room =        klsi_105_write_room,
 	.read_bulk_callback =klsi_105_read_bulk_callback,
-	.ioctl =	     klsi_105_ioctl,
 	.set_termios =	     klsi_105_set_termios,
 	/*.break_ctl =	     klsi_105_break_ctl,*/
 	.tiocmget =          klsi_105_tiocmget,
@@ -899,69 +894,6 @@
 */
 	return retval;
 }
-					
-static int klsi_105_ioctl (struct usb_serial_port *port, struct file * file,
-			   unsigned int cmd, unsigned long arg)
-{
-	struct klsi_105_private *priv = usb_get_serial_port_data(port);
-	void __user *user_arg = (void __user *)arg;
-	
-	dbg("%scmd=0x%x", __FUNCTION__, cmd);
-
-	/* Based on code from acm.c and others */
-	switch (cmd) {
-	case TIOCMIWAIT:
-		/* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
-		/* TODO */
-		dbg("%s - TIOCMIWAIT not handled", __FUNCTION__);
-		return -ENOIOCTLCMD;
-	case TIOCGICOUNT:
-		/* return count of modemline transitions */
-		/* TODO */
-		dbg("%s - TIOCGICOUNT not handled", __FUNCTION__);
-		return -ENOIOCTLCMD;
-	case TCGETS:
-		/* return current info to caller */
-		dbg("%s - TCGETS data faked/incomplete", __FUNCTION__);
-
-		if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct termios)))
-			return -EFAULT;
-
-		if (kernel_termios_to_user_termios((struct termios __user *)arg,
-						   &priv->termios))
-			return -EFAULT;
-		return 0;
-	case TCSETS:
-		/* set port termios to the one given by the user */
-		dbg("%s - TCSETS not handled", __FUNCTION__);
-
-		if (!access_ok(VERIFY_READ, user_arg, sizeof(struct termios)))
-			return -EFAULT;
-
-		if (user_termios_to_kernel_termios(&priv->termios,
-						   (struct termios __user *)arg))
-			return -EFAULT;
-		klsi_105_set_termios(port, &priv->termios);
-		return 0;
-	case TCSETSW: {
-		/* set port termios and try to wait for completion of last
-		 * write operation */
-		/* We guess here. If there are not too many write urbs
-		 * outstanding, we lie. */
-		/* what is the right way to wait here? schedule() ? */
-	        /*
-		while (klsi_105_chars_in_buffer(port) > (NUM_URBS / 4 ) * URB_TRANSFER_BUFFER_SIZE)
-			    schedule();
-		 */
-		return -ENOIOCTLCMD;
-		      }
-	default:
-		dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd);
-		return(-ENOIOCTLCMD);
-		break;
-	}
-	return 0;
-} /* klsi_105_ioctl */
 
 static void klsi_105_throttle (struct usb_serial_port *port)
 {
diff -ru 2.2/drivers/usb/serial/mos7840.c 3.4/drivers/usb/serial/mos7840.c
--- 2.2/drivers/usb/serial/mos7840.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/usb/serial/mos7840.c	2006-12-22 01:57:07.000000000 +0100
@@ -2460,12 +2460,6 @@
 		tty_ldisc_deref(ld);
 		return 0;
 
-	case TCGETS:
-		if (kernel_termios_to_user_termios
-		    ((struct termios __user *)argp, tty->termios))
-			return -EFAULT;
-		return 0;
-
 	case TIOCSERGETLSR:
 		dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number);
 		return mos7840_get_lsr_info(mos7840_port, argp);
diff -ru 2.2/drivers/usb/serial/option.c 3.4/drivers/usb/serial/option.c
--- 2.2/drivers/usb/serial/option.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/usb/serial/option.c	2006-12-22 01:57:07.000000000 +0100
@@ -79,6 +79,7 @@
 #define OPTION_PRODUCT_COBRA            0x6500
 #define OPTION_PRODUCT_COBRA2           0x6600
 #define HUAWEI_PRODUCT_E600             0x1001
+#define HUAWEI_PRODUCT_E220             0x1003
 #define AUDIOVOX_PRODUCT_AIRCARD        0x0112
 #define NOVATELWIRELESS_PRODUCT_U740    0x1400
 #define ANYDATA_PRODUCT_ID              0x6501
@@ -90,6 +91,7 @@
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
+	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
 	{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
@@ -103,6 +105,7 @@
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
+	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
 	{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
diff -ru 2.2/drivers/usb/storage/unusual_devs.h 3.4/drivers/usb/storage/unusual_devs.h
--- 2.2/drivers/usb/storage/unusual_devs.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/drivers/usb/storage/unusual_devs.h	2006-12-22 01:57:07.000000000 +0100
@@ -153,6 +153,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
 
+/* Reported by <honkkis@gmail.com> */
+UNUSUAL_DEV(  0x0421, 0x0433, 0x0100, 0x0100,
+		"Nokia",
+		"E70",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
+
 /* Reported by Jon Hart <Jon.Hart@web.de> */
 UNUSUAL_DEV(  0x0421, 0x0434, 0x0100, 0x0100,
 		"Nokia",
@@ -1328,6 +1335,15 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
+/* This prevents the kernel from detecting the virtual cd-drive with the
+ * Windows drivers.  <johann.wilhelm@student.tugraz.at>
+*/
+UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0xffff,
+		"HUAWEI",
+		"E220 USB-UMTS Install",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_DEVICE),
+
 /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
 UNUSUAL_DEV(  0x132b, 0x000b, 0x0001, 0x0001,
 		"Minolta",
diff -ru 2.2/drivers/video/aty/aty128fb.c 3.4/drivers/video/aty/aty128fb.c
--- 2.2/drivers/video/aty/aty128fb.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/video/aty/aty128fb.c	2006-12-23 16:57:57.000000000 +0100
@@ -1834,7 +1834,7 @@
 
 	snprintf(name, sizeof(name), "aty128bl%d", info->node);
 
-	bd = backlight_device_register(name, par, &aty128_bl_data);
+	bd = backlight_device_register(name, info->dev, par, &aty128_bl_data);
 	if (IS_ERR(bd)) {
 		info->bl_dev = NULL;
 		printk(KERN_WARNING "aty128: Backlight registration failed\n");
diff -ru 2.2/drivers/video/aty/atyfb_base.c 3.4/drivers/video/aty/atyfb_base.c
--- 2.2/drivers/video/aty/atyfb_base.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/drivers/video/aty/atyfb_base.c	2006-12-23 16:57:57.000000000 +0100
@@ -2211,7 +2211,7 @@
 
 	snprintf(name, sizeof(name), "atybl%d", info->node);
 
-	bd = backlight_device_register(name, par, &aty_bl_data);
+	bd = backlight_device_register(name, info->dev, par, &aty_bl_data);
 	if (IS_ERR(bd)) {
 		info->bl_dev = NULL;
 		printk(KERN_WARNING "aty: Backlight registration failed\n");
diff -ru 2.2/drivers/video/aty/radeon_backlight.c 3.4/drivers/video/aty/radeon_backlight.c
--- 2.2/drivers/video/aty/radeon_backlight.c	2006-10-02 17:39:23.000000000 +0200
+++ 3.4/drivers/video/aty/radeon_backlight.c	2006-12-23 16:57:57.000000000 +0100
@@ -163,7 +163,7 @@
 
 	snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
 
-	bd = backlight_device_register(name, pdata, &radeon_bl_data);
+	bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data);
 	if (IS_ERR(bd)) {
 		rinfo->info->bl_dev = NULL;
 		printk("radeonfb: Backlight registration failed\n");
diff -ru 2.2/drivers/video/backlight/backlight.c 3.4/drivers/video/backlight/backlight.c
--- 2.2/drivers/video/backlight/backlight.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/video/backlight/backlight.c	2006-12-23 16:57:57.000000000 +0100
@@ -216,8 +216,10 @@
  * Creates and registers new backlight class_device. Returns either an
  * ERR_PTR() or a pointer to the newly allocated device.
  */
-struct backlight_device *backlight_device_register(const char *name, void *devdata,
-						   struct backlight_properties *bp)
+struct backlight_device *backlight_device_register(const char *name,
+	struct device *dev,
+	void *devdata,
+	struct backlight_properties *bp)
 {
 	int i, rc;
 	struct backlight_device *new_bd;
@@ -232,6 +234,7 @@
 	new_bd->props = bp;
 	memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev));
 	new_bd->class_dev.class = &backlight_class;
+	new_bd->class_dev.dev = dev;
 	strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN);
 	class_set_devdata(&new_bd->class_dev, devdata);
 
diff -ru 2.2/drivers/video/gxt4500.c 3.4/drivers/video/gxt4500.c
--- 2.2/drivers/video/gxt4500.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/drivers/video/gxt4500.c	2006-12-23 01:11:19.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- * Frame buffer device for IBM GXT4500P display adaptor
+ * Frame buffer device for IBM GXT4500P and GXT6000P display adaptors
  *
  * Copyright (C) 2006 Paul Mackerras, IBM Corp. <paulus@samba.org>
  */
@@ -11,8 +11,10 @@
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include <linux/delay.h>
+#include <linux/string.h>
 
 #define PCI_DEVICE_ID_IBM_GXT4500P	0x21c
+#define PCI_DEVICE_ID_IBM_GXT6000P	0x170
 
 /* GXT4500P registers */
 
@@ -94,6 +96,7 @@
 #define PLL_M			0x4040
 #define PLL_N			0x4044
 #define PLL_POSTDIV		0x4048
+#define PLL_C			0x404c
 
 /* Hardware cursor */
 #define CURSOR_X		0x4078
@@ -140,6 +143,7 @@
 	int pixfmt;		/* pixel format, see DFA_PIX_* values */
 
 	/* PLL parameters */
+	int refclk_ps;		/* ref clock period in picoseconds */
 	int pll_m;		/* ref clock divisor */
 	int pll_n;		/* VCO divisor */
 	int pll_pd1;		/* first post-divisor */
@@ -166,6 +170,21 @@
 	.vmode = FB_VMODE_NONINTERLACED
 };
 
+/* List of supported cards */
+enum gxt_cards {
+	GXT4500P,
+	GXT6000P
+};
+
+/* Card-specific information */
+static const struct cardinfo {
+	int	refclk_ps;	/* period of PLL reference clock in ps */
+	const char *cardname;
+} cardinfo[] = {
+	[GXT4500P] = { .refclk_ps = 9259, .cardname = "IBM GXT4500P" },
+	[GXT6000P] = { .refclk_ps = 40000, .cardname = "IBM GXT6000P" },
+};
+
 /*
  * The refclk and VCO dividers appear to use a linear feedback shift
  * register, which gets reloaded when it reaches a terminal value, at
@@ -203,27 +222,16 @@
 /* 130 */	0x9e, 0x4f, 0x27, 0x93, 0xc9, 0xe4, 0x72, 0x39, 0x1c, 0x0e,
 /* 140 */	0x87, 0xc3, 0x61, 0x30, 0x18, 0x8c, 0xc6, 0x63, 0x31, 0x98,
 /* 150 */	0xcc, 0xe6, 0x73, 0xb9, 0x5c, 0x2e, 0x97, 0x4b, 0xa5, 0xd2,
-/* 160 */	0x69, 0xb4, 0xda, 0xed, 0x76, 0xbb, 0x5d, 0xae, 0xd7, 0x6b,
-/* 170 */	0xb5, 0x5a, 0xad, 0x56, 0xab, 0xd5, 0x6a, 0x35, 0x1a, 0x8d,
-/* 180 */	0x46, 0x23, 0x11, 0x88, 0x44, 0x22, 0x91, 0xc8, 0x64, 0x32,
-/* 190 */	0x19, 0x0c, 0x86, 0x43, 0x21, 0x10, 0x08, 0x04, 0x02, 0x81,
-/* 200 */	0x40, 0xa0, 0xd0, 0x68, 0x34, 0x9a, 0xcd, 0x66, 0x33, 0x99,
-/* 210 */	0x4c, 0xa6, 0x53, 0xa9, 0xd4, 0xea, 0x75, 0x3a, 0x9d, 0xce,
-/* 220 */	0xe7, 0xf3, 0xf9, 0x7c, 0x3e, 0x1f, 0x8f, 0x47, 0xa3, 0x51,
-/* 230 */	0xa8, 0x54, 0xaa, 0x55, 0x2a, 0x15, 0x0a, 0x05, 0x82, 0xc1,
-/* 240 */	0x60, 0xb0, 0x58, 0xac, 0xd6, 0xeb, 0xf5, 0x7a, 0xbd, 0xde,
-/* 250 */	0x6f, 0x37, 0x1b, 0x0d, 0x06, 0x03, 0x01,
+/* 160 */	0x69,
 };
 
-#define REF_PERIOD_PS	9259	/* period of reference clock in ps */
-
 static int calc_pll(int period_ps, struct gxt4500_par *par)
 {
 	int m, n, pdiv1, pdiv2, postdiv;
-	int pll_period, best_error, t;
+	int pll_period, best_error, t, intf;
 
-	/* only deal with range 1MHz - 400MHz */
-	if (period_ps < 2500 || period_ps > 1000000)
+	/* only deal with range 5MHz - 300MHz */
+	if (period_ps < 3333 || period_ps > 200000)
 		return -1;
 
 	best_error = 1000000;
@@ -231,14 +239,17 @@
 		for (pdiv2 = 1; pdiv2 <= pdiv1; ++pdiv2) {
 			postdiv = pdiv1 * pdiv2;
 			pll_period = (period_ps + postdiv - 1) / postdiv;
-			/* keep pll in range 500..1250 MHz */
-			if (pll_period < 800 || pll_period > 2000)
+			/* keep pll in range 350..600 MHz */
+			if (pll_period < 1666 || pll_period > 2857)
 				continue;
-			for (m = 3; m <= 40; ++m) {
-				n = REF_PERIOD_PS * m * postdiv / period_ps;
-				if (n < 5 || n > 256)
+			for (m = 1; m <= 64; ++m) {
+				intf = m * par->refclk_ps;
+				if (intf > 500000)
+					break;
+				n = intf * postdiv / period_ps;
+				if (n < 3 || n > 160)
 					continue;
-				t = REF_PERIOD_PS * m * postdiv / n;
+				t = par->refclk_ps * m * postdiv / n;
 				t -= period_ps;
 				if (t >= 0 && t < best_error) {
 					par->pll_m = m;
@@ -257,7 +268,7 @@
 
 static int calc_pixclock(struct gxt4500_par *par)
 {
-	return REF_PERIOD_PS * par->pll_m * par->pll_pd1 * par->pll_pd2
+	return par->refclk_ps * par->pll_m * par->pll_pd1 * par->pll_pd2
 		/ par->pll_n;
 }
 
@@ -357,7 +368,7 @@
 	struct gxt4500_par *par = info->par;
 	struct fb_var_screeninfo *var = &info->var;
 	int err;
-	u32 ctrlreg;
+	u32 ctrlreg, tmp;
 	unsigned int dfa_ctl, pixfmt, stride;
 	unsigned int wid_tiles, i;
 	unsigned int prefetch_pix, htot;
@@ -376,10 +387,25 @@
 	writereg(par, DTG_CONTROL, ctrlreg);
 
 	/* set PLL registers */
+	tmp = readreg(par, PLL_C) & ~0x7f;
+	if (par->pll_n < 38)
+		tmp |= 0x29;
+	if (par->pll_n < 69)
+		tmp |= 0x35;
+	else if (par->pll_n < 100)
+		tmp |= 0x76;
+	else
+		tmp |= 0x7e;
+	writereg(par, PLL_C, tmp);
 	writereg(par, PLL_M, mdivtab[par->pll_m - 1]);
 	writereg(par, PLL_N, ndivtab[par->pll_n - 2]);
-	writereg(par, PLL_POSTDIV,
-		 ((8 - par->pll_pd1) << 3) | (8 - par->pll_pd2));
+	tmp = ((8 - par->pll_pd2) << 3) | (8 - par->pll_pd1);
+	if (par->pll_pd1 == 8 || par->pll_pd2 == 8) {
+		/* work around erratum */
+		writereg(par, PLL_POSTDIV, tmp | 0x9);
+		udelay(1);
+	}
+	writereg(par, PLL_POSTDIV, tmp);
 	msleep(20);
 
 	/* turn off hardware cursor */
@@ -483,8 +509,8 @@
 
 	if (reg > 1023)
 		return 1;
-	cmap_entry = ((transp & 0xff00) << 16) | ((blue & 0xff00) << 8) |
-		(green & 0xff00) | (red >> 8);
+	cmap_entry = ((transp & 0xff00) << 16) | ((red & 0xff00) << 8) |
+		(green & 0xff00) | (blue >> 8);
 	writereg(par, CMAP + reg * 4, cmap_entry);
 
 	if (reg < 16 && par->pixfmt != DFA_PIX_8BIT) {
@@ -585,6 +611,7 @@
 	struct gxt4500_par *par;
 	struct fb_info *info;
 	struct fb_var_screeninfo var;
+	enum gxt_cards cardtype;
 
 	err = pci_enable_device(pdev);
 	if (err) {
@@ -613,7 +640,11 @@
 		goto err_free_fb;
 	}
 	par = info->par;
+	cardtype = ent->driver_data;
+	par->refclk_ps = cardinfo[cardtype].refclk_ps;
 	info->fix = gxt4500_fix;
+	strlcpy(info->fix.id, cardinfo[cardtype].cardname,
+		sizeof(info->fix.id));
 	info->pseudo_palette = par->pseudo_palette;
 
 	info->fix.mmio_start = reg_phys;
@@ -703,8 +734,10 @@
 
 /* supported chipsets */
 static const struct pci_device_id gxt4500_pci_tbl[] = {
-	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT4500P,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT4500P),
+	  .driver_data = GXT4500P },
+	{ PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT6000P),
+	  .driver_data = GXT6000P },
 	{ 0 }
 };
 
@@ -735,7 +768,7 @@
 module_exit(gxt4500_exit);
 
 MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
-MODULE_DESCRIPTION("FBDev driver for IBM GXT4500P");
+MODULE_DESCRIPTION("FBDev driver for IBM GXT4500P/6000P");
 MODULE_LICENSE("GPL");
 module_param(mode_option, charp, 0);
 MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
diff -ru 2.2/drivers/video/nvidia/nv_backlight.c 3.4/drivers/video/nvidia/nv_backlight.c
--- 2.2/drivers/video/nvidia/nv_backlight.c	2006-10-02 17:39:26.000000000 +0200
+++ 3.4/drivers/video/nvidia/nv_backlight.c	2006-12-23 16:57:57.000000000 +0100
@@ -141,7 +141,7 @@
 
 	snprintf(name, sizeof(name), "nvidiabl%d", info->node);
 
-	bd = backlight_device_register(name, par, &nvidia_bl_data);
+	bd = backlight_device_register(name, info->dev, par, &nvidia_bl_data);
 	if (IS_ERR(bd)) {
 		info->bl_dev = NULL;
 		printk(KERN_WARNING "nvidia: Backlight registration failed\n");
diff -ru 2.2/drivers/video/pxafb.c 3.4/drivers/video/pxafb.c
--- 2.2/drivers/video/pxafb.c	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/drivers/video/pxafb.c	2006-12-22 01:57:07.000000000 +0100
@@ -1216,7 +1216,7 @@
 		done:
 			if (res_specified) {
 				dev_info(dev, "overriding resolution: %dx%d\n", xres, yres);
-				inf->xres = xres; inf->yres = yres;
+				inf->modes[0].xres = xres; inf->modes[0].yres = yres;
 			}
 			if (bpp_specified)
 				switch (bpp) {
@@ -1225,48 +1225,48 @@
 				case 4:
 				case 8:
 				case 16:
-					inf->bpp = bpp;
+					inf->modes[0].bpp = bpp;
 					dev_info(dev, "overriding bit depth: %d\n", bpp);
 					break;
 				default:
 					dev_err(dev, "Depth %d is not valid\n", bpp);
 				}
                 } else if (!strncmp(this_opt, "pixclock:", 9)) {
-                        inf->pixclock = simple_strtoul(this_opt+9, NULL, 0);
-			dev_info(dev, "override pixclock: %ld\n", inf->pixclock);
+                        inf->modes[0].pixclock = simple_strtoul(this_opt+9, NULL, 0);
+			dev_info(dev, "override pixclock: %ld\n", inf->modes[0].pixclock);
                 } else if (!strncmp(this_opt, "left:", 5)) {
-                        inf->left_margin = simple_strtoul(this_opt+5, NULL, 0);
-			dev_info(dev, "override left: %u\n", inf->left_margin);
+                        inf->modes[0].left_margin = simple_strtoul(this_opt+5, NULL, 0);
+			dev_info(dev, "override left: %u\n", inf->modes[0].left_margin);
                 } else if (!strncmp(this_opt, "right:", 6)) {
-                        inf->right_margin = simple_strtoul(this_opt+6, NULL, 0);
-			dev_info(dev, "override right: %u\n", inf->right_margin);
+                        inf->modes[0].right_margin = simple_strtoul(this_opt+6, NULL, 0);
+			dev_info(dev, "override right: %u\n", inf->modes[0].right_margin);
                 } else if (!strncmp(this_opt, "upper:", 6)) {
-                        inf->upper_margin = simple_strtoul(this_opt+6, NULL, 0);
-			dev_info(dev, "override upper: %u\n", inf->upper_margin);
+                        inf->modes[0].upper_margin = simple_strtoul(this_opt+6, NULL, 0);
+			dev_info(dev, "override upper: %u\n", inf->modes[0].upper_margin);
                 } else if (!strncmp(this_opt, "lower:", 6)) {
-                        inf->lower_margin = simple_strtoul(this_opt+6, NULL, 0);
-			dev_info(dev, "override lower: %u\n", inf->lower_margin);
+                        inf->modes[0].lower_margin = simple_strtoul(this_opt+6, NULL, 0);
+			dev_info(dev, "override lower: %u\n", inf->modes[0].lower_margin);
                 } else if (!strncmp(this_opt, "hsynclen:", 9)) {
-                        inf->hsync_len = simple_strtoul(this_opt+9, NULL, 0);
-			dev_info(dev, "override hsynclen: %u\n", inf->hsync_len);
+                        inf->modes[0].hsync_len = simple_strtoul(this_opt+9, NULL, 0);
+			dev_info(dev, "override hsynclen: %u\n", inf->modes[0].hsync_len);
                 } else if (!strncmp(this_opt, "vsynclen:", 9)) {
-                        inf->vsync_len = simple_strtoul(this_opt+9, NULL, 0);
-			dev_info(dev, "override vsynclen: %u\n", inf->vsync_len);
+                        inf->modes[0].vsync_len = simple_strtoul(this_opt+9, NULL, 0);
+			dev_info(dev, "override vsynclen: %u\n", inf->modes[0].vsync_len);
                 } else if (!strncmp(this_opt, "hsync:", 6)) {
                         if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
 				dev_info(dev, "override hsync: Active Low\n");
-				inf->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+				inf->modes[0].sync &= ~FB_SYNC_HOR_HIGH_ACT;
 			} else {
 				dev_info(dev, "override hsync: Active High\n");
-				inf->sync |= FB_SYNC_HOR_HIGH_ACT;
+				inf->modes[0].sync |= FB_SYNC_HOR_HIGH_ACT;
 			}
                 } else if (!strncmp(this_opt, "vsync:", 6)) {
                         if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
 				dev_info(dev, "override vsync: Active Low\n");
-				inf->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+				inf->modes[0].sync &= ~FB_SYNC_VERT_HIGH_ACT;
 			} else {
 				dev_info(dev, "override vsync: Active High\n");
-				inf->sync |= FB_SYNC_VERT_HIGH_ACT;
+				inf->modes[0].sync |= FB_SYNC_VERT_HIGH_ACT;
 			}
                 } else if (!strncmp(this_opt, "dpc:", 4)) {
                         if (simple_strtoul(this_opt+4, NULL, 0) == 0) {
diff -ru 2.2/drivers/video/riva/fbdev.c 3.4/drivers/video/riva/fbdev.c
--- 2.2/drivers/video/riva/fbdev.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/drivers/video/riva/fbdev.c	2006-12-23 16:57:57.000000000 +0100
@@ -384,7 +384,7 @@
 
 	snprintf(name, sizeof(name), "rivabl%d", info->node);
 
-	bd = backlight_device_register(name, par, &riva_bl_data);
+	bd = backlight_device_register(name, info->dev, par, &riva_bl_data);
 	if (IS_ERR(bd)) {
 		info->bl_dev = NULL;
 		printk(KERN_WARNING "riva: Backlight registration failed\n");
diff -ru 2.2/drivers/video/sa1100fb.c 3.4/drivers/video/sa1100fb.c
--- 2.2/drivers/video/sa1100fb.c	2006-10-09 14:52:14.000000000 +0200
+++ 3.4/drivers/video/sa1100fb.c	2006-12-22 01:57:07.000000000 +0100
@@ -1200,9 +1200,9 @@
  * Our LCD controller task (which is called when we blank or unblank)
  * via keventd.
  */
-static void sa1100fb_task(void *dummy)
+static void sa1100fb_task(struct work_struct *w)
 {
-	struct sa1100fb_info *fbi = dummy;
+	struct sa1100fb_info *fbi = container_of(w, struct sa1100fb_info, task);
 	u_int state = xchg(&fbi->task_state, -1);
 
 	set_ctrlr_state(fbi, state);
@@ -1444,7 +1444,7 @@
 					  fbi->max_bpp / 8;
 
 	init_waitqueue_head(&fbi->ctrlr_wait);
-	INIT_WORK(&fbi->task, sa1100fb_task, fbi);
+	INIT_WORK(&fbi->task, sa1100fb_task);
 	init_MUTEX(&fbi->ctrlr_sem);
 
 	return fbi;
diff -ru 2.2/fs/buffer.c 3.4/fs/buffer.c
--- 2.2/fs/buffer.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/fs/buffer.c	2006-12-22 01:57:07.000000000 +0100
@@ -2834,7 +2834,7 @@
 	int ret = 0;
 
 	BUG_ON(!PageLocked(page));
-	if (PageWriteback(page))
+	if (PageDirty(page) || PageWriteback(page))
 		return 0;
 
 	if (mapping == NULL) {		/* can this still happen? */
@@ -2845,22 +2845,6 @@
 	spin_lock(&mapping->private_lock);
 	ret = drop_buffers(page, &buffers_to_free);
 	spin_unlock(&mapping->private_lock);
-	if (ret) {
-		/*
-		 * If the filesystem writes its buffers by hand (eg ext3)
-		 * then we can have clean buffers against a dirty page.  We
-		 * clean the page here; otherwise later reattachment of buffers
-		 * could encounter a non-uptodate page, which is unresolvable.
-		 * This only applies in the rare case where try_to_free_buffers
-		 * succeeds but the page is not freed.
-		 *
-		 * Also, during truncate, discard_buffer will have marked all
-		 * the page's buffers clean.  We discover that here and clean
-		 * the page also.
-		 */
-		if (test_clear_page_dirty(page))
-			task_io_account_cancelled_write(PAGE_CACHE_SIZE);
-	}
 out:
 	if (buffers_to_free) {
 		struct buffer_head *bh = buffers_to_free;
diff -ru 2.2/fs/cifs/file.c 3.4/fs/cifs/file.c
--- 2.2/fs/cifs/file.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/fs/cifs/file.c	2006-12-24 16:38:17.000000000 +0100
@@ -1245,14 +1245,21 @@
 				wait_on_page_writeback(page);
 
 			if (PageWriteback(page) ||
-					!test_clear_page_dirty(page)) {
+					!clear_page_dirty_for_io(page)) {
 				unlock_page(page);
 				break;
 			}
 
+			/*
+			 * This actually clears the dirty bit in the radix tree.
+			 * See cifs_writepage() for more commentary.
+			 */
+			set_page_writeback(page);
+
 			if (page_offset(page) >= mapping->host->i_size) {
 				done = 1;
 				unlock_page(page);
+				end_page_writeback(page);
 				break;
 			}
 
@@ -1316,6 +1323,7 @@
 					SetPageError(page);
 				kunmap(page);
 				unlock_page(page);
+				end_page_writeback(page);
 				page_cache_release(page);
 			}
 			if ((wbc->nr_to_write -= n_iov) <= 0)
@@ -1352,11 +1360,23 @@
         if (!PageUptodate(page)) {
 		cFYI(1, ("ppw - page not up to date"));
 	}
-	
+
+	/*
+	 * Set the "writeback" flag, and clear "dirty" in the radix tree.
+	 *
+	 * A writepage() implementation always needs to do either this,
+	 * or re-dirty the page with "redirty_page_for_writepage()" in
+	 * the case of a failure.
+	 *
+	 * Just unlocking the page will cause the radix tree tag-bits
+	 * to fail to update with the state of the page correctly.
+	 */
+	set_page_writeback(page);		
 	rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE);
 	SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
 	unlock_page(page);
-	page_cache_release(page);	
+	end_page_writeback(page);
+	page_cache_release(page);
 	FreeXid(xid);
 	return rc;
 }
diff -ru 2.2/fs/dlm/lowcomms-tcp.c 3.4/fs/dlm/lowcomms-tcp.c
--- 2.2/fs/dlm/lowcomms-tcp.c	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/fs/dlm/lowcomms-tcp.c	2006-12-22 01:57:07.000000000 +0100
@@ -143,7 +143,7 @@
 /* An array of pointers to connections, indexed by NODEID */
 static struct connection **connections;
 static DECLARE_MUTEX(connections_lock);
-static kmem_cache_t *con_cache;
+static struct kmem_cache *con_cache;
 static int conn_array_size;
 
 /* List of sockets that have reads pending */
diff -ru 2.2/fs/file.c 3.4/fs/file.c
--- 2.2/fs/file.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/fs/file.c	2006-12-23 01:11:19.000000000 +0100
@@ -206,7 +206,7 @@
 		copy_fdtable(new_fdt, cur_fdt);
 		rcu_assign_pointer(files->fdt, new_fdt);
 		if (cur_fdt->max_fds > NR_OPEN_DEFAULT)
-			call_rcu(&cur_fdt->rcu, free_fdtable_rcu);
+			free_fdtable(cur_fdt);
 	} else {
 		/* Somebody else expanded, so undo our attempt */
 		free_fdarr(new_fdt);
diff -ru 2.2/fs/fuse/file.c 3.4/fs/fuse/file.c
--- 2.2/fs/fuse/file.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/fs/fuse/file.c	2006-12-22 01:57:07.000000000 +0100
@@ -483,10 +483,8 @@
 			i_size_write(inode, pos);
 		spin_unlock(&fc->lock);
 
-		if (offset == 0 && to == PAGE_CACHE_SIZE) {
-			clear_page_dirty(page);
+		if (offset == 0 && to == PAGE_CACHE_SIZE)
 			SetPageUptodate(page);
-		}
 	}
 	fuse_invalidate_attr(inode);
 	return err;
diff -ru 2.2/fs/gfs2/Kconfig 3.4/fs/gfs2/Kconfig
--- 2.2/fs/gfs2/Kconfig	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/fs/gfs2/Kconfig	2006-12-22 01:57:07.000000000 +0100
@@ -34,7 +34,9 @@
 
 config GFS2_FS_LOCKING_DLM
 	tristate "GFS2 DLM locking module"
-	depends on GFS2_FS
+	depends on GFS2_FS && NET && INET && (IPV6 || IPV6=n)
+	select IP_SCTP if DLM_SCTP
+	select CONFIGFS_FS
 	select DLM
 	help
 	Multiple node locking module for GFS2
diff -ru 2.2/fs/hugetlbfs/inode.c 3.4/fs/hugetlbfs/inode.c
--- 2.2/fs/hugetlbfs/inode.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/fs/hugetlbfs/inode.c	2006-12-22 01:57:07.000000000 +0100
@@ -176,7 +176,7 @@
 
 static void truncate_huge_page(struct page *page)
 {
-	clear_page_dirty(page);
+	cancel_dirty_page(page, /* No IO accounting for huge pages? */0);
 	ClearPageUptodate(page);
 	remove_from_page_cache(page);
 	put_page(page);
diff -ru 2.2/fs/jbd/commit.c 3.4/fs/jbd/commit.c
--- 2.2/fs/jbd/commit.c	2006-10-04 18:55:38.000000000 +0200
+++ 3.4/fs/jbd/commit.c	2006-12-23 01:11:19.000000000 +0100
@@ -248,8 +248,12 @@
 				bufs = 0;
 				goto write_out_data;
 			}
-		}
-		else {
+		} else if (!locked && buffer_locked(bh)) {
+			__journal_file_buffer(jh, commit_transaction,
+						BJ_Locked);
+			jbd_unlock_bh_state(bh);
+			put_bh(bh);
+		} else {
 			BUFFER_TRACE(bh, "writeout complete: unfile");
 			__journal_unfile_buffer(jh);
 			jbd_unlock_bh_state(bh);
diff -ru 2.2/fs/jfs/jfs_metapage.c 3.4/fs/jfs/jfs_metapage.c
--- 2.2/fs/jfs/jfs_metapage.c	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/fs/jfs/jfs_metapage.c	2006-12-22 01:57:07.000000000 +0100
@@ -764,22 +764,9 @@
 	} else if (mp->lsn)	/* discard_metapage doesn't remove it */
 		remove_from_logsync(mp);
 
-#if MPS_PER_PAGE == 1
-	/*
-	 * If we know this is the only thing in the page, we can throw
-	 * the page out of the page cache.  If pages are larger, we
-	 * don't want to do this.
-	 */
-
-	/* Retest mp->count since we may have released page lock */
-	if (test_bit(META_discard, &mp->flag) && !mp->count) {
-		clear_page_dirty(page);
-		ClearPageUptodate(page);
-	}
-#else
 	/* Try to keep metapages from using up too much memory */
 	drop_metapage(page, mp);
-#endif
+
 	unlock_page(page);
 	page_cache_release(page);
 }
diff -ru 2.2/fs/Kconfig 3.4/fs/Kconfig
--- 2.2/fs/Kconfig	2006-12-13 18:28:47.000000000 +0100
+++ 3.4/fs/Kconfig	2006-12-23 01:11:19.000000000 +0100
@@ -1198,13 +1198,16 @@
 
 config JFFS_FS
 	tristate "Journalling Flash File System (JFFS) support"
-	depends on MTD && BLOCK
+	depends on MTD && BLOCK && BROKEN
 	help
 	  JFFS is the Journalling Flash File System developed by Axis
 	  Communications in Sweden, aimed at providing a crash/powerdown-safe
 	  file system for disk-less embedded devices. Further information is
 	  available at (<http://developer.axis.com/software/jffs/>).
 
+	  NOTE: This filesystem is deprecated and is scheduled for removal in
+	  2.6.21.  See Documentation/feature-removal-schedule.txt
+
 config JFFS_FS_VERBOSE
 	int "JFFS debugging verbosity (0 = quiet, 3 = noisy)"
 	depends on JFFS_FS
diff -ru 2.2/fs/partitions/check.c 3.4/fs/partitions/check.c
--- 2.2/fs/partitions/check.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/fs/partitions/check.c	2006-12-19 14:47:35.000000000 +0100
@@ -365,7 +365,7 @@
 	kobject_put(&p->kobj);
 }
 
-void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
+void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flag)
 {
 	struct hd_struct *p;
 
@@ -390,6 +390,15 @@
 	if (!disk->part_uevent_suppress)
 		kobject_uevent(&p->kobj, KOBJ_ADD);
 	sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem");
+	if (flag == ADDPART_FLAG_WHOLEDISK) {
+		static struct attribute addpartattr = {
+			.name = "whole_disk",
+			.mode = S_IRUSR | S_IRGRP | S_IROTH,
+			.owner = THIS_MODULE,
+		};
+
+		sysfs_create_file(&p->kobj, &addpartattr);
+	}
 	partition_sysfs_add_subdir(p);
 	disk->part[part-1] = p;
 }
@@ -543,9 +552,9 @@
 			printk(" %s: p%d exceeds device capacity\n",
 				disk->disk_name, p);
 		}
-		add_partition(disk, p, from, size);
+		add_partition(disk, p, from, size, state->parts[p].flags);
 #ifdef CONFIG_BLK_DEV_MD
-		if (state->parts[p].flags)
+		if (state->parts[p].flags == ADDPART_FLAG_RAID)
 			md_autodetect_dev(bdev->bd_dev+p);
 #endif
 	}
diff -ru 2.2/fs/partitions/msdos.c 3.4/fs/partitions/msdos.c
--- 2.2/fs/partitions/msdos.c	2006-10-11 15:48:10.000000000 +0200
+++ 3.4/fs/partitions/msdos.c	2006-12-19 14:47:35.000000000 +0100
@@ -155,7 +155,7 @@
 
 			put_partition(state, state->next, next, size);
 			if (SYS_IND(p) == LINUX_RAID_PARTITION)
-				state->parts[state->next].flags = 1;
+				state->parts[state->next].flags = ADDPART_FLAG_RAID;
 			loopct = 0;
 			if (++state->next == state->limit)
 				goto done;
diff -ru 2.2/fs/partitions/sgi.c 3.4/fs/partitions/sgi.c
--- 2.2/fs/partitions/sgi.c	2006-10-02 17:39:28.000000000 +0200
+++ 3.4/fs/partitions/sgi.c	2006-12-19 14:47:35.000000000 +0100
@@ -72,7 +72,7 @@
 		if (blocks) {
 			put_partition(state, slot, start, blocks);
 			if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION)
-				state->parts[slot].flags = 1;
+				state->parts[slot].flags = ADDPART_FLAG_RAID;
 		}
 		slot++;
 	}
diff -ru 2.2/fs/partitions/sun.c 3.4/fs/partitions/sun.c
--- 2.2/fs/partitions/sun.c	2006-10-02 17:39:28.000000000 +0200
+++ 3.4/fs/partitions/sun.c	2006-12-19 14:47:35.000000000 +0100
@@ -81,7 +81,9 @@
 		if (num_sectors) {
 			put_partition(state, slot, st_sector, num_sectors);
 			if (label->infos[i].id == LINUX_RAID_PARTITION)
-				state->parts[slot].flags = 1;
+				state->parts[slot].flags = ADDPART_FLAG_RAID;
+			if (label->infos[i].id == SUN_WHOLE_DISK)
+				state->parts[slot].flags = ADDPART_FLAG_WHOLEDISK;
 		}
 		slot++;
 	}
diff -ru 2.2/fs/pipe.c 3.4/fs/pipe.c
--- 2.2/fs/pipe.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/fs/pipe.c	2006-12-22 01:57:07.000000000 +0100
@@ -935,8 +935,9 @@
 
 void free_write_pipe(struct file *f)
 {
-	mntput(f->f_path.mnt);
+	free_pipe_info(f->f_dentry->d_inode);
 	dput(f->f_path.dentry);
+	mntput(f->f_path.mnt);
 	put_filp(f);
 }
 
@@ -994,6 +995,8 @@
  err_fdr:
 	put_unused_fd(fdr);
  err_read_pipe:
+	dput(fr->f_dentry);
+	mntput(fr->f_vfsmnt);
 	put_filp(fr);
  err_write_pipe:
 	free_write_pipe(fw);
diff -ru 2.2/fs/reiserfs/stree.c 3.4/fs/reiserfs/stree.c
--- 2.2/fs/reiserfs/stree.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/fs/reiserfs/stree.c	2006-12-24 16:38:17.000000000 +0100
@@ -1459,7 +1459,7 @@
 				bh = next;
 			} while (bh != head);
 			if (PAGE_SIZE == bh->b_size) {
-				clear_page_dirty(page);
+				cancel_dirty_page(page, PAGE_CACHE_SIZE);
 			}
 		}
 	}
diff -ru 2.2/fs/stack.c 3.4/fs/stack.c
--- 2.2/fs/stack.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/fs/stack.c	2006-12-23 01:11:19.000000000 +0100
@@ -34,7 +34,5 @@
 	dest->i_ctime = src->i_ctime;
 	dest->i_blkbits = src->i_blkbits;
 	dest->i_flags = src->i_flags;
-
-	fsstack_copy_inode_size(dest, src);
 }
 EXPORT_SYMBOL_GPL(fsstack_copy_attr_all);
diff -ru 2.2/fs/sysv/super.c 3.4/fs/sysv/super.c
--- 2.2/fs/sysv/super.c	2006-10-13 04:58:10.000000000 +0200
+++ 3.4/fs/sysv/super.c	2006-12-23 01:11:19.000000000 +0100
@@ -528,9 +528,6 @@
 	.fs_flags	= FS_REQUIRES_DEV,
 };
 
-extern int sysv_init_icache(void) __init;
-extern void sysv_destroy_icache(void);
-
 static int __init init_sysv_fs(void)
 {
 	int error;
diff -ru 2.2/fs/sysv/sysv.h 3.4/fs/sysv/sysv.h
--- 2.2/fs/sysv/sysv.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/fs/sysv/sysv.h	2006-12-23 01:11:19.000000000 +0100
@@ -143,6 +143,9 @@
 extern int sysv_sync_file(struct file *, struct dentry *, int);
 extern void sysv_set_inode(struct inode *, dev_t);
 extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int sysv_init_icache(void);
+extern void sysv_destroy_icache(void);
+
 
 /* dir.c */
 extern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct page **);
diff -ru 2.2/fs/xfs/linux-2.6/xfs_aops.c 3.4/fs/xfs/linux-2.6/xfs_aops.c
--- 2.2/fs/xfs/linux-2.6/xfs_aops.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/fs/xfs/linux-2.6/xfs_aops.c	2006-12-22 01:57:07.000000000 +0100
@@ -341,9 +341,9 @@
 {
 	ASSERT(PageLocked(page));
 	ASSERT(!PageWriteback(page));
-	set_page_writeback(page);
 	if (clear_dirty)
-		clear_page_dirty(page);
+		clear_page_dirty_for_io(page);
+	set_page_writeback(page);
 	unlock_page(page);
 	if (!buffers) {
 		end_page_writeback(page);
diff -ru 2.2/include/acpi/acpixf.h 3.4/include/acpi/acpixf.h
--- 2.2/include/acpi/acpixf.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/acpi/acpixf.h	2006-12-23 16:57:57.000000000 +0100
@@ -97,11 +97,12 @@
 
 acpi_status acpi_load_tables(void);
 
-#ifdef ACPI_FUTURE_USAGE
 acpi_status acpi_load_table(struct acpi_table_header *table_ptr);
 
-acpi_status acpi_unload_table(acpi_table_type table_type);
+acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id);
 
+#ifdef ACPI_FUTURE_USAGE
+acpi_status acpi_unload_table(acpi_table_type table_type);
 acpi_status
 acpi_get_table_header(acpi_table_type table_type,
 		      u32 instance, struct acpi_table_header *out_table_header);
@@ -180,6 +181,8 @@
 
 acpi_status acpi_get_type(acpi_handle object, acpi_object_type * out_type);
 
+acpi_status acpi_get_id(acpi_handle object, acpi_owner_id * out_type);
+
 acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle);
 
 /*
diff -ru 2.2/include/asm-arm/arch-iop13xx/iq81340.h 3.4/include/asm-arm/arch-iop13xx/iq81340.h
--- 2.2/include/asm-arm/arch-iop13xx/iq81340.h	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/include/asm-arm/arch-iop13xx/iq81340.h	2006-12-22 01:57:07.000000000 +0100
@@ -24,8 +24,5 @@
 #define PBI_CF_IDE_BASE     (IQ81340_CMP_FLSH)
 #define PBI_CF_BAR_ADDR     (IOP13XX_PBI_BAR1)
 
-/* These are the values used in the Machine description */
-#define PHYS_IO         0xfeffff00
-#define IO_PG_OFFSET    0xffffff00
-#define BOOT_PARAM_OFFSET  0x00000100
+
 #endif	/* _IQ81340_H_ */
diff -ru 2.2/include/asm-arm/arch-ixp23xx/memory.h 3.4/include/asm-arm/arch-ixp23xx/memory.h
--- 2.2/include/asm-arm/arch-ixp23xx/memory.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-ixp23xx/memory.h	2006-12-22 01:57:07.000000000 +0100
@@ -41,21 +41,7 @@
 	data = *((volatile int *)IXP23XX_PCI_SDRAM_BAR);		\
 	 __phys_to_virt((((b - (data & 0xfffffff0)) + 0x00000000))); })
 
-/*
- * Coherency support.  Only supported on A2 CPUs or on A1
- * systems that have the cache coherency workaround.
- */
-static inline int __ixp23xx_arch_is_coherent(void)
-{
-	extern unsigned int processor_id;
-
-	if (((processor_id & 15) >= 4) || machine_is_roadrunner())
-		return 1;
-
-	return 0;
-}
-
-#define arch_is_coherent()	__ixp23xx_arch_is_coherent()
+#define arch_is_coherent()	1
 
 #endif
 
diff -ru 2.2/include/asm-arm/arch-s3c2410/anubis-cpld.h 3.4/include/asm-arm/arch-s3c2410/anubis-cpld.h
--- 2.2/include/asm-arm/arch-s3c2410/anubis-cpld.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/anubis-cpld.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/anubis-cpld.h
  *
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
  *	http://www.simtec.co.uk/products/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/anubis-irq.h 3.4/include/asm-arm/arch-s3c2410/anubis-irq.h
--- 2.2/include/asm-arm/arch-s3c2410/anubis-irq.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/anubis-irq.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/anubis-irq.h
  *
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
  *	http://www.simtec.co.uk/products/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/anubis-map.h 3.4/include/asm-arm/arch-s3c2410/anubis-map.h
--- 2.2/include/asm-arm/arch-s3c2410/anubis-map.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/anubis-map.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/anubis-map.h
  *
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
  *	http://www.simtec.co.uk/products/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/audio.h 3.4/include/asm-arm/arch-s3c2410/audio.h
--- 2.2/include/asm-arm/arch-s3c2410/audio.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/audio.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/audio.h
  *
- * (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
  *	http://www.simtec.co.uk/products/SWLINUX/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/bast-cpld.h 3.4/include/asm-arm/arch-s3c2410/bast-cpld.h
--- 2.2/include/asm-arm/arch-s3c2410/bast-cpld.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/bast-cpld.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/bast-cpld.h
  *
- * (c) 2003,2004 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * BAST - CPLD control constants
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/bast-irq.h 3.4/include/asm-arm/arch-s3c2410/bast-irq.h
--- 2.2/include/asm-arm/arch-s3c2410/bast-irq.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/bast-irq.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/bast-irq.h
  *
- * (c) 2003,2004 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Machine BAST - IRQ Number definitions
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/bast-map.h 3.4/include/asm-arm/arch-s3c2410/bast-map.h
--- 2.2/include/asm-arm/arch-s3c2410/bast-map.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/bast-map.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/bast-map.h
  *
- * (c) 2003,2004 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Machine BAST - Memory map definitions
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/bast-pmu.h 3.4/include/asm-arm/arch-s3c2410/bast-pmu.h
--- 2.2/include/asm-arm/arch-s3c2410/bast-pmu.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/bast-pmu.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/bast-pmu.h
  *
- * (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003,2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	Vincent Sanders <vince@simtec.co.uk>
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/h1940-latch.h 3.4/include/asm-arm/arch-s3c2410/h1940-latch.h
--- 2.2/include/asm-arm/arch-s3c2410/h1940-latch.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/h1940-latch.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/h1940-latch.h
  *
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
@@ -16,7 +16,7 @@
 
 
 #ifndef __ASSEMBLY__
-#define H1940_LATCH		((void __iomem *)0xF8000000)
+#define H1940_LATCH		((void __force __iomem *)0xF8000000)
 #else
 #define H1940_LATCH		0xF8000000
 #endif
diff -ru 2.2/include/asm-arm/arch-s3c2410/hardware.h 3.4/include/asm-arm/arch-s3c2410/hardware.h
--- 2.2/include/asm-arm/arch-s3c2410/hardware.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/hardware.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/hardware.h
  *
- * (c) 2003 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - hardware
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/iic.h 3.4/include/asm-arm/arch-s3c2410/iic.h
--- 2.2/include/asm-arm/arch-s3c2410/iic.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/iic.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/iic.h
  *
- * (c) 2004 Simtec Electronics
+ * Copyright (c) 2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - I2C Controller platfrom_device info
diff -ru 2.2/include/asm-arm/arch-s3c2410/leds-gpio.h 3.4/include/asm-arm/arch-s3c2410/leds-gpio.h
--- 2.2/include/asm-arm/arch-s3c2410/leds-gpio.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/leds-gpio.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/leds-gpio.h
  *
- * (c) 2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/map.h 3.4/include/asm-arm/arch-s3c2410/map.h
--- 2.2/include/asm-arm/arch-s3c2410/map.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/map.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/map.h
  *
- * (c) 2003 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - Memory map definitions
  *
@@ -25,7 +25,7 @@
  */
 
 #ifndef __ASSEMBLY__
-#define S3C2410_ADDR(x)	  ((void __iomem *)0xF0000000 + (x))
+#define S3C2410_ADDR(x)	  ((void __iomem __force *)0xF0000000 + (x))
 #else
 #define S3C2410_ADDR(x)	  (0xF0000000 + (x))
 #endif
@@ -47,73 +47,65 @@
 #define S3C24XX_SZ_MEMCTRL SZ_1M
 
 /* USB host controller */
-#define S3C24XX_VA_USBHOST S3C2410_ADDR(0x00200000)
 #define S3C2400_PA_USBHOST (0x14200000)
 #define S3C2410_PA_USBHOST (0x49000000)
 #define S3C24XX_SZ_USBHOST SZ_1M
 
 /* DMA controller */
-#define S3C24XX_VA_DMA	   S3C2410_ADDR(0x00300000)
 #define S3C2400_PA_DMA	   (0x14600000)
 #define S3C2410_PA_DMA	   (0x4B000000)
 #define S3C24XX_SZ_DMA	   SZ_1M
 
 /* Clock and Power management */
-#define S3C24XX_VA_CLKPWR  S3C2410_ADDR(0x00400000)
+#define S3C24XX_VA_CLKPWR  S3C2410_ADDR(0x00200000)
 #define S3C2400_PA_CLKPWR  (0x14800000)
 #define S3C2410_PA_CLKPWR  (0x4C000000)
 #define S3C24XX_SZ_CLKPWR  SZ_1M
 
 /* LCD controller */
-#define S3C24XX_VA_LCD	   S3C2410_ADDR(0x00600000)
+#define S3C24XX_VA_LCD	   S3C2410_ADDR(0x00300000)
 #define S3C2400_PA_LCD	   (0x14A00000)
 #define S3C2410_PA_LCD	   (0x4D000000)
 #define S3C24XX_SZ_LCD	   SZ_1M
 
 /* NAND flash controller */
-#define S3C24XX_VA_NAND	   S3C2410_ADDR(0x00700000)
 #define S3C2410_PA_NAND	   (0x4E000000)
 #define S3C24XX_SZ_NAND	   SZ_1M
 
 /* MMC controller - available on the S3C2400 */
-#define S3C2400_VA_MMC 	   S3C2400_ADDR(0x00700000)
 #define S3C2400_PA_MMC 	   (0x15A00000)
 #define S3C2400_SZ_MMC 	   SZ_1M
 
 /* UARTs */
-#define S3C24XX_VA_UART	   S3C2410_ADDR(0x00800000)
+#define S3C24XX_VA_UART	   S3C2410_ADDR(0x00400000)
 #define S3C2400_PA_UART	   (0x15000000)
 #define S3C2410_PA_UART	   (0x50000000)
 #define S3C24XX_SZ_UART	   SZ_1M
 
 /* Timers */
-#define S3C24XX_VA_TIMER   S3C2410_ADDR(0x00900000)
+#define S3C24XX_VA_TIMER   S3C2410_ADDR(0x00500000)
 #define S3C2400_PA_TIMER   (0x15100000)
 #define S3C2410_PA_TIMER   (0x51000000)
 #define S3C24XX_SZ_TIMER   SZ_1M
 
 /* USB Device port */
-#define S3C24XX_VA_USBDEV  S3C2410_ADDR(0x00A00000)
+#define S3C24XX_VA_USBDEV  S3C2410_ADDR(0x00600000)
 #define S3C2400_PA_USBDEV  (0x15200140)
 #define S3C2410_PA_USBDEV  (0x52000000)
 #define S3C24XX_SZ_USBDEV  SZ_1M
 
 /* Watchdog */
-#define S3C24XX_VA_WATCHDOG S3C2410_ADDR(0x00B00000)
+#define S3C24XX_VA_WATCHDOG S3C2410_ADDR(0x00700000)
 #define S3C2400_PA_WATCHDOG (0x15300000)
 #define S3C2410_PA_WATCHDOG (0x53000000)
 #define S3C24XX_SZ_WATCHDOG SZ_1M
 
 /* IIC hardware controller */
-#define S3C24XX_VA_IIC	   S3C2410_ADDR(0x00C00000)
 #define S3C2400_PA_IIC	   (0x15400000)
 #define S3C2410_PA_IIC	   (0x54000000)
 #define S3C24XX_SZ_IIC	   SZ_1M
 
-#define VA_IIC_BASE	   (S3C24XX_VA_IIC)
-
 /* IIS controller */
-#define S3C24XX_VA_IIS	   S3C2410_ADDR(0x00D00000)
 #define S3C2400_PA_IIS	   (0x15508000)
 #define S3C2410_PA_IIS	   (0x55000000)
 #define S3C24XX_SZ_IIS	   SZ_1M
@@ -134,25 +126,21 @@
 #define S3C24XX_SZ_GPIO	   SZ_1M
 
 /* RTC */
-#define S3C24XX_VA_RTC	   S3C2410_ADDR(0x00F00000)
 #define S3C2400_PA_RTC	   (0x15700040)
 #define S3C2410_PA_RTC	   (0x57000000)
 #define S3C24XX_SZ_RTC	   SZ_1M
 
 /* ADC */
-#define S3C24XX_VA_ADC	   S3C2410_ADDR(0x01000000)
 #define S3C2400_PA_ADC	   (0x15800000)
 #define S3C2410_PA_ADC	   (0x58000000)
 #define S3C24XX_SZ_ADC	   SZ_1M
 
 /* SPI */
-#define S3C24XX_VA_SPI	   S3C2410_ADDR(0x01100000)
 #define S3C2400_PA_SPI	   (0x15900000)
 #define S3C2410_PA_SPI	   (0x59000000)
 #define S3C24XX_SZ_SPI	   SZ_1M
 
 /* SDI */
-#define S3C24XX_VA_SDI	   S3C2410_ADDR(0x01200000)
 #define S3C2410_PA_SDI	   (0x5A000000)
 #define S3C24XX_SZ_SDI	   SZ_1M
 
diff -ru 2.2/include/asm-arm/arch-s3c2410/nand.h 3.4/include/asm-arm/arch-s3c2410/nand.h
--- 2.2/include/asm-arm/arch-s3c2410/nand.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/nand.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/nand.h
  *
- * (c) 2004 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - NAND device controller platfrom_device info
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/osiris-cpld.h 3.4/include/asm-arm/arch-s3c2410/osiris-cpld.h
--- 2.2/include/asm-arm/arch-s3c2410/osiris-cpld.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/osiris-cpld.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/osiris-cpld.h
  *
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
  *	http://www.simtec.co.uk/products/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/regs-serial.h 3.4/include/asm-arm/arch-s3c2410/regs-serial.h
--- 2.2/include/asm-arm/arch-s3c2410/regs-serial.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/regs-serial.h	2006-12-22 01:57:07.000000000 +0100
@@ -197,7 +197,7 @@
 	unsigned char	   hwport;	 /* hardware port number */
 	unsigned char	   unused;
 	unsigned short	   flags;
-	unsigned long	   uart_flags;	 /* default uart flags */
+	upf_t		   uart_flags;	 /* default uart flags */
 
 	unsigned long	   ucon;	 /* value of ucon for port */
 	unsigned long	   ulcon;	 /* value of ulcon for port */
diff -ru 2.2/include/asm-arm/arch-s3c2410/system.h 3.4/include/asm-arm/arch-s3c2410/system.h
--- 2.2/include/asm-arm/arch-s3c2410/system.h	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/include/asm-arm/arch-s3c2410/system.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/system.h
  *
- * (c) 2003 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - System function defines and includes
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/timex.h 3.4/include/asm-arm/arch-s3c2410/timex.h
--- 2.2/include/asm-arm/arch-s3c2410/timex.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/timex.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/timex.h
  *
- * (c) 2003-2005 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - time parameters
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/uncompress.h 3.4/include/asm-arm/arch-s3c2410/uncompress.h
--- 2.2/include/asm-arm/arch-s3c2410/uncompress.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/uncompress.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/uncompress.h
  *
- * (c) 2003 Simtec Electronics
- *    Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - uncompress code
  *
@@ -13,6 +13,7 @@
 #ifndef __ASM_ARCH_UNCOMPRESS_H
 #define __ASM_ARCH_UNCOMPRESS_H
 
+typedef unsigned int upf_t;	/* cannot include linux/serial_core.h */
 
 /* defines for UART registers */
 #include "asm/arch/regs-serial.h"
diff -ru 2.2/include/asm-arm/arch-s3c2410/usb-control.h 3.4/include/asm-arm/arch-s3c2410/usb-control.h
--- 2.2/include/asm-arm/arch-s3c2410/usb-control.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/usb-control.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/usb-control.h
  *
- * (c) 2004 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - usb port information
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/vr1000-cpld.h 3.4/include/asm-arm/arch-s3c2410/vr1000-cpld.h
--- 2.2/include/asm-arm/arch-s3c2410/vr1000-cpld.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/vr1000-cpld.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/vr1000-cpld.h
  *
- * (c) 2003 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * VR1000 - CPLD control constants
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/vr1000-irq.h 3.4/include/asm-arm/arch-s3c2410/vr1000-irq.h
--- 2.2/include/asm-arm/arch-s3c2410/vr1000-irq.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/vr1000-irq.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/vr1000-irq.h
  *
- * (c) 2003,2004 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Machine VR1000 - IRQ Number definitions
  *
diff -ru 2.2/include/asm-arm/arch-s3c2410/vr1000-map.h 3.4/include/asm-arm/arch-s3c2410/vr1000-map.h
--- 2.2/include/asm-arm/arch-s3c2410/vr1000-map.h	2006-10-02 17:39:29.000000000 +0200
+++ 3.4/include/asm-arm/arch-s3c2410/vr1000-map.h	2006-12-22 01:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/vr1000-map.h
  *
- * (c) 2003-2005 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Machine VR1000 - Memory map definitions
  *
diff -ru 2.2/include/asm-arm/elf.h 3.4/include/asm-arm/elf.h
--- 2.2/include/asm-arm/elf.h	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/include/asm-arm/elf.h	2006-12-22 01:57:07.000000000 +0100
@@ -52,6 +52,7 @@
 #define HWCAP_EDSP	128
 #define HWCAP_JAVA	256
 #define HWCAP_IWMMXT	512
+#define HWCAP_CRUNCH	1024
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
diff -ru 2.2/include/asm-arm/system.h 3.4/include/asm-arm/system.h
--- 2.2/include/asm-arm/system.h	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/include/asm-arm/system.h	2006-12-22 01:57:07.000000000 +0100
@@ -73,6 +73,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/linkage.h>
+#include <linux/irqflags.h>
 
 struct thread_info;
 struct task_struct;
@@ -139,6 +140,9 @@
 #define	cpu_is_xscale()	1
 #endif
 
+extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
+extern unsigned long cr_alignment;	/* defined in entry-armv.S */
+
 static inline unsigned int get_cr(void)
 {
 	unsigned int val;
@@ -152,6 +156,10 @@
 	  : : "r" (val) : "cc");
 }
 
+#ifndef CONFIG_SMP
+extern void adjust_cr(unsigned long mask, unsigned long set);
+#endif
+
 #define CPACC_FULL(n)		(3 << (n * 2))
 #define CPACC_SVC(n)		(1 << (n * 2))
 #define CPACC_DISABLE(n)	(0 << (n * 2))
@@ -170,29 +178,6 @@
 	  : : "r" (val) : "cc");
 }
 
-extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
-extern unsigned long cr_alignment;	/* defined in entry-armv.S */
-
-#ifndef CONFIG_SMP
-static inline void adjust_cr(unsigned long mask, unsigned long set)
-{
-	unsigned long flags, cr;
-
-	mask &= ~CR_A;
-
-	set &= mask;
-
-	local_irq_save(flags);
-
-	cr_no_alignment = (cr_no_alignment & ~mask) | set;
-	cr_alignment = (cr_alignment & ~mask) | set;
-
-	set_cr((get_cr() & ~mask) | set);
-
-	local_irq_restore(flags);
-}
-#endif
-
 #define UDBG_UNDEFINED	(1 << 0)
 #define UDBG_SYSCALL	(1 << 1)
 #define UDBG_BADABORT	(1 << 2)
@@ -248,8 +233,6 @@
 {
 }
 
-#include <linux/irqflags.h>
-
 #ifdef CONFIG_SMP
 
 #define smp_mb()		mb()
diff -ru 2.2/include/asm-arm/unistd.h 3.4/include/asm-arm/unistd.h
--- 2.2/include/asm-arm/unistd.h	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/include/asm-arm/unistd.h	2006-12-22 01:57:07.000000000 +0100
@@ -360,6 +360,18 @@
 #define __NR_readlinkat			(__NR_SYSCALL_BASE+332)
 #define __NR_fchmodat			(__NR_SYSCALL_BASE+333)
 #define __NR_faccessat			(__NR_SYSCALL_BASE+334)
+					/* 335 for pselect6 */
+					/* 336 for ppoll */
+#define __NR_unshare			(__NR_SYSCALL_BASE+337)
+#define __NR_set_robust_list		(__NR_SYSCALL_BASE+338)
+#define __NR_get_robust_list		(__NR_SYSCALL_BASE+339)
+#define __NR_splice			(__NR_SYSCALL_BASE+340)
+#define __NR_arm_sync_file_range	(__NR_SYSCALL_BASE+341)
+#define __NR_tee			(__NR_SYSCALL_BASE+342)
+#define __NR_vmsplice			(__NR_SYSCALL_BASE+343)
+#define __NR_move_pages			(__NR_SYSCALL_BASE+344)
+#define __NR_getcpu			(__NR_SYSCALL_BASE+345)
+					/* 346 for epoll_pwait */
 
 /*
  * The following SWIs are ARM private.
diff -ru 2.2/include/asm-generic/vmlinux.lds.h 3.4/include/asm-generic/vmlinux.lds.h
--- 2.2/include/asm-generic/vmlinux.lds.h	2006-12-15 20:49:08.000000000 +0100
+++ 3.4/include/asm-generic/vmlinux.lds.h	2006-12-22 01:57:07.000000000 +0100
@@ -35,6 +35,9 @@
 		VMLINUX_SYMBOL(__start_pci_fixups_enable) = .;		\
 		*(.pci_fixup_enable)					\
 		VMLINUX_SYMBOL(__end_pci_fixups_enable) = .;		\
+		VMLINUX_SYMBOL(__start_pci_fixups_resume) = .;		\
+		*(.pci_fixup_resume)					\
+		VMLINUX_SYMBOL(__end_pci_fixups_resume) = .;		\
 	}								\
 									\
 	/* RapidIO route ops */						\
diff -ru 2.2/include/asm-i386/acpi.h 3.4/include/asm-i386/acpi.h
--- 2.2/include/asm-i386/acpi.h	2006-12-02 07:58:09.000000000 +0100
+++ 3.4/include/asm-i386/acpi.h	2006-12-23 16:57:57.000000000 +0100
@@ -56,30 +56,8 @@
 #define ACPI_ENABLE_IRQS()  local_irq_enable()
 #define ACPI_FLUSH_CPU_CACHE()	wbinvd()
 
-
-static inline int
-__acpi_acquire_global_lock (unsigned int *lock)
-{
-	unsigned int old, new, val;
-	do {
-		old = *lock;
-		new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
-		val = cmpxchg(lock, old, new);
-	} while (unlikely (val != old));
-	return (new < 3) ? -1 : 0;
-}
-
-static inline int
-__acpi_release_global_lock (unsigned int *lock)
-{
-	unsigned int old, new, val;
-	do {
-		old = *lock;
-		new = old & ~0x3;
-		val = cmpxchg(lock, old, new);
-	} while (unlikely (val != old));
-	return old & 0x1;
-}
+int __acpi_acquire_global_lock(unsigned int *lock);
+int __acpi_release_global_lock(unsigned int *lock);
 
 #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
 	((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr))
diff -ru 2.2/include/asm-i386/e820.h 3.4/include/asm-i386/e820.h
--- 2.2/include/asm-i386/e820.h	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/include/asm-i386/e820.h	2006-12-23 01:11:19.000000000 +0100
@@ -40,7 +40,7 @@
 			   unsigned type);
 extern void find_max_pfn(void);
 extern void register_bootmem_low_pages(unsigned long max_low_pfn);
-extern void register_memory(void);
+extern void e820_register_memory(void);
 extern void limit_regions(unsigned long long size);
 extern void print_memory_map(char *who);
 
diff -ru 2.2/include/asm-powerpc/spu.h 3.4/include/asm-powerpc/spu.h
--- 2.2/include/asm-powerpc/spu.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/include/asm-powerpc/spu.h	2006-12-22 01:57:07.000000000 +0100
@@ -161,6 +161,7 @@
 extern long spu_sys_callback(struct spu_syscall_block *s);
 
 /* syscalls implemented in spufs */
+struct file;
 extern struct spufs_calls {
 	asmlinkage long (*create_thread)(const char __user *name,
 					unsigned int flags, mode_t mode);
@@ -232,6 +233,7 @@
  * to object-id spufs file from user space and the notifer
  * function can assume that spu->ctx is valid.
  */
+struct notifier_block;
 int spu_switch_event_register(struct notifier_block * n);
 int spu_switch_event_unregister(struct notifier_block * n);
 
diff -ru 2.2/include/asm-sparc/bitops.h 3.4/include/asm-sparc/bitops.h
--- 2.2/include/asm-sparc/bitops.h	2006-10-02 17:39:30.000000000 +0200
+++ 3.4/include/asm-sparc/bitops.h	2006-12-18 04:27:33.000000000 +0100
@@ -14,6 +14,10 @@
 
 #ifdef __KERNEL__
 
+extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
+extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
+extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
+
 /*
  * Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
  * is in the highest of the four bytes and bit '31' is the high bit
@@ -22,134 +26,62 @@
  */
 static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
 {
-	register unsigned long mask asm("g2");
-	register unsigned long *ADDR asm("g1");
-	register int tmp1 asm("g3");
-	register int tmp2 asm("g4");
-	register int tmp3 asm("g5");
-	register int tmp4 asm("g7");
+	unsigned long *ADDR, mask;
 
 	ADDR = ((unsigned long *) addr) + (nr >> 5);
 	mask = 1 << (nr & 31);
 
-	__asm__ __volatile__(
-	"mov	%%o7, %%g4\n\t"
-	"call	___set_bit\n\t"
-	" add	%%o7, 8, %%o7\n"
-	: "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
-	: "0" (mask), "r" (ADDR)
-	: "memory", "cc");
-
-	return mask != 0;
+	return ___set_bit(ADDR, mask) != 0;
 }
 
 static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
 {
-	register unsigned long mask asm("g2");
-	register unsigned long *ADDR asm("g1");
-	register int tmp1 asm("g3");
-	register int tmp2 asm("g4");
-	register int tmp3 asm("g5");
-	register int tmp4 asm("g7");
+	unsigned long *ADDR, mask;
 
 	ADDR = ((unsigned long *) addr) + (nr >> 5);
 	mask = 1 << (nr & 31);
 
-	__asm__ __volatile__(
-	"mov	%%o7, %%g4\n\t"
-	"call	___set_bit\n\t"
-	" add	%%o7, 8, %%o7\n"
-	: "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
-	: "0" (mask), "r" (ADDR)
-	: "memory", "cc");
+	(void) ___set_bit(ADDR, mask);
 }
 
 static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
 {
-	register unsigned long mask asm("g2");
-	register unsigned long *ADDR asm("g1");
-	register int tmp1 asm("g3");
-	register int tmp2 asm("g4");
-	register int tmp3 asm("g5");
-	register int tmp4 asm("g7");
+	unsigned long *ADDR, mask;
 
 	ADDR = ((unsigned long *) addr) + (nr >> 5);
 	mask = 1 << (nr & 31);
 
-	__asm__ __volatile__(
-	"mov	%%o7, %%g4\n\t"
-	"call	___clear_bit\n\t"
-	" add	%%o7, 8, %%o7\n"
-	: "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
-	: "0" (mask), "r" (ADDR)
-	: "memory", "cc");
-
-	return mask != 0;
+	return ___clear_bit(ADDR, mask) != 0;
 }
 
 static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
 {
-	register unsigned long mask asm("g2");
-	register unsigned long *ADDR asm("g1");
-	register int tmp1 asm("g3");
-	register int tmp2 asm("g4");
-	register int tmp3 asm("g5");
-	register int tmp4 asm("g7");
+	unsigned long *ADDR, mask;
 
 	ADDR = ((unsigned long *) addr) + (nr >> 5);
 	mask = 1 << (nr & 31);
 
-	__asm__ __volatile__(
-	"mov	%%o7, %%g4\n\t"
-	"call	___clear_bit\n\t"
-	" add	%%o7, 8, %%o7\n"
-	: "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
-	: "0" (mask), "r" (ADDR)
-	: "memory", "cc");
+	(void) ___clear_bit(ADDR, mask);
 }
 
 static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
 {
-	register unsigned long mask asm("g2");
-	register unsigned long *ADDR asm("g1");
-	register int tmp1 asm("g3");
-	register int tmp2 asm("g4");
-	register int tmp3 asm("g5");
-	register int tmp4 asm("g7");
+	unsigned long *ADDR, mask;
 
 	ADDR = ((unsigned long *) addr) + (nr >> 5);
 	mask = 1 << (nr & 31);
 
-	__asm__ __volatile__(
-	"mov	%%o7, %%g4\n\t"
-	"call	___change_bit\n\t"
-	" add	%%o7, 8, %%o7\n"
-	: "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
-	: "0" (mask), "r" (ADDR)
-	: "memory", "cc");
-
-	return mask != 0;
+	return ___change_bit(ADDR, mask) != 0;
 }
 
 static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
 {
-	register unsigned long mask asm("g2");
-	register unsigned long *ADDR asm("g1");
-	register int tmp1 asm("g3");
-	register int tmp2 asm("g4");
-	register int tmp3 asm("g5");
-	register int tmp4 asm("g7");
+	unsigned long *ADDR, mask;
 
 	ADDR = ((unsigned long *) addr) + (nr >> 5);
 	mask = 1 << (nr & 31);
 
-	__asm__ __volatile__(
-	"mov	%%o7, %%g4\n\t"
-	"call	___change_bit\n\t"
-	" add	%%o7, 8, %%o7\n"
-	: "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
-	: "0" (mask), "r" (ADDR)
-	: "memory", "cc");
+	(void) ___change_bit(ADDR, mask);
 }
 
 #include <asm-generic/bitops/non-atomic.h>
diff -ru 2.2/include/asm-sparc64/hw_irq.h 3.4/include/asm-sparc64/hw_irq.h
--- 2.2/include/asm-sparc64/hw_irq.h	2006-10-02 17:39:31.000000000 +0200
+++ 3.4/include/asm-sparc64/hw_irq.h	2006-12-18 04:27:33.000000000 +0100
@@ -1,6 +1,4 @@
 #ifndef __ASM_SPARC64_HW_IRQ_H
 #define __ASM_SPARC64_HW_IRQ_H
 
-extern void hw_resend_irq(struct hw_interrupt_type *handler, unsigned int virt_irq);
-
 #endif
diff -ru 2.2/include/asm-sparc64/percpu.h 3.4/include/asm-sparc64/percpu.h
--- 2.2/include/asm-sparc64/percpu.h	2006-10-02 17:39:31.000000000 +0200
+++ 3.4/include/asm-sparc64/percpu.h	2006-12-18 04:27:33.000000000 +0100
@@ -5,6 +5,16 @@
 
 #ifdef CONFIG_SMP
 
+#ifdef CONFIG_MODULES
+# define PERCPU_MODULE_RESERVE 8192
+#else
+# define PERCPU_MODULE_RESERVE 0
+#endif
+
+#define PERCPU_ENOUGH_ROOM \
+	(ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES) + \
+	 PERCPU_MODULE_RESERVE)
+
 extern void setup_per_cpu_areas(void);
 
 extern unsigned long __per_cpu_base;
diff -ru 2.2/include/asm-x86_64/acpi.h 3.4/include/asm-x86_64/acpi.h
--- 2.2/include/asm-x86_64/acpi.h	2006-11-20 02:11:28.000000000 +0100
+++ 3.4/include/asm-x86_64/acpi.h	2006-12-23 16:57:57.000000000 +0100
@@ -54,30 +54,8 @@
 #define ACPI_ENABLE_IRQS()  local_irq_enable()
 #define ACPI_FLUSH_CPU_CACHE()	wbinvd()
 
-
-static inline int
-__acpi_acquire_global_lock (unsigned int *lock)
-{
-	unsigned int old, new, val;
-	do {
-		old = *lock;
-		new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
-		val = cmpxchg(lock, old, new);
-	} while (unlikely (val != old));
-	return (new < 3) ? -1 : 0;
-}
-
-static inline int
-__acpi_release_global_lock (unsigned int *lock)
-{
-	unsigned int old, new, val;
-	do {
-		old = *lock;
-		new = old & ~0x3;
-		val = cmpxchg(lock, old, new);
-	} while (unlikely (val != old));
-	return old & 0x1;
-}
+int __acpi_acquire_global_lock(unsigned int *lock);
+int __acpi_release_global_lock(unsigned int *lock);
 
 #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
 	((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr))
diff -ru 2.2/include/linux/backlight.h 3.4/include/linux/backlight.h
--- 2.2/include/linux/backlight.h	2006-10-02 17:39:31.000000000 +0200
+++ 3.4/include/linux/backlight.h	2006-12-23 16:57:57.000000000 +0100
@@ -54,7 +54,7 @@
 };
 
 extern struct backlight_device *backlight_device_register(const char *name,
-	void *devdata, struct backlight_properties *bp);
+	struct device *dev,void *devdata,struct backlight_properties *bp);
 extern void backlight_device_unregister(struct backlight_device *bd);
 
 #define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev)
Only in 3.4/include/linux: .backlight.h.swp
diff -ru 2.2/include/linux/blkdev.h 3.4/include/linux/blkdev.h
--- 2.2/include/linux/blkdev.h	2006-12-13 18:28:47.000000000 +0100
+++ 3.4/include/linux/blkdev.h	2006-12-22 01:57:07.000000000 +0100
@@ -331,10 +331,6 @@
 
 #include <linux/elevator.h>
 
-typedef int (merge_request_fn) (request_queue_t *, struct request *,
-				struct bio *);
-typedef int (merge_requests_fn) (request_queue_t *, struct request *,
-				 struct request *);
 typedef void (request_fn_proc) (request_queue_t *q);
 typedef int (make_request_fn) (request_queue_t *q, struct bio *bio);
 typedef int (prep_rq_fn) (request_queue_t *, struct request *);
@@ -376,9 +372,6 @@
 	struct request_list	rq;
 
 	request_fn_proc		*request_fn;
-	merge_request_fn	*back_merge_fn;
-	merge_request_fn	*front_merge_fn;
-	merge_requests_fn	*merge_requests_fn;
 	make_request_fn		*make_request_fn;
 	prep_rq_fn		*prep_rq_fn;
 	unplug_fn		*unplug_fn;
@@ -649,6 +642,11 @@
 		struct gendisk *, struct scsi_ioctl_command __user *);
 
 /*
+ * Temporary export, until SCSI gets fixed up.
+ */
+extern int ll_back_merge_fn(request_queue_t *, struct request *, struct bio *);
+
+/*
  * A queue has just exitted congestion.  Note this in the global counter of
  * congested queues, and wake up anyone who was waiting for requests to be
  * put back.
@@ -674,7 +672,7 @@
 extern void blk_run_queue(request_queue_t *);
 extern void blk_start_queueing(request_queue_t *);
 extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned long);
-extern int blk_rq_unmap_user(struct request *);
+extern int blk_rq_unmap_user(struct bio *);
 extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, gfp_t);
 extern int blk_rq_map_user_iov(request_queue_t *, struct request *,
 			       struct sg_iovec *, int, unsigned int);
diff -ru 2.2/include/linux/connector.h 3.4/include/linux/connector.h
--- 2.2/include/linux/connector.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/include/linux/connector.h	2006-12-22 01:57:08.000000000 +0100
@@ -133,7 +133,7 @@
 struct cn_callback_entry {
 	struct list_head callback_entry;
 	struct cn_callback *cb;
-	struct delayed_work work;
+	struct work_struct work;
 	struct cn_queue_dev *pdev;
 
 	struct cn_callback_id id;
diff -ru 2.2/include/linux/debug_locks.h 3.4/include/linux/debug_locks.h
--- 2.2/include/linux/debug_locks.h	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/include/linux/debug_locks.h	2006-12-23 01:11:19.000000000 +0100
@@ -24,7 +24,7 @@
 	int __ret = 0;							\
 									\
 	if (unlikely(c)) {						\
-		if (debug_locks_silent || debug_locks_off())		\
+		if (debug_locks_off() && !debug_locks_silent)		\
 			WARN_ON(1);					\
 		__ret = 1;						\
 	}								\
diff -ru 2.2/include/linux/device.h 3.4/include/linux/device.h
--- 2.2/include/linux/device.h	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/include/linux/device.h	2006-12-22 01:57:08.000000000 +0100
@@ -433,6 +433,8 @@
 	return dev->is_registered;
 }
 
+void driver_init(void);
+
 /*
  * High level routines for use by the bus drivers
  */
diff -ru 2.2/include/linux/elevator.h 3.4/include/linux/elevator.h
--- 2.2/include/linux/elevator.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/include/linux/elevator.h	2006-12-22 01:57:08.000000000 +0100
@@ -12,6 +12,8 @@
 
 typedef void (elevator_merged_fn) (request_queue_t *, struct request *, int);
 
+typedef int (elevator_allow_merge_fn) (request_queue_t *, struct request *, struct bio *);
+
 typedef int (elevator_dispatch_fn) (request_queue_t *, int);
 
 typedef void (elevator_add_req_fn) (request_queue_t *, struct request *);
@@ -33,6 +35,7 @@
 	elevator_merge_fn *elevator_merge_fn;
 	elevator_merged_fn *elevator_merged_fn;
 	elevator_merge_req_fn *elevator_merge_req_fn;
+	elevator_allow_merge_fn *elevator_allow_merge_fn;
 
 	elevator_dispatch_fn *elevator_dispatch_fn;
 	elevator_add_req_fn *elevator_add_req_fn;
diff -ru 2.2/include/linux/file.h 3.4/include/linux/file.h
--- 2.2/include/linux/file.h	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/include/linux/file.h	2006-12-23 01:11:19.000000000 +0100
@@ -80,6 +80,11 @@
 extern void free_fdtable_rcu(struct rcu_head *rcu);
 extern void __init files_defer_init(void);
 
+static inline void free_fdtable(struct fdtable *fdt)
+{
+	call_rcu(&fdt->rcu, free_fdtable_rcu);
+}
+
 static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
 {
 	struct file * file = NULL;
diff -ru 2.2/include/linux/genhd.h 3.4/include/linux/genhd.h
--- 2.2/include/linux/genhd.h	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/include/linux/genhd.h	2006-12-19 14:47:35.000000000 +0100
@@ -20,6 +20,8 @@
 	LINUX_EXTENDED_PARTITION = 0x85,
 	WIN98_EXTENDED_PARTITION = 0x0f,
 
+	SUN_WHOLE_DISK = DOS_EXTENDED_PARTITION,
+
 	LINUX_SWAP_PARTITION = 0x82,
 	LINUX_RAID_PARTITION = 0xfd,	/* autodetect RAID partition */
 
@@ -400,10 +402,14 @@
 
 #ifdef __KERNEL__
 
+#define ADDPART_FLAG_NONE	0
+#define ADDPART_FLAG_RAID	1
+#define ADDPART_FLAG_WHOLEDISK	2
+
 char *disk_name (struct gendisk *hd, int part, char *buf);
 
 extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
-extern void add_partition(struct gendisk *, int, sector_t, sector_t);
+extern void add_partition(struct gendisk *, int, sector_t, sector_t, int);
 extern void delete_partition(struct gendisk *, int);
 
 extern struct gendisk *alloc_disk_node(int minors, int node_id);
diff -ru 2.2/include/linux/if_fddi.h 3.4/include/linux/if_fddi.h
--- 2.2/include/linux/if_fddi.h	2006-10-02 17:39:32.000000000 +0200
+++ 3.4/include/linux/if_fddi.h	2006-12-23 01:11:19.000000000 +0100
@@ -103,6 +103,8 @@
 	} __attribute__ ((packed));
 
 #ifdef __KERNEL__
+#include <linux/netdevice.h>
+
 /* Define FDDI statistics structure */
 struct fddi_statistics {
 
diff -ru 2.2/include/linux/input.h 3.4/include/linux/input.h
--- 2.2/include/linux/input.h	2006-12-08 14:37:38.000000000 +0100
+++ 3.4/include/linux/input.h	2006-12-22 01:57:08.000000000 +0100
@@ -491,6 +491,21 @@
 #define KEY_DIGITS		0x19d
 #define KEY_TEEN		0x19e
 #define KEY_TWEN		0x19f
+#define KEY_VIDEOPHONE		0x1a0
+#define KEY_GAMES		0x1a1
+#define KEY_ZOOMIN		0x1a2
+#define KEY_ZOOMOUT		0x1a3
+#define KEY_ZOOMRESET		0x1a4
+#define KEY_WORDPROCESSOR	0x1a5
+#define KEY_EDITOR		0x1a6
+#define KEY_SPREADSHEET		0x1a7
+#define KEY_GRAPHICSEDITOR	0x1a8
+#define KEY_PRESENTATION	0x1a9
+#define KEY_DATABASE		0x1aa
+#define KEY_NEWS		0x1ab
+#define KEY_VOICEMAIL		0x1ac
+#define KEY_ADDRESSBOOK		0x1ad
+#define KEY_MESSENGER		0x1ae
 
 #define KEY_DEL_EOL		0x1c0
 #define KEY_DEL_EOS		0x1c1
diff -ru 2.2/include/linux/ioport.h 3.4/include/linux/ioport.h
--- 2.2/include/linux/ioport.h	2006-12-08 19:31:48.000000000 +0100
+++ 3.4/include/linux/ioport.h	2006-12-22 01:57:08.000000000 +0100
@@ -91,6 +91,9 @@
 #define IORESOURCE_ROM_COPY		(1<<2)	/* ROM is alloc'd copy, resource field overlaid */
 #define IORESOURCE_ROM_BIOS_COPY	(1<<3)	/* ROM is BIOS copy, resource field overlaid */
 
+/* PCI control bits.  Shares IORESOURCE_BITS with above PCI ROM.  */
+#define IORESOURCE_PCI_FIXED		(1<<4)	/* Do not move resource */
+
 /* PC/ISA/whatever - the normal PC address spaces: IO and memory */
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
diff -ru 2.2/include/linux/Kbuild 3.4/include/linux/Kbuild
--- 2.2/include/linux/Kbuild	2006-12-10 23:31:29.000000000 +0100
+++ 3.4/include/linux/Kbuild	2006-12-23 01:11:21.000000000 +0100
@@ -119,7 +119,6 @@
 header-y += nfs_mount.h
 header-y += oom.h
 header-y += param.h
-header-y += pci_ids.h
 header-y += pci_regs.h
 header-y += personality.h
 header-y += pfkeyv2.h
@@ -138,7 +137,6 @@
 header-y += raw.h
 header-y += resource.h
 header-y += rose.h
-header-y += sctp.h
 header-y += smbno.h
 header-y += snmp.h
 header-y += sockios.h
@@ -162,7 +160,6 @@
 header-y += wireless.h
 header-y += xattr.h
 header-y += x25.h
-header-y += zorro_ids.h
 
 unifdef-y += acct.h
 unifdef-y += adb.h
diff -ru 2.2/include/linux/kobject.h 3.4/include/linux/kobject.h
--- 2.2/include/linux/kobject.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/include/linux/kobject.h	2006-12-22 01:57:08.000000000 +0100
@@ -265,8 +265,8 @@
 					struct subsys_attribute *);
 
 #if defined(CONFIG_HOTPLUG)
-void kobject_uevent(struct kobject *kobj, enum kobject_action action);
-void kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
+int kobject_uevent(struct kobject *kobj, enum kobject_action action);
+int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
 			char *envp[]);
 
 int add_uevent_var(char **envp, int num_envp, int *cur_index,
@@ -274,11 +274,12 @@
 			const char *format, ...)
 	__attribute__((format (printf, 7, 8)));
 #else
-static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { }
-static inline void kobject_uevent_env(struct kobject *kobj,
+static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action)
+{ return 0; }
+static inline int kobject_uevent_env(struct kobject *kobj,
 				      enum kobject_action action,
 				      char *envp[])
-{ }
+{ return 0; }
 
 static inline int add_uevent_var(char **envp, int num_envp, int *cur_index,
 				      char *buffer, int buffer_size, int *cur_len, 
diff -ru 2.2/include/linux/kvm.h 3.4/include/linux/kvm.h
--- 2.2/include/linux/kvm.h	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/include/linux/kvm.h	2006-12-23 01:11:19.000000000 +0100
@@ -11,6 +11,8 @@
 #include <asm/types.h>
 #include <linux/ioctl.h>
 
+#define KVM_API_VERSION 1
+
 /*
  * Architectural interrupt line count, and the size of the bitmap needed
  * to hold them.
@@ -209,6 +211,7 @@
 
 #define KVMIO 0xAE
 
+#define KVM_GET_API_VERSION       _IO(KVMIO, 1)
 #define KVM_RUN                   _IOWR(KVMIO, 2, struct kvm_run)
 #define KVM_GET_REGS              _IOWR(KVMIO, 3, struct kvm_regs)
 #define KVM_SET_REGS              _IOW(KVMIO, 4, struct kvm_regs)
diff -ru 2.2/include/linux/page-flags.h 3.4/include/linux/page-flags.h
--- 2.2/include/linux/page-flags.h	2006-10-02 17:39:32.000000000 +0200
+++ 3.4/include/linux/page-flags.h	2006-12-22 01:57:08.000000000 +0100
@@ -253,15 +253,11 @@
 
 struct page;	/* forward declaration */
 
-int test_clear_page_dirty(struct page *page);
+extern void cancel_dirty_page(struct page *page, unsigned int account_size);
+
 int test_clear_page_writeback(struct page *page);
 int test_set_page_writeback(struct page *page);
 
-static inline void clear_page_dirty(struct page *page)
-{
-	test_clear_page_dirty(page);
-}
-
 static inline void set_page_writeback(struct page *page)
 {
 	test_set_page_writeback(page);
diff -ru 2.2/include/linux/pci.h 3.4/include/linux/pci.h
--- 2.2/include/linux/pci.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/include/linux/pci.h	2006-12-22 01:57:08.000000000 +0100
@@ -20,9 +20,6 @@
 /* Include the pci register defines */
 #include <linux/pci_regs.h>
 
-/* Include the ID list */
-#include <linux/pci_ids.h>
-
 /*
  * The PCI interface treats multi-function devices as independent
  * devices.  The slot/function address of each device is encoded
@@ -54,6 +51,9 @@
 #include <asm/atomic.h>
 #include <linux/device.h>
 
+/* Include the ID list */
+#include <linux/pci_ids.h>
+
 /* File state for mmap()s on /proc/bus/pci/X/Y */
 enum pci_mmap_state {
 	pci_mmap_io,
@@ -396,6 +396,21 @@
  */
 #define pci_module_init	pci_register_driver
 
+/**
+ * PCI_VDEVICE - macro used to describe a specific pci device in short form
+ * @vend: the vendor name
+ * @dev: the 16 bit PCI Device ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific PCI device.  The subvendor, and subdevice fields will be set
+ * to PCI_ANY_ID. The macro allows the next field to follow as the device
+ * private data.
+ */
+
+#define PCI_VDEVICE(vendor, device)		\
+	PCI_VENDOR_ID_##vendor, (device),	\
+	PCI_ANY_ID, PCI_ANY_ID, 0, 0
+
 /* these external functions are only available when PCI support is enabled */
 #ifdef CONFIG_PCI
 
@@ -454,6 +469,8 @@
 int pci_find_capability (struct pci_dev *dev, int cap);
 int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
 int pci_find_ext_capability (struct pci_dev *dev, int cap);
+int pci_find_ht_capability (struct pci_dev *dev, int ht_cap);
+int pci_find_next_ht_capability (struct pci_dev *dev, int pos, int ht_cap);
 struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
 
 struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
@@ -468,6 +485,7 @@
 struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn);
 struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from);
 int pci_dev_present(const struct pci_device_id *ids);
+const struct pci_device_id *pci_find_present(const struct pci_device_id *ids);
 
 int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
 int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
@@ -681,6 +699,7 @@
 { return NULL; }
 
 #define pci_dev_present(ids)	(0)
+#define pci_find_present(ids)	(NULL)
 #define pci_dev_put(dev)	do { } while (0)
 
 static inline void pci_set_master(struct pci_dev *dev) { }
@@ -783,6 +802,7 @@
 	pci_fixup_header,	/* After reading configuration header */
 	pci_fixup_final,	/* Final phase of device fixups */
 	pci_fixup_enable,	/* pci_enable_device() time */
+	pci_fixup_resume,	/* pci_enable_device() time */
 };
 
 /* Anonymous variables would be nice... */
@@ -801,6 +821,9 @@
 #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook)			\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable,			\
 			vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook)			\
+	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume,			\
+			resume##vendor##device##hook, vendor, device, hook)
 
 
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
diff -ru 2.2/include/linux/pci_ids.h 3.4/include/linux/pci_ids.h
--- 2.2/include/linux/pci_ids.h	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/include/linux/pci_ids.h	2006-12-22 01:57:08.000000000 +0100
@@ -104,6 +104,10 @@
 #define PCI_CLASS_SERIAL_FIBER		0x0c04
 #define PCI_CLASS_SERIAL_SMBUS		0x0c05
 
+#define PCI_BASE_CLASS_WIRELESS			0x0d
+#define PCI_CLASS_WIRELESS_RF_CONTROLLER	0x0d10
+#define PCI_CLASS_WIRELESS_WHCI			0x0d1010
+
 #define PCI_BASE_CLASS_INTELLIGENT	0x0e
 #define PCI_CLASS_INTELLIGENT_I2O	0x0e00
 
diff -ru 2.2/include/linux/pci_regs.h 3.4/include/linux/pci_regs.h
--- 2.2/include/linux/pci_regs.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/include/linux/pci_regs.h	2006-12-22 01:57:08.000000000 +0100
@@ -475,15 +475,32 @@
 #define PCI_PWR_CAP		12	/* Capability */
 #define  PCI_PWR_CAP_BUDGET(x)	((x) & 1)	/* Included in system budget */
 
-/* Hypertransport sub capability types */
+/*
+ * Hypertransport sub capability types
+ *
+ * Unfortunately there are both 3 bit and 5 bit capability types defined
+ * in the HT spec, catering for that is a little messy. You probably don't
+ * want to use these directly, just use pci_find_ht_capability() and it
+ * will do the right thing for you.
+ */
+#define HT_3BIT_CAP_MASK	0xE0
 #define HT_CAPTYPE_SLAVE	0x00	/* Slave/Primary link configuration */
 #define HT_CAPTYPE_HOST		0x20	/* Host/Secondary link configuration */
+
+#define HT_5BIT_CAP_MASK	0xF8
 #define HT_CAPTYPE_IRQ		0x80	/* IRQ Configuration */
 #define HT_CAPTYPE_REMAPPING_40	0xA0	/* 40 bit address remapping */
 #define HT_CAPTYPE_REMAPPING_64 0xA2	/* 64 bit address remapping */
 #define HT_CAPTYPE_UNITID_CLUMP	0x90	/* Unit ID clumping */
 #define HT_CAPTYPE_EXTCONF	0x98	/* Extended Configuration Space Access */
 #define HT_CAPTYPE_MSI_MAPPING	0xA8	/* MSI Mapping Capability */
+#define  HT_MSI_FLAGS		0x02		/* Offset to flags */
+#define  HT_MSI_FLAGS_ENABLE	0x1		/* Mapping enable */
+#define  HT_MSI_FLAGS_FIXED	0x2		/* Fixed mapping only */
+#define  HT_MSI_FIXED_ADDR	0x00000000FEE00000ULL	/* Fixed addr */
+#define  HT_MSI_ADDR_LO		0x04		/* Offset to low addr bits */
+#define  HT_MSI_ADDR_LO_MASK	0xFFF00000	/* Low address bit mask */
+#define  HT_MSI_ADDR_HI		0x08		/* Offset to high addr bits */
 #define HT_CAPTYPE_DIRECT_ROUTE	0xB0	/* Direct routing configuration */
 #define HT_CAPTYPE_VCSET	0xB8	/* Virtual Channel configuration */
 #define HT_CAPTYPE_ERROR_RETRY	0xC0	/* Retry on error configuration */
diff -ru 2.2/include/linux/rmap.h 3.4/include/linux/rmap.h
--- 2.2/include/linux/rmap.h	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/include/linux/rmap.h	2006-12-23 01:11:19.000000000 +0100
@@ -72,7 +72,7 @@
 void page_add_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
 void page_add_new_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
 void page_add_file_rmap(struct page *);
-void page_remove_rmap(struct page *);
+void page_remove_rmap(struct page *, struct vm_area_struct *);
 
 /**
  * page_dup_rmap - duplicate pte mapping to a page
diff -ru 2.2/include/linux/sctp.h 3.4/include/linux/sctp.h
--- 2.2/include/linux/sctp.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/include/linux/sctp.h	2006-12-23 01:11:19.000000000 +0100
@@ -180,7 +180,7 @@
 	SCTP_PARAM_ERR_CAUSE		= __constant_htons(0xc003),
 	SCTP_PARAM_SET_PRIMARY		= __constant_htons(0xc004),
 	SCTP_PARAM_SUCCESS_REPORT	= __constant_htons(0xc005),
-	SCTP_PARAM_ADAPTION_LAYER_IND   = __constant_htons(0xc006),
+	SCTP_PARAM_ADAPTATION_LAYER_IND = __constant_htons(0xc006),
 
 } sctp_param_t; /* enum */
 
@@ -281,11 +281,11 @@
 	sctp_paramhdr_t param_hdr;
 } __attribute__((packed)) sctp_ecn_capable_param_t;
 
-/* ADDIP Section 3.2.6 Adaption Layer Indication */
-typedef struct sctp_adaption_ind_param {
+/* ADDIP Section 3.2.6 Adaptation Layer Indication */
+typedef struct sctp_adaptation_ind_param {
 	struct sctp_paramhdr param_hdr;
-	__be32 adaption_ind;
-} __attribute__((packed)) sctp_adaption_ind_param_t;
+	__be32 adaptation_ind;
+} __attribute__((packed)) sctp_adaptation_ind_param_t;
 
 /* RFC 2960.  Section 3.3.3 Initiation Acknowledgement (INIT ACK) (2):
  *   The INIT ACK chunk is used to acknowledge the initiation of an SCTP
diff -ru 2.2/include/linux/vmstat.h 3.4/include/linux/vmstat.h
--- 2.2/include/linux/vmstat.h	2006-10-02 17:39:32.000000000 +0200
+++ 3.4/include/linux/vmstat.h	2006-12-23 01:11:19.000000000 +0100
@@ -10,8 +10,9 @@
 /*
  * Light weight per cpu counter implementation.
  *
- * Counters should only be incremented and no critical kernel component
- * should rely on the counter values.
+ * Counters should only be incremented.  You need to set EMBEDDED
+ * to disable VM_EVENT_COUNTERS.  Things like procps (vmstat,
+ * top, etc) use /proc/vmstat and depend on these counters.
  *
  * Counters are handled completely inline. On many platforms the code
  * generated will simply be the increment of a global address.
@@ -73,7 +74,13 @@
 }
 
 extern void all_vm_events(unsigned long *);
+#ifdef CONFIG_HOTPLUG
 extern void vm_events_fold_cpu(int cpu);
+#else
+static inline void vm_events_fold_cpu(int cpu)
+{
+}
+#endif
 
 #else
 
diff -ru 2.2/include/linux/workqueue.h 3.4/include/linux/workqueue.h
--- 2.2/include/linux/workqueue.h	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/include/linux/workqueue.h	2006-12-16 22:22:59.000000000 +0100
@@ -8,16 +8,21 @@
 #include <linux/timer.h>
 #include <linux/linkage.h>
 #include <linux/bitops.h>
+#include <asm/atomic.h>
 
 struct workqueue_struct;
 
 struct work_struct;
 typedef void (*work_func_t)(struct work_struct *work);
 
+/*
+ * The first word is the work queue pointer and the flags rolled into
+ * one
+ */
+#define work_data_bits(work) ((unsigned long *)(&(work)->data))
+
 struct work_struct {
-	/* the first word is the work queue pointer and the flags rolled into
-	 * one */
-	unsigned long management;
+	atomic_long_t data;
 #define WORK_STRUCT_PENDING 0		/* T if work item pending execution */
 #define WORK_STRUCT_NOAUTOREL 1		/* F if work item automatically released on exec */
 #define WORK_STRUCT_FLAG_MASK (3UL)
@@ -26,6 +31,9 @@
 	work_func_t func;
 };
 
+#define WORK_DATA_INIT(autorelease) \
+	ATOMIC_LONG_INIT((autorelease) << WORK_STRUCT_NOAUTOREL)
+
 struct delayed_work {
 	struct work_struct work;
 	struct timer_list timer;
@@ -36,13 +44,13 @@
 };
 
 #define __WORK_INITIALIZER(n, f) {				\
-	.management = 0,					\
+	.data = WORK_DATA_INIT(0),				\
         .entry	= { &(n).entry, &(n).entry },			\
 	.func = (f),						\
 	}
 
 #define __WORK_INITIALIZER_NAR(n, f) {				\
-	.management = (1 << WORK_STRUCT_NOAUTOREL),		\
+	.data = WORK_DATA_INIT(1),				\
         .entry	= { &(n).entry, &(n).entry },			\
 	.func = (f),						\
 	}
@@ -82,17 +90,21 @@
 
 /*
  * initialize all of a work item in one go
+ *
+ * NOTE! No point in using "atomic_long_set()": useing a direct
+ * assignment of the work data initializer allows the compiler
+ * to generate better code.
  */
 #define INIT_WORK(_work, _func)					\
 	do {							\
-		(_work)->management = 0;			\
+		(_work)->data = (atomic_long_t) WORK_DATA_INIT(0);	\
 		INIT_LIST_HEAD(&(_work)->entry);		\
 		PREPARE_WORK((_work), (_func));			\
 	} while (0)
 
 #define INIT_WORK_NAR(_work, _func)					\
 	do {								\
-		(_work)->management = (1 << WORK_STRUCT_NOAUTOREL);	\
+		(_work)->data = (atomic_long_t) WORK_DATA_INIT(1);	\
 		INIT_LIST_HEAD(&(_work)->entry);			\
 		PREPARE_WORK((_work), (_func));				\
 	} while (0)
@@ -114,15 +126,15 @@
  * @work: The work item in question
  */
 #define work_pending(work) \
-	test_bit(WORK_STRUCT_PENDING, &(work)->management)
+	test_bit(WORK_STRUCT_PENDING, work_data_bits(work))
 
 /**
  * delayed_work_pending - Find out whether a delayable work item is currently
  * pending
  * @work: The work item in question
  */
-#define delayed_work_pending(work) \
-	test_bit(WORK_STRUCT_PENDING, &(work)->work.management)
+#define delayed_work_pending(w) \
+	work_pending(&(w)->work)
 
 /**
  * work_release - Release a work item under execution
@@ -143,7 +155,7 @@
  * This should also be used to release a delayed work item.
  */
 #define work_release(work) \
-	clear_bit(WORK_STRUCT_PENDING, &(work)->management)
+	clear_bit(WORK_STRUCT_PENDING, work_data_bits(work))
 
 
 extern struct workqueue_struct *__create_workqueue(const char *name,
@@ -188,7 +200,7 @@
 
 	ret = del_timer_sync(&work->timer);
 	if (ret)
-		clear_bit(WORK_STRUCT_PENDING, &work->work.management);
+		work_release(&work->work);
 	return ret;
 }
 
diff -ru 2.2/include/net/ax25.h 3.4/include/net/ax25.h
--- 2.2/include/net/ax25.h	2006-12-12 05:42:34.000000000 +0100
+++ 3.4/include/net/ax25.h	2006-12-22 01:57:08.000000000 +0100
@@ -277,7 +277,7 @@
 extern ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
 extern void ax25_send_to_raw(ax25_address *, struct sk_buff *, int);
 extern void ax25_destroy_socket(ax25_cb *);
-extern ax25_cb *ax25_create_cb(void);
+extern ax25_cb * __must_check ax25_create_cb(void);
 extern void ax25_fillin_cb(ax25_cb *, ax25_dev *);
 extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
 
@@ -333,11 +333,25 @@
 extern void ax25_ds_idletimer_expiry(ax25_cb *);
 
 /* ax25_iface.c */
-extern int  ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *));
+
+struct ax25_protocol {
+	struct ax25_protocol *next;
+	unsigned int pid;
+	int (*func)(struct sk_buff *, ax25_cb *);
+};
+
+extern void ax25_register_pid(struct ax25_protocol *ap);
 extern void ax25_protocol_release(unsigned int);
-extern int  ax25_linkfail_register(void (*)(ax25_cb *, int));
-extern void ax25_linkfail_release(void (*)(ax25_cb *, int));
-extern int  ax25_listen_register(ax25_address *, struct net_device *);
+
+struct ax25_linkfail {
+	struct hlist_node lf_node;
+	void (*func)(ax25_cb *, int);
+};
+
+extern void ax25_linkfail_register(struct ax25_linkfail *lf);
+extern void ax25_linkfail_release(struct ax25_linkfail *lf);
+extern int __must_check ax25_listen_register(ax25_address *,
+	struct net_device *);
 extern void ax25_listen_release(ax25_address *, struct net_device *);
 extern int  (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *);
 extern int  ax25_listen_mine(ax25_address *, struct net_device *);
@@ -415,7 +429,7 @@
 /* ax25_uid.c */
 extern int  ax25_uid_policy;
 extern ax25_uid_assoc *ax25_findbyuid(uid_t);
-extern int  ax25_uid_ioctl(int, struct sockaddr_ax25 *);
+extern int __must_check ax25_uid_ioctl(int, struct sockaddr_ax25 *);
 extern struct file_operations ax25_uid_fops;
 extern void ax25_uid_free(void);
 
diff -ru 2.2/include/net/ip6_checksum.h 3.4/include/net/ip6_checksum.h
--- 2.2/include/net/ip6_checksum.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/include/net/ip6_checksum.h	2006-12-23 01:11:19.000000000 +0100
@@ -87,7 +87,7 @@
 	carry = (sum < uproto);
 	sum += carry;
 
-	return csum_fold((__force __wsum)csum);
+	return csum_fold((__force __wsum)sum);
 }
 
 #endif
diff -ru 2.2/include/net/rose.h 3.4/include/net/rose.h
--- 2.2/include/net/rose.h	2006-10-02 17:39:32.000000000 +0200
+++ 3.4/include/net/rose.h	2006-12-22 01:57:08.000000000 +0100
@@ -188,13 +188,13 @@
 extern void rose_enquiry_response(struct sock *);
 
 /* rose_route.c */
-extern struct rose_neigh *rose_loopback_neigh;
+extern struct rose_neigh rose_loopback_neigh;
 extern struct file_operations rose_neigh_fops;
 extern struct file_operations rose_nodes_fops;
 extern struct file_operations rose_routes_fops;
 
-extern int  rose_add_loopback_neigh(void);
-extern int  rose_add_loopback_node(rose_address *);
+extern void rose_add_loopback_neigh(void);
+extern int __must_check rose_add_loopback_node(rose_address *);
 extern void rose_del_loopback_node(rose_address *);
 extern void rose_rt_device_down(struct net_device *);
 extern void rose_link_device_down(struct net_device *);
diff -ru 2.2/include/net/sctp/sctp.h 3.4/include/net/sctp/sctp.h
--- 2.2/include/net/sctp/sctp.h	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/include/net/sctp/sctp.h	2006-12-23 01:11:19.000000000 +0100
@@ -128,8 +128,6 @@
 				     int flags);
 extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
 extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
-int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
-                        void *ptr);
 
 /*
  * sctp/socket.c
diff -ru 2.2/include/net/sctp/structs.h 3.4/include/net/sctp/structs.h
--- 2.2/include/net/sctp/structs.h	2006-12-14 04:27:37.000000000 +0100
+++ 3.4/include/net/sctp/structs.h	2006-12-23 01:11:19.000000000 +0100
@@ -306,7 +306,7 @@
 	__u8 disable_fragments;
 	__u8 pd_mode;
 	__u8 v4mapped;
-	__u32 adaption_ind;
+	__u32 adaptation_ind;
 
 	/* Receive to here while partial delivery is in effect. */
 	struct sk_buff_head pd_lobby;
@@ -388,7 +388,7 @@
 	/* Padding for future use */
 	__u8 padding;  		
 
-	__u32 adaption_ind;	
+	__u32 adaptation_ind;
 
 
 	/* This is a shim for my peer's INIT packet, followed by
@@ -431,7 +431,7 @@
 	struct sctp_ipv4addr_param *v4;
 	struct sctp_ipv6addr_param *v6;
 	union sctp_addr_param *addr;
-	struct sctp_adaption_ind_param *aind;
+	struct sctp_adaptation_ind_param *aind;
 };
 
 /* RFC 2960.  Section 3.3.5 Heartbeat.
@@ -1483,7 +1483,7 @@
 		__u8    asconf_capable;  /* Does peer support ADDIP? */
 		__u8    prsctp_capable;  /* Can peer do PR-SCTP? */
 
-		__u32   adaption_ind;	 /* Adaption Code point. */
+		__u32   adaptation_ind;	 /* Adaptation Code point. */
 
 		/* This mask is used to disable sending the ASCONF chunk
 		 * with specified parameter to peer.
diff -ru 2.2/include/net/sctp/ulpevent.h 3.4/include/net/sctp/ulpevent.h
--- 2.2/include/net/sctp/ulpevent.h	2006-10-13 04:58:10.000000000 +0200
+++ 3.4/include/net/sctp/ulpevent.h	2006-12-23 01:11:19.000000000 +0100
@@ -120,7 +120,7 @@
 	const struct sctp_association *asoc,
 	__u32 indication, gfp_t gfp);
 
-struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication(
+struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication(
 	const struct sctp_association *asoc, gfp_t gfp);
 
 struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
diff -ru 2.2/include/net/sctp/user.h 3.4/include/net/sctp/user.h
--- 2.2/include/net/sctp/user.h	2006-12-14 04:27:37.000000000 +0100
+++ 3.4/include/net/sctp/user.h	2006-12-23 01:11:19.000000000 +0100
@@ -75,8 +75,8 @@
 #define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR
 	SCTP_PRIMARY_ADDR,
 #define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR
-	SCTP_ADAPTION_LAYER,      
-#define SCTP_ADAPTION_LAYER SCTP_ADAPTION_LAYER
+	SCTP_ADAPTATION_LAYER,
+#define SCTP_ADAPTATION_LAYER SCTP_ADAPTATION_LAYER
 	SCTP_DISABLE_FRAGMENTS,
 #define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS
 	SCTP_PEER_ADDR_PARAMS,
@@ -331,17 +331,17 @@
 };
 
 /*
- * 5.3.1.6 SCTP_ADAPTION_INDICATION
+ * 5.3.1.6 SCTP_ADAPTATION_INDICATION
  *
- *   When a peer sends a Adaption Layer Indication parameter , SCTP
+ *   When a peer sends a Adaptation Layer Indication parameter , SCTP
  *   delivers this notification to inform the application
- *   that of the peers requested adaption layer.
+ *   that of the peers requested adaptation layer.
  */
-struct sctp_adaption_event {
+struct sctp_adaptation_event {
 	__u16 sai_type;
 	__u16 sai_flags;
 	__u32 sai_length;
-	__u32 sai_adaption_ind;
+	__u32 sai_adaptation_ind;
 	sctp_assoc_t sai_assoc_id;
 };
 
@@ -374,7 +374,7 @@
 	__u8 sctp_peer_error_event;
 	__u8 sctp_shutdown_event;
 	__u8 sctp_partial_delivery_event;
-	__u8 sctp_adaption_layer_event;
+	__u8 sctp_adaptation_layer_event;
 };
 
 /*
@@ -395,7 +395,7 @@
 	struct sctp_remote_error sn_remote_error;
 	struct sctp_send_failed sn_send_failed;
 	struct sctp_shutdown_event sn_shutdown_event;
-	struct sctp_adaption_event sn_adaption_event;
+	struct sctp_adaptation_event sn_adaptation_event;
 	struct sctp_pdapi_event sn_pdapi_event;
 };
 
@@ -412,7 +412,7 @@
 	SCTP_REMOTE_ERROR,
 	SCTP_SHUTDOWN_EVENT,
 	SCTP_PARTIAL_DELIVERY_EVENT,
-	SCTP_ADAPTION_INDICATION,
+	SCTP_ADAPTATION_INDICATION,
 };
 
 /* Notification error codes used to fill up the error fields in some
@@ -488,13 +488,13 @@
 } __attribute__((packed, aligned(4)));
 
 /*
- * 7.1.11 Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER)
+ * 7.1.11 Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER)
  *
- * Requests that the local endpoint set the specified Adaption Layer
+ * Requests that the local endpoint set the specified Adaptation Layer
  * Indication parameter for all future INIT and INIT-ACK exchanges.
  */
-struct sctp_setadaption {
-	__u32	ssb_adaption_ind;
+struct sctp_setadaptation {
+	__u32	ssb_adaptation_ind;
 };
 
 /*
diff -ru 2.2/include/net/tcp.h 3.4/include/net/tcp.h
--- 2.2/include/net/tcp.h	2006-12-07 02:52:15.000000000 +0100
+++ 3.4/include/net/tcp.h	2006-12-23 01:11:19.000000000 +0100
@@ -242,14 +242,9 @@
 
 static inline int before(__u32 seq1, __u32 seq2)
 {
-        return (__s32)(seq1-seq2) < 0;
+        return (__s32)(seq2-seq1) > 0;
 }
-
-static inline int after(__u32 seq1, __u32 seq2)
-{
-	return (__s32)(seq2-seq1) < 0;
-}
-
+#define after(seq2, seq1) 	before(seq1, seq2)
 
 /* is s2<=s1<=s3 ? */
 static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
diff -ru 2.2/include/rdma/ib_verbs.h 3.4/include/rdma/ib_verbs.h
--- 2.2/include/rdma/ib_verbs.h	2006-12-14 20:31:28.000000000 +0100
+++ 3.4/include/rdma/ib_verbs.h	2006-12-18 04:27:33.000000000 +0100
@@ -1639,7 +1639,14 @@
 {
 	if (dev->dma_ops)
 		return dev->dma_ops->alloc_coherent(dev, size, dma_handle, flag);
-	return dma_alloc_coherent(dev->dma_device, size, dma_handle, flag);
+	else {
+		dma_addr_t handle;
+		void *ret;
+
+		ret = dma_alloc_coherent(dev->dma_device, size, &handle, flag);
+		*dma_handle = handle;
+		return ret;
+	}
 }
 
 /**
diff -ru 2.2/include/sound/pcm_oss.h 3.4/include/sound/pcm_oss.h
--- 2.2/include/sound/pcm_oss.h	2006-10-02 17:39:32.000000000 +0200
+++ 3.4/include/sound/pcm_oss.h	2006-12-22 01:57:08.000000000 +0100
@@ -56,6 +56,7 @@
 	size_t mmap_bytes;
 	char *buffer;				/* vmallocated period */
 	size_t buffer_used;			/* used length from period buffer */
+	struct mutex params_lock;
 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
 	struct snd_pcm_plugin *plugin_first;
 	struct snd_pcm_plugin *plugin_last;
diff -ru 2.2/include/sound/version.h 3.4/include/sound/version.h
--- 2.2/include/sound/version.h	2006-11-29 04:53:09.000000000 +0100
+++ 3.4/include/sound/version.h	2006-12-22 01:57:08.000000000 +0100
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by alsa/ksync script.  */
-#define CONFIG_SND_VERSION "1.0.13"
-#define CONFIG_SND_DATE " (Tue Nov 28 14:07:24 2006 UTC)"
+#define CONFIG_SND_VERSION "1.0.14rc1"
+#define CONFIG_SND_DATE " (Wed Dec 20 08:11:48 2006 UTC)"
diff -ru 2.2/include/sound/ymfpci.h 3.4/include/sound/ymfpci.h
--- 2.2/include/sound/ymfpci.h	2006-10-02 17:39:32.000000000 +0200
+++ 3.4/include/sound/ymfpci.h	2006-12-22 01:57:08.000000000 +0100
@@ -286,7 +286,7 @@
 	int irq;
 
 	unsigned int device_id;	/* PCI device ID */
-	unsigned int rev;	/* PCI revision */
+	unsigned char rev;	/* PCI revision */
 	unsigned long reg_area_phys;
 	void __iomem *reg_area_virt;
 	struct resource *res_reg_area;
@@ -345,7 +345,6 @@
 	struct snd_kcontrol *spdif_pcm_ctl;
 	int mode_dup4ch;
 	int rear_opened;
-	int rear_swap;
 	int spdif_opened;
 	struct {
 		u16 left;
@@ -378,7 +377,7 @@
 int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
 int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
 int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
-int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap);
+int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch);
 int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);
 
 #endif /* __SOUND_YMFPCI_H */
diff -ru 2.2/init/Kconfig 3.4/init/Kconfig
--- 2.2/init/Kconfig	2006-12-13 18:28:54.000000000 +0100
+++ 3.4/init/Kconfig	2006-12-23 01:11:21.000000000 +0100
@@ -459,7 +459,7 @@
 
 config SLAB
 	default y
-	bool "Use full SLAB allocator" if EMBEDDED
+	bool "Use full SLAB allocator" if (EMBEDDED && !SMP && !SPARSEMEM)
 	help
 	  Disabling this replaces the advanced SLAB allocator and
 	  kmalloc support with the drastically simpler SLOB allocator.
@@ -470,10 +470,10 @@
 	default y
 	bool "Enable VM event counters for /proc/vmstat" if EMBEDDED
 	help
-	  VM event counters are only needed to for event counts to be
-	  shown. They have no function for the kernel itself. This
-	  option allows the disabling of the VM event counters.
-	  /proc/vmstat will only show page counts.
+	  VM event counters are needed for event counts to be shown.
+	  This option allows the disabling of the VM event counters
+	  on EMBEDDED systems.  /proc/vmstat will only show page counts
+	  if VM event counters are disabled.
 
 endmenu		# General setup
 
diff -ru 2.2/init/main.c 3.4/init/main.c
--- 2.2/init/main.c	2006-12-12 06:41:13.000000000 +0100
+++ 3.4/init/main.c	2006-12-22 01:57:10.000000000 +0100
@@ -53,6 +53,7 @@
 #include <linux/utsrelease.h>
 #include <linux/pid_namespace.h>
 #include <linux/compile.h>
+#include <linux/device.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -94,7 +95,6 @@
 extern void prio_tree_init(void);
 extern void radix_tree_init(void);
 extern void free_initmem(void);
-extern void driver_init(void);
 extern void prepare_namespace(void);
 #ifdef	CONFIG_ACPI
 extern void acpi_early_init(void);
diff -ru 2.2/init/Makefile 3.4/init/Makefile
--- 2.2/init/Makefile	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/init/Makefile	2006-12-23 01:11:19.000000000 +0100
@@ -18,12 +18,3 @@
 $(obj)/main.o: include/linux/compile.h
 $(obj)/version.o: include/linux/compile.h
 
-# compile.h changes depending on hostname, generation number, etc,
-# so we regenerate it always.
-# mkcompile_h will make sure to only update the
-# actual file if its content has changed.
-
-include/linux/compile.h: FORCE
-	@echo '  CHK     $@'
-	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \
-	"$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(CFLAGS)"
diff -ru 2.2/kernel/auditfilter.c 3.4/kernel/auditfilter.c
--- 2.2/kernel/auditfilter.c	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/kernel/auditfilter.c	2006-12-23 01:11:20.000000000 +0100
@@ -800,8 +800,8 @@
 
 	/* our own copy of se_str */
 	se_str = kstrdup(sf->se_str, GFP_KERNEL);
-	if (unlikely(IS_ERR(se_str)))
-	    return -ENOMEM;
+	if (unlikely(!se_str))
+		return -ENOMEM;
 	df->se_str = se_str;
 
 	/* our own (refreshed) copy of se_rule */
diff -ru 2.2/kernel/cpu.c 3.4/kernel/cpu.c
--- 2.2/kernel/cpu.c	2006-12-08 04:50:57.000000000 +0100
+++ 3.4/kernel/cpu.c	2006-12-24 16:38:17.000000000 +0100
@@ -258,7 +258,7 @@
 
 int disable_nonboot_cpus(void)
 {
-	int cpu, first_cpu, error;
+	int cpu, first_cpu, error = 0;
 
 	mutex_lock(&cpu_add_remove_lock);
 	first_cpu = first_cpu(cpu_present_map);
@@ -294,7 +294,7 @@
 		/* Make sure the CPUs won't be enabled by someone else */
 		cpu_hotplug_disabled = 1;
 	} else {
-		printk(KERN_ERR "Non-boot CPUs are not disabled");
+		printk(KERN_ERR "Non-boot CPUs are not disabled\n");
 	}
 out:
 	mutex_unlock(&cpu_add_remove_lock);
diff -ru 2.2/kernel/exit.c 3.4/kernel/exit.c
--- 2.2/kernel/exit.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/kernel/exit.c	2006-12-23 01:11:20.000000000 +0100
@@ -468,7 +468,7 @@
 		fdt = files_fdtable(files);
 		if (fdt != &files->fdtab)
 			kmem_cache_free(files_cachep, files);
-		call_rcu(&fdt->rcu, free_fdtable_rcu);
+		free_fdtable(fdt);
 	}
 }
 
@@ -597,14 +597,6 @@
 static void
 reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
 {
-	/* We don't want people slaying init.  */
-	if (p->exit_signal != -1)
-		p->exit_signal = SIGCHLD;
-
-	if (p->pdeath_signal)
-		/* We already hold the tasklist_lock here.  */
-		group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
-
 	/* Move the child from its dying parent to the new one.  */
 	if (unlikely(traced)) {
 		/* Preserve ptrace links if someone else is tracing this child.  */
@@ -620,13 +612,7 @@
 		p->parent = p->real_parent;
 		add_parent(p);
 
-		/* If we'd notified the old parent about this child's death,
-		 * also notify the new parent.
-		 */
-		if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 &&
-		    thread_group_empty(p))
-			do_notify_parent(p, p->exit_signal);
-		else if (p->state == TASK_TRACED) {
+		if (p->state == TASK_TRACED) {
 			/*
 			 * If it was at a trace stop, turn it into
 			 * a normal stop since it's no longer being
@@ -636,6 +622,27 @@
 		}
 	}
 
+	/* If this is a threaded reparent there is no need to
+	 * notify anyone anything has happened.
+	 */
+	if (p->real_parent->group_leader == father->group_leader)
+		return;
+
+	/* We don't want people slaying init.  */
+	if (p->exit_signal != -1)
+		p->exit_signal = SIGCHLD;
+		
+	if (p->pdeath_signal)
+		/* We already hold the tasklist_lock here.  */
+		group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
+
+	/* If we'd notified the old parent about this child's death,
+	 * also notify the new parent.
+	 */
+	if (!traced && p->exit_state == EXIT_ZOMBIE &&
+	    p->exit_signal != -1 && thread_group_empty(p))
+		do_notify_parent(p, p->exit_signal);
+
 	/*
 	 * process group orphan check
 	 * Case ii: Our child is in a different pgrp
diff -ru 2.2/kernel/irq/chip.c 3.4/kernel/irq/chip.c
--- 2.2/kernel/irq/chip.c	2006-11-20 02:11:28.000000000 +0100
+++ 3.4/kernel/irq/chip.c	2006-12-23 01:11:20.000000000 +0100
@@ -517,10 +517,9 @@
 
 	if (!handle)
 		handle = handle_bad_irq;
-
-	if (desc->chip == &no_irq_chip) {
+	else if (desc->chip == &no_irq_chip) {
 		printk(KERN_WARNING "Trying to install %sinterrupt handler "
-		       "for IRQ%d\n", is_chained ? "chained " : " ", irq);
+		       "for IRQ%d\n", is_chained ? "chained " : "", irq);
 		/*
 		 * Some ARM implementations install a handler for really dumb
 		 * interrupt hardware without setting an irq_chip. This worked
diff -ru 2.2/kernel/power/disk.c 3.4/kernel/power/disk.c
--- 2.2/kernel/power/disk.c	2006-12-08 04:50:58.000000000 +0100
+++ 3.4/kernel/power/disk.c	2006-12-23 16:57:57.000000000 +0100
@@ -60,9 +60,11 @@
 {
 	switch(mode) {
 	case PM_DISK_PLATFORM:
-		kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
-		pm_ops->enter(PM_SUSPEND_DISK);
-		break;
+		if (pm_ops && pm_ops->enter) {
+			kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
+			pm_ops->enter(PM_SUSPEND_DISK);
+			break;
+		}
 	case PM_DISK_SHUTDOWN:
 		kernel_power_off();
 		break;
diff -ru 2.2/kernel/power/main.c 3.4/kernel/power/main.c
--- 2.2/kernel/power/main.c	2006-12-08 04:50:58.000000000 +0100
+++ 3.4/kernel/power/main.c	2006-12-23 16:57:57.000000000 +0100
@@ -29,7 +29,7 @@
 DEFINE_MUTEX(pm_mutex);
 
 struct pm_ops *pm_ops;
-suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN;
+suspend_disk_method_t pm_disk_mode = PM_DISK_PLATFORM;
 
 /**
  *	pm_set_ops - Set the global power method table. 
diff -ru 2.2/kernel/printk.c 3.4/kernel/printk.c
--- 2.2/kernel/printk.c	2006-12-08 04:50:58.000000000 +0100
+++ 3.4/kernel/printk.c	2006-12-23 01:11:20.000000000 +0100
@@ -335,7 +335,7 @@
 
 static int __read_mostly ignore_loglevel;
 
-int __init ignore_loglevel_setup(char *str)
+static int __init ignore_loglevel_setup(char *str)
 {
 	ignore_loglevel = 1;
 	printk(KERN_INFO "debug: ignoring loglevel setting.\n");
diff -ru 2.2/kernel/relay.c 3.4/kernel/relay.c
--- 2.2/kernel/relay.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/kernel/relay.c	2006-12-23 01:11:20.000000000 +0100
@@ -302,7 +302,7 @@
 
 /**
  *	wakeup_readers - wake up readers waiting on a channel
- *	@private: the channel buffer
+ *	@work: work struct that contains the the channel buffer
  *
  *	This is the work function used to defer reader waking.  The
  *	reason waking is deferred is that calling directly from write
@@ -322,7 +322,7 @@
  *
  *	See relay_reset for description of effect.
  */
-static inline void __relay_reset(struct rchan_buf *buf, unsigned int init)
+static void __relay_reset(struct rchan_buf *buf, unsigned int init)
 {
 	size_t i;
 
@@ -418,7 +418,7 @@
  *	The channel buffer and channel buffer data structure are then freed
  *	automatically when the last reference is given up.
  */
-static inline void relay_close_buf(struct rchan_buf *buf)
+static void relay_close_buf(struct rchan_buf *buf)
 {
 	buf->finalized = 1;
 	cancel_delayed_work(&buf->wake_readers);
@@ -426,7 +426,7 @@
 	kref_put(&buf->kref, relay_remove_buf);
 }
 
-static inline void setup_callbacks(struct rchan *chan,
+static void setup_callbacks(struct rchan *chan,
 				   struct rchan_callbacks *cb)
 {
 	if (!cb) {
@@ -946,11 +946,10 @@
 /*
  *	relay_file_read_subbufs - read count bytes, bridging subbuf boundaries
  */
-static inline ssize_t relay_file_read_subbufs(struct file *filp,
-					      loff_t *ppos,
-					      subbuf_actor_t subbuf_actor,
-					      read_actor_t actor,
-					      read_descriptor_t *desc)
+static ssize_t relay_file_read_subbufs(struct file *filp, loff_t *ppos,
+					subbuf_actor_t subbuf_actor,
+					read_actor_t actor,
+					read_descriptor_t *desc)
 {
 	struct rchan_buf *buf = filp->private_data;
 	size_t read_start, avail;
diff -ru 2.2/kernel/sched.c 3.4/kernel/sched.c
--- 2.2/kernel/sched.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/kernel/sched.c	2006-12-23 01:11:20.000000000 +0100
@@ -1567,6 +1567,7 @@
 	return try_to_wake_up(p, state, 0);
 }
 
+static void task_running_tick(struct rq *rq, struct task_struct *p);
 /*
  * Perform scheduler related setup for a newly forked process p.
  * p is forked by current.
@@ -1627,7 +1628,7 @@
 		 * runqueue lock is not a problem.
 		 */
 		current->time_slice = 1;
-		scheduler_tick();
+		task_running_tick(cpu_rq(cpu), current);
 	}
 	local_irq_enable();
 	put_cpu();
@@ -4618,8 +4619,10 @@
 
 static inline int __resched_legal(int expected_preempt_count)
 {
+#ifdef CONFIG_PREEMPT
 	if (unlikely(preempt_count() != expected_preempt_count))
 		return 0;
+#endif
 	if (unlikely(system_state != SYSTEM_RUNNING))
 		return 0;
 	return 1;
@@ -5607,7 +5610,7 @@
 }
 
 /* cpus with isolated domains */
-static cpumask_t __cpuinitdata cpu_isolated_map = CPU_MASK_NONE;
+static cpumask_t cpu_isolated_map = CPU_MASK_NONE;
 
 /* Setup the mask of cpus configured for isolated domains */
 static int __init isolated_cpu_setup(char *str)
diff -ru 2.2/kernel/timer.c 3.4/kernel/timer.c
--- 2.2/kernel/timer.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/kernel/timer.c	2006-12-23 01:11:20.000000000 +0100
@@ -1344,11 +1344,10 @@
 		 * should never happens anyway). You just have the printk()
 		 * that will tell you if something is gone wrong and where.
 		 */
-		if (timeout < 0)
-		{
+		if (timeout < 0) {
 			printk(KERN_ERR "schedule_timeout: wrong timeout "
-				"value %lx from %p\n", timeout,
-				__builtin_return_address(0));
+				"value %lx\n", timeout);
+			dump_stack();
 			current->state = TASK_RUNNING;
 			goto out;
 		}
diff -ru 2.2/kernel/workqueue.c 3.4/kernel/workqueue.c
--- 2.2/kernel/workqueue.c	2006-12-10 05:32:05.000000000 +0100
+++ 3.4/kernel/workqueue.c	2006-12-23 01:11:20.000000000 +0100
@@ -96,13 +96,13 @@
 	BUG_ON(!work_pending(work));
 
 	new = (unsigned long) wq | (1UL << WORK_STRUCT_PENDING);
-	new |= work->management & WORK_STRUCT_FLAG_MASK;
-	work->management = new;
+	new |= WORK_STRUCT_FLAG_MASK & *work_data_bits(work);
+	atomic_long_set(&work->data, new);
 }
 
 static inline void *get_wq_data(struct work_struct *work)
 {
-	return (void *) (work->management & WORK_STRUCT_WQ_DATA_MASK);
+	return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK);
 }
 
 static int __run_work(struct cpu_workqueue_struct *cwq, struct work_struct *work)
@@ -133,7 +133,7 @@
 		list_del_init(&work->entry);
 		spin_unlock_irqrestore(&cwq->lock, flags);
 
-		if (!test_bit(WORK_STRUCT_NOAUTOREL, &work->management))
+		if (!test_bit(WORK_STRUCT_NOAUTOREL, work_data_bits(work)))
 			work_release(work);
 		f(work);
 
@@ -206,7 +206,7 @@
 {
 	int ret = 0, cpu = get_cpu();
 
-	if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) {
+	if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
 		if (unlikely(is_single_threaded(wq)))
 			cpu = singlethread_cpu;
 		BUG_ON(!list_empty(&work->entry));
@@ -233,7 +233,7 @@
 /**
  * queue_delayed_work - queue work on a workqueue after delay
  * @wq: workqueue to use
- * @work: delayable work to queue
+ * @dwork: delayable work to queue
  * @delay: number of jiffies to wait before queueing
  *
  * Returns 0 if @work was already on a queue, non-zero otherwise.
@@ -248,7 +248,7 @@
 	if (delay == 0)
 		return queue_work(wq, work);
 
-	if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) {
+	if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
 		BUG_ON(timer_pending(timer));
 		BUG_ON(!list_empty(&work->entry));
 
@@ -268,7 +268,7 @@
  * queue_delayed_work_on - queue work on specific CPU after delay
  * @cpu: CPU number to execute work on
  * @wq: workqueue to use
- * @work: work to queue
+ * @dwork: work to queue
  * @delay: number of jiffies to wait before queueing
  *
  * Returns 0 if @work was already on a queue, non-zero otherwise.
@@ -280,7 +280,7 @@
 	struct timer_list *timer = &dwork->timer;
 	struct work_struct *work = &dwork->work;
 
-	if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) {
+	if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
 		BUG_ON(timer_pending(timer));
 		BUG_ON(!list_empty(&work->entry));
 
@@ -321,7 +321,7 @@
 		spin_unlock_irqrestore(&cwq->lock, flags);
 
 		BUG_ON(get_wq_data(work) != cwq);
-		if (!test_bit(WORK_STRUCT_NOAUTOREL, &work->management))
+		if (!test_bit(WORK_STRUCT_NOAUTOREL, work_data_bits(work)))
 			work_release(work);
 		f(work);
 
@@ -637,9 +637,11 @@
 
 	mutex_lock(&workqueue_mutex);
 	for_each_online_cpu(cpu) {
-		INIT_WORK(per_cpu_ptr(works, cpu), func);
-		__queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu),
-				per_cpu_ptr(works, cpu));
+		struct work_struct *work = per_cpu_ptr(works, cpu);
+
+		INIT_WORK(work, func);
+		set_bit(WORK_STRUCT_PENDING, work_data_bits(work));
+		__queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu), work);
 	}
 	mutex_unlock(&workqueue_mutex);
 	flush_workqueue(keventd_wq);
diff -ru 2.2/lib/kobject_uevent.c 3.4/lib/kobject_uevent.c
--- 2.2/lib/kobject_uevent.c	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/lib/kobject_uevent.c	2006-12-22 01:57:08.000000000 +0100
@@ -63,8 +63,11 @@
  * @action: action that is happening (usually KOBJ_MOVE)
  * @kobj: struct kobject that the action is happening to
  * @envp_ext: pointer to environmental data
+ *
+ * Returns 0 if kobject_uevent() is completed with success or the
+ * corresponding error when it fails.
  */
-void kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
+int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
 			char *envp_ext[])
 {
 	char **envp;
@@ -79,14 +82,16 @@
 	u64 seq;
 	char *seq_buff;
 	int i = 0;
-	int retval;
+	int retval = 0;
 	int j;
 
 	pr_debug("%s\n", __FUNCTION__);
 
 	action_string = action_to_string(action);
-	if (!action_string)
-		return;
+	if (!action_string) {
+		pr_debug("kobject attempted to send uevent without action_string!\n");
+		return -EINVAL;
+	}
 
 	/* search the kset we belong to */
 	top_kobj = kobj;
@@ -95,31 +100,39 @@
 			top_kobj = top_kobj->parent;
 		} while (!top_kobj->kset && top_kobj->parent);
 	}
-	if (!top_kobj->kset)
-		return;
+	if (!top_kobj->kset) {
+		pr_debug("kobject attempted to send uevent without kset!\n");
+		return -EINVAL;
+	}
 
 	kset = top_kobj->kset;
 	uevent_ops = kset->uevent_ops;
 
 	/*  skip the event, if the filter returns zero. */
 	if (uevent_ops && uevent_ops->filter)
-		if (!uevent_ops->filter(kset, kobj))
-			return;
+		if (!uevent_ops->filter(kset, kobj)) {
+			pr_debug("kobject filter function caused the event to drop!\n");
+			return 0;
+		}
 
 	/* environment index */
 	envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
 	if (!envp)
-		return;
+		return -ENOMEM;
 
 	/* environment values */
 	buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
-	if (!buffer)
+	if (!buffer) {
+		retval = -ENOMEM;
 		goto exit;
+	}
 
 	/* complete object path */
 	devpath = kobject_get_path(kobj, GFP_KERNEL);
-	if (!devpath)
+	if (!devpath) {
+		retval = -ENOENT;
 		goto exit;
+	}
 
 	/* originating subsystem */
 	if (uevent_ops && uevent_ops->name)
@@ -204,7 +217,7 @@
 	kfree(devpath);
 	kfree(buffer);
 	kfree(envp);
-	return;
+	return retval;
 }
 
 EXPORT_SYMBOL_GPL(kobject_uevent_env);
@@ -214,10 +227,13 @@
  *
  * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE)
  * @kobj: struct kobject that the action is happening to
+ *
+ * Returns 0 if kobject_uevent() is completed with success or the
+ * corresponding error when it fails.
  */
-void kobject_uevent(struct kobject *kobj, enum kobject_action action)
+int kobject_uevent(struct kobject *kobj, enum kobject_action action)
 {
-	kobject_uevent_env(kobj, action, NULL);
+	return kobject_uevent_env(kobj, action, NULL);
 }
 
 EXPORT_SYMBOL_GPL(kobject_uevent);
diff -ru 2.2/lib/kref.c 3.4/lib/kref.c
--- 2.2/lib/kref.c	2006-10-02 17:39:32.000000000 +0200
+++ 3.4/lib/kref.c	2006-12-22 01:57:08.000000000 +0100
@@ -52,12 +52,7 @@
 	WARN_ON(release == NULL);
 	WARN_ON(release == (void (*)(struct kref *))kfree);
 
-	/*
-	 * if current count is one, we are the last user and can release object
-	 * right now, avoiding an atomic operation on 'refcount'
-	 */
-	if ((atomic_read(&kref->refcount) == 1) ||
-	    (atomic_dec_and_test(&kref->refcount))) {
+	if (atomic_dec_and_test(&kref->refcount)) {
 		release(kref);
 		return 1;
 	}
diff -ru 2.2/MAINTAINERS 3.4/MAINTAINERS
--- 2.2/MAINTAINERS	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/MAINTAINERS	2006-12-23 16:57:57.000000000 +0100
@@ -406,14 +406,14 @@
 
 ARM/S3C2410 ARM ARCHITECTURE
 P:	Ben Dooks
-M:	ben-s3c2410@fluff.org
+M:	ben-linux@fluff.org
 L:	linux-arm-kernel@lists.arm.linux.org.uk	(subscribers-only)
 W:	http://www.fluff.org/ben/linux/
 S:	Maintained
 
 ARM/S3C2440 ARM ARCHITECTURE
 P:	Ben Dooks
-M:	ben-s3c2440@fluff.org
+M:	ben-linux@fluff.org
 L:	linux-arm-kernel@lists.arm.linux.org.uk	(subscribers-only)
 W:	http://www.fluff.org/ben/linux/
 S:	Maintained
@@ -943,11 +943,8 @@
 S:	Maintained
 
 DOCBOOK FOR DOCUMENTATION
-P:	Martin Waitz
-M:	tali@admingilde.org
 P:	Randy Dunlap
 M:	rdunlap@xenotime.net
-T:	git http://tali.admingilde.org/git/linux-docbook.git
 S:	Maintained
 
 DOCKING STATION DRIVER
@@ -1277,6 +1274,12 @@
 W:	http://drama.obuda.kando.hu/~fero/cgi-bin/hgafb.shtml
 S:	Maintained
 
+HID CORE LAYER
+P:	Jiri Kosina
+M:	jkosina@suse.cz
+L:	linux-input@atrey.karlin.mff.cuni.cz
+S:	Maintained
+
 HIGH-SPEED SCC DRIVER FOR AX.25
 P:	Klaus Kudielka
 M:	klaus.kudielka@ieee.org
@@ -1397,6 +1400,15 @@
 T:	git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
 S:	Maintained
 
+IBM ACPI EXTRAS DRIVER
+P:	Henrique de Moraes Holschuh
+M:	ibm-acpi@hmh.eng.br
+L:	ibm-acpi-devel@lists.sourceforge.net
+W:	http://ibm-acpi.sourceforge.net
+W:	http://thinkwiki.org/wiki/Ibm-acpi
+T:	git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
+S:	Maintained
+
 SN-IA64 (Itanium) SUB-PLATFORM
 P:	Jes Sorensen
 M:	jes@sgi.com
@@ -3124,7 +3136,7 @@
 P:	David Brownell
 M:	dbrownell@users.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
-S:	Maintained
+S:	Odd Fixes
 
 USB ET61X[12]51 DRIVER
 P:	Luca Risolia
@@ -3177,11 +3189,11 @@
 W:	http://www.one-eyed-alien.net/~mdharm/linux-usb/
 
 USB OHCI DRIVER
-P:	Roman Weissgaerber
-M:	weissg@vienna.at
+P:	David Brownell
+M:	dbrownell@users.sourceforge.net
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
-S:	Maintained
+S:	Odd Fixes
 
 USB OPTION-CARD DRIVER
 P:	Matthias Urlichs
diff -ru 2.2/Makefile 3.4/Makefile
--- 2.2/Makefile	2006-12-15 20:49:09.000000000 +0100
+++ 3.4/Makefile	2006-12-24 16:38:56.000000000 +0100
@@ -1,8 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 20
-EXTRAVERSION =-rc1-ubuntu1
-NAME=Avast! A bilge rat!
+EXTRAVERSION =-rc2-ubuntu1
+NAME = Homicidal Dwarf Hamster
 
 ifdef UBUNTUBUILD
 EXTRAVERSION =
@@ -376,10 +376,14 @@
 # Detect when mixed targets is specified, and make a second invocation
 # of make so .config is not included in this case either (for *config).
 
-no-dot-config-targets := clean mrproper distclean \
+PHONY += generated_headers
+
+generated_headers: include/linux/version.h include/linux/compile.h \
+		include/linux/utsrelease.h
+
+no-dot-config-targets := generated_headers clean mrproper distclean \
 			 cscope TAGS tags help %docs check% \
-			 include/linux/version.h headers_% \
-			 kernelrelease kernelversion
+			 headers_% kernelrelease kernelversion
 
 config-targets := 0
 mixed-targets  := 0
@@ -743,6 +747,16 @@
 
 endif # ifdef CONFIG_KALLSYMS
 
+# compile.h changes depending on hostname, generation number, etc,
+# so we regenerate it always.
+# mkcompile_h will make sure to only update the
+# actual file if its content has changed.
+
+include/linux/compile.h: FORCE
+	@echo '  CHK     $@'
+	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \
+	"$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(CFLAGS)"
+
 # vmlinux image - including updated kernel symbols
 vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
 ifdef CONFIG_HEADERS_CHECK
@@ -861,8 +875,8 @@
 # prepare2 creates a makefile if using a separate output directory
 prepare2: prepare3 outputmakefile
 
-prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
-                   include/asm include/config/auto.conf
+prepare1: prepare2 generated_headers include/asm include/config/auto.conf
+
 ifneq ($(KBUILD_MODULES),)
 	$(Q)mkdir -p $(MODVERDIR)
 	$(Q)rm -f $(MODVERDIR)/*
@@ -931,14 +945,14 @@
 HDRARCHES=$(filter-out generic,$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
 
 PHONY += headers_install_all
-headers_install_all: include/linux/version.h scripts_basic FORCE
+headers_install_all: generated_headers scripts_basic FORCE
 	$(Q)$(MAKE) $(build)=scripts scripts/unifdef
 	$(Q)for arch in $(HDRARCHES); do \
 	 $(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch ;\
 	 done
 
 PHONY += headers_install
-headers_install: include/linux/version.h scripts_basic FORCE
+headers_install: generated_headers scripts_basic FORCE
 	@if [ ! -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
 	  echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \
 	  exit 1 ; fi
@@ -1035,8 +1049,7 @@
 # Directories & files removed with 'make mrproper'
 MRPROPER_DIRS  += include/config include2 usr/include
 MRPROPER_FILES += .config .config.old include/asm .version .old_version \
-                  include/linux/autoconf.h include/linux/version.h      \
-                  include/linux/utsrelease.h                            \
+                  include/linux/autoconf.h generated-headers		\
 		  Module.symvers tags TAGS cscope*
 
 # clean - Delete most, but leave enough to build external modules
diff -ru 2.2/mm/filemap_xip.c 3.4/mm/filemap_xip.c
--- 2.2/mm/filemap_xip.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/mm/filemap_xip.c	2006-12-23 01:11:20.000000000 +0100
@@ -189,7 +189,7 @@
 			/* Nuke the page table entry. */
 			flush_cache_page(vma, address, pte_pfn(*pte));
 			pteval = ptep_clear_flush(vma, address, pte);
-			page_remove_rmap(page);
+			page_remove_rmap(page, vma);
 			dec_mm_counter(mm, file_rss);
 			BUG_ON(pte_dirty(pteval));
 			pte_unmap_unlock(pte, ptl);
diff -ru 2.2/mm/fremap.c 3.4/mm/fremap.c
--- 2.2/mm/fremap.c	2006-12-08 04:50:58.000000000 +0100
+++ 3.4/mm/fremap.c	2006-12-23 01:11:20.000000000 +0100
@@ -33,7 +33,7 @@
 		if (page) {
 			if (pte_dirty(pte))
 				set_page_dirty(page);
-			page_remove_rmap(page);
+			page_remove_rmap(page, vma);
 			page_cache_release(page);
 		}
 	} else {
diff -ru 2.2/mm/memory.c 3.4/mm/memory.c
--- 2.2/mm/memory.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/mm/memory.c	2006-12-23 01:11:20.000000000 +0100
@@ -681,7 +681,7 @@
 					mark_page_accessed(page);
 				file_rss--;
 			}
-			page_remove_rmap(page);
+			page_remove_rmap(page, vma);
 			tlb_remove_page(tlb, page);
 			continue;
 		}
@@ -1586,7 +1586,7 @@
 	page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
 	if (likely(pte_same(*page_table, orig_pte))) {
 		if (old_page) {
-			page_remove_rmap(old_page);
+			page_remove_rmap(old_page, vma);
 			if (!PageAnon(old_page)) {
 				dec_mm_counter(mm, file_rss);
 				inc_mm_counter(mm, anon_rss);
diff -ru 2.2/mm/mincore.c 3.4/mm/mincore.c
--- 2.2/mm/mincore.c	2006-10-02 17:39:32.000000000 +0200
+++ 3.4/mm/mincore.c	2006-12-18 04:27:33.000000000 +0100
@@ -1,7 +1,7 @@
 /*
  *	linux/mm/mincore.c
  *
- * Copyright (C) 1994-1999  Linus Torvalds
+ * Copyright (C) 1994-2006  Linus Torvalds
  */
 
 /*
@@ -38,46 +38,51 @@
 	return present;
 }
 
-static long mincore_vma(struct vm_area_struct * vma,
-	unsigned long start, unsigned long end, unsigned char __user * vec)
+/*
+ * Do a chunk of "sys_mincore()". We've already checked
+ * all the arguments, we hold the mmap semaphore: we should
+ * just return the amount of info we're asked for.
+ */
+static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pages)
 {
-	long error, i, remaining;
-	unsigned char * tmp;
-
-	error = -ENOMEM;
-	if (!vma->vm_file)
-		return error;
-
-	start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
-	if (end > vma->vm_end)
-		end = vma->vm_end;
-	end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
-
-	error = -EAGAIN;
-	tmp = (unsigned char *) __get_free_page(GFP_KERNEL);
-	if (!tmp)
-		return error;
-
-	/* (end - start) is # of pages, and also # of bytes in "vec */
-	remaining = (end - start),
+	unsigned long i, nr, pgoff;
+	struct vm_area_struct *vma = find_vma(current->mm, addr);
 
-	error = 0;
-	for (i = 0; remaining > 0; remaining -= PAGE_SIZE, i++) {
-		int j = 0;
-		long thispiece = (remaining < PAGE_SIZE) ?
-						remaining : PAGE_SIZE;
+	/*
+	 * find_vma() didn't find anything above us, or we're
+	 * in an unmapped hole in the address space: ENOMEM.
+	 */
+	if (!vma || addr < vma->vm_start)
+		return -ENOMEM;
 
-		while (j < thispiece)
-			tmp[j++] = mincore_page(vma, start++);
+	/*
+	 * Ok, got it. But check whether it's a segment we support
+	 * mincore() on. Right now, we don't do any anonymous mappings.
+	 *
+	 * FIXME: This is just stupid. And returning ENOMEM is 
+	 * stupid too. We should just look at the page tables. But
+	 * this is what we've traditionally done, so we'll just
+	 * continue doing it.
+	 */
+	if (!vma->vm_file)
+		return -ENOMEM;
 
-		if (copy_to_user(vec + PAGE_SIZE * i, tmp, thispiece)) {
-			error = -EFAULT;
-			break;
-		}
-	}
+	/*
+	 * Calculate how many pages there are left in the vma, and
+	 * what the pgoff is for our address.
+	 */
+	nr = (vma->vm_end - addr) >> PAGE_SHIFT;
+	if (nr > pages)
+		nr = pages;
+
+	pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
+	pgoff += vma->vm_pgoff;
+
+	/* And then we just fill the sucker in.. */
+	for (i = 0 ; i < nr; i++, pgoff++)
+		vec[i] = mincore_page(vma, pgoff);
 
-	free_page((unsigned long) tmp);
-	return error;
+	return nr;
 }
 
 /*
@@ -107,82 +112,50 @@
 asmlinkage long sys_mincore(unsigned long start, size_t len,
 	unsigned char __user * vec)
 {
-	int index = 0;
-	unsigned long end, limit;
-	struct vm_area_struct * vma;
-	size_t max;
-	int unmapped_error = 0;
-	long error;
+	long retval;
+	unsigned long pages;
+	unsigned char *tmp;
 
-	/* check the arguments */
+	/* Check the start address: needs to be page-aligned.. */
  	if (start & ~PAGE_CACHE_MASK)
-		goto einval;
-
-	limit = TASK_SIZE;
-	if (start >= limit)
-		goto enomem;
+		return -EINVAL;
 
-	if (!len)
-		return 0;
+	/* ..and we need to be passed a valid user-space range */
+	if (!access_ok(VERIFY_READ, (void __user *) start, len))
+		return -ENOMEM;
 
-	max = limit - start;
-	len = PAGE_CACHE_ALIGN(len);
-	if (len > max || !len)
-		goto enomem;
+	/* This also avoids any overflows on PAGE_CACHE_ALIGN */
+	pages = len >> PAGE_SHIFT;
+	pages += (len & ~PAGE_MASK) != 0;
 
-	end = start + len;
+	if (!access_ok(VERIFY_WRITE, vec, pages))
+		return -EFAULT;
 
-	/* check the output buffer whilst holding the lock */
-	error = -EFAULT;
-	down_read(&current->mm->mmap_sem);
-
-	if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT))
-		goto out;
-
-	/*
-	 * If the interval [start,end) covers some unmapped address
-	 * ranges, just ignore them, but return -ENOMEM at the end.
-	 */
-	error = 0;
+	tmp = (void *) __get_free_page(GFP_USER);
+	if (!tmp)
+		return -EAGAIN;
 
-	vma = find_vma(current->mm, start);
-	while (vma) {
-		/* Here start < vma->vm_end. */
-		if (start < vma->vm_start) {
-			unmapped_error = -ENOMEM;
-			start = vma->vm_start;
-		}
+	retval = 0;
+	while (pages) {
+		/*
+		 * Do at most PAGE_SIZE entries per iteration, due to
+		 * the temporary buffer size.
+		 */
+		down_read(&current->mm->mmap_sem);
+		retval = do_mincore(start, tmp, min(pages, PAGE_SIZE));
+		up_read(&current->mm->mmap_sem);
 
-		/* Here vma->vm_start <= start < vma->vm_end. */
-		if (end <= vma->vm_end) {
-			if (start < end) {
-				error = mincore_vma(vma, start, end,
-							&vec[index]);
-				if (error)
-					goto out;
-			}
-			error = unmapped_error;
-			goto out;
+		if (retval <= 0)
+			break;
+		if (copy_to_user(vec, tmp, retval)) {
+			retval = -EFAULT;
+			break;
 		}
-
-		/* Here vma->vm_start <= start < vma->vm_end < end. */
-		error = mincore_vma(vma, start, vma->vm_end, &vec[index]);
-		if (error)
-			goto out;
-		index += (vma->vm_end - start) >> PAGE_CACHE_SHIFT;
-		start = vma->vm_end;
-		vma = vma->vm_next;
+		pages -= retval;
+		vec += retval;
+		start += retval << PAGE_SHIFT;
+		retval = 0;
 	}
-
-	/* we found a hole in the area queried if we arrive here */
-	error = -ENOMEM;
-
-out:
-	up_read(&current->mm->mmap_sem);
-	return error;
-
-einval:
-	return -EINVAL;
-enomem:
-	return -ENOMEM;
+	free_page((unsigned long) tmp);
+	return retval;
 }
diff -ru 2.2/mm/page-writeback.c 3.4/mm/page-writeback.c
--- 2.2/mm/page-writeback.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/mm/page-writeback.c	2006-12-22 01:57:08.000000000 +0100
@@ -845,38 +845,6 @@
 EXPORT_SYMBOL(set_page_dirty_lock);
 
 /*
- * Clear a page's dirty flag, while caring for dirty memory accounting. 
- * Returns true if the page was previously dirty.
- */
-int test_clear_page_dirty(struct page *page)
-{
-	struct address_space *mapping = page_mapping(page);
-	unsigned long flags;
-
-	if (!mapping)
-		return TestClearPageDirty(page);
-
-	write_lock_irqsave(&mapping->tree_lock, flags);
-	if (TestClearPageDirty(page)) {
-		radix_tree_tag_clear(&mapping->page_tree,
-				page_index(page), PAGECACHE_TAG_DIRTY);
-		write_unlock_irqrestore(&mapping->tree_lock, flags);
-		/*
-		 * We can continue to use `mapping' here because the
-		 * page is locked, which pins the address_space
-		 */
-		if (mapping_cap_account_dirty(mapping)) {
-			page_mkclean(page);
-			dec_zone_page_state(page, NR_FILE_DIRTY);
-		}
-		return 1;
-	}
-	write_unlock_irqrestore(&mapping->tree_lock, flags);
-	return 0;
-}
-EXPORT_SYMBOL(test_clear_page_dirty);
-
-/*
  * Clear a page's dirty flag, while caring for dirty memory accounting.
  * Returns true if the page was previously dirty.
  *
diff -ru 2.2/mm/rmap.c 3.4/mm/rmap.c
--- 2.2/mm/rmap.c	2006-10-20 23:43:45.000000000 +0200
+++ 3.4/mm/rmap.c	2006-12-23 01:11:20.000000000 +0100
@@ -47,6 +47,7 @@
 #include <linux/rmap.h>
 #include <linux/rcupdate.h>
 #include <linux/module.h>
+#include <linux/kallsyms.h>
 
 #include <asm/tlbflush.h>
 
@@ -432,7 +433,7 @@
 {
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long address;
-	pte_t *pte, entry;
+	pte_t *pte;
 	spinlock_t *ptl;
 	int ret = 0;
 
@@ -444,17 +445,18 @@
 	if (!pte)
 		goto out;
 
-	if (!pte_dirty(*pte) && !pte_write(*pte))
-		goto unlock;
+	if (pte_dirty(*pte) || pte_write(*pte)) {
+		pte_t entry;
 
-	entry = ptep_get_and_clear(mm, address, pte);
-	entry = pte_mkclean(entry);
-	entry = pte_wrprotect(entry);
-	ptep_establish(vma, address, pte, entry);
-	lazy_mmu_prot_update(entry);
-	ret = 1;
+		flush_cache_page(vma, address, pte_pfn(*pte));
+		entry = ptep_clear_flush(vma, address, pte);
+		entry = pte_wrprotect(entry);
+		entry = pte_mkclean(entry);
+		set_pte_at(vma, address, pte, entry);
+		lazy_mmu_prot_update(entry);
+		ret = 1;
+	}
 
-unlock:
 	pte_unmap_unlock(pte, ptl);
 out:
 	return ret;
@@ -489,6 +491,8 @@
 		if (mapping)
 			ret = page_mkclean_file(mapping, page);
 	}
+	if (page_test_and_clear_dirty(page))
+		ret = 1;
 
 	return ret;
 }
@@ -567,14 +571,20 @@
  *
  * The caller needs to hold the pte lock.
  */
-void page_remove_rmap(struct page *page)
+void page_remove_rmap(struct page *page, struct vm_area_struct *vma)
 {
 	if (atomic_add_negative(-1, &page->_mapcount)) {
 		if (unlikely(page_mapcount(page) < 0)) {
 			printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page));
+			printk (KERN_EMERG "  page pfn = %lx\n", page_to_pfn(page));
 			printk (KERN_EMERG "  page->flags = %lx\n", page->flags);
 			printk (KERN_EMERG "  page->count = %x\n", page_count(page));
 			printk (KERN_EMERG "  page->mapping = %p\n", page->mapping);
+			print_symbol (KERN_EMERG "  vma->vm_ops = %s\n", (unsigned long)vma->vm_ops);
+			if (vma->vm_ops)
+				print_symbol (KERN_EMERG "  vma->vm_ops->nopage = %s\n", (unsigned long)vma->vm_ops->nopage);
+			if (vma->vm_file && vma->vm_file->f_op)
+				print_symbol (KERN_EMERG "  vma->vm_file->f_op->mmap = %s\n", (unsigned long)vma->vm_file->f_op->mmap);
 			BUG();
 		}
 
@@ -679,7 +689,7 @@
 		dec_mm_counter(mm, file_rss);
 
 
-	page_remove_rmap(page);
+	page_remove_rmap(page, vma);
 	page_cache_release(page);
 
 out_unmap:
@@ -769,7 +779,7 @@
 		if (pte_dirty(pteval))
 			set_page_dirty(page);
 
-		page_remove_rmap(page);
+		page_remove_rmap(page, vma);
 		page_cache_release(page);
 		dec_mm_counter(mm, file_rss);
 		(*mapcount)--;
diff -ru 2.2/mm/shmem.c 3.4/mm/shmem.c
--- 2.2/mm/shmem.c	2006-12-08 19:05:37.000000000 +0100
+++ 3.4/mm/shmem.c	2006-12-23 01:11:20.000000000 +0100
@@ -515,7 +515,12 @@
 			size = SHMEM_NR_DIRECT;
 		nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size);
 	}
-	if (!topdir)
+
+	/*
+	 * If there are no indirect blocks or we are punching a hole
+	 * below indirect blocks, nothing to be done.
+	 */
+	if (!topdir || (punch_hole && (limit <= SHMEM_NR_DIRECT)))
 		goto done2;
 
 	BUG_ON(limit <= SHMEM_NR_DIRECT);
diff -ru 2.2/mm/slab.c 3.4/mm/slab.c
--- 2.2/mm/slab.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/mm/slab.c	2006-12-23 01:11:20.000000000 +0100
@@ -3553,7 +3553,7 @@
  *
  * Currently only used for dentry validation.
  */
-int fastcall kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
+int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
 {
 	unsigned long addr = (unsigned long)ptr;
 	unsigned long min_addr = PAGE_OFFSET;
@@ -3587,6 +3587,7 @@
  * @cachep: The cache to allocate from.
  * @flags: See kmalloc().
  * @nodeid: node number of the target node.
+ * @caller: return address of caller, used for debug information
  *
  * Identical to kmem_cache_alloc but it will allocate memory on the given
  * node, which can improve the performance for cpu bound structures.
diff -ru 2.2/mm/truncate.c 3.4/mm/truncate.c
--- 2.2/mm/truncate.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/mm/truncate.c	2006-12-24 16:38:17.000000000 +0100
@@ -51,6 +51,26 @@
 		do_invalidatepage(page, partial);
 }
 
+void cancel_dirty_page(struct page *page, unsigned int account_size)
+{
+	/* If we're cancelling the page, it had better not be mapped any more */
+	if (page_mapped(page)) {
+		static unsigned int warncount;
+
+		WARN_ON(++warncount < 5);
+	}
+		
+	if (TestClearPageDirty(page)) {
+		struct address_space *mapping = page->mapping;
+		if (mapping && mapping_cap_account_dirty(mapping)) {
+			dec_zone_page_state(page, NR_FILE_DIRTY);
+			if (account_size)
+				task_io_account_cancelled_write(account_size);
+		}
+	}
+}
+EXPORT_SYMBOL(cancel_dirty_page);
+
 /*
  * If truncate cannot remove the fs-private metadata from the page, the page
  * becomes anonymous.  It will be left on the LRU and may even be mapped into
@@ -67,11 +87,11 @@
 	if (page->mapping != mapping)
 		return;
 
+	cancel_dirty_page(page, PAGE_CACHE_SIZE);
+
 	if (PagePrivate(page))
 		do_invalidatepage(page, 0);
 
-	if (test_clear_page_dirty(page))
-		task_io_account_cancelled_write(PAGE_CACHE_SIZE);
 	ClearPageUptodate(page);
 	ClearPageMappedToDisk(page);
 	remove_from_page_cache(page);
@@ -350,7 +370,6 @@
 		for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 			pgoff_t page_index;
-			int was_dirty;
 
 			lock_page(page);
 			if (page->mapping != mapping) {
@@ -386,12 +405,8 @@
 					  PAGE_CACHE_SIZE, 0);
 				}
 			}
-			was_dirty = test_clear_page_dirty(page);
-			if (!invalidate_complete_page2(mapping, page)) {
-				if (was_dirty)
-					set_page_dirty(page);
+			if (!invalidate_complete_page2(mapping, page))
 				ret = -EIO;
-			}
 			unlock_page(page);
 		}
 		pagevec_release(&pvec);
diff -ru 2.2/mm/vmscan.c 3.4/mm/vmscan.c
--- 2.2/mm/vmscan.c	2006-12-14 01:58:58.000000000 +0100
+++ 3.4/mm/vmscan.c	2006-12-23 01:11:20.000000000 +0100
@@ -1369,8 +1369,8 @@
  *
  * For pass > 3 we also try to shrink the LRU lists that contain a few pages
  */
-static unsigned long shrink_all_zones(unsigned long nr_pages, int pass,
-				      int prio, struct scan_control *sc)
+static unsigned long shrink_all_zones(unsigned long nr_pages, int prio,
+				      int pass, struct scan_control *sc)
 {
 	struct zone *zone;
 	unsigned long nr_to_scan, ret = 0;
diff -ru 2.2/net/ax25/af_ax25.c 3.4/net/ax25/af_ax25.c
--- 2.2/net/ax25/af_ax25.c	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/net/ax25/af_ax25.c	2006-12-22 01:57:08.000000000 +0100
@@ -1088,8 +1088,8 @@
 /*
  *	FIXME: nonblock behaviour looks like it may have a bug.
  */
-static int ax25_connect(struct socket *sock, struct sockaddr *uaddr,
-	int addr_len, int flags)
+static int __must_check ax25_connect(struct socket *sock,
+	struct sockaddr *uaddr, int addr_len, int flags)
 {
 	struct sock *sk = sock->sk;
 	ax25_cb *ax25 = ax25_sk(sk), *ax25t;
diff -ru 2.2/net/ax25/ax25_iface.c 3.4/net/ax25/ax25_iface.c
--- 2.2/net/ax25/ax25_iface.c	2006-10-02 17:39:32.000000000 +0200
+++ 3.4/net/ax25/ax25_iface.c	2006-12-22 01:57:08.000000000 +0100
@@ -29,17 +29,10 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 
-static struct protocol_struct {
-	struct protocol_struct *next;
-	unsigned int pid;
-	int (*func)(struct sk_buff *, ax25_cb *);
-} *protocol_list = NULL;
+static struct ax25_protocol *protocol_list;
 static DEFINE_RWLOCK(protocol_list_lock);
 
-static struct linkfail_struct {
-	struct linkfail_struct *next;
-	void (*func)(ax25_cb *, int);
-} *linkfail_list = NULL;
+static HLIST_HEAD(ax25_linkfail_list);
 static DEFINE_SPINLOCK(linkfail_lock);
 
 static struct listen_struct {
@@ -49,36 +42,23 @@
 } *listen_list = NULL;
 static DEFINE_SPINLOCK(listen_lock);
 
-int ax25_protocol_register(unsigned int pid,
-	int (*func)(struct sk_buff *, ax25_cb *))
+/*
+ * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT,
+ * AX25_P_IP or AX25_P_ARP ...
+ */
+void ax25_register_pid(struct ax25_protocol *ap)
 {
-	struct protocol_struct *protocol;
-
-	if (pid == AX25_P_TEXT || pid == AX25_P_SEGMENT)
-		return 0;
-#ifdef CONFIG_INET
-	if (pid == AX25_P_IP || pid == AX25_P_ARP)
-		return 0;
-#endif
-	if ((protocol = kmalloc(sizeof(*protocol), GFP_ATOMIC)) == NULL)
-		return 0;
-
-	protocol->pid  = pid;
-	protocol->func = func;
-
 	write_lock_bh(&protocol_list_lock);
-	protocol->next = protocol_list;
-	protocol_list  = protocol;
+	ap->next = protocol_list;
+	protocol_list = ap;
 	write_unlock_bh(&protocol_list_lock);
-
-	return 1;
 }
 
-EXPORT_SYMBOL(ax25_protocol_register);
+EXPORT_SYMBOL_GPL(ax25_register_pid);
 
 void ax25_protocol_release(unsigned int pid)
 {
-	struct protocol_struct *s, *protocol;
+	struct ax25_protocol *s, *protocol;
 
 	write_lock_bh(&protocol_list_lock);
 	protocol = protocol_list;
@@ -110,54 +90,19 @@
 
 EXPORT_SYMBOL(ax25_protocol_release);
 
-int ax25_linkfail_register(void (*func)(ax25_cb *, int))
+void ax25_linkfail_register(struct ax25_linkfail *lf)
 {
-	struct linkfail_struct *linkfail;
-
-	if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL)
-		return 0;
-
-	linkfail->func = func;
-
 	spin_lock_bh(&linkfail_lock);
-	linkfail->next = linkfail_list;
-	linkfail_list  = linkfail;
+	hlist_add_head(&lf->lf_node, &ax25_linkfail_list);
 	spin_unlock_bh(&linkfail_lock);
-
-	return 1;
 }
 
 EXPORT_SYMBOL(ax25_linkfail_register);
 
-void ax25_linkfail_release(void (*func)(ax25_cb *, int))
+void ax25_linkfail_release(struct ax25_linkfail *lf)
 {
-	struct linkfail_struct *s, *linkfail;
-
 	spin_lock_bh(&linkfail_lock);
-	linkfail = linkfail_list;
-	if (linkfail == NULL) {
-		spin_unlock_bh(&linkfail_lock);
-		return;
-	}
-
-	if (linkfail->func == func) {
-		linkfail_list = linkfail->next;
-		spin_unlock_bh(&linkfail_lock);
-		kfree(linkfail);
-		return;
-	}
-
-	while (linkfail != NULL && linkfail->next != NULL) {
-		if (linkfail->next->func == func) {
-			s = linkfail->next;
-			linkfail->next = linkfail->next->next;
-			spin_unlock_bh(&linkfail_lock);
-			kfree(s);
-			return;
-		}
-
-		linkfail = linkfail->next;
-	}
+	hlist_del_init(&lf->lf_node);
 	spin_unlock_bh(&linkfail_lock);
 }
 
@@ -171,7 +116,7 @@
 		return 0;
 
 	if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL)
-		return 0;
+		return -ENOMEM;
 
 	listen->callsign = *callsign;
 	listen->dev      = dev;
@@ -181,7 +126,7 @@
 	listen_list  = listen;
 	spin_unlock_bh(&listen_lock);
 
-	return 1;
+	return 0;
 }
 
 EXPORT_SYMBOL(ax25_listen_register);
@@ -223,7 +168,7 @@
 int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
 {
 	int (*res)(struct sk_buff *, ax25_cb *) = NULL;
-	struct protocol_struct *protocol;
+	struct ax25_protocol *protocol;
 
 	read_lock(&protocol_list_lock);
 	for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
@@ -242,7 +187,8 @@
 
 	spin_lock_bh(&listen_lock);
 	for (listen = listen_list; listen != NULL; listen = listen->next)
-		if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL)) {
+		if (ax25cmp(&listen->callsign, callsign) == 0 &&
+		    (listen->dev == dev || listen->dev == NULL)) {
 			spin_unlock_bh(&listen_lock);
 			return 1;
 	}
@@ -253,17 +199,18 @@
 
 void ax25_link_failed(ax25_cb *ax25, int reason)
 {
-	struct linkfail_struct *linkfail;
+	struct ax25_linkfail *lf;
+	struct hlist_node *node;
 
 	spin_lock_bh(&linkfail_lock);
-	for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next)
-		(linkfail->func)(ax25, reason);
+	hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node)
+		lf->func(ax25, reason);
 	spin_unlock_bh(&linkfail_lock);
 }
 
 int ax25_protocol_is_registered(unsigned int pid)
 {
-	struct protocol_struct *protocol;
+	struct ax25_protocol *protocol;
 	int res = 0;
 
 	read_lock_bh(&protocol_list_lock);
diff -ru 2.2/net/ax25/ax25_route.c 3.4/net/ax25/ax25_route.c
--- 2.2/net/ax25/ax25_route.c	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/net/ax25/ax25_route.c	2006-12-22 01:57:08.000000000 +0100
@@ -71,7 +71,7 @@
 	write_unlock(&ax25_route_lock);
 }
 
-static int ax25_rt_add(struct ax25_routes_struct *route)
+static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
 {
 	ax25_route *ax25_rt;
 	ax25_dev *ax25_dev;
diff -ru 2.2/net/ipv4/route.c 3.4/net/ipv4/route.c
--- 2.2/net/ipv4/route.c	2006-12-10 23:31:24.000000000 +0100
+++ 3.4/net/ipv4/route.c	2006-12-22 01:57:08.000000000 +0100
@@ -1325,7 +1325,8 @@
 	/* Check for load limit; set rate_last to the latest sent
 	 * redirect.
 	 */
-	if (time_after(jiffies,
+	if (rt->u.dst.rate_tokens == 0 ||
+	    time_after(jiffies,
 		       (rt->u.dst.rate_last +
 			(ip_rt_redirect_load << rt->u.dst.rate_tokens)))) {
 		icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
diff -ru 2.2/net/ipv4/tcp_ipv4.c 3.4/net/ipv4/tcp_ipv4.c
--- 2.2/net/ipv4/tcp_ipv4.c	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/net/ipv4/tcp_ipv4.c	2006-12-22 01:57:08.000000000 +0100
@@ -928,6 +928,7 @@
 			if (tp->md5sig_info->entries4 == 0) {
 				kfree(tp->md5sig_info->keys4);
 				tp->md5sig_info->keys4 = NULL;
+				tp->md5sig_info->alloced4 = 0;
 			} else if (tp->md5sig_info->entries4 != i) {
 				/* Need to do some manipulation */
 				memcpy(&tp->md5sig_info->keys4[i],
@@ -1185,7 +1186,7 @@
 		return 0;
 
 	if (hash_expected && !hash_location) {
-		LIMIT_NETDEBUG(KERN_INFO "MD5 Hash NOT expected but found "
+		LIMIT_NETDEBUG(KERN_INFO "MD5 Hash expected but NOT found "
 			       "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)\n",
 			       NIPQUAD(iph->saddr), ntohs(th->source),
 			       NIPQUAD(iph->daddr), ntohs(th->dest));
diff -ru 2.2/net/ipv4/udp.c 3.4/net/ipv4/udp.c
--- 2.2/net/ipv4/udp.c	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/net/ipv4/udp.c	2006-12-23 01:11:20.000000000 +0100
@@ -165,11 +165,14 @@
 				goto gotit;
 			}
 			size = 0;
-			sk_for_each(sk2, node, head)
-				if (++size < best_size_so_far) {
-					best_size_so_far = size;
-					best = result;
-				}
+			sk_for_each(sk2, node, head) {
+				if (++size >= best_size_so_far)
+					goto next;
+			}
+			best_size_so_far = size;
+			best = result;
+		next:
+			;
 		}
 		result = best;
 		for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) {
diff -ru 2.2/net/ipv6/netfilter/Kconfig 3.4/net/ipv6/netfilter/Kconfig
--- 2.2/net/ipv6/netfilter/Kconfig	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/net/ipv6/netfilter/Kconfig	2006-12-22 01:57:08.000000000 +0100
@@ -7,7 +7,7 @@
 
 config NF_CONNTRACK_IPV6
 	tristate "IPv6 connection tracking support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	depends on INET && IPV6 && EXPERIMENTAL && NF_CONNTRACK
 	---help---
 	  Connection tracking keeps a record of what packets have passed
 	  through your machine, in order to figure out how they are related
@@ -21,6 +21,7 @@
 
 config IP6_NF_QUEUE
 	tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)"
+	depends on INET && IPV6 && NETFILTER && EXPERIMENTAL
 	---help---
 
 	  This option adds a queue handler to the kernel for IPv6
@@ -41,7 +42,7 @@
 
 config IP6_NF_IPTABLES
 	tristate "IP6 tables support (required for filtering)"
-	depends on NETFILTER_XTABLES
+	depends on INET && IPV6 && EXPERIMENTAL && NETFILTER_XTABLES
 	help
 	  ip6tables is a general, extensible packet identification framework.
 	  Currently only the packet filtering and packet mangling subsystem
diff -ru 2.2/net/netlabel/netlabel_cipso_v4.c 3.4/net/netlabel/netlabel_cipso_v4.c
--- 2.2/net/netlabel/netlabel_cipso_v4.c	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/net/netlabel/netlabel_cipso_v4.c	2006-12-23 01:11:20.000000000 +0100
@@ -162,6 +162,7 @@
 	struct nlattr *nla_b;
 	int nla_a_rem;
 	int nla_b_rem;
+	u32 iter;
 
 	if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
 	    !info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
@@ -185,20 +186,31 @@
 	ret_val = netlbl_cipsov4_add_common(info, doi_def);
 	if (ret_val != 0)
 		goto add_std_failure;
+	ret_val = -EINVAL;
 
 	nla_for_each_nested(nla_a,
 			    info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
 			    nla_a_rem)
 		if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) {
+			if (nla_validate_nested(nla_a,
+					    NLBL_CIPSOV4_A_MAX,
+					    netlbl_cipsov4_genl_policy) != 0)
+					goto add_std_failure;
 			nla_for_each_nested(nla_b, nla_a, nla_b_rem)
 				switch (nla_b->nla_type) {
 				case NLBL_CIPSOV4_A_MLSLVLLOC:
+					if (nla_get_u32(nla_b) >
+					    CIPSO_V4_MAX_LOC_LVLS)
+						goto add_std_failure;
 					if (nla_get_u32(nla_b) >=
 					    doi_def->map.std->lvl.local_size)
 					     doi_def->map.std->lvl.local_size =
 						     nla_get_u32(nla_b) + 1;
 					break;
 				case NLBL_CIPSOV4_A_MLSLVLREM:
+					if (nla_get_u32(nla_b) >
+					    CIPSO_V4_MAX_REM_LVLS)
+						goto add_std_failure;
 					if (nla_get_u32(nla_b) >=
 					    doi_def->map.std->lvl.cipso_size)
 					     doi_def->map.std->lvl.cipso_size =
@@ -206,9 +218,6 @@
 					break;
 				}
 		}
-	if (doi_def->map.std->lvl.local_size > CIPSO_V4_MAX_LOC_LVLS ||
-	    doi_def->map.std->lvl.cipso_size > CIPSO_V4_MAX_REM_LVLS)
-		goto add_std_failure;
 	doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size,
 					      sizeof(u32),
 					      GFP_KERNEL);
@@ -223,6 +232,10 @@
 		ret_val = -ENOMEM;
 		goto add_std_failure;
 	}
+	for (iter = 0; iter < doi_def->map.std->lvl.local_size; iter++)
+		doi_def->map.std->lvl.local[iter] = CIPSO_V4_INV_LVL;
+	for (iter = 0; iter < doi_def->map.std->lvl.cipso_size; iter++)
+		doi_def->map.std->lvl.cipso[iter] = CIPSO_V4_INV_LVL;
 	nla_for_each_nested(nla_a,
 			    info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
 			    nla_a_rem)
@@ -230,11 +243,6 @@
 			struct nlattr *lvl_loc;
 			struct nlattr *lvl_rem;
 
-			if (nla_validate_nested(nla_a,
-					      NLBL_CIPSOV4_A_MAX,
-					      netlbl_cipsov4_genl_policy) != 0)
-				goto add_std_failure;
-
 			lvl_loc = nla_find_nested(nla_a,
 						  NLBL_CIPSOV4_A_MLSLVLLOC);
 			lvl_rem = nla_find_nested(nla_a,
@@ -264,12 +272,18 @@
 				nla_for_each_nested(nla_b, nla_a, nla_b_rem)
 					switch (nla_b->nla_type) {
 					case NLBL_CIPSOV4_A_MLSCATLOC:
+						if (nla_get_u32(nla_b) >
+						    CIPSO_V4_MAX_LOC_CATS)
+							goto add_std_failure;
 						if (nla_get_u32(nla_b) >=
 					      doi_def->map.std->cat.local_size)
 					     doi_def->map.std->cat.local_size =
 						     nla_get_u32(nla_b) + 1;
 						break;
 					case NLBL_CIPSOV4_A_MLSCATREM:
+						if (nla_get_u32(nla_b) >
+						    CIPSO_V4_MAX_REM_CATS)
+							goto add_std_failure;
 						if (nla_get_u32(nla_b) >=
 					      doi_def->map.std->cat.cipso_size)
 					     doi_def->map.std->cat.cipso_size =
@@ -277,9 +291,6 @@
 						break;
 					}
 			}
-		if (doi_def->map.std->cat.local_size > CIPSO_V4_MAX_LOC_CATS ||
-		    doi_def->map.std->cat.cipso_size > CIPSO_V4_MAX_REM_CATS)
-			goto add_std_failure;
 		doi_def->map.std->cat.local = kcalloc(
 			                      doi_def->map.std->cat.local_size,
 					      sizeof(u32),
@@ -296,6 +307,10 @@
 			ret_val = -ENOMEM;
 			goto add_std_failure;
 		}
+		for (iter = 0; iter < doi_def->map.std->cat.local_size; iter++)
+			doi_def->map.std->cat.local[iter] = CIPSO_V4_INV_CAT;
+		for (iter = 0; iter < doi_def->map.std->cat.cipso_size; iter++)
+			doi_def->map.std->cat.cipso[iter] = CIPSO_V4_INV_CAT;
 		nla_for_each_nested(nla_a,
 				    info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
 				    nla_a_rem)
diff -ru 2.2/net/netrom/af_netrom.c 3.4/net/netrom/af_netrom.c
--- 2.2/net/netrom/af_netrom.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/net/netrom/af_netrom.c	2006-12-22 01:57:08.000000000 +0100
@@ -1377,6 +1377,15 @@
 
 static struct net_device **dev_nr;
 
+static struct ax25_protocol nr_pid = {
+	.pid	= AX25_P_NETROM,
+	.func	= nr_route_frame
+};
+
+static struct ax25_linkfail nr_linkfail_notifier = {
+	.func	= nr_link_failed,
+};
+
 static int __init nr_proto_init(void)
 {
 	int i;
@@ -1424,8 +1433,8 @@
 		
 	register_netdevice_notifier(&nr_dev_notifier);
 
-	ax25_protocol_register(AX25_P_NETROM, nr_route_frame);
-	ax25_linkfail_register(nr_link_failed);
+	ax25_register_pid(&nr_pid);
+	ax25_linkfail_register(&nr_linkfail_notifier);
 
 #ifdef CONFIG_SYSCTL
 	nr_register_sysctl();
@@ -1474,7 +1483,7 @@
 	nr_unregister_sysctl();
 #endif
 
-	ax25_linkfail_release(nr_link_failed);
+	ax25_linkfail_release(&nr_linkfail_notifier);
 	ax25_protocol_release(AX25_P_NETROM);
 
 	unregister_netdevice_notifier(&nr_dev_notifier);
diff -ru 2.2/net/netrom/nr_dev.c 3.4/net/netrom/nr_dev.c
--- 2.2/net/netrom/nr_dev.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/net/netrom/nr_dev.c	2006-12-22 01:57:08.000000000 +0100
@@ -128,25 +128,37 @@
 	return -37;
 }
 
-static int nr_set_mac_address(struct net_device *dev, void *addr)
+static int __must_check nr_set_mac_address(struct net_device *dev, void *addr)
 {
 	struct sockaddr *sa = addr;
+	int err;
+
+	if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
+		return 0;
+
+	if (dev->flags & IFF_UP) {
+		err = ax25_listen_register((ax25_address *)sa->sa_data, NULL);
+		if (err)
+			return err;
 
-	if (dev->flags & IFF_UP)
 		ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
+	}
 
 	memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
 
-	if (dev->flags & IFF_UP)
-		ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
-
 	return 0;
 }
 
 static int nr_open(struct net_device *dev)
 {
+	int err;
+
+	err = ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
+	if (err)
+		return err;
+
 	netif_start_queue(dev);
-	ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
+
 	return 0;
 }
 
diff -ru 2.2/net/netrom/nr_route.c 3.4/net/netrom/nr_route.c
--- 2.2/net/netrom/nr_route.c	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/net/netrom/nr_route.c	2006-12-22 01:57:08.000000000 +0100
@@ -87,8 +87,9 @@
  *	Add a new route to a node, and in the process add the node and the
  *	neighbour if it is new.
  */
-static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax25,
-	ax25_digi *ax25_digi, struct net_device *dev, int quality, int obs_count)
+static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
+	ax25_address *ax25, ax25_digi *ax25_digi, struct net_device *dev,
+	int quality, int obs_count)
 {
 	struct nr_node  *nr_node;
 	struct nr_neigh *nr_neigh;
@@ -406,7 +407,8 @@
 /*
  *	Lock a neighbour with a quality.
  */
-static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
+static int __must_check nr_add_neigh(ax25_address *callsign,
+	ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
 {
 	struct nr_neigh *nr_neigh;
 
@@ -777,9 +779,13 @@
 	nr_src  = (ax25_address *)(skb->data + 0);
 	nr_dest = (ax25_address *)(skb->data + 7);
 
-	if (ax25 != NULL)
-		nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
-			    ax25->ax25_dev->dev, 0, sysctl_netrom_obsolescence_count_initialiser);
+	if (ax25 != NULL) {
+		ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
+		                  ax25->ax25_dev->dev, 0,
+		                  sysctl_netrom_obsolescence_count_initialiser);
+		if (ret)
+			return ret;
+	}
 
 	if ((dev = nr_dev_get(nr_dest)) != NULL) {	/* Its for me */
 		if (ax25 == NULL)			/* Its from me */
@@ -844,6 +850,7 @@
 	ret = (nr_neigh->ax25 != NULL);
 	nr_node_unlock(nr_node);
 	nr_node_put(nr_node);
+
 	return ret;
 }
 
diff -ru 2.2/net/rose/af_rose.c 3.4/net/rose/af_rose.c
--- 2.2/net/rose/af_rose.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/net/rose/af_rose.c	2006-12-22 01:57:08.000000000 +0100
@@ -1314,7 +1314,8 @@
 		if (copy_from_user(&rose_callsign, argp, sizeof(ax25_address)))
 			return -EFAULT;
 		if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
-			ax25_listen_register(&rose_callsign, NULL);
+			return ax25_listen_register(&rose_callsign, NULL);
+
 		return 0;
 
 	case SIOCRSGL2CALL:
@@ -1481,6 +1482,15 @@
 
 static struct net_device **dev_rose;
 
+static struct ax25_protocol rose_pid = {
+	.pid	= AX25_P_ROSE,
+	.func	= rose_route_frame
+};
+
+static struct ax25_linkfail rose_linkfail_notifier = {
+	.func	= rose_link_failed
+};
+
 static int __init rose_proto_init(void)
 {
 	int i;
@@ -1530,8 +1540,8 @@
 	sock_register(&rose_family_ops);
 	register_netdevice_notifier(&rose_dev_notifier);
 
-	ax25_protocol_register(AX25_P_ROSE, rose_route_frame);
-	ax25_linkfail_register(rose_link_failed);
+	ax25_register_pid(&rose_pid);
+	ax25_linkfail_register(&rose_linkfail_notifier);
 
 #ifdef CONFIG_SYSCTL
 	rose_register_sysctl();
@@ -1579,7 +1589,7 @@
 	rose_rt_free();
 
 	ax25_protocol_release(AX25_P_ROSE);
-	ax25_linkfail_release(rose_link_failed);
+	ax25_linkfail_release(&rose_linkfail_notifier);
 
 	if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
 		ax25_listen_release(&rose_callsign, NULL);
diff -ru 2.2/net/rose/rose_dev.c 3.4/net/rose/rose_dev.c
--- 2.2/net/rose/rose_dev.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/net/rose/rose_dev.c	2006-12-22 01:57:08.000000000 +0100
@@ -93,20 +93,34 @@
 static int rose_set_mac_address(struct net_device *dev, void *addr)
 {
 	struct sockaddr *sa = addr;
+	int err;
 
-	rose_del_loopback_node((rose_address *)dev->dev_addr);
+	if (!memcpy(dev->dev_addr, sa->sa_data, dev->addr_len))
+		return 0;
 
-	memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
+	if (dev->flags & IFF_UP) {
+		err = rose_add_loopback_node((rose_address *)dev->dev_addr);
+		if (err)
+			return err;
+
+		rose_del_loopback_node((rose_address *)dev->dev_addr);
+	}
 
-	rose_add_loopback_node((rose_address *)dev->dev_addr);
+	memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
 
 	return 0;
 }
 
 static int rose_open(struct net_device *dev)
 {
+	int err;
+
+	err = rose_add_loopback_node((rose_address *)dev->dev_addr);
+	if (err)
+		return err;
+
 	netif_start_queue(dev);
-	rose_add_loopback_node((rose_address *)dev->dev_addr);
+
 	return 0;
 }
 
diff -ru 2.2/net/rose/rose_loopback.c 3.4/net/rose/rose_loopback.c
--- 2.2/net/rose/rose_loopback.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/net/rose/rose_loopback.c	2006-12-22 01:57:08.000000000 +0100
@@ -79,7 +79,8 @@
 
 		skb->h.raw = skb->data;
 
-		if ((sk = rose_find_socket(lci_o, rose_loopback_neigh)) != NULL) {
+		sk = rose_find_socket(lci_o, &rose_loopback_neigh);
+		if (sk) {
 			if (rose_process_rx_frame(sk, skb) == 0)
 				kfree_skb(skb);
 			continue;
@@ -87,7 +88,7 @@
 
 		if (frametype == ROSE_CALL_REQUEST) {
 			if ((dev = rose_dev_get(dest)) != NULL) {
-				if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0)
+				if (rose_rx_call_request(skb, dev, &rose_loopback_neigh, lci_o) == 0)
 					kfree_skb(skb);
 			} else {
 				kfree_skb(skb);
diff -ru 2.2/net/rose/rose_route.c 3.4/net/rose/rose_route.c
--- 2.2/net/rose/rose_route.c	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/net/rose/rose_route.c	2006-12-22 01:57:08.000000000 +0100
@@ -46,13 +46,13 @@
 static struct rose_route *rose_route_list;
 static DEFINE_SPINLOCK(rose_route_list_lock);
 
-struct rose_neigh *rose_loopback_neigh;
+struct rose_neigh rose_loopback_neigh;
 
 /*
  *	Add a new route to a node, and in the process add the node and the
  *	neighbour if it is new.
  */
-static int rose_add_node(struct rose_route_struct *rose_route,
+static int __must_check rose_add_node(struct rose_route_struct *rose_route,
 	struct net_device *dev)
 {
 	struct rose_node  *rose_node, *rose_tmpn, *rose_tmpp;
@@ -361,33 +361,30 @@
 /*
  *	Add the loopback neighbour.
  */
-int rose_add_loopback_neigh(void)
+void rose_add_loopback_neigh(void)
 {
-	if ((rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_ATOMIC)) == NULL)
-		return -ENOMEM;
+	struct rose_neigh *sn = &rose_loopback_neigh;
 
-	rose_loopback_neigh->callsign  = null_ax25_address;
-	rose_loopback_neigh->digipeat  = NULL;
-	rose_loopback_neigh->ax25      = NULL;
-	rose_loopback_neigh->dev       = NULL;
-	rose_loopback_neigh->count     = 0;
-	rose_loopback_neigh->use       = 0;
-	rose_loopback_neigh->dce_mode  = 1;
-	rose_loopback_neigh->loopback  = 1;
-	rose_loopback_neigh->number    = rose_neigh_no++;
-	rose_loopback_neigh->restarted = 1;
+	sn->callsign  = null_ax25_address;
+	sn->digipeat  = NULL;
+	sn->ax25      = NULL;
+	sn->dev       = NULL;
+	sn->count     = 0;
+	sn->use       = 0;
+	sn->dce_mode  = 1;
+	sn->loopback  = 1;
+	sn->number    = rose_neigh_no++;
+	sn->restarted = 1;
 
-	skb_queue_head_init(&rose_loopback_neigh->queue);
+	skb_queue_head_init(&sn->queue);
 
-	init_timer(&rose_loopback_neigh->ftimer);
-	init_timer(&rose_loopback_neigh->t0timer);
+	init_timer(&sn->ftimer);
+	init_timer(&sn->t0timer);
 
 	spin_lock_bh(&rose_neigh_list_lock);
-	rose_loopback_neigh->next = rose_neigh_list;
-	rose_neigh_list           = rose_loopback_neigh;
+	sn->next = rose_neigh_list;
+	rose_neigh_list           = sn;
 	spin_unlock_bh(&rose_neigh_list_lock);
-
-	return 0;
 }
 
 /*
@@ -421,13 +418,13 @@
 	rose_node->mask         = 10;
 	rose_node->count        = 1;
 	rose_node->loopback     = 1;
-	rose_node->neighbour[0] = rose_loopback_neigh;
+	rose_node->neighbour[0] = &rose_loopback_neigh;
 
 	/* Insert at the head of list. Address is always mask=10 */
 	rose_node->next = rose_node_list;
 	rose_node_list  = rose_node;
 
-	rose_loopback_neigh->count++;
+	rose_loopback_neigh.count++;
 
 out:
 	spin_unlock_bh(&rose_node_list_lock);
@@ -458,7 +455,7 @@
 
 	rose_remove_node(rose_node);
 
-	rose_loopback_neigh->count--;
+	rose_loopback_neigh.count--;
 
 out:
 	spin_unlock_bh(&rose_node_list_lock);
diff -ru 2.2/net/sctp/ipv6.c 3.4/net/sctp/ipv6.c
--- 2.2/net/sctp/ipv6.c	2006-12-14 04:27:37.000000000 +0100
+++ 3.4/net/sctp/ipv6.c	2006-12-23 01:11:20.000000000 +0100
@@ -79,8 +79,8 @@
 #include <asm/uaccess.h>
 
 /* Event handler for inet6 address addition/deletion events.  */
-int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
-                        void *ptr)
+static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
+				void *ptr)
 {
 	struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
 	struct sctp_sockaddr_entry *addr;
diff -ru 2.2/net/sctp/protocol.c 3.4/net/sctp/protocol.c
--- 2.2/net/sctp/protocol.c	2006-12-14 04:27:37.000000000 +0100
+++ 3.4/net/sctp/protocol.c	2006-12-23 01:11:20.000000000 +0100
@@ -601,8 +601,8 @@
 }
 
 /* Event handler for inet address addition/deletion events.  */
-int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
-                        void *ptr)
+static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
+			       void *ptr)
 {
 	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
 	struct sctp_sockaddr_entry *addr;
diff -ru 2.2/net/sctp/sm_make_chunk.c 3.4/net/sctp/sm_make_chunk.c
--- 2.2/net/sctp/sm_make_chunk.c	2006-12-08 04:50:58.000000000 +0100
+++ 3.4/net/sctp/sm_make_chunk.c	2006-12-23 01:11:20.000000000 +0100
@@ -184,7 +184,7 @@
 	struct sctp_sock *sp;
 	sctp_supported_addrs_param_t sat;
 	__be16 types[2];
-	sctp_adaption_ind_param_t aiparam;
+	sctp_adaptation_ind_param_t aiparam;
 
 	/* RFC 2960 3.3.2 Initiation (INIT) (1)
 	 *
@@ -249,9 +249,9 @@
 	sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
 	if (sctp_prsctp_enable)
 		sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
-	aiparam.param_hdr.type = SCTP_PARAM_ADAPTION_LAYER_IND;
+	aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
 	aiparam.param_hdr.length = htons(sizeof(aiparam));
-	aiparam.adaption_ind = htonl(sp->adaption_ind);
+	aiparam.adaptation_ind = htonl(sp->adaptation_ind);
 	sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
 nodata:
 	kfree(addrs.v);
@@ -269,7 +269,7 @@
 	sctp_cookie_param_t *cookie;
 	int cookie_len;
 	size_t chunksize;
-	sctp_adaption_ind_param_t aiparam;
+	sctp_adaptation_ind_param_t aiparam;
 
 	retval = NULL;
 
@@ -323,9 +323,9 @@
 	if (asoc->peer.prsctp_capable)
 		sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
 
-	aiparam.param_hdr.type = SCTP_PARAM_ADAPTION_LAYER_IND;
+	aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
 	aiparam.param_hdr.length = htons(sizeof(aiparam));
-	aiparam.adaption_ind = htonl(sctp_sk(asoc->base.sk)->adaption_ind);
+	aiparam.adaptation_ind = htonl(sctp_sk(asoc->base.sk)->adaptation_ind);
 	sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
 
 	/* We need to remove the const qualifier at this point.  */
@@ -1300,8 +1300,8 @@
 	/* Remember PR-SCTP capability. */
 	cookie->c.prsctp_capable = asoc->peer.prsctp_capable;
 
-	/* Save adaption indication in the cookie. */
-	cookie->c.adaption_ind = asoc->peer.adaption_ind;
+	/* Save adaptation indication in the cookie. */
+	cookie->c.adaptation_ind = asoc->peer.adaptation_ind;
 
 	/* Set an expiration time for the cookie.  */
 	do_gettimeofday(&cookie->c.expiration);
@@ -1512,7 +1512,7 @@
 	retval->addip_serial = retval->c.initial_tsn;
 	retval->adv_peer_ack_point = retval->ctsn_ack_point;
 	retval->peer.prsctp_capable = retval->c.prsctp_capable;
-	retval->peer.adaption_ind = retval->c.adaption_ind;
+	retval->peer.adaptation_ind = retval->c.adaptation_ind;
 
 	/* The INIT stuff will be done by the side effects.  */
 	return retval;
@@ -1743,7 +1743,7 @@
 	case SCTP_PARAM_HEARTBEAT_INFO:
 	case SCTP_PARAM_UNRECOGNIZED_PARAMETERS:
 	case SCTP_PARAM_ECN_CAPABLE:
-	case SCTP_PARAM_ADAPTION_LAYER_IND:
+	case SCTP_PARAM_ADAPTATION_LAYER_IND:
 		break;
 
 	case SCTP_PARAM_HOST_NAME_ADDRESS:
@@ -2098,8 +2098,8 @@
 		asoc->peer.ecn_capable = 1;
 		break;
 
-	case SCTP_PARAM_ADAPTION_LAYER_IND:
-		asoc->peer.adaption_ind = param.aind->adaption_ind;
+	case SCTP_PARAM_ADAPTATION_LAYER_IND:
+		asoc->peer.adaptation_ind = param.aind->adaptation_ind;
 		break;
 
 	case SCTP_PARAM_FWD_TSN_SUPPORT:
diff -ru 2.2/net/sctp/sm_statefuns.c 3.4/net/sctp/sm_statefuns.c
--- 2.2/net/sctp/sm_statefuns.c	2006-12-07 02:52:16.000000000 +0100
+++ 3.4/net/sctp/sm_statefuns.c	2006-12-23 01:11:20.000000000 +0100
@@ -688,12 +688,12 @@
 		goto nomem_ev;
 
 	/* Sockets API Draft Section 5.3.1.6 	
-	 * When a peer sends a Adaption Layer Indication parameter , SCTP
+	 * When a peer sends a Adaptation Layer Indication parameter , SCTP
 	 * delivers this notification to inform the application that of the
-	 * peers requested adaption layer.
+	 * peers requested adaptation layer.
 	 */
-	if (new_asoc->peer.adaption_ind) {
-		ai_ev = sctp_ulpevent_make_adaption_indication(new_asoc,
+	if (new_asoc->peer.adaptation_ind) {
+		ai_ev = sctp_ulpevent_make_adaptation_indication(new_asoc,
 							    GFP_ATOMIC);
 		if (!ai_ev)
 			goto nomem_aiev;
@@ -820,12 +820,12 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
 
 	/* Sockets API Draft Section 5.3.1.6
-	 * When a peer sends a Adaption Layer Indication parameter , SCTP
+	 * When a peer sends a Adaptation Layer Indication parameter , SCTP
 	 * delivers this notification to inform the application that of the
-	 * peers requested adaption layer.
+	 * peers requested adaptation layer.
 	 */
-	if (asoc->peer.adaption_ind) {
-		ev = sctp_ulpevent_make_adaption_indication(asoc, GFP_ATOMIC);
+	if (asoc->peer.adaptation_ind) {
+		ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
 		if (!ev)
 			goto nomem;
 
@@ -1698,12 +1698,12 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
 
 	/* Sockets API Draft Section 5.3.1.6
-	 * When a peer sends a Adaption Layer Indication parameter , SCTP
+	 * When a peer sends a Adaptation Layer Indication parameter , SCTP
 	 * delivers this notification to inform the application that of the
-	 * peers requested adaption layer.
+	 * peers requested adaptation layer.
 	 */
-	if (asoc->peer.adaption_ind) {
-		ev = sctp_ulpevent_make_adaption_indication(asoc, GFP_ATOMIC);
+	if (asoc->peer.adaptation_ind) {
+		ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
 		if (!ev)
 			goto nomem_ev;
 
@@ -1791,12 +1791,12 @@
 			goto nomem;
 
 		/* Sockets API Draft Section 5.3.1.6
-		 * When a peer sends a Adaption Layer Indication parameter,
+		 * When a peer sends a Adaptation Layer Indication parameter,
 		 * SCTP delivers this notification to inform the application
-		 * that of the peers requested adaption layer.
+		 * that of the peers requested adaptation layer.
 		 */
-		if (asoc->peer.adaption_ind) {
-			ai_ev = sctp_ulpevent_make_adaption_indication(asoc,
+		if (asoc->peer.adaptation_ind) {
+			ai_ev = sctp_ulpevent_make_adaptation_indication(asoc,
 								 GFP_ATOMIC);
 			if (!ai_ev)
 				goto nomem;
diff -ru 2.2/net/sctp/socket.c 3.4/net/sctp/socket.c
--- 2.2/net/sctp/socket.c	2006-12-14 04:27:37.000000000 +0100
+++ 3.4/net/sctp/socket.c	2006-12-23 01:11:20.000000000 +0100
@@ -2731,17 +2731,17 @@
 	return err;
 }
 
-static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval,
 					  int optlen)
 {
-	struct sctp_setadaption adaption;
+	struct sctp_setadaptation adaptation;
 
-	if (optlen != sizeof(struct sctp_setadaption))
+	if (optlen != sizeof(struct sctp_setadaptation))
 		return -EINVAL;
-	if (copy_from_user(&adaption, optval, optlen)) 
+	if (copy_from_user(&adaptation, optval, optlen))
 		return -EFAULT;
 
-	sctp_sk(sk)->adaption_ind = adaption.ssb_adaption_ind;
+	sctp_sk(sk)->adaptation_ind = adaptation.ssb_adaptation_ind;
 
 	return 0;
 }
@@ -2894,8 +2894,8 @@
 	case SCTP_MAXSEG:
 		retval = sctp_setsockopt_maxseg(sk, optval, optlen);
 		break;
-	case SCTP_ADAPTION_LAYER:
-		retval = sctp_setsockopt_adaption_layer(sk, optval, optlen);
+	case SCTP_ADAPTATION_LAYER:
+		retval = sctp_setsockopt_adaptation_layer(sk, optval, optlen);
 		break;
 	case SCTP_CONTEXT:
 		retval = sctp_setsockopt_context(sk, optval, optlen);
@@ -3123,7 +3123,7 @@
 	/* User specified fragmentation limit. */
 	sp->user_frag         = 0;
 
-	sp->adaption_ind = 0;
+	sp->adaptation_ind = 0;
 
 	sp->pf = sctp_get_pf_specific(sk->sk_family);
 
@@ -4210,21 +4210,21 @@
 }
 
 /*
- * 7.1.11  Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER)
+ * 7.1.11  Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER)
  *
- * Requests that the local endpoint set the specified Adaption Layer
+ * Requests that the local endpoint set the specified Adaptation Layer
  * Indication parameter for all future INIT and INIT-ACK exchanges.
  */
-static int sctp_getsockopt_adaption_layer(struct sock *sk, int len,
+static int sctp_getsockopt_adaptation_layer(struct sock *sk, int len,
 				  char __user *optval, int __user *optlen)
 {
-	struct sctp_setadaption adaption;
+	struct sctp_setadaptation adaptation;
 
-	if (len != sizeof(struct sctp_setadaption))
+	if (len != sizeof(struct sctp_setadaptation))
 		return -EINVAL;
 
-	adaption.ssb_adaption_ind = sctp_sk(sk)->adaption_ind;
-	if (copy_to_user(optval, &adaption, len))
+	adaptation.ssb_adaptation_ind = sctp_sk(sk)->adaptation_ind;
+	if (copy_to_user(optval, &adaptation, len))
 		return -EFAULT;
 
 	return 0;
@@ -4635,8 +4635,8 @@
 		retval = sctp_getsockopt_peer_addr_info(sk, len, optval,
 							optlen);
 		break;
-	case SCTP_ADAPTION_LAYER:
-		retval = sctp_getsockopt_adaption_layer(sk, len, optval,
+	case SCTP_ADAPTATION_LAYER:
+		retval = sctp_getsockopt_adaptation_layer(sk, len, optval,
 							optlen);
 		break;
 	case SCTP_CONTEXT:
diff -ru 2.2/net/sctp/ulpevent.c 3.4/net/sctp/ulpevent.c
--- 2.2/net/sctp/ulpevent.c	2006-12-14 04:27:37.000000000 +0100
+++ 3.4/net/sctp/ulpevent.c	2006-12-23 01:11:20.000000000 +0100
@@ -609,31 +609,31 @@
 	return NULL;
 }
 
-/* Create and initialize a SCTP_ADAPTION_INDICATION notification.
+/* Create and initialize a SCTP_ADAPTATION_INDICATION notification.
  *
  * Socket Extensions for SCTP
- * 5.3.1.6 SCTP_ADAPTION_INDICATION
+ * 5.3.1.6 SCTP_ADAPTATION_INDICATION
  */
-struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication(
+struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication(
 	const struct sctp_association *asoc, gfp_t gfp)
 {
 	struct sctp_ulpevent *event;
-	struct sctp_adaption_event *sai;
+	struct sctp_adaptation_event *sai;
 	struct sk_buff *skb;
 
-	event = sctp_ulpevent_new(sizeof(struct sctp_adaption_event),
+	event = sctp_ulpevent_new(sizeof(struct sctp_adaptation_event),
 				  MSG_NOTIFICATION, gfp);
 	if (!event)
 		goto fail;
 
 	skb = sctp_event2skb(event);
-	sai = (struct sctp_adaption_event *)
-		skb_put(skb, sizeof(struct sctp_adaption_event));
+	sai = (struct sctp_adaptation_event *)
+		skb_put(skb, sizeof(struct sctp_adaptation_event));
 
-	sai->sai_type = SCTP_ADAPTION_INDICATION;
+	sai->sai_type = SCTP_ADAPTATION_INDICATION;
 	sai->sai_flags = 0;
-	sai->sai_length = sizeof(struct sctp_adaption_event);
-	sai->sai_adaption_ind = asoc->peer.adaption_ind;
+	sai->sai_length = sizeof(struct sctp_adaptation_event);
+	sai->sai_adaptation_ind = asoc->peer.adaptation_ind;
 	sctp_ulpevent_set_owner(event, asoc);
 	sai->sai_assoc_id = sctp_assoc2id(asoc);
 
diff -ru 2.2/net/sunrpc/auth_gss/gss_spkm3_mech.c 3.4/net/sunrpc/auth_gss/gss_spkm3_mech.c
--- 2.2/net/sunrpc/auth_gss/gss_spkm3_mech.c	2006-12-08 04:50:58.000000000 +0100
+++ 3.4/net/sunrpc/auth_gss/gss_spkm3_mech.c	2006-12-23 01:11:20.000000000 +0100
@@ -228,7 +228,7 @@
 	status = gss_mech_register(&gss_spkm3_mech);
 	if (status)
 		printk("Failed to register spkm3 gss mechanism!\n");
-	return 0;
+	return status;
 }
 
 static void __exit cleanup_spkm3_module(void)
diff -ru 2.2/scripts/kernel-doc 3.4/scripts/kernel-doc
--- 2.2/scripts/kernel-doc	2006-12-08 04:50:58.000000000 +0100
+++ 3.4/scripts/kernel-doc	2006-12-23 01:11:20.000000000 +0100
@@ -1469,6 +1469,7 @@
 	my $param = shift;
 	my $type = shift;
 	my $file = shift;
+	my $anon = 0;
 
 	my $param_name = $param;
 	$param_name =~ s/\[.*//;
@@ -1484,9 +1485,20 @@
 	    $param="void";
 	    $parameterdescs{void} = "no arguments";
 	}
+	elsif ($type eq "" && ($param eq "struct" or $param eq "union"))
+	# handle unnamed (anonymous) union or struct:
+	{
+		$type = $param;
+		$param = "{unnamed_" . $param. "}";
+		$parameterdescs{$param} = "anonymous\n";
+		$anon = 1;
+	}
+
 	# warn if parameter has no description
-	# (but ignore ones starting with # as these are no parameters
-	# but inline preprocessor statements
+	# (but ignore ones starting with # as these are not parameters
+	# but inline preprocessor statements);
+	# also ignore unnamed structs/unions;
+	if (!$anon) {
 	if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) {
 
 	    $parameterdescs{$param_name} = $undescribed;
@@ -1500,6 +1512,7 @@
 	                 " No description found for parameter '$param'\n";
 	    ++$warnings;
         }
+        }
 
 	push @parameterlist, $param;
 	$parametertypes{$param} = $type;
diff -ru 2.2/sound/aoa/codecs/snd-aoa-codec-onyx.h 3.4/sound/aoa/codecs/snd-aoa-codec-onyx.h
--- 2.2/sound/aoa/codecs/snd-aoa-codec-onyx.h	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/aoa/codecs/snd-aoa-codec-onyx.h	2006-12-22 01:57:08.000000000 +0100
@@ -9,7 +9,6 @@
 #define __SND_AOA_CODEC_ONYX_H
 #include <stddef.h>
 #include <linux/i2c.h>
-#include <linux/i2c-dev.h>
 #include <asm/pmac_low_i2c.h>
 #include <asm/prom.h>
 
diff -ru 2.2/sound/aoa/codecs/snd-aoa-codec-tas.c 3.4/sound/aoa/codecs/snd-aoa-codec-tas.c
--- 2.2/sound/aoa/codecs/snd-aoa-codec-tas.c	2006-11-29 04:53:09.000000000 +0100
+++ 3.4/sound/aoa/codecs/snd-aoa-codec-tas.c	2006-12-22 01:57:08.000000000 +0100
@@ -61,7 +61,6 @@
  */
 #include <stddef.h>
 #include <linux/i2c.h>
-#include <linux/i2c-dev.h>
 #include <asm/pmac_low_i2c.h>
 #include <asm/prom.h>
 #include <linux/delay.h>
diff -ru 2.2/sound/core/control.c 3.4/sound/core/control.c
--- 2.2/sound/core/control.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/core/control.c	2006-12-22 01:57:08.000000000 +0100
@@ -1275,7 +1275,7 @@
 			schedule();
 			remove_wait_queue(&ctl->change_sleep, &wait);
 			if (signal_pending(current))
-				return result > 0 ? result : -ERESTARTSYS;
+				return -ERESTARTSYS;
 			spin_lock_irq(&ctl->read_lock);
 		}
 		kev = snd_kctl_event(ctl->events.next);
diff -ru 2.2/sound/core/oss/pcm_oss.c 3.4/sound/core/oss/pcm_oss.c
--- 2.2/sound/core/oss/pcm_oss.c	2006-11-29 04:53:09.000000000 +0100
+++ 3.4/sound/core/oss/pcm_oss.c	2006-12-22 01:57:08.000000000 +0100
@@ -810,6 +810,8 @@
 	struct snd_mask sformat_mask;
 	struct snd_mask mask;
 
+	if (mutex_lock_interruptible(&runtime->oss.params_lock))
+		return -EINTR;
 	sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL);
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
 	sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
@@ -1020,6 +1022,7 @@
 	kfree(sw_params);
 	kfree(params);
 	kfree(sparams);
+	mutex_unlock(&runtime->oss.params_lock);
 	return err;
 }
 
@@ -1307,14 +1310,17 @@
 
 	if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
 		return tmp;
+	mutex_lock(&runtime->oss.params_lock);
 	while (bytes > 0) {
 		if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
 			tmp = bytes;
 			if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
 				tmp = runtime->oss.period_bytes - runtime->oss.buffer_used;
 			if (tmp > 0) {
-				if (copy_from_user(runtime->oss.buffer + runtime->oss.buffer_used, buf, tmp))
-					return xfer > 0 ? (snd_pcm_sframes_t)xfer : -EFAULT;
+				if (copy_from_user(runtime->oss.buffer + runtime->oss.buffer_used, buf, tmp)) {
+					tmp = -EFAULT;
+					goto err;
+				}
 			}
 			runtime->oss.buffer_used += tmp;
 			buf += tmp;
@@ -1325,22 +1331,24 @@
 				tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer + runtime->oss.period_ptr, 
 							 runtime->oss.buffer_used - runtime->oss.period_ptr, 1);
 				if (tmp <= 0)
-					return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
+					goto err;
 				runtime->oss.bytes += tmp;
 				runtime->oss.period_ptr += tmp;
 				runtime->oss.period_ptr %= runtime->oss.period_bytes;
 				if (runtime->oss.period_ptr == 0 ||
 				    runtime->oss.period_ptr == runtime->oss.buffer_used)
 					runtime->oss.buffer_used = 0;
-				else if ((substream->f_flags & O_NONBLOCK) != 0)
-					return xfer > 0 ? xfer : -EAGAIN;
+				else if ((substream->f_flags & O_NONBLOCK) != 0) {
+					tmp = -EAGAIN;
+					goto err;
+				}
 			}
 		} else {
 			tmp = snd_pcm_oss_write2(substream,
 						 (const char __force *)buf,
 						 runtime->oss.period_bytes, 0);
 			if (tmp <= 0)
-				return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
+				goto err;
 			runtime->oss.bytes += tmp;
 			buf += tmp;
 			bytes -= tmp;
@@ -1350,7 +1358,12 @@
 				break;
 		}
 	}
+	mutex_unlock(&runtime->oss.params_lock);
 	return xfer;
+
+ err:
+	mutex_unlock(&runtime->oss.params_lock);
+	return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 }
 
 static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, size_t bytes, int in_kernel)
@@ -1397,12 +1410,13 @@
 
 	if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
 		return tmp;
+	mutex_lock(&runtime->oss.params_lock);
 	while (bytes > 0) {
 		if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
 			if (runtime->oss.buffer_used == 0) {
 				tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
 				if (tmp <= 0)
-					return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
+					goto err;
 				runtime->oss.bytes += tmp;
 				runtime->oss.period_ptr = tmp;
 				runtime->oss.buffer_used = tmp;
@@ -1410,8 +1424,10 @@
 			tmp = bytes;
 			if ((size_t) tmp > runtime->oss.buffer_used)
 				tmp = runtime->oss.buffer_used;
-			if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_ptr - runtime->oss.buffer_used), tmp))
-				return xfer > 0 ? (snd_pcm_sframes_t)xfer : -EFAULT;
+			if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_ptr - runtime->oss.buffer_used), tmp)) {
+				tmp = -EFAULT;
+				goto err;
+			}
 			buf += tmp;
 			bytes -= tmp;
 			xfer += tmp;
@@ -1420,14 +1436,19 @@
 			tmp = snd_pcm_oss_read2(substream, (char __force *)buf,
 						runtime->oss.period_bytes, 0);
 			if (tmp <= 0)
-				return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
+				goto err;
 			runtime->oss.bytes += tmp;
 			buf += tmp;
 			bytes -= tmp;
 			xfer += tmp;
 		}
 	}
+	mutex_unlock(&runtime->oss.params_lock);
 	return xfer;
+
+ err:
+	mutex_unlock(&runtime->oss.params_lock);
+	return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 }
 
 static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
@@ -1528,6 +1549,7 @@
 			return err;
 		format = snd_pcm_oss_format_from(runtime->oss.format);
 		width = snd_pcm_format_physical_width(format);
+		mutex_lock(&runtime->oss.params_lock);
 		if (runtime->oss.buffer_used > 0) {
 #ifdef OSS_DEBUG
 			printk("sync: buffer_used\n");
@@ -1537,8 +1559,10 @@
 						   runtime->oss.buffer + runtime->oss.buffer_used,
 						   size);
 			err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes);
-			if (err < 0)
+			if (err < 0) {
+				mutex_unlock(&runtime->oss.params_lock);
 				return err;
+			}
 		} else if (runtime->oss.period_ptr > 0) {
 #ifdef OSS_DEBUG
 			printk("sync: period_ptr\n");
@@ -1548,8 +1572,10 @@
 						   runtime->oss.buffer,
 						   size * 8 / width);
 			err = snd_pcm_oss_sync1(substream, size);
-			if (err < 0)
+			if (err < 0) {
+				mutex_unlock(&runtime->oss.params_lock);
 				return err;
+			}
 		}
 		/*
 		 * The ALSA's period might be a bit large than OSS one.
@@ -1579,6 +1605,7 @@
 				snd_pcm_lib_writev(substream, buffers, size);
 			}
 		}
+		mutex_unlock(&runtime->oss.params_lock);
 		/*
 		 * finish sync: drain the buffer
 		 */
@@ -2172,6 +2199,7 @@
 	runtime->oss.params = 1;
 	runtime->oss.trigger = 1;
 	runtime->oss.rate = 8000;
+	mutex_init(&runtime->oss.params_lock);
 	switch (SNDRV_MINOR_OSS_DEVICE(minor)) {
 	case SNDRV_MINOR_OSS_PCM_8:
 		runtime->oss.format = AFMT_U8;
diff -ru 2.2/sound/core/pcm.c 3.4/sound/core/pcm.c
--- 2.2/sound/core/pcm.c	2006-12-07 02:52:17.000000000 +0100
+++ 3.4/sound/core/pcm.c	2006-12-22 01:57:08.000000000 +0100
@@ -640,6 +640,10 @@
 		err = snd_pcm_substream_proc_init(substream);
 		if (err < 0) {
 			snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
+			if (prev == NULL)
+				pstr->substream = NULL;
+			else
+				prev->next = NULL;
 			kfree(substream);
 			return err;
 		}
diff -ru 2.2/sound/core/pcm_lib.c 3.4/sound/core/pcm_lib.c
--- 2.2/sound/core/pcm_lib.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/core/pcm_lib.c	2006-12-22 01:57:08.000000000 +0100
@@ -79,19 +79,17 @@
 			runtime->silence_filled -= frames;
 			if ((snd_pcm_sframes_t)runtime->silence_filled < 0) {
 				runtime->silence_filled = 0;
-				runtime->silence_start = (ofs + frames) - runtime->buffer_size;
+				runtime->silence_start = new_hw_ptr;
 			} else {
-				runtime->silence_start = ofs - runtime->silence_filled;
+				runtime->silence_start = ofs;
 			}
-			if ((snd_pcm_sframes_t)runtime->silence_start < 0)
-				runtime->silence_start += runtime->boundary;
 		}
 		frames = runtime->buffer_size - runtime->silence_filled;
 	}
 	snd_assert(frames <= runtime->buffer_size, return);
 	if (frames == 0)
 		return;
-	ofs = (runtime->silence_start + runtime->silence_filled) % runtime->buffer_size;
+	ofs = runtime->silence_start % runtime->buffer_size;
 	while (frames > 0) {
 		transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
 		if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
diff -ru 2.2/sound/core/rawmidi.c 3.4/sound/core/rawmidi.c
--- 2.2/sound/core/rawmidi.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/core/rawmidi.c	2006-12-22 01:57:08.000000000 +0100
@@ -1385,7 +1385,6 @@
 	struct snd_rawmidi_substream *substream;
 	int idx;
 
-	INIT_LIST_HEAD(&stream->substreams);
 	for (idx = 0; idx < count; idx++) {
 		substream = kzalloc(sizeof(*substream), GFP_KERNEL);
 		if (substream == NULL) {
@@ -1440,6 +1439,9 @@
 	rmidi->device = device;
 	mutex_init(&rmidi->open_mutex);
 	init_waitqueue_head(&rmidi->open_wait);
+	INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams);
+	INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams);
+
 	if (id != NULL)
 		strlcpy(rmidi->id, id, sizeof(rmidi->id));
 	if ((err = snd_rawmidi_alloc_substreams(rmidi,
diff -ru 2.2/sound/core/seq/seq_memory.c 3.4/sound/core/seq/seq_memory.c
--- 2.2/sound/core/seq/seq_memory.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/core/seq/seq_memory.c	2006-12-22 01:57:08.000000000 +0100
@@ -151,7 +151,7 @@
 		return len;
 	newlen = len;
 	if (size_aligned > 0)
-		newlen = ((len + size_aligned - 1) / size_aligned) * size_aligned;
+		newlen = roundup(len, size_aligned);
 	if (count < newlen)
 		return -EAGAIN;
 
diff -ru 2.2/sound/core/sgbuf.c 3.4/sound/core/sgbuf.c
--- 2.2/sound/core/sgbuf.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/core/sgbuf.c	2006-12-22 01:57:08.000000000 +0100
@@ -27,7 +27,7 @@
 
 /* table entries are align to 32 */
 #define SGBUF_TBL_ALIGN		32
-#define sgbuf_align_table(tbl)	((((tbl) + SGBUF_TBL_ALIGN - 1) / SGBUF_TBL_ALIGN) * SGBUF_TBL_ALIGN)
+#define sgbuf_align_table(tbl)	ALIGN((tbl), SGBUF_TBL_ALIGN)
 
 int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
 {
diff -ru 2.2/sound/isa/gus/gus_mem.c 3.4/sound/isa/gus/gus_mem.c
--- 2.2/sound/isa/gus/gus_mem.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/isa/gus/gus_mem.c	2006-12-22 01:57:08.000000000 +0100
@@ -143,9 +143,8 @@
 	struct snd_gf1_mem_block *pblock;
 	unsigned int ptr1, ptr2;
 
-	align--;
-	if (w_16 && align < 1)
-		align = 1;
+	if (w_16 && align < 2)
+		align = 2;
 	block->flags = w_16 ? SNDRV_GF1_MEM_BLOCK_16BIT : 0;
 	block->owner = SNDRV_GF1_MEM_OWNER_DRIVER;
 	block->share = 0;
@@ -165,7 +164,7 @@
 			if (pblock->next->ptr < boundary)
 				ptr2 = pblock->next->ptr;
 		}
-		ptr1 = (pblock->ptr + pblock->size + align) & ~align;
+		ptr1 = ALIGN(pblock->ptr + pblock->size, align);
 		if (ptr1 >= ptr2)
 			continue;
 		size1 = ptr2 - ptr1;
diff -ru 2.2/sound/isa/sb/sb_common.c 3.4/sound/isa/sb/sb_common.c
--- 2.2/sound/isa/sb/sb_common.c	2006-10-09 14:52:16.000000000 +0200
+++ 3.4/sound/isa/sb/sb_common.c	2006-12-22 01:57:08.000000000 +0100
@@ -232,7 +232,7 @@
 	chip->port = port;
 	
 	if (request_irq(irq, irq_handler, hardware == SB_HW_ALS4000 ?
-			IRQF_DISABLED | IRQF_SHARED : IRQF_DISABLED,
+			IRQF_SHARED : IRQF_DISABLED,
 			"SoundBlaster", (void *) chip)) {
 		snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq);
 		snd_sbdsp_free(chip);
diff -ru 2.2/sound/isa/wavefront/wavefront_synth.c 3.4/sound/isa/wavefront/wavefront_synth.c
--- 2.2/sound/isa/wavefront/wavefront_synth.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/isa/wavefront/wavefront_synth.c	2006-12-22 01:57:08.000000000 +0100
@@ -1068,7 +1068,7 @@
 			blocksize = max_blksize;
 		} else {
 			/* round to nearest 16-byte value */
-			blocksize = ((length-written+7)&~0x7);
+			blocksize = ALIGN(length - written, 8);
 		}
 
 		if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_BLOCK, NULL, NULL)) {
diff -ru 2.2/sound/oss/dmasound/tas3001c.c 3.4/sound/oss/dmasound/tas3001c.c
--- 2.2/sound/oss/dmasound/tas3001c.c	2006-12-11 05:38:39.000000000 +0100
+++ 3.4/sound/oss/dmasound/tas3001c.c	2006-12-18 04:28:25.000000000 +0100
@@ -50,7 +50,7 @@
 	int output_id;
 	int speaker_id;
 	struct tas_drce_t drce_state;
-	struct work_struct device_change_work;
+	struct work_struct change;
 };
 
 
@@ -670,8 +670,8 @@
 static void
 tas3001c_device_change_handler(struct work_struct *work)
 {
-	struct tas3001c_data_t *self =
-		container_of(work, struct tas3001c_data_t, device_change_work);
+	struct tas3001c_data_t *self;
+	self = container_of(work, struct tas3001c_data_t, change);
 	tas3001c_update_device_parameters(self);
 }
 
@@ -685,7 +685,7 @@
 	self->output_id=output_id;
 	self->speaker_id=speaker_id;
 
-	schedule_work(&self->device_change_work);
+	schedule_work(&self->change);
 	return 0;
 }
 
@@ -822,7 +822,7 @@
 			tas3001c_write_biquad_shadow(self, i, j,
 				&tas3001c_eq_unity);
 
-	INIT_WORK(&self->device_change_work, tas3001c_device_change_handler);
+	INIT_WORK(&self->change, tas3001c_device_change_handler);
 	return 0;
 }
 
diff -ru 2.2/sound/oss/dmasound/tas3004.c 3.4/sound/oss/dmasound/tas3004.c
--- 2.2/sound/oss/dmasound/tas3004.c	2006-12-11 05:34:54.000000000 +0100
+++ 3.4/sound/oss/dmasound/tas3004.c	2006-12-18 04:28:51.000000000 +0100
@@ -48,7 +48,7 @@
 	int output_id;
 	int speaker_id;
 	struct tas_drce_t drce_state;
-	struct work_struct device_change_work;
+	struct work_struct change;
 };
 
 #define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
@@ -917,8 +917,8 @@
 static void
 tas3004_device_change_handler(struct work_struct *work)
 {
-	struct tas3004_data_t *self =
-		container_of(work, struct tas3004_data_t, device_change_work);
+	struct tas3004_data_t *self;
+	self = container_of(work, struct tas3004_data_t, change);
 	tas3004_update_device_parameters(self);
 }
 
@@ -932,7 +932,7 @@
 	self->output_id=output_id;
 	self->speaker_id=speaker_id;
 
-	schedule_work(&self->device_change_work);
+	schedule_work(&self->change);
 
 	return 0;
 }
@@ -1110,7 +1110,7 @@
 	tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
 	tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
 
-	INIT_WORK(&self->device_change_work, tas3004_device_change_handler);
+	INIT_WORK(&self->change, tas3004_device_change_handler);
 	return 0;
 }
 
diff -ru 2.2/sound/pci/ac97/ac97_codec.c 3.4/sound/pci/ac97/ac97_codec.c
--- 2.2/sound/pci/ac97/ac97_codec.c	2006-12-07 02:52:17.000000000 +0100
+++ 3.4/sound/pci/ac97/ac97_codec.c	2006-12-22 01:57:08.000000000 +0100
@@ -129,9 +129,9 @@
 { 0x434d4941, 0xffffffff, "CMI9738",		patch_cm9738,	NULL },
 { 0x434d4961, 0xffffffff, "CMI9739",		patch_cm9739,	NULL },
 { 0x434d4969, 0xffffffff, "CMI9780",		patch_cm9780,	NULL },
-{ 0x434d4978, 0xffffffff, "CMI9761",		patch_cm9761,	NULL },
-{ 0x434d4982, 0xffffffff, "CMI9761",		patch_cm9761,	NULL },
-{ 0x434d4983, 0xffffffff, "CMI9761",		patch_cm9761,	NULL },
+{ 0x434d4978, 0xffffffff, "CMI9761A",		patch_cm9761,	NULL },
+{ 0x434d4982, 0xffffffff, "CMI9761B",		patch_cm9761,	NULL },
+{ 0x434d4983, 0xffffffff, "CMI9761A+",		patch_cm9761,	NULL },
 { 0x43525900, 0xfffffff8, "CS4297",		NULL,		NULL },
 { 0x43525910, 0xfffffff8, "CS4297A",		patch_cirrus_spdif,	NULL },
 { 0x43525920, 0xfffffff8, "CS4298",		patch_cirrus_spdif,		NULL },
@@ -382,7 +382,7 @@
 	unsigned short old, new;
 
 	old = snd_ac97_read_cache(ac97, reg);
-	new = (old & ~mask) | value;
+	new = (old & ~mask) | (value & mask);
 	change = old != new;
 	if (change) {
 		ac97->regs[reg] = new;
@@ -399,7 +399,7 @@
 
 	mutex_lock(&ac97->page_mutex);
 	old = ac97->spec.ad18xx.pcmreg[codec];
-	new = (old & ~mask) | value;
+	new = (old & ~mask) | (value & mask);
 	change = old != new;
 	if (change) {
 		mutex_lock(&ac97->reg_mutex);
diff -ru 2.2/sound/pci/ac97/ac97_patch.c 3.4/sound/pci/ac97/ac97_patch.c
--- 2.2/sound/pci/ac97/ac97_patch.c	2006-10-09 14:52:21.000000000 +0200
+++ 3.4/sound/pci/ac97/ac97_patch.c	2006-12-22 01:57:08.000000000 +0100
@@ -1467,7 +1467,9 @@
 	snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0002);		// ID1C
 	ac97->spec.ad18xx.codec_cfg[unchained_idx] = 0x0002;
 	if (cidx1 >= 0) {
-		if (patch_ad1881_chained1(ac97, cidx1, 0x0006))		// SDIE | ID1C
+		if (cidx2 < 0)
+			patch_ad1881_chained1(ac97, cidx1, 0);
+		else if (patch_ad1881_chained1(ac97, cidx1, 0x0006))	// SDIE | ID1C
 			patch_ad1881_chained1(ac97, cidx2, 0);
 		else if (patch_ad1881_chained1(ac97, cidx2, 0x0006))	// SDIE | ID1C
 			patch_ad1881_chained1(ac97, cidx1, 0);
@@ -2261,7 +2263,8 @@
 	else { /* ALC655 */
 		if (ac97->subsystem_vendor == 0x1462 &&
 		    (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
-		     ac97->subsystem_device == 0x0161)) /* LG K1 Express */
+		     ac97->subsystem_device == 0x0161 || /* LG K1 Express */
+		     ac97->subsystem_device == 0x0351))  /* MSI L725 laptop */
 			val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
 		else
 			val |= (1 << 1); /* Pin 47 is spdif input pin */
diff -ru 2.2/sound/pci/ad1889.c 3.4/sound/pci/ad1889.c
--- 2.2/sound/pci/ad1889.c	2006-10-09 14:52:21.000000000 +0200
+++ 3.4/sound/pci/ad1889.c	2006-12-22 01:57:08.000000000 +0100
@@ -858,7 +858,7 @@
 	synchronize_irq(chip->irq);
 	
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void*)chip);
+		free_irq(chip->irq, chip);
 
 skip_hw:
 	if (chip->iobase)
@@ -945,7 +945,7 @@
 	spin_lock_init(&chip->lock);	/* only now can we call ad1889_free */
 
 	if (request_irq(pci->irq, snd_ad1889_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, card->driver, (void*)chip)) {
+			IRQF_SHARED, card->driver, chip)) {
 		printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
 		snd_ad1889_free(chip);
 		return -EBUSY;
diff -ru 2.2/sound/pci/ali5451/ali5451.c 3.4/sound/pci/ali5451/ali5451.c
--- 2.2/sound/pci/ali5451/ali5451.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/ali5451/ali5451.c	2006-12-22 01:57:08.000000000 +0100
@@ -2095,7 +2095,7 @@
 		snd_ali_disable_address_interrupt(codec);
 	if (codec->irq >= 0) {
 		synchronize_irq(codec->irq);
-		free_irq(codec->irq, (void *)codec);
+		free_irq(codec->irq, codec);
 	}
 	if (codec->port)
 		pci_release_regions(codec->pci);
@@ -2192,7 +2192,8 @@
 		return err;
 	codec->port = pci_resource_start(codec->pci, 0);
 
-	if (request_irq(codec->pci->irq, snd_ali_card_interrupt, IRQF_DISABLED|IRQF_SHARED, "ALI 5451", (void *)codec)) {
+	if (request_irq(codec->pci->irq, snd_ali_card_interrupt,
+			IRQF_SHARED, "ALI 5451", codec)) {
 		snd_printk(KERN_ERR "Unable to request irq.\n");
 		return -EBUSY;
 	}
diff -ru 2.2/sound/pci/als300.c 3.4/sound/pci/als300.c
--- 2.2/sound/pci/als300.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/als300.c	2006-12-22 01:57:08.000000000 +0100
@@ -190,7 +190,7 @@
 	snd_als300_dbgcallenter();
 	snd_als300_set_irq_flag(chip, IRQ_DISABLE);
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
 	kfree(chip);
@@ -722,8 +722,8 @@
 	else
 		irq_handler = snd_als300_interrupt;
 
-	if (request_irq(pci->irq, irq_handler, IRQF_DISABLED|IRQF_SHARED,
-					card->shortname, (void *)chip)) {
+	if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
+			card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_als300_free(chip);
 		return -EBUSY;
diff -ru 2.2/sound/pci/atiixp.c 3.4/sound/pci/atiixp.c
--- 2.2/sound/pci/atiixp.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/atiixp.c	2006-12-22 01:57:08.000000000 +0100
@@ -1583,7 +1583,7 @@
 		return -EIO;
 	}
 
-	if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
 			card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_atiixp_free(chip);
diff -ru 2.2/sound/pci/atiixp_modem.c 3.4/sound/pci/atiixp_modem.c
--- 2.2/sound/pci/atiixp_modem.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/atiixp_modem.c	2006-12-22 01:57:08.000000000 +0100
@@ -1256,7 +1256,7 @@
 		return -EIO;
 	}
 
-	if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
 			card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_atiixp_free(chip);
diff -ru 2.2/sound/pci/au88x0/au88x0.c 3.4/sound/pci/au88x0/au88x0.c
--- 2.2/sound/pci/au88x0/au88x0.c	2006-10-09 14:52:21.000000000 +0200
+++ 3.4/sound/pci/au88x0/au88x0.c	2006-12-22 01:57:08.000000000 +0100
@@ -198,7 +198,7 @@
 	}
 
 	if ((err = request_irq(pci->irq, vortex_interrupt,
-	                       IRQF_DISABLED | IRQF_SHARED, CARD_NAME_SHORT,
+	                       IRQF_SHARED, CARD_NAME_SHORT,
 	                       chip)) != 0) {
 		printk(KERN_ERR "cannot grab irq\n");
 		goto irq_out;
diff -ru 2.2/sound/pci/azt3328.c 3.4/sound/pci/azt3328.c
--- 2.2/sound/pci/azt3328.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/azt3328.c	2006-12-22 01:57:08.000000000 +0100
@@ -1513,7 +1513,7 @@
 __end_hw:
 	snd_azf3328_free_joystick(chip);
         if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
 
@@ -1724,7 +1724,8 @@
 	chip->synth_port = pci_resource_start(pci, 3);
 	chip->mixer_port = pci_resource_start(pci, 4);
 
-	if (request_irq(pci->irq, snd_azf3328_interrupt, IRQF_DISABLED|IRQF_SHARED, card->shortname, (void *)chip)) {
+	if (request_irq(pci->irq, snd_azf3328_interrupt,
+			IRQF_SHARED, card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		err = -EBUSY;
 		goto out_err;
diff -ru 2.2/sound/pci/bt87x.c 3.4/sound/pci/bt87x.c
--- 2.2/sound/pci/bt87x.c	2006-10-09 14:52:21.000000000 +0200
+++ 3.4/sound/pci/bt87x.c	2006-12-22 01:57:08.000000000 +0100
@@ -699,7 +699,7 @@
 						     SNDRV_DMA_TYPE_DEV_SG,
 						     snd_dma_pci_data(chip->pci),
 							128 * 1024,
-							(255 * 4092 + 1023) & ~1023);
+							ALIGN(255 * 4092, 1024));
 }
 
 static int __devinit snd_bt87x_create(struct snd_card *card,
@@ -747,7 +747,7 @@
 	snd_bt87x_writel(chip, REG_INT_MASK, 0);
 	snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
 
-	if (request_irq(pci->irq, snd_bt87x_interrupt, IRQF_DISABLED | IRQF_SHARED,
+	if (request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
 			"Bt87x audio", chip)) {
 		snd_bt87x_free(chip);
 		snd_printk(KERN_ERR "cannot grab irq\n");
diff -ru 2.2/sound/pci/ca0106/ca0106.h 3.4/sound/pci/ca0106/ca0106.h
--- 2.2/sound/pci/ca0106/ca0106.h	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/pci/ca0106/ca0106.h	2006-12-22 01:57:08.000000000 +0100
@@ -590,7 +590,7 @@
 	struct resource *res_port;
 	int irq;
 
-	unsigned int revision;		/* chip revision */
+	unsigned char revision;		/* chip revision */
 	unsigned int serial;            /* serial number */
 	unsigned short model;		/* subsystem id */
 
diff -ru 2.2/sound/pci/ca0106/ca0106_main.c 3.4/sound/pci/ca0106/ca0106_main.c
--- 2.2/sound/pci/ca0106/ca0106_main.c	2006-10-09 14:52:21.000000000 +0200
+++ 3.4/sound/pci/ca0106/ca0106_main.c	2006-12-22 01:57:08.000000000 +0100
@@ -154,6 +154,7 @@
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for the CA0106 soundcard.");
@@ -161,6 +162,8 @@
 MODULE_PARM_DESC(id, "ID string for the CA0106 soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable the CA0106 soundcard.");
+module_param_array(subsystem, uint, NULL, 0444);
+MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
 
 #include "ca0106.h"
 
@@ -194,6 +197,17 @@
 	   .gpio_type = 1,
 	   .i2c_adc = 1,
 	   .spi_dac = 1 } ,
+	 /* New Audigy LS. Has a different DAC. */
+	 /* SB0570:
+	  * CTRL:CA0106-DAT
+	  * ADC: WM8775EDS
+	  * DAC: WM8768GEDS
+	  */
+	 { .serial = 0x10111102,
+	   .name   = "Audigy SE OEM [SB0570a]",
+	   .gpio_type = 1,
+	   .i2c_adc = 1,
+	   .spi_dac = 1 } ,
 	 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
 	 /* SB0438
 	  * CTRL:CA0106-DAT
@@ -1046,7 +1060,7 @@
 
 	// release the irq
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	pci_disable_device(chip->pci);
 	kfree(chip);
 	return 0;
@@ -1223,7 +1237,7 @@
 	{ 0x15, ADC_MUX_LINEIN },  /* ADC Mixer control */
 };
 
-static int __devinit snd_ca0106_create(struct snd_card *card,
+static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
 					 struct pci_dev *pci,
 					 struct snd_ca0106 **rchip)
 {
@@ -1267,8 +1281,7 @@
 	}
 
 	if (request_irq(pci->irq, snd_ca0106_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, "snd_ca0106",
-			(void *)chip)) {
+			IRQF_SHARED, "snd_ca0106", chip)) {
 		snd_ca0106_free(chip);
 		printk(KERN_ERR "cannot grab irq\n");
 		return -EBUSY;
@@ -1283,21 +1296,29 @@
 
 	pci_set_master(pci);
 	/* read revision & serial */
-	pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
+	pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision);
 	pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
 	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
 #if 1
-	printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
+	printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n", chip->model,
 	       chip->revision, chip->serial);
 #endif
 	strcpy(card->driver, "CA0106");
 	strcpy(card->shortname, "CA0106");
 
 	for (c = ca0106_chip_details; c->serial; c++) {
-		if (c->serial == chip->serial)
+		if (subsystem[dev]) {
+			if (c->serial == subsystem[dev])
+				break;
+		} else if (c->serial == chip->serial)
 			break;
 	}
 	chip->details = c;
+	if (subsystem[dev]) {
+		printk(KERN_INFO "snd-ca0106: Sound card name=%s, subsystem=0x%x. Forced to subsystem=0x%x\n",
+                        c->name, chip->serial, subsystem[dev]);
+	}
+
 	sprintf(card->longname, "%s at 0x%lx irq %i",
 		c->name, chip->port, chip->irq);
 
@@ -1540,7 +1561,7 @@
 	if (card == NULL)
 		return -ENOMEM;
 
-	if ((err = snd_ca0106_create(card, pci, &chip)) < 0) {
+	if ((err = snd_ca0106_create(dev, card, pci, &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
diff -ru 2.2/sound/pci/cmipci.c 3.4/sound/pci/cmipci.c
--- 2.2/sound/pci/cmipci.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/cmipci.c	2006-12-22 01:57:08.000000000 +0100
@@ -2862,7 +2862,7 @@
 	cm->iobase = pci_resource_start(pci, 0);
 
 	if (request_irq(pci->irq, snd_cmipci_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, card->driver, cm)) {
+			IRQF_SHARED, card->driver, cm)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cmipci_free(cm);
 		return -EBUSY;
diff -ru 2.2/sound/pci/cs4281.c 3.4/sound/pci/cs4281.c
--- 2.2/sound/pci/cs4281.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/cs4281.c	2006-12-22 01:57:08.000000000 +0100
@@ -1391,7 +1391,7 @@
 		return -ENOMEM;
 	}
 	
-	if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED,
 			"CS4281", chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cs4281_free(chip);
diff -ru 2.2/sound/pci/cs46xx/cs46xx_lib.c 3.4/sound/pci/cs46xx/cs46xx_lib.c
--- 2.2/sound/pci/cs46xx/cs46xx_lib.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/cs46xx/cs46xx_lib.c	2006-12-22 01:57:08.000000000 +0100
@@ -3867,7 +3867,7 @@
 		}
 	}
 
-	if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
 			"CS46XX", chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cs46xx_free(chip);
diff -ru 2.2/sound/pci/cs5535audio/cs5535audio.c 3.4/sound/pci/cs5535audio/cs5535audio.c
--- 2.2/sound/pci/cs5535audio/cs5535audio.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/cs5535audio/cs5535audio.c	2006-12-22 01:57:08.000000000 +0100
@@ -320,7 +320,7 @@
 	cs5535au->port = pci_resource_start(pci, 0);
 
 	if (request_irq(pci->irq, snd_cs5535audio_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, "CS5535 Audio", cs5535au)) {
+			IRQF_SHARED, "CS5535 Audio", cs5535au)) {
 		snd_printk("unable to grab IRQ %d\n", pci->irq);
 		err = -EBUSY;
 		goto sndfail;
diff -ru 2.2/sound/pci/echoaudio/echoaudio.c 3.4/sound/pci/echoaudio/echoaudio.c
--- 2.2/sound/pci/echoaudio/echoaudio.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/echoaudio/echoaudio.c	2006-12-22 01:57:09.000000000 +0100
@@ -1872,7 +1872,7 @@
 	DE_INIT(("Stopped.\n"));
 
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 
 	if (chip->dsp_registers)
 		iounmap(chip->dsp_registers);
@@ -1950,8 +1950,8 @@
 	chip->dsp_registers = (volatile u32 __iomem *)
 		ioremap_nocache(chip->dsp_registers_phys, sz);
 
-	if (request_irq(pci->irq, snd_echo_interrupt, IRQF_DISABLED | IRQF_SHARED,
-						ECHOCARD_NAME, (void *)chip)) {
+	if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
+			ECHOCARD_NAME, chip)) {
 		snd_echo_free(chip);
 		snd_printk(KERN_ERR "cannot grab irq\n");
 		return -EBUSY;
diff -ru 2.2/sound/pci/emu10k1/emu10k1_main.c 3.4/sound/pci/emu10k1/emu10k1_main.c
--- 2.2/sound/pci/emu10k1/emu10k1_main.c	2006-11-29 04:53:09.000000000 +0100
+++ 3.4/sound/pci/emu10k1/emu10k1_main.c	2006-12-22 01:57:09.000000000 +0100
@@ -759,7 +759,7 @@
 	free_pm_buffer(emu);
 #endif
 	if (emu->irq >= 0)
-		free_irq(emu->irq, (void *)emu);
+		free_irq(emu->irq, emu);
 	if (emu->port)
 		pci_release_regions(emu->pci);
 	if (emu->card_capabilities->ca0151_chip) /* P16V */	
@@ -1246,7 +1246,8 @@
 	}
 	emu->port = pci_resource_start(pci, 0);
 
-	if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_DISABLED|IRQF_SHARED, "EMU10K1", (void *)emu)) {
+	if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED,
+			"EMU10K1", emu)) {
 		err = -EBUSY;
 		goto error;
 	}
diff -ru 2.2/sound/pci/emu10k1/emu10k1x.c 3.4/sound/pci/emu10k1/emu10k1x.c
--- 2.2/sound/pci/emu10k1/emu10k1x.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/emu10k1/emu10k1x.c	2006-12-22 01:57:09.000000000 +0100
@@ -235,7 +235,7 @@
 	struct resource *res_port;
 	int irq;
 
-	unsigned int revision;		/* chip revision */
+	unsigned char revision;		/* chip revision */
 	unsigned int serial;            /* serial number */
 	unsigned short model;		/* subsystem id */
 
@@ -760,7 +760,7 @@
 
 	// release the irq
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 
 	// release the DMA
 	if (chip->dma_buffer.area) {
@@ -927,8 +927,7 @@
 	}
 
 	if (request_irq(pci->irq, snd_emu10k1x_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, "EMU10K1X",
-			(void *)chip)) {
+			IRQF_SHARED, "EMU10K1X", chip)) {
 		snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
 		snd_emu10k1x_free(chip);
 		return -EBUSY;
@@ -943,7 +942,7 @@
 
 	pci_set_master(pci);
 	/* read revision & serial */
-	pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
+	pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision);
 	pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
 	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
 	snd_printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
diff -ru 2.2/sound/pci/ens1370.c 3.4/sound/pci/ens1370.c
--- 2.2/sound/pci/ens1370.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/ens1370.c	2006-12-22 01:57:09.000000000 +0100
@@ -2141,7 +2141,7 @@
 		return err;
 	}
 	ensoniq->port = pci_resource_start(pci, 0);
-	if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED,
 			"Ensoniq AudioPCI", ensoniq)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ensoniq_free(ensoniq);
diff -ru 2.2/sound/pci/es1938.c 3.4/sound/pci/es1938.c
--- 2.2/sound/pci/es1938.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/es1938.c	2006-12-22 01:57:09.000000000 +0100
@@ -1508,7 +1508,7 @@
 	}
 
 	if (request_irq(pci->irq, snd_es1938_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, "ES1938", chip)) {
+			IRQF_SHARED, "ES1938", chip)) {
 		printk(KERN_ERR "es1938: unable to grab IRQ %d, "
 		       "disabling device\n", pci->irq);
 		snd_card_disconnect(card);
@@ -1631,7 +1631,7 @@
 	chip->vc_port = pci_resource_start(pci, 2);
 	chip->mpu_port = pci_resource_start(pci, 3);
 	chip->game_port = pci_resource_start(pci, 4);
-	if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,
 			"ES1938", chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_es1938_free(chip);
diff -ru 2.2/sound/pci/es1968.c 3.4/sound/pci/es1968.c
--- 2.2/sound/pci/es1968.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/es1968.c	2006-12-22 01:57:09.000000000 +0100
@@ -1337,7 +1337,7 @@
 	struct esm_memory *buf;
 	struct list_head *p;
 	
-	size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN;
+	size = ALIGN(size, ESM_MEM_ALIGN);
 	mutex_lock(&chip->memory_mutex);
 	list_for_each(p, &chip->buf_list) {
 		buf = list_entry(p, struct esm_memory, list);
@@ -2462,7 +2462,7 @@
 	}
 
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	snd_es1968_free_gameport(chip);
 	chip->master_switch = NULL;
 	chip->master_volume = NULL;
@@ -2552,8 +2552,8 @@
 		return err;
 	}
 	chip->io_port = pci_resource_start(pci, 0);
-	if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_DISABLED|IRQF_SHARED,
-			"ESS Maestro", (void*)chip)) {
+	if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
+			"ESS Maestro", chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_es1968_free(chip);
 		return -EBUSY;
diff -ru 2.2/sound/pci/fm801.c 3.4/sound/pci/fm801.c
--- 2.2/sound/pci/fm801.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/fm801.c	2006-12-22 01:57:09.000000000 +0100
@@ -1395,7 +1395,7 @@
 	}
 	chip->port = pci_resource_start(pci, 0);
 	if ((tea575x_tuner & 0x0010) == 0) {
-		if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_DISABLED|IRQF_SHARED,
+		if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
 				"FM801", chip)) {
 			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
 			snd_fm801_free(chip);
diff -ru 2.2/sound/pci/hda/hda_codec.c 3.4/sound/pci/hda/hda_codec.c
--- 2.2/sound/pci/hda/hda_codec.c	2006-12-07 02:52:17.000000000 +0100
+++ 3.4/sound/pci/hda/hda_codec.c	2006-12-22 01:57:09.000000000 +0100
@@ -1367,9 +1367,6 @@
 	{ 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
 	{ 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
 
-	/* not autodetected value */
-	{ 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
-
 	{ 0 } /* terminator */
 };
 
diff -ru 2.2/sound/pci/hda/hda_intel.c 3.4/sound/pci/hda/hda_intel.c
--- 2.2/sound/pci/hda/hda_intel.c	2006-11-20 02:11:28.000000000 +0100
+++ 3.4/sound/pci/hda/hda_intel.c	2006-12-22 01:57:09.000000000 +0100
@@ -1380,7 +1380,8 @@
 
 static int azx_acquire_irq(struct azx *chip, int do_disconnect)
 {
-	if (request_irq(chip->pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(chip->pci->irq, azx_interrupt,
+			chip->msi ? 0 : IRQF_SHARED,
 			"HDA Intel", chip)) {
 		printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
 		       "disabling device\n", chip->pci->irq);
diff -ru 2.2/sound/pci/hda/hda_proc.c 3.4/sound/pci/hda/hda_proc.c
--- 2.2/sound/pci/hda/hda_proc.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/pci/hda/hda_proc.c	2006-12-22 01:57:09.000000000 +0100
@@ -45,7 +45,7 @@
 	if (names[wid_value])
 		return names[wid_value];
 	else
-		return "UNKOWN Widget";
+		return "UNKNOWN Widget";
 }
 
 static void print_amp_caps(struct snd_info_buffer *buffer,
@@ -88,6 +88,48 @@
 	snd_iprintf(buffer, "\n");
 }
 
+static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
+{
+	static unsigned int rates[] = {
+		8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
+		96000, 176400, 192000, 384000
+	};
+	int i;
+
+	pcm &= AC_SUPPCM_RATES;
+	snd_iprintf(buffer, "    rates [0x%x]:", pcm);
+	for (i = 0; i < ARRAY_SIZE(rates); i++) 
+		if (pcm & (1 << i))
+			snd_iprintf(buffer, " %d", rates[i]);
+	snd_iprintf(buffer, "\n");
+}
+
+static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
+{
+	static unsigned int bits[] = { 8, 16, 20, 24, 32 };
+	int i;
+
+	pcm = (pcm >> 16) & 0xff;
+	snd_iprintf(buffer, "    bits [0x%x]:", pcm);
+	for (i = 0; i < ARRAY_SIZE(bits); i++)
+		if (pcm & (1 << i))
+			snd_iprintf(buffer, " %d", bits[i]);
+	snd_iprintf(buffer, "\n");
+}
+
+static void print_pcm_formats(struct snd_info_buffer *buffer,
+			      unsigned int streams)
+{
+	snd_iprintf(buffer, "    formats [0x%x]:", streams & 0xf);
+	if (streams & AC_SUPFMT_PCM)
+		snd_iprintf(buffer, " PCM");
+	if (streams & AC_SUPFMT_FLOAT32)
+		snd_iprintf(buffer, " FLOAT");
+	if (streams & AC_SUPFMT_AC3)
+		snd_iprintf(buffer, " AC3");
+	snd_iprintf(buffer, "\n");
+}
+
 static void print_pcm_caps(struct snd_info_buffer *buffer,
 			   struct hda_codec *codec, hda_nid_t nid)
 {
@@ -97,8 +139,9 @@
 		snd_iprintf(buffer, "N/A\n");
 		return;
 	}
-	snd_iprintf(buffer, "rates 0x%03x, bits 0x%02x, types 0x%x\n",
-		    pcm & AC_SUPPCM_RATES, (pcm >> 16) & 0xff, stream & 0xf);
+	print_pcm_rates(buffer, pcm);
+	print_pcm_bits(buffer, pcm);
+	print_pcm_formats(buffer, stream);
 }
 
 static const char *get_jack_location(u32 cfg)
@@ -210,7 +253,7 @@
 	snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
 	if (! codec->afg)
 		return;
-	snd_iprintf(buffer, "Default PCM: ");
+	snd_iprintf(buffer, "Default PCM:\n");
 	print_pcm_caps(buffer, codec, codec->afg);
 	snd_iprintf(buffer, "Default Amp-In caps: ");
 	print_amp_caps(buffer, codec, codec->afg, HDA_INPUT);
@@ -278,7 +321,7 @@
 
 		if ((wid_type == AC_WID_AUD_OUT || wid_type == AC_WID_AUD_IN) &&
 		    (wid_caps & AC_WCAP_FORMAT_OVRD)) {
-			snd_iprintf(buffer, "  PCM: ");
+			snd_iprintf(buffer, "  PCM:\n");
 			print_pcm_caps(buffer, codec, nid);
 		}
 
diff -ru 2.2/sound/pci/hda/patch_analog.c 3.4/sound/pci/hda/patch_analog.c
--- 2.2/sound/pci/hda/patch_analog.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/hda/patch_analog.c	2006-12-22 01:57:09.000000000 +0100
@@ -794,6 +794,8 @@
 	{ .modelname = "3stack",	.config = AD1986A_3STACK },
 	{ .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84,
 	  .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x817f,
+	  .config = AD1986A_3STACK }, /* ASUS P5P-L2 */
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x81b3,
 	  .config = AD1986A_3STACK }, /* ASUS P5RD2-VM / P5GPL-X SE */
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x81cb,
@@ -811,7 +813,7 @@
 	{ .pci_subvendor = 0x144d, .pci_subdevice = 0xc024,
 	  .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */
 	{ .pci_subvendor = 0x144d, .pci_subdevice = 0xc026,
-	  .config = AD1986A_LAPTOP_EAPD }, /* Samsung X10-T2300 Culesa */
+	  .config = AD1986A_LAPTOP_EAPD }, /* Samsung X11-T2300 Culesa */
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1153,
 	  .config = AD1986A_LAPTOP_EAPD }, /* ASUS M9 */
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1213,
@@ -822,6 +824,8 @@
 	  .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5F */
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1297,
 	  .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x12b3,
+	  .config = AD1986A_LAPTOP_EAPD }, /* ASUS V1j */
 	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30af,
 	  .config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */
 	{ .pci_subvendor = 0x17aa, .pci_subdevice = 0x2066,
@@ -1640,7 +1644,7 @@
 	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
 				      spec->num_channel_mode,
 				      &spec->multiout.max_channels);
-	if (! err && spec->need_dac_fix)
+	if (err >= 0 && spec->need_dac_fix)
 		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
 	return err;
 }
diff -ru 2.2/sound/pci/hda/patch_realtek.c 3.4/sound/pci/hda/patch_realtek.c
--- 2.2/sound/pci/hda/patch_realtek.c	2006-11-29 04:53:09.000000000 +0100
+++ 3.4/sound/pci/hda/patch_realtek.c	2006-12-22 01:57:09.000000000 +0100
@@ -271,7 +271,7 @@
 	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
 				      spec->num_channel_mode,
 				      &spec->multiout.max_channels);
-	if (! err && spec->need_dac_fix)
+	if (err >= 0 && spec->need_dac_fix)
 		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
 	return err;
 }
@@ -5872,6 +5872,8 @@
 	{ .modelname = "hp-bpc", .config = ALC262_HP_BPC },
 	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x280c,
 	  .config = ALC262_HP_BPC }, /* xw4400 */
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x2801,
+	  .config = ALC262_HP_BPC }, /* q965 */
 	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3014,
 	  .config = ALC262_HP_BPC }, /* xw6400 */
 	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3015,
diff -ru 2.2/sound/pci/hda/patch_si3054.c 3.4/sound/pci/hda/patch_si3054.c
--- 2.2/sound/pci/hda/patch_si3054.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/hda/patch_si3054.c	2006-12-22 01:57:09.000000000 +0100
@@ -243,7 +243,8 @@
 
 	if((val&SI3054_MEI_READY) != SI3054_MEI_READY) {
 		snd_printk(KERN_ERR "si3054: cannot initialize. EXT MID = %04x\n", val);
-		return -EACCES;
+		/* let's pray that this is no fatal error */
+		/* return -EACCES; */
 	}
 
 	SET_REG(codec, SI3054_GPIO_POLARITY, 0xffff);
diff -ru 2.2/sound/pci/ice1712/ice1712.c 3.4/sound/pci/ice1712/ice1712.c
--- 2.2/sound/pci/ice1712/ice1712.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/ice1712/ice1712.c	2006-12-22 01:57:09.000000000 +0100
@@ -2614,7 +2614,7 @@
 	ice->dmapath_port = pci_resource_start(pci, 2);
 	ice->profi_port = pci_resource_start(pci, 3);
 
-	if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED,
 			"ICE1712", ice)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ice1712_free(ice);
diff -ru 2.2/sound/pci/ice1712/ice1724.c 3.4/sound/pci/ice1712/ice1724.c
--- 2.2/sound/pci/ice1712/ice1724.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/ice1712/ice1724.c	2006-12-22 01:57:09.000000000 +0100
@@ -2253,7 +2253,7 @@
 	ice->profi_port = pci_resource_start(pci, 1);
 
 	if (request_irq(pci->irq, snd_vt1724_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, "ICE1724", ice)) {
+			IRQF_SHARED, "ICE1724", ice)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_vt1724_free(ice);
 		return -EIO;
diff -ru 2.2/sound/pci/intel8x0.c 3.4/sound/pci/intel8x0.c
--- 2.2/sound/pci/intel8x0.c	2006-10-26 16:21:09.000000000 +0200
+++ 3.4/sound/pci/intel8x0.c	2006-12-22 01:57:09.000000000 +0100
@@ -2509,7 +2509,7 @@
 	}
 	pci_set_master(pci);
 	if (request_irq(pci->irq, snd_intel8x0_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+			IRQF_SHARED, card->shortname, chip)) {
 		printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
 		       "disabling device\n", pci->irq);
 		snd_card_disconnect(card);
@@ -2887,7 +2887,7 @@
 
 	/* request irq after initializaing int_sta_mask, etc */
 	if (request_irq(pci->irq, snd_intel8x0_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+			IRQF_SHARED, card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_intel8x0_free(chip);
 		return -EBUSY;
diff -ru 2.2/sound/pci/intel8x0m.c 3.4/sound/pci/intel8x0m.c
--- 2.2/sound/pci/intel8x0m.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/intel8x0m.c	2006-12-22 01:57:09.000000000 +0100
@@ -1071,7 +1071,7 @@
 	}
 	pci_set_master(pci);
 	if (request_irq(pci->irq, snd_intel8x0_interrupt,
-			IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+			IRQF_SHARED, card->shortname, chip)) {
 		printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
 		       "disabling device\n", pci->irq);
 		snd_card_disconnect(card);
@@ -1205,7 +1205,7 @@
 	}
 
  port_inited:
-	if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_SHARED,
 			card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_intel8x0_free(chip);
diff -ru 2.2/sound/pci/korg1212/korg1212.c 3.4/sound/pci/korg1212/korg1212.c
--- 2.2/sound/pci/korg1212/korg1212.c	2006-10-11 15:48:10.000000000 +0200
+++ 3.4/sound/pci/korg1212/korg1212.c	2006-12-22 01:57:09.000000000 +0100
@@ -2233,7 +2233,7 @@
         }
 
         err = request_irq(pci->irq, snd_korg1212_interrupt,
-                          IRQF_DISABLED|IRQF_SHARED,
+                          IRQF_SHARED,
                           "korg1212", korg1212);
 
         if (err) {
diff -ru 2.2/sound/pci/maestro3.c 3.4/sound/pci/maestro3.c
--- 2.2/sound/pci/maestro3.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/maestro3.c	2006-12-22 01:57:09.000000000 +0100
@@ -2377,7 +2377,7 @@
 	 * shifted list address is aligned.
 	 * list address = (mem address >> 1) >> 7;
 	 */
-	data_bytes = (data_bytes + 255) & ~255;
+	data_bytes = ALIGN(data_bytes, 256);
 	address = 0x1100 + ((data_bytes/2) * index);
 
 	if ((address + (data_bytes/2)) >= 0x1c00) {
@@ -2762,7 +2762,7 @@
 
 	tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
 
-	if (request_irq(pci->irq, snd_m3_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
 			card->driver, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_m3_free(chip);
diff -ru 2.2/sound/pci/mixart/mixart.c 3.4/sound/pci/mixart/mixart.c
--- 2.2/sound/pci/mixart/mixart.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/pci/mixart/mixart.c	2006-12-22 01:57:09.000000000 +0100
@@ -1066,7 +1066,7 @@
 
 	/* release irq  */
 	if (mgr->irq >= 0)
-		free_irq(mgr->irq, (void *)mgr);
+		free_irq(mgr->irq, mgr);
 
 	/* reset board if some firmware was loaded */
 	if(mgr->dsp_loaded) {
@@ -1319,7 +1319,8 @@
 						   pci_resource_len(pci, i));
 	}
 
-	if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_DISABLED|IRQF_SHARED, CARD_NAME, (void *)mgr)) {
+	if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED,
+			CARD_NAME, mgr)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_mixart_free(mgr);
 		return -EBUSY;
diff -ru 2.2/sound/pci/nm256/nm256.c 3.4/sound/pci/nm256/nm256.c
--- 2.2/sound/pci/nm256/nm256.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/nm256/nm256.c	2006-12-22 01:57:09.000000000 +0100
@@ -465,7 +465,7 @@
 {
 	mutex_lock(&chip->irq_mutex);
 	if (chip->irq < 0) {
-		if (request_irq(chip->pci->irq, chip->interrupt, IRQF_DISABLED|IRQF_SHARED,
+		if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED,
 				chip->card->driver, chip)) {
 			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
 			mutex_unlock(&chip->irq_mutex);
diff -ru 2.2/sound/pci/pcxhr/pcxhr.c 3.4/sound/pci/pcxhr/pcxhr.c
--- 2.2/sound/pci/pcxhr/pcxhr.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/pci/pcxhr/pcxhr.c	2006-12-22 01:57:09.000000000 +0100
@@ -1250,7 +1250,7 @@
 	mgr->pci = pci;
 	mgr->irq = -1;
 
-	if (request_irq(pci->irq, pcxhr_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED,
 			card_name, mgr)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		pcxhr_free(mgr);
diff -ru 2.2/sound/pci/riptide/riptide.c 3.4/sound/pci/riptide/riptide.c
--- 2.2/sound/pci/riptide/riptide.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/riptide/riptide.c	2006-12-22 01:57:09.000000000 +0100
@@ -1899,9 +1899,8 @@
 	hwport = (struct riptideport *)chip->port;
 	UNSET_AIE(hwport);
 
-	if (request_irq
-	    (pci->irq, snd_riptide_interrupt, IRQF_DISABLED | IRQF_SHARED,
-	     "RIPTIDE", chip)) {
+	if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED,
+			"RIPTIDE", chip)) {
 		snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
 			   pci->irq);
 		snd_riptide_free(chip);
diff -ru 2.2/sound/pci/rme32.c 3.4/sound/pci/rme32.c
--- 2.2/sound/pci/rme32.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/rme32.c	2006-12-22 01:57:09.000000000 +0100
@@ -1373,7 +1373,8 @@
 		return -ENOMEM;
 	}
 
-	if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_DISABLED | IRQF_SHARED, "RME32", (void *) rme32)) {
+	if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_SHARED,
+			"RME32", rme32)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
diff -ru 2.2/sound/pci/rme9652/hdsp.c 3.4/sound/pci/rme9652/hdsp.c
--- 2.2/sound/pci/rme9652/hdsp.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/rme9652/hdsp.c	2006-12-22 01:57:09.000000000 +0100
@@ -3516,8 +3516,8 @@
 
 	/* Align to bus-space 64K boundary */
 
-	cb_bus = (hdsp->capture_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
-	pb_bus = (hdsp->playback_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
+	cb_bus = ALIGN(hdsp->capture_dma_buf.addr, 0x10000ul);
+	pb_bus = ALIGN(hdsp->playback_dma_buf.addr, 0x10000ul);
 
 	/* Tell the card where it is */
 
@@ -4934,13 +4934,14 @@
 		return -EBUSY;
 	}
 
-	if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_DISABLED|IRQF_SHARED, "hdsp", (void *)hdsp)) {
+	if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED,
+			"hdsp", hdsp)) {
 		snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
 
 	hdsp->irq = pci->irq;
-	hdsp->precise_ptr = 1;
+	hdsp->precise_ptr = 0;
 	hdsp->use_midi_tasklet = 1;
 
 	if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
diff -ru 2.2/sound/pci/rme9652/hdspm.c 3.4/sound/pci/rme9652/hdspm.c
--- 2.2/sound/pci/rme9652/hdspm.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/rme9652/hdspm.c	2006-12-22 01:57:09.000000000 +0100
@@ -3496,8 +3496,7 @@
 		   hdspm->port + io_extent - 1);
 
 	if (request_irq(pci->irq, snd_hdspm_interrupt,
-			IRQF_DISABLED | IRQF_SHARED, "hdspm",
-			(void *) hdspm)) {
+			IRQF_SHARED, "hdspm", hdspm)) {
 		snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
diff -ru 2.2/sound/pci/rme9652/rme9652.c 3.4/sound/pci/rme9652/rme9652.c
--- 2.2/sound/pci/rme9652/rme9652.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/rme9652/rme9652.c	2006-12-22 01:57:09.000000000 +0100
@@ -1827,8 +1827,8 @@
 
 	/* Align to bus-space 64K boundary */
 
-	cb_bus = (rme9652->capture_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
-	pb_bus = (rme9652->playback_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
+	cb_bus = ALIGN(rme9652->capture_dma_buf.addr, 0x10000ul);
+	pb_bus = ALIGN(rme9652->playback_dma_buf.addr, 0x10000ul);
 
 	/* Tell the card where it is */
 
@@ -2500,7 +2500,8 @@
 		return -EBUSY;
 	}
 	
-	if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_DISABLED|IRQF_SHARED, "rme9652", (void *)rme9652)) {
+	if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED,
+			"rme9652", rme9652)) {
 		snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
diff -ru 2.2/sound/pci/rme96.c 3.4/sound/pci/rme96.c
--- 2.2/sound/pci/rme96.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/rme96.c	2006-12-22 01:57:09.000000000 +0100
@@ -1587,7 +1587,8 @@
 		return -ENOMEM;
 	}
 
-	if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_DISABLED|IRQF_SHARED, "RME96", (void *)rme96)) {
+	if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED,
+			"RME96", rme96)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
diff -ru 2.2/sound/pci/sonicvibes.c 3.4/sound/pci/sonicvibes.c
--- 2.2/sound/pci/sonicvibes.c	2006-10-09 14:52:22.000000000 +0200
+++ 3.4/sound/pci/sonicvibes.c	2006-12-22 01:57:09.000000000 +0100
@@ -1195,7 +1195,7 @@
 	pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port);
 	pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
 	if (sonic->irq >= 0)
-		free_irq(sonic->irq, (void *)sonic);
+		free_irq(sonic->irq, sonic);
 	release_and_free_resource(sonic->res_dmaa);
 	release_and_free_resource(sonic->res_dmac);
 	pci_release_regions(sonic->pci);
@@ -1257,7 +1257,8 @@
 	sonic->midi_port = pci_resource_start(pci, 3);
 	sonic->game_port = pci_resource_start(pci, 4);
 
-	if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_DISABLED|IRQF_SHARED, "S3 SonicVibes", (void *)sonic)) {
+	if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED,
+			"S3 SonicVibes", sonic)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_sonicvibes_free(sonic);
 		return -EBUSY;
diff -ru 2.2/sound/pci/trident/trident_main.c 3.4/sound/pci/trident/trident_main.c
--- 2.2/sound/pci/trident/trident_main.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/trident/trident_main.c	2006-12-22 01:57:09.000000000 +0100
@@ -3380,8 +3380,8 @@
 		snd_printk(KERN_ERR "trident: unable to allocate TLB buffer\n");
 		return -ENOMEM;
 	}
-	trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer.area + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1));
-	trident->tlb.entries_dmaaddr = (trident->tlb.buffer.addr + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1);
+	trident->tlb.entries = (unsigned int*)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4);
+	trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4);
 	/* allocate shadow TLB page table (virtual addresses) */
 	trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
 	if (trident->tlb.shadow_entries == NULL) {
@@ -3608,7 +3608,7 @@
 	}
 	trident->port = pci_resource_start(pci, 0);
 
-	if (request_irq(pci->irq, snd_trident_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
 			"Trident Audio", trident)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_trident_free(trident);
diff -ru 2.2/sound/pci/via82xx.c 3.4/sound/pci/via82xx.c
--- 2.2/sound/pci/via82xx.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/via82xx.c	2006-12-22 01:57:09.000000000 +0100
@@ -2307,7 +2307,7 @@
 	if (request_irq(pci->irq,
 			chip_type == TYPE_VIA8233 ?
 			snd_via8233_interrupt :	snd_via686_interrupt,
-			IRQF_DISABLED|IRQF_SHARED,
+			IRQF_SHARED,
 			card->driver, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
@@ -2366,7 +2366,7 @@
 
 static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
 {
-	static struct dxs_whitelist whitelist[] = {
+	static struct dxs_whitelist whitelist[] __devinitdata = {
 		{ .subvendor = 0x1005, .subdevice = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */
 		{ .subvendor = 0x1019, .subdevice = 0x0996, .action = VIA_DXS_48K },
 		{ .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */
@@ -2427,7 +2427,7 @@
 		{ .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC },	/* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */
 		{ } /* terminator */
 	};
-	struct dxs_whitelist *w;
+	const struct dxs_whitelist *w;
 	unsigned short subsystem_vendor;
 	unsigned short subsystem_device;
 
diff -ru 2.2/sound/pci/via82xx_modem.c 3.4/sound/pci/via82xx_modem.c
--- 2.2/sound/pci/via82xx_modem.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/via82xx_modem.c	2006-12-22 01:57:09.000000000 +0100
@@ -1124,7 +1124,7 @@
 		return err;
 	}
 	chip->port = pci_resource_start(pci, 0);
-	if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+	if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED,
 			card->driver, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
diff -ru 2.2/sound/pci/vx222/vx222.c 3.4/sound/pci/vx222/vx222.c
--- 2.2/sound/pci/vx222/vx222.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/vx222/vx222.c	2006-12-22 01:57:09.000000000 +0100
@@ -169,8 +169,8 @@
 	for (i = 0; i < 2; i++)
 		vx->port[i] = pci_resource_start(pci, i + 1);
 
-	if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_DISABLED|IRQF_SHARED,
-			CARD_NAME, (void *) chip)) {
+	if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
+			CARD_NAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_vx222_free(chip);
 		return -EBUSY;
diff -ru 2.2/sound/pci/ymfpci/ymfpci.c 3.4/sound/pci/ymfpci/ymfpci.c
--- 2.2/sound/pci/ymfpci/ymfpci.c	2006-10-02 17:39:33.000000000 +0200
+++ 3.4/sound/pci/ymfpci/ymfpci.c	2006-12-22 01:57:09.000000000 +0100
@@ -49,7 +49,6 @@
 static long joystick_port[SNDRV_CARDS];
 #endif
 static int rear_switch[SNDRV_CARDS];
-static int rear_swap[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 };
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard.");
@@ -67,8 +66,6 @@
 #endif
 module_param_array(rear_switch, bool, NULL, 0444);
 MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
-module_param_array(rear_swap, bool, NULL, 0444);
-MODULE_PARM_DESC(rear_swap, "Swap rear channels (must be enabled for correct IEC958 (S/PDIF)) output");
 
 static struct pci_device_id snd_ymfpci_ids[] = {
         { 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* YMF724 */
@@ -298,7 +295,7 @@
 		snd_card_free(card);
 		return err;
 	}
-	if ((err = snd_ymfpci_mixer(chip, rear_switch[dev], rear_swap[dev])) < 0) {
+	if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) {
 		snd_card_free(card);
 		return err;
 	}
diff -ru 2.2/sound/pci/ymfpci/ymfpci_main.c 3.4/sound/pci/ymfpci/ymfpci_main.c
--- 2.2/sound/pci/ymfpci/ymfpci_main.c	2006-10-25 06:27:02.000000000 +0200
+++ 3.4/sound/pci/ymfpci/ymfpci_main.c	2006-12-22 01:57:09.000000000 +0100
@@ -910,7 +910,7 @@
 	ypcm = runtime->private_data;
 	ypcm->output_front = 1;
 	ypcm->output_rear = chip->mode_dup4ch ? 1 : 0;
-	ypcm->swap_rear = chip->rear_swap;
+	ypcm->swap_rear = 0;
 	spin_lock_irq(&chip->reg_lock);
 	if (ypcm->output_rear) {
 		ymfpci_open_extension(chip);
@@ -936,6 +936,7 @@
 	ypcm = runtime->private_data;
 	ypcm->output_front = 0;
 	ypcm->output_rear = 1;
+	ypcm->swap_rear = 1;
 	spin_lock_irq(&chip->reg_lock);
 	snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
 			  snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) | 2);
@@ -963,6 +964,7 @@
 	ypcm = runtime->private_data;
 	ypcm->output_front = 0;
 	ypcm->output_rear = 1;
+	ypcm->swap_rear = 0;
 	spin_lock_irq(&chip->reg_lock);
 	ymfpci_open_extension(chip);
 	chip->rear_opened++;
@@ -1755,7 +1757,7 @@
 	chip->ac97 = NULL;
 }
 
-int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap)
+int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
 {
 	struct snd_ac97_template ac97;
 	struct snd_kcontrol *kctl;
@@ -1767,7 +1769,6 @@
 		.read = snd_ymfpci_codec_read,
 	};
 
-	chip->rear_swap = rear_swap;
 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
 		return err;
 	chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus;
@@ -2025,10 +2026,10 @@
 	chip->bank_size_effect = snd_ymfpci_readl(chip, YDSXGR_EFFCTRLSIZE) << 2;
 	chip->work_size = YDSXG_DEFAULT_WORK_SIZE;
 	
-	size = ((playback_ctrl_size + 0x00ff) & ~0x00ff) +
-	       ((chip->bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0x00ff) & ~0x00ff) +
-	       ((chip->bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0x00ff) & ~0x00ff) +
-	       ((chip->bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0x00ff) & ~0x00ff) +
+	size = ALIGN(playback_ctrl_size, 0x100) +
+	       ALIGN(chip->bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES, 0x100) +
+	       ALIGN(chip->bank_size_capture * 2 * YDSXG_CAPTURE_VOICES, 0x100) +
+	       ALIGN(chip->bank_size_effect * 2 * YDSXG_EFFECT_VOICES, 0x100) +
 	       chip->work_size;
 	/* work_ptr must be aligned to 256 bytes, but it's already
 	   covered with the kernel page allocation mechanism */
@@ -2043,8 +2044,8 @@
 	chip->bank_base_playback_addr = ptr_addr;
 	chip->ctrl_playback = (u32 *)ptr;
 	chip->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);
-	ptr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
-	ptr_addr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
+	ptr += ALIGN(playback_ctrl_size, 0x100);
+	ptr_addr += ALIGN(playback_ctrl_size, 0x100);
 	for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {
 		chip->voices[voice].number = voice;
 		chip->voices[voice].bank = (struct snd_ymfpci_playback_bank *)ptr;
@@ -2055,8 +2056,8 @@
 			ptr_addr += chip->bank_size_playback;
 		}
 	}
-	ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);
-	ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;
+	ptr = (char *)ALIGN((unsigned long)ptr, 0x100);
+	ptr_addr = ALIGN(ptr_addr, 0x100);
 	chip->bank_base_capture = ptr;
 	chip->bank_base_capture_addr = ptr_addr;
 	for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)
@@ -2065,8 +2066,8 @@
 			ptr += chip->bank_size_capture;
 			ptr_addr += chip->bank_size_capture;
 		}
-	ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);
-	ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;
+	ptr = (char *)ALIGN((unsigned long)ptr, 0x100);
+	ptr_addr = ALIGN(ptr_addr, 0x100);
 	chip->bank_base_effect = ptr;
 	chip->bank_base_effect_addr = ptr_addr;
 	for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)
@@ -2075,8 +2076,8 @@
 			ptr += chip->bank_size_effect;
 			ptr_addr += chip->bank_size_effect;
 		}
-	ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);
-	ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;
+	ptr = (char *)ALIGN((unsigned long)ptr, 0x100);
+	ptr_addr = ALIGN(ptr_addr, 0x100);
 	chip->work_base = ptr;
 	chip->work_base_addr = ptr_addr;
 	
@@ -2153,7 +2154,7 @@
 		snd_dma_free_pages(&chip->work_ptr);
 	
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	release_and_free_resource(chip->res_reg_area);
 
 	pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
@@ -2290,7 +2291,7 @@
 	chip->pci = pci;
 	chip->irq = -1;
 	chip->device_id = pci->device;
-	pci_read_config_byte(pci, PCI_REVISION_ID, (u8 *)&chip->rev);
+	pci_read_config_byte(pci, PCI_REVISION_ID, &chip->rev);
 	chip->reg_area_phys = pci_resource_start(pci, 0);
 	chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000);
 	pci_set_master(pci);
@@ -2300,7 +2301,8 @@
 		snd_ymfpci_free(chip);
 		return -EBUSY;
 	}
-	if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_DISABLED|IRQF_SHARED, "YMFPCI", (void *) chip)) {
+	if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED,
+			"YMFPCI", chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ymfpci_free(chip);
 		return -EBUSY;
@@ -2322,7 +2324,6 @@
 		return -EIO;
 	}
 
-	chip->rear_swap = 1;
 	if ((err = snd_ymfpci_ac3_init(chip)) < 0) {
 		snd_ymfpci_free(chip);
 		return err;
diff -ru 2.2/sound/usb/usbaudio.c 3.4/sound/usb/usbaudio.c
--- 2.2/sound/usb/usbaudio.c	2006-11-29 04:53:09.000000000 +0100
+++ 3.4/sound/usb/usbaudio.c	2006-12-22 01:57:09.000000000 +0100
@@ -3577,8 +3577,7 @@
 		printk(KERN_WARNING "invalid nrpacks value.\n");
 		return -EINVAL;
 	}
-	usb_register(&usb_audio_driver);
-	return 0;
+	return usb_register(&usb_audio_driver);
 }
 
 
diff -ru 2.2/ubuntu/media/Kconfig 3.4/ubuntu/media/Kconfig
--- 2.2/ubuntu/media/Kconfig	2006-12-14 01:18:40.000000000 +0100
+++ 3.4/ubuntu/media/Kconfig	2006-12-16 07:00:26.000000000 +0100
@@ -2,5 +2,6 @@
 
 source "ubuntu/media/ov511/Kconfig"
 source "ubuntu/media/ivtv/Kconfig"
+source "ubuntu/media/usbvideo/Kconfig"
 
 endmenu
diff -ru 2.2/ubuntu/media/Makefile 3.4/ubuntu/media/Makefile
--- 2.2/ubuntu/media/Makefile	2006-12-14 01:15:48.000000000 +0100
+++ 3.4/ubuntu/media/Makefile	2006-12-16 07:00:54.000000000 +0100
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_USB_OV511_NEW)	+= ov511/
 obj-$(CONFIG_IVTV)		+= ivtv/
+obj-$(CONFIG_USB_UVCCAM)	+= usbvideo/
Only in 3.4/ubuntu/media: usbvideo
diff -ru 2.2/ubuntu/wireless/prism2/prism2sta.c 3.4/ubuntu/wireless/prism2/prism2sta.c
--- 2.2/ubuntu/wireless/prism2/prism2sta.c	2006-12-09 06:21:39.000000000 +0100
+++ 3.4/ubuntu/wireless/prism2/prism2sta.c	2006-12-18 04:22:10.000000000 +0100
@@ -1539,7 +1539,7 @@
 				WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
 
 			/* Get the ball rolling on the comms quality stuff */
-			prism2sta_commsqual_defer(ws);
+			prism2sta_commsqual_defer(&hw->commsqual_bh);
 		}
 		break;
 
