Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
diff --git a/CREDITS b/CREDITS
index 9bd099d..d65ffe5 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2475,13 +2475,9 @@
 S: USA
 
 N: Dave Neuer
-E: dneuer@innovation-charter.com
-E: mr_fred_smoothie@yahoo.com
+E: dave.neuer@pobox.com
 D: Helped implement support for Compaq's H31xx series iPAQs
 D: Other mostly minor tweaks & bugfixes
-S: 325 E. Main St., Suite 3
-S: Carnegie, PA 15105
-S: USA
 
 N: Michael Neuffer
 E: mike@i-Connect.Net
diff --git a/Makefile b/Makefile
index c11a317..9e005e1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 12
-EXTRAVERSION =-rc5
+EXTRAVERSION =-rc6
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bf397a9..5eee3bc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -497,7 +497,7 @@
 
 config CPU_FREQ_SA1100
 	bool
-	depends on CPU_FREQ && (SA1100_LART || SA1100_PLEB)
+	depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
 	default y
 
 config CPU_FREQ_SA1110
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index 665bd2c..d3fe253 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -47,3 +47,10 @@
                orr     r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
 #endif
 
+#ifdef CONFIG_ARCH_IXP2000
+		mov	r1, #-1
+		mov	r0, #0xd6000000
+		str	r1, [r0, #0x14]
+		str	r1, [r0, #0x18]
+#endif
+
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
index 2b4059d..5d92af9 100644
--- a/arch/arm/configs/badge4_defconfig
+++ b/arch/arm/configs/badge4_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sat Mar 26 21:32:26 2005
+# Linux kernel version: 2.6.12-rc6-git3
+# Thu Jun  9 19:00:50 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -16,6 +16,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -34,6 +35,8 @@
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -109,7 +112,6 @@
 CONFIG_CPU_CACHE_V4WB=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -122,6 +124,7 @@
 # Bus support
 #
 CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -131,6 +134,7 @@
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_DISCONTIGMEM=y
 # CONFIG_LEDS is not set
@@ -152,12 +156,14 @@
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_SA1100=y
 
 #
 # Floating point emulation
@@ -294,7 +300,6 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -428,7 +433,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -526,6 +530,7 @@
 # CONFIG_SMC_IRCC_FIR is not set
 # CONFIG_ALI_FIR is not set
 CONFIG_SA1100_FIR=y
+# CONFIG_VIA_FIR is not set
 CONFIG_BT=m
 CONFIG_BT_L2CAP=m
 # CONFIG_BT_SCO is not set
@@ -618,7 +623,6 @@
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -687,7 +691,6 @@
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -736,6 +739,7 @@
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -747,6 +751,7 @@
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -871,7 +876,6 @@
 #
 CONFIG_USB_STORAGE=y
 CONFIG_USB_STORAGE_DEBUG=y
-# CONFIG_USB_STORAGE_RW_DETECT is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
@@ -954,9 +958,11 @@
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
 CONFIG_USB_SERIAL_BELKIN=m
 CONFIG_USB_SERIAL_WHITEHEAT=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -985,6 +991,7 @@
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
 # CONFIG_USB_SERIAL_TI is not set
 CONFIG_USB_SERIAL_CYBERJACK=m
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index b4e297d..b9de07d 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Mon Mar 28 00:02:26 2005
+# Linux kernel version: 2.6.12-rc4
+# Thu Jun  9 01:59:03 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -16,6 +16,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -33,6 +34,8 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -120,6 +123,7 @@
 # Bus support
 #
 CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -138,6 +142,7 @@
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_DISCONTIGMEM=y
 # CONFIG_LEDS is not set
@@ -159,12 +164,13 @@
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+CONFIG_CPU_FREQ_SA1100=y
 
 #
 # Floating point emulation
@@ -298,7 +304,6 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
@@ -379,7 +384,6 @@
 # Networking options
 #
 # CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -476,6 +480,7 @@
 # CONFIG_SMC_IRCC_FIR is not set
 # CONFIG_ALI_FIR is not set
 CONFIG_SA1100_FIR=m
+# CONFIG_VIA_FIR is not set
 # CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
@@ -647,7 +652,6 @@
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -676,9 +680,11 @@
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 CONFIG_FB_SA1100=y
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig
index 6987c8c..fb41a36 100644
--- a/arch/arm/configs/hackkit_defconfig
+++ b/arch/arm/configs/hackkit_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Mon Mar 28 00:22:34 2005
+# Linux kernel version: 2.6.12-rc6-git3
+# Thu Jun  9 20:58:58 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -16,6 +16,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -34,6 +35,8 @@
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -109,7 +112,6 @@
 CONFIG_CPU_CACHE_V4WB=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -119,6 +121,7 @@
 # Bus support
 #
 CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -128,6 +131,7 @@
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_DISCONTIGMEM=y
 CONFIG_LEDS=y
@@ -151,12 +155,14 @@
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_SA1100=y
 
 #
 # Floating point emulation
@@ -280,7 +286,6 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
@@ -338,7 +343,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -484,7 +488,6 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -533,7 +536,6 @@
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 4eb3615..e14278d 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -269,7 +269,7 @@
 	add	r5, sp, #S_PC
 	ldmia	r7, {r2 - r4}			@ Get USR pc, cpsr
 
-#if __LINUX_ARM_ARCH__ < 6
+#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
 	@ make sure our user space atomic helper is aborted
 	cmp	r2, #VIRT_OFFSET
 	bichs	r3, r3, #PSR_Z_BIT
@@ -616,11 +616,17 @@
 
 __kuser_cmpxchg:				@ 0xffff0fc0
 
-#if __LINUX_ARM_ARCH__ < 6
+#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
 
-#ifdef CONFIG_SMP  /* sanity check */
-#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?"
-#endif
+	/*
+	 * Poor you.  No fast solution possible...
+	 * The kernel itself must perform the operation.
+	 * A special ghost syscall is used for that (see traps.c).
+	 */
+	swi	#0x9ffff0
+	mov	pc, lr
+
+#elif __LINUX_ARM_ARCH__ < 6
 
 	/*
 	 * Theory of operation:
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 14df16b..45d2a03 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -464,6 +464,55 @@
 #endif
 		return 0;
 
+#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
+	/*
+	 * Atomically store r1 in *r2 if *r2 is equal to r0 for user space.
+	 * Return zero in r0 if *MEM was changed or non-zero if no exchange
+	 * happened.  Also set the user C flag accordingly.
+	 * If access permissions have to be fixed up then non-zero is
+	 * returned and the operation has to be re-attempted.
+	 *
+	 * *NOTE*: This is a ghost syscall private to the kernel.  Only the
+	 * __kuser_cmpxchg code in entry-armv.S should be aware of its
+	 * existence.  Don't ever use this from user code.
+	 */
+	case 0xfff0:
+	{
+		extern void do_DataAbort(unsigned long addr, unsigned int fsr,
+					 struct pt_regs *regs);
+		unsigned long val;
+		unsigned long addr = regs->ARM_r2;
+		struct mm_struct *mm = current->mm;
+		pgd_t *pgd; pmd_t *pmd; pte_t *pte;
+
+		regs->ARM_cpsr &= ~PSR_C_BIT;
+		spin_lock(&mm->page_table_lock);
+		pgd = pgd_offset(mm, addr);
+		if (!pgd_present(*pgd))
+			goto bad_access;
+		pmd = pmd_offset(pgd, addr);
+		if (!pmd_present(*pmd))
+			goto bad_access;
+		pte = pte_offset_map(pmd, addr);
+		if (!pte_present(*pte) || !pte_write(*pte))
+			goto bad_access;
+		val = *(unsigned long *)addr;
+		val -= regs->ARM_r0;
+		if (val == 0) {
+			*(unsigned long *)addr = regs->ARM_r1;
+			regs->ARM_cpsr |= PSR_C_BIT;
+		}
+		spin_unlock(&mm->page_table_lock);
+		return val;
+
+		bad_access:
+		spin_unlock(&mm->page_table_lock);
+		/* simulate a read access fault */
+		do_DataAbort(addr, 15 + (1 << 11), regs);
+		return -1;
+	}
+#endif
+
 	default:
 		/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
 		   if not implemented, rather than raising SIGILL.  This
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
index 6d1d7c2..5e240e4 100644
--- a/arch/arm/lib/io-writesw-armv4.S
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -87,9 +87,9 @@
 		subs	r2, r2, #2
 		orr	ip, ip, r3, push_hbyte1
 		strh	ip, [r0]
-		bpl	2b
+		bpl	1b
 
-3:		tst	r2, #1
-2:		movne	ip, r3, lsr #8
+		tst	r2, #1
+3:		movne	ip, r3, lsr #8
 		strneh	ip, [r0]
 		mov	pc, lr
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 3f95223..6823ae2 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -304,6 +304,15 @@
 	PWER  = 0xC0000002;
 	PRER  = 0x00000002;
 	PFER  = 0x00000002;
+ 	/*	for use I SRAM as framebuffer.	*/
+ 	PSLR |= 0xF04;
+ 	PCFR = 0x66;
+ 	/*	For Keypad wakeup.	*/
+ 	KPC &=~KPC_ASACT;
+ 	KPC |=KPC_AS;
+ 	PKWR  = 0x000FD000;
+ 	/*	Need read PKWR back after set it.	*/
+ 	PKWR;
 }
 
 MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 82a4bf3..9799fe8 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -29,9 +29,6 @@
  */
 #undef DEBUG
 
-extern void pxa_cpu_suspend(void);
-extern void pxa_cpu_resume(void);
-
 #define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
 #define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]
 
@@ -63,6 +60,12 @@
 	SLEEP_SAVE_ICMR,
 	SLEEP_SAVE_CKEN,
 
+#ifdef CONFIG_PXA27x
+ 	SLEEP_SAVE_MDREFR,
+ 	SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
+ 	SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
+#endif
+
 	SLEEP_SAVE_CKSUM,
 
 	SLEEP_SAVE_SIZE
@@ -75,9 +78,7 @@
 	unsigned long checksum = 0;
 	struct timespec delta, rtc;
 	int i;
-
-	if (state != PM_SUSPEND_MEM)
-		return -EINVAL;
+	extern void pxa_cpu_pm_enter(suspend_state_t state);
 
 #ifdef CONFIG_IWMMXT
 	/* force any iWMMXt context to ram **/
@@ -100,16 +101,17 @@
 	SAVE(GAFR2_L); SAVE(GAFR2_U);
 
 #ifdef CONFIG_PXA27x
+	SAVE(MDREFR);
 	SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
 	SAVE(GAFR3_L); SAVE(GAFR3_U);
+	SAVE(PWER); SAVE(PCFR); SAVE(PRER);
+	SAVE(PFER); SAVE(PKWR);
 #endif
 
 	SAVE(ICMR);
 	ICMR = 0;
 
 	SAVE(CKEN);
-	CKEN = 0;
-
 	SAVE(PSTR);
 
 	/* Note: wake up source are set up in each machine specific files */
@@ -123,16 +125,13 @@
 	/* Clear sleep reset status */
 	RCSR = RCSR_SMR;
 
-	/* set resume return address */
-	PSPR = virt_to_phys(pxa_cpu_resume);
-
 	/* before sleeping, calculate and save a checksum */
 	for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
 		checksum += sleep_save[i];
 	sleep_save[SLEEP_SAVE_CKSUM] = checksum;
 
 	/* *** go zzz *** */
-	pxa_cpu_suspend();
+	pxa_cpu_pm_enter(state);
 
 	/* after sleeping, validate the checksum */
 	checksum = 0;
@@ -145,7 +144,7 @@
 		LUB_HEXLED = 0xbadbadc5;
 #endif
 		while (1)
-			pxa_cpu_suspend();
+			pxa_cpu_pm_enter(state);
 	}
 
 	/* ensure not to come back here if it wasn't intended */
@@ -162,8 +161,11 @@
 	RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
 
 #ifdef CONFIG_PXA27x
+	RESTORE(MDREFR);
 	RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
 	RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
+	RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
+	RESTORE(PFER); RESTORE(PKWR);
 #endif
 
 	PSSR = PSSR_RDH | PSSR_PH;
@@ -197,7 +199,9 @@
  */
 static int pxa_pm_prepare(suspend_state_t state)
 {
-	return 0;
+	extern int pxa_cpu_pm_prepare(suspend_state_t state);
+
+	return pxa_cpu_pm_prepare(state);
 }
 
 /*
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index e887b71..b6d945a 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -102,3 +102,32 @@
 }
 
 EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
+
+
+int pxa_cpu_pm_prepare(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void pxa_cpu_pm_enter(suspend_state_t state)
+{
+	extern void pxa_cpu_suspend(unsigned int);
+	extern void pxa_cpu_resume(void);
+
+	CKEN = 0;
+
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		/* set resume return address */
+		PSPR = virt_to_phys(pxa_cpu_resume);
+		pxa_cpu_suspend(3);
+		break;
+	}
+}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 7e863af..aa3c3b2 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -120,6 +120,38 @@
 EXPORT_SYMBOL(get_memclk_frequency_10khz);
 EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
 
+int pxa_cpu_pm_prepare(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+void pxa_cpu_pm_enter(suspend_state_t state)
+{
+	extern void pxa_cpu_standby(void);
+	extern void pxa_cpu_suspend(unsigned int);
+	extern void pxa_cpu_resume(void);
+
+	CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
+
+	/* ensure voltage-change sequencer not initiated, which hangs */
+	PCFR &= ~PCFR_FVC;
+
+	/* Clear edge-detect status register. */
+	PEDR = 0xDF12FE1B;
+
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		/* set resume return address */
+		PSPR = virt_to_phys(pxa_cpu_resume);
+		pxa_cpu_suspend(3);
+		break;
+	}
+}
 
 /*
  * device registration specific to PXA27x.
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index bc229fa..c7c2889 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -785,6 +785,10 @@
 	chan->client = NULL;
 	chan->in_use = 0;
 
+	if (chan->irq_claimed)
+		free_irq(chan->irq, (void *)chan);
+	chan->irq_claimed = 0;
+
 	local_irq_restore(flags);
 
 	return 0;
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 50cde57..6923316 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -150,7 +150,7 @@
 
 config H3600_SLEEVE
 	tristate "Compaq iPAQ Handheld sleeve support"
-	depends on SA1100_H3600
+	depends on SA1100_H3100 || SA1100_H3600
 	help
 	  Choose this option to enable support for extension packs (sleeves)
 	  for the Compaq iPAQ H3XXX series of handheld computers.  This option
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 48bac7d..3fefb43 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -228,7 +228,6 @@
 	select CPU_CACHE_V4WB
 	select CPU_CACHE_VIVT
 	select CPU_TLB_V4WB
-	select CPU_MINICACHE
 
 # XScale
 config CPU_XSCALE
@@ -239,7 +238,6 @@
 	select CPU_ABRT_EV5T
 	select CPU_CACHE_VIVT
 	select CPU_TLB_V4WBI
-	select CPU_MINICACHE
 
 # ARMv6
 config CPU_V6
@@ -345,11 +343,6 @@
 config CPU_TLB_V6
 	bool
 
-config CPU_MINICACHE
-	bool
-	help
-	  Processor has a minicache.
-
 comment "Processor Features"
 
 config ARM_THUMB
@@ -429,3 +422,11 @@
 	  assume directly accessing that register and always obtain the
 	  expected value only on ARMv7 and above.
 
+config NEEDS_SYSCALL_FOR_CMPXCHG
+	bool
+	default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
+	help
+	  SMP on a pre-ARMv6 processor?  Well OK then.
+	  Forget about fast user space cmpxchg support.
+	  It is just not possible.
+
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index ccf316c..59f47d4 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -31,8 +31,6 @@
 obj-$(CONFIG_CPU_SA1100)	+= copypage-v4mc.o
 obj-$(CONFIG_CPU_XSCALE)	+= copypage-xscale.o
 
-obj-$(CONFIG_CPU_MINICACHE)	+= minicache.o
-
 obj-$(CONFIG_CPU_TLB_V3)	+= tlb-v3.o
 obj-$(CONFIG_CPU_TLB_V4WT)	+= tlb-v4.o
 obj-$(CONFIG_CPU_TLB_V4WB)	+= tlb-v4wb.o
diff --git a/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S
deleted file mode 100644
index bb27731..0000000
--- a/arch/arm/mm/copypage-xscale.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *  linux/arch/arm/lib/copypage-xscale.S
- *
- *  Copyright (C) 2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/constants.h>
-
-/*
- * General note:
- *  We don't really want write-allocate cache behaviour for these functions
- *  since that will just eat through 8K of the cache.
- */
-
-	.text
-	.align	5
-/*
- * XScale optimised copy_user_page
- *  r0 = destination
- *  r1 = source
- *  r2 = virtual user address of ultimate destination page
- *
- * The source page may have some clean entries in the cache already, but we
- * can safely ignore them - break_cow() will flush them out of the cache
- * if we eventually end up using our copied page.
- *
- * What we could do is use the mini-cache to buffer reads from the source
- * page.  We rely on the mini-cache being smaller than one page, so we'll
- * cycle through the complete cache anyway.
- */
-ENTRY(xscale_mc_copy_user_page)
-	stmfd	sp!, {r4, r5, lr}
-	mov	r5, r0
-	mov	r0, r1
-	bl	map_page_minicache
-	mov	r1, r5
-	mov	lr, #PAGE_SZ/64-1
-
-	/*
-	 * Strangely enough, best performance is achieved
-	 * when prefetching destination as well.  (NP)
-	 */
-	pld	[r0, #0]
-	pld	[r0, #32]
-	pld	[r1, #0]
-	pld	[r1, #32]
-
-1:	pld	[r0, #64]
-	pld	[r0, #96]
-	pld	[r1, #64]
-	pld	[r1, #96]
-
-2:	ldrd	r2, [r0], #8
-	ldrd	r4, [r0], #8
-	mov	ip, r1
-	strd	r2, [r1], #8
-	ldrd	r2, [r0], #8
-	strd	r4, [r1], #8
-	ldrd	r4, [r0], #8
-	strd	r2, [r1], #8
-	strd	r4, [r1], #8
-	mcr	p15, 0, ip, c7, c10, 1		@ clean D line
-	ldrd	r2, [r0], #8
-	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line
-	ldrd	r4, [r0], #8
-	mov	ip, r1
-	strd	r2, [r1], #8
-	ldrd	r2, [r0], #8
-	strd	r4, [r1], #8
-	ldrd	r4, [r0], #8
-	strd	r2, [r1], #8
-	strd	r4, [r1], #8
-	mcr	p15, 0, ip, c7, c10, 1		@ clean D line
-	subs	lr, lr, #1
-	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line
-	bgt	1b
-	beq	2b
-
-	ldmfd	sp!, {r4, r5, pc}
-
-	.align	5
-/*
- * XScale optimised clear_user_page
- *  r0 = destination
- *  r1 = virtual user address of ultimate destination page
- */
-ENTRY(xscale_mc_clear_user_page)
-	mov	r1, #PAGE_SZ/32
-	mov	r2, #0
-	mov	r3, #0
-1:	mov	ip, r0
-	strd	r2, [r0], #8
-	strd	r2, [r0], #8
-	strd	r2, [r0], #8
-	strd	r2, [r0], #8
-	mcr	p15, 0, ip, c7, c10, 1		@ clean D line
-	subs	r1, r1, #1
-	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line
-	bne	1b
-	mov	pc, lr
-
-	__INITDATA
-
-	.type	xscale_mc_user_fns, #object
-ENTRY(xscale_mc_user_fns)
-	.long	xscale_mc_clear_user_page
-	.long	xscale_mc_copy_user_page
-	.size	xscale_mc_user_fns, . - xscale_mc_user_fns
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
new file mode 100644
index 0000000..42a6ee2
--- /dev/null
+++ b/arch/arm/mm/copypage-xscale.c
@@ -0,0 +1,131 @@
+/*
+ *  linux/arch/arm/lib/copypage-xscale.S
+ *
+ *  Copyright (C) 1995-2005 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This handles the mini data cache, as found on SA11x0 and XScale
+ * processors.  When we copy a user page page, we map it in such a way
+ * that accesses to this page will not touch the main data cache, but
+ * will be cached in the mini data cache.  This prevents us thrashing
+ * the main data cache on page faults.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+/*
+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
+ * specific hacks for copying pages efficiently.
+ */
+#define COPYPAGE_MINICACHE	0xffff8000
+
+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
+				  L_PTE_CACHEABLE)
+
+#define TOP_PTE(x)	pte_offset_kernel(top_pmd, x)
+
+static DEFINE_SPINLOCK(minicache_lock);
+
+/*
+ * XScale mini-dcache optimised copy_user_page
+ *
+ * We flush the destination cache lines just before we write the data into the
+ * corresponding address.  Since the Dcache is read-allocate, this removes the
+ * Dcache aliasing issue.  The writes will be forwarded to the write buffer,
+ * and merged as appropriate.
+ */
+static void __attribute__((naked))
+mc_copy_user_page(void *from, void *to)
+{
+	/*
+	 * Strangely enough, best performance is achieved
+	 * when prefetching destination as well.  (NP)
+	 */
+	asm volatile(
+	"stmfd	sp!, {r4, r5, lr}		\n\
+	mov	lr, %2				\n\
+	pld	[r0, #0]			\n\
+	pld	[r0, #32]			\n\
+	pld	[r1, #0]			\n\
+	pld	[r1, #32]			\n\
+1:	pld	[r0, #64]			\n\
+	pld	[r0, #96]			\n\
+	pld	[r1, #64]			\n\
+	pld	[r1, #96]			\n\
+2:	ldrd	r2, [r0], #8			\n\
+	ldrd	r4, [r0], #8			\n\
+	mov	ip, r1				\n\
+	strd	r2, [r1], #8			\n\
+	ldrd	r2, [r0], #8			\n\
+	strd	r4, [r1], #8			\n\
+	ldrd	r4, [r0], #8			\n\
+	strd	r2, [r1], #8			\n\
+	strd	r4, [r1], #8			\n\
+	mcr	p15, 0, ip, c7, c10, 1		@ clean D line\n\
+	ldrd	r2, [r0], #8			\n\
+	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line\n\
+	ldrd	r4, [r0], #8			\n\
+	mov	ip, r1				\n\
+	strd	r2, [r1], #8			\n\
+	ldrd	r2, [r0], #8			\n\
+	strd	r4, [r1], #8			\n\
+	ldrd	r4, [r0], #8			\n\
+	strd	r2, [r1], #8			\n\
+	strd	r4, [r1], #8			\n\
+	mcr	p15, 0, ip, c7, c10, 1		@ clean D line\n\
+	subs	lr, lr, #1			\n\
+	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line\n\
+	bgt	1b				\n\
+	beq	2b				\n\
+	ldmfd	sp!, {r4, r5, pc}		"
+	:
+	: "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
+}
+
+void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
+{
+	spin_lock(&minicache_lock);
+
+	set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
+	flush_tlb_kernel_page(COPYPAGE_MINICACHE);
+
+	mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
+
+	spin_unlock(&minicache_lock);
+}
+
+/*
+ * XScale optimised clear_user_page
+ */
+void __attribute__((naked))
+xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr)
+{
+	asm volatile(
+	"mov	r1, %0				\n\
+	mov	r2, #0				\n\
+	mov	r3, #0				\n\
+1:	mov	ip, r0				\n\
+	strd	r2, [r0], #8			\n\
+	strd	r2, [r0], #8			\n\
+	strd	r2, [r0], #8			\n\
+	strd	r2, [r0], #8			\n\
+	mcr	p15, 0, ip, c7, c10, 1		@ clean D line\n\
+	subs	r1, r1, #1			\n\
+	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line\n\
+	bne	1b				\n\
+	mov	pc, lr"
+	:
+	: "I" (PAGE_SIZE / 32));
+}
+
+struct cpu_user_fns xscale_mc_user_fns __initdata = {
+	.cpu_clear_user_page	= xscale_mc_clear_user_page, 
+	.cpu_copy_user_page	= xscale_mc_copy_user_page,
+};
diff --git a/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c
deleted file mode 100644
index dedf2ab..0000000
--- a/arch/arm/mm/minicache.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *  linux/arch/arm/mm/minicache.c
- *
- *  Copyright (C) 2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This handles the mini data cache, as found on SA11x0 and XScale
- * processors.  When we copy a user page page, we map it in such a way
- * that accesses to this page will not touch the main data cache, but
- * will be cached in the mini data cache.  This prevents us thrashing
- * the main data cache on page faults.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-
-/*
- * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
- * specific hacks for copying pages efficiently.
- */
-#define minicache_address (0xffff8000)
-#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
-				  L_PTE_CACHEABLE)
-
-static pte_t *minicache_pte;
-
-/*
- * Note that this is intended to be called only from the copy_user_page
- * asm code; anything else will require special locking to prevent the
- * mini-cache space being re-used.  (Note: probably preempt unsafe).
- *
- * We rely on the fact that the minicache is 2K, and we'll be pushing
- * 4K of data through it, so we don't actually have to specifically
- * flush the minicache when we change the mapping.
- *
- * Note also: assert(PAGE_OFFSET <= virt < high_memory).
- * Unsafe: preempt, kmap.
- */
-unsigned long map_page_minicache(unsigned long virt)
-{
-	set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot));
-	flush_tlb_kernel_page(minicache_address);
-
-	return minicache_address;
-}
-
-static int __init minicache_init(void)
-{
-	pgd_t *pgd;
-	pmd_t *pmd;
-
-	spin_lock(&init_mm.page_table_lock);
-
-	pgd = pgd_offset_k(minicache_address);
-	pmd = pmd_alloc(&init_mm, pgd, minicache_address);
-	if (!pmd)
-		BUG();
-	minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address);
-	if (!minicache_pte)
-		BUG();
-
-	spin_unlock(&init_mm.page_table_lock);
-
-	return 0;
-}
-
-core_initcall(minicache_init);
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 0fbcfe0..51ecd51 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -43,7 +43,7 @@
 # Note: kbuild does not track this dependency due to usage of .incbin
 $(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
 targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
-targets += vsyscall.lds
+targets += vsyscall-note.o vsyscall.lds
 
 # The DSO images are built using a special linker script.
 quiet_cmd_syscall = SYSCALL $@
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index 4f3cdef..962b6c4 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -460,9 +460,9 @@
 	;;
 
 	st8 [r2]=r14				// update current->blocked with new mask
-	cmpxchg4.acq r14=[r9],r18,ar.ccv	// current->thread_info->flags <- r18
+	cmpxchg4.acq r8=[r9],r18,ar.ccv		// current->thread_info->flags <- r18
 	;;
-	cmp.ne p6,p0=r17,r14			// update failed?
+	cmp.ne p6,p0=r17,r8			// update failed?
 (p6)	br.cond.spnt.few 1b			// yes -> retry
 
 #ifdef CONFIG_SMP
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index febc091..f1aca7c 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -825,14 +825,16 @@
 		 * XXX Should have an arch-hook for running this after final section
 		 *     addresses have been selected...
 		 */
-		/* See if gp can cover the entire core module:  */
-		uint64_t gp = (uint64_t) mod->module_core + MAX_LTOFF / 2;
-		if (mod->core_size >= MAX_LTOFF)
+		uint64_t gp;
+		if (mod->core_size > MAX_LTOFF)
 			/*
 			 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
 			 * at the end of the module.
 			 */
-			gp = (uint64_t) mod->module_core + mod->core_size - MAX_LTOFF / 2;
+			gp = mod->core_size - MAX_LTOFF / 2;
+		else
+			gp = mod->core_size / 2;
+		gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
 		mod->arch.gp = gp;
 		DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
 	}
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 08c8a5e..575a8f6 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -635,11 +635,17 @@
 {
 	struct ia64_psr *psr = ia64_psr(ia64_task_regs(task));
 
+	/*
+	 * Prevent migrating this task while
+	 * we're fiddling with the FPU state
+	 */
+	preempt_disable();
 	if (ia64_is_local_fpu_owner(task) && psr->mfh) {
 		psr->mfh = 0;
 		task->thread.flags |= IA64_THREAD_FPH_VALID;
 		ia64_save_fpu(&task->thread.fph[0]);
 	}
+	preempt_enable();
 }
 
 /*
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index b7e6b4c..d14692e 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -720,7 +720,8 @@
 	ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page)));
 
 	/*
-	 * Initialize default control register to defer all speculative faults.  The
+	 * Initialize default control register to defer speculative faults except
+	 * for those arising from TLB misses, which are not deferred.  The
 	 * kernel MUST NOT depend on a particular setting of these bits (in other words,
 	 * the kernel must have recovery code for all speculative accesses).  Turn on
 	 * dcr.lc as per recommendation by the architecture team.  Most IA-32 apps
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index e82ad78..1861173 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -111,6 +111,24 @@
 	siginfo_t siginfo;
 	int sig, code;
 
+	/* break.b always sets cr.iim to 0, which causes problems for
+	 * debuggers.  Get the real break number from the original instruction,
+	 * but only for kernel code.  User space break.b is left alone, to
+	 * preserve the existing behaviour.  All break codings have the same
+	 * format, so there is no need to check the slot type.
+	 */
+	if (break_num == 0 && !user_mode(regs)) {
+		struct ia64_psr *ipsr = ia64_psr(regs);
+		unsigned long *bundle = (unsigned long *)regs->cr_iip;
+		unsigned long slot;
+		switch (ipsr->ri) {
+		      case 0:  slot = (bundle[0] >>  5); break;
+		      case 1:  slot = (bundle[0] >> 46) | (bundle[1] << 18); break;
+		      default: slot = (bundle[1] >> 23); break;
+		}
+		break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff);
+	}
+
 	/* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
 	siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
 	siginfo.si_imm = break_num;
@@ -202,13 +220,21 @@
 
 	/* first, grant user-level access to fph partition: */
 	psr->dfh = 0;
+
+	/*
+	 * Make sure that no other task gets in on this processor
+	 * while we're claiming the FPU
+	 */
+	preempt_disable();
 #ifndef CONFIG_SMP
 	{
 		struct task_struct *fpu_owner
 			= (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
 
-		if (ia64_is_local_fpu_owner(current))
+		if (ia64_is_local_fpu_owner(current)) {
+			preempt_enable_no_resched();
 			return;
+		}
 
 		if (fpu_owner)
 			ia64_flush_fph(fpu_owner);
@@ -226,6 +252,7 @@
 		 */
 		psr->mfh = 1;
 	}
+	preempt_enable_no_resched();
 }
 
 static inline int
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 547785e..4eb2f52 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -305,8 +305,9 @@
 	struct page *page;
 
 	/*
-	 * Map the gate page twice: once read-only to export the ELF headers etc. and once
-	 * execute-only page to enable privilege-promotion via "epc":
+	 * Map the gate page twice: once read-only to export the ELF
+	 * headers etc. and once execute-only page to enable
+	 * privilege-promotion via "epc":
 	 */
 	page = virt_to_page(ia64_imva(__start_gate_section));
 	put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
@@ -315,6 +316,20 @@
 	put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
 #else
 	put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
+	/* Fill in the holes (if any) with read-only zero pages: */
+	{
+		unsigned long addr;
+
+		for (addr = GATE_ADDR + PAGE_SIZE;
+		     addr < GATE_ADDR + PERCPU_PAGE_SIZE;
+		     addr += PAGE_SIZE)
+		{
+			put_kernel_page(ZERO_PAGE(0), addr,
+					PAGE_READONLY);
+			put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE,
+					PAGE_READONLY);
+		}
+	}
 #endif
 	ia64_patch_gate();
 }
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index e64cb81..44bfc7f 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -222,7 +222,7 @@
 
 extern int platform_intr_list[];
 extern nasid_t master_nasid;
-static int shub_1_1_found __initdata;
+static int __initdata shub_1_1_found = 0;
 
 /*
  * sn_check_for_wars
@@ -251,7 +251,7 @@
 	} else {
 		for_each_online_node(cnode) {
 			if (is_shub_1_1(cnodeid_to_nasid(cnode)))
-				sn_hub_info->shub_1_1_found = 1;
+				shub_1_1_found = 1;
 		}
 	}
 }
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
index 8aa5e8c..d44b7dc 100644
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/ppc/kernel/cputable.c
@@ -838,6 +838,17 @@
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 	},
+	{	/* 405EP */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x51210000,
+		.cpu_name		= "405EP",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB,
+		.cpu_user_features	= PPC_FEATURE_32 |
+			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+	},
 
 #endif /* CONFIG_40x */
 #ifdef CONFIG_44x
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index e4f1615..7329ef1 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -619,7 +619,7 @@
 _GLOBAL(flush_icache_range)
 BEGIN_FTR_SECTION
 	blr				/* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
 	li	r5,L1_CACHE_LINE_SIZE-1
 	andc	r3,r3,r5
 	subf	r4,r3,r4
@@ -736,7 +736,7 @@
 _GLOBAL(__flush_dcache_icache)
 BEGIN_FTR_SECTION
 	blr					/* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
 	rlwinm	r3,r3,0,0,19			/* Get page base address */
 	li	r4,4096/L1_CACHE_LINE_SIZE	/* Number of lines in a page */
 	mtctr	r4
@@ -764,7 +764,7 @@
 _GLOBAL(__flush_dcache_icache_phys)
 BEGIN_FTR_SECTION
 	blr					/* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
 	mfmsr	r10
 	rlwinm	r0,r10,0,28,26			/* clear DR */
 	mtmsr	r0
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index 937f46d..5fdd4f6 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -83,7 +83,7 @@
 static u32 slew_done_gpio;
 static int no_schedule;
 static int has_cpu_l2lve;
-
+static int is_pmu_based;
 
 /* There are only two frequency states for each processor. Values
  * are in kHz for the time being.
@@ -463,7 +463,7 @@
 	 */
 	no_schedule = 1;
 	sleep_freq = cur_freq;
-	if (cur_freq == low_freq)
+	if (cur_freq == low_freq && !is_pmu_based)
 		do_set_cpu_speed(CPUFREQ_HIGH, 0);
 	return 0;
 }
@@ -588,6 +588,7 @@
 		return 1;
 	hi_freq = (*value) / 1000;
 	set_speed_proc = pmu_set_cpu_speed;
+	is_pmu_based = 1;
 
 	return 0;
 }
@@ -692,6 +693,7 @@
 		hi_freq = cur_freq;
 		low_freq = 400000;
 		set_speed_proc = pmu_set_cpu_speed;
+		is_pmu_based = 1;
 	}
 	/* Else check for TiPb 400 & 500 */
 	else if (machine_is_compatible("PowerBook3,2")) {
@@ -703,6 +705,7 @@
 		hi_freq = cur_freq;
 		low_freq = 300000;
 		set_speed_proc = pmu_set_cpu_speed;
+		is_pmu_based = 1;
 	}
 	/* Else check for 750FX */
 	else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c
index 7b607d1..d5218b1 100644
--- a/arch/ppc64/boot/prom.c
+++ b/arch/ppc64/boot/prom.c
@@ -11,6 +11,23 @@
 #include <linux/string.h>
 #include <linux/ctype.h>
 
+extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor);
+
+/* The unnecessary pointer compare is there
+ * to check for type safety (n must be 64bit)
+ */
+# define do_div(n,base) ({				\
+	__u32 __base = (base);			\
+	__u32 __rem;					\
+	(void)(((typeof((n)) *)0) == ((unsigned long long *)0));	\
+	if (((n) >> 32) == 0) {			\
+		__rem = (__u32)(n) % __base;		\
+		(n) = (__u32)(n) / __base;		\
+	} else 						\
+		__rem = __div64_32(&(n), __base);	\
+	__rem;						\
+ })
+
 int (*prom)(void *);
 
 void *chosen_handle;
@@ -352,7 +369,7 @@
 #define SPECIAL	32		/* 0x */
 #define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
 
-static char * number(char * str, long num, int base, int size, int precision, int type)
+static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
 {
 	char c,sign,tmp[66];
 	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
@@ -367,9 +384,9 @@
 	c = (type & ZEROPAD) ? '0' : ' ';
 	sign = 0;
 	if (type & SIGN) {
-		if (num < 0) {
+		if ((signed long long)num < 0) {
 			sign = '-';
-			num = -num;
+			num = - (signed long long)num;
 			size--;
 		} else if (type & PLUS) {
 			sign = '+';
@@ -389,8 +406,7 @@
 	if (num == 0)
 		tmp[i++]='0';
 	else while (num != 0) {
-		tmp[i++] = digits[num % base];
-		num /= base;
+		tmp[i++] = digits[do_div(num, base)];
 	}
 	if (i > precision)
 		precision = i;
@@ -426,7 +442,7 @@
 int vsprintf(char *buf, const char *fmt, va_list args)
 {
 	int len;
-	unsigned long num;
+	unsigned long long num;
 	int i, base;
 	char * str;
 	const char *s;
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index 103daaf..e950a20 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -45,12 +45,17 @@
 
 int arch_prepare_kprobe(struct kprobe *p)
 {
+	int ret = 0;
 	kprobe_opcode_t insn = *p->addr;
 
-	if (IS_MTMSRD(insn) || IS_RFID(insn))
-		/* cannot put bp on RFID/MTMSRD */
-		return 1;
-	return 0;
+	if ((unsigned long)p->addr & 0x03) {
+		printk("Attempt to register kprobe at an unaligned address\n");
+		ret = -EINVAL;
+	} else if (IS_MTMSRD(insn) || IS_RFID(insn)) {
+		printk("Cannot register a kprobe on rfid or mtmsrd\n");
+		ret = -EINVAL;
+	}
+	return ret;
 }
 
 void arch_copy_kprobe(struct kprobe *p)
@@ -172,8 +177,6 @@
 	ret = emulate_step(regs, p->ainsn.insn[0]);
 	if (ret == 0)
 		regs->nip = (unsigned long)p->addr + 4;
-
-	regs->msr &= ~MSR_SE;
 }
 
 static inline int post_kprobe_handler(struct pt_regs *regs)
@@ -210,6 +213,7 @@
 
 	if (kprobe_status & KPROBE_HIT_SS) {
 		resume_execution(current_kprobe, regs);
+		regs->msr &= ~MSR_SE;
 		regs->msr |= kprobe_saved_msr;
 
 		unlock_kprobes();
@@ -233,8 +237,6 @@
 	 */
 	preempt_disable();
 	switch (val) {
-	case DIE_IABR_MATCH:
-	case DIE_DABR_MATCH:
 	case DIE_BPT:
 		if (kprobe_handler(args->regs))
 			ret = NOTIFY_STOP;
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index b944717..e3c73b3 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -792,7 +792,7 @@
 	.llong .compat_sys_newstat
 	.llong .compat_sys_newlstat
 	.llong .compat_sys_newfstat
-	.llong .sys_uname
+	.llong .sys32_uname
 	.llong .sys_ni_syscall		/* 110 old iopl syscall */
 	.llong .sys_vhangup
 	.llong .sys_ni_syscall		/* old idle syscall */
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 7cf7a96..9c8e317 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -791,31 +791,6 @@
 }
 
 
-asmlinkage int ppc64_newuname(struct new_utsname __user * name)
-{
-	int errno = sys_newuname(name);
-
-	if (current->personality == PER_LINUX32 && !errno) {
-		if(copy_to_user(name->machine, "ppc\0\0", 8)) {
-			errno = -EFAULT;
-		}
-	}
-	return errno;
-}
-
-asmlinkage int ppc64_personality(unsigned long personality)
-{
-	int ret;
-	if (current->personality == PER_LINUX32 && personality == PER_LINUX)
-		personality = PER_LINUX32;
-	ret = sys_personality(personality);
-	if (ret == PER_LINUX32)
-		ret = PER_LINUX;
-	return ret;
-}
-
-
-
 /* Note: it is necessary to treat mode as an unsigned int,
  * with the corresponding cast to a signed int to insure that the 
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -1158,26 +1133,47 @@
 }
 #endif
 
+asmlinkage int sys32_uname(struct old_utsname __user * name)
+{
+	int err = 0;
+	
+	down_read(&uts_sem);
+	if (copy_to_user(name, &system_utsname, sizeof(*name)))
+		err = -EFAULT;
+	up_read(&uts_sem);
+	if (!err && personality(current->personality) == PER_LINUX32) {
+		/* change "ppc64" to "ppc" */
+		if (__put_user(0, name->machine + 3)
+		    || __put_user(0, name->machine + 4))
+			err = -EFAULT;
+	}
+	return err;
+}
+
 asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
 {
 	int error;
-	
-	if (!name)
-		return -EFAULT;
+
 	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
 		return -EFAULT;
   
 	down_read(&uts_sem);
 	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
-	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
-	error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
-	error -= __put_user(0,name->release+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
-	error -= __put_user(0,name->version+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
-	error = __put_user(0,name->machine+__OLD_UTS_LEN);
+	error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
+	error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+	error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
+	error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+	error |= __put_user(0,name->release+__OLD_UTS_LEN);
+	error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+	error |= __put_user(0,name->version+__OLD_UTS_LEN);
+	error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+	error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+	if (personality(current->personality) == PER_LINUX32) {
+		/* change "ppc64" to "ppc" */
+		error |= __put_user(0, name->machine + 3);
+		error |= __put_user(0, name->machine + 4);
+	}
+	
 	up_read(&uts_sem);
 
 	error = error ? -EFAULT : 0;
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
index f2865ff..a8cbb20 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/ppc64/kernel/syscalls.c
@@ -199,24 +199,33 @@
 	return ret;
 }
 
-static int __init set_fakeppc(char *str)
+long ppc64_personality(unsigned long personality)
 {
-	if (*str)
-		return 0;
-	init_task.personality = PER_LINUX32;
-	return 1;
-}
-__setup("fakeppc", set_fakeppc);
+	long ret;
 
-asmlinkage int sys_uname(struct old_utsname __user * name)
+	if (personality(current->personality) == PER_LINUX32
+	    && personality == PER_LINUX)
+		personality = PER_LINUX32;
+	ret = sys_personality(personality);
+	if (ret == PER_LINUX32)
+		ret = PER_LINUX;
+	return ret;
+}
+
+long ppc64_newuname(struct new_utsname __user * name)
 {
-	int err = -EFAULT;
-	
+	int err = 0;
+
 	down_read(&uts_sem);
-	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
-		err = 0;
+	if (copy_to_user(name, &system_utsname, sizeof(*name)))
+		err = -EFAULT;
 	up_read(&uts_sem);
-	
+	if (!err && personality(current->personality) == PER_LINUX32) {
+		/* change ppc64 to ppc */
+		if (__put_user(0, name->machine + 3)
+		    || __put_user(0, name->machine + 4))
+			err = -EFAULT;
+	}
 	return err;
 }
 
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index 01ae196..c067435 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -28,6 +28,7 @@
 //#include <linux/kernel_stat.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
+#include <linux/workqueue.h>
 
 #include "appldata.h"
 
@@ -133,9 +134,12 @@
 static int appldata_timer_active;
 
 /*
- * Tasklet
+ * Work queue
  */
-static struct tasklet_struct appldata_tasklet_struct;
+static struct workqueue_struct *appldata_wq;
+static void appldata_work_fn(void *data);
+static DECLARE_WORK(appldata_work, appldata_work_fn, NULL);
+
 
 /*
  * Ops list
@@ -144,11 +148,11 @@
 static LIST_HEAD(appldata_ops_list);
 
 
-/************************* timer, tasklet, DIAG ******************************/
+/*************************** timer, work, DIAG *******************************/
 /*
  * appldata_timer_function()
  *
- * schedule tasklet and reschedule timer
+ * schedule work and reschedule timer
  */
 static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
 {
@@ -157,22 +161,22 @@
 		atomic_read(&appldata_expire_count));
 	if (atomic_dec_and_test(&appldata_expire_count)) {
 		atomic_set(&appldata_expire_count, num_online_cpus());
-		tasklet_schedule((struct tasklet_struct *) data);
+		queue_work(appldata_wq, (struct work_struct *) data);
 	}
 }
 
 /*
- * appldata_tasklet_function()
+ * appldata_work_fn()
  *
  * call data gathering function for each (active) module
  */
-static void appldata_tasklet_function(unsigned long data)
+static void appldata_work_fn(void *data)
 {
 	struct list_head *lh;
 	struct appldata_ops *ops;
 	int i;
 
-	P_DEBUG("  -= Tasklet =-\n");
+	P_DEBUG("  -= Work Queue =-\n");
 	i = 0;
 	spin_lock(&appldata_ops_lock);
 	list_for_each(lh, &appldata_ops_list) {
@@ -231,7 +235,7 @@
 			: "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc");
 	return (int) ry;
 }
-/********************** timer, tasklet, DIAG <END> ***************************/
+/************************ timer, work, DIAG <END> ****************************/
 
 
 /****************************** /proc stuff **********************************/
@@ -411,7 +415,7 @@
 	struct list_head *lh;
 
 	found = 0;
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	list_for_each(lh, &appldata_ops_list) {
 		tmp_ops = list_entry(lh, struct appldata_ops, list);
 		if (&tmp_ops->ctl_table[2] == ctl) {
@@ -419,15 +423,15 @@
 		}
 	}
 	if (!found) {
-		spin_unlock_bh(&appldata_ops_lock);
+		spin_unlock(&appldata_ops_lock);
 		return -ENODEV;
 	}
 	ops = ctl->data;
 	if (!try_module_get(ops->owner)) {	// protect this function
-		spin_unlock_bh(&appldata_ops_lock);
+		spin_unlock(&appldata_ops_lock);
 		return -ENODEV;
 	}
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 
 	if (!*lenp || *ppos) {
 		*lenp = 0;
@@ -451,10 +455,11 @@
 		return -EFAULT;
 	}
 
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	if ((buf[0] == '1') && (ops->active == 0)) {
-		if (!try_module_get(ops->owner)) {	// protect tasklet
-			spin_unlock_bh(&appldata_ops_lock);
+		// protect work queue callback
+		if (!try_module_get(ops->owner)) {
+			spin_unlock(&appldata_ops_lock);
 			module_put(ops->owner);
 			return -ENODEV;
 		}
@@ -485,7 +490,7 @@
 		}
 		module_put(ops->owner);
 	}
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 out:
 	*lenp = len;
 	*ppos += len;
@@ -529,7 +534,7 @@
 	}
 	memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table));
 
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	list_for_each(lh, &appldata_ops_list) {
 		tmp_ops = list_entry(lh, struct appldata_ops, list);
 		P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",
@@ -541,18 +546,18 @@
 				APPLDATA_PROC_NAME_LENGTH) == 0) {
 			P_ERROR("Name \"%s\" already registered!\n", ops->name);
 			kfree(ops->ctl_table);
-			spin_unlock_bh(&appldata_ops_lock);
+			spin_unlock(&appldata_ops_lock);
 			return -EBUSY;
 		}
 		if (tmp_ops->ctl_nr == ops->ctl_nr) {
 			P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);
 			kfree(ops->ctl_table);
-			spin_unlock_bh(&appldata_ops_lock);
+			spin_unlock(&appldata_ops_lock);
 			return -EBUSY;
 		}
 	}
 	list_add(&ops->list, &appldata_ops_list);
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 
 	ops->ctl_table[0].ctl_name = CTL_APPLDATA;
 	ops->ctl_table[0].procname = appldata_proc_name;
@@ -583,12 +588,12 @@
  */
 void appldata_unregister_ops(struct appldata_ops *ops)
 {
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	unregister_sysctl_table(ops->sysctl_header);
 	list_del(&ops->list);
 	kfree(ops->ctl_table);
 	ops->ctl_table = NULL;
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 	P_INFO("%s-ops unregistered!\n", ops->name);
 }
 /********************** module-ops management <END> **************************/
@@ -602,7 +607,7 @@
 	init_virt_timer(&per_cpu(appldata_timer, cpu));
 	per_cpu(appldata_timer, cpu).function = appldata_timer_function;
 	per_cpu(appldata_timer, cpu).data = (unsigned long)
-		&appldata_tasklet_struct;
+		&appldata_work;
 	atomic_inc(&appldata_expire_count);
 	spin_lock(&appldata_timer_lock);
 	__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
@@ -615,7 +620,7 @@
 	del_virt_timer(&per_cpu(appldata_timer, cpu));
 	if (atomic_dec_and_test(&appldata_expire_count)) {
 		atomic_set(&appldata_expire_count, num_online_cpus());
-		tasklet_schedule(&appldata_tasklet_struct);
+		queue_work(appldata_wq, &appldata_work);
 	}
 	spin_lock(&appldata_timer_lock);
 	__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
@@ -648,7 +653,7 @@
 /*
  * appldata_init()
  *
- * init timer and tasklet, register /proc entries
+ * init timer, register /proc entries
  */
 static int __init appldata_init(void)
 {
@@ -657,6 +662,12 @@
 	P_DEBUG("sizeof(parameter_list) = %lu\n",
 		sizeof(struct appldata_parameter_list));
 
+	appldata_wq = create_singlethread_workqueue("appldata");
+	if (!appldata_wq) {
+		P_ERROR("Could not create work queue\n");
+		return -ENOMEM;
+	}
+
 	for_each_online_cpu(i)
 		appldata_online_cpu(i);
 
@@ -670,7 +681,6 @@
 	appldata_table[1].de->owner = THIS_MODULE;
 #endif
 
-	tasklet_init(&appldata_tasklet_struct, appldata_tasklet_function, 0);
 	P_DEBUG("Base interface initialized.\n");
 	return 0;
 }
@@ -678,7 +688,7 @@
 /*
  * appldata_exit()
  *
- * stop timer and tasklet, unregister /proc entries
+ * stop timer, unregister /proc entries
  */
 static void __exit appldata_exit(void)
 {
@@ -690,7 +700,7 @@
 	/*
 	 * ops list should be empty, but just in case something went wrong...
 	 */
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	list_for_each(lh, &appldata_ops_list) {
 		ops = list_entry(lh, struct appldata_ops, list);
 		rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,
@@ -700,7 +710,7 @@
 				"return code: %d\n", ops->name, rc);
 		}
 	}
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 
 	for_each_online_cpu(i)
 		appldata_offline_cpu(i);
@@ -709,7 +719,7 @@
 
 	unregister_sysctl_table(appldata_sysctl_header);
 
-	tasklet_kill(&appldata_tasklet_struct);
+	destroy_workqueue(appldata_wq);
 	P_DEBUG("... module unloaded!\n");
 }
 /**************************** init / exit <END> ******************************/
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index 462ee9a..f0e2fbe 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -68,7 +68,7 @@
 	u64 pgmajfault;		/* page faults (major only) */
 // <-- New in 2.6
 
-} appldata_mem_data;
+} __attribute__((packed)) appldata_mem_data;
 
 
 static inline void appldata_debug_print(struct appldata_mem_data *mem_data)
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c
index dd61638..2a4c743 100644
--- a/arch/s390/appldata/appldata_net_sum.c
+++ b/arch/s390/appldata/appldata_net_sum.c
@@ -57,7 +57,7 @@
 	u64 rx_dropped;		/* no space in linux buffers     */
 	u64 tx_dropped;		/* no space available in linux   */
 	u64 collisions;		/* collisions while transmitting */
-} appldata_net_sum_data;
+} __attribute__((packed)) appldata_net_sum_data;
 
 
 static inline void appldata_print_debug(struct appldata_net_sum_data *net_data)
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index b83f074..e0a476b 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -49,7 +49,7 @@
 	u32 per_cpu_softirq;	/* ... spent in softirqs            */
 	u32 per_cpu_iowait;	/* ... spent while waiting for I/O  */
 // <-- New in 2.6
-};
+} __attribute__((packed));
 
 struct appldata_os_data {
 	u64 timestamp;
@@ -75,7 +75,7 @@
 
 	/* per cpu data */
 	struct appldata_os_per_cpu os_cpu[0];
-};
+} __attribute__((packed));
 
 static struct appldata_os_data *appldata_os_data;
 
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 2688936..06afa31 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -40,6 +40,7 @@
 #include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/unistd.h>
 
 #ifdef CONFIG_S390_SUPPORT
 #include "compat_ptrace.h"
@@ -130,13 +131,19 @@
 peek_user(struct task_struct *child, addr_t addr, addr_t data)
 {
 	struct user *dummy = NULL;
-	addr_t offset, tmp;
+	addr_t offset, tmp, mask;
 
 	/*
 	 * Stupid gdb peeks/pokes the access registers in 64 bit with
 	 * an alignment of 4. Programmers from hell...
 	 */
-	if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK)
+	mask = __ADDR_MASK;
+#ifdef CONFIG_ARCH_S390X
+	if (addr >= (addr_t) &dummy->regs.acrs &&
+	    addr < (addr_t) &dummy->regs.orig_gpr2)
+		mask = 3;
+#endif
+	if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
 		return -EIO;
 
 	if (addr < (addr_t) &dummy->regs.acrs) {
@@ -153,6 +160,16 @@
 		 * access registers are stored in the thread structure
 		 */
 		offset = addr - (addr_t) &dummy->regs.acrs;
+#ifdef CONFIG_ARCH_S390X
+		/*
+		 * Very special case: old & broken 64 bit gdb reading
+		 * from acrs[15]. Result is a 64 bit value. Read the
+		 * 32 bit acrs[15] value and shift it by 32. Sick...
+		 */
+		if (addr == (addr_t) &dummy->regs.acrs[15])
+			tmp = ((unsigned long) child->thread.acrs[15]) << 32;
+		else
+#endif
 		tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset);
 
 	} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
@@ -167,6 +184,9 @@
 		 */
 		offset = addr - (addr_t) &dummy->regs.fp_regs;
 		tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset);
+		if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
+			tmp &= (unsigned long) FPC_VALID_MASK
+				<< (BITS_PER_LONG - 32);
 
 	} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
 		/*
@@ -191,13 +211,19 @@
 poke_user(struct task_struct *child, addr_t addr, addr_t data)
 {
 	struct user *dummy = NULL;
-	addr_t offset;
+	addr_t offset, mask;
 
 	/*
 	 * Stupid gdb peeks/pokes the access registers in 64 bit with
 	 * an alignment of 4. Programmers from hell indeed...
 	 */
-	if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK)
+	mask = __ADDR_MASK;
+#ifdef CONFIG_ARCH_S390X
+	if (addr >= (addr_t) &dummy->regs.acrs &&
+	    addr < (addr_t) &dummy->regs.orig_gpr2)
+		mask = 3;
+#endif
+	if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
 		return -EIO;
 
 	if (addr < (addr_t) &dummy->regs.acrs) {
@@ -224,6 +250,17 @@
 		 * access registers are stored in the thread structure
 		 */
 		offset = addr - (addr_t) &dummy->regs.acrs;
+#ifdef CONFIG_ARCH_S390X
+		/*
+		 * Very special case: old & broken 64 bit gdb writing
+		 * to acrs[15] with a 64 bit value. Ignore the lower
+		 * half of the value and write the upper 32 bit to
+		 * acrs[15]. Sick...
+		 */
+		if (addr == (addr_t) &dummy->regs.acrs[15])
+			child->thread.acrs[15] = (unsigned int) (data >> 32);
+		else
+#endif
 		*(addr_t *)((addr_t) &child->thread.acrs + offset) = data;
 
 	} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
@@ -237,7 +274,8 @@
 		 * floating point regs. are stored in the thread structure
 		 */
 		if (addr == (addr_t) &dummy->regs.fp_regs.fpc &&
-		    (data & ~FPC_VALID_MASK) != 0)
+		    (data & ~((unsigned long) FPC_VALID_MASK
+			      << (BITS_PER_LONG - 32))) != 0)
 			return -EINVAL;
 		offset = addr - (addr_t) &dummy->regs.fp_regs;
 		*(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data;
@@ -723,6 +761,13 @@
 				 ? 0x80 : 0));
 
 	/*
+	 * If the debuffer has set an invalid system call number,
+	 * we prepare to skip the system call restart handling.
+	 */
+	if (!entryexit && regs->gprs[2] >= NR_syscalls)
+		regs->trap = -1;
+
+	/*
 	 * this isn't the same as continuing with a signal, but it will do
 	 * for normal use.  strace only continues with a signal if the
 	 * stopping signal is not SIGTRAP.  -brl
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 80306bc..75fde94 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -207,7 +207,7 @@
 	 * we are not in an interrupt and that there is a 
 	 * user context.
 	 */
-        if (user_address == 0 || in_interrupt() || !mm)
+        if (user_address == 0 || in_atomic() || !mm)
                 goto no_context;
 
 	/*
diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char
index 3e50fdb..62d87b7 100644
--- a/arch/um/Kconfig_char
+++ b/arch/um/Kconfig_char
@@ -204,5 +204,11 @@
 	http://sourceforge.net/projects/gkernel/).  rngd periodically reads
 	/dev/hwrng and injects the entropy into /dev/random.
 
+config MMAPPER
+	tristate "iomem emulation driver"
+	help
+	This driver allows a host file to be used as emulated IO memory inside
+	UML.
+
 endmenu
 
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 583b8e1..5d37681 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -143,22 +143,22 @@
 {
 	struct winch_data data;
 	unsigned long stack;
-	int fds[2], pid, n, err;
+	int fds[2], n, err;
 	char c;
 
 	err = os_pipe(fds, 1, 1);
 	if(err < 0){
 		printk("winch_tramp : os_pipe failed, err = %d\n", -err);
-		return(err);
+		goto out;
 	}
 
 	data = ((struct winch_data) { .pty_fd 		= fd,
 				      .pipe_fd 		= fds[1],
 				      .close_me 	= fds[0] } );
-	pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
-	if(pid < 0){
+	err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
+	if(err < 0){
 		printk("fork of winch_thread failed - errno = %d\n", errno);
-		return(pid);
+		goto out_close;
 	}
 
 	os_close_file(fds[1]);
@@ -168,14 +168,22 @@
 		printk("winch_tramp : failed to read synchronization byte\n");
 		printk("read failed, err = %d\n", -n);
 		printk("fd %d will not support SIGWINCH\n", fd);
-		*fd_out = -1;
+                err = -EINVAL;
+		goto out_close1;
 	}
-	return(pid);
+	return err ;
+
+ out_close:
+	os_close_file(fds[1]);
+ out_close1:
+	os_close_file(fds[0]);
+ out:
+	return err;
 }
 
 void register_winch(int fd, struct tty_struct *tty)
 {
-	int pid, thread, thread_fd;
+	int pid, thread, thread_fd = -1;
 	int count;
 	char c = 1;
 
@@ -186,7 +194,7 @@
 	if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
 			     tty) && (pid == -1)){
 		thread = winch_tramp(fd, tty, &thread_fd);
-		if(fd != -1){
+		if(thread > 0){
 			register_winch_irq(thread_fd, fd, thread, tty);
 
 			count = os_write_file(thread_fd, &c, sizeof(c));
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index a63231d..a37a5ac 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/init.h> 
 #include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
@@ -117,24 +118,39 @@
 	.release	= mmapper_release,
 };
 
+static struct miscdevice mmapper_dev = {
+	.minor		= MISC_DYNAMIC_MINOR,
+	.name		= "mmapper",
+	.fops		= &mmapper_fops
+};
+
 static int __init mmapper_init(void)
 {
+	int err;
+
 	printk(KERN_INFO "Mapper v0.1\n");
 
 	v_buf = (char *) find_iomem("mmapper", &mmapper_size);
 	if(mmapper_size == 0){
 		printk(KERN_ERR "mmapper_init - find_iomem failed\n");
-		return(0);
+		goto out;
+	}
+
+	err = misc_register(&mmapper_dev);
+	if(err){
+		printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
+		       err);
+		goto out;
 	}
 
 	p_buf = __pa(v_buf);
-
-	devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper");
-	return(0);
+out:
+	return 0;
 }
 
 static void mmapper_exit(void)
 {
+	misc_deregister(&mmapper_dev);
 }
 
 module_init(mmapper_init);
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 47229fe..3730d4f 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -32,7 +32,7 @@
 	return(0);
 }
 
-void tap_check_ips(char *gate_addr, char *eth_addr)
+void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
 {
 	int tap_addr[4];
 
diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h
index 495f2f1..d523618 100644
--- a/arch/um/drivers/slip.h
+++ b/arch/um/drivers/slip.h
@@ -12,8 +12,8 @@
 	char *addr;
 	char *gate_addr;
 	int slave;
-	char ibuf[ENC_BUF_SIZE];
-	char obuf[ENC_BUF_SIZE];
+	unsigned char ibuf[ENC_BUF_SIZE];
+	unsigned char obuf[ENC_BUF_SIZE];
 	int more; /* more data: do not read fd until ibuf has been drained */
 	int pos;
 	int esc;
diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_proto.h
index 7206361..4c4d94a 100644
--- a/arch/um/drivers/slip_proto.h
+++ b/arch/um/drivers/slip_proto.h
@@ -12,7 +12,8 @@
 #define SLIP_ESC_END         0334	/* ESC ESC_END means END 'data'	*/
 #define SLIP_ESC_ESC         0335	/* ESC ESC_ESC means ESC 'data'	*/
 
-static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
+static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos,
+                             int *esc)
 {
 	int ret;
 
diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h
index 04e407d..afa4e30 100644
--- a/arch/um/drivers/slirp.h
+++ b/arch/um/drivers/slirp.h
@@ -24,8 +24,8 @@
 	struct arg_list_dummy_wrapper argw;
 	int pid;
 	int slave;
-	char ibuf[ENC_BUF_SIZE];
-	char obuf[ENC_BUF_SIZE];
+	unsigned char ibuf[ENC_BUF_SIZE];
+	unsigned char obuf[ENC_BUF_SIZE];
 	int more; /* more data: do not read fd until ibuf has been drained */
 	int pos;
 	int esc;
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 98565b5..429ae8e 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -22,9 +22,9 @@
 }
 
 static struct console stderr_console = {
-	.name		"stderr",
-	.write		stderr_console_write,
-	.flags		CON_PRINTBUFFER,
+	.name		= "stderr",
+	.write		= stderr_console_write,
+	.flags		= CON_PRINTBUFFER,
 };
 
 static int __init stderr_console_init(void)
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 9fbe308..cfa368e 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -56,7 +56,7 @@
 	int as_interrupt;
 
 	int originating_fd;
-	int originlen;
+	unsigned int originlen;
 	unsigned char origin[128];			/* sockaddr_un */
 
 	struct mconsole_request request;
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 36807b7..89885a7 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -35,7 +35,7 @@
 extern void free_output_buffer(void *buffer);
 
 extern int tap_open_common(void *dev, char *gate_addr);
-extern void tap_check_ips(char *gate_addr, char *eth_addr);
+extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr);
 
 extern void read_output(int fd, char *output_out, int len);
 
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index d246d5a..881d298 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -136,7 +136,7 @@
 extern int os_open_file(char *file, struct openflags flags, int mode);
 extern int os_read_file(int fd, void *buf, int len);
 extern int os_write_file(int fd, const void *buf, int count);
-extern int os_file_size(char *file, long long *size_out);
+extern int os_file_size(char *file, unsigned long long *size_out);
 extern int os_file_modtime(char *file, unsigned long *modtime);
 extern int os_pipe(int *fd, int stream, int close_on_exec);
 extern int os_set_fd_async(int fd, int owner);
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index b8c5b8a..7b6a24d 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -41,9 +41,6 @@
 extern char host_info[];
 
 extern char saved_command_line[];
-extern char command_line[];
-
-extern char *tempdir;
 
 extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
 extern unsigned long _unprotected_end;
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index ab5d327..fc71ef2 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -68,8 +68,11 @@
 	 * 0 if it just exits
 	 */
 	n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
-	if(n == 1)
+	if(n == 1){
+		/* Handle any immediate reschedules or signals */
+		interrupt_end();
 		userspace(&current->thread.regs.regs);
+	}
 	else do_exit(0);
 }
 
@@ -96,6 +99,8 @@
 	schedule_tail(current->thread.prev_sched);
 	current->thread.prev_sched = NULL;
 
+	/* Handle any immediate reschedules or signals */
+	interrupt_end();
 	userspace(&current->thread.regs.regs);
 }
 
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index 9aee0b6..f0d6060 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -45,7 +45,11 @@
 				elf_aux_hwcap = auxv->a_un.a_val;
 				break;
 			case AT_PLATFORM:
-				elf_aux_platform = auxv->a_un.a_ptr;
+                                /* elf.h removed the pointer elements from
+                                 * a_un, so we have to use a_val, which is
+                                 * all that's left.
+                                 */
+				elf_aux_platform = (char *) auxv->a_un.a_val;
 				break;
 			case AT_PAGESZ:
 				page_size = auxv->a_un.a_val;
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 77d4066..fd45bb2 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -363,7 +363,7 @@
 		       (int (*)(int, void *, int)) write, copy_to_user_proc));
 }
 
-int os_file_size(char *file, long long *size_out)
+int os_file_size(char *file, unsigned long long *size_out)
 {
 	struct uml_stat buf;
 	int err;
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index a491f72..504e634 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -33,12 +33,10 @@
 
 int fix_aperture __initdata = 1;
 
-#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
+/* This code runs before the PCI subsystem is initialized, so just
+   access the northbridge directly. */
 
-static struct resource aper_res = {
-	.name = "Aperture",
-	.flags = IORESOURCE_MEM,
-};
+#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
 
 static u32 __init allocate_aperture(void) 
 {
@@ -55,24 +53,11 @@
 	aper_size = (32 * 1024 * 1024) << fallback_aper_order; 
 
 	/* 
-	 * Aperture has to be naturally aligned. This means an 2GB
-	 * aperture won't have much chances to find a place in the
-	 * lower 4GB of memory.  Unfortunately we cannot move it up
-	 * because that would make the IOMMU useless.
+	 * Aperture has to be naturally aligned. This means an 2GB aperture won't
+	 * have much chances to find a place in the lower 4GB of memory.
+	 * Unfortunately we cannot move it up because that would make the
+	 * IOMMU useless.
 	 */
-
-	/* First try to find some free unused space */
-	if (!allocate_resource(&iomem_resource, &aper_res,
-			       aper_size,
-			       0, 0xffffffff,
-			       aper_size,
-			       NULL, NULL)) {
-		printk(KERN_INFO "Putting aperture at %lx-%lx\n",
-		       aper_res.start, aper_res.end);
-		return aper_res.start;
-	}
-
-	/* No free space found. Go on to waste some memory... */
 	p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
 	if (!p || __pa(p)+aper_size > 0xffffffff) {
 		printk("Cannot allocate aperture memory hole (%p,%uK)\n",
@@ -81,7 +66,7 @@
 			free_bootmem_node(nd0, (unsigned long)p, aper_size); 
 		return 0;
 	}
-	printk("Mapping aperture over %d KB of precious RAM @ %lx\n",
+	printk("Mapping aperture over %d KB of RAM @ %lx\n",
 	       aper_size >> 10, __pa(p)); 
 	return (u32)__pa(p); 
 }
@@ -102,16 +87,10 @@
 		printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
 		return 0; 
 	} 
-	/* Don't check the resource here because the aperture is usually
-	   in an e820 reserved area, and we allocated these earlier. */
 	return 1;
 } 
 
-/*
- * Find a PCI capability.
- * This code runs before the PCI subsystem is initialized, so just
- * access the northbridge directly.
- */
+/* Find a PCI capability */
 static __u32 __init find_cap(int num, int slot, int func, int cap) 
 { 
 	u8 pos;
@@ -276,6 +255,8 @@
 		   fallback_aper_force) { 
 		printk("Your BIOS doesn't leave a aperture memory hole\n");
 		printk("Please enable the IOMMU option in the BIOS setup\n");
+		printk("This costs you %d MB of RAM\n",
+		       32 << fallback_aper_order);
 
 		aper_order = fallback_aper_order;
 		aper_alloc = allocate_aperture();
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index adc4dcc..19c5e59 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -51,7 +51,7 @@
  * This many LUNs per USB device.
  * Every one of them takes a host, see UB_MAX_HOSTS.
  */
-#define UB_MAX_LUNS   4
+#define UB_MAX_LUNS   9
 
 /*
  */
@@ -2100,7 +2100,7 @@
 			nluns = rc;
 			break;
 		}
-		mdelay(100);
+		msleep(100);
 	}
 
 	for (i = 0; i < nluns; i++) {
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index ad9c113..c1fe013 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -278,6 +278,8 @@
 #define AGP_GENERIC_SIZES_ENTRIES 11
 extern struct aper_size_info_16 agp3_generic_sizes[];
 
+#define virt_to_gart(x) (phys_to_gart(virt_to_phys(x)))
+#define gart_to_virt(x) (phys_to_virt(gart_to_phys(x)))
 
 extern int agp_off;
 extern int agp_try_unsupported_boot;
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 0212feb..9c9c9c2 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -150,7 +150,7 @@
 	pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
 	pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
 			(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
-			  virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN ));
+			  virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN ));
 	return addr;
 }
 
@@ -174,7 +174,7 @@
 	pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
 	pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
 			(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
-			  virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN));
+			  virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN));
 	agp_generic_destroy_page(addr);
 }
 
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index e62a3c2..3a41672 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -43,7 +43,7 @@
 
 	SetPageReserved(virt_to_page(page_map->real));
 	global_cache_flush();
-	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
+	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL) {
 		ClearPageReserved(virt_to_page(page_map->real));
@@ -154,7 +154,7 @@
 
 	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
 	agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
-	agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
+	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
@@ -167,7 +167,7 @@
 
 	/* Calculate the agp offset */
 	for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
-		writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1,
+		writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1,
 			page_dir.remapped+GET_PAGE_DIR_OFF(addr));
 		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 399c042..1407945 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -219,7 +219,7 @@
 
 static int amd_8151_configure(void)
 {
-	unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real);
+	unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real);
 
 	/* Configure AGP regs in each x86-64 host bridge. */
 	for_each_nb() {
@@ -591,7 +591,7 @@
 {
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 
-	release_mem_region(virt_to_phys(bridge->gatt_table_real),
+	release_mem_region(virt_to_gart(bridge->gatt_table_real),
 			   amd64_aperture_sizes[bridge->aperture_size_idx].size);
 	agp_remove_bridge(bridge);
 	agp_put_bridge(bridge);
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index a65f882..e572ced 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -61,7 +61,7 @@
 
 	SetPageReserved(virt_to_page(page_map->real));
 	err = map_page_into_agp(virt_to_page(page_map->real));
-	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
+	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL || err) {
 		ClearPageReserved(virt_to_page(page_map->real));
@@ -343,7 +343,7 @@
 
 	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
 	agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped;
-	agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real);
+	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
 
 	/* Write out the size register */
 	current_size = A_SIZE_LVL2(agp_bridge->current_size);
@@ -373,7 +373,7 @@
 
 	/* Calculate the agp offset */
 	for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
-		writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1,
+		writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1,
 			page_dir.remapped+GET_PAGE_DIR_OFF(addr));
 		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 2f3dfb6..4d4e602 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -148,7 +148,7 @@
 			return -ENOMEM;
 		}
 
-		bridge->scratch_page_real = virt_to_phys(addr);
+		bridge->scratch_page_real = virt_to_gart(addr);
 		bridge->scratch_page =
 		    bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0);
 	}
@@ -189,7 +189,7 @@
 err_out:
 	if (bridge->driver->needs_scratch_page)
 		bridge->driver->agp_destroy_page(
-				phys_to_virt(bridge->scratch_page_real));
+				gart_to_virt(bridge->scratch_page_real));
 	if (got_gatt)
 		bridge->driver->free_gatt_table(bridge);
 	if (got_keylist) {
@@ -214,7 +214,7 @@
 	if (bridge->driver->agp_destroy_page &&
 	    bridge->driver->needs_scratch_page)
 		bridge->driver->agp_destroy_page(
-				phys_to_virt(bridge->scratch_page_real));
+				gart_to_virt(bridge->scratch_page_real));
 }
 
 /* When we remove the global variable agp_bridge from all drivers
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 1383c31..ac19fdc 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -219,7 +219,7 @@
 
 		efficeon_private.l1_table[index] = page;
 
-		value = __pa(page) | pati | present | index;
+		value = virt_to_gart(page) | pati | present | index;
 
 		pci_write_config_dword(agp_bridge->dev,
 			EFFICEON_ATTPAGE, value);
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index c321a92..f0079e9 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -153,7 +153,7 @@
 	}
 	if (curr->page_count != 0) {
 		for (i = 0; i < curr->page_count; i++) {
-			curr->bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i]));
+			curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
 		}
 	}
 	agp_free_key(curr->key);
@@ -209,7 +209,7 @@
 			agp_free_memory(new);
 			return NULL;
 		}
-		new->memory[i] = virt_to_phys(addr);
+		new->memory[i] = virt_to_gart(addr);
 		new->page_count++;
 	}
        new->bridge = bridge;
@@ -295,19 +295,6 @@
 EXPORT_SYMBOL_GPL(agp_num_entries);
 
 
-static int check_bridge_mode(struct pci_dev *dev)
-{
-	u32 agp3;
-	u8 cap_ptr;
-
-	cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
-	pci_read_config_dword(dev, cap_ptr+AGPSTAT, &agp3);
-	if (agp3 & AGPSTAT_MODE_3_0)
-		return 1;
-	return 0;
-}
-
-
 /**
  *	agp_copy_info  -  copy bridge state information
  *
@@ -328,7 +315,7 @@
 	info->version.minor = bridge->version->minor;
 	info->chipset = SUPPORTED;
 	info->device = bridge->dev;
-	if (check_bridge_mode(bridge->dev))
+	if (bridge->mode & AGPSTAT_MODE_3_0)
 		info->mode = bridge->mode & ~AGP3_RESERVED_MASK;
 	else
 		info->mode = bridge->mode & ~AGP2_RESERVED_MASK;
@@ -661,7 +648,7 @@
 		bridge_agpstat &= ~AGPSTAT_FW;
 
 	/* Check to see if we are operating in 3.0 mode */
-	if (check_bridge_mode(agp_bridge->dev))
+	if (agp_bridge->mode & AGPSTAT_MODE_3_0)
 		agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);
 	else
 		agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);
@@ -732,7 +719,7 @@
 
 	/* Do AGP version specific frobbing. */
 	if (bridge->major_version >= 3) {
-		if (check_bridge_mode(bridge->dev)) {
+		if (bridge->mode & AGPSTAT_MODE_3_0) {
 			/* If we have 3.5, we can do the isoch stuff. */
 			if (bridge->minor_version >= 5)
 				agp_3_5_enable(bridge);
@@ -806,8 +793,7 @@
 				break;
 			}
 
-			table = (char *) __get_free_pages(GFP_KERNEL,
-							  page_order);
+			table = alloc_gatt_pages(page_order);
 
 			if (table == NULL) {
 				i++;
@@ -838,7 +824,7 @@
 		size = ((struct aper_size_info_fixed *) temp)->size;
 		page_order = ((struct aper_size_info_fixed *) temp)->page_order;
 		num_entries = ((struct aper_size_info_fixed *) temp)->num_entries;
-		table = (char *) __get_free_pages(GFP_KERNEL, page_order);
+		table = alloc_gatt_pages(page_order);
 	}
 
 	if (table == NULL)
@@ -853,7 +839,7 @@
 	agp_gatt_table = (void *)table;
 
 	bridge->driver->cache_flush();
-	bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
+	bridge->gatt_table = ioremap_nocache(virt_to_gart(table),
 					(PAGE_SIZE * (1 << page_order)));
 	bridge->driver->cache_flush();
 
@@ -861,11 +847,11 @@
 		for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
 			ClearPageReserved(page);
 
-		free_pages((unsigned long) table, page_order);
+		free_gatt_pages(table, page_order);
 
 		return -ENOMEM;
 	}
-	bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real);
+	bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real);
 
 	/* AK: bogus, should encode addresses > 4GB */
 	for (i = 0; i < num_entries; i++) {
@@ -919,7 +905,7 @@
 	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
 		ClearPageReserved(page);
 
-	free_pages((unsigned long) bridge->gatt_table_real, page_order);
+	free_gatt_pages(bridge->gatt_table_real, page_order);
 
 	agp_gatt_table = NULL;
 	bridge->gatt_table = NULL;
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 6052bfa..99762b6 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -110,7 +110,7 @@
 	hp->gart_size = HP_ZX1_GART_SIZE;
 	hp->gatt_entries = hp->gart_size / hp->io_page_size;
 
-	hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
+	hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
 	hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 
 	if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
@@ -248,7 +248,7 @@
 	agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
 
 	if (hp->io_pdir_owner) {
-		writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
+		writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
 		readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
 		writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
 		readl(hp->ioc_regs+HP_ZX1_TCNFG);
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index adbea89..9494329 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -372,7 +372,7 @@
 	}
 	memset(lp->alloced_map, 0, map_size);
 
-	lp->paddr = virt_to_phys(lpage);
+	lp->paddr = virt_to_gart(lpage);
 	lp->refcount = 0;
 	atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 	return 0;
@@ -383,7 +383,7 @@
 	kfree(lp->alloced_map);
 	lp->alloced_map = NULL;
 
-	free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
+	free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
 	atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 }
 
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 8c7d727..51266d6 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -286,7 +286,7 @@
 	if (new == NULL)
 		return NULL;
 
-	new->memory[0] = virt_to_phys(addr);
+	new->memory[0] = virt_to_gart(addr);
 	if (pg_count == 4) {
 		/* kludge to get 4 physical pages for ARGB cursor */
 		new->memory[1] = new->memory[0] + PAGE_SIZE;
@@ -329,10 +329,10 @@
 	agp_free_key(curr->key);
 	if(curr->type == AGP_PHYS_MEMORY) {
 		if (curr->page_count == 4)
-			i8xx_destroy_pages(phys_to_virt(curr->memory[0]));
+			i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
 		else
 			agp_bridge->driver->agp_destroy_page(
-				 phys_to_virt(curr->memory[0]));
+				 gart_to_virt(curr->memory[0]));
 		vfree(curr->memory);
 	}
 	kfree(curr);
@@ -418,7 +418,8 @@
 		case I915_GMCH_GMS_STOLEN_48M:
 			/* Check it's really I915G */
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
-			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB)
 				gtt_entries = MB(48) - KB(size);
 			else
 				gtt_entries = 0;
@@ -426,7 +427,8 @@
 		case I915_GMCH_GMS_STOLEN_64M:
 			/* Check it's really I915G */
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
-			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB)
 				gtt_entries = MB(64) - KB(size);
 			else
 				gtt_entries = 0;
@@ -1662,6 +1664,14 @@
 		}
 		name = "915GM";
 		break;
+	case PCI_DEVICE_ID_INTEL_82945G_HB:
+		if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG)) {
+			bridge->driver = &intel_915_driver;
+		} else {
+			bridge->driver = &intel_845_driver;
+		}
+		name = "945G";
+		break;
 	case PCI_DEVICE_ID_INTEL_7505_0:
 		bridge->driver = &intel_7505_driver;
 		name = "E7505";
@@ -1801,6 +1811,7 @@
 	ID(PCI_DEVICE_ID_INTEL_7205_0),
 	ID(PCI_DEVICE_ID_INTEL_82915G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
+	ID(PCI_DEVICE_ID_INTEL_82945G_HB),
 	{ }
 };
 
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 4b3eda2..d3aa159 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -133,11 +133,14 @@
 	off_t j;
 	void *temp;
 	struct agp_bridge_data *bridge;
+	u64 *table;
 
 	bridge = mem->bridge;
 	if (!bridge)
 		return -EINVAL;
 
+	table = (u64 *)bridge->gatt_table;
+
 	temp = bridge->current_size;
 
 	switch (bridge->driver->size_type) {
@@ -175,7 +178,7 @@
 	j = pg_start;
 
 	while (j < (pg_start + mem->page_count)) {
-		if (*(bridge->gatt_table + j))
+		if (table[j])
 			return -EBUSY;
 		j++;
 	}
@@ -186,7 +189,7 @@
 	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		*(bridge->gatt_table + j) =
+		table[j] =
 		    bridge->driver->mask_memory(bridge, mem->memory[i],
 						mem->type);
 	}
@@ -200,6 +203,7 @@
 {
 	size_t i;
 	struct agp_bridge_data *bridge;
+	u64 *table;
 
 	bridge = mem->bridge;
 	if (!bridge)
@@ -209,8 +213,10 @@
 		return -EINVAL;
 	}
 
+	table = (u64 *)bridge->gatt_table;
+
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		*(bridge->gatt_table + i) = 0;
+		table[i] = 0;
 	}
 
 	bridge->driver->tlb_flush(mem);
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 10c2330..a9fb12c 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -51,7 +51,7 @@
 	}
 	SetPageReserved(virt_to_page(page_map->real));
 	global_cache_flush();
-	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), 
+	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL) {
 		ClearPageReserved(virt_to_page(page_map->real));
@@ -162,7 +162,7 @@
 	/* Create a fake scratch directory */
 	for(i = 0; i < 1024; i++) {
 		writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i);
-		writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
+		writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
 	}
 
 	retval = serverworks_create_gatt_pages(value->num_entries / 1024);
@@ -174,7 +174,7 @@
 
 	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
 	agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
-	agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
+	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
@@ -187,7 +187,7 @@
 	/* Calculate the agp offset */	
 
 	for(i = 0; i < value->num_entries / 1024; i++)
-		writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);
+		writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);
 
 	return 0;
 }
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index a673971..c825531 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -407,7 +407,7 @@
 
 	bridge->gatt_table_real = (u32 *) table;
 	bridge->gatt_table = (u32 *)table;
-	bridge->gatt_bus_addr = virt_to_phys(table);
+	bridge->gatt_bus_addr = virt_to_gart(table);
 
 	for (i = 0; i < num_entries; i++)
 		bridge->gatt_table[i] = 0;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 7a24506..f022f09 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1995,9 +1995,6 @@
 	unsigned char ch, gdl;
 	int ignored = 0;
 	int cnt = 0;
-	unsigned char *cp;
-	char *fp;
-	int count;
 	int recv_room;
 	int max = 256;
 	unsigned long flags;
@@ -2011,10 +2008,6 @@
 		//return;
 	}
 
-	cp = tty->flip.char_buf;
-	fp = tty->flip.flag_buf;
-	count = 0;
-
 	// following add by Victor Yu. 09-02-2002
 	if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {
 
@@ -2041,12 +2034,10 @@
 		}
 		while (gdl--) {
 			ch = inb(info->base + UART_RX);
-			count++;
-			*cp++ = ch;
-			*fp++ = 0;
+			tty_insert_flip_char(tty, ch, 0);
 			cnt++;
 			/*
-			   if((count>=HI_WATER) && (info->stop_rx==0)){
+			   if((cnt>=HI_WATER) && (info->stop_rx==0)){
 			   mxser_stoprx(tty);
 			   info->stop_rx=1;
 			   break;
@@ -2061,7 +2052,7 @@
 		if (max-- < 0)
 			break;
 		/*
-		   if((count>=HI_WATER) && (info->stop_rx==0)){
+		   if((cnt>=HI_WATER) && (info->stop_rx==0)){
 		   mxser_stoprx(tty);
 		   info->stop_rx=1;
 		   break;
@@ -2078,36 +2069,33 @@
 			if (++ignored > 100)
 				break;
 		} else {
-			count++;
+			char flag = 0;
 			if (*status & UART_LSR_SPECIAL) {
 				if (*status & UART_LSR_BI) {
-					*fp++ = TTY_BREAK;
+					flag = TTY_BREAK;
 /* added by casper 1/11/2000 */
 					info->icount.brk++;
-
 /* */
 					if (info->flags & ASYNC_SAK)
 						do_SAK(tty);
 				} else if (*status & UART_LSR_PE) {
-					*fp++ = TTY_PARITY;
+					flag = TTY_PARITY;
 /* added by casper 1/11/2000 */
 					info->icount.parity++;
 /* */
 				} else if (*status & UART_LSR_FE) {
-					*fp++ = TTY_FRAME;
+					flag = TTY_FRAME;
 /* added by casper 1/11/2000 */
 					info->icount.frame++;
 /* */
 				} else if (*status & UART_LSR_OE) {
-					*fp++ = TTY_OVERRUN;
+					flag = TTY_OVERRUN;
 /* added by casper 1/11/2000 */
 					info->icount.overrun++;
 /* */
-				} else
-					*fp++ = 0;
-			} else
-				*fp++ = 0;
-			*cp++ = ch;
+				}
+			}
+			tty_insert_flip_char(tty, ch, flag);
 			cnt++;
 			if (cnt >= recv_room) {
 				if (!info->ldisc_stop_rx) {
@@ -2132,13 +2120,13 @@
 		// above add by Victor Yu. 09-02-2002
 	} while (*status & UART_LSR_DR);
 
-      end_intr:		// add by Victor Yu. 09-02-2002
+end_intr:		// add by Victor Yu. 09-02-2002
 
 	mxvar_log.rxcnt[info->port] += cnt;
 	info->mon_data.rxcnt += cnt;
 	info->mon_data.up_rxcnt += cnt;
 	spin_unlock_irqrestore(&info->slock, flags);
-	
+
 	tty_flip_buffer_push(tty);
 }
 
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index af0446c..48fdf1e5 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -54,7 +54,7 @@
 module_param_named(softraw, atkbd_softraw, bool, 0);
 MODULE_PARM_DESC(softraw, "Use software generated rawmode");
 
-static int atkbd_scroll = 1;
+static int atkbd_scroll = 0;
 module_param_named(scroll, atkbd_scroll, bool, 0);
 MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
 
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index bb9f404..b941ee2 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -2593,6 +2593,9 @@
 	/* Restore VIA */
 	restore_via_state();
 
+	/* tweak LPJ before cpufreq is there */
+	loops_per_jiffy *= 2;
+
 	/* Restore video */
 	pmac_call_early_video_resume();
 
@@ -2613,6 +2616,9 @@
 	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
 	pmu_wait_complete(&req);
 
+	/* Restore LPJ, cpufreq will adjust the cpu frequency */
+	loops_per_jiffy /= 2;
+
 	pmac_wakeup_devices();
 
 	return 0;
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 1e97b3c..0c1b852 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -985,6 +985,9 @@
 	if (!error)
 		return 0;	/* I/O complete */
 
+	if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio))
+		return error;
+
 	spin_lock(&m->lock);
 	if (!m->nr_valid_paths) {
 		if (!m->queue_if_no_path || m->suspended) {
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 13ed8dc..55af32e 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -802,13 +802,14 @@
 
 	spin_lock_irqsave(&port->pending_gate, flags);
 
+	if (!port->pending_lpmask) {
+		spin_unlock_irqrestore(&port->pending_gate, flags);
+		return;
+	}
+
 	printk(KERN_WARNING "%s: Tx timeout!  Resetting lp connections: %08x\n",
 	       dev->name, port->pending_lpmask);
 
-	/* If we've timed out the queue must be stopped, which should
-	 * only ever happen when there is a pending packet. */
-	WARN_ON(! port->pending_lpmask);
-
 	for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
 		struct veth_lpar_connection *cnx = veth_cnx[i];
 
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 41e51711..c6e8b25f 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -1274,6 +1274,9 @@
 		spin_lock_irqsave(&lp->window_lock, flags);
 		update_stats(dev);
 		spin_unlock_irqrestore(&lp->window_lock, flags);
+
+		/* force interrupts off */
+		outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
 	}
 
 	link->open--;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index c59507f..b3768d8 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1585,8 +1585,8 @@
 	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 	RTL_W8(EarlyTxThres, EarlyTxThld);
 
-	/* For gigabit rtl8169, MTU + header + CRC + VLAN */
-	RTL_W16(RxMaxSize, tp->rx_buf_sz);
+	/* Low hurts. Let's disable the filtering. */
+	RTL_W16(RxMaxSize, 16383);
 
 	/* Set Rx Config register */
 	i = rtl8169_rx_config |
@@ -2127,6 +2127,11 @@
 	}
 }
 
+static inline int rtl8169_fragmented_frame(u32 status)
+{
+	return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag);
+}
+
 static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
 {
 	u32 opts1 = le32_to_cpu(desc->opts1);
@@ -2177,27 +2182,41 @@
 
 	while (rx_left > 0) {
 		unsigned int entry = cur_rx % NUM_RX_DESC;
+		struct RxDesc *desc = tp->RxDescArray + entry;
 		u32 status;
 
 		rmb();
-		status = le32_to_cpu(tp->RxDescArray[entry].opts1);
+		status = le32_to_cpu(desc->opts1);
 
 		if (status & DescOwn)
 			break;
 		if (status & RxRES) {
-			printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);
+			printk(KERN_INFO "%s: Rx ERROR. status = %08x\n",
+			       dev->name, status);
 			tp->stats.rx_errors++;
 			if (status & (RxRWT | RxRUNT))
 				tp->stats.rx_length_errors++;
 			if (status & RxCRC)
 				tp->stats.rx_crc_errors++;
+			rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
 		} else {
-			struct RxDesc *desc = tp->RxDescArray + entry;
 			struct sk_buff *skb = tp->Rx_skbuff[entry];
 			int pkt_size = (status & 0x00001FFF) - 4;
 			void (*pci_action)(struct pci_dev *, dma_addr_t,
 				size_t, int) = pci_dma_sync_single_for_device;
 
+			/*
+			 * The driver does not support incoming fragmented
+			 * frames. They are seen as a symptom of over-mtu
+			 * sized frames.
+			 */
+			if (unlikely(rtl8169_fragmented_frame(status))) {
+				tp->stats.rx_dropped++;
+				tp->stats.rx_length_errors++;
+				rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
+				goto move_on;
+			}
+
 			rtl8169_rx_csum(skb, desc);
 			
 			pci_dma_sync_single_for_cpu(tp->pci_dev,
@@ -2224,7 +2243,7 @@
 			tp->stats.rx_bytes += pkt_size;
 			tp->stats.rx_packets++;
 		}
-		
+move_on:		
 		cur_rx++; 
 		rx_left--;
 	}
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index fc9b5cd..a0b8848 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7,7 +7,12 @@
  * Copyright (C) 2005 Broadcom Corporation.
  *
  * Firmware is:
- * 	Copyright (C) 2000-2003 Broadcom Corporation.
+ *	Derived from proprietary unpublished source code,
+ *	Copyright (C) 2000-2003 Broadcom Corporation.
+ *
+ *	Permission is hereby granted for the distribution of this firmware
+ *	data in hexadecimal or equivalent format, provided this copyright
+ *	notice is accompanying it.
  */
 
 #include <linux/config.h>
@@ -61,8 +66,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.29"
-#define DRV_MODULE_RELDATE	"May 23, 2005"
+#define DRV_MODULE_VERSION	"3.31"
+#define DRV_MODULE_RELDATE	"June 8, 2005"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -8555,6 +8560,16 @@
 
 		case NIC_SRAM_DATA_CFG_LED_MODE_MAC:
 			tp->led_ctrl = LED_CTRL_MODE_MAC;
+
+			/* Default to PHY_1_MODE if 0 (MAC_MODE) is
+			 * read on some older 5700/5701 bootcode.
+			 */
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+			    ASIC_REV_5700 ||
+			    GET_ASIC_REV(tp->pci_chip_rev_id) ==
+			    ASIC_REV_5701)
+				tp->led_ctrl = LED_CTRL_MODE_PHY_1;
+
 			break;
 
 		case SHASTA_EXT_LED_SHARED:
@@ -9680,10 +9695,24 @@
 	}
 	if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) !=
 	    DMA_RWCTRL_WRITE_BNDRY_16) {
+		static struct pci_device_id dma_wait_state_chipsets[] = {
+			{ PCI_DEVICE(PCI_VENDOR_ID_APPLE,
+				     PCI_DEVICE_ID_APPLE_UNI_N_PCI15) },
+			{ },
+		};
+
 		/* DMA test passed without adjusting DMA boundary,
-		 * just restore the calculated DMA boundary
+		 * now look for chipsets that are known to expose the
+		 * DMA bug without failing the test.
 		 */
-		tp->dma_rwctrl = saved_dma_rwctrl;
+		if (pci_dev_present(dma_wait_state_chipsets)) {
+			tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK;
+			tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16;
+		}
+		else
+			/* Safe to use the calculated DMA boundary. */
+			tp->dma_rwctrl = saved_dma_rwctrl;
+
 		tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
 	}
 
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index 8132d94..30af105 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -217,6 +217,8 @@
 	kfree(slot->hotplug_slot->info);
 	kfree(slot->hotplug_slot->name);
 	kfree(slot->hotplug_slot);
+	if (slot->dev)
+		pci_dev_put(slot->dev);
 	kfree(slot);
 }
 
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index c878028..225b5e5 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -315,9 +315,12 @@
 				    PCI_DEVFN(PCI_SLOT(slot->devfn), i));
 		if (dev) {
 			pci_remove_bus_device(dev);
-			slot->dev = NULL;
+			pci_dev_put(dev);
 		}
 	}
+	pci_dev_put(slot->dev);
+	slot->dev = NULL;
+
 	dbg("%s - exit", __FUNCTION__);
 	return 0;
 }
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
index 93481b4..1d2ef1e 100644
--- a/drivers/pci/pci.ids
+++ b/drivers/pci/pci.ids
@@ -7173,6 +7173,7 @@
 	080f  Sentry5 DDR/SDR RAM Controller
 	0811  Sentry5 External Interface Core
 	0816  BCM3302 Sentry5 MIPS32 CPU
+	1600  NetXtreme BCM5752 Gigabit Ethernet PCI Express
 	1644  NetXtreme BCM5700 Gigabit Ethernet
 		1014 0277  Broadcom Vigil B5700 1000Base-T
 		1028 00d1  Broadcom BCM5700
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 637e949..968033f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -456,21 +456,16 @@
 } 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC,         quirk_amd_8131_ioapic ); 
 
+static void __init quirk_svw_msi(struct pci_dev *dev)
+{
+	pci_msi_quirk = 1;
+	printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n");
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi );
 #endif /* CONFIG_X86_IO_APIC */
 
 
 /*
- * 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.
- */
-
-/*
  * FIXME: it is questionable that quirk_via_acpi
  * is needed.  It shows up as an ISA bridge, and does not
  * support the PCI_INTERRUPT_LINE register at all.  Therefore
@@ -492,28 +487,30 @@
 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 );
 
-static void quirk_via_irqpic(struct pci_dev *dev)
+/*
+ * 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.
+ */
+static void quirk_via_irq(struct pci_dev *dev)
 {
 	u8 irq, new_irq;
 
-#ifdef CONFIG_X86_IO_APIC
-	if (nr_ioapics && !skip_ioapic_setup)
-		return;
-#endif
-#ifdef CONFIG_ACPI
-	if (acpi_irq_model != ACPI_IRQ_MODEL_PIC)
-		return;
-#endif
 	new_irq = dev->irq & 0xf;
 	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
 	if (new_irq != irq) {
-		printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n",
+		printk(KERN_INFO "PCI: Via 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_irqpic);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
 
 /*
  * PIIX3 USB: We have to disable USB interrupts that are
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 21d194c..9e58f13 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2577,7 +2577,6 @@
 next_sg:
 	sg = &qc->sg[qc->cursg];
 
-next_page:
 	page = sg->page;
 	offset = sg->offset + qc->cursg_ofs;
 
@@ -2585,6 +2584,7 @@
 	page = nth_page(page, (offset >> PAGE_SHIFT));
 	offset %= PAGE_SIZE;
 
+	/* don't overrun current sg */
 	count = min(sg->length - qc->cursg_ofs, bytes);
 
 	/* don't cross page boundaries */
@@ -2609,8 +2609,6 @@
 	kunmap(page);
 
 	if (bytes) {
-		if (qc->cursg_ofs < sg->length)
-			goto next_page;
 		goto next_sg;
 	}
 }
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 238580d..49ed557 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -432,7 +432,13 @@
 		writeb(cls, mmio_base + SIL_FIFO_R0);
 		writeb(cls, mmio_base + SIL_FIFO_W0);
 		writeb(cls, mmio_base + SIL_FIFO_R1);
-		writeb(cls, mmio_base + SIL_FIFO_W2);
+		writeb(cls, mmio_base + SIL_FIFO_W1);
+		if (ent->driver_data == sil_3114) {
+			writeb(cls, mmio_base + SIL_FIFO_R2);
+			writeb(cls, mmio_base + SIL_FIFO_W2);
+			writeb(cls, mmio_base + SIL_FIFO_R3);
+			writeb(cls, mmio_base + SIL_FIFO_W3);
+		}
 	} else
 		printk(KERN_WARNING DRV_NAME "(%s): cache line size not set.  Driver may not function\n",
 			pci_name(pdev));
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 22565a6..98641c3 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -197,7 +197,7 @@
 sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
 {
 	struct tty_struct *tty = sport->port.info->tty;
-	unsigned int status, ch, flg, ignored = 0;
+	unsigned int status, ch, flg;
 
 	status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
 		 UTSR0_TO_SM(UART_GET_UTSR0(sport));
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 5d2ceb6..1f98532 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -234,7 +234,7 @@
 		return "DSIU";
 	}
 
-	return "unknown";
+	return NULL;
 }
 
 static unsigned int siu_tx_empty(struct uart_port *port)
@@ -482,9 +482,6 @@
 	struct uart_port *port;
 	uint8_t iir, lsr;
 
-	if (dev_id == NULL)
-		return IRQ_NONE;
-
 	port = (struct uart_port *)dev_id;
 
 	iir = siu_read(port, UART_IIR);
@@ -507,6 +504,9 @@
 {
 	int retval;
 
+	if (port->membase == NULL)
+		return -ENODEV;
+
 	siu_clear_fifo(port);
 
 	(void)siu_read(port, UART_LSR);
@@ -545,9 +545,6 @@
 	unsigned long flags;
 	uint8_t lcr;
 
-	if (port->membase == NULL)
-		return;
-
 	siu_write(port, UART_IER, 0);
 
 	spin_lock_irqsave(&port->lock, flags);
@@ -802,53 +799,6 @@
 
 #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
 
-static void early_set_termios(struct uart_port *port, struct termios *new,
-                              struct termios *old)
-{
-	tcflag_t c_cflag;
-	uint8_t lcr;
-	unsigned int baud, quot;
-
-	c_cflag = new->c_cflag;
-	switch (c_cflag & CSIZE) {
-	case CS5:
-		lcr = UART_LCR_WLEN5;
-		break;
-	case CS6:
-		lcr = UART_LCR_WLEN6;
-		break;
-	case CS7:
-		lcr = UART_LCR_WLEN7;
-		break;
-	default:
-		lcr = UART_LCR_WLEN8;
-		break;
-	}
-
-	if (c_cflag & CSTOPB)
-		lcr |= UART_LCR_STOP;
-	if (c_cflag & PARENB)
-		lcr |= UART_LCR_PARITY;
-	if ((c_cflag & PARODD) != PARODD)
-		lcr |= UART_LCR_EPAR;
-	if (c_cflag & CMSPAR)
-		lcr |= UART_LCR_SPAR;
-
-	baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
-	quot = uart_get_divisor(port, baud);
-
-	siu_write(port, UART_LCR, lcr | UART_LCR_DLAB);
-
-	siu_write(port, UART_DLL, (uint8_t)quot);
-	siu_write(port, UART_DLM, (uint8_t)(quot >> 8));
-
-	siu_write(port, UART_LCR, lcr);
-}
-
-static struct uart_ops early_uart_ops = {
-	.set_termios	= early_set_termios,
-};
-
 #define BOTH_EMPTY	(UART_LSR_TEMT | UART_LSR_THRE)
 
 static void wait_for_xmitr(struct uart_port *port)
@@ -915,7 +865,7 @@
 	if (port->membase == NULL) {
 		if (port->mapbase == 0)
 			return -ENODEV;
-		port->membase = (unsigned char __iomem *)KSEG1ADDR(port->mapbase);
+		port->membase = ioremap(port->mapbase, siu_port_size(port));
 	}
 
 	vr41xx_select_siu_interface(SIU_INTERFACE_RS232C);
@@ -949,7 +899,7 @@
 
 	for (i = 0; i < num; i++) {
 		port = &siu_uart_ports[i];
-		port->ops = &early_uart_ops;
+		port->ops = &siu_uart_ops;
 	}
 
 	register_console(&siu_console);
@@ -994,8 +944,10 @@
 		port->dev = dev;
 
 		retval = uart_add_one_port(&siu_uart_driver, port);
-		if (retval)
+		if (retval < 0) {
+			port->dev = NULL;
 			break;
+		}
 	}
 
 	if (i == 0 && retval < 0) {
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 051c3a7..3bfcc7b 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -264,7 +264,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.4.1"
+#define DRIVER_VERSION "v1.4.2"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>"
 #define DRIVER_DESC "USB FTDI Serial Converters Driver"
 
@@ -687,6 +687,8 @@
  	char prev_status, diff_status;        /* Used for TIOCMIWAIT */
 	__u8 rx_flags;		/* receive state flags (throttling) */
 	spinlock_t rx_lock;	/* spinlock for receive state */
+	struct work_struct rx_work;
+	int rx_processed;
 
 	__u16 interface;	/* FT2232C port interface (0 for FT232/245) */
 
@@ -717,7 +719,7 @@
 static int  ftdi_chars_in_buffer	(struct usb_serial_port *port);
 static void ftdi_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);
 static void ftdi_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);
-static void ftdi_process_read		(struct usb_serial_port *port);
+static void ftdi_process_read		(void *param);
 static void ftdi_set_termios		(struct usb_serial_port *port, struct termios * old);
 static int  ftdi_tiocmget               (struct usb_serial_port *port, struct file *file);
 static int  ftdi_tiocmset		(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear);
@@ -1387,6 +1389,8 @@
 		port->read_urb->transfer_buffer_length = BUFSZ;
 	}
 
+	INIT_WORK(&priv->rx_work, ftdi_process_read, port);
+
 	/* Free port's existing write urb and transfer buffer. */
 	if (port->write_urb) {
 		usb_free_urb (port->write_urb);
@@ -1617,6 +1621,7 @@
 	spin_unlock_irqrestore(&priv->rx_lock, flags);
 
 	/* Start reading from the device */
+	priv->rx_processed = 0;
 	usb_fill_bulk_urb(port->read_urb, dev,
 		      usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
 		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
@@ -1667,6 +1672,10 @@
 			err("Error from RTS LOW urb");
 		}
 	} /* Note change no line if hupcl is off */
+
+	/* cancel any scheduled reading */
+	cancel_delayed_work(&priv->rx_work);
+	flush_scheduled_work();
 	
 	/* shutdown our bulk read */
 	if (port->read_urb)
@@ -1862,23 +1871,14 @@
 		return;
 	}
 
-	/* If throttled, delay receive processing until unthrottled. */
-	spin_lock(&priv->rx_lock);
-	if (priv->rx_flags & THROTTLED) {
-		dbg("Deferring read urb processing until unthrottled");
-		priv->rx_flags |= ACTUALLY_THROTTLED;
-		spin_unlock(&priv->rx_lock);
-		return;
-	}
-	spin_unlock(&priv->rx_lock);
-
 	ftdi_process_read(port);
 
 } /* ftdi_read_bulk_callback */
 
 
-static void ftdi_process_read (struct usb_serial_port *port)
+static void ftdi_process_read (void *param)
 { /* ftdi_process_read */
+	struct usb_serial_port *port = (struct usb_serial_port*)param;
 	struct urb *urb;
 	struct tty_struct *tty;
 	struct ftdi_private *priv;
@@ -1889,6 +1889,7 @@
 	int result;
 	int need_flip;
 	int packet_offset;
+	unsigned long flags;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -1915,12 +1916,18 @@
 
 	data = urb->transfer_buffer;
 
-        /* The first two bytes of every read packet are status */
-	if (urb->actual_length > 2) {
-		usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+	if (priv->rx_processed) {
+		dbg("%s - already processed: %d bytes, %d remain", __FUNCTION__,
+				priv->rx_processed,
+				urb->actual_length - priv->rx_processed);
 	} else {
-                dbg("Status only: %03oo %03oo",data[0],data[1]);
-        }
+		/* The first two bytes of every read packet are status */
+		if (urb->actual_length > 2) {
+			usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+		} else {
+			dbg("Status only: %03oo %03oo",data[0],data[1]);
+		}
+	}
 
 
 	/* TO DO -- check for hung up line and handle appropriately: */
@@ -1929,8 +1936,12 @@
 	/* if CD is dropped and the line is not CLOCAL then we should hangup */
 
 	need_flip = 0;
-	for (packet_offset=0; packet_offset < urb->actual_length; packet_offset += PKTSZ) {
+	for (packet_offset = priv->rx_processed; packet_offset < urb->actual_length; packet_offset += PKTSZ) {
+		int length;
+
 		/* Compare new line status to the old one, signal if different */
+		/* N.B. packet may be processed more than once, but differences
+		 * are only processed once.  */
 		if (priv != NULL) {
 			char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK;
 			if (new_status != priv->prev_status) {
@@ -1940,6 +1951,35 @@
 			}
 		}
 
+		length = min(PKTSZ, urb->actual_length-packet_offset)-2;
+		if (length < 0) {
+			err("%s - bad packet length: %d", __FUNCTION__, length+2);
+			length = 0;
+		}
+
+		/* have to make sure we don't overflow the buffer
+		   with tty_insert_flip_char's */
+		if (tty->flip.count+length > TTY_FLIPBUF_SIZE) {
+			tty_flip_buffer_push(tty);
+			need_flip = 0;
+
+			if (tty->flip.count != 0) {
+				/* flip didn't work, this happens when ftdi_process_read() is
+				 * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */
+				dbg("%s - flip buffer push failed", __FUNCTION__);
+				break;
+			}
+		}
+		if (priv->rx_flags & THROTTLED) {
+			dbg("%s - throttled", __FUNCTION__);
+			break;
+		}
+		if (tty->ldisc.receive_room(tty)-tty->flip.count < length) {
+			/* break out & wait for throttling/unthrottling to happen */
+			dbg("%s - receive room low", __FUNCTION__);
+			break;
+		}
+
 		/* Handle errors and break */
 		error_flag = TTY_NORMAL;
 		/* Although the device uses a bitmask and hence can have multiple */
@@ -1962,13 +2002,8 @@
 			error_flag = TTY_FRAME;
 			dbg("FRAMING error");
 		}
-		if (urb->actual_length > packet_offset + 2) {
-			for (i = 2; (i < PKTSZ) && ((i+packet_offset) < urb->actual_length); ++i) {
-				/* have to make sure we don't overflow the buffer
-				  with tty_insert_flip_char's */
-				if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-					tty_flip_buffer_push(tty);
-				}
+		if (length > 0) {
+			for (i = 2; i < length+2; i++) {
 				/* Note that the error flag is duplicated for 
 				   every character received since we don't know
 				   which character it applied to */
@@ -2005,6 +2040,35 @@
 		tty_flip_buffer_push(tty);
 	}
 
+	if (packet_offset < urb->actual_length) {
+		/* not completely processed - record progress */
+		priv->rx_processed = packet_offset;
+		dbg("%s - incomplete, %d bytes processed, %d remain",
+				__FUNCTION__, packet_offset,
+				urb->actual_length - packet_offset);
+		/* check if we were throttled while processing */
+		spin_lock_irqsave(&priv->rx_lock, flags);
+		if (priv->rx_flags & THROTTLED) {
+			priv->rx_flags |= ACTUALLY_THROTTLED;
+			spin_unlock_irqrestore(&priv->rx_lock, flags);
+			dbg("%s - deferring remainder until unthrottled",
+					__FUNCTION__);
+			return;
+		}
+		spin_unlock_irqrestore(&priv->rx_lock, flags);
+		/* if the port is closed stop trying to read */
+		if (port->open_count > 0){
+			/* delay processing of remainder */
+			schedule_delayed_work(&priv->rx_work, 1);
+		} else {
+			dbg("%s - port is closed", __FUNCTION__);
+		}
+		return;
+	}
+
+	/* urb is completely processed */
+	priv->rx_processed = 0;
+
 	/* if the port is closed stop trying to read */
 	if (port->open_count > 0){
 		/* Continue trying to always read  */
@@ -2444,7 +2508,7 @@
 	spin_unlock_irqrestore(&priv->rx_lock, flags);
 
 	if (actually_throttled)
-		ftdi_process_read(port);
+		schedule_work(&priv->rx_work);
 }
 
 static int __init ftdi_init (void)
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index f0cd67d..c8998dc 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -520,7 +520,7 @@
 		DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
 
 		down_write(&current->mm->mmap_sem);
-		textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0);
+		textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 0);
 		up_write(&current->mm->mmap_sem);
 		if (!textpos  || textpos >= (unsigned long) -4096) {
 			if (!textpos)
@@ -532,7 +532,7 @@
 		down_write(&current->mm->mmap_sem);
 		realdatastart = do_mmap(0, 0, data_len + extra +
 				MAX_SHARED_LIBS * sizeof(unsigned long),
-				PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0);
+				PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
 		up_write(&current->mm->mmap_sem);
 
 		if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -574,7 +574,7 @@
 		down_write(&current->mm->mmap_sem);
 		textpos = do_mmap(0, 0, text_len + data_len + extra +
 					MAX_SHARED_LIBS * sizeof(unsigned long),
-				PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0);
+				PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
 		up_write(&current->mm->mmap_sem);
 		if (!textpos  || textpos >= (unsigned long) -4096) {
 			if (!textpos)
diff --git a/fs/mpage.c b/fs/mpage.c
index b92c0e6..bb9aebe 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -79,8 +79,11 @@
 		if (--bvec >= bio->bi_io_vec)
 			prefetchw(&bvec->bv_page->flags);
 
-		if (!uptodate)
+		if (!uptodate){
 			SetPageError(page);
+			if (page->mapping)
+				set_bit(AS_EIO, &page->mapping->flags);
+		}
 		end_page_writeback(page);
 	} while (bvec >= bio->bi_io_vec);
 	bio_put(bio);
diff --git a/fs/namei.c b/fs/namei.c
index dd78f01..a7f7f44 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -493,12 +493,21 @@
 	return PTR_ERR(link);
 }
 
-static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
+struct path {
+	struct vfsmount *mnt;
+	struct dentry *dentry;
+};
+
+static inline int __do_follow_link(struct path *path, struct nameidata *nd)
 {
 	int error;
+	struct dentry *dentry = path->dentry;
 
-	touch_atime(nd->mnt, dentry);
+	touch_atime(path->mnt, dentry);
 	nd_set_link(nd, NULL);
+
+	if (path->mnt == nd->mnt)
+		mntget(path->mnt);
 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
 	if (!error) {
 		char *s = nd_get_link(nd);
@@ -507,6 +516,8 @@
 		if (dentry->d_inode->i_op->put_link)
 			dentry->d_inode->i_op->put_link(dentry, nd);
 	}
+	dput(dentry);
+	mntput(path->mnt);
 
 	return error;
 }
@@ -518,7 +529,7 @@
  * Without that kind of total limit, nasty chains of consecutive
  * symlinks can cause almost arbitrarily long lookups. 
  */
-static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
+static inline int do_follow_link(struct path *path, struct nameidata *nd)
 {
 	int err = -ELOOP;
 	if (current->link_count >= MAX_NESTED_LINKS)
@@ -527,17 +538,20 @@
 		goto loop;
 	BUG_ON(nd->depth >= MAX_NESTED_LINKS);
 	cond_resched();
-	err = security_inode_follow_link(dentry, nd);
+	err = security_inode_follow_link(path->dentry, nd);
 	if (err)
 		goto loop;
 	current->link_count++;
 	current->total_link_count++;
 	nd->depth++;
-	err = __do_follow_link(dentry, nd);
+	err = __do_follow_link(path, nd);
 	current->link_count--;
 	nd->depth--;
 	return err;
 loop:
+	dput(path->dentry);
+	if (path->mnt != nd->mnt)
+		mntput(path->mnt);
 	path_release(nd);
 	return err;
 }
@@ -565,87 +579,91 @@
 /* no need for dcache_lock, as serialization is taken care in
  * namespace.c
  */
-static int follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+static int __follow_mount(struct path *path)
 {
 	int res = 0;
-	while (d_mountpoint(*dentry)) {
-		struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
+	while (d_mountpoint(path->dentry)) {
+		struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry);
 		if (!mounted)
 			break;
-		mntput(*mnt);
-		*mnt = mounted;
-		dput(*dentry);
-		*dentry = dget(mounted->mnt_root);
+		dput(path->dentry);
+		if (res)
+			mntput(path->mnt);
+		path->mnt = mounted;
+		path->dentry = dget(mounted->mnt_root);
 		res = 1;
 	}
 	return res;
 }
 
+static void follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+{
+	while (d_mountpoint(*dentry)) {
+		struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
+		if (!mounted)
+			break;
+		dput(*dentry);
+		mntput(*mnt);
+		*mnt = mounted;
+		*dentry = dget(mounted->mnt_root);
+	}
+}
+
 /* no need for dcache_lock, as serialization is taken care in
  * namespace.c
  */
-static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
+int follow_down(struct vfsmount **mnt, struct dentry **dentry)
 {
 	struct vfsmount *mounted;
 
 	mounted = lookup_mnt(*mnt, *dentry);
 	if (mounted) {
+		dput(*dentry);
 		mntput(*mnt);
 		*mnt = mounted;
-		dput(*dentry);
 		*dentry = dget(mounted->mnt_root);
 		return 1;
 	}
 	return 0;
 }
 
-int follow_down(struct vfsmount **mnt, struct dentry **dentry)
-{
-	return __follow_down(mnt,dentry);
-}
- 
-static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
+static inline void follow_dotdot(struct nameidata *nd)
 {
 	while(1) {
 		struct vfsmount *parent;
-		struct dentry *old = *dentry;
+		struct dentry *old = nd->dentry;
 
                 read_lock(&current->fs->lock);
-		if (*dentry == current->fs->root &&
-		    *mnt == current->fs->rootmnt) {
+		if (nd->dentry == current->fs->root &&
+		    nd->mnt == current->fs->rootmnt) {
                         read_unlock(&current->fs->lock);
 			break;
 		}
                 read_unlock(&current->fs->lock);
 		spin_lock(&dcache_lock);
-		if (*dentry != (*mnt)->mnt_root) {
-			*dentry = dget((*dentry)->d_parent);
+		if (nd->dentry != nd->mnt->mnt_root) {
+			nd->dentry = dget(nd->dentry->d_parent);
 			spin_unlock(&dcache_lock);
 			dput(old);
 			break;
 		}
 		spin_unlock(&dcache_lock);
 		spin_lock(&vfsmount_lock);
-		parent = (*mnt)->mnt_parent;
-		if (parent == *mnt) {
+		parent = nd->mnt->mnt_parent;
+		if (parent == nd->mnt) {
 			spin_unlock(&vfsmount_lock);
 			break;
 		}
 		mntget(parent);
-		*dentry = dget((*mnt)->mnt_mountpoint);
+		nd->dentry = dget(nd->mnt->mnt_mountpoint);
 		spin_unlock(&vfsmount_lock);
 		dput(old);
-		mntput(*mnt);
-		*mnt = parent;
+		mntput(nd->mnt);
+		nd->mnt = parent;
 	}
-	follow_mount(mnt, dentry);
+	follow_mount(&nd->mnt, &nd->dentry);
 }
 
-struct path {
-	struct vfsmount *mnt;
-	struct dentry *dentry;
-};
-
 /*
  *  It's more convoluted than I'd like it to be, but... it's still fairly
  *  small and for now I'd prefer to have fast path as straight as possible.
@@ -664,6 +682,7 @@
 done:
 	path->mnt = mnt;
 	path->dentry = dentry;
+	__follow_mount(path);
 	return 0;
 
 need_lookup:
@@ -751,7 +770,7 @@
 			case 2:	
 				if (this.name[1] != '.')
 					break;
-				follow_dotdot(&nd->mnt, &nd->dentry);
+				follow_dotdot(nd);
 				inode = nd->dentry->d_inode;
 				/* fallthrough */
 			case 1:
@@ -771,8 +790,6 @@
 		err = do_lookup(nd, &this, &next);
 		if (err)
 			break;
-		/* Check mountpoints.. */
-		follow_mount(&next.mnt, &next.dentry);
 
 		err = -ENOENT;
 		inode = next.dentry->d_inode;
@@ -783,10 +800,7 @@
 			goto out_dput;
 
 		if (inode->i_op->follow_link) {
-			mntget(next.mnt);
-			err = do_follow_link(next.dentry, nd);
-			dput(next.dentry);
-			mntput(next.mnt);
+			err = do_follow_link(&next, nd);
 			if (err)
 				goto return_err;
 			err = -ENOENT;
@@ -798,6 +812,8 @@
 				break;
 		} else {
 			dput(nd->dentry);
+			if (nd->mnt != next.mnt)
+				mntput(nd->mnt);
 			nd->mnt = next.mnt;
 			nd->dentry = next.dentry;
 		}
@@ -819,7 +835,7 @@
 			case 2:	
 				if (this.name[1] != '.')
 					break;
-				follow_dotdot(&nd->mnt, &nd->dentry);
+				follow_dotdot(nd);
 				inode = nd->dentry->d_inode;
 				/* fallthrough */
 			case 1:
@@ -833,19 +849,17 @@
 		err = do_lookup(nd, &this, &next);
 		if (err)
 			break;
-		follow_mount(&next.mnt, &next.dentry);
 		inode = next.dentry->d_inode;
 		if ((lookup_flags & LOOKUP_FOLLOW)
 		    && inode && inode->i_op && inode->i_op->follow_link) {
-			mntget(next.mnt);
-			err = do_follow_link(next.dentry, nd);
-			dput(next.dentry);
-			mntput(next.mnt);
+			err = do_follow_link(&next, nd);
 			if (err)
 				goto return_err;
 			inode = nd->dentry->d_inode;
 		} else {
 			dput(nd->dentry);
+			if (nd->mnt != next.mnt)
+				mntput(nd->mnt);
 			nd->mnt = next.mnt;
 			nd->dentry = next.dentry;
 		}
@@ -885,6 +899,8 @@
 		return 0;
 out_dput:
 		dput(next.dentry);
+		if (nd->mnt != next.mnt)
+			mntput(next.mnt);
 		break;
 	}
 	path_release(nd);
@@ -1398,7 +1414,7 @@
 int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
 {
 	int acc_mode, error = 0;
-	struct dentry *dentry;
+	struct path path;
 	struct dentry *dir;
 	int count = 0;
 
@@ -1442,23 +1458,24 @@
 	dir = nd->dentry;
 	nd->flags &= ~LOOKUP_PARENT;
 	down(&dir->d_inode->i_sem);
-	dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+	path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+	path.mnt = nd->mnt;
 
 do_last:
-	error = PTR_ERR(dentry);
-	if (IS_ERR(dentry)) {
+	error = PTR_ERR(path.dentry);
+	if (IS_ERR(path.dentry)) {
 		up(&dir->d_inode->i_sem);
 		goto exit;
 	}
 
 	/* Negative dentry, just create the file */
-	if (!dentry->d_inode) {
+	if (!path.dentry->d_inode) {
 		if (!IS_POSIXACL(dir->d_inode))
 			mode &= ~current->fs->umask;
-		error = vfs_create(dir->d_inode, dentry, mode, nd);
+		error = vfs_create(dir->d_inode, path.dentry, mode, nd);
 		up(&dir->d_inode->i_sem);
 		dput(nd->dentry);
-		nd->dentry = dentry;
+		nd->dentry = path.dentry;
 		if (error)
 			goto exit;
 		/* Don't check for write permission, don't truncate */
@@ -1476,22 +1493,24 @@
 	if (flag & O_EXCL)
 		goto exit_dput;
 
-	if (d_mountpoint(dentry)) {
+	if (__follow_mount(&path)) {
 		error = -ELOOP;
 		if (flag & O_NOFOLLOW)
 			goto exit_dput;
-		while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
 	}
 	error = -ENOENT;
-	if (!dentry->d_inode)
+	if (!path.dentry->d_inode)
 		goto exit_dput;
-	if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
+	if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link)
 		goto do_link;
 
 	dput(nd->dentry);
-	nd->dentry = dentry;
+	nd->dentry = path.dentry;
+	if (nd->mnt != path.mnt)
+		mntput(nd->mnt);
+	nd->mnt = path.mnt;
 	error = -EISDIR;
-	if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
+	if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode))
 		goto exit;
 ok:
 	error = may_open(nd, acc_mode, flag);
@@ -1500,7 +1519,9 @@
 	return 0;
 
 exit_dput:
-	dput(dentry);
+	dput(path.dentry);
+	if (nd->mnt != path.mnt)
+		mntput(path.mnt);
 exit:
 	path_release(nd);
 	return error;
@@ -1520,18 +1541,15 @@
 	 * are done. Procfs-like symlinks just set LAST_BIND.
 	 */
 	nd->flags |= LOOKUP_PARENT;
-	error = security_inode_follow_link(dentry, nd);
+	error = security_inode_follow_link(path.dentry, nd);
 	if (error)
 		goto exit_dput;
-	error = __do_follow_link(dentry, nd);
-	dput(dentry);
+	error = __do_follow_link(&path, nd);
 	if (error)
 		return error;
 	nd->flags &= ~LOOKUP_PARENT;
-	if (nd->last_type == LAST_BIND) {
-		dentry = nd->dentry;
+	if (nd->last_type == LAST_BIND)
 		goto ok;
-	}
 	error = -EISDIR;
 	if (nd->last_type != LAST_NORM)
 		goto exit;
@@ -1546,7 +1564,8 @@
 	}
 	dir = nd->dentry;
 	down(&dir->d_inode->i_sem);
-	dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+	path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+	path.mnt = nd->mnt;
 	putname(nd->last.name);
 	goto do_last;
 }
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 73f96ac..ff6155f 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -528,19 +528,39 @@
 	dentry->d_time = jiffies;
 }
 
+/*
+ * Return the intent data that applies to this particular path component
+ *
+ * Note that the current set of intents only apply to the very last
+ * component of the path.
+ * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT.
+ */
+static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask)
+{
+	if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))
+		return 0;
+	return nd->flags & mask;
+}
+
+/*
+ * Inode and filehandle revalidation for lookups.
+ *
+ * We force revalidation in the cases where the VFS sets LOOKUP_REVAL,
+ * or if the intent information indicates that we're about to open this
+ * particular file and the "nocto" mount flag is not set.
+ *
+ */
 static inline
 int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 
 	if (nd != NULL) {
-		int ndflags = nd->flags;
 		/* VFS wants an on-the-wire revalidation */
-		if (ndflags & LOOKUP_REVAL)
+		if (nd->flags & LOOKUP_REVAL)
 			goto out_force;
 		/* This is an open(2) */
-		if ((ndflags & LOOKUP_OPEN) &&
-				!(ndflags & LOOKUP_CONTINUE) &&
+		if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 &&
 				!(server->flags & NFS_MOUNT_NOCTO))
 			goto out_force;
 	}
@@ -560,12 +580,8 @@
 int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
 		       struct nameidata *nd)
 {
-	int ndflags = 0;
-
-	if (nd)
-		ndflags = nd->flags;
 	/* Don't revalidate a negative dentry if we're creating a new file */
-	if ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE))
+	if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0)
 		return 0;
 	return !nfs_check_verifier(dir, dentry);
 }
@@ -700,12 +716,16 @@
 	.d_iput		= nfs_dentry_iput,
 };
 
+/*
+ * Use intent information to check whether or not we're going to do
+ * an O_EXCL create using this path component.
+ */
 static inline
 int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
 {
 	if (NFS_PROTO(dir)->version == 2)
 		return 0;
-	if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE))
+	if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
 		return 0;
 	return (nd->intent.open.flags & O_EXCL) != 0;
 }
@@ -772,12 +792,13 @@
 	.d_iput		= nfs_dentry_iput,
 };
 
+/*
+ * Use intent information to determine whether we need to substitute
+ * the NFSv4-style stateful OPEN for the LOOKUP call
+ */
 static int is_atomic_open(struct inode *dir, struct nameidata *nd)
 {
-	if (!nd)
-		return 0;
-	/* Check that we are indeed trying to open this file */
-	if ((nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_OPEN))
+	if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0)
 		return 0;
 	/* NFS does not (yet) have a stateful open for directories */
 	if (nd->flags & LOOKUP_DIRECTORY)
diff --git a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h
index c99dbbb..ef855a3 100644
--- a/include/asm-alpha/agp.h
+++ b/include/asm-alpha/agp.h
@@ -10,4 +10,14 @@
 #define flush_agp_mappings() 
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
index a8e3c2d..0834626 100644
--- a/include/asm-arm/arch-ixp2000/io.h
+++ b/include/asm-arm/arch-ixp2000/io.h
@@ -75,8 +75,8 @@
 	 * Is this cycle meant for the CS8900?
 	 */
 	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-		 (port <= IXDP2X01_CS8900_VIRT_END))) {
+		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
 		u8 *buf8 = (u8*)buf;
 		register u32 tmp32;
 
@@ -100,8 +100,8 @@
 	 * Is this cycle meant for the CS8900?
 	 */
 	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-		 (port <= IXDP2X01_CS8900_VIRT_END))) {
+		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
 		register u32 tmp32;
 		u8 *buf8 = (u8*)buf;
 		do {
@@ -124,8 +124,8 @@
 	 * Is this cycle meant for the CS8900?
 	 */
 	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-		 (port <= IXDP2X01_CS8900_VIRT_END))) {
+		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
 		return (u16)(*port);  
 	}
 
@@ -137,8 +137,8 @@
 	register volatile u32 *port = (volatile u32 *)ptr;
 
 	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-		 (port <= IXDP2X01_CS8900_VIRT_END))) {
+		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
 		*port = value;  
 		return;
 	}
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 39741d3..b5e54a9e 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1296,6 +1296,7 @@
 #define GPIO111_MMCDAT3		111	/* MMC DAT3 (PXA27x) */
 #define GPIO111_MMCCS1		111	/* MMC Chip Select 1 (PXA27x) */
 #define GPIO112_MMCCMD		112	/* MMC CMD (PXA27x) */
+#define GPIO113_I2S_SYSCLK	113	/* I2S System Clock (PXA27x) */
 #define GPIO113_AC97_RESET_N	113	/* AC97 NRESET on (PXA27x) */
 
 /* GPIO alternate function mode & direction */
@@ -1428,6 +1429,7 @@
 #define GPIO111_MMCDAT3_MD	(111 | GPIO_ALT_FN_1_OUT)
 #define GPIO110_MMCCS1_MD	(111 | GPIO_ALT_FN_1_OUT)
 #define GPIO112_MMCCMD_MD	(112 | GPIO_ALT_FN_1_OUT)
+#define GPIO113_I2S_SYSCLK_MD	(113 | GPIO_ALT_FN_1_OUT)
 #define GPIO113_AC97_RESET_N_MD	(113 | GPIO_ALT_FN_2_OUT)
 #define GPIO117_I2CSCL_MD	(117 | GPIO_ALT_FN_1_OUT)
 #define GPIO118_I2CSDA_MD	(118 | GPIO_ALT_FN_1_IN)
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index cbceacbe..a1696ba 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -38,9 +38,9 @@
  */
 #define ELF_CLASS	ELFCLASS32
 #ifdef __ARMEB__
-#define ELF_DATA	ELFDATA2MSB;
+#define ELF_DATA	ELFDATA2MSB
 #else
-#define ELF_DATA	ELFDATA2LSB;
+#define ELF_DATA	ELFDATA2LSB
 #endif
 #define ELF_ARCH	EM_ARM
 
diff --git a/include/asm-arm26/elf.h b/include/asm-arm26/elf.h
index 8b14947..5a47fdb 100644
--- a/include/asm-arm26/elf.h
+++ b/include/asm-arm26/elf.h
@@ -36,7 +36,7 @@
  * These are used to set parameters in the core dumps.
  */
 #define ELF_CLASS	ELFCLASS32
-#define ELF_DATA	ELFDATA2LSB;
+#define ELF_DATA	ELFDATA2LSB
 #define ELF_ARCH	EM_ARM
 
 #define USE_ELF_CORE_DUMP
diff --git a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h
index 82431ed..1ec8a34 100644
--- a/include/asm-h8300/kmap_types.h
+++ b/include/asm-h8300/kmap_types.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
+#ifndef _ASM_H8300_KMAP_TYPES_H
+#define _ASM_H8300_KMAP_TYPES_H
 
 enum km_type {
 	KM_BOUNCE_READ,
@@ -13,6 +13,8 @@
 	KM_PTE1,
 	KM_IRQ0,
 	KM_IRQ1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h
index abe0885..63f727a 100644
--- a/include/asm-h8300/mman.h
+++ b/include/asm-h8300/mman.h
@@ -4,6 +4,7 @@
 #define PROT_READ	0x1		/* page can be read */
 #define PROT_WRITE	0x2		/* page can be written */
 #define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_SEM	0x8		/* page may be used for atomic ops */
 #define PROT_NONE	0x0		/* page can not be accessed */
 #define PROT_GROWSDOWN	0x01000000	/* mprotect flag: extend change to start of growsdown vma */
 #define PROT_GROWSUP	0x02000000	/* mprotect flag: extend change to end of growsup vma */
@@ -19,6 +20,8 @@
 #define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
 #define MAP_LOCKED	0x2000		/* pages are locked */
 #define MAP_NORESERVE	0x4000		/* don't check for reservations */
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_INVALIDATE	2		/* invalidate the caches */
diff --git a/include/asm-i386/agp.h b/include/asm-i386/agp.h
index a917ff5..b82f5f3 100644
--- a/include/asm-i386/agp.h
+++ b/include/asm-i386/agp.h
@@ -21,4 +21,14 @@
    worth it. Would need a page for it. */
 #define flush_agp_cache() asm volatile("wbinvd":::"memory")
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-i386/mach-numaq/mach_ipi.h b/include/asm-i386/mach-numaq/mach_ipi.h
index 1b46fd3..c604448 100644
--- a/include/asm-i386/mach-numaq/mach_ipi.h
+++ b/include/asm-i386/mach-numaq/mach_ipi.h
@@ -1,7 +1,7 @@
 #ifndef __ASM_MACH_IPI_H
 #define __ASM_MACH_IPI_H
 
-inline void send_IPI_mask_sequence(cpumask_t, int vector);
+void send_IPI_mask_sequence(cpumask_t, int vector);
 
 static inline void send_IPI_mask(cpumask_t mask, int vector)
 {
diff --git a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h
index d1316f1..4e517f0 100644
--- a/include/asm-ia64/agp.h
+++ b/include/asm-ia64/agp.h
@@ -18,4 +18,14 @@
 #define flush_agp_mappings()		/* nothing */
 #define flush_agp_cache()		mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif /* _ASM_IA64_AGP_H */
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index ea121a0..fcc9c33 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -8,7 +8,7 @@
  * This hopefully works with any (fixed) IA-64 page-size, as defined
  * in <asm/page.h>.
  *
- * Copyright (C) 1998-2004 Hewlett-Packard Co
+ * Copyright (C) 1998-2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -551,7 +551,11 @@
 
 /* These tell get_user_pages() that the first gate page is accessible from user-level.  */
 #define FIXADDR_USER_START	GATE_ADDR
-#define FIXADDR_USER_END	(GATE_ADDR + 2*PERCPU_PAGE_SIZE)
+#ifdef HAVE_BUGGY_SEGREL
+# define FIXADDR_USER_END	(GATE_ADDR + 2*PAGE_SIZE)
+#else
+# define FIXADDR_USER_END	(GATE_ADDR + 2*PERCPU_PAGE_SIZE)
+#endif
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 9e1ba8b..91bbd1f 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -403,7 +403,10 @@
  * task_struct at this point.
  */
 
-/* Return TRUE if task T owns the fph partition of the CPU we're running on. */
+/*
+ * Return TRUE if task T owns the fph partition of the CPU we're running on.
+ * Must be called from code that has preemption disabled.
+ */
 #define ia64_is_local_fpu_owner(t)								\
 ({												\
 	struct task_struct *__ia64_islfo_task = (t);						\
@@ -411,7 +414,10 @@
 	 && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER));	\
 })
 
-/* Mark task T as owning the fph partition of the CPU we're running on. */
+/*
+ * Mark task T as owning the fph partition of the CPU we're running on.
+ * Must be called from code that has preemption disabled.
+ */
 #define ia64_set_local_fpu_owner(t) do {						\
 	struct task_struct *__ia64_slfo_task = (t);					\
 	__ia64_slfo_task->thread.last_fph_cpu = smp_processor_id();			\
diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h
index be27cfa8..ca9e423 100644
--- a/include/asm-ppc/agp.h
+++ b/include/asm-ppc/agp.h
@@ -10,4 +10,14 @@
 #define flush_agp_mappings()
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-ppc/sigcontext.h b/include/asm-ppc/sigcontext.h
index f82dccc..b7a417e 100644
--- a/include/asm-ppc/sigcontext.h
+++ b/include/asm-ppc/sigcontext.h
@@ -2,7 +2,7 @@
 #define _ASM_PPC_SIGCONTEXT_H
 
 #include <asm/ptrace.h>
-
+#include <linux/compiler.h>
 
 struct sigcontext {
 	unsigned long	_unused[4];
diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h
index be27cfa8..ca9e423 100644
--- a/include/asm-ppc64/agp.h
+++ b/include/asm-ppc64/agp.h
@@ -10,4 +10,14 @@
 #define flush_agp_mappings()
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h
index 6c42d61..085eedb 100644
--- a/include/asm-ppc64/elf.h
+++ b/include/asm-ppc64/elf.h
@@ -221,9 +221,7 @@
 		set_thread_flag(TIF_ABI_PENDING);		\
 	else							\
 		clear_thread_flag(TIF_ABI_PENDING);		\
-	if (ibcs2)						\
-		set_personality(PER_SVR4);			\
-	else if (current->personality != PER_LINUX32)		\
+	if (personality(current->personality) != PER_LINUX32)	\
 		set_personality(PER_LINUX);			\
 } while (0)
 
diff --git a/include/asm-s390/user.h b/include/asm-s390/user.h
index c64f8c1..1dc74ba 100644
--- a/include/asm-s390/user.h
+++ b/include/asm-s390/user.h
@@ -10,7 +10,7 @@
 #define _S390_USER_H
 
 #include <asm/page.h>
-#include <linux/ptrace.h>
+#include <asm/ptrace.h>
 /* Core file format: The core file is written in such a way that gdb
    can understand it and provide useful information to the user (under
    linux we use the 'trad-core' bfd).  There are quite a number of
diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h
index f461144..0a780e8 100644
--- a/include/asm-sparc/uaccess.h
+++ b/include/asm-sparc/uaccess.h
@@ -41,10 +41,11 @@
  * No one can read/write anything from userland in the kernel space by setting
  * large size and address near to PAGE_OFFSET - a fault will break his intentions.
  */
-#define __user_ok(addr,size) ((addr) < STACK_TOP)
+#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
-#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+#define access_ok(type, addr, size)					\
+	({ (void)(type); __access_ok((unsigned long)(addr), size); })
 
 /* this function will go away soon - use access_ok() instead */
 static inline int __deprecated verify_area(int type, const void __user * addr, unsigned long size)
diff --git a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h
index ba05bdf..58f8cb6 100644
--- a/include/asm-sparc64/agp.h
+++ b/include/asm-sparc64/agp.h
@@ -8,4 +8,14 @@
 #define flush_agp_mappings() 
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h
index 0bb9019..06c52ee 100644
--- a/include/asm-x86_64/agp.h
+++ b/include/asm-x86_64/agp.h
@@ -19,4 +19,14 @@
    worth it. Would need a page for it. */
 #define flush_agp_cache() asm volatile("wbinvd":::"memory")
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d5a55bd..b123cc0 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -25,6 +25,8 @@
 #ifndef _LINUX_ACPI_H
 #define _LINUX_ACPI_H
 
+#include <linux/config.h>
+
 #ifdef	CONFIG_ACPI
 
 #ifndef _LINUX
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index b0d6134..b8b4ebf 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -874,6 +874,7 @@
 #define PCI_DEVICE_ID_APPLE_KL_USB_P	0x0026
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P	0x0027
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15	0x002d
+#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15	0x002e
 #define PCI_DEVICE_ID_APPLE_UNI_N_FW2	0x0030
 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2	0x0032
 #define PCI_DEVIEC_ID_APPLE_UNI_N_ATA	0x0033
@@ -2382,6 +2383,8 @@
 #define PCI_DEVICE_ID_INTEL_82915G_IG	0x2582
 #define PCI_DEVICE_ID_INTEL_82915GM_HB	0x2590
 #define PCI_DEVICE_ID_INTEL_82915GM_IG	0x2592
+#define PCI_DEVICE_ID_INTEL_82945G_HB	0x2770
+#define PCI_DEVICE_ID_INTEL_82945G_IG	0x2772
 #define PCI_DEVICE_ID_INTEL_ICH6_0	0x2640
 #define PCI_DEVICE_ID_INTEL_ICH6_1	0x2641
 #define PCI_DEVICE_ID_INTEL_ICH6_2	0x2642
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h
index aa6b48bb..a6b2cc5 100644
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/linux/tc_ematch/tc_em_meta.h
@@ -56,6 +56,36 @@
 	TCF_META_ID_TCCLASSID,
 	TCF_META_ID_RTCLASSID,
 	TCF_META_ID_RTIIF,
+	TCF_META_ID_SK_FAMILY,
+	TCF_META_ID_SK_STATE,
+	TCF_META_ID_SK_REUSE,
+	TCF_META_ID_SK_BOUND_IF,
+	TCF_META_ID_SK_REFCNT,
+	TCF_META_ID_SK_SHUTDOWN,
+	TCF_META_ID_SK_PROTO,
+	TCF_META_ID_SK_TYPE,
+	TCF_META_ID_SK_RCVBUF,
+	TCF_META_ID_SK_RMEM_ALLOC,
+	TCF_META_ID_SK_WMEM_ALLOC,
+	TCF_META_ID_SK_OMEM_ALLOC,
+	TCF_META_ID_SK_WMEM_QUEUED,
+	TCF_META_ID_SK_RCV_QLEN,
+	TCF_META_ID_SK_SND_QLEN,
+ 	TCF_META_ID_SK_ERR_QLEN,
+	TCF_META_ID_SK_FORWARD_ALLOCS,
+	TCF_META_ID_SK_SNDBUF,
+ 	TCF_META_ID_SK_ALLOCS,
+ 	TCF_META_ID_SK_ROUTE_CAPS,
+ 	TCF_META_ID_SK_HASHENT,
+ 	TCF_META_ID_SK_LINGERTIME,
+ 	TCF_META_ID_SK_ACK_BACKLOG,
+ 	TCF_META_ID_SK_MAX_ACK_BACKLOG,
+ 	TCF_META_ID_SK_PRIO,
+ 	TCF_META_ID_SK_RCVLOWAT,
+ 	TCF_META_ID_SK_RCVTIMEO,
+ 	TCF_META_ID_SK_SNDTIMEO,
+ 	TCF_META_ID_SK_SENDMSG_OFF,
+ 	TCF_META_ID_SK_WRITE_PENDING,
 	__TCF_META_ID_MAX
 };
 #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1)
diff --git a/mm/filemap.c b/mm/filemap.c
index 1d33fec..4a2fee2 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1968,6 +1968,7 @@
 	do {
 		unsigned long index;
 		unsigned long offset;
+		unsigned long maxlen;
 		size_t copied;
 
 		offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
@@ -1982,7 +1983,10 @@
 		 * same page as we're writing to, without it being marked
 		 * up-to-date.
 		 */
-		fault_in_pages_readable(buf, bytes);
+		maxlen = cur_iov->iov_len - iov_base;
+		if (maxlen > bytes)
+			maxlen = bytes;
+		fault_in_pages_readable(buf, maxlen);
 
 		page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
 		if (!page) {
@@ -2024,6 +2028,8 @@
 					filemap_set_next_iovec(&cur_iov,
 							&iov_base, status);
 					buf = cur_iov->iov_base + iov_base;
+				} else {
+					iov_base += status;
 				}
 			}
 		}
diff --git a/net/core/dev.c b/net/core/dev.c
index f15a3ff..ab93577 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1744,6 +1744,7 @@
 	struct softnet_data *queue = &__get_cpu_var(softnet_data);
 	unsigned long start_time = jiffies;
 
+	backlog_dev->weight = weight_p;
 	for (;;) {
 		struct sk_buff *skb;
 		struct net_device *dev;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 8ec4848..a3eeb88 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -356,7 +356,7 @@
 {
 	struct ethtool_coalesce coalesce;
 
-	if (!dev->ethtool_ops->get_coalesce)
+	if (!dev->ethtool_ops->set_coalesce)
 		return -EOPNOTSUPP;
 
 	if (copy_from_user(&coalesce, useraddr, sizeof(coalesce)))
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 910eb4c..e2137f3 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -185,6 +185,22 @@
 static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, 
 			 store_tx_queue_len);
 
+NETDEVICE_SHOW(weight, fmt_dec);
+
+static int change_weight(struct net_device *net, unsigned long new_weight)
+{
+	net->weight = new_weight;
+	return 0;
+}
+
+static ssize_t store_weight(struct class_device *dev, const char *buf, size_t len)
+{
+	return netdev_store(dev, buf, len, change_weight);
+}
+
+static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, 
+			 store_weight);
+
 
 static struct class_device_attribute *net_class_attributes[] = {
 	&class_device_attr_ifindex,
@@ -194,6 +210,7 @@
 	&class_device_attr_features,
 	&class_device_attr_mtu,
 	&class_device_attr_flags,
+	&class_device_attr_weight,
 	&class_device_attr_type,
 	&class_device_attr_address,
 	&class_device_attr_broadcast,
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 3b1c9fa..ba3b0c2 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -882,6 +882,7 @@
 	t->parms.hop_limit = p->hop_limit;
 	t->parms.encap_limit = p->encap_limit;
 	t->parms.flowinfo = p->flowinfo;
+	t->parms.link = p->link;
 	ip6ip6_tnl_link_config(t);
 	return 0;
 }
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index b094118..b22c9be 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -405,7 +405,7 @@
 	---help---
 	  Size of the local stack variable used while evaluating the tree of
 	  ematches. Limits the depth of the tree, i.e. the number of
-	  encapsulated precedences. Every level requires 4 bytes of addtional
+	  encapsulated precedences. Every level requires 4 bytes of additional
 	  stack space.
 
 config NET_EMATCH_CMP
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 0d2d441..dfb300b 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -261,6 +261,9 @@
 	rta = (struct rtattr *) b;
 	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
 
+	if (f->res.classid)
+		RTA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid);
+
 	if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 ||
 	    tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
 		goto rtattr_failure;
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index f1eeaf6..48bb23c 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -32,7 +32,7 @@
  * 	      +-----------+                           +-----------+
  * 	            |                                       |
  * 	            ---> meta_ops[INT][INDEV](...)          |
- *                            |                            |
+ *	                      |                             |
  * 	            -----------                             |
  * 	            V                                       V
  * 	      +-----------+                           +-----------+
@@ -70,6 +70,7 @@
 #include <net/dst.h>
 #include <net/route.h>
 #include <net/pkt_cls.h>
+#include <net/sock.h>
 
 struct meta_obj
 {
@@ -284,6 +285,214 @@
 }
 
 /**************************************************************************
+ * Socket Attributes
+ **************************************************************************/
+
+#define SKIP_NONLOCAL(skb)			\
+	if (unlikely(skb->sk == NULL)) {	\
+		*err = -1;			\
+		return;				\
+	}
+
+META_COLLECTOR(int_sk_family)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_family;
+}
+
+META_COLLECTOR(int_sk_state)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_state;
+}
+
+META_COLLECTOR(int_sk_reuse)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_reuse;
+}
+
+META_COLLECTOR(int_sk_bound_if)
+{
+	SKIP_NONLOCAL(skb);
+	/* No error if bound_dev_if is 0, legal userspace check */
+	dst->value = skb->sk->sk_bound_dev_if;
+}
+
+META_COLLECTOR(var_sk_bound_if)
+{
+	SKIP_NONLOCAL(skb);
+
+	 if (skb->sk->sk_bound_dev_if == 0) {
+		dst->value = (unsigned long) "any";
+		dst->len = 3;
+	 } else  {
+		struct net_device *dev;
+		
+		dev = dev_get_by_index(skb->sk->sk_bound_dev_if);
+		*err = var_dev(dev, dst);
+		if (dev)
+			dev_put(dev);
+	 }
+}
+
+META_COLLECTOR(int_sk_refcnt)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = atomic_read(&skb->sk->sk_refcnt);
+}
+
+META_COLLECTOR(int_sk_rcvbuf)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_rcvbuf;
+}
+
+META_COLLECTOR(int_sk_shutdown)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_shutdown;
+}
+
+META_COLLECTOR(int_sk_proto)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_protocol;
+}
+
+META_COLLECTOR(int_sk_type)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_type;
+}
+
+META_COLLECTOR(int_sk_rmem_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = atomic_read(&skb->sk->sk_rmem_alloc);
+}
+
+META_COLLECTOR(int_sk_wmem_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = atomic_read(&skb->sk->sk_wmem_alloc);
+}
+
+META_COLLECTOR(int_sk_omem_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = atomic_read(&skb->sk->sk_omem_alloc);
+}
+
+META_COLLECTOR(int_sk_rcv_qlen)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_receive_queue.qlen;
+}
+
+META_COLLECTOR(int_sk_snd_qlen)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_write_queue.qlen;
+}
+
+META_COLLECTOR(int_sk_wmem_queued)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_wmem_queued;
+}
+
+META_COLLECTOR(int_sk_fwd_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_forward_alloc;
+}
+
+META_COLLECTOR(int_sk_sndbuf)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_sndbuf;
+}
+
+META_COLLECTOR(int_sk_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_allocation;
+}
+
+META_COLLECTOR(int_sk_route_caps)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_route_caps;
+}
+
+META_COLLECTOR(int_sk_hashent)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_hashent;
+}
+
+META_COLLECTOR(int_sk_lingertime)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_lingertime / HZ;
+}
+
+META_COLLECTOR(int_sk_err_qlen)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_error_queue.qlen;
+}
+
+META_COLLECTOR(int_sk_ack_bl)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_ack_backlog;
+}
+
+META_COLLECTOR(int_sk_max_ack_bl)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_max_ack_backlog;
+}
+
+META_COLLECTOR(int_sk_prio)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_priority;
+}
+
+META_COLLECTOR(int_sk_rcvlowat)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_rcvlowat;
+}
+
+META_COLLECTOR(int_sk_rcvtimeo)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_rcvtimeo / HZ;
+}
+
+META_COLLECTOR(int_sk_sndtimeo)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_sndtimeo / HZ;
+}
+
+META_COLLECTOR(int_sk_sendmsg_off)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_sndmsg_off;
+}
+
+META_COLLECTOR(int_sk_write_pend)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_write_pending;
+}
+
+/**************************************************************************
  * Meta value collectors assignment table
  **************************************************************************/
 
@@ -293,41 +502,75 @@
 			       struct meta_value *, struct meta_obj *, int *);
 };
 
+#define META_ID(name) TCF_META_ID_##name
+#define META_FUNC(name) { .get = meta_##name }
+
 /* Meta value operations table listing all meta value collectors and
  * assigns them to a type and meta id. */
 static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
 	[TCF_META_TYPE_VAR] = {
-		[TCF_META_ID_DEV]	= { .get = meta_var_dev },
-		[TCF_META_ID_INDEV]	= { .get = meta_var_indev },
-		[TCF_META_ID_REALDEV]	= { .get = meta_var_realdev }
+		[META_ID(DEV)]			= META_FUNC(var_dev),
+		[META_ID(INDEV)]		= META_FUNC(var_indev),
+		[META_ID(REALDEV)]		= META_FUNC(var_realdev),
+		[META_ID(SK_BOUND_IF)] 		= META_FUNC(var_sk_bound_if),
 	},
 	[TCF_META_TYPE_INT] = {
-		[TCF_META_ID_RANDOM]	= { .get = meta_int_random },
-		[TCF_META_ID_LOADAVG_0]	= { .get = meta_int_loadavg_0 },
-		[TCF_META_ID_LOADAVG_1]	= { .get = meta_int_loadavg_1 },
-		[TCF_META_ID_LOADAVG_2]	= { .get = meta_int_loadavg_2 },
-		[TCF_META_ID_DEV]	= { .get = meta_int_dev },
-		[TCF_META_ID_INDEV]	= { .get = meta_int_indev },
-		[TCF_META_ID_REALDEV]	= { .get = meta_int_realdev },
-		[TCF_META_ID_PRIORITY]	= { .get = meta_int_priority },
-		[TCF_META_ID_PROTOCOL]	= { .get = meta_int_protocol },
-		[TCF_META_ID_SECURITY]	= { .get = meta_int_security },
-		[TCF_META_ID_PKTTYPE]	= { .get = meta_int_pkttype },
-		[TCF_META_ID_PKTLEN]	= { .get = meta_int_pktlen },
-		[TCF_META_ID_DATALEN]	= { .get = meta_int_datalen },
-		[TCF_META_ID_MACLEN]	= { .get = meta_int_maclen },
+		[META_ID(RANDOM)]		= META_FUNC(int_random),
+		[META_ID(LOADAVG_0)]		= META_FUNC(int_loadavg_0),
+		[META_ID(LOADAVG_1)]		= META_FUNC(int_loadavg_1),
+		[META_ID(LOADAVG_2)]		= META_FUNC(int_loadavg_2),
+		[META_ID(DEV)]			= META_FUNC(int_dev),
+		[META_ID(INDEV)]		= META_FUNC(int_indev),
+		[META_ID(REALDEV)]		= META_FUNC(int_realdev),
+		[META_ID(PRIORITY)]		= META_FUNC(int_priority),
+		[META_ID(PROTOCOL)]		= META_FUNC(int_protocol),
+		[META_ID(SECURITY)]		= META_FUNC(int_security),
+		[META_ID(PKTTYPE)]		= META_FUNC(int_pkttype),
+		[META_ID(PKTLEN)]		= META_FUNC(int_pktlen),
+		[META_ID(DATALEN)]		= META_FUNC(int_datalen),
+		[META_ID(MACLEN)]		= META_FUNC(int_maclen),
 #ifdef CONFIG_NETFILTER
-		[TCF_META_ID_NFMARK]	= { .get = meta_int_nfmark },
+		[META_ID(NFMARK)]		= META_FUNC(int_nfmark),
 #endif
-		[TCF_META_ID_TCINDEX]	= { .get = meta_int_tcindex },
+		[META_ID(TCINDEX)]		= META_FUNC(int_tcindex),
 #ifdef CONFIG_NET_CLS_ACT
-		[TCF_META_ID_TCVERDICT]	= { .get = meta_int_tcverd },
-		[TCF_META_ID_TCCLASSID]	= { .get = meta_int_tcclassid },
+		[META_ID(TCVERDICT)]		= META_FUNC(int_tcverd),
+		[META_ID(TCCLASSID)]		= META_FUNC(int_tcclassid),
 #endif
 #ifdef CONFIG_NET_CLS_ROUTE
-		[TCF_META_ID_RTCLASSID]	= { .get = meta_int_rtclassid },
+		[META_ID(RTCLASSID)]		= META_FUNC(int_rtclassid),
 #endif
-		[TCF_META_ID_RTIIF]	= { .get = meta_int_rtiif }
+		[META_ID(RTIIF)]		= META_FUNC(int_rtiif),
+		[META_ID(SK_FAMILY)]		= META_FUNC(int_sk_family),
+		[META_ID(SK_STATE)]		= META_FUNC(int_sk_state),
+		[META_ID(SK_REUSE)]		= META_FUNC(int_sk_reuse),
+		[META_ID(SK_BOUND_IF)]		= META_FUNC(int_sk_bound_if),
+		[META_ID(SK_REFCNT)]		= META_FUNC(int_sk_refcnt),
+		[META_ID(SK_RCVBUF)]		= META_FUNC(int_sk_rcvbuf),
+		[META_ID(SK_SNDBUF)]		= META_FUNC(int_sk_sndbuf),
+		[META_ID(SK_SHUTDOWN)]		= META_FUNC(int_sk_shutdown),
+		[META_ID(SK_PROTO)]		= META_FUNC(int_sk_proto),
+		[META_ID(SK_TYPE)]		= META_FUNC(int_sk_type),
+		[META_ID(SK_RMEM_ALLOC)]	= META_FUNC(int_sk_rmem_alloc),
+		[META_ID(SK_WMEM_ALLOC)]	= META_FUNC(int_sk_wmem_alloc),
+		[META_ID(SK_OMEM_ALLOC)]	= META_FUNC(int_sk_omem_alloc),
+		[META_ID(SK_WMEM_QUEUED)]	= META_FUNC(int_sk_wmem_queued),
+		[META_ID(SK_RCV_QLEN)]		= META_FUNC(int_sk_rcv_qlen),
+		[META_ID(SK_SND_QLEN)]		= META_FUNC(int_sk_snd_qlen),
+		[META_ID(SK_ERR_QLEN)]		= META_FUNC(int_sk_err_qlen),
+		[META_ID(SK_FORWARD_ALLOCS)]	= META_FUNC(int_sk_fwd_alloc),
+		[META_ID(SK_ALLOCS)]		= META_FUNC(int_sk_alloc),
+		[META_ID(SK_ROUTE_CAPS)]	= META_FUNC(int_sk_route_caps),
+		[META_ID(SK_HASHENT)]		= META_FUNC(int_sk_hashent),
+		[META_ID(SK_LINGERTIME)]	= META_FUNC(int_sk_lingertime),
+		[META_ID(SK_ACK_BACKLOG)]	= META_FUNC(int_sk_ack_bl),
+		[META_ID(SK_MAX_ACK_BACKLOG)]	= META_FUNC(int_sk_max_ack_bl),
+		[META_ID(SK_PRIO)]		= META_FUNC(int_sk_prio),
+		[META_ID(SK_RCVLOWAT)]		= META_FUNC(int_sk_rcvlowat),
+		[META_ID(SK_RCVTIMEO)]		= META_FUNC(int_sk_rcvtimeo),
+		[META_ID(SK_SNDTIMEO)]		= META_FUNC(int_sk_sndtimeo),
+		[META_ID(SK_SENDMSG_OFF)]	= META_FUNC(int_sk_sendmsg_off),
+		[META_ID(SK_WRITE_PENDING)]	= META_FUNC(int_sk_write_pend),
 	}
 };
 
@@ -396,9 +639,9 @@
 	/* Let gcc optimize it, the unlikely is not really based on
 	 * some numbers but jump free code for mismatches seems
 	 * more logical. */
-	if (unlikely(a == b))
+	if (unlikely(a->value == b->value))
 		return 0;
-	else if (a < b)
+	else if (a->value < b->value)
 		return -1;
 	else
 		return 1;