Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge

* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge:
  powerpc: Fix various syscall/signal/swapcontext bugs
  [PATCH] powerpc: incorrect rmo_top handling in prom_init
  [PATCH] powerpc: Fix incorrect pud_ERROR() message
  [PATCH] powerpc: Expose SMT and L1 icache snoop userland features
  [PATCH] powerpc: Fix windfarm_pm112 not starting all control loops
  [PATCH] powerpc: Fix old g5 issues with windfarm
  powerpc32: Fix timebase synchronization on 32-bit powermacs
  powerpc: Turn off verbose debug output in powermac platform functions
  powerpc: Fix might-sleep warning in program check exception handler
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 840aad4..c9a660e 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -92,7 +92,6 @@
 
 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
 	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
-	DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame));
 	DEFINE(TI_TASK, offsetof(struct thread_info, task));
 #ifdef CONFIG_PPC32
 	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 1069645..e4e8137 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -53,8 +53,10 @@
 				 PPC_FEATURE_HAS_MMU)
 #define COMMON_USER_PPC64	(COMMON_USER | PPC_FEATURE_64)
 #define COMMON_USER_POWER4	(COMMON_USER_PPC64 | PPC_FEATURE_POWER4)
-#define COMMON_USER_POWER5	(COMMON_USER_PPC64 | PPC_FEATURE_POWER5)
-#define COMMON_USER_POWER5_PLUS	(COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS)
+#define COMMON_USER_POWER5	(COMMON_USER_PPC64 | PPC_FEATURE_POWER5 |\
+				 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
+#define COMMON_USER_POWER5_PLUS	(COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS|\
+				 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
 #define COMMON_USER_BOOKE	(PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
 				 PPC_FEATURE_BOOKE)
 
@@ -267,7 +269,8 @@
 		.cpu_name		= "Cell Broadband Engine",
 		.cpu_features		= CPU_FTRS_CELL,
 		.cpu_user_features	= COMMON_USER_PPC64 |
-			PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP,
+			PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP |
+			PPC_FEATURE_SMT,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.cpu_setup		= __setup_cpu_be,
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index f20a672..4827ca1 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -227,7 +227,7 @@
 	MTMSRD(r10)
 	lwz	r9,TI_FLAGS(r12)
 	li	r8,-_LAST_ERRNO
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK)
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
 	bne-	syscall_exit_work
 	cmplw	0,r3,r8
 	blt+	syscall_exit_cont
@@ -287,8 +287,10 @@
 
 syscall_exit_work:
 	andi.	r0,r9,_TIF_RESTOREALL
-	bne-	2f
-	cmplw	0,r3,r8
+	beq+	0f
+	REST_NVGPRS(r1)
+	b	2f
+0:	cmplw	0,r3,r8
 	blt+	1f
 	andi.	r0,r9,_TIF_NOERROR
 	bne-	1f
@@ -302,9 +304,7 @@
 2:	andi.	r0,r9,(_TIF_PERSYSCALL_MASK)
 	beq	4f
 
-	/* Clear per-syscall TIF flags if any are set, but _leave_
-	_TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
-	yet.  */
+	/* Clear per-syscall TIF flags if any are set.  */
 
 	li	r11,_TIF_PERSYSCALL_MASK
 	addi	r12,r12,TI_FLAGS
@@ -318,8 +318,13 @@
 	subi	r12,r12,TI_FLAGS
 	
 4:	/* Anything which requires enabling interrupts? */
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
-	beq	7f
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+	beq	ret_from_except
+
+	/* Re-enable interrupts */
+	ori	r10,r10,MSR_EE
+	SYNC
+	MTMSRD(r10)
 
 	/* Save NVGPRS if they're not saved already */
 	lwz	r4,_TRAP(r1)
@@ -328,71 +333,11 @@
 	SAVE_NVGPRS(r1)
 	li	r4,0xc00
 	stw	r4,_TRAP(r1)
-
-	/* Re-enable interrupts */
-5:	ori	r10,r10,MSR_EE
-	SYNC
-	MTMSRD(r10)
-
-	andi.	r0,r9,_TIF_SAVE_NVGPRS
-	bne	save_user_nvgprs
-
-save_user_nvgprs_cont:
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
-	beq	7f
-
+5:
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	do_syscall_trace_leave
-	REST_NVGPRS(r1)
+	b	ret_from_except_full
 
-6:	lwz	r3,GPR3(r1)
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
-	SYNC
-	MTMSRD(r10)		/* disable interrupts again */
-	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
-	lwz	r9,TI_FLAGS(r12)
-7:
-	andi.	r0,r9,_TIF_NEED_RESCHED
-	bne	8f
-	lwz	r5,_MSR(r1)
-	andi.	r5,r5,MSR_PR
-	beq	ret_from_except
-	andi.	r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
-	beq	ret_from_except
-	b	do_user_signal
-8:
-	ori	r10,r10,MSR_EE
-	SYNC
-	MTMSRD(r10)		/* re-enable interrupts */
-	bl	schedule
-	b	6b
-
-save_user_nvgprs:
-	lwz	r8,TI_SIGFRAME(r12)
-
-.macro savewords start, end
-  1:	stw \start,4*(\start)(r8)
-	.section __ex_table,"a"
-	.align	2
-	.long	1b,save_user_nvgprs_fault
-	.previous
-	.if \end - \start
-	savewords "(\start+1)",\end
-	.endif
-.endm	
-	savewords 14,31
-	b	save_user_nvgprs_cont
-
-	
-save_user_nvgprs_fault:
-	li	r3,11		/* SIGSEGV */
-	lwz	r4,TI_TASK(r12)
-	bl	force_sigsegv
-
-	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
-	lwz	r9,TI_FLAGS(r12)
-	b	save_user_nvgprs_cont
-	
 #ifdef SHOW_SYSCALLS
 do_show_syscall:
 #ifdef SHOW_SYSCALLS_TASK
@@ -490,6 +435,14 @@
 	stw	r0,_TRAP(r1)		/* register set saved */
 	b	sys_clone
 
+	.globl	ppc_swapcontext
+ppc_swapcontext:
+	SAVE_NVGPRS(r1)
+	lwz	r0,_TRAP(r1)
+	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
+	stw	r0,_TRAP(r1)		/* register set saved */
+	b	sys_swapcontext
+
 /*
  * Top-level page fault handling.
  * This is in assembler because if do_page_fault tells us that
@@ -683,7 +636,7 @@
 	/* Check current_thread_info()->flags */
 	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
 	lwz	r9,TI_FLAGS(r9)
-	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK)
+	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED)
 	bne	do_work
 
 restore_user:
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 388f861..24be0cf 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -160,7 +160,7 @@
 	mtmsrd	r10,1
 	ld	r9,TI_FLAGS(r12)
 	li	r11,-_LAST_ERRNO
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR|_TIF_RESTORE_SIGMASK)
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
 	bne-	syscall_exit_work
 	cmpld	r3,r11
 	ld	r5,_CCR(r1)
@@ -216,8 +216,10 @@
 	 If TIF_NOERROR is set, just save r3 as it is. */
 
 	andi.	r0,r9,_TIF_RESTOREALL
-	bne-	2f
-	cmpld	r3,r11		/* r10 is -LAST_ERRNO */
+	beq+	0f
+	REST_NVGPRS(r1)
+	b	2f
+0:	cmpld	r3,r11		/* r10 is -LAST_ERRNO */
 	blt+	1f
 	andi.	r0,r9,_TIF_NOERROR
 	bne-	1f
@@ -229,9 +231,7 @@
 2:	andi.	r0,r9,(_TIF_PERSYSCALL_MASK)
 	beq	4f
 
-	/* Clear per-syscall TIF flags if any are set, but _leave_
-	_TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
-	yet.  */
+	/* Clear per-syscall TIF flags if any are set.  */
 
 	li	r11,_TIF_PERSYSCALL_MASK
 	addi	r12,r12,TI_FLAGS
@@ -240,10 +240,9 @@
 	stdcx.	r10,0,r12
 	bne-	3b
 	subi	r12,r12,TI_FLAGS
-	
-4:	bl	.save_nvgprs
-	/* Anything else left to do? */
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
+
+4:	/* Anything else left to do? */
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
 	beq	.ret_from_except_lite
 
 	/* Re-enable interrupts */
@@ -251,26 +250,10 @@
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10,1
 
-	andi.	r0,r9,_TIF_SAVE_NVGPRS
-	bne	save_user_nvgprs
-
-	/* If tracing, re-enable interrupts and do it */
-save_user_nvgprs_cont:	
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
-	beq	5f
-	
+	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_syscall_trace_leave
-	REST_NVGPRS(r1)
-	clrrdi	r12,r1,THREAD_SHIFT
-
-	/* Disable interrupts again and handle other work if any */
-5:	mfmsr	r10
-	rldicl	r10,r10,48,1
-	rotldi	r10,r10,16
-	mtmsrd	r10,1
-
-	b	.ret_from_except_lite
+	b	.ret_from_except
 
 /* Save non-volatile GPRs, if not already saved. */
 _GLOBAL(save_nvgprs)
@@ -282,51 +265,6 @@
 	std	r0,_TRAP(r1)
 	blr
 
-
-save_user_nvgprs:
-	ld	r10,TI_SIGFRAME(r12)
-	andi.	r0,r9,_TIF_32BIT
-	beq-	save_user_nvgprs_64
-
-	/* 32-bit save to userspace */
-
-.macro savewords start, end
-  1:	stw \start,4*(\start)(r10)
-	.section __ex_table,"a"
-	.align	3
-	.llong	1b,save_user_nvgprs_fault
-	.previous
-	.if \end - \start
-	savewords "(\start+1)",\end
-	.endif
-.endm	
-	savewords 14,31
-	b	save_user_nvgprs_cont
-
-save_user_nvgprs_64:
-	/* 64-bit save to userspace */
-
-.macro savelongs start, end
-  1:	std \start,8*(\start)(r10)
-	.section __ex_table,"a"
-	.align	3
-	.llong	1b,save_user_nvgprs_fault
-	.previous
-	.if \end - \start
-	savelongs "(\start+1)",\end
-	.endif
-.endm	
-	savelongs 14,31
-	b	save_user_nvgprs_cont
-
-save_user_nvgprs_fault:
-	li	r3,11		/* SIGSEGV */
-	ld	r4,TI_TASK(r12)
-	bl	.force_sigsegv
-
-	clrrdi	r12,r1,THREAD_SHIFT
-	ld	r9,TI_FLAGS(r12)
-	b	save_user_nvgprs_cont
 	
 /*
  * The sigsuspend and rt_sigsuspend system calls can call do_signal
@@ -352,6 +290,16 @@
 	bl	.sys_clone
 	b	syscall_exit
 
+_GLOBAL(ppc32_swapcontext)
+	bl	.save_nvgprs
+	bl	.compat_sys_swapcontext
+	b	syscall_exit
+
+_GLOBAL(ppc64_swapcontext)
+	bl	.save_nvgprs
+	bl	.sys_swapcontext
+	b	syscall_exit
+
 _GLOBAL(ret_from_fork)
 	bl	.schedule_tail
 	REST_NVGPRS(r1)
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index d34fe53..813c2cd 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -978,7 +978,7 @@
 			if (size == 0)
 				continue;
 			prom_debug("    %x %x\n", base, size);
-			if (base == 0)
+			if (base == 0 && (RELOC(of_platform) & PLATFORM_LPAR))
 				RELOC(rmo_top) = size;
 			if ((base + size) > RELOC(ram_top))
 				RELOC(ram_top) = base + size;
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 400793c..bcb8357 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -561,10 +561,7 @@
 				   regs->result);
 
 	if ((test_thread_flag(TIF_SYSCALL_TRACE)
-#ifdef CONFIG_PPC64
-	     || test_thread_flag(TIF_SINGLESTEP)
-#endif
-	     )
+	     || test_thread_flag(TIF_SINGLESTEP))
 	    && (current->ptrace & PT_PTRACED))
 		do_syscall_trace();
 }
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index bd837b5d..d7a4e81 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -151,10 +151,7 @@
 	elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
 	int i;
 
-	if (!FULL_REGS(regs)) {
-		set_thread_flag(TIF_SAVE_NVGPRS);
-		current_thread_info()->nvgprs_frame = frame->mc_gregs;
-	}
+	WARN_ON(!FULL_REGS(regs));
 
 	for (i = 0; i <= PT_RESULT; i ++) {
 		if (i == 14 && !FULL_REGS(regs))
@@ -215,15 +212,7 @@
 static inline int save_general_regs(struct pt_regs *regs,
 		struct mcontext __user *frame)
 {
-	if (!FULL_REGS(regs)) {
-		/* Zero out the unsaved GPRs to avoid information
-		   leak, and set TIF_SAVE_NVGPRS to ensure that the
-		   registers do actually get saved later. */
-		memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
-		current_thread_info()->nvgprs_frame = &frame->mc_gregs;
-		set_thread_flag(TIF_SAVE_NVGPRS);
-	}
-
+	WARN_ON(!FULL_REGS(regs));
 	return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
 }
 
@@ -826,8 +815,8 @@
 }
 
 long sys_swapcontext(struct ucontext __user *old_ctx,
-		       struct ucontext __user *new_ctx,
-		       int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
+		     struct ucontext __user *new_ctx,
+		     int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
 {
 	unsigned char tmp;
 
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 497a5d3..4324f8a 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -118,14 +118,7 @@
 	err |= __put_user(0, &sc->v_regs);
 #endif /* CONFIG_ALTIVEC */
 	err |= __put_user(&sc->gp_regs, &sc->regs);
-	if (!FULL_REGS(regs)) {
-		/* Zero out the unsaved GPRs to avoid information
-		   leak, and set TIF_SAVE_NVGPRS to ensure that the
-		   registers do actually get saved later. */
-		memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
-		set_thread_flag(TIF_SAVE_NVGPRS);
-		current_thread_info()->nvgprs_frame = &sc->gp_regs;
-	}
+	WARN_ON(!FULL_REGS(regs));
 	err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
 	err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE);
 	err |= __put_user(signr, &sc->signal);
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 8a9f994..1ad55f0 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -288,7 +288,7 @@
 COMPAT_SYS(clock_gettime)
 COMPAT_SYS(clock_getres)
 COMPAT_SYS(clock_nanosleep)
-COMPAT_SYS(swapcontext)
+SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext)
 COMPAT_SYS(tgkill)
 COMPAT_SYS(utimes)
 COMPAT_SYS(statfs64)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 7509aa6..98660ae 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -814,6 +814,8 @@
 		return;
 	}
 
+	local_irq_enable();
+
 	/* Try to emulate it if we should. */
 	if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
 		switch (emulate_instruction(regs)) {
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
index 4ffd2a98..9b7150f 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -9,7 +9,12 @@
 #include <asm/pmac_feature.h>
 #include <asm/pmac_pfunc.h>
 
+#undef DEBUG
+#ifdef DEBUG
 #define DBG(fmt...)	printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
 
 static irqreturn_t macio_gpio_irq(int irq, void *data, struct pt_regs *regs)
 {
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index 356a739..4baa75b 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -20,7 +20,13 @@
 #define LOG_PARSE(fmt...)
 #define LOG_ERROR(fmt...)	printk(fmt)
 #define LOG_BLOB(t,b,c)
+
+#undef DEBUG
+#ifdef DEBUG
 #define DBG(fmt...)		printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
 
 /* Command numbers */
 #define PMF_CMD_LIST			0
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 0df2cdc..6d64a9b 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -435,7 +435,7 @@
  */
 
 static void (*pmac_tb_freeze)(int freeze);
-static unsigned long timebase;
+static u64 timebase;
 static int tb_req;
 
 static void smp_core99_give_timebase(void)
diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c
index 7964bf6..77e4dc7 100644
--- a/arch/ppc/kernel/asm-offsets.c
+++ b/arch/ppc/kernel/asm-offsets.c
@@ -131,7 +131,6 @@
 	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
 	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
 
-	DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame));
 	DEFINE(TI_TASK, offsetof(struct thread_info, task));
 	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index a48b950..3a28159 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -227,7 +227,7 @@
 	MTMSRD(r10)
 	lwz	r9,TI_FLAGS(r12)
 	li	r8,-_LAST_ERRNO
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
 	bne-	syscall_exit_work
 	cmplw	0,r3,r8
 	blt+	syscall_exit_cont
@@ -287,8 +287,10 @@
 
 syscall_exit_work:
 	andi.	r0,r9,_TIF_RESTOREALL
-	bne-	2f
-	cmplw	0,r3,r8
+	beq+	0f
+	REST_NVGPRS(r1)
+	b	2f
+0:	cmplw	0,r3,r8
 	blt+	1f
 	andi.	r0,r9,_TIF_NOERROR
 	bne-	1f
@@ -302,9 +304,7 @@
 2:	andi.	r0,r9,(_TIF_PERSYSCALL_MASK)
 	beq	4f
 
-	/* Clear per-syscall TIF flags if any are set, but _leave_
-	_TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
-	yet.  */
+	/* Clear per-syscall TIF flags if any are set.  */
 
 	li	r11,_TIF_PERSYSCALL_MASK
 	addi	r12,r12,TI_FLAGS
@@ -318,8 +318,13 @@
 	subi	r12,r12,TI_FLAGS
 	
 4:	/* Anything which requires enabling interrupts? */
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
-	beq	7f
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+	beq	ret_from_except
+
+	/* Re-enable interrupts */
+	ori	r10,r10,MSR_EE
+	SYNC
+	MTMSRD(r10)
 
 	/* Save NVGPRS if they're not saved already */
 	lwz	r4,TRAP(r1)
@@ -328,71 +333,11 @@
 	SAVE_NVGPRS(r1)
 	li	r4,0xc00
 	stw	r4,TRAP(r1)
-
-	/* Re-enable interrupts */
-5:	ori	r10,r10,MSR_EE
-	SYNC
-	MTMSRD(r10)
-
-	andi.	r0,r9,_TIF_SAVE_NVGPRS
-	bne	save_user_nvgprs
-
-save_user_nvgprs_cont:
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
-	beq	7f
-
+5:
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	do_syscall_trace_leave
-	REST_NVGPRS(r1)
+	b	ret_from_except_full
 
-6:	lwz	r3,GPR3(r1)
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
-	SYNC
-	MTMSRD(r10)		/* disable interrupts again */
-	rlwinm	r12,r1,0,0,18	/* current_thread_info() */
-	lwz	r9,TI_FLAGS(r12)
-7:
-	andi.	r0,r9,_TIF_NEED_RESCHED
-	bne	8f
-	lwz	r5,_MSR(r1)
-	andi.	r5,r5,MSR_PR
-	beq	ret_from_except
-	andi.	r0,r9,_TIF_SIGPENDING
-	beq	ret_from_except
-	b	do_user_signal
-8:
-	ori	r10,r10,MSR_EE
-	SYNC
-	MTMSRD(r10)		/* re-enable interrupts */
-	bl	schedule
-	b	6b
-
-save_user_nvgprs:
-	lwz	r8,TI_SIGFRAME(r12)
-
-.macro savewords start, end
-  1:	stw \start,4*(\start)(r8)
-	.section __ex_table,"a"
-	.align	2
-	.long	1b,save_user_nvgprs_fault
-	.previous
-	.if \end - \start
-	savewords "(\start+1)",\end
-	.endif
-.endm	
-	savewords 14,31
-	b	save_user_nvgprs_cont
-
-	
-save_user_nvgprs_fault:
-	li	r3,11		/* SIGSEGV */
-	lwz	r4,TI_TASK(r12)
-	bl	force_sigsegv
-
-	rlwinm	r12,r1,0,0,18	/* current_thread_info() */
-	lwz	r9,TI_FLAGS(r12)
-	b	save_user_nvgprs_cont
-	
 #ifdef SHOW_SYSCALLS
 do_show_syscall:
 #ifdef SHOW_SYSCALLS_TASK
@@ -490,6 +435,14 @@
 	stw	r0,TRAP(r1)		/* register set saved */
 	b	sys_clone
 
+	.globl	ppc_swapcontext
+ppc_swapcontext:
+	SAVE_NVGPRS(r1)
+	lwz	r0,TRAP(r1)
+	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
+	stw	r0,TRAP(r1)		/* register set saved */
+	b	sys_swapcontext
+
 /*
  * Top-level page fault handling.
  * This is in assembler because if do_page_fault tells us that
@@ -683,7 +636,7 @@
 	/* Check current_thread_info()->flags */
 	rlwinm	r9,r1,0,0,18
 	lwz	r9,TI_FLAGS(r9)
-	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
+	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED)
 	bne	do_work
 
 restore_user:
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index bb8d5ef..6c0ba04 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -35,6 +35,8 @@
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 
+#include <asm/prom.h>
+
 #include "windfarm.h"
 
 #define VERSION "0.2"
@@ -465,6 +467,11 @@
 {
 	DBG("wf: core loaded\n");
 
+	/* Don't register on old machines that use therm_pm72 for now */
+	if (machine_is_compatible("PowerMac7,2") ||
+	    machine_is_compatible("PowerMac7,3") ||
+	    machine_is_compatible("RackMac3,1"))
+		return -ENODEV;
 	platform_device_register(&wf_platform_device);
 	return 0;
 }
diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c
index 607dbac..81337cd 100644
--- a/drivers/macintosh/windfarm_cpufreq_clamp.c
+++ b/drivers/macintosh/windfarm_cpufreq_clamp.c
@@ -8,6 +8,8 @@
 #include <linux/wait.h>
 #include <linux/cpufreq.h>
 
+#include <asm/prom.h>
+
 #include "windfarm.h"
 
 #define VERSION "0.3"
@@ -74,6 +76,12 @@
 {
 	struct wf_control *clamp;
 
+	/* Don't register on old machines that use therm_pm72 for now */
+	if (machine_is_compatible("PowerMac7,2") ||
+	    machine_is_compatible("PowerMac7,3") ||
+	    machine_is_compatible("RackMac3,1"))
+		return -ENODEV;
+
 	clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);
 	if (clamp == NULL)
 		return -ENOMEM;
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index 906d3ec..423bfa24 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -25,7 +25,7 @@
 
 #include "windfarm.h"
 
-#define VERSION "0.1"
+#define VERSION "0.2"
 
 #undef DEBUG
 
@@ -113,6 +113,7 @@
 					     const char *loc)
 {
 	struct wf_lm75_sensor *lm;
+	int rc;
 
 	DBG("wf_lm75: creating  %s device at address 0x%02x\n",
 	    ds1775 ? "ds1775" : "lm75", addr);
@@ -139,9 +140,11 @@
 	lm->i2c.driver = &wf_lm75_driver;
 	strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1);
 
-	if (i2c_attach_client(&lm->i2c)) {
-		printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
-		       ds1775 ? "ds1775" : "lm75", lm->i2c.name);
+	rc = i2c_attach_client(&lm->i2c);
+	if (rc) {
+		printk(KERN_ERR "windfarm: failed to attach %s %s to i2c,"
+		       " err %d\n", ds1775 ? "ds1775" : "lm75",
+		       lm->i2c.name, rc);
 		goto fail;
 	}
 
@@ -175,16 +178,22 @@
 	     (dev = of_get_next_child(busnode, dev)) != NULL;) {
 		const char *loc =
 			get_property(dev, "hwsensor-location", NULL);
-		u32 *reg = (u32 *)get_property(dev, "reg", NULL);
-		DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg);
-		if (loc == NULL || reg == NULL)
+		u8 addr;
+
+		/* We must re-match the adapter in order to properly check
+		 * the channel on multibus setups
+		 */
+		if (!pmac_i2c_match_adapter(dev, adapter))
+			continue;
+		addr = pmac_i2c_get_dev_addr(dev);
+		if (loc == NULL || addr == 0)
 			continue;
 		/* real lm75 */
 		if (device_is_compatible(dev, "lm75"))
-			wf_lm75_create(adapter, *reg, 0, loc);
+			wf_lm75_create(adapter, addr, 0, loc);
 		/* ds1775 (compatible, better resolution */
 		else if (device_is_compatible(dev, "ds1775"))
-			wf_lm75_create(adapter, *reg, 1, loc);
+			wf_lm75_create(adapter, addr, 1, loc);
 	}
 	return 0;
 }
@@ -206,6 +215,11 @@
 
 static int __init wf_lm75_sensor_init(void)
 {
+	/* Don't register on old machines that use therm_pm72 for now */
+	if (machine_is_compatible("PowerMac7,2") ||
+	    machine_is_compatible("PowerMac7,3") ||
+	    machine_is_compatible("RackMac3,1"))
+		return -ENODEV;
 	return i2c_add_driver(&wf_lm75_driver);
 }
 
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index 5b9ad6ca..8e99d40 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -17,7 +17,7 @@
 
 #include "windfarm.h"
 
-#define VERSION "0.1"
+#define VERSION "0.2"
 
 /* This currently only exports the external temperature sensor,
    since that's all the control loops need. */
@@ -81,7 +81,7 @@
 static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr)
 {
 	struct wf_6690_sensor *max;
-	char *name = "u4-temp";
+	char *name = "backside-temp";
 
 	max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
 	if (max == NULL) {
@@ -118,7 +118,6 @@
 	struct device_node *busnode, *dev = NULL;
 	struct pmac_i2c_bus *bus;
 	const char *loc;
-	u32 *reg;
 
 	bus = pmac_i2c_adapter_to_bus(adapter);
 	if (bus == NULL)
@@ -126,16 +125,23 @@
 	busnode = pmac_i2c_get_bus_node(bus);
 
 	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
+		u8 addr;
+
+		/* We must re-match the adapter in order to properly check
+		 * the channel on multibus setups
+		 */
+		if (!pmac_i2c_match_adapter(dev, adapter))
+			continue;
 		if (!device_is_compatible(dev, "max6690"))
 			continue;
+		addr = pmac_i2c_get_dev_addr(dev);
 		loc = get_property(dev, "hwsensor-location", NULL);
-		reg = (u32 *) get_property(dev, "reg", NULL);
-		if (!loc || !reg)
+		if (loc == NULL || addr == 0)
 			continue;
-		printk("found max6690, loc=%s reg=%x\n", loc, *reg);
+		printk("found max6690, loc=%s addr=0x%02x\n", loc, addr);
 		if (strcmp(loc, "BACKSIDE"))
 			continue;
-		wf_max6690_create(adapter, *reg);
+		wf_max6690_create(adapter, addr);
 	}
 
 	return 0;
@@ -153,6 +159,11 @@
 
 static int __init wf_max6690_sensor_init(void)
 {
+	/* Don't register on old machines that use therm_pm72 for now */
+	if (machine_is_compatible("PowerMac7,2") ||
+	    machine_is_compatible("PowerMac7,3") ||
+	    machine_is_compatible("RackMac3,1"))
+		return -ENODEV;
 	return i2c_add_driver(&wf_max6690_driver);
 }
 
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c
index c2a4e68..ef66bf2 100644
--- a/drivers/macintosh/windfarm_pm112.c
+++ b/drivers/macintosh/windfarm_pm112.c
@@ -358,6 +358,7 @@
 		return;
 	if (!backside_tick) {
 		/* first time; initialize things */
+		printk(KERN_INFO "windfarm: Backside control loop started.\n");
 		backside_param.min = backside_fan->ops->get_min(backside_fan);
 		backside_param.max = backside_fan->ops->get_max(backside_fan);
 		wf_pid_init(&backside_pid, &backside_param);
@@ -407,6 +408,7 @@
 		return;
 	if (!drive_bay_tick) {
 		/* first time; initialize things */
+		printk(KERN_INFO "windfarm: Drive bay control loop started.\n");
 		drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan);
 		drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan);
 		wf_pid_init(&drive_bay_pid, &drive_bay_prm);
@@ -458,6 +460,7 @@
 		return;
 	if (!slots_started) {
 		/* first time; initialize things */
+		printk(KERN_INFO "windfarm: Slots control loop started.\n");
 		wf_pid_init(&slots_pid, &slots_param);
 		slots_started = 1;
 	}
@@ -504,6 +507,7 @@
 
 	if (!started) {
 		started = 1;
+		printk(KERN_INFO "windfarm: CPUs control loops started.\n");
 		for (i = 0; i < nr_cores; ++i) {
 			if (create_cpu_loop(i) < 0) {
 				failure_state = FAILURE_PERM;
@@ -594,8 +598,6 @@
 {
 	unsigned int i;
 
-	if (have_all_sensors)
-		return;
 	if (!strncmp(sr->name, "cpu-temp-", 9)) {
 		i = sr->name[9] - '0';
 		if (sr->name[10] == 0 && i < NR_CORES &&
@@ -613,7 +615,7 @@
 	} else if (!strcmp(sr->name, "slots-power")) {
 		if (slots_power == NULL && wf_get_sensor(sr) == 0)
 			slots_power = sr;
-	} else if (!strcmp(sr->name, "u4-temp")) {
+	} else if (!strcmp(sr->name, "backside-temp")) {
 		if (u4_temp == NULL && wf_get_sensor(sr) == 0)
 			u4_temp = sr;
 	} else
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 90d005b..5638518 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -20,6 +20,8 @@
 #define PPC_FEATURE_POWER5_PLUS		0x00020000
 #define PPC_FEATURE_CELL		0x00010000
 #define PPC_FEATURE_BOOKE		0x00008000
+#define PPC_FEATURE_SMT			0x00004000
+#define PPC_FEATURE_ICACHE_SNOOP	0x00002000
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
diff --git a/include/asm-powerpc/pgtable-4k.h b/include/asm-powerpc/pgtable-4k.h
index e9590c0..80a7832 100644
--- a/include/asm-powerpc/pgtable-4k.h
+++ b/include/asm-powerpc/pgtable-4k.h
@@ -88,4 +88,4 @@
     (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)))
 
 #define pud_ERROR(e) \
-	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pud_val(e))
+	printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index 237fc2b..ffc7462 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -37,7 +37,6 @@
 	int		preempt_count;		/* 0 => preemptable,
 						   <0 => BUG */
 	struct restart_block restart_block;
-	void __user *nvgprs_frame;
 	/* low level flags - has atomic operations done on it */
 	unsigned long	flags ____cacheline_aligned_in_smp;
 };
@@ -120,7 +119,6 @@
 #define TIF_MEMDIE		10
 #define TIF_SECCOMP		11	/* secure computing */
 #define TIF_RESTOREALL		12	/* Restore all regs (implies NOERROR) */
-#define TIF_SAVE_NVGPRS		13	/* Save r14-r31 in signal frame */
 #define TIF_NOERROR		14	/* Force successful syscall return */
 #define TIF_RESTORE_SIGMASK	15	/* Restore signal mask in do_signal */
 
@@ -137,15 +135,13 @@
 #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_RESTOREALL		(1<<TIF_RESTOREALL)
-#define _TIF_SAVE_NVGPRS	(1<<TIF_SAVE_NVGPRS)
 #define _TIF_NOERROR		(1<<TIF_NOERROR)
 #define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
 #define _TIF_USER_WORK_MASK	(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
-				 _TIF_NEED_RESCHED | _TIF_RESTOREALL | \
-				 _TIF_RESTORE_SIGMASK)
-#define _TIF_PERSYSCALL_MASK	(_TIF_RESTOREALL|_TIF_NOERROR|_TIF_SAVE_NVGPRS)
+				 _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK)
+#define _TIF_PERSYSCALL_MASK	(_TIF_RESTOREALL|_TIF_NOERROR)
 
 #endif /* __KERNEL__ */