Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fix

* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fix:
  sparc64: fix alignment bug in linker definition script
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 5c8695a..2d7ea850 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -62,7 +62,7 @@
 What:	old NCR53C9x driver
 When:	October 2007
 Why:	Replaced by the much better esp_scsi driver.  Actual low-level
-	driver can ported over almost trivially.
+	driver can be ported over almost trivially.
 Who:	David Miller <davem@davemloft.net>
 	Christoph Hellwig <hch@lst.de>
 
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index aae2282..ce91560 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1132,9 +1132,9 @@
 			when set.
 			Format: <int>
 
-	noaliencache	[MM, NUMA] Disables the allcoation of alien caches in
-			the slab allocator.  Saves per-node memory, but will
-			impact performance on real NUMA hardware.
+	noaliencache	[MM, NUMA, SLAB] Disables the allocation of alien
+			caches in the slab allocator.  Saves per-node memory,
+			but will impact performance.
 
 	noalign		[KNL,ARM]
 
@@ -1613,6 +1613,37 @@
 
 	slram=		[HW,MTD]
 
+	slub_debug	[MM, SLUB]
+			Enabling slub_debug allows one to determine the culprit
+			if slab objects become corrupted. Enabling slub_debug
+			creates guard zones around objects and poisons objects
+			when not in use. Also tracks the last alloc / free.
+			For more information see Documentation/vm/slub.txt.
+
+	slub_max_order= [MM, SLUB]
+			Determines the maximum allowed order for slabs. Setting
+			this too high may cause fragmentation.
+			For more information see Documentation/vm/slub.txt.
+
+	slub_min_objects=	[MM, SLUB]
+			The minimum objects per slab. SLUB will increase the
+			slab order up to slub_max_order to generate a
+			sufficiently big slab to satisfy the number of objects.
+			The higher the number of objects the smaller the overhead
+			of tracking slabs.
+			For more information see Documentation/vm/slub.txt.
+
+	slub_min_order=	[MM, SLUB]
+			Determines the mininum page order for slabs. Must be
+			lower than slub_max_order
+			For more information see Documentation/vm/slub.txt.
+
+	slub_nomerge	[MM, SLUB]
+			Disable merging of slabs of similar size. May be
+			necessary if there is some reason to distinguish
+			allocs to different slabs.
+			For more information see Documentation/vm/slub.txt.
+
 	smart2=		[HW]
 			Format: <io1>[,<io2>[,...,<io8>]]
 
diff --git a/Documentation/networking/xfrm_sysctl.txt b/Documentation/networking/xfrm_sysctl.txt
new file mode 100644
index 0000000..5bbd167
--- /dev/null
+++ b/Documentation/networking/xfrm_sysctl.txt
@@ -0,0 +1,4 @@
+/proc/sys/net/core/xfrm_* Variables:
+
+xfrm_acq_expires - INTEGER
+	default 30 - hard timeout in seconds for acquire requests
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 57b878c..355ff0a 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -917,6 +917,7 @@
 	  ref		Reference board, base config
 	  m2-2		Some Gateway MX series laptops
 	  m6		Some Gateway NX series laptops
+	  pa6		Gateway NX860 series
 
 	STAC9227/9228/9229/927x
 	  ref		Reference board
diff --git a/Documentation/vm/slub.txt b/Documentation/vm/slub.txt
index 727c8d8..1523320 100644
--- a/Documentation/vm/slub.txt
+++ b/Documentation/vm/slub.txt
@@ -1,13 +1,9 @@
 Short users guide for SLUB
 --------------------------
 
-First of all slub should transparently replace SLAB. If you enable
-SLUB then everything should work the same (Note the word "should".
-There is likely not much value in that word at this point).
-
 The basic philosophy of SLUB is very different from SLAB. SLAB
 requires rebuilding the kernel to activate debug options for all
-SLABS. SLUB always includes full debugging but its off by default.
+slab caches. SLUB always includes full debugging but it is off by default.
 SLUB can enable debugging only for selected slabs in order to avoid
 an impact on overall system performance which may make a bug more
 difficult to find.
@@ -76,13 +72,28 @@
 Careful with tracing: It may spew out lots of information and never stop if
 used on the wrong slab.
 
-SLAB Merging
+Slab merging
 ------------
 
-If no debugging is specified then SLUB may merge similar slabs together
+If no debug options are specified then SLUB may merge similar slabs together
 in order to reduce overhead and increase cache hotness of objects.
 slabinfo -a displays which slabs were merged together.
 
+Slab validation
+---------------
+
+SLUB can validate all object if the kernel was booted with slub_debug. In
+order to do so you must have the slabinfo tool. Then you can do
+
+slabinfo -v
+
+which will test all objects. Output will be generated to the syslog.
+
+This also works in a more limited way if boot was without slab debug.
+In that case slabinfo -v simply tests all reachable objects. Usually
+these are in the cpu slabs and the partial slabs. Full slabs are not
+tracked by SLUB in a non debug situation.
+
 Getting more performance
 ------------------------
 
@@ -91,9 +102,9 @@
 governed by the order of the allocation for each slab. The allocations
 can be influenced by kernel parameters:
 
-slub_min_objects=x		(default 8)
+slub_min_objects=x		(default 4)
 slub_min_order=x		(default 0)
-slub_max_order=x		(default 4)
+slub_max_order=x		(default 1)
 
 slub_min_objects allows to specify how many objects must at least fit
 into one slab in order for the allocation order to be acceptable.
@@ -109,5 +120,107 @@
 super large order pages to fit slub_min_objects of a slab cache with
 large object sizes into one high order page.
 
+SLUB Debug output
+-----------------
 
-Christoph Lameter, <clameter@sgi.com>, April 10, 2007
+Here is a sample of slub debug output:
+
+*** SLUB kmalloc-8: Redzone Active@0xc90f6d20 slab 0xc528c530 offset=3360 flags=0x400000c3 inuse=61 freelist=0xc90f6d58
+  Bytes b4 0xc90f6d10:  00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ
+    Object 0xc90f6d20:  31 30 31 39 2e 30 30 35                         1019.005
+   Redzone 0xc90f6d28:  00 cc cc cc                                     .
+FreePointer 0xc90f6d2c -> 0xc90f6d58
+Last alloc: get_modalias+0x61/0xf5 jiffies_ago=53 cpu=1 pid=554
+Filler 0xc90f6d50:  5a 5a 5a 5a 5a 5a 5a 5a                         ZZZZZZZZ
+  [<c010523d>] dump_trace+0x63/0x1eb
+  [<c01053df>] show_trace_log_lvl+0x1a/0x2f
+  [<c010601d>] show_trace+0x12/0x14
+  [<c0106035>] dump_stack+0x16/0x18
+  [<c017e0fa>] object_err+0x143/0x14b
+  [<c017e2cc>] check_object+0x66/0x234
+  [<c017eb43>] __slab_free+0x239/0x384
+  [<c017f446>] kfree+0xa6/0xc6
+  [<c02e2335>] get_modalias+0xb9/0xf5
+  [<c02e23b7>] dmi_dev_uevent+0x27/0x3c
+  [<c027866a>] dev_uevent+0x1ad/0x1da
+  [<c0205024>] kobject_uevent_env+0x20a/0x45b
+  [<c020527f>] kobject_uevent+0xa/0xf
+  [<c02779f1>] store_uevent+0x4f/0x58
+  [<c027758e>] dev_attr_store+0x29/0x2f
+  [<c01bec4f>] sysfs_write_file+0x16e/0x19c
+  [<c0183ba7>] vfs_write+0xd1/0x15a
+  [<c01841d7>] sys_write+0x3d/0x72
+  [<c0104112>] sysenter_past_esp+0x5f/0x99
+  [<b7f7b410>] 0xb7f7b410
+  =======================
+@@@ SLUB kmalloc-8: Restoring redzone (0xcc) from 0xc90f6d28-0xc90f6d2b
+
+
+
+If SLUB encounters a corrupted object then it will perform the following
+actions:
+
+1. Isolation and report of the issue
+
+This will be a message in the system log starting with
+
+*** SLUB <slab cache affected>: <What went wrong>@<object address>
+offset=<offset of object into slab> flags=<slabflags>
+inuse=<objects in use in this slab> freelist=<first free object in slab>
+
+2. Report on how the problem was dealt with in order to ensure the continued
+operation of the system.
+
+These are messages in the system log beginning with
+
+@@@ SLUB <slab cache affected>: <corrective action taken>
+
+
+In the above sample SLUB found that the Redzone of an active object has
+been overwritten. Here a string of 8 characters was written into a slab that
+has the length of 8 characters. However, a 8 character string needs a
+terminating 0. That zero has overwritten the first byte of the Redzone field.
+After reporting the details of the issue encountered the @@@ SLUB message
+tell us that SLUB has restored the redzone to its proper value and then
+system operations continue.
+
+Various types of lines can follow the @@@ SLUB line:
+
+Bytes b4 <address> : <bytes>
+	Show a few bytes before the object where the problem was detected.
+	Can be useful if the corruption does not stop with the start of the
+	object.
+
+Object <address> : <bytes>
+	The bytes of the object. If the object is inactive then the bytes
+	typically contain poisoning values. Any non-poison value shows a
+	corruption by a write after free.
+
+Redzone <address> : <bytes>
+	The redzone following the object. The redzone is used to detect
+	writes after the object. All bytes should always have the same
+	value. If there is any deviation then it is due to a write after
+	the object boundary.
+
+Freepointer
+	The pointer to the next free object in the slab. May become
+	corrupted if overwriting continues after the red zone.
+
+Last alloc:
+Last free:
+	Shows the address from which the object was allocated/freed last.
+	We note the pid, the time and the CPU that did so. This is usually
+	the most useful information to figure out where things went wrong.
+	Here get_modalias() did an kmalloc(8) instead of a kmalloc(9).
+
+Filler <address> : <bytes>
+	Unused data to fill up the space in order to get the next object
+	properly aligned. In the debug case we make sure that there are
+	at least 4 bytes of filler. This allow for the detection of writes
+	before the object.
+
+Following the filler will be a stackdump. That stackdump describes the
+location where the error was detected. The cause of the corruption is more
+likely to be found by looking at the information about the last alloc / free.
+
+Christoph Lameter, <clameter@sgi.com>, May 23, 2007
diff --git a/MAINTAINERS b/MAINTAINERS
index 953291d..4cc17b9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2334,7 +2334,7 @@
 
 MEGARAID SCSI DRIVERS
 P:	Neela Syam Kolli
-M:	Neela.Kolli@engenio.com
+M:	megaraidlinux@lsi.com
 S:	linux-scsi@vger.kernel.org
 W:	http://megaraid.lsilogic.com
 S:	Maintained
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index c95e95e..debc8f0 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -391,11 +391,10 @@
 	bne	$2, $work_resched
 
 $work_notifysig:
-	mov	$sp, $17
+	mov	$sp, $16
 	br	$1, do_switch_stack
-	mov	$5, $21
-	mov	$sp, $18
-	mov	$31, $16
+	mov	$sp, $17
+	mov	$5, $18
 	jsr	$26, do_notify_resume
 	bsr	$1, undo_switch_stack
 	br	restore_all
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 6e7d1fe..28c84e5 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/log2.h>
 
 #include <asm/io.h>
 #include <asm/hwrpb.h>
@@ -53,7 +54,7 @@
 {
 	unsigned long mem = max_low_pfn << PAGE_SHIFT;
 	if (mem < max)
-		max = 1UL << ceil_log2(mem);
+		max = roundup_pow_of_two(mem);
 	return max;
 }
 
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 915f263..bd5e68c 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -43,6 +43,7 @@
 #include <linux/notifier.h>
 #include <asm/setup.h>
 #include <asm/io.h>
+#include <linux/log2.h>
 
 extern struct atomic_notifier_head panic_notifier_list;
 static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
@@ -1303,7 +1304,7 @@
 	long size = minsize, maxsize = MAX_BCACHE_SIZE * 2;
 
 	if (maxsize > (max_low_pfn + 1) << PAGE_SHIFT)
-		maxsize = 1 << (floor_log2(max_low_pfn + 1) + PAGE_SHIFT);
+		maxsize = 1 << (ilog2(max_low_pfn + 1) + PAGE_SHIFT);
 
 	/* Get the first block cached. */
 	read_mem_block(__va(0), stride, size);
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 7f64aa7..410af4f 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -32,8 +32,8 @@
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 asmlinkage void ret_from_sys_call(void);
-static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *,
-		     unsigned long, unsigned long);
+static void do_signal(struct pt_regs *, struct switch_stack *,
+		      unsigned long, unsigned long);
 
 
 /*
@@ -146,11 +146,9 @@
 asmlinkage int
 do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
 {
-	sigset_t oldset;
-
 	mask &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	oldset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
@@ -160,19 +158,17 @@
 	regs->r0 = EINTR;
 	regs->r19 = 1;
 
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&oldset, regs, sw, 0, 0))
-			return -EINTR;
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
 }
 
 asmlinkage int
 do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
 		 struct pt_regs *regs, struct switch_stack *sw)
 {
-	sigset_t oldset, set;
+	sigset_t set;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
 	if (sigsetsize != sizeof(sigset_t))
@@ -182,7 +178,7 @@
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sighand->siglock);
-	oldset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	current->blocked = set;
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
@@ -192,12 +188,10 @@
 	regs->r0 = EINTR;
 	regs->r19 = 1;
 
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&oldset, regs, sw, 0, 0))
-			return -EINTR;
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
 }
 
 asmlinkage int
@@ -436,7 +430,7 @@
 	return err;
 }
 
-static void
+static int
 setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
 	    struct pt_regs *regs, struct switch_stack * sw)
 {
@@ -481,13 +475,14 @@
 		current->comm, current->pid, frame, regs->pc, regs->r26);
 #endif
 
-	return;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
-static void
+static int
 setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	       sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
 {
@@ -543,34 +538,38 @@
 		current->comm, current->pid, frame, regs->pc, regs->r26);
 #endif
 
-	return;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
 
 /*
  * OK, we're invoking a handler.
  */
-static inline void
+static inline int
 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	      sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw)
 {
+	int ret;
+
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(sig, ka, info, oldset, regs, sw);
+		ret = setup_rt_frame(sig, ka, info, oldset, regs, sw);
 	else
-		setup_frame(sig, ka, oldset, regs, sw);
+		ret = setup_frame(sig, ka, oldset, regs, sw);
 
-	if (ka->sa.sa_flags & SA_RESETHAND)
-		ka->sa.sa_handler = SIG_DFL;
+	if (ret == 0) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		if (!(ka->sa.sa_flags & SA_NODEFER)) 
+			sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER)) 
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	return ret;
 }
 
 static inline void
@@ -611,30 +610,42 @@
  * restart. "r0" is also used as an indicator whether we can restart at
  * all (if we get here from anything but a syscall return, it will be 0)
  */
-static int
-do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
+static void
+do_signal(struct pt_regs * regs, struct switch_stack * sw,
 	  unsigned long r0, unsigned long r19)
 {
 	siginfo_t info;
 	int signr;
 	unsigned long single_stepping = ptrace_cancel_bpt(current);
 	struct k_sigaction ka;
+	sigset_t *oldset;
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
 		oldset = &current->blocked;
 
 	/* This lets the debugger run, ... */
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
 	/* ... so re-check the single stepping. */
 	single_stepping |= ptrace_cancel_bpt(current);
 
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
-		if (r0) syscall_restart(r0, r19, regs, &ka);
-		handle_signal(signr, &ka, &info, oldset, regs, sw);
+		if (r0)
+			syscall_restart(r0, r19, regs, &ka);
+		if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) {
+			/* A signal was successfully delivered, and the
+			   saved sigmask was stored on the signal frame,
+			   and will be restored by sigreturn.  So we can
+			   simply clear the restore sigmask flag.  */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
 		if (single_stepping) 
 			ptrace_set_bpt(current); /* re-set bpt */
-		return 1;
+		return;
 	}
 
 	if (r0) {
@@ -654,17 +665,22 @@
 			break;
 		}
 	}
+
+	/* If there's no signal to deliver, we just restore the saved mask.  */
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
+
 	if (single_stepping)
 		ptrace_set_bpt(current);	/* re-set breakpoint */
-
-	return 0;
 }
 
 void
-do_notify_resume(sigset_t *oldset, struct pt_regs *regs,
-		 struct switch_stack *sw, unsigned long r0,
-		 unsigned long r19, unsigned long thread_info_flags)
+do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
+		 unsigned long thread_info_flags,
+		 unsigned long r0, unsigned long r19)
 {
-	if (thread_info_flags & _TIF_SIGPENDING)
-		do_signal(oldset, regs, sw, r0, r19);
+	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+		do_signal(regs, sw, r0, r19);
 }
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S
index f6cfe8c..79de99e3 100644
--- a/arch/alpha/kernel/systbls.S
+++ b/arch/alpha/kernel/systbls.S
@@ -465,6 +465,38 @@
 	.quad sys_inotify_init
 	.quad sys_inotify_add_watch		/* 445 */
 	.quad sys_inotify_rm_watch
+	.quad sys_fdatasync
+	.quad sys_kexec_load
+	.quad sys_migrate_pages
+	.quad sys_openat			/* 450 */
+	.quad sys_mkdirat
+	.quad sys_mknodat
+	.quad sys_fchownat
+	.quad sys_futimesat
+	.quad sys_fstatat64			/* 455 */
+	.quad sys_unlinkat
+	.quad sys_renameat
+	.quad sys_linkat
+	.quad sys_symlinkat
+	.quad sys_readlinkat			/* 460 */
+	.quad sys_fchmodat
+	.quad sys_faccessat
+	.quad sys_pselect6
+	.quad sys_ppoll
+	.quad sys_unshare			/* 465 */
+	.quad sys_set_robust_list
+	.quad sys_get_robust_list
+	.quad sys_splice
+	.quad sys_sync_file_range
+	.quad sys_tee				/* 470 */
+	.quad sys_vmsplice
+	.quad sys_move_pages
+	.quad sys_getcpu
+	.quad sys_epoll_pwait
+	.quad sys_utimensat			/* 475 */
+	.quad sys_signalfd
+	.quad sys_timerfd
+	.quad sys_eventfd
 
 	.size sys_call_table, . - sys_call_table
 	.type sys_call_table, @object
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
index ea098f3..266f78e 100644
--- a/arch/alpha/lib/Makefile
+++ b/arch/alpha/lib/Makefile
@@ -37,7 +37,8 @@
 	$(ev6-y)clear_page.o \
 	$(ev6-y)copy_page.o \
 	fpreg.o \
-	callback_srm.o srm_puts.o srm_printk.o
+	callback_srm.o srm_puts.o srm_printk.o \
+	fls.o
 
 lib-$(CONFIG_SMP) += dec_and_lock.o
 
diff --git a/arch/alpha/lib/fls.c b/arch/alpha/lib/fls.c
new file mode 100644
index 0000000..7ad84ea
--- /dev/null
+++ b/arch/alpha/lib/fls.c
@@ -0,0 +1,38 @@
+/* 
+ * arch/alpha/lib/fls.c
+ */
+
+#include <linux/module.h>
+#include <asm/bitops.h>
+
+/* This is fls(x)-1, except zero is held to zero.  This allows most
+   efficent input into extbl, plus it allows easy handling of fls(0)=0.  */
+
+const unsigned char __flsm1_tab[256] = 
+{
+  0,
+  0,
+  1, 1,
+  2, 2, 2, 2,
+  3, 3, 3, 3, 3, 3, 3, 3,
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+
+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+
+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+EXPORT_SYMBOL(__flsm1_tab);
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 9179e82..f73d62e 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -57,7 +57,7 @@
 #define EXPORT_SYMBOL_ALIAS(sym,orig)		\
  EXPORT_CRC_ALIAS(sym)				\
  static const struct kernel_symbol __ksymtab_##sym	\
-  __attribute_used__ __attribute__((section("__ksymtab"))) =	\
+  __used __attribute__((section("__ksymtab"))) =	\
     { (unsigned long)&orig, #sym };
 
 /*
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index 8b63ad8..ae31deb 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -13,7 +13,7 @@
 		/*
 		 * Check current frame pointer is within bounds
 		 */
-		if ((fp - 12) < low || fp + 4 >= high)
+		if (fp < (low + 12) || fp + 4 >= high)
 			break;
 
 		frame = (struct stackframe *)(fp - 12);
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
index 6043c38..af49789 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -132,7 +132,7 @@
 	},
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
 	*num_partitions = ARRAY_SIZE(dk_nand_partition);
 	return dk_nand_partition;
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c
index 76f6e1e..7d9b1a2 100644
--- a/arch/arm/mach-at91/board-kb9202.c
+++ b/arch/arm/mach-at91/board-kb9202.c
@@ -96,7 +96,7 @@
 	},
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
 	*num_partitions = ARRAY_SIZE(kb9202_nand_partition);
 	return kb9202_nand_partition;
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 1f0c8a4..26ca8ab3 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -178,7 +178,7 @@
 	},
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
 	*num_partitions = ARRAY_SIZE(ek_nand_partition);
 	return ek_nand_partition;
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index f574585..c164c8e 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -180,7 +180,7 @@
 	},
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
 	*num_partitions = ARRAY_SIZE(ek_nand_partition);
 	return ek_nand_partition;
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index 30c79ac..9b61320 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -87,7 +87,7 @@
 	},
 };
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
 	*num_partitions = ARRAY_SIZE(ek_nand_partition);
 	return ek_nand_partition;
diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c
index 4f984fd..35eb232 100644
--- a/arch/arm/mach-footbridge/cats-pci.c
+++ b/arch/arm/mach-footbridge/cats-pci.c
@@ -45,7 +45,7 @@
 	.postinit		= dc21285_postinit,
 };
 
-static int cats_pci_init(void)
+static int __init cats_pci_init(void)
 {
 	if (machine_is_cats())
 		pci_common_init(&cats_pci);
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index 7a7fa51..1c474cf 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -201,7 +201,6 @@
 {
 	imx_mmc_device.dev.platform_data = info;
 }
-EXPORT_SYMBOL(imx_set_mmc_info);
 
 static struct imxfb_mach_info imx_fb_info;
 
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
index 0fdd03a..ce7c15c 100644
--- a/arch/arm/mach-ixp2000/ixdp2400.c
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -164,7 +164,7 @@
 
 subsys_initcall(ixdp2400_pci_init);
 
-void ixdp2400_init_irq(void)
+void __init ixdp2400_init_irq(void)
 {
 	ixdp2x00_init_irq(IXDP2400_CPLD_INT_STAT, IXDP2400_CPLD_INT_MASK, IXDP2400_NR_IRQS);
 }
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index 70d247f..14f09b80 100644
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -279,7 +279,7 @@
 
 subsys_initcall(ixdp2800_pci_init);
 
-void ixdp2800_init_irq(void)
+void __init ixdp2800_init_irq(void)
 {
 	ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2800_NR_IRQS);
 }
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 011065b..73c651e 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -145,7 +145,7 @@
 	.unmask	= ixdp2x00_irq_unmask
 };
 
-void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs)
+void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs)
 {
 	unsigned int irq;
 
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index 7a86a25..c41a6b5 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -124,7 +124,7 @@
 	.unmask	= ixdp2351_intb_unmask
 };
 
-void ixdp2351_init_irq(void)
+void __init ixdp2351_init_irq(void)
 {
 	int irq;
 
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
index ac7d43d..227f808 100644
--- a/arch/arm/mach-ixp23xx/pci.c
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -284,7 +284,7 @@
 	return 1;
 }
 
-void ixp23xx_pci_slave_init(void)
+void __init ixp23xx_pci_slave_init(void)
 {
 	ixp23xx_pci_common_init();
 }
diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c
index d06e21b..e3564496 100644
--- a/arch/arm/mach-ixp23xx/roadrunner.c
+++ b/arch/arm/mach-ixp23xx/roadrunner.c
@@ -110,7 +110,7 @@
 	return NO_IRQ;
 }
 
-static void roadrunner_pci_preinit(void)
+static void __init roadrunner_pci_preinit(void)
 {
 	set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQT_LOW);
 	set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQT_LOW);
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 9715ef5..0609098 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -104,9 +104,6 @@
 	  DSM-G600 RevA device. For more information on this platform,
 	  see http://www.nslu2-linux.org/wiki/DSMG600/HomePage
 
-#
-# Avila and IXDP share the same source for now. Will change in future
-#
 config	ARCH_IXDP4XX
 	bool
 	depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 64685da..8112f72 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -283,7 +283,7 @@
 	.handler	= ixp4xx_timer_interrupt,
 };
 
-static void __init ixp4xx_timer_init(void)
+void __init ixp4xx_timer_init(void)
 {
 	/* Reset/disable counter */
 	*IXP4XX_OSRT1 = 0;
diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
index 7bc94f3..ad2e5b9 100644
--- a/arch/arm/mach-ixp4xx/coyote-pci.c
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -25,10 +25,6 @@
 
 #include <asm/mach/pci.h>
 
-extern void ixp4xx_pci_preinit(void);
-extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
-extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
-
 void __init coyote_pci_preinit(void)
 {
 	set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW);
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 1caff65..1e75e10 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -18,6 +18,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
+#include <asm/mach/time.h>
 
 static struct flash_platform_data dsmg600_flash_data = {
 	.map_name		= "cfi_probe",
@@ -128,6 +129,19 @@
 	gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH);
 }
 
+static void __init dsmg600_timer_init(void)
+{
+    /* The xtal on this machine is non-standard. */
+    ixp4xx_timer_freq = DSMG600_FREQ;
+
+    /* Call standard timer_init function. */
+    ixp4xx_timer_init();
+}
+
+static struct sys_timer dsmg600_timer = {
+    .init   = dsmg600_timer_init,
+};
+
 static void __init dsmg600_init(void)
 {
 	ixp4xx_sys_init();
@@ -155,21 +169,13 @@
 #endif
 }
 
-static void __init dsmg600_fixup(struct machine_desc *desc,
-                struct tag *tags, char **cmdline, struct meminfo *mi)
-{
-       /* The xtal on this machine is non-standard. */
-        ixp4xx_timer_freq = DSMG600_FREQ;
-}
-
 MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
 	/* Maintainer: www.nslu2-linux.org */
 	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
 	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
 	.boot_params	= 0x00000100,
-	.fixup          = dsmg600_fixup,
 	.map_io		= ixp4xx_map_io,
 	.init_irq	= ixp4xx_init_irq,
-	.timer          = &ixp4xx_timer,
+	.timer          = &dsmg600_timer,
 	.init_machine	= dsmg600_init,
 MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
index 509a95a..d1e75b7 100644
--- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
@@ -23,10 +23,6 @@
 
 #include <asm/mach/pci.h>
 
-extern void ixp4xx_pci_preinit(void);
-extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
-extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
-
 void __init ixdpg425_pci_preinit(void)
 {
 	set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW);
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 9a31444..78a1741 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -155,7 +155,8 @@
 
 	pm_power_off = nas100d_power_off;
 
-	/* This is only useful on a modified machine, but it is valuable
+	/*
+	 * This is only useful on a modified machine, but it is valuable
 	 * to have it first in order to see debug messages, and so that
 	 * it does *not* get removed if platform_add_devices fails!
 	 */
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index 162c266..9bf8ccb 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -22,6 +22,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
+#include <asm/mach/time.h>
 
 static struct flash_platform_data nslu2_flash_data = {
 	.map_name		= "cfi_probe",
@@ -49,26 +50,26 @@
 static struct resource nslu2_led_resources[] = {
 	{
 		.name		= "ready",  /* green led */
-		.start		= NSLU2_LED_GRN,
-		.end		= NSLU2_LED_GRN,
+		.start		= NSLU2_LED_GRN_GPIO,
+		.end		= NSLU2_LED_GRN_GPIO,
 		.flags		= IXP4XX_GPIO_HIGH,
 	},
 	{
 		.name		= "status", /* red led */
-		.start		= NSLU2_LED_RED,
-		.end		= NSLU2_LED_RED,
+		.start		= NSLU2_LED_RED_GPIO,
+		.end		= NSLU2_LED_RED_GPIO,
 		.flags		= IXP4XX_GPIO_HIGH,
 	},
 	{
 		.name		= "disk-1",
-		.start		= NSLU2_LED_DISK1,
-		.end		= NSLU2_LED_DISK1,
+		.start		= NSLU2_LED_DISK1_GPIO,
+		.end		= NSLU2_LED_DISK1_GPIO,
 		.flags		= IXP4XX_GPIO_LOW,
 	},
 	{
 		.name		= "disk-2",
-		.start		= NSLU2_LED_DISK2,
-		.end		= NSLU2_LED_DISK2,
+		.start		= NSLU2_LED_DISK2_GPIO,
+		.end		= NSLU2_LED_DISK2_GPIO,
 		.flags		= IXP4XX_GPIO_LOW,
 	},
 };
@@ -157,10 +158,21 @@
 	gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
 }
 
+static void __init nslu2_timer_init(void)
+{
+    /* The xtal on this machine is non-standard. */
+    ixp4xx_timer_freq = NSLU2_FREQ;
+
+    /* Call standard timer_init function. */
+    ixp4xx_timer_init();
+}
+
+static struct sys_timer nslu2_timer = {
+    .init   = nslu2_timer_init,
+};
+
 static void __init nslu2_init(void)
 {
-	ixp4xx_timer_freq = NSLU2_FREQ;
-
 	ixp4xx_sys_init();
 
 	nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
@@ -169,7 +181,8 @@
 
 	pm_power_off = nslu2_power_off;
 
-	/* This is only useful on a modified machine, but it is valuable
+	/*
+	 * This is only useful on a modified machine, but it is valuable
 	 * to have it first in order to see debug messages, and so that
 	 * it does *not* get removed if platform_add_devices fails!
 	 */
@@ -185,6 +198,6 @@
 	.boot_params	= 0x00000100,
 	.map_io		= ixp4xx_map_io,
 	.init_irq	= ixp4xx_init_irq,
-	.timer          = &ixp4xx_timer,
+	.timer          = &nslu2_timer,
 	.init_machine	= nslu2_init,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/bast.h b/arch/arm/mach-s3c2410/bast.h
deleted file mode 100644
index e985437..0000000
--- a/arch/arm/mach-s3c2410/bast.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/bast.h
-extern void bast_init_irq(void);
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index bc308ce..435adcc 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -160,7 +160,7 @@
 #endif
 };
 
-void __init amlm5900_map_io(void)
+static void __init amlm5900_map_io(void)
 {
 	s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
 	s3c24xx_init_clocks(0);
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index c602aa3..782b581 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
@@ -29,6 +30,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
+#include <asm/arch/reset.h>
 #include <asm/arch/idle.h>
 
 #include <asm/arch/regs-clock.h>
@@ -38,6 +40,7 @@
 #include <asm/arch/regs-gpioj.h>
 #include <asm/arch/regs-dsc.h>
 #include <asm/arch/regs-spi.h>
+#include <asm/arch/regs-s3c2412.h>
 
 #include <asm/plat-s3c24xx/s3c2412.h>
 #include <asm/plat-s3c24xx/cpu.h>
@@ -106,6 +109,23 @@
 	cpu_do_idle();
 }
 
+static void s3c2412_hard_reset(void)
+{
+	/* errata "Watch-dog/Software Reset Problem" specifies that
+	 * this reset must be done with the SYSCLK sourced from
+	 * EXTCLK instead of FOUT to avoid a glitch in the reset
+	 * mechanism.
+	 *
+	 * See the watchdog section of the S3C2412 manual for more
+	 * information on this fix.
+	 */
+
+	__raw_writel(0x00, S3C2412_CLKSRC);
+	__raw_writel(S3C2412_SWRST_RESET, S3C2412_SWRST);
+
+	mdelay(1);
+}
+
 /* s3c2412_map_io
  *
  * register the standard cpu IO areas, and any passed in from the
@@ -122,6 +142,10 @@
 
 	s3c24xx_idle = s3c2412_idle;
 
+	/* set custom reset hook */
+
+	s3c24xx_reset_hook = s3c2412_hard_reset;
+
 	/* register our io-tables */
 
 	iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 5955efb..5840294 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -394,7 +394,7 @@
 	return 0;
 }
 
-struct clk clk_usb_bus_host = {
+static struct clk clk_usb_bus_host = {
 	.name		= "usb-bus-host-parent",
 	.id		= -1,
 	.parent		= &clk_esysclk,
@@ -758,7 +758,6 @@
 		.parent		= &clk_h,
 		.enable		= s3c2443_clkcon_enable_h,
 		.ctrlbit	= S3C2443_HCLKCON_CFC,
-		.ctrlbit	= S3C2443_HCLKCON_HSMMC,
 	}, {
 		.name		= "ssmc",
 		.id		= -1,
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index d7c038a..4cbf946 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -139,12 +139,12 @@
 	return ret;
 }
 
-static struct sa1100_port_fns neponset_port_fns __initdata = {
+static struct sa1100_port_fns neponset_port_fns __devinitdata = {
 	.set_mctrl	= neponset_set_mctrl,
 	.get_mctrl	= neponset_get_mctrl,
 };
 
-static int neponset_probe(struct platform_device *dev)
+static int __devinit neponset_probe(struct platform_device *dev)
 {
 	sa1100_register_uart_fns(&neponset_port_fns);
 
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 5f472a8..e7904bc9 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -379,7 +379,7 @@
 	select CPU_CP15_MMU
 	select CPU_HAS_ASID
 	select CPU_COPY_V6 if MMU
-	select CPU_TLB_V6 if MMU
+	select CPU_TLB_V7 if MMU
 
 # Figure out what processor architecture version we should be using.
 # This defines the compiler instruction set which depends on the machine type.
@@ -498,6 +498,9 @@
 config CPU_TLB_V6
 	bool
 
+config CPU_TLB_V7
+	bool
+
 endif
 
 config CPU_HAS_ASID
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index b5bd335..7627027 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -46,6 +46,7 @@
 obj-$(CONFIG_CPU_TLB_V4WB)	+= tlb-v4wb.o
 obj-$(CONFIG_CPU_TLB_V4WBI)	+= tlb-v4wbi.o
 obj-$(CONFIG_CPU_TLB_V6)	+= tlb-v6.o
+obj-$(CONFIG_CPU_TLB_V7)	+= tlb-v7.o
 
 obj-$(CONFIG_CPU_ARM610)	+= proc-arm6_7.o
 obj-$(CONFIG_CPU_ARM710)	+= proc-arm6_7.o
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index dd823dd..718f478 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -256,7 +256,7 @@
 	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
 	.long	cpu_v7_name
 	.long	v7_processor_functions
-	.long	v6wbi_tlb_fns
+	.long	v7wbi_tlb_fns
 	.long	v6_user_fns
 	.long	v7_cache_fns
 	.size	__v7_proc_info, . - __v7_proc_info
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
new file mode 100644
index 0000000..b56dda8
--- /dev/null
+++ b/arch/arm/mm/tlb-v7.S
@@ -0,0 +1,88 @@
+/*
+ *  linux/arch/arm/mm/tlb-v7.S
+ *
+ *  Copyright (C) 1997-2002 Russell King
+ *  Modified for ARMv7 by Catalin Marinas
+ *
+ * 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.
+ *
+ *  ARM architecture version 6 TLB handling functions.
+ *  These assume a split I/D TLB.
+ */
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+/*
+ *	v7wbi_flush_user_tlb_range(start, end, vma)
+ *
+ *	Invalidate a range of TLB entries in the specified address space.
+ *
+ *	- start - start address (may not be aligned)
+ *	- end   - end address (exclusive, may not be aligned)
+ *	- vma   - vma_struct describing address range
+ *
+ *	It is assumed that:
+ *	- the "Invalidate single entry" instruction will invalidate
+ *	  both the I and the D TLBs on Harvard-style TLBs
+ */
+ENTRY(v7wbi_flush_user_tlb_range)
+	vma_vm_mm r3, r2			@ get vma->vm_mm
+	mmid	r3, r3				@ get vm_mm->context.id
+	dsb
+	mov	r0, r0, lsr #PAGE_SHIFT		@ align address
+	mov	r1, r1, lsr #PAGE_SHIFT
+	asid	r3, r3				@ mask ASID
+	orr	r0, r3, r0, lsl #PAGE_SHIFT	@ Create initial MVA
+	mov	r1, r1, lsl #PAGE_SHIFT
+	vma_vm_flags r2, r2			@ get vma->vm_flags
+1:
+	mcr	p15, 0, r0, c8, c6, 1		@ TLB invalidate D MVA (was 1)
+	tst	r2, #VM_EXEC			@ Executable area ?
+	mcrne	p15, 0, r0, c8, c5, 1		@ TLB invalidate I MVA (was 1)
+	add	r0, r0, #PAGE_SZ
+	cmp	r0, r1
+	blo	1b
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c5, 6		@ flush BTAC/BTB
+	dsb
+	mov	pc, lr
+
+/*
+ *	v7wbi_flush_kern_tlb_range(start,end)
+ *
+ *	Invalidate a range of kernel TLB entries
+ *
+ *	- start - start address (may not be aligned)
+ *	- end   - end address (exclusive, may not be aligned)
+ */
+ENTRY(v7wbi_flush_kern_tlb_range)
+	dsb
+	mov	r0, r0, lsr #PAGE_SHIFT		@ align address
+	mov	r1, r1, lsr #PAGE_SHIFT
+	mov	r0, r0, lsl #PAGE_SHIFT
+	mov	r1, r1, lsl #PAGE_SHIFT
+1:
+	mcr	p15, 0, r0, c8, c6, 1		@ TLB invalidate D MVA
+	mcr	p15, 0, r0, c8, c5, 1		@ TLB invalidate I MVA
+	add	r0, r0, #PAGE_SZ
+	cmp	r0, r1
+	blo	1b
+	mov	r2, #0
+	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
+	dsb
+	isb
+	mov	pc, lr
+
+	.section ".text.init", #alloc, #execinstr
+
+	.type	v7wbi_tlb_fns, #object
+ENTRY(v7wbi_tlb_fns)
+	.long	v7wbi_flush_user_tlb_range
+	.long	v7wbi_flush_kern_tlb_range
+	.long	v6wbi_tlb_flags
+	.size	v7wbi_tlb_fns, . - v7wbi_tlb_fns
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
index 0a30674..260fe29 100644
--- a/arch/arm/nwfpe/softfloat.h
+++ b/arch/arm/nwfpe/softfloat.h
@@ -273,4 +273,7 @@
 extern flag float32_is_nan( float32 a );
 extern flag float64_is_nan( float64 a );
 
+extern int32 float64_to_uint32( struct roundingData *roundData, float64 a );
+extern int32 float64_to_uint32_round_to_zero( float64 a );
+
 #endif
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c
index 8985007..7791da7 100644
--- a/arch/arm/oprofile/op_model_mpcore.c
+++ b/arch/arm/oprofile/op_model_mpcore.c
@@ -257,8 +257,13 @@
  */
 static void em_route_irq(int irq, unsigned int cpu)
 {
-	irq_desc[irq].affinity = cpumask_of_cpu(cpu);
-	irq_desc[irq].chip->set_affinity(irq, cpumask_of_cpu(cpu));
+	struct irq_desc *desc = irq_desc + irq;
+	cpumask_t mask = cpumask_of_cpu(cpu);
+
+	spin_lock_irq(&desc->lock);
+	desc->affinity = mask;
+	desc->chip->set_affinity(irq, mask);
+	spin_unlock_irq(&desc->lock);
 }
 
 static int em_setup(void)
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 08f07a7..88baed1 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -943,10 +943,9 @@
 
 static void smp_tune_scheduling(void)
 {
-	unsigned long cachesize;       /* kB   */
-
 	if (cpu_khz) {
-		cachesize = boot_cpu_data.x86_cache_size;
+		/* cache size in kB */
+		long cachesize = boot_cpu_data.x86_cache_size;
 
 		if (cachesize > 0)
 			max_cache_size = cachesize * 1024;
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index b8536c7c..85cdd23 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -355,8 +355,9 @@
 	  adventurous.
 
 config SINGLE_MEMORY_CHUNK
-	bool "Use one physical chunk of memory only"
-	depends on ADVANCED && !SUN3
+	bool "Use one physical chunk of memory only" if ADVANCED && !SUN3
+	default y if SUN3
+	select NEED_MULTIPLE_NODES
 	help
 	  Ignore all but the first contiguous chunk of physical memory for VM
 	  purposes.  This will save a few bytes kernel size and may speed up
@@ -377,6 +378,14 @@
 	  is hardwired on.  The 53c710 SCSI driver is known to suffer from
 	  this problem.
 
+config ARCH_DISCONTIGMEM_ENABLE
+	def_bool !SINGLE_MEMORY_CHUNK
+
+config NODES_SHIFT
+	int
+	default "3"
+	depends on !SINGLE_MEMORY_CHUNK
+
 source "mm/Kconfig"
 
 endmenu
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
index c20831a..aa383a5 100644
--- a/arch/m68k/Makefile
+++ b/arch/m68k/Makefile
@@ -19,6 +19,7 @@
 # override top level makefile
 AS += -m68020
 LDFLAGS := -m m68kelf
+LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
 ifneq ($(COMPILE_ARCH),$(ARCH))
 	# prefix for cross-compiling binaries
 	CROSS_COMPILE = m68k-linux-gnu-
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
index 0b68ab8..a806208 100644
--- a/arch/m68k/kernel/Makefile
+++ b/arch/m68k/kernel/Makefile
@@ -9,13 +9,12 @@
 endif
 extra-y	+= vmlinux.lds
 
-obj-y	:= entry.o process.o traps.o ints.o signal.o ptrace.o \
+obj-y	:= entry.o process.o traps.o ints.o signal.o ptrace.o module.o \
 	   sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o devres.o
 
 devres-y = ../../../kernel/irq/devres.o
 
 obj-$(CONFIG_PCI)	+= bios32.o
-obj-$(CONFIG_MODULES)	+= module.o
 obj-y$(CONFIG_MMU_SUN3) += dma.o	# no, it's not a typo
 
 EXTRA_AFLAGS := -traditional
diff --git a/arch/m68k/kernel/module.c b/arch/m68k/kernel/module.c
index 3b1a2ff..774862b 100644
--- a/arch/m68k/kernel/module.c
+++ b/arch/m68k/kernel/module.c
@@ -1,3 +1,9 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
 #include <linux/moduleloader.h>
 #include <linux/elf.h>
 #include <linux/vmalloc.h>
@@ -11,6 +17,8 @@
 #define DEBUGP(fmt...)
 #endif
 
+#ifdef CONFIG_MODULES
+
 void *module_alloc(unsigned long size)
 {
 	if (size == 0)
@@ -118,11 +126,32 @@
 
 int module_finalize(const Elf_Ehdr *hdr,
 		    const Elf_Shdr *sechdrs,
-		    struct module *me)
+		    struct module *mod)
 {
+	module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
+
 	return 0;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
 }
+
+#endif /* CONFIG_MODULES */
+
+void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+		  struct m68k_fixup_info *end)
+{
+	struct m68k_fixup_info *fixup;
+
+	for (fixup = start; fixup < end; fixup++) {
+		switch (fixup->type) {
+		case m68k_fixup_memoffset:
+			*(u32 *)fixup->addr = m68k_memoffset;
+			break;
+		case m68k_fixup_vnode_shift:
+			*(u16 *)fixup->addr += m68k_virt_to_node_shift;
+			break;
+		}
+	}
+}
diff --git a/arch/m68k/kernel/module.lds b/arch/m68k/kernel/module.lds
new file mode 100644
index 0000000..fda94fa
--- /dev/null
+++ b/arch/m68k/kernel/module.lds
@@ -0,0 +1,7 @@
+SECTIONS {
+	.m68k_fixup : {
+		__start_fixup = .;
+		*(.m68k_fixup)
+		__stop_fixup = .;
+	}
+}
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
index 6103193..215c7bd 100644
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -60,14 +60,12 @@
 int m68k_num_memory;
 int m68k_realnum_memory;
 EXPORT_SYMBOL(m68k_realnum_memory);
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
 unsigned long m68k_memoffset;
 EXPORT_SYMBOL(m68k_memoffset);
-#endif
 struct mem_info m68k_memory[NUM_MEMINFO];
 EXPORT_SYMBOL(m68k_memory);
 
-static struct mem_info m68k_ramdisk;
+struct mem_info m68k_ramdisk;
 
 static char m68k_command_line[CL_SIZE];
 
@@ -208,9 +206,6 @@
 void __init setup_arch(char **cmdline_p)
 {
 	extern int _etext, _edata, _end;
-#ifndef CONFIG_SUN3
-	unsigned long endmem, startmem;
-#endif
 	int i;
 
 	/* The bootinfo is located right after the kernel bss */
@@ -320,30 +315,16 @@
 		panic("No configuration setup");
 	}
 
+	paging_init();
+
 #ifndef CONFIG_SUN3
-	startmem= m68k_memory[0].addr;
-	endmem = startmem + m68k_memory[0].size;
-	high_memory = (void *)PAGE_OFFSET;
-	for (i = 0; i < m68k_num_memory; i++) {
-		m68k_memory[i].size &= MASK_256K;
-		if (m68k_memory[i].addr < startmem)
-			startmem = m68k_memory[i].addr;
-		if (m68k_memory[i].addr+m68k_memory[i].size > endmem)
-			endmem = m68k_memory[i].addr+m68k_memory[i].size;
-		high_memory += m68k_memory[i].size;
-	}
-
-	availmem += init_bootmem_node(NODE_DATA(0), availmem >> PAGE_SHIFT,
-				      startmem >> PAGE_SHIFT, endmem >> PAGE_SHIFT);
-
-	for (i = 0; i < m68k_num_memory; i++)
-		free_bootmem(m68k_memory[i].addr, m68k_memory[i].size);
-
-	reserve_bootmem(m68k_memory[0].addr, availmem - m68k_memory[0].addr);
-
+	for (i = 1; i < m68k_num_memory; i++)
+		free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
+				  m68k_memory[i].size);
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (m68k_ramdisk.size) {
-		reserve_bootmem(m68k_ramdisk.addr, m68k_ramdisk.size);
+		reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)),
+				     m68k_ramdisk.addr, m68k_ramdisk.size);
 		initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
 		initrd_end = initrd_start + m68k_ramdisk.size;
 		printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
@@ -362,8 +343,6 @@
 
 #endif /* !CONFIG_SUN3 */
 
-	paging_init();
-
 /* set ISA defs early as possible */
 #if defined(CONFIG_ISA) && defined(MULTI_ISA)
 #if defined(CONFIG_Q40)
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index 78f1392..40f02b1 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -60,6 +60,11 @@
   __con_initcall_start = .;
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
+  .m68k_fixup : {
+	__start_fixup = .;
+	*(.m68k_fixup)
+	__stop_fixup = .;
+  }
   SECURITY_INIT
 #ifdef CONFIG_BLK_DEV_INITRD
   . = ALIGN(8192);
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index c8999b2..f06425b 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -54,6 +54,11 @@
 	__con_initcall_start = .;
 	.con_initcall.init : { *(.con_initcall.init) }
 	__con_initcall_end = .;
+	.m68k_fixup : {
+		__start_fixup = .;
+		*(.m68k_fixup)
+		__stop_fixup = .;
+	}
 	SECURITY_INIT
 #ifdef CONFIG_BLK_DEV_INITRD
 	. = ALIGN(8192);
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
index ab90213..f1de19e 100644
--- a/arch/m68k/mm/init.c
+++ b/arch/m68k/mm/init.c
@@ -7,6 +7,7 @@
  *  to motorola.c and sun3mmu.c
  */
 
+#include <linux/module.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -31,6 +32,37 @@
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
+static bootmem_data_t __initdata bootmem_data[MAX_NUMNODES];
+
+pg_data_t pg_data_map[MAX_NUMNODES];
+EXPORT_SYMBOL(pg_data_map);
+
+int m68k_virt_to_node_shift;
+
+#ifndef CONFIG_SINGLE_MEMORY_CHUNK
+pg_data_t *pg_data_table[65];
+EXPORT_SYMBOL(pg_data_table);
+#endif
+
+void m68k_setup_node(int node)
+{
+#ifndef CONFIG_SINGLE_MEMORY_CHUNK
+	struct mem_info *info = m68k_memory + node;
+	int i, end;
+
+	i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift();
+	end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift();
+	for (; i <= end; i++) {
+		if (pg_data_table[i])
+			printk("overlap at %u for chunk %u\n", i, node);
+		pg_data_table[i] = pg_data_map + node;
+	}
+#endif
+	pg_data_map[node].bdata = bootmem_data + node;
+	node_set_online(node);
+}
+
+
 /*
  * ZERO_PAGE is a special page that is used for zero-initialized
  * data and COW.
@@ -40,52 +72,51 @@
 
 void show_mem(void)
 {
-    unsigned long i;
-    int free = 0, total = 0, reserved = 0, shared = 0;
-    int cached = 0;
+	pg_data_t *pgdat;
+	int free = 0, total = 0, reserved = 0, shared = 0;
+	int cached = 0;
+	int i;
 
-    printk("\nMem-info:\n");
-    show_free_areas();
-    printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-    i = max_mapnr;
-    while (i-- > 0) {
-	total++;
-	if (PageReserved(mem_map+i))
-	    reserved++;
-	else if (PageSwapCache(mem_map+i))
-	    cached++;
-	else if (!page_count(mem_map+i))
-	    free++;
-	else
-	    shared += page_count(mem_map+i) - 1;
-    }
-    printk("%d pages of RAM\n",total);
-    printk("%d free pages\n",free);
-    printk("%d reserved pages\n",reserved);
-    printk("%d pages shared\n",shared);
-    printk("%d pages swap cached\n",cached);
+	printk("\nMem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+	for_each_online_pgdat(pgdat) {
+		for (i = 0; i < pgdat->node_spanned_pages; i++) {
+			struct page *page = pgdat->node_mem_map + i;
+			total++;
+			if (PageReserved(page))
+				reserved++;
+			else if (PageSwapCache(page))
+				cached++;
+			else if (!page_count(page))
+				free++;
+			else
+				shared += page_count(page) - 1;
+		}
+	}
+	printk("%d pages of RAM\n",total);
+	printk("%d free pages\n",free);
+	printk("%d reserved pages\n",reserved);
+	printk("%d pages shared\n",shared);
+	printk("%d pages swap cached\n",cached);
 }
 
 extern void init_pointer_table(unsigned long ptable);
 
 /* References to section boundaries */
 
-extern char _text, _etext, _edata, __bss_start, _end;
-extern char __init_begin, __init_end;
+extern char _text[], _etext[];
+extern char __init_begin[], __init_end[];
 
 extern pmd_t *zero_pgtable;
 
 void __init mem_init(void)
 {
+	pg_data_t *pgdat;
 	int codepages = 0;
 	int datapages = 0;
 	int initpages = 0;
-	unsigned long tmp;
-#ifndef CONFIG_SUN3
 	int i;
-#endif
-
-	max_mapnr = num_physpages = (((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT);
 
 #ifdef CONFIG_ATARI
 	if (MACH_IS_ATARI)
@@ -93,19 +124,25 @@
 #endif
 
 	/* this will put all memory onto the freelists */
-	totalram_pages = free_all_bootmem();
+	totalram_pages = num_physpages = 0;
+	for_each_online_pgdat(pgdat) {
+		num_physpages += pgdat->node_present_pages;
 
-	for (tmp = PAGE_OFFSET ; tmp < (unsigned long)high_memory; tmp += PAGE_SIZE) {
-		if (PageReserved(virt_to_page(tmp))) {
-			if (tmp >= (unsigned long)&_text
-			    && tmp < (unsigned long)&_etext)
+		totalram_pages += free_all_bootmem_node(pgdat);
+		for (i = 0; i < pgdat->node_spanned_pages; i++) {
+			struct page *page = pgdat->node_mem_map + i;
+			char *addr = page_to_virt(page);
+
+			if (!PageReserved(page))
+				continue;
+			if (addr >= _text &&
+			    addr < _etext)
 				codepages++;
-			else if (tmp >= (unsigned long) &__init_begin
-				 && tmp < (unsigned long) &__init_end)
+			else if (addr >= __init_begin &&
+				 addr < __init_end)
 				initpages++;
 			else
 				datapages++;
-			continue;
 		}
 	}
 
@@ -124,7 +161,7 @@
 
 	printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n",
 	       (unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
-	       max_mapnr << (PAGE_SHIFT-10),
+	       totalram_pages << (PAGE_SHIFT-10),
 	       codepages << (PAGE_SHIFT-10),
 	       datapages << (PAGE_SHIFT-10),
 	       initpages << (PAGE_SHIFT-10));
diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c
index 13c0b4a..b747352 100644
--- a/arch/m68k/mm/memory.c
+++ b/arch/m68k/mm/memory.c
@@ -127,67 +127,6 @@
 	return 0;
 }
 
-#ifdef DEBUG_INVALID_PTOV
-int mm_inv_cnt = 5;
-#endif
-
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
-/*
- * The following two routines map from a physical address to a kernel
- * virtual address and vice versa.
- */
-unsigned long mm_vtop(unsigned long vaddr)
-{
-	int i=0;
-	unsigned long voff = (unsigned long)vaddr - PAGE_OFFSET;
-
-	do {
-		if (voff < m68k_memory[i].size) {
-#ifdef DEBUGPV
-			printk ("VTOP(%p)=%lx\n", vaddr,
-				m68k_memory[i].addr + voff);
-#endif
-			return m68k_memory[i].addr + voff;
-		}
-		voff -= m68k_memory[i].size;
-	} while (++i < m68k_num_memory);
-
-	/* As a special case allow `__pa(high_memory)'.  */
-	if (voff == 0)
-		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
-
-	return -1;
-}
-EXPORT_SYMBOL(mm_vtop);
-
-unsigned long mm_ptov (unsigned long paddr)
-{
-	int i = 0;
-	unsigned long poff, voff = PAGE_OFFSET;
-
-	do {
-		poff = paddr - m68k_memory[i].addr;
-		if (poff < m68k_memory[i].size) {
-#ifdef DEBUGPV
-			printk ("PTOV(%lx)=%lx\n", paddr, poff + voff);
-#endif
-			return poff + voff;
-		}
-		voff += m68k_memory[i].size;
-	} while (++i < m68k_num_memory);
-
-#ifdef DEBUG_INVALID_PTOV
-	if (mm_inv_cnt > 0) {
-		mm_inv_cnt--;
-		printk("Invalid use of phys_to_virt(0x%lx) at 0x%p!\n",
-			paddr, __builtin_return_address(0));
-	}
-#endif
-	return -1;
-}
-EXPORT_SYMBOL(mm_ptov);
-#endif
-
 /* invalidate page in both caches */
 static inline void clear040(unsigned long paddr)
 {
@@ -354,15 +293,3 @@
 }
 EXPORT_SYMBOL(cache_push);
 
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
-int mm_end_of_chunk (unsigned long addr, int len)
-{
-	int i;
-
-	for (i = 0; i < m68k_num_memory; i++)
-		if (m68k_memory[i].addr + m68k_memory[i].size == addr + len)
-			return 1;
-	return 0;
-}
-EXPORT_SYMBOL(mm_end_of_chunk);
-#endif
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index afcccdc..7d571a2 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -43,6 +43,11 @@
 EXPORT_SYMBOL(mm_cachebits);
 #endif
 
+/* size of memory already mapped in head.S */
+#define INIT_MAPPED_SIZE	(4UL<<20)
+
+extern unsigned long availmem;
+
 static pte_t * __init kernel_page_table(void)
 {
 	pte_t *ptablep;
@@ -98,19 +103,20 @@
 	return last_pgtable;
 }
 
-static unsigned long __init
-map_chunk (unsigned long addr, long size)
+static void __init map_node(int node)
 {
 #define PTRTREESIZE (256*1024)
 #define ROOTTREESIZE (32*1024*1024)
-	static unsigned long virtaddr = PAGE_OFFSET;
-	unsigned long physaddr;
+	unsigned long physaddr, virtaddr, size;
 	pgd_t *pgd_dir;
 	pmd_t *pmd_dir;
 	pte_t *pte_dir;
 
-	physaddr = (addr | m68k_supervisor_cachemode |
-		    _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
+	size = m68k_memory[node].size;
+	physaddr = m68k_memory[node].addr;
+	virtaddr = (unsigned long)phys_to_virt(physaddr);
+	physaddr |= m68k_supervisor_cachemode |
+		    _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY;
 	if (CPU_IS_040_OR_060)
 		physaddr |= _PAGE_GLOBAL040;
 
@@ -190,8 +196,6 @@
 #ifdef DEBUG
 	printk("\n");
 #endif
-
-	return virtaddr;
 }
 
 /*
@@ -200,15 +204,16 @@
  */
 void __init paging_init(void)
 {
-	int chunk;
-	unsigned long mem_avail = 0;
 	unsigned long zones_size[MAX_NR_ZONES] = { 0, };
+	unsigned long min_addr, max_addr;
+	unsigned long addr, size, end;
+	int i;
 
 #ifdef DEBUG
 	{
 		extern unsigned long availmem;
-		printk ("start of paging_init (%p, %lx, %lx, %lx)\n",
-			kernel_pg_dir, availmem, start_mem, end_mem);
+		printk ("start of paging_init (%p, %lx)\n",
+			kernel_pg_dir, availmem);
 	}
 #endif
 
@@ -222,24 +227,62 @@
 			pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
 	}
 
-	/*
-	 * Map the physical memory available into the kernel virtual
-	 * address space.  It may allocate some memory for page
-	 * tables and thus modify availmem.
-	 */
+	min_addr = m68k_memory[0].addr;
+	max_addr = min_addr + m68k_memory[0].size;
+	for (i = 1; i < m68k_num_memory;) {
+		if (m68k_memory[i].addr < min_addr) {
+			printk("Ignoring memory chunk at 0x%lx:0x%lx before the first chunk\n",
+				m68k_memory[i].addr, m68k_memory[i].size);
+			printk("Fix your bootloader or use a memfile to make use of this area!\n");
+			m68k_num_memory--;
+			memmove(m68k_memory + i, m68k_memory + i + 1,
+				(m68k_num_memory - i) * sizeof(struct mem_info));
+			continue;
+		}
+		addr = m68k_memory[i].addr + m68k_memory[i].size;
+		if (addr > max_addr)
+			max_addr = addr;
+		i++;
+	}
+	m68k_memoffset = min_addr - PAGE_OFFSET;
+	m68k_virt_to_node_shift = fls(max_addr - min_addr - 1) - 6;
 
-	for (chunk = 0; chunk < m68k_num_memory; chunk++) {
-		mem_avail = map_chunk (m68k_memory[chunk].addr,
-				       m68k_memory[chunk].size);
+	module_fixup(NULL, __start_fixup, __stop_fixup);
+	flush_icache();
 
+	high_memory = phys_to_virt(max_addr);
+
+	min_low_pfn = availmem >> PAGE_SHIFT;
+	max_low_pfn = max_addr >> PAGE_SHIFT;
+
+	for (i = 0; i < m68k_num_memory; i++) {
+		addr = m68k_memory[i].addr;
+		end = addr + m68k_memory[i].size;
+		m68k_setup_node(i);
+		availmem = PAGE_ALIGN(availmem);
+		availmem += init_bootmem_node(NODE_DATA(i),
+					      availmem >> PAGE_SHIFT,
+					      addr >> PAGE_SHIFT,
+					      end >> PAGE_SHIFT);
 	}
 
+	/*
+	 * Map the physical memory available into the kernel virtual
+	 * address space. First initialize the bootmem allocator with
+	 * the memory we already mapped, so map_node() has something
+	 * to allocate.
+	 */
+	addr = m68k_memory[0].addr;
+	size = m68k_memory[0].size;
+	free_bootmem_node(NODE_DATA(0), availmem, min(INIT_MAPPED_SIZE, size) - (availmem - addr));
+	map_node(0);
+	if (size > INIT_MAPPED_SIZE)
+		free_bootmem_node(NODE_DATA(0), addr + INIT_MAPPED_SIZE, size - INIT_MAPPED_SIZE);
+
+	for (i = 1; i < m68k_num_memory; i++)
+		map_node(i);
+
 	flush_tlb_all();
-#ifdef DEBUG
-	printk ("memory available is %ldKB\n", mem_avail >> 10);
-	printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
-		start_mem, end_mem);
-#endif
 
 	/*
 	 * initialize the bad page table and bad page to point
@@ -256,14 +299,11 @@
 #ifdef DEBUG
 	printk ("before free_area_init\n");
 #endif
-	zones_size[ZONE_DMA] = (mach_max_dma_address < (unsigned long)high_memory ?
-				(mach_max_dma_address+1) : (unsigned long)high_memory);
-	zones_size[ZONE_NORMAL] = (unsigned long)high_memory - zones_size[0];
-
-	zones_size[ZONE_DMA] = (zones_size[ZONE_DMA] - PAGE_OFFSET) >> PAGE_SHIFT;
-	zones_size[ZONE_NORMAL] >>= PAGE_SHIFT;
-
-	free_area_init(zones_size);
+	for (i = 0; i < m68k_num_memory; i++) {
+		zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT;
+		free_area_init_node(i, pg_data_map + i, zones_size,
+				    m68k_memory[i].addr >> PAGE_SHIFT, NULL);
+	}
 }
 
 extern char __init_begin, __init_end;
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
index 4851b84..c0fbd27 100644
--- a/arch/m68k/sun3/config.c
+++ b/arch/m68k/sun3/config.c
@@ -21,6 +21,7 @@
 #include <asm/contregs.h>
 #include <asm/movs.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/sun3-head.h>
 #include <asm/sun3mmu.h>
 #include <asm/rtc.h>
@@ -127,6 +128,7 @@
 	high_memory = (void *)memory_end;
 	availmem = memory_start;
 
+	m68k_setup_node(0);
 	availmem += init_bootmem_node(NODE_DATA(0), start_page, 0, num_pages);
 	availmem = (availmem + (PAGE_SIZE-1)) & PAGE_MASK;
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 56d3c0d..5eaeafd 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -118,6 +118,7 @@
 	depends on BUG
 
 config SYS_SUPPORTS_APM_EMULATION
+	default y if PMAC_APM_EMU
 	bool
 
 config DEFAULT_UIMAGE
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index eae68ab..d29308f 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -67,7 +67,7 @@
 			interrupt-controller;
 			#interrupt-cells = <3>;
 			device_type = "interrupt-controller";
-			compatible = "mpc5200_pic";
+			compatible = "mpc5200-pic";
 			reg = <500 80>;
 			built-in;
 		};
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index 5185625..f242531 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -67,7 +67,7 @@
 			interrupt-controller;
 			#interrupt-cells = <3>;
 			device_type = "interrupt-controller";
-			compatible = "mpc5200b-pic\0mpc5200_pic";
+			compatible = "mpc5200b-pic\0mpc5200-pic";
 			reg = <500 80>;
 			built-in;
 		};
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index d8232b7..f6ae1a5 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -93,7 +93,7 @@
 	free_pages((unsigned long)pgd, PGDIR_ORDER);
 }
 
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
 	pte_t *pte;
 	extern int mem_init_done;
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 7104567..5bcc58d 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -169,7 +169,7 @@
 
 /***********/
 /***********/
-int mv643xx_eth_add_pds(void)
+static int __init mv643xx_eth_add_pds(void)
 {
 	int ret = 0;
 	static struct pci_device_id pci_marvell_mv64360[] = {
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index a410bc76..07b1c4e 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -384,7 +384,7 @@
 static dev_t boot_dev;
 
 #ifdef CONFIG_SCSI
-void __init note_scsi_host(struct device_node *node, void *host)
+void note_scsi_host(struct device_node *node, void *host)
 {
 	int l;
 	char *p;
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig
index 887739f..f611d34 100644
--- a/arch/powerpc/sysdev/qe_lib/Kconfig
+++ b/arch/powerpc/sysdev/qe_lib/Kconfig
@@ -5,15 +5,13 @@
 config UCC_SLOW
 	bool
 	default n
-	select UCC
 	help
 	  This option provides qe_lib support to UCC slow
 	  protocols: UART, BISYNC, QMC
 
 config UCC_FAST
 	bool
-	default n
-	select UCC
+	default y if UCC_GETH
 	help
 	  This option provides qe_lib support to UCC fast
 	  protocols: HDLC, Ethernet, ATM, transparent
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index ab64256..fba7ca1 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -596,7 +596,11 @@
 	mr	r12,r4		/* restart at exc_exit_restart */
 	b	2b
 
-	.comm	fee_restarts,4
+	.section .bss
+	.align	2
+fee_restarts:
+	.space	4
+	.previous
 
 /* aargh, a nonrecoverable interrupt, panic */
 /* aargh, we don't know which trap this is */
@@ -851,7 +855,11 @@
 	mtspr	SPRN_DBSR,r11	/* clear all pending debug events */
 	blr
 
-	.comm	global_dbcr0,8
+	.section .bss
+	.align	4
+global_dbcr0:
+	.space	8
+	.previous
 #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
 
 do_work:			/* r10 contains MSR_KERNEL here */
@@ -926,4 +934,8 @@
 	/* shouldn't return */
 	b	4b
 
-	.comm	ee_restarts,4
+	.section .bss
+	.align	2
+ee_restarts:
+	.space	4
+	.previous
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 4ad4996..a416520 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -40,7 +40,6 @@
 #include <asm/time.h>
 #include <asm/cputable.h>
 #include <asm/btext.h>
-#include <asm/div64.h>
 #include <asm/xmon.h>
 #include <asm/signal.h>
 #include <asm/dcr.h>
@@ -93,7 +92,6 @@
 EXPORT_SYMBOL(strcat);
 EXPORT_SYMBOL(strlen);
 EXPORT_SYMBOL(strcmp);
-EXPORT_SYMBOL(__div64_32);
 
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
diff --git a/arch/ppc/mm/hashtable.S b/arch/ppc/mm/hashtable.S
index e756942..5f364dc 100644
--- a/arch/ppc/mm/hashtable.S
+++ b/arch/ppc/mm/hashtable.S
@@ -30,7 +30,11 @@
 #include <asm/asm-offsets.h>
 
 #ifdef CONFIG_SMP
-	.comm	mmu_hash_lock,4
+	.section .bss
+	.align	2
+	.globl mmu_hash_lock
+mmu_hash_lock:
+	.space	4
 #endif /* CONFIG_SMP */
 
 /*
@@ -461,9 +465,17 @@
 	sync		/* make sure pte updates get to memory */
 	blr
 
-	.comm	next_slot,4
-	.comm	primary_pteg_full,4
-	.comm	htab_hash_searches,4
+	.section .bss
+	.align	2
+next_slot:
+	.space	4
+	.globl primary_pteg_full
+primary_pteg_full:
+	.space	4
+	.globl htab_hash_searches
+htab_hash_searches:
+	.space	4
+	.previous
 
 /*
  * Flush the entry for a particular page from the hash table.
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
index c023b72..35ebb63 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -92,7 +92,7 @@
 	free_pages((unsigned long)pgd, PGDIR_ORDER);
 }
 
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
 	pte_t *pte;
 	extern int mem_init_done;
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 2782cf9..b9a1ce1 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -481,9 +481,17 @@
 
 /* Diagnose 224 functions */
 
-static void diag224(void *ptr)
+static int diag224(void *ptr)
 {
-	asm volatile("diag %0,%1,0x224" : :"d" (0), "d"(ptr) : "memory");
+	int rc = -ENOTSUPP;
+
+	asm volatile(
+		"	diag	%1,%2,0x224\n"
+		"0:	lhi	%0,0x0\n"
+		"1:\n"
+		EX_TABLE(0b,1b)
+		: "+d" (rc) :"d" (0), "d" (ptr) : "memory");
+	return rc;
 }
 
 static int diag224_get_name_table(void)
@@ -492,7 +500,10 @@
 	diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
 	if (!diag224_cpu_names)
 		return -ENOMEM;
-	diag224(diag224_cpu_names);
+	if (diag224(diag224_cpu_names)) {
+		kfree(diag224_cpu_names);
+		return -ENOTSUPP;
+	}
 	EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16);
 	return 0;
 }
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index dca6eaf..1b2f5ce 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -163,7 +163,7 @@
 
 static debug_info_t *debug_area_first = NULL;
 static debug_info_t *debug_area_last = NULL;
-static DECLARE_MUTEX(debug_lock);
+static DEFINE_MUTEX(debug_mutex);
 
 static int initialized;
 
@@ -576,7 +576,7 @@
 	int rc = 0;
 	file_private_info_t *p_info;
 
-	down(&debug_lock);
+	mutex_lock(&debug_mutex);
 	p_info = ((file_private_info_t *) file->private_data);
 	if (p_info->view->input_proc)
 		rc = p_info->view->input_proc(p_info->debug_info_org,
@@ -584,7 +584,7 @@
 					      length, offset);
 	else
 		rc = -EPERM;
-	up(&debug_lock);
+	mutex_unlock(&debug_mutex);
 	return rc;		/* number of input characters */
 }
 
@@ -602,7 +602,7 @@
 	file_private_info_t *p_info;
 	debug_info_t *debug_info, *debug_info_snapshot;
 
-	down(&debug_lock);
+	mutex_lock(&debug_mutex);
 	debug_info = file->f_path.dentry->d_inode->i_private;
 	/* find debug view */
 	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
@@ -653,7 +653,7 @@
 	file->private_data = p_info;
 	debug_info_get(debug_info);
 out:
-	up(&debug_lock);
+	mutex_unlock(&debug_mutex);
 	return rc;
 }
 
@@ -688,7 +688,7 @@
 
 	if (!initialized)
 		BUG();
-	down(&debug_lock);
+	mutex_lock(&debug_mutex);
 
         /* create new debug_info */
 
@@ -702,7 +702,7 @@
         if (!rc){
 		printk(KERN_ERR "debug: debug_register failed for %s\n",name);
         }
-	up(&debug_lock);
+	mutex_unlock(&debug_mutex);
 	return rc;
 }
 
@@ -716,9 +716,9 @@
 {
 	if (!id)
 		goto out;
-	down(&debug_lock);
+	mutex_lock(&debug_mutex);
 	debug_info_put(id);
-	up(&debug_lock);
+	mutex_unlock(&debug_mutex);
 
 out:
 	return;
@@ -1054,11 +1054,11 @@
 	int rc = 0;
 
 	s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table);
-	down(&debug_lock);
+	mutex_lock(&debug_mutex);
 	debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL);
 	printk(KERN_INFO "debug: Initialization complete\n");
 	initialized = 1;
-	up(&debug_lock);
+	mutex_unlock(&debug_mutex);
 
 	return rc;
 }
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 6bfb088..51d6309 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -102,7 +102,7 @@
 /*
  * cpu_init() initializes state that is per-CPU.
  */
-void __devinit cpu_init (void)
+void __cpuinit cpu_init(void)
 {
         int addr = hard_smp_processor_id();
 
@@ -915,7 +915,7 @@
 	setup_zfcpdump(console_devno);
 }
 
-void print_cpu_info(struct cpuinfo_S390 *cpuinfo)
+void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
 {
    printk("cpu %d "
 #ifdef CONFIG_SMP
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 09f028a..8ff2fea 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -492,7 +492,7 @@
 /*
  *	Activate a secondary processor.
  */
-int __devinit start_secondary(void *cpuvoid)
+int __cpuinit start_secondary(void *cpuvoid)
 {
 	/* Setup the cpu */
 	cpu_init();
@@ -741,7 +741,7 @@
 			smp_create_idle(cpu);
 }
 
-void __devinit smp_prepare_boot_cpu(void)
+void __init smp_prepare_boot_cpu(void)
 {
 	BUG_ON(smp_processor_id() != 0);
 
@@ -750,7 +750,7 @@
 	current_set[0] = current;
 }
 
-void smp_cpus_done(unsigned int max_cpus)
+void __init smp_cpus_done(unsigned int max_cpus)
 {
 	cpu_present_map = cpu_possible_map;
 }
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 7b11224..883b03b 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -39,7 +39,7 @@
 cflags-$(CONFIG_CPU_SH3)		:= -m3
 cflags-$(CONFIG_CPU_SH4)		:= -m4 \
 	$(call cc-option,-mno-implicit-fp,-m4-nofpu)
-cflags-$(CONFIG_CPU_SH4A)		:= -m4a $(call cc-option,-m4a-nofpu,)
+cflags-$(CONFIG_CPU_SH4A)		:= $(call cc-option,-m4a,) $(call cc-option,-m4a-nofpu,)
 
 cflags-$(CONFIG_CPU_BIG_ENDIAN)		+= -mb
 cflags-$(CONFIG_CPU_LITTLE_ENDIAN)	+= -ml
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
index 8057a27..cf8e119 100644
--- a/arch/sh/drivers/dma/dma-api.c
+++ b/arch/sh/drivers/dma/dma-api.c
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/mm.h>
+#include <linux/sched.h>
 #include <asm/dma.h>
 
 DEFINE_SPINLOCK(dma_spin_lock);
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
index 849a9e1..ebc73b8 100644
--- a/arch/sh/kernel/cf-enabler.c
+++ b/arch/sh/kernel/cf-enabler.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/interrupt.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -149,6 +150,11 @@
 	ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
 	return 0;
 }
+#else
+static int __init cf_init_se(void)
+{
+	return -1;
+}
 #endif
 
 int __init cf_init(void)
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 832c0b4..659cc08 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -320,6 +320,7 @@
 
 	.align	2
 5:	.long	0x00001000	! DSP
+6:	.long	in_nmi
 7:	.long	0x30000000
 
 ! common exception handler
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 8cd0490..fab2eb0 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -12,6 +12,7 @@
  */
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/smp.h>
 #include <asm/processor.h>
 #include <asm/cache.h>
 
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index dbebadd..283e142 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -10,6 +10,8 @@
  * Free Software Foundation; either version 2 of the License, or (at your
  * option) any later version.
  */
+
+#include <linux/err.h>
 #include <linux/cache.h>
 #include <linux/cpumask.h>
 #include <linux/delay.h>
diff --git a/arch/sh/kernel/timers/timer.c b/arch/sh/kernel/timers/timer.c
index a6bcc91..4e7e747 100644
--- a/arch/sh/kernel/timers/timer.c
+++ b/arch/sh/kernel/timers/timer.c
@@ -13,7 +13,7 @@
 #include <linux/string.h>
 #include <asm/timer.h>
 
-static struct sys_timer *sys_timers[] __initdata = {
+static struct sys_timer *sys_timers[] = {
 #ifdef CONFIG_SH_TMU
 	&tmu_timer,
 #endif
@@ -26,7 +26,7 @@
 	NULL,
 };
 
-static char timer_override[10] __initdata;
+static char timer_override[10];
 static int __init timer_setup(char *str)
 {
 	if (str)
@@ -53,4 +53,3 @@
 
 	return NULL;
 }
-
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c
index e146baf..2aa9438 100644
--- a/arch/sh/kernel/vsyscall/vsyscall.c
+++ b/arch/sh/kernel/vsyscall/vsyscall.c
@@ -17,6 +17,7 @@
 #include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/elf.h>
+#include <linux/sched.h>
 
 /*
  * Should the kernel map a VDSO page into processes and pass its
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index bd992c0..fbcc00c 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -178,6 +178,13 @@
 	bool
 	default n
 
+config EMULATED_CMPXCHG
+	bool
+	default y
+	help
+	  Sparc32 does not have a CAS instruction like sparc64. cmpxchg()
+	  is emulated, and therefore it is not completely atomic.
+
 config SUN_PM
 	bool
 	default y
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index f1401b5..7b4612d 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -148,7 +148,7 @@
 }
 
 /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
-static void __init kick_start_clock(void)
+static void __devinit kick_start_clock(void)
 {
 	struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs;
 	unsigned char sec;
@@ -223,7 +223,7 @@
 	return (data1 == data2);	/* Was the write blocked? */
 }
 
-static void __init mostek_set_system_time(void)
+static void __devinit mostek_set_system_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec;
 	struct mostek48t02 *mregs;
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 559335f..cbddeb3 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -2,6 +2,7 @@
  * atomic32.c: 32-bit atomic_t implementation
  *
  * Copyright (C) 2004 Keith M Wesolowski
+ * Copyright (C) 2007 Kyle McMartin
  * 
  * Based on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf
  */
@@ -117,3 +118,17 @@
 	return old & mask;
 }
 EXPORT_SYMBOL(___change_bit);
+
+unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new)
+{
+	unsigned long flags;
+	u32 prev;
+
+	spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
+	if ((prev = *ptr) == old)
+		*ptr = new;
+	spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
+
+	return (unsigned long)prev;
+}
+EXPORT_SYMBOL(__cmpxchg_u32);
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 831781c..bd00f89 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -147,10 +147,10 @@
 	  If you don't know what to do here, say N.
 
 config NR_CPUS
-	int "Maximum number of CPUs (2-64)"
-	range 2 64
+	int "Maximum number of CPUs (2-1024)"
+	range 2 1024
 	depends on SMP
-	default "32"
+	default "64"
 
 source "drivers/cpufreq/Kconfig"
 
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index c749dcc..d8d1909 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -8,11 +8,11 @@
 extra-y		:= head.o init_task.o vmlinux.lds
 
 obj-y		:= process.o setup.o cpu.o idprom.o \
-		   traps.o devices.o auxio.o una_asm.o \
+		   traps.o auxio.o una_asm.o \
 		   irq.o ptrace.o time.o sys_sparc.o signal.o \
 		   unaligned.o central.o pci.o starfire.o semaphore.o \
 		   power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
-		   visemul.o prom.o of_device.o hvapi.o
+		   visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o
 
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-$(CONFIG_PCI)	 += ebus.o isa.o pci_common.o pci_iommu.o \
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c
deleted file mode 100644
index 0e03c8e..0000000
--- a/arch/sparc64/kernel/devices.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* devices.c: Initial scan of the prom device tree for important
- *            Sparc device nodes which we need to find.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <linux/kernel.h>
-#include <linux/threads.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/bootmem.h>
-
-#include <asm/page.h>
-#include <asm/oplib.h>
-#include <asm/system.h>
-#include <asm/smp.h>
-#include <asm/spitfire.h>
-#include <asm/timer.h>
-#include <asm/cpudata.h>
-
-/* Used to synchronize accesses to NatSemi SUPER I/O chip configure
- * operations in asm/ns87303.h
- */
-DEFINE_SPINLOCK(ns87303_lock);
-
-extern void cpu_probe(void);
-extern void central_probe(void);
-
-static const char *cpu_mid_prop(void)
-{
-	if (tlb_type == spitfire)
-		return "upa-portid";
-	return "portid";
-}
-
-static int get_cpu_mid(struct device_node *dp)
-{
-	struct property *prop;
-
-	if (tlb_type == hypervisor) {
-		struct linux_prom64_registers *reg;
-		int len;
-
-		prop = of_find_property(dp, "cpuid", &len);
-		if (prop && len == 4)
-			return *(int *) prop->value;
-
-		prop = of_find_property(dp, "reg", NULL);
-		reg = prop->value;
-		return (reg[0].phys_addr >> 32) & 0x0fffffffUL;
-	} else {
-		const char *prop_name = cpu_mid_prop();
-
-		prop = of_find_property(dp, prop_name, NULL);
-		if (prop)
-			return *(int *) prop->value;
-		return 0;
-	}
-}
-
-static int check_cpu_node(struct device_node *dp, int *cur_inst,
-			  int (*compare)(struct device_node *, int, void *),
-			  void *compare_arg,
-			  struct device_node **dev_node, int *mid)
-{
-	if (!compare(dp, *cur_inst, compare_arg)) {
-		if (dev_node)
-			*dev_node = dp;
-		if (mid)
-			*mid = get_cpu_mid(dp);
-		return 0;
-	}
-
-	(*cur_inst)++;
-
-	return -ENODEV;
-}
-
-static int __cpu_find_by(int (*compare)(struct device_node *, int, void *),
-			 void *compare_arg,
-			 struct device_node **dev_node, int *mid)
-{
-	struct device_node *dp;
-	int cur_inst;
-
-	cur_inst = 0;
-	for_each_node_by_type(dp, "cpu") {
-		int err = check_cpu_node(dp, &cur_inst,
-					 compare, compare_arg,
-					 dev_node, mid);
-		if (err == 0)
-			return 0;
-	}
-
-	return -ENODEV;
-}
-
-static int cpu_instance_compare(struct device_node *dp, int instance, void *_arg)
-{
-	int desired_instance = (int) (long) _arg;
-
-	if (instance == desired_instance)
-		return 0;
-	return -ENODEV;
-}
-
-int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid)
-{
-	return __cpu_find_by(cpu_instance_compare, (void *)(long)instance,
-			     dev_node, mid);
-}
-
-static int cpu_mid_compare(struct device_node *dp, int instance, void *_arg)
-{
-	int desired_mid = (int) (long) _arg;
-	int this_mid;
-
-	this_mid = get_cpu_mid(dp);
-	if (this_mid == desired_mid)
-		return 0;
-	return -ENODEV;
-}
-
-int cpu_find_by_mid(int mid, struct device_node **dev_node)
-{
-	return __cpu_find_by(cpu_mid_compare, (void *)(long)mid,
-			     dev_node, NULL);
-}
-
-void __init device_scan(void)
-{
-	/* FIX ME FAST... -DaveM */
-	ioport_resource.end = 0xffffffffffffffffUL;
-
-	prom_printf("Booting Linux...\n");
-
-#ifndef CONFIG_SMP
-	{
-		struct device_node *dp;
-		int err, def;
-
-		err = cpu_find_by_instance(0, &dp, NULL);
-		if (err) {
-			prom_printf("No cpu nodes, cannot continue\n");
-			prom_halt();
-		}
-		cpu_data(0).clock_tick =
-			of_getintprop_default(dp, "clock-frequency", 0);
-
-		def = ((tlb_type == hypervisor) ?
-		       (8 * 1024) :
-		       (16 * 1024));
-		cpu_data(0).dcache_size = of_getintprop_default(dp,
-								"dcache-size",
-								def);
-
-		def = 32;
-		cpu_data(0).dcache_line_size =
-			of_getintprop_default(dp, "dcache-line-size", def);
-
-		def = 16 * 1024;
-		cpu_data(0).icache_size = of_getintprop_default(dp,
-								"icache-size",
-								def);
-
-		def = 32;
-		cpu_data(0).icache_line_size =
-			of_getintprop_default(dp, "icache-line-size", def);
-
-		def = ((tlb_type == hypervisor) ?
-		       (3 * 1024 * 1024) :
-		       (4 * 1024 * 1024));
-		cpu_data(0).ecache_size = of_getintprop_default(dp,
-								"ecache-size",
-								def);
-
-		def = 64;
-		cpu_data(0).ecache_line_size =
-			of_getintprop_default(dp, "ecache-line-size", def);
-		printk("CPU[0]: Caches "
-		       "D[sz(%d):line_sz(%d)] "
-		       "I[sz(%d):line_sz(%d)] "
-		       "E[sz(%d):line_sz(%d)]\n",
-		       cpu_data(0).dcache_size, cpu_data(0).dcache_line_size,
-		       cpu_data(0).icache_size, cpu_data(0).icache_line_size,
-		       cpu_data(0).ecache_size, cpu_data(0).ecache_line_size);
-	}
-#endif
-
-	central_probe();
-
-	cpu_probe();
-}
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 732b77c..ed712e0 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1725,74 +1725,127 @@
 	 * returns %o0: sysino
 	 */
 	.globl	sun4v_devino_to_sysino
+	.type	sun4v_devino_to_sysino,#function
 sun4v_devino_to_sysino:
 	mov	HV_FAST_INTR_DEVINO2SYSINO, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 mov	%o1, %o0
+	.size	sun4v_devino_to_sysino, .-sun4v_devino_to_sysino
 
 	/* %o0: sysino
 	 *
 	 * returns %o0: intr_enabled (HV_INTR_{DISABLED,ENABLED})
 	 */
 	.globl	sun4v_intr_getenabled
+	.type	sun4v_intr_getenabled,#function
 sun4v_intr_getenabled:
 	mov	HV_FAST_INTR_GETENABLED, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 mov	%o1, %o0
+	.size	sun4v_intr_getenabled, .-sun4v_intr_getenabled
 
 	/* %o0: sysino
 	 * %o1: intr_enabled (HV_INTR_{DISABLED,ENABLED})
 	 */
 	.globl	sun4v_intr_setenabled
+	.type	sun4v_intr_setenabled,#function
 sun4v_intr_setenabled:
 	mov	HV_FAST_INTR_SETENABLED, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 nop
+	.size	sun4v_intr_setenabled, .-sun4v_intr_setenabled
 
 	/* %o0: sysino
 	 *
 	 * returns %o0: intr_state (HV_INTR_STATE_*)
 	 */
 	.globl	sun4v_intr_getstate
+	.type	sun4v_intr_getstate,#function
 sun4v_intr_getstate:
 	mov	HV_FAST_INTR_GETSTATE, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 mov	%o1, %o0
+	.size	sun4v_intr_getstate, .-sun4v_intr_getstate
 
 	/* %o0: sysino
 	 * %o1: intr_state (HV_INTR_STATE_*)
 	 */
 	.globl	sun4v_intr_setstate
+	.type	sun4v_intr_setstate,#function
 sun4v_intr_setstate:
 	mov	HV_FAST_INTR_SETSTATE, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 nop
+	.size	sun4v_intr_setstate, .-sun4v_intr_setstate
 
 	/* %o0: sysino
 	 *
 	 * returns %o0: cpuid
 	 */
 	.globl	sun4v_intr_gettarget
+	.type	sun4v_intr_gettarget,#function
 sun4v_intr_gettarget:
 	mov	HV_FAST_INTR_GETTARGET, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 mov	%o1, %o0
+	.size	sun4v_intr_gettarget, .-sun4v_intr_gettarget
 
 	/* %o0: sysino
 	 * %o1: cpuid
 	 */
 	.globl	sun4v_intr_settarget
+	.type	sun4v_intr_settarget,#function
 sun4v_intr_settarget:
 	mov	HV_FAST_INTR_SETTARGET, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 nop
+	.size	sun4v_intr_settarget, .-sun4v_intr_settarget
+
+	/* %o0:	cpuid
+	 * %o1: pc
+	 * %o2:	rtba
+	 * %o3:	arg0
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_cpu_start
+	.type	sun4v_cpu_start,#function
+sun4v_cpu_start:
+	mov	HV_FAST_CPU_START, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_cpu_start, .-sun4v_cpu_start
+
+	/* %o0:	cpuid
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_cpu_stop
+	.type	sun4v_cpu_stop,#function
+sun4v_cpu_stop:
+	mov	HV_FAST_CPU_STOP, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_cpu_stop, .-sun4v_cpu_stop
+
+	/* returns %o0:	status  */
+	.globl	sun4v_cpu_yield
+	.type	sun4v_cpu_yield, #function
+sun4v_cpu_yield:
+	mov	HV_FAST_CPU_YIELD, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_cpu_yield, .-sun4v_cpu_yield
 
 	/* %o0:	type
 	 * %o1:	queue paddr
@@ -1801,20 +1854,13 @@
 	 * returns %o0:	status
 	 */
 	.globl	sun4v_cpu_qconf
+	.type	sun4v_cpu_qconf,#function
 sun4v_cpu_qconf:
 	mov	HV_FAST_CPU_QCONF, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 nop
-
-	/* returns %o0:	status
-	 */
-	.globl	sun4v_cpu_yield
-sun4v_cpu_yield:
-	mov	HV_FAST_CPU_YIELD, %o5
-	ta	HV_FAST_TRAP
-	retl
-	 nop
+	.size	sun4v_cpu_qconf, .-sun4v_cpu_qconf
 
 	/* %o0:	num cpus in cpu list
 	 * %o1:	cpu list paddr
@@ -1823,11 +1869,13 @@
 	 * returns %o0: status
 	 */
 	.globl	sun4v_cpu_mondo_send
+	.type	sun4v_cpu_mondo_send,#function
 sun4v_cpu_mondo_send:
 	mov	HV_FAST_CPU_MONDO_SEND, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 nop
+	.size	sun4v_cpu_mondo_send, .-sun4v_cpu_mondo_send
 
 	/* %o0:	CPU ID
 	 *
@@ -1835,6 +1883,7 @@
 	 *         %o0:	cpu state as HV_CPU_STATE_*
 	 */
 	.globl	sun4v_cpu_state
+	.type	sun4v_cpu_state,#function
 sun4v_cpu_state:
 	mov	HV_FAST_CPU_STATE, %o5
 	ta	HV_FAST_TRAP
@@ -1843,6 +1892,37 @@
 	mov	%o1, %o0
 1:	retl
 	 nop
+	.size	sun4v_cpu_state, .-sun4v_cpu_state
+
+	/* %o0: virtual address
+	 * %o1: must be zero
+	 * %o2: TTE
+	 * %o3: HV_MMU_* flags
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_mmu_map_perm_addr
+	.type	sun4v_mmu_map_perm_addr,#function
+sun4v_mmu_map_perm_addr:
+	mov	HV_FAST_MMU_MAP_PERM_ADDR, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_mmu_map_perm_addr, .-sun4v_mmu_map_perm_addr
+
+	/* %o0: number of TSB descriptions
+	 * %o1: TSB descriptions real address
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_mmu_tsb_ctx0
+	.type	sun4v_mmu_tsb_ctx0,#function
+sun4v_mmu_tsb_ctx0:
+	mov	HV_FAST_MMU_TSB_CTX0, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_mmu_tsb_ctx0, .-sun4v_mmu_tsb_ctx0
 
 	/* %o0:	API group number
 	 * %o1: pointer to unsigned long major number storage
@@ -1851,6 +1931,7 @@
 	 * returns %o0: status
 	 */
 	.globl	sun4v_get_version
+	.type	sun4v_get_version,#function
 sun4v_get_version:
 	mov	HV_CORE_GET_VER, %o5
 	mov	%o1, %o3
@@ -1859,6 +1940,7 @@
 	stx	%o1, [%o3]
 	retl
 	 stx	%o2, [%o4]
+	.size	sun4v_get_version, .-sun4v_get_version
 
 	/* %o0: API group number
 	 * %o1: desired major number
@@ -1868,18 +1950,49 @@
 	 * returns %o0: status
 	 */
 	.globl	sun4v_set_version
+	.type	sun4v_set_version,#function
 sun4v_set_version:
 	mov	HV_CORE_SET_VER, %o5
 	mov	%o3, %o4
 	ta	HV_CORE_TRAP
 	retl
 	 stx	%o1, [%o4]
+	.size	sun4v_set_version, .-sun4v_set_version
+
+	/* %o0: pointer to unsigned long time
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_tod_get
+	.type	sun4v_tod_get,#function
+sun4v_tod_get:
+	mov	%o0, %o4
+	mov	HV_FAST_TOD_GET, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%o4]
+	retl
+	 nop
+	.size	sun4v_tod_get, .-sun4v_tod_get
+
+	/* %o0: time
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_tod_set
+	.type	sun4v_tod_set,#function
+sun4v_tod_set:
+	mov	HV_FAST_TOD_SET, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_tod_set, .-sun4v_tod_set
 
 	/* %o0: pointer to unsigned long status
 	 *
 	 * returns %o0: signed character
 	 */
 	.globl	sun4v_con_getchar
+	.type	sun4v_con_getchar,#function
 sun4v_con_getchar:
 	mov	%o0, %o4
 	mov	HV_FAST_CONS_GETCHAR, %o5
@@ -1889,17 +2002,20 @@
 	stx	%o0, [%o4]
 	retl
 	 sra	%o1, 0, %o0
+	.size	sun4v_con_getchar, .-sun4v_con_getchar
 
 	/* %o0: signed long character
 	 *
 	 * returns %o0: status
 	 */
 	.globl	sun4v_con_putchar
+	.type	sun4v_con_putchar,#function
 sun4v_con_putchar:
 	mov	HV_FAST_CONS_PUTCHAR, %o5
 	ta	HV_FAST_TRAP
 	retl
 	 sra	%o0, 0, %o0
+	.size	sun4v_con_putchar, .-sun4v_con_putchar
 
 	/* %o0: buffer real address
 	 * %o1: buffer size
@@ -1908,6 +2024,7 @@
 	 * returns %o0: status
 	 */
 	.globl	sun4v_con_read
+	.type	sun4v_con_read,#function
 sun4v_con_read:
 	mov	%o2, %o4
 	mov	HV_FAST_CONS_READ, %o5
@@ -1922,6 +2039,7 @@
 	stx	%o1, [%o4]
 1:	retl
 	 nop
+	.size	sun4v_con_read, .-sun4v_con_read
 
 	/* %o0: buffer real address
 	 * %o1: buffer size
@@ -1930,6 +2048,7 @@
 	 * returns %o0: status
 	 */
 	.globl	sun4v_con_write
+	.type	sun4v_con_write,#function
 sun4v_con_write:
 	mov	%o2, %o4
 	mov	HV_FAST_CONS_WRITE, %o5
@@ -1937,3 +2056,517 @@
 	stx	%o1, [%o4]
 	retl
 	 nop
+	.size	sun4v_con_write, .-sun4v_con_write
+
+	/* %o0:	soft state
+	 * %o1:	address of description string
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_mach_set_soft_state
+	.type	sun4v_mach_set_soft_state,#function
+sun4v_mach_set_soft_state:
+	mov	HV_FAST_MACH_SET_SOFT_STATE, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_mach_set_soft_state, .-sun4v_mach_set_soft_state
+
+	/* %o0: exit code
+	 *
+	 * Does not return.
+	 */
+	.globl	sun4v_mach_exit
+	.type	sun4v_mach_exit,#function
+sun4v_mach_exit:
+	mov	HV_FAST_MACH_EXIT, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_mach_exit, .-sun4v_mach_exit
+
+	/* %o0: buffer real address
+	 * %o1: buffer length
+	 * %o2: pointer to unsigned long real_buf_len
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_mach_desc
+	.type	sun4v_mach_desc,#function
+sun4v_mach_desc:
+	mov	%o2, %o4
+	mov	HV_FAST_MACH_DESC, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%o4]
+	retl
+	 nop
+	.size	sun4v_mach_desc, .-sun4v_mach_desc
+
+	/* %o0: new timeout in milliseconds
+	 * %o1: pointer to unsigned long orig_timeout
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_mach_set_watchdog
+	.type	sun4v_mach_set_watchdog,#function
+sun4v_mach_set_watchdog:
+	mov	%o1, %o4
+	mov	HV_FAST_MACH_SET_WATCHDOG, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%o4]
+	retl
+	 nop
+	.size	sun4v_mach_set_watchdog, .-sun4v_mach_set_watchdog
+
+	/* No inputs and does not return.  */
+	.globl	sun4v_mach_sir
+	.type	sun4v_mach_sir,#function
+sun4v_mach_sir:
+	mov	%o1, %o4
+	mov	HV_FAST_MACH_SIR, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%o4]
+	retl
+	 nop
+	.size	sun4v_mach_sir, .-sun4v_mach_sir
+
+	/* %o0: channel
+	 * %o1:	ra
+	 * %o2:	num_entries
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_tx_qconf
+	.type	sun4v_ldc_tx_qconf,#function
+sun4v_ldc_tx_qconf:
+	mov	HV_FAST_LDC_TX_QCONF, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_ldc_tx_qconf, .-sun4v_ldc_tx_qconf
+
+	/* %o0: channel
+	 * %o1:	pointer to unsigned long ra
+	 * %o2:	pointer to unsigned long num_entries
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_tx_qinfo
+	.type	sun4v_ldc_tx_qinfo,#function
+sun4v_ldc_tx_qinfo:
+	mov	%o1, %g1
+	mov	%o2, %g2
+	mov	HV_FAST_LDC_TX_QINFO, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	stx	%o2, [%g2]
+	retl
+	 nop
+	.size	sun4v_ldc_tx_qinfo, .-sun4v_ldc_tx_qinfo
+
+	/* %o0: channel
+	 * %o1:	pointer to unsigned long head_off
+	 * %o2:	pointer to unsigned long tail_off
+	 * %o2:	pointer to unsigned long chan_state
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_tx_get_state
+	.type	sun4v_ldc_tx_get_state,#function
+sun4v_ldc_tx_get_state:
+	mov	%o1, %g1
+	mov	%o2, %g2
+	mov	%o3, %g3
+	mov	HV_FAST_LDC_TX_GET_STATE, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	stx	%o2, [%g2]
+	stx	%o3, [%g3]
+	retl
+	 nop
+	.size	sun4v_ldc_tx_get_state, .-sun4v_ldc_tx_get_state
+
+	/* %o0: channel
+	 * %o1:	tail_off
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_tx_set_qtail
+	.type	sun4v_ldc_tx_set_qtail,#function
+sun4v_ldc_tx_set_qtail:
+	mov	HV_FAST_LDC_TX_SET_QTAIL, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_ldc_tx_set_qtail, .-sun4v_ldc_tx_set_qtail
+
+	/* %o0: channel
+	 * %o1:	ra
+	 * %o2:	num_entries
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_rx_qconf
+	.type	sun4v_ldc_rx_qconf,#function
+sun4v_ldc_rx_qconf:
+	mov	HV_FAST_LDC_RX_QCONF, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_ldc_rx_qconf, .-sun4v_ldc_rx_qconf
+
+	/* %o0: channel
+	 * %o1:	pointer to unsigned long ra
+	 * %o2:	pointer to unsigned long num_entries
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_rx_qinfo
+	.type	sun4v_ldc_rx_qinfo,#function
+sun4v_ldc_rx_qinfo:
+	mov	%o1, %g1
+	mov	%o2, %g2
+	mov	HV_FAST_LDC_RX_QINFO, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	stx	%o2, [%g2]
+	retl
+	 nop
+	.size	sun4v_ldc_rx_qinfo, .-sun4v_ldc_rx_qinfo
+
+	/* %o0: channel
+	 * %o1:	pointer to unsigned long head_off
+	 * %o2:	pointer to unsigned long tail_off
+	 * %o2:	pointer to unsigned long chan_state
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_rx_get_state
+	.type	sun4v_ldc_rx_get_state,#function
+sun4v_ldc_rx_get_state:
+	mov	%o1, %g1
+	mov	%o2, %g2
+	mov	%o3, %g3
+	mov	HV_FAST_LDC_RX_GET_STATE, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	stx	%o2, [%g2]
+	stx	%o3, [%g3]
+	retl
+	 nop
+	.size	sun4v_ldc_rx_get_state, .-sun4v_ldc_rx_get_state
+
+	/* %o0: channel
+	 * %o1:	head_off
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_rx_set_qhead
+	.type	sun4v_ldc_rx_set_qhead,#function
+sun4v_ldc_rx_set_qhead:
+	mov	HV_FAST_LDC_RX_SET_QHEAD, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_ldc_rx_set_qhead, .-sun4v_ldc_rx_set_qhead
+
+	/* %o0: channel
+	 * %o1:	ra
+	 * %o2:	num_entries
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_ldc_set_map_table
+	.type	sun4v_ldc_set_map_table,#function
+sun4v_ldc_set_map_table:
+	mov	HV_FAST_LDC_SET_MAP_TABLE, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_ldc_set_map_table, .-sun4v_ldc_set_map_table
+
+	/* %o0: channel
+	 * %o1:	pointer to unsigned long ra
+	 * %o2:	pointer to unsigned long num_entries
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_ldc_get_map_table
+	.type	sun4v_ldc_get_map_table,#function
+sun4v_ldc_get_map_table:
+	mov	%o1, %g1
+	mov	%o2, %g2
+	mov	HV_FAST_LDC_GET_MAP_TABLE, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	stx	%o2, [%g2]
+	retl
+	 nop
+	.size	sun4v_ldc_get_map_table, .-sun4v_ldc_get_map_table
+
+	/* %o0:	channel
+	 * %o1:	dir_code
+	 * %o2:	tgt_raddr
+	 * %o3:	lcl_raddr
+	 * %o4:	len
+	 * %o5:	pointer to unsigned long actual_len
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_copy
+	.type	sun4v_ldc_copy,#function
+sun4v_ldc_copy:
+	mov	%o5, %g1
+	mov	HV_FAST_LDC_COPY, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	retl
+	 nop
+	.size	sun4v_ldc_copy, .-sun4v_ldc_copy
+
+	/* %o0:	channel
+	 * %o1:	cookie
+	 * %o2:	pointer to unsigned long ra
+	 * %o3:	pointer to unsigned long perm
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_mapin
+	.type	sun4v_ldc_mapin,#function
+sun4v_ldc_mapin:
+	mov	%o2, %g1
+	mov	%o3, %g2
+	mov	HV_FAST_LDC_MAPIN, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	stx	%o2, [%g2]
+	retl
+	 nop
+	.size	sun4v_ldc_mapin, .-sun4v_ldc_mapin
+
+	/* %o0:	ra
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_unmap
+	.type	sun4v_ldc_unmap,#function
+sun4v_ldc_unmap:
+	mov	HV_FAST_LDC_UNMAP, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_ldc_unmap, .-sun4v_ldc_unmap
+
+	/* %o0:	cookie
+	 * %o1:	mte_cookie
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ldc_revoke
+	.type	sun4v_ldc_revoke,#function
+sun4v_ldc_revoke:
+	mov	HV_FAST_LDC_REVOKE, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_ldc_revoke, .-sun4v_ldc_revoke
+
+	/* %o0: device handle
+	 * %o1:	device INO
+	 * %o2:	pointer to unsigned long cookie
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_vintr_get_cookie
+	.type	sun4v_vintr_get_cookie,#function
+sun4v_vintr_get_cookie:
+	mov	%o2, %g1
+	mov	HV_FAST_VINTR_GET_COOKIE, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	retl
+	 nop
+	.size	sun4v_vintr_get_cookie, .-sun4v_vintr_get_cookie
+
+	/* %o0: device handle
+	 * %o1:	device INO
+	 * %o2:	cookie
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_vintr_set_cookie
+	.type	sun4v_vintr_set_cookie,#function
+sun4v_vintr_set_cookie:
+	mov	HV_FAST_VINTR_SET_COOKIE, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_vintr_set_cookie, .-sun4v_vintr_set_cookie
+
+	/* %o0: device handle
+	 * %o1:	device INO
+	 * %o2:	pointer to unsigned long valid_state
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_vintr_get_valid
+	.type	sun4v_vintr_get_valid,#function
+sun4v_vintr_get_valid:
+	mov	%o2, %g1
+	mov	HV_FAST_VINTR_GET_VALID, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	retl
+	 nop
+	.size	sun4v_vintr_get_valid, .-sun4v_vintr_get_valid
+
+	/* %o0: device handle
+	 * %o1:	device INO
+	 * %o2:	valid_state
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_vintr_set_valid
+	.type	sun4v_vintr_set_valid,#function
+sun4v_vintr_set_valid:
+	mov	HV_FAST_VINTR_SET_VALID, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_vintr_set_valid, .-sun4v_vintr_set_valid
+
+	/* %o0: device handle
+	 * %o1:	device INO
+	 * %o2:	pointer to unsigned long state
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_vintr_get_state
+	.type	sun4v_vintr_get_state,#function
+sun4v_vintr_get_state:
+	mov	%o2, %g1
+	mov	HV_FAST_VINTR_GET_STATE, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	retl
+	 nop
+	.size	sun4v_vintr_get_state, .-sun4v_vintr_get_state
+
+	/* %o0: device handle
+	 * %o1:	device INO
+	 * %o2:	state
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_vintr_set_state
+	.type	sun4v_vintr_set_state,#function
+sun4v_vintr_set_state:
+	mov	HV_FAST_VINTR_SET_STATE, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_vintr_set_state, .-sun4v_vintr_set_state
+
+	/* %o0: device handle
+	 * %o1:	device INO
+	 * %o2:	pointer to unsigned long cpuid
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_vintr_get_target
+	.type	sun4v_vintr_get_target,#function
+sun4v_vintr_get_target:
+	mov	%o2, %g1
+	mov	HV_FAST_VINTR_GET_TARGET, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%g1]
+	retl
+	 nop
+	.size	sun4v_vintr_get_target, .-sun4v_vintr_get_target
+
+	/* %o0: device handle
+	 * %o1:	device INO
+	 * %o2:	cpuid
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_vintr_set_target
+	.type	sun4v_vintr_set_target,#function
+sun4v_vintr_set_target:
+	mov	HV_FAST_VINTR_SET_TARGET, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_vintr_set_target, .-sun4v_vintr_set_target
+
+	/* %o0: NCS sub-function
+	 * %o1:	sub-function arg real-address
+	 * %o2:	sub-function arg size
+	 *
+	 * returns %o0:	status
+	 */
+	.globl	sun4v_ncs_request
+	.type	sun4v_ncs_request,#function
+sun4v_ncs_request:
+	mov	HV_FAST_NCS_REQUEST, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_ncs_request, .-sun4v_ncs_request
+
+	.globl	sun4v_scv_send
+	.type	sun4v_scv_send,#function
+sun4v_scv_send:
+	save	%sp, -192, %sp
+	mov	%i0, %o0
+	mov	%i1, %o1
+	mov	%i2, %o2
+	mov	HV_FAST_SVC_SEND, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%i3]
+	ret
+	restore
+	.size	sun4v_scv_send, .-sun4v_scv_send
+
+	.globl	sun4v_scv_recv
+	.type	sun4v_scv_recv,#function
+sun4v_scv_recv:
+	save	%sp, -192, %sp
+	mov	%i0, %o0
+	mov	%i1, %o1
+	mov	%i2, %o2
+	mov	HV_FAST_SVC_RECV, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%i3]
+	ret
+	restore
+	.size	sun4v_scv_recv, .-sun4v_scv_recv
+
+	.globl	sun4v_scv_getstatus
+	.type	sun4v_scv_getstatus,#function
+sun4v_scv_getstatus:
+	mov	HV_FAST_SVC_GETSTATUS, %o5
+	mov	%o1, %o4
+	ta	HV_FAST_TRAP
+	stx	%o1, [%o4]
+	retl
+	 nop
+	.size	sun4v_scv_getstatus, .-sun4v_scv_getstatus
+
+	.globl	sun4v_scv_setstatus
+	.type	sun4v_scv_setstatus,#function
+sun4v_scv_setstatus:
+	mov	HV_FAST_SVC_SETSTATUS, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_scv_setstatus, .-sun4v_scv_setstatus
+
+	.globl	sun4v_scv_clrstatus
+	.type	sun4v_scv_clrstatus,#function
+sun4v_scv_clrstatus:
+	mov	HV_FAST_SVC_CLRSTATUS, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+	.size	sun4v_scv_clrstatus, .-sun4v_scv_clrstatus
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index baea10a..7725952 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -523,7 +523,7 @@
 #else
 	mov	0, %o0
 #endif
-	stb	%o0, [%g6 + TI_CPU]
+	sth	%o0, [%g6 + TI_CPU]
 
 	/* Off we go.... */
 	call	start_kernel
@@ -653,33 +653,54 @@
 	 restore
 sparc64_boot_end:
 
-#include "ktlb.S"
-#include "tsb.S"
 #include "etrap.S"
 #include "rtrap.S"
 #include "winfixup.S"
 #include "entry.S"
 #include "sun4v_tlb_miss.S"
 #include "sun4v_ivec.S"
+#include "ktlb.S"
+#include "tsb.S"
 
 /*
  * The following skip makes sure the trap table in ttable.S is aligned
  * on a 32K boundary as required by the v9 specs for TBA register.
  *
  * We align to a 32K boundary, then we have the 32K kernel TSB,
- * then the 32K aligned trap table.
+ * the 64K kernel 4MB TSB, and then the 32K aligned trap table.
  */
 1:
 	.skip	0x4000 + _start - 1b
 
+! 0x0000000000408000
+
 	.globl	swapper_tsb
 swapper_tsb:
 	.skip	(32 * 1024)
 
-! 0x0000000000408000
+	.globl	swapper_4m_tsb
+swapper_4m_tsb:
+	.skip	(64 * 1024)
 
+! 0x0000000000420000
+
+	/* Some care needs to be exercised if you try to move the
+	 * location of the trap table relative to other things.  For
+	 * one thing there are br* instructions in some of the
+	 * trap table entires which branch back to code in ktlb.S
+	 * Those instructions can only handle a signed 16-bit
+	 * displacement.
+	 *
+	 * There is a binutils bug (bugzilla #4558) which causes
+	 * the relocation overflow checks for such instructions to
+	 * not be done correctly.  So bintuils will not notice the
+	 * error and will instead write junk into the relocation and
+	 * you'll have an unbootable kernel.
+	 */
 #include "ttable.S"
 
+! 0x0000000000428000
+
 #include "systbls.S"
 
 	.data
diff --git a/arch/sparc64/kernel/hvapi.c b/arch/sparc64/kernel/hvapi.c
index f03ffc8..f34f5d6 100644
--- a/arch/sparc64/kernel/hvapi.c
+++ b/arch/sparc64/kernel/hvapi.c
@@ -9,6 +9,7 @@
 
 #include <asm/hypervisor.h>
 #include <asm/oplib.h>
+#include <asm/sstate.h>
 
 /* If the hypervisor indicates that the API setting
  * calls are unsupported, by returning HV_EBADTRAP or
@@ -107,7 +108,7 @@
 				p->minor = actual_minor;
 				ret = 0;
 			} else if (hv_ret == HV_EBADTRAP ||
-				   HV_ENOTSUPPORTED) {
+				   hv_ret == HV_ENOTSUPPORTED) {
 				if (p->flags & FLAG_PRE_API) {
 					if (major == 1) {
 						p->major = 1;
@@ -179,6 +180,8 @@
 	if (sun4v_hvapi_register(group, major, &minor))
 		goto bad;
 
+	sun4v_sstate_init();
+
 	return;
 
 bad:
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 3edc18e..a36f8dd 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -171,8 +171,6 @@
 	return 0;
 }
 
-extern unsigned long real_hard_smp_processor_id(void);
-
 static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid)
 {
 	unsigned int tid;
@@ -694,9 +692,20 @@
 	trap_block[cpu].irq_worklist = 0;
 }
 
-static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type)
+/* Please be very careful with register_one_mondo() and
+ * sun4v_register_mondo_queues().
+ *
+ * On SMP this gets invoked from the CPU trampoline before
+ * the cpu has fully taken over the trap table from OBP,
+ * and it's kernel stack + %g6 thread register state is
+ * not fully cooked yet.
+ *
+ * Therefore you cannot make any OBP calls, not even prom_printf,
+ * from these two routines.
+ */
+static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask)
 {
-	unsigned long num_entries = 128;
+	unsigned long num_entries = (qmask + 1) / 64;
 	unsigned long status;
 
 	status = sun4v_cpu_qconf(type, paddr, num_entries);
@@ -711,44 +720,58 @@
 {
 	struct trap_per_cpu *tb = &trap_block[this_cpu];
 
-	register_one_mondo(tb->cpu_mondo_pa, HV_CPU_QUEUE_CPU_MONDO);
-	register_one_mondo(tb->dev_mondo_pa, HV_CPU_QUEUE_DEVICE_MONDO);
-	register_one_mondo(tb->resum_mondo_pa, HV_CPU_QUEUE_RES_ERROR);
-	register_one_mondo(tb->nonresum_mondo_pa, HV_CPU_QUEUE_NONRES_ERROR);
+	register_one_mondo(tb->cpu_mondo_pa, HV_CPU_QUEUE_CPU_MONDO,
+			   tb->cpu_mondo_qmask);
+	register_one_mondo(tb->dev_mondo_pa, HV_CPU_QUEUE_DEVICE_MONDO,
+			   tb->dev_mondo_qmask);
+	register_one_mondo(tb->resum_mondo_pa, HV_CPU_QUEUE_RES_ERROR,
+			   tb->resum_qmask);
+	register_one_mondo(tb->nonresum_mondo_pa, HV_CPU_QUEUE_NONRES_ERROR,
+			   tb->nonresum_qmask);
 }
 
-static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, int use_bootmem)
+static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem)
 {
-	void *page;
+	unsigned long size = PAGE_ALIGN(qmask + 1);
+	unsigned long order = get_order(size);
+	void *p = NULL;
 
-	if (use_bootmem)
-		page = alloc_bootmem_low_pages(PAGE_SIZE);
-	else
-		page = (void *) get_zeroed_page(GFP_ATOMIC);
+	if (use_bootmem) {
+		p = __alloc_bootmem_low(size, size, 0);
+	} else {
+		struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order);
+		if (page)
+			p = page_address(page);
+	}
 
-	if (!page) {
+	if (!p) {
 		prom_printf("SUN4V: Error, cannot allocate mondo queue.\n");
 		prom_halt();
 	}
 
-	*pa_ptr = __pa(page);
+	*pa_ptr = __pa(p);
 }
 
-static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, int use_bootmem)
+static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem)
 {
-	void *page;
+	unsigned long size = PAGE_ALIGN(qmask + 1);
+	unsigned long order = get_order(size);
+	void *p = NULL;
 
-	if (use_bootmem)
-		page = alloc_bootmem_low_pages(PAGE_SIZE);
-	else
-		page = (void *) get_zeroed_page(GFP_ATOMIC);
+	if (use_bootmem) {
+		p = __alloc_bootmem_low(size, size, 0);
+	} else {
+		struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order);
+		if (page)
+			p = page_address(page);
+	}
 
-	if (!page) {
+	if (!p) {
 		prom_printf("SUN4V: Error, cannot allocate kbuf page.\n");
 		prom_halt();
 	}
 
-	*pa_ptr = __pa(page);
+	*pa_ptr = __pa(p);
 }
 
 static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_bootmem)
@@ -779,12 +802,12 @@
 	struct trap_per_cpu *tb = &trap_block[cpu];
 
 	if (alloc) {
-		alloc_one_mondo(&tb->cpu_mondo_pa, use_bootmem);
-		alloc_one_mondo(&tb->dev_mondo_pa, use_bootmem);
-		alloc_one_mondo(&tb->resum_mondo_pa, use_bootmem);
-		alloc_one_kbuf(&tb->resum_kernel_buf_pa, use_bootmem);
-		alloc_one_mondo(&tb->nonresum_mondo_pa, use_bootmem);
-		alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, use_bootmem);
+		alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask, use_bootmem);
+		alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask, use_bootmem);
+		alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask, use_bootmem);
+		alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask, use_bootmem);
+		alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask, use_bootmem);
+		alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, tb->nonresum_qmask, use_bootmem);
 
 		init_cpu_send_mondo_info(tb, use_bootmem);
 	}
diff --git a/arch/sparc64/kernel/itlb_miss.S b/arch/sparc64/kernel/itlb_miss.S
index ad46e20..5a8377b 100644
--- a/arch/sparc64/kernel/itlb_miss.S
+++ b/arch/sparc64/kernel/itlb_miss.S
@@ -11,12 +11,12 @@
 /* ITLB ** ICACHE line 2: TSB compare and TLB load	*/
 	bne,pn	%xcc, tsb_miss_itlb		! Miss
 	 mov	FAULT_CODE_ITLB, %g3
-	andcc	%g5, _PAGE_EXEC_4U, %g0		! Executable?
+	sethi	%hi(_PAGE_EXEC_4U), %g4
+	andcc	%g5, %g4, %g0			! Executable?
 	be,pn	%xcc, tsb_do_fault
 	 nop					! Delay slot, fill me
 	stxa	%g5, [%g0] ASI_ITLB_DATA_IN	! Load TLB
 	retry					! Trap done
-	nop
 
 /* ITLB ** ICACHE line 3: 				*/
 	nop
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c
new file mode 100644
index 0000000..9246c2c
--- /dev/null
+++ b/arch/sparc64/kernel/mdesc.c
@@ -0,0 +1,619 @@
+/* mdesc.c: Sun4V machine description handling.
+ *
+ * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/log2.h>
+
+#include <asm/hypervisor.h>
+#include <asm/mdesc.h>
+#include <asm/prom.h>
+#include <asm/oplib.h>
+#include <asm/smp.h>
+
+/* Unlike the OBP device tree, the machine description is a full-on
+ * DAG.  An arbitrary number of ARCs are possible from one
+ * node to other nodes and thus we can't use the OBP device_node
+ * data structure to represent these nodes inside of the kernel.
+ *
+ * Actually, it isn't even a DAG, because there are back pointers
+ * which create cycles in the graph.
+ *
+ * mdesc_hdr and mdesc_elem describe the layout of the data structure
+ * we get from the Hypervisor.
+ */
+struct mdesc_hdr {
+	u32	version; /* Transport version */
+	u32	node_sz; /* node block size */
+	u32	name_sz; /* name block size */
+	u32	data_sz; /* data block size */
+};
+
+struct mdesc_elem {
+	u8	tag;
+#define MD_LIST_END	0x00
+#define MD_NODE		0x4e
+#define MD_NODE_END	0x45
+#define MD_NOOP		0x20
+#define MD_PROP_ARC	0x61
+#define MD_PROP_VAL	0x76
+#define MD_PROP_STR	0x73
+#define MD_PROP_DATA	0x64
+	u8	name_len;
+	u16	resv;
+	u32	name_offset;
+	union {
+		struct {
+			u32	data_len;
+			u32	data_offset;
+		} data;
+		u64	val;
+	} d;
+};
+
+static struct mdesc_hdr *main_mdesc;
+static struct mdesc_node *allnodes;
+
+static struct mdesc_node *allnodes_tail;
+static unsigned int unique_id;
+
+static struct mdesc_node **mdesc_hash;
+static unsigned int mdesc_hash_size;
+
+static inline unsigned int node_hashfn(u64 node)
+{
+	return ((unsigned int) (node ^ (node >> 8) ^ (node >> 16)))
+		& (mdesc_hash_size - 1);
+}
+
+static inline void hash_node(struct mdesc_node *mp)
+{
+	struct mdesc_node **head = &mdesc_hash[node_hashfn(mp->node)];
+
+	mp->hash_next = *head;
+	*head = mp;
+
+	if (allnodes_tail) {
+		allnodes_tail->allnodes_next = mp;
+		allnodes_tail = mp;
+	} else {
+		allnodes = allnodes_tail = mp;
+	}
+}
+
+static struct mdesc_node *find_node(u64 node)
+{
+	struct mdesc_node *mp = mdesc_hash[node_hashfn(node)];
+
+	while (mp) {
+		if (mp->node == node)
+			return mp;
+
+		mp = mp->hash_next;
+	}
+	return NULL;
+}
+
+struct property *md_find_property(const struct mdesc_node *mp,
+				  const char *name,
+				  int *lenp)
+{
+	struct property *pp;
+
+	for (pp = mp->properties; pp != 0; pp = pp->next) {
+		if (strcasecmp(pp->name, name) == 0) {
+			if (lenp)
+				*lenp = pp->length;
+			break;
+		}
+	}
+	return pp;
+}
+EXPORT_SYMBOL(md_find_property);
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+const void *md_get_property(const struct mdesc_node *mp, const char *name,
+			    int *lenp)
+{
+	struct property *pp = md_find_property(mp, name, lenp);
+	return pp ? pp->value : NULL;
+}
+EXPORT_SYMBOL(md_get_property);
+
+struct mdesc_node *md_find_node_by_name(struct mdesc_node *from,
+					const char *name)
+{
+	struct mdesc_node *mp;
+
+	mp = from ? from->allnodes_next : allnodes;
+	for (; mp != NULL; mp = mp->allnodes_next) {
+		if (strcmp(mp->name, name) == 0)
+			break;
+	}
+	return mp;
+}
+EXPORT_SYMBOL(md_find_node_by_name);
+
+static unsigned int mdesc_early_allocated;
+
+static void * __init mdesc_early_alloc(unsigned long size)
+{
+	void *ret;
+
+	ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
+	if (ret == NULL) {
+		prom_printf("MDESC: alloc of %lu bytes failed.\n", size);
+		prom_halt();
+	}
+
+	memset(ret, 0, size);
+
+	mdesc_early_allocated += size;
+
+	return ret;
+}
+
+static unsigned int __init count_arcs(struct mdesc_elem *ep)
+{
+	unsigned int ret = 0;
+
+	ep++;
+	while (ep->tag != MD_NODE_END) {
+		if (ep->tag == MD_PROP_ARC)
+			ret++;
+		ep++;
+	}
+	return ret;
+}
+
+static void __init mdesc_node_alloc(u64 node, struct mdesc_elem *ep, const char *names)
+{
+	unsigned int num_arcs = count_arcs(ep);
+	struct mdesc_node *mp;
+
+	mp = mdesc_early_alloc(sizeof(*mp) +
+			       (num_arcs * sizeof(struct mdesc_arc)));
+	mp->name = names + ep->name_offset;
+	mp->node = node;
+	mp->unique_id = unique_id++;
+	mp->num_arcs = num_arcs;
+
+	hash_node(mp);
+}
+
+static inline struct mdesc_elem *node_block(struct mdesc_hdr *mdesc)
+{
+	return (struct mdesc_elem *) (mdesc + 1);
+}
+
+static inline void *name_block(struct mdesc_hdr *mdesc)
+{
+	return ((void *) node_block(mdesc)) + mdesc->node_sz;
+}
+
+static inline void *data_block(struct mdesc_hdr *mdesc)
+{
+	return ((void *) name_block(mdesc)) + mdesc->name_sz;
+}
+
+/* In order to avoid recursion (the graph can be very deep) we use a
+ * two pass algorithm.  First we allocate all the nodes and hash them.
+ * Then we iterate over each node, filling in the arcs and properties.
+ */
+static void __init build_all_nodes(struct mdesc_hdr *mdesc)
+{
+	struct mdesc_elem *start, *ep;
+	struct mdesc_node *mp;
+	const char *names;
+	void *data;
+	u64 last_node;
+
+	start = ep = node_block(mdesc);
+	last_node = mdesc->node_sz / 16;
+
+	names = name_block(mdesc);
+
+	while (1) {
+		u64 node = ep - start;
+
+		if (ep->tag == MD_LIST_END)
+			break;
+
+		if (ep->tag != MD_NODE) {
+			prom_printf("MDESC: Inconsistent element list.\n");
+			prom_halt();
+		}
+
+		mdesc_node_alloc(node, ep, names);
+
+		if (ep->d.val >= last_node) {
+			printk("MDESC: Warning, early break out of node scan.\n");
+			printk("MDESC: Next node [%lu] last_node [%lu].\n",
+			       node, last_node);
+			break;
+		}
+
+		ep = start + ep->d.val;
+	}
+
+	data = data_block(mdesc);
+	for (mp = allnodes; mp; mp = mp->allnodes_next) {
+		struct mdesc_elem *ep = start + mp->node;
+		struct property **link = &mp->properties;
+		unsigned int this_arc = 0;
+
+		ep++;
+		while (ep->tag != MD_NODE_END) {
+			switch (ep->tag) {
+			case MD_PROP_ARC: {
+				struct mdesc_node *target;
+
+				if (this_arc >= mp->num_arcs) {
+					prom_printf("MDESC: ARC overrun [%u:%u]\n",
+						    this_arc, mp->num_arcs);
+					prom_halt();
+				}
+				target = find_node(ep->d.val);
+				if (!target) {
+					printk("MDESC: Warning, arc points to "
+					       "missing node, ignoring.\n");
+					break;
+				}
+				mp->arcs[this_arc].name =
+					(names + ep->name_offset);
+				mp->arcs[this_arc].arc = target;
+				this_arc++;
+				break;
+			}
+
+			case MD_PROP_VAL:
+			case MD_PROP_STR:
+			case MD_PROP_DATA: {
+				struct property *p = mdesc_early_alloc(sizeof(*p));
+
+				p->unique_id = unique_id++;
+				p->name = (char *) names + ep->name_offset;
+				if (ep->tag == MD_PROP_VAL) {
+					p->value = &ep->d.val;
+					p->length = 8;
+				} else {
+					p->value = data + ep->d.data.data_offset;
+					p->length = ep->d.data.data_len;
+				}
+				*link = p;
+				link = &p->next;
+				break;
+			}
+
+			case MD_NOOP:
+				break;
+
+			default:
+				printk("MDESC: Warning, ignoring unknown tag type %02x\n",
+				       ep->tag);
+			}
+			ep++;
+		}
+	}
+}
+
+static unsigned int __init count_nodes(struct mdesc_hdr *mdesc)
+{
+	struct mdesc_elem *ep = node_block(mdesc);
+	struct mdesc_elem *end;
+	unsigned int cnt = 0;
+
+	end = ((void *)ep) + mdesc->node_sz;
+	while (ep < end) {
+		if (ep->tag == MD_NODE)
+			cnt++;
+		ep++;
+	}
+	return cnt;
+}
+
+static void __init report_platform_properties(void)
+{
+	struct mdesc_node *pn = md_find_node_by_name(NULL, "platform");
+	const char *s;
+	const u64 *v;
+
+	if (!pn) {
+		prom_printf("No platform node in machine-description.\n");
+		prom_halt();
+	}
+
+	s = md_get_property(pn, "banner-name", NULL);
+	printk("PLATFORM: banner-name [%s]\n", s);
+	s = md_get_property(pn, "name", NULL);
+	printk("PLATFORM: name [%s]\n", s);
+
+	v = md_get_property(pn, "hostid", NULL);
+	if (v)
+		printk("PLATFORM: hostid [%08lx]\n", *v);
+	v = md_get_property(pn, "serial#", NULL);
+	if (v)
+		printk("PLATFORM: serial# [%08lx]\n", *v);
+	v = md_get_property(pn, "stick-frequency", NULL);
+	printk("PLATFORM: stick-frequency [%08lx]\n", *v);
+	v = md_get_property(pn, "mac-address", NULL);
+	if (v)
+		printk("PLATFORM: mac-address [%lx]\n", *v);
+	v = md_get_property(pn, "watchdog-resolution", NULL);
+	if (v)
+		printk("PLATFORM: watchdog-resolution [%lu ms]\n", *v);
+	v = md_get_property(pn, "watchdog-max-timeout", NULL);
+	if (v)
+		printk("PLATFORM: watchdog-max-timeout [%lu ms]\n", *v);
+	v = md_get_property(pn, "max-cpus", NULL);
+	if (v)
+		printk("PLATFORM: max-cpus [%lu]\n", *v);
+}
+
+static int inline find_in_proplist(const char *list, const char *match, int len)
+{
+	while (len > 0) {
+		int l;
+
+		if (!strcmp(list, match))
+			return 1;
+		l = strlen(list) + 1;
+		list += l;
+		len -= l;
+	}
+	return 0;
+}
+
+static void __init fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_node *mp)
+{
+	const u64 *level = md_get_property(mp, "level", NULL);
+	const u64 *size = md_get_property(mp, "size", NULL);
+	const u64 *line_size = md_get_property(mp, "line-size", NULL);
+	const char *type;
+	int type_len;
+
+	type = md_get_property(mp, "type", &type_len);
+
+	switch (*level) {
+	case 1:
+		if (find_in_proplist(type, "instn", type_len)) {
+			c->icache_size = *size;
+			c->icache_line_size = *line_size;
+		} else if (find_in_proplist(type, "data", type_len)) {
+			c->dcache_size = *size;
+			c->dcache_line_size = *line_size;
+		}
+		break;
+
+	case 2:
+		c->ecache_size = *size;
+		c->ecache_line_size = *line_size;
+		break;
+
+	default:
+		break;
+	}
+
+	if (*level == 1) {
+		unsigned int i;
+
+		for (i = 0; i < mp->num_arcs; i++) {
+			struct mdesc_node *t = mp->arcs[i].arc;
+
+			if (strcmp(mp->arcs[i].name, "fwd"))
+				continue;
+
+			if (!strcmp(t->name, "cache"))
+				fill_in_one_cache(c, t);
+		}
+	}
+}
+
+static void __init mark_core_ids(struct mdesc_node *mp, int core_id)
+{
+	unsigned int i;
+
+	for (i = 0; i < mp->num_arcs; i++) {
+		struct mdesc_node *t = mp->arcs[i].arc;
+		const u64 *id;
+
+		if (strcmp(mp->arcs[i].name, "back"))
+			continue;
+
+		if (!strcmp(t->name, "cpu")) {
+			id = md_get_property(t, "id", NULL);
+			if (*id < NR_CPUS)
+				cpu_data(*id).core_id = core_id;
+		} else {
+			unsigned int j;
+
+			for (j = 0; j < t->num_arcs; j++) {
+				struct mdesc_node *n = t->arcs[j].arc;
+
+				if (strcmp(t->arcs[j].name, "back"))
+					continue;
+
+				if (strcmp(n->name, "cpu"))
+					continue;
+
+				id = md_get_property(n, "id", NULL);
+				if (*id < NR_CPUS)
+					cpu_data(*id).core_id = core_id;
+			}
+		}
+	}
+}
+
+static void __init set_core_ids(void)
+{
+	struct mdesc_node *mp;
+	int idx;
+
+	idx = 1;
+	md_for_each_node_by_name(mp, "cache") {
+		const u64 *level = md_get_property(mp, "level", NULL);
+		const char *type;
+		int len;
+
+		if (*level != 1)
+			continue;
+
+		type = md_get_property(mp, "type", &len);
+		if (!find_in_proplist(type, "instn", len))
+			continue;
+
+		mark_core_ids(mp, idx);
+
+		idx++;
+	}
+}
+
+static void __init get_one_mondo_bits(const u64 *p, unsigned int *mask, unsigned char def)
+{
+	u64 val;
+
+	if (!p)
+		goto use_default;
+	val = *p;
+
+	if (!val || val >= 64)
+		goto use_default;
+
+	*mask = ((1U << val) * 64U) - 1U;
+	return;
+
+use_default:
+	*mask = ((1U << def) * 64U) - 1U;
+}
+
+static void __init get_mondo_data(struct mdesc_node *mp, struct trap_per_cpu *tb)
+{
+	const u64 *val;
+
+	val = md_get_property(mp, "q-cpu-mondo-#bits", NULL);
+	get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7);
+
+	val = md_get_property(mp, "q-dev-mondo-#bits", NULL);
+	get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7);
+
+	val = md_get_property(mp, "q-resumable-#bits", NULL);
+	get_one_mondo_bits(val, &tb->resum_qmask, 6);
+
+	val = md_get_property(mp, "q-nonresumable-#bits", NULL);
+	get_one_mondo_bits(val, &tb->nonresum_qmask, 2);
+}
+
+static void __init mdesc_fill_in_cpu_data(void)
+{
+	struct mdesc_node *mp;
+
+	ncpus_probed = 0;
+	md_for_each_node_by_name(mp, "cpu") {
+		const u64 *id = md_get_property(mp, "id", NULL);
+		const u64 *cfreq = md_get_property(mp, "clock-frequency", NULL);
+		struct trap_per_cpu *tb;
+		cpuinfo_sparc *c;
+		unsigned int i;
+		int cpuid;
+
+		ncpus_probed++;
+
+		cpuid = *id;
+
+#ifdef CONFIG_SMP
+		if (cpuid >= NR_CPUS)
+			continue;
+#else
+		/* On uniprocessor we only want the values for the
+		 * real physical cpu the kernel booted onto, however
+		 * cpu_data() only has one entry at index 0.
+		 */
+		if (cpuid != real_hard_smp_processor_id())
+			continue;
+		cpuid = 0;
+#endif
+
+		c = &cpu_data(cpuid);
+		c->clock_tick = *cfreq;
+
+		tb = &trap_block[cpuid];
+		get_mondo_data(mp, tb);
+
+		for (i = 0; i < mp->num_arcs; i++) {
+			struct mdesc_node *t = mp->arcs[i].arc;
+			unsigned int j;
+
+			if (strcmp(mp->arcs[i].name, "fwd"))
+				continue;
+
+			if (!strcmp(t->name, "cache")) {
+				fill_in_one_cache(c, t);
+				continue;
+			}
+
+			for (j = 0; j < t->num_arcs; j++) {
+				struct mdesc_node *n;
+
+				n = t->arcs[j].arc;
+				if (strcmp(t->arcs[j].name, "fwd"))
+					continue;
+
+				if (!strcmp(n->name, "cache"))
+					fill_in_one_cache(c, n);
+			}
+		}
+
+#ifdef CONFIG_SMP
+		cpu_set(cpuid, cpu_present_map);
+		cpu_set(cpuid, phys_cpu_present_map);
+#endif
+
+		c->core_id = 0;
+	}
+
+	set_core_ids();
+
+	smp_fill_in_sib_core_maps();
+}
+
+void __init sun4v_mdesc_init(void)
+{
+	unsigned long len, real_len, status;
+
+	(void) sun4v_mach_desc(0UL, 0UL, &len);
+
+	printk("MDESC: Size is %lu bytes.\n", len);
+
+	main_mdesc = mdesc_early_alloc(len);
+
+	status = sun4v_mach_desc(__pa(main_mdesc), len, &real_len);
+	if (status != HV_EOK || real_len > len) {
+		prom_printf("sun4v_mach_desc fails, err(%lu), "
+			    "len(%lu), real_len(%lu)\n",
+			    status, len, real_len);
+		prom_halt();
+	}
+
+	len = count_nodes(main_mdesc);
+	printk("MDESC: %lu nodes.\n", len);
+
+	len = roundup_pow_of_two(len);
+
+	mdesc_hash = mdesc_early_alloc(len * sizeof(struct mdesc_node *));
+	mdesc_hash_size = len;
+
+	printk("MDESC: Hash size %lu entries.\n", len);
+
+	build_all_nodes(main_mdesc);
+
+	printk("MDESC: Built graph with %u bytes of memory.\n",
+	       mdesc_early_allocated);
+
+	report_platform_properties();
+	mdesc_fill_in_cpu_data();
+}
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index d4c077d..38a32bc 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -306,6 +306,20 @@
 	pci_controller_scan(pci_controller_init);
 }
 
+static int ofpci_verbose;
+
+static int __init ofpci_debug(char *str)
+{
+	int val = 0;
+
+	get_option(&str, &val);
+	if (val)
+		ofpci_verbose = 1;
+	return 1;
+}
+
+__setup("ofpci_debug=", ofpci_debug);
+
 static unsigned long pci_parse_of_flags(u32 addr0)
 {
 	unsigned long flags = 0;
@@ -337,7 +351,9 @@
 	addrs = of_get_property(node, "assigned-addresses", &proplen);
 	if (!addrs)
 		return;
-	printk("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
+	if (ofpci_verbose)
+		printk("    parse addresses (%d bytes) @ %p\n",
+		       proplen, addrs);
 	op_res = &op->resource[0];
 	for (; proplen >= 20; proplen -= 20, addrs += 5, op_res++) {
 		struct resource *res;
@@ -348,8 +364,9 @@
 		if (!flags)
 			continue;
 		i = addrs[0] & 0xff;
-		printk("  start: %lx, end: %lx, i: %x\n",
-		       op_res->start, op_res->end, i);
+		if (ofpci_verbose)
+			printk("  start: %lx, end: %lx, i: %x\n",
+			       op_res->start, op_res->end, i);
 
 		if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
 			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
@@ -393,8 +410,9 @@
 	if (type == NULL)
 		type = "";
 
-	printk("    create device, devfn: %x, type: %s hostcontroller(%d)\n",
-	       devfn, type, host_controller);
+	if (ofpci_verbose)
+		printk("    create device, devfn: %x, type: %s\n",
+		       devfn, type);
 
 	dev->bus = bus;
 	dev->sysdata = node;
@@ -434,8 +452,9 @@
 		sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
 			dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
 	}
-	printk("    class: 0x%x device name: %s\n",
-	       dev->class, pci_name(dev));
+	if (ofpci_verbose)
+		printk("    class: 0x%x device name: %s\n",
+		       dev->class, pci_name(dev));
 
 	/* I have seen IDE devices which will not respond to
 	 * the bmdma simplex check reads if bus mastering is
@@ -469,7 +488,8 @@
 	}
 	pci_parse_of_addrs(sd->op, node, dev);
 
-	printk("    adding to system ...\n");
+	if (ofpci_verbose)
+		printk("    adding to system ...\n");
 
 	pci_device_add(dev, bus);
 
@@ -547,7 +567,8 @@
 	unsigned int flags;
 	u64 size;
 
-	printk("of_scan_pci_bridge(%s)\n", node->full_name);
+	if (ofpci_verbose)
+		printk("of_scan_pci_bridge(%s)\n", node->full_name);
 
 	/* parse bus-range property */
 	busrange = of_get_property(node, "bus-range", &len);
@@ -632,7 +653,8 @@
 simba_cont:
 	sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
 		bus->number);
-	printk("    bus name: %s\n", bus->name);
+	if (ofpci_verbose)
+		printk("    bus name: %s\n", bus->name);
 
 	pci_of_scan_bus(pbm, node, bus);
 }
@@ -646,12 +668,14 @@
 	int reglen, devfn;
 	struct pci_dev *dev;
 
-	printk("PCI: scan_bus[%s] bus no %d\n",
-	       node->full_name, bus->number);
+	if (ofpci_verbose)
+		printk("PCI: scan_bus[%s] bus no %d\n",
+		       node->full_name, bus->number);
 
 	child = NULL;
 	while ((child = of_get_next_child(node, child)) != NULL) {
-		printk("  * %s\n", child->full_name);
+		if (ofpci_verbose)
+			printk("  * %s\n", child->full_name);
 		reg = of_get_property(child, "reg", &reglen);
 		if (reg == NULL || reglen < 20)
 			continue;
@@ -661,7 +685,9 @@
 		dev = of_create_pci_dev(pbm, child, bus, devfn, 0);
 		if (!dev)
 			continue;
-		printk("PCI: dev header type: %x\n", dev->hdr_type);
+		if (ofpci_verbose)
+			printk("PCI: dev header type: %x\n",
+			       dev->hdr_type);
 
 		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
 		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index e237779..323d6c2 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -762,9 +762,10 @@
 			/* Of course, Sun has to encode things a thousand
 			 * different ways, inconsistently.
 			 */
-			cpu_find_by_instance(0, &dp, NULL);
-			if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe"))
-				hummingbird_p = 1;
+			for_each_node_by_type(dp, "cpu") {
+				if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe"))
+					hummingbird_p = 1;
+			}
 		}
 	}
 
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 044e8ec..6b3fe2c 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -12,6 +12,7 @@
 #include <linux/percpu.h>
 #include <linux/irq.h>
 #include <linux/msi.h>
+#include <linux/log2.h>
 
 #include <asm/iommu.h>
 #include <asm/irq.h>
@@ -26,6 +27,9 @@
 
 #include "pci_sun4v.h"
 
+static unsigned long vpci_major = 1;
+static unsigned long vpci_minor = 1;
+
 #define PGLIST_NENTS	(PAGE_SIZE / sizeof(u64))
 
 struct iommu_batch {
@@ -638,9 +642,8 @@
 {
 	struct iommu *iommu = pbm->iommu;
 	struct property *prop;
-	unsigned long num_tsb_entries, sz;
+	unsigned long num_tsb_entries, sz, tsbsize;
 	u32 vdma[2], dma_mask, dma_offset;
-	int tsbsize;
 
 	prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
 	if (prop) {
@@ -654,31 +657,15 @@
 		vdma[1] = 0x80000000;
 	}
 
-	dma_mask = vdma[0];
-	switch (vdma[1]) {
-		case 0x20000000:
-			dma_mask |= 0x1fffffff;
-			tsbsize = 64;
-			break;
-
-		case 0x40000000:
-			dma_mask |= 0x3fffffff;
-			tsbsize = 128;
-			break;
-
-		case 0x80000000:
-			dma_mask |= 0x7fffffff;
-			tsbsize = 256;
-			break;
-
-		default:
-			prom_printf("PCI-SUN4V: strange virtual-dma size.\n");
-			prom_halt();
+	if ((vdma[0] | vdma[1]) & ~IO_PAGE_MASK) {
+		prom_printf("PCI-SUN4V: strange virtual-dma[%08x:%08x].\n",
+			    vdma[0], vdma[1]);
+		prom_halt();
 	};
 
-	tsbsize *= (8 * 1024);
-
-	num_tsb_entries = tsbsize / sizeof(iopte_t);
+	dma_mask = (roundup_pow_of_two(vdma[1]) - 1UL);
+	num_tsb_entries = vdma[1] / IO_PAGE_SIZE;
+	tsbsize = num_tsb_entries * sizeof(iopte_t);
 
 	dma_offset = vdma[0];
 
@@ -689,7 +676,7 @@
 	iommu->dma_addr_mask = dma_mask;
 
 	/* Allocate and initialize the free area map.  */
-	sz = num_tsb_entries / 8;
+	sz = (num_tsb_entries + 7) / 8;
 	sz = (sz + 7UL) & ~7UL;
 	iommu->arena.map = kzalloc(sz, GFP_KERNEL);
 	if (!iommu->arena.map) {
@@ -1178,6 +1165,7 @@
 
 void sun4v_pci_init(struct device_node *dp, char *model_name)
 {
+	static int hvapi_negotiated = 0;
 	struct pci_controller_info *p;
 	struct pci_pbm_info *pbm;
 	struct iommu *iommu;
@@ -1186,6 +1174,20 @@
 	u32 devhandle;
 	int i;
 
+	if (!hvapi_negotiated++) {
+		int err = sun4v_hvapi_register(HV_GRP_PCI,
+					       vpci_major,
+					       &vpci_minor);
+
+		if (err) {
+			prom_printf("SUN4V_PCI: Could not register hvapi, "
+				    "err=%d\n", err);
+			prom_halt();
+		}
+		printk("SUN4V_PCI: Registered hvapi major[%lu] minor[%lu]\n",
+		       vpci_major, vpci_minor);
+	}
+
 	prop = of_find_property(dp, "reg", NULL);
 	regs = prop->value;
 
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 699b24b..5d6adea 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -19,6 +19,7 @@
 #include <asm/prom.h>
 #include <asm/of_device.h>
 #include <asm/io.h>
+#include <asm/sstate.h>
 
 #include <linux/unistd.h>
 
@@ -53,6 +54,7 @@
 
 void machine_power_off(void)
 {
+	sstate_poweroff();
 	if (!serial_console || scons_pwroff) {
 #ifdef CONFIG_PCI
 		if (power_reg) {
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 952762b..f5f97e2 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -45,6 +45,7 @@
 #include <asm/mmu_context.h>
 #include <asm/unistd.h>
 #include <asm/hypervisor.h>
+#include <asm/sstate.h>
 
 /* #define VERBOSE_SHOWREGS */
 
@@ -106,6 +107,7 @@
 
 void machine_halt(void)
 {
+	sstate_halt();
 	if (!serial_console && prom_palette)
 		prom_palette (1);
 	if (prom_keyboard)
@@ -116,6 +118,7 @@
 
 void machine_alt_power_off(void)
 {
+	sstate_poweroff();
 	if (!serial_console && prom_palette)
 		prom_palette(1);
 	if (prom_keyboard)
@@ -128,6 +131,7 @@
 {
 	char *p;
 	
+	sstate_reboot();
 	p = strchr (reboot_command, '\n');
 	if (p) *p = 0;
 	if (!serial_console && prom_palette)
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index 02830e4..dad4b3b 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -28,6 +28,7 @@
 #include <asm/irq.h>
 #include <asm/asi.h>
 #include <asm/upa.h>
+#include <asm/smp.h>
 
 static struct device_node *allnodes;
 
@@ -1665,6 +1666,150 @@
 	return ret;
 }
 
+static const char *get_mid_prop(void)
+{
+	return (tlb_type == spitfire ? "upa-portid" : "portid");
+}
+
+struct device_node *of_find_node_by_cpuid(int cpuid)
+{
+	struct device_node *dp;
+	const char *mid_prop = get_mid_prop();
+
+	for_each_node_by_type(dp, "cpu") {
+		int id = of_getintprop_default(dp, mid_prop, -1);
+		const char *this_mid_prop = mid_prop;
+
+		if (id < 0) {
+			this_mid_prop = "cpuid";
+			id = of_getintprop_default(dp, this_mid_prop, -1);
+		}
+
+		if (id < 0) {
+			prom_printf("OF: Serious problem, cpu lacks "
+				    "%s property", this_mid_prop);
+			prom_halt();
+		}
+		if (cpuid == id)
+			return dp;
+	}
+	return NULL;
+}
+
+static void __init of_fill_in_cpu_data(void)
+{
+	struct device_node *dp;
+	const char *mid_prop = get_mid_prop();
+
+	ncpus_probed = 0;
+	for_each_node_by_type(dp, "cpu") {
+		int cpuid = of_getintprop_default(dp, mid_prop, -1);
+		const char *this_mid_prop = mid_prop;
+		struct device_node *portid_parent;
+		int portid = -1;
+
+		portid_parent = NULL;
+		if (cpuid < 0) {
+			this_mid_prop = "cpuid";
+			cpuid = of_getintprop_default(dp, this_mid_prop, -1);
+			if (cpuid >= 0) {
+				int limit = 2;
+
+				portid_parent = dp;
+				while (limit--) {
+					portid_parent = portid_parent->parent;
+					if (!portid_parent)
+						break;
+					portid = of_getintprop_default(portid_parent,
+								       "portid", -1);
+					if (portid >= 0)
+						break;
+				}
+			}
+		}
+
+		if (cpuid < 0) {
+			prom_printf("OF: Serious problem, cpu lacks "
+				    "%s property", this_mid_prop);
+			prom_halt();
+		}
+
+		ncpus_probed++;
+
+#ifdef CONFIG_SMP
+		if (cpuid >= NR_CPUS)
+			continue;
+#else
+		/* On uniprocessor we only want the values for the
+		 * real physical cpu the kernel booted onto, however
+		 * cpu_data() only has one entry at index 0.
+		 */
+		if (cpuid != real_hard_smp_processor_id())
+			continue;
+		cpuid = 0;
+#endif
+
+		cpu_data(cpuid).clock_tick =
+			of_getintprop_default(dp, "clock-frequency", 0);
+
+		if (portid_parent) {
+			cpu_data(cpuid).dcache_size =
+				of_getintprop_default(dp, "l1-dcache-size",
+						      16 * 1024);
+			cpu_data(cpuid).dcache_line_size =
+				of_getintprop_default(dp, "l1-dcache-line-size",
+						      32);
+			cpu_data(cpuid).icache_size =
+				of_getintprop_default(dp, "l1-icache-size",
+						      8 * 1024);
+			cpu_data(cpuid).icache_line_size =
+				of_getintprop_default(dp, "l1-icache-line-size",
+						      32);
+			cpu_data(cpuid).ecache_size =
+				of_getintprop_default(dp, "l2-cache-size", 0);
+			cpu_data(cpuid).ecache_line_size =
+				of_getintprop_default(dp, "l2-cache-line-size", 0);
+			if (!cpu_data(cpuid).ecache_size ||
+			    !cpu_data(cpuid).ecache_line_size) {
+				cpu_data(cpuid).ecache_size =
+					of_getintprop_default(portid_parent,
+							      "l2-cache-size",
+							      (4 * 1024 * 1024));
+				cpu_data(cpuid).ecache_line_size =
+					of_getintprop_default(portid_parent,
+							      "l2-cache-line-size", 64);
+			}
+
+			cpu_data(cpuid).core_id = portid + 1;
+		} else {
+			cpu_data(cpuid).dcache_size =
+				of_getintprop_default(dp, "dcache-size", 16 * 1024);
+			cpu_data(cpuid).dcache_line_size =
+				of_getintprop_default(dp, "dcache-line-size", 32);
+
+			cpu_data(cpuid).icache_size =
+				of_getintprop_default(dp, "icache-size", 16 * 1024);
+			cpu_data(cpuid).icache_line_size =
+				of_getintprop_default(dp, "icache-line-size", 32);
+
+			cpu_data(cpuid).ecache_size =
+				of_getintprop_default(dp, "ecache-size",
+						      (4 * 1024 * 1024));
+			cpu_data(cpuid).ecache_line_size =
+				of_getintprop_default(dp, "ecache-line-size", 64);
+
+			cpu_data(cpuid).core_id = 0;
+		}
+
+#ifdef CONFIG_SMP
+		cpu_set(cpuid, cpu_present_map);
+		cpu_set(cpuid, phys_cpu_present_map);
+#endif
+	}
+
+	smp_fill_in_sib_core_maps();
+}
+
 void __init prom_build_devicetree(void)
 {
 	struct device_node **nextp;
@@ -1679,4 +1824,7 @@
 				     &nextp);
 	printk("PROM: Built device tree with %u bytes of memory.\n",
 	       prom_early_allocated);
+
+	if (tlb_type != hypervisor)
+		of_fill_in_cpu_data();
 }
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index dea9c3c..de9b4c1 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -46,11 +46,17 @@
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/mmu.h>
+#include <asm/ns87303.h>
 
 #ifdef CONFIG_IP_PNP
 #include <net/ipconfig.h>
 #endif
 
+/* Used to synchronize accesses to NatSemi SUPER I/O chip configure
+ * operations in asm/ns87303.h
+ */
+DEFINE_SPINLOCK(ns87303_lock);
+
 struct screen_info screen_info = {
 	0, 0,			/* orig-x, orig-y */
 	0,			/* unused */
@@ -370,8 +376,6 @@
 	init_cur_cpu_trap(current_thread_info());
 
 	paging_init();
-
-	smp_setup_cpu_possible_map();
 }
 
 static int __init set_preferred_console(void)
@@ -424,7 +428,7 @@
 unsigned int dcache_parity_tl1_occurred;
 unsigned int icache_parity_tl1_occurred;
 
-static int ncpus_probed;
+int ncpus_probed;
 
 static int show_cpuinfo(struct seq_file *m, void *__unused)
 {
@@ -516,14 +520,6 @@
 
 	err = -ENOMEM;
 
-	/* Count the number of physically present processors in
-	 * the machine, even on uniprocessor, so that /proc/cpuinfo
-	 * output is consistent with 2.4.x
-	 */
-	ncpus_probed = 0;
-	while (!cpu_find_by_instance(ncpus_probed, NULL, NULL))
-		ncpus_probed++;
-
 	for_each_possible_cpu(i) {
 		struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
 		if (p) {
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 24fdf1d..c550bba 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -40,6 +40,7 @@
 #include <asm/tlb.h>
 #include <asm/sections.h>
 #include <asm/prom.h>
+#include <asm/mdesc.h>
 
 extern void calibrate_delay(void);
 
@@ -75,53 +76,6 @@
 			   i, cpu_data(i).clock_tick);
 }
 
-void __init smp_store_cpu_info(int id)
-{
-	struct device_node *dp;
-	int def;
-
-	cpu_data(id).udelay_val			= loops_per_jiffy;
-
-	cpu_find_by_mid(id, &dp);
-	cpu_data(id).clock_tick =
-		of_getintprop_default(dp, "clock-frequency", 0);
-
-	def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024));
-	cpu_data(id).dcache_size =
-		of_getintprop_default(dp, "dcache-size", def);
-
-	def = 32;
-	cpu_data(id).dcache_line_size =
-		of_getintprop_default(dp, "dcache-line-size", def);
-
-	def = 16 * 1024;
-	cpu_data(id).icache_size =
-		of_getintprop_default(dp, "icache-size", def);
-
-	def = 32;
-	cpu_data(id).icache_line_size =
-		of_getintprop_default(dp, "icache-line-size", def);
-
-	def = ((tlb_type == hypervisor) ?
-	       (3 * 1024 * 1024) :
-	       (4 * 1024 * 1024));
-	cpu_data(id).ecache_size =
-		of_getintprop_default(dp, "ecache-size", def);
-
-	def = 64;
-	cpu_data(id).ecache_line_size =
-		of_getintprop_default(dp, "ecache-line-size", def);
-
-	printk("CPU[%d]: Caches "
-	       "D[sz(%d):line_sz(%d)] "
-	       "I[sz(%d):line_sz(%d)] "
-	       "E[sz(%d):line_sz(%d)]\n",
-	       id,
-	       cpu_data(id).dcache_size, cpu_data(id).dcache_line_size,
-	       cpu_data(id).icache_size, cpu_data(id).icache_line_size,
-	       cpu_data(id).ecache_size, cpu_data(id).ecache_line_size);
-}
-
 extern void setup_sparc64_timer(void);
 
 static volatile unsigned long callin_flag = 0;
@@ -145,7 +99,7 @@
 	local_irq_enable();
 
 	calibrate_delay();
-	smp_store_cpu_info(cpuid);
+	cpu_data(cpuid).udelay_val = loops_per_jiffy;
 	callin_flag = 1;
 	__asm__ __volatile__("membar #Sync\n\t"
 			     "flush  %%g6" : : : "memory");
@@ -340,9 +294,8 @@
 
 		prom_startcpu_cpuid(cpu, entry, cookie);
 	} else {
-		struct device_node *dp;
+		struct device_node *dp = of_find_node_by_cpuid(cpu);
 
-		cpu_find_by_mid(cpu, &dp);
 		prom_startcpu(dp->node, entry, cookie);
 	}
 
@@ -447,7 +400,7 @@
 static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
 {
 	u64 pstate, ver;
-	int nack_busy_id, is_jbus;
+	int nack_busy_id, is_jbus, need_more;
 
 	if (cpus_empty(mask))
 		return;
@@ -463,6 +416,7 @@
 	__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
 
 retry:
+	need_more = 0;
 	__asm__ __volatile__("wrpr %0, %1, %%pstate\n\t"
 			     : : "r" (pstate), "i" (PSTATE_IE));
 
@@ -491,6 +445,10 @@
 				: /* no outputs */
 				: "r" (target), "i" (ASI_INTR_W));
 			nack_busy_id++;
+			if (nack_busy_id == 32) {
+				need_more = 1;
+				break;
+			}
 		}
 	}
 
@@ -507,6 +465,16 @@
 			if (dispatch_stat == 0UL) {
 				__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
 						     : : "r" (pstate));
+				if (unlikely(need_more)) {
+					int i, cnt = 0;
+					for_each_cpu_mask(i, mask) {
+						cpu_clear(i, mask);
+						cnt++;
+						if (cnt == 32)
+							break;
+					}
+					goto retry;
+				}
 				return;
 			}
 			if (!--stuck)
@@ -544,6 +512,8 @@
 				if ((dispatch_stat & check_mask) == 0)
 					cpu_clear(i, mask);
 				this_busy_nack += 2;
+				if (this_busy_nack == 64)
+					break;
 			}
 
 			goto retry;
@@ -1191,23 +1161,14 @@
 
 static void __init smp_tune_scheduling(void)
 {
-	struct device_node *dp;
-	int instance;
-	unsigned int def, smallest = ~0U;
+	unsigned int smallest = ~0U;
+	int i;
 
-	def = ((tlb_type == hypervisor) ?
-	       (3 * 1024 * 1024) :
-	       (4 * 1024 * 1024));
+	for (i = 0; i < NR_CPUS; i++) {
+		unsigned int val = cpu_data(i).ecache_size;
 
-	instance = 0;
-	while (!cpu_find_by_instance(instance, &dp, NULL)) {
-		unsigned int val;
-
-		val = of_getintprop_default(dp, "ecache-size", def);
-		if (val < smallest)
+		if (val && val < smallest)
 			smallest = val;
-
-		instance++;
 	}
 
 	/* Any value less than 256K is nonsense.  */
@@ -1230,60 +1191,44 @@
 	int i;
 
 	if (num_possible_cpus() > max_cpus) {
-		int instance, mid;
-
-		instance = 0;
-		while (!cpu_find_by_instance(instance, NULL, &mid)) {
-			if (mid != boot_cpu_id) {
-				cpu_clear(mid, phys_cpu_present_map);
-				cpu_clear(mid, cpu_present_map);
+		for_each_possible_cpu(i) {
+			if (i != boot_cpu_id) {
+				cpu_clear(i, phys_cpu_present_map);
+				cpu_clear(i, cpu_present_map);
 				if (num_possible_cpus() <= max_cpus)
 					break;
 			}
-			instance++;
 		}
 	}
 
-	for_each_possible_cpu(i) {
-		if (tlb_type == hypervisor) {
-			int j;
-
-			/* XXX get this mapping from machine description */
-			for_each_possible_cpu(j) {
-				if ((j >> 2) == (i >> 2))
-					cpu_set(j, cpu_sibling_map[i]);
-			}
-		} else {
-			cpu_set(i, cpu_sibling_map[i]);
-		}
-	}
-
-	smp_store_cpu_info(boot_cpu_id);
+	cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy;
 	smp_tune_scheduling();
 }
 
-/* Set this up early so that things like the scheduler can init
- * properly.  We use the same cpu mask for both the present and
- * possible cpu map.
- */
-void __init smp_setup_cpu_possible_map(void)
-{
-	int instance, mid;
-
-	instance = 0;
-	while (!cpu_find_by_instance(instance, NULL, &mid)) {
-		if (mid < NR_CPUS) {
-			cpu_set(mid, phys_cpu_present_map);
-			cpu_set(mid, cpu_present_map);
-		}
-		instance++;
-	}
-}
-
 void __devinit smp_prepare_boot_cpu(void)
 {
 }
 
+void __devinit smp_fill_in_sib_core_maps(void)
+{
+	unsigned int i;
+
+	for_each_possible_cpu(i) {
+		unsigned int j;
+
+		if (cpu_data(i).core_id == 0) {
+			cpu_set(i, cpu_sibling_map[i]);
+			continue;
+		}
+
+		for_each_possible_cpu(j) {
+			if (cpu_data(i).core_id ==
+			    cpu_data(j).core_id)
+				cpu_set(j, cpu_sibling_map[i]);
+		}
+	}
+}
+
 int __cpuinit __cpu_up(unsigned int cpu)
 {
 	int ret = smp_boot_one_cpu(cpu);
@@ -1337,7 +1282,7 @@
 EXPORT_SYMBOL(__per_cpu_base);
 EXPORT_SYMBOL(__per_cpu_shift);
 
-void __init setup_per_cpu_areas(void)
+void __init real_setup_per_cpu_areas(void)
 {
 	unsigned long goal, size, i;
 	char *ptr;
diff --git a/arch/sparc64/kernel/sstate.c b/arch/sparc64/kernel/sstate.c
new file mode 100644
index 0000000..5b6e75b
--- /dev/null
+++ b/arch/sparc64/kernel/sstate.c
@@ -0,0 +1,104 @@
+/* sstate.c: System soft state support.
+ *
+ * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#include <linux/init.h>
+
+#include <asm/hypervisor.h>
+#include <asm/sstate.h>
+#include <asm/oplib.h>
+#include <asm/head.h>
+#include <asm/io.h>
+
+static int hv_supports_soft_state;
+
+static unsigned long kimage_addr_to_ra(const char *p)
+{
+	unsigned long val = (unsigned long) p;
+
+	return kern_base + (val - KERNBASE);
+}
+
+static void do_set_sstate(unsigned long state, const char *msg)
+{
+	unsigned long err;
+
+	if (!hv_supports_soft_state)
+		return;
+
+	err = sun4v_mach_set_soft_state(state, kimage_addr_to_ra(msg));
+	if (err) {
+		printk(KERN_WARNING "SSTATE: Failed to set soft-state to "
+		       "state[%lx] msg[%s], err=%lu\n",
+		       state, msg, err);
+	}
+}
+
+static const char booting_msg[32] __attribute__((aligned(32))) =
+	"Linux booting";
+static const char running_msg[32] __attribute__((aligned(32))) =
+	"Linux running";
+static const char halting_msg[32] __attribute__((aligned(32))) =
+	"Linux halting";
+static const char poweroff_msg[32] __attribute__((aligned(32))) =
+	"Linux powering off";
+static const char rebooting_msg[32] __attribute__((aligned(32))) =
+	"Linux rebooting";
+static const char panicing_msg[32] __attribute__((aligned(32))) =
+	"Linux panicing";
+
+void sstate_booting(void)
+{
+	do_set_sstate(HV_SOFT_STATE_TRANSITION, booting_msg);
+}
+
+void sstate_running(void)
+{
+	do_set_sstate(HV_SOFT_STATE_NORMAL, running_msg);
+}
+
+void sstate_halt(void)
+{
+	do_set_sstate(HV_SOFT_STATE_TRANSITION, halting_msg);
+}
+
+void sstate_poweroff(void)
+{
+	do_set_sstate(HV_SOFT_STATE_TRANSITION, poweroff_msg);
+}
+
+void sstate_reboot(void)
+{
+	do_set_sstate(HV_SOFT_STATE_TRANSITION, rebooting_msg);
+}
+
+static int sstate_panic_event(struct notifier_block *n, unsigned long event, void *ptr)
+{
+	do_set_sstate(HV_SOFT_STATE_TRANSITION, panicing_msg);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sstate_panic_block = {
+	.notifier_call	=	sstate_panic_event,
+	.priority	=	INT_MAX,
+};
+
+void __init sun4v_sstate_init(void)
+{
+	unsigned long major, minor;
+
+	major = 1;
+	minor = 0;
+	if (sun4v_hvapi_register(HV_GRP_SOFT_STATE, major, &minor))
+		return;
+
+	hv_supports_soft_state = 1;
+
+	prom_sun4v_guest_soft_state();
+	atomic_notifier_chain_register(&panic_notifier_list,
+				       &sstate_panic_block);
+}
diff --git a/arch/sparc64/kernel/sun4v_ivec.S b/arch/sparc64/kernel/sun4v_ivec.S
index 405855d..574bc24 100644
--- a/arch/sparc64/kernel/sun4v_ivec.S
+++ b/arch/sparc64/kernel/sun4v_ivec.S
@@ -22,12 +22,12 @@
 	be,pn	%xcc, sun4v_cpu_mondo_queue_empty
 	 nop
 
-	/* Get &trap_block[smp_processor_id()] into %g3.  */
-	ldxa	[%g0] ASI_SCRATCHPAD, %g3
-	sub	%g3, TRAP_PER_CPU_FAULT_INFO, %g3
+	/* Get &trap_block[smp_processor_id()] into %g4.  */
+	ldxa	[%g0] ASI_SCRATCHPAD, %g4
+	sub	%g4, TRAP_PER_CPU_FAULT_INFO, %g4
 
 	/* Get CPU mondo queue base phys address into %g7.  */
-	ldx	[%g3 + TRAP_PER_CPU_CPU_MONDO_PA], %g7
+	ldx	[%g4 + TRAP_PER_CPU_CPU_MONDO_PA], %g7
 
 	/* Now get the cross-call arguments and handler PC, same
 	 * layout as sun4u:
@@ -47,8 +47,7 @@
 	add	%g2, 0x40 - 0x8 - 0x8, %g2
 
 	/* Update queue head pointer.  */
-	sethi	%hi(8192 - 1), %g4
-	or	%g4, %lo(8192 - 1), %g4
+	lduw	[%g4 + TRAP_PER_CPU_CPU_MONDO_QMASK], %g4
 	and	%g2, %g4, %g2
 
 	mov	INTRQ_CPU_MONDO_HEAD, %g4
@@ -71,12 +70,12 @@
 	be,pn	%xcc, sun4v_dev_mondo_queue_empty
 	 nop
 
-	/* Get &trap_block[smp_processor_id()] into %g3.  */
-	ldxa	[%g0] ASI_SCRATCHPAD, %g3
-	sub	%g3, TRAP_PER_CPU_FAULT_INFO, %g3
+	/* Get &trap_block[smp_processor_id()] into %g4.  */
+	ldxa	[%g0] ASI_SCRATCHPAD, %g4
+	sub	%g4, TRAP_PER_CPU_FAULT_INFO, %g4
 
 	/* Get DEV mondo queue base phys address into %g5.  */
-	ldx	[%g3 + TRAP_PER_CPU_DEV_MONDO_PA], %g5
+	ldx	[%g4 + TRAP_PER_CPU_DEV_MONDO_PA], %g5
 
 	/* Load IVEC into %g3.  */
 	ldxa	[%g5 + %g2] ASI_PHYS_USE_EC, %g3
@@ -90,8 +89,7 @@
 	 */
 
 	/* Update queue head pointer, this frees up some registers.  */
-	sethi	%hi(8192 - 1), %g4
-	or	%g4, %lo(8192 - 1), %g4
+	lduw	[%g4 + TRAP_PER_CPU_DEV_MONDO_QMASK], %g4
 	and	%g2, %g4, %g2
 
 	mov	INTRQ_DEVICE_MONDO_HEAD, %g4
@@ -143,6 +141,8 @@
 	brnz,pn	%g1, sun4v_res_mondo_queue_full
 	 nop
 
+	lduw	[%g3 + TRAP_PER_CPU_RESUM_QMASK], %g4
+
 	/* Remember this entry's offset in %g1.  */
 	mov	%g2, %g1
 
@@ -173,8 +173,6 @@
 	add	%g2, 0x08, %g2
 
 	/* Update queue head pointer.  */
-	sethi	%hi(8192 - 1), %g4
-	or	%g4, %lo(8192 - 1), %g4
 	and	%g2, %g4, %g2
 
 	mov	INTRQ_RESUM_MONDO_HEAD, %g4
@@ -254,6 +252,8 @@
 	brnz,pn	%g1, sun4v_nonres_mondo_queue_full
 	 nop
 
+	lduw	[%g3 + TRAP_PER_CPU_NONRESUM_QMASK], %g4
+
 	/* Remember this entry's offset in %g1.  */
 	mov	%g2, %g1
 
@@ -284,8 +284,6 @@
 	add	%g2, 0x08, %g2
 
 	/* Update queue head pointer.  */
-	sethi	%hi(8192 - 1), %g4
-	or	%g4, %lo(8192 - 1), %g4
 	and	%g2, %g4, %g2
 
 	mov	INTRQ_NONRESUM_MONDO_HEAD, %g4
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 2d63d76..a31a043 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -680,22 +680,14 @@
 
 static u32 hypervisor_get_time(void)
 {
-	register unsigned long func asm("%o5");
-	register unsigned long arg0 asm("%o0");
-	register unsigned long arg1 asm("%o1");
+	unsigned long ret, time;
 	int retries = 10000;
 
 retry:
-	func = HV_FAST_TOD_GET;
-	arg0 = 0;
-	arg1 = 0;
-	__asm__ __volatile__("ta	%6"
-			     : "=&r" (func), "=&r" (arg0), "=&r" (arg1)
-			     : "0" (func), "1" (arg0), "2" (arg1),
-			       "i" (HV_FAST_TRAP));
-	if (arg0 == HV_EOK)
-		return arg1;
-	if (arg0 == HV_EWOULDBLOCK) {
+	ret = sun4v_tod_get(&time);
+	if (ret == HV_EOK)
+		return time;
+	if (ret == HV_EWOULDBLOCK) {
 		if (--retries > 0) {
 			udelay(100);
 			goto retry;
@@ -709,20 +701,14 @@
 
 static int hypervisor_set_time(u32 secs)
 {
-	register unsigned long func asm("%o5");
-	register unsigned long arg0 asm("%o0");
+	unsigned long ret;
 	int retries = 10000;
 
 retry:
-	func = HV_FAST_TOD_SET;
-	arg0 = secs;
-	__asm__ __volatile__("ta	%4"
-			     : "=&r" (func), "=&r" (arg0)
-			     : "0" (func), "1" (arg0),
-			       "i" (HV_FAST_TRAP));
-	if (arg0 == HV_EOK)
+	ret = sun4v_tod_set(secs);
+	if (ret == HV_EOK)
 		return 0;
-	if (arg0 == HV_EWOULDBLOCK) {
+	if (ret == HV_EWOULDBLOCK) {
 		if (--retries > 0) {
 			udelay(100);
 			goto retry;
@@ -862,7 +848,6 @@
 static unsigned long sparc64_init_timers(void)
 {
 	struct device_node *dp;
-	struct property *prop;
 	unsigned long clock;
 #ifdef CONFIG_SMP
 	extern void smp_tick_init(void);
@@ -879,17 +864,15 @@
 		if (manuf == 0x17 && impl == 0x13) {
 			/* Hummingbird, aka Ultra-IIe */
 			tick_ops = &hbtick_operations;
-			prop = of_find_property(dp, "stick-frequency", NULL);
+			clock = of_getintprop_default(dp, "stick-frequency", 0);
 		} else {
 			tick_ops = &tick_operations;
-			cpu_find_by_instance(0, &dp, NULL);
-			prop = of_find_property(dp, "clock-frequency", NULL);
+			clock = local_cpu_data().clock_tick;
 		}
 	} else {
 		tick_ops = &stick_operations;
-		prop = of_find_property(dp, "stick-frequency", NULL);
+		clock = of_getintprop_default(dp, "stick-frequency", 0);
 	}
-	clock = *(unsigned int *) prop->value;
 
 #ifdef CONFIG_SMP
 	smp_tick_init();
@@ -1365,6 +1348,7 @@
 	return hypervisor_set_time(seconds);
 }
 
+#ifdef CONFIG_PCI
 static void bq4802_get_rtc_time(struct rtc_time *time)
 {
 	unsigned char val = readb(bq4802_regs + 0x0e);
@@ -1436,6 +1420,7 @@
 
 	return 0;
 }
+#endif /* CONFIG_PCI */
 
 struct mini_rtc_ops {
 	void (*get_rtc_time)(struct rtc_time *);
@@ -1452,10 +1437,12 @@
 	.set_rtc_time = hypervisor_set_rtc_time,
 };
 
+#ifdef CONFIG_PCI
 static struct mini_rtc_ops bq4802_rtc_ops = {
 	.get_rtc_time = bq4802_get_rtc_time,
 	.set_rtc_time = bq4802_set_rtc_time,
 };
+#endif /* CONFIG_PCI */
 
 static struct mini_rtc_ops *mini_rtc_ops;
 
@@ -1579,8 +1566,10 @@
 		mini_rtc_ops = &hypervisor_rtc_ops;
 	else if (this_is_starfire)
 		mini_rtc_ops = &starfire_rtc_ops;
+#ifdef CONFIG_PCI
 	else if (bq4802_regs)
 		mini_rtc_ops = &bq4802_rtc_ops;
+#endif /* CONFIG_PCI */
 	else
 		return -ENODEV;
 
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index d0fde36..00a9e32 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -795,8 +795,7 @@
 void __init cheetah_ecache_flush_init(void)
 {
 	unsigned long largest_size, smallest_linesize, order, ver;
-	struct device_node *dp;
-	int i, instance, sz;
+	int i, sz;
 
 	/* Scan all cpu device tree nodes, note two values:
 	 * 1) largest E-cache size
@@ -805,18 +804,20 @@
 	largest_size = 0UL;
 	smallest_linesize = ~0UL;
 
-	instance = 0;
-	while (!cpu_find_by_instance(instance, &dp, NULL)) {
+	for (i = 0; i < NR_CPUS; i++) {
 		unsigned long val;
 
-		val = of_getintprop_default(dp, "ecache-size",
-					    (2 * 1024 * 1024));
+		val = cpu_data(i).ecache_size;
+		if (!val)
+			continue;
+
 		if (val > largest_size)
 			largest_size = val;
-		val = of_getintprop_default(dp, "ecache-line-size", 64);
+
+		val = cpu_data(i).ecache_line_size;
 		if (val < smallest_linesize)
 			smallest_linesize = val;
-		instance++;
+
 	}
 
 	if (largest_size == 0UL || smallest_linesize == ~0UL) {
@@ -2564,7 +2565,15 @@
 	    (TRAP_PER_CPU_TSB_HUGE_TEMP !=
 	     offsetof(struct trap_per_cpu, tsb_huge_temp)) ||
 	    (TRAP_PER_CPU_IRQ_WORKLIST !=
-	     offsetof(struct trap_per_cpu, irq_worklist)))
+	     offsetof(struct trap_per_cpu, irq_worklist)) ||
+	    (TRAP_PER_CPU_CPU_MONDO_QMASK !=
+	     offsetof(struct trap_per_cpu, cpu_mondo_qmask)) ||
+	    (TRAP_PER_CPU_DEV_MONDO_QMASK !=
+	     offsetof(struct trap_per_cpu, dev_mondo_qmask)) ||
+	    (TRAP_PER_CPU_RESUM_QMASK !=
+	     offsetof(struct trap_per_cpu, resum_qmask)) ||
+	    (TRAP_PER_CPU_NONRESUM_QMASK !=
+	     offsetof(struct trap_per_cpu, nonresum_qmask)))
 		trap_per_cpu_offsets_are_bolixed_dave();
 
 	if ((TSB_CONFIG_TSB !=
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 6e5b01d..3010227 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -23,6 +23,7 @@
 #include <linux/kprobes.h>
 #include <linux/cache.h>
 #include <linux/sort.h>
+#include <linux/percpu.h>
 
 #include <asm/head.h>
 #include <asm/system.h>
@@ -43,8 +44,8 @@
 #include <asm/tsb.h>
 #include <asm/hypervisor.h>
 #include <asm/prom.h>
-
-extern void device_scan(void);
+#include <asm/sstate.h>
+#include <asm/mdesc.h>
 
 #define MAX_PHYS_ADDRESS	(1UL << 42UL)
 #define KPTE_BITMAP_CHUNK_SZ	(256UL * 1024UL * 1024UL)
@@ -60,8 +61,11 @@
 unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)];
 
 #ifndef CONFIG_DEBUG_PAGEALLOC
-/* A special kernel TSB for 4MB and 256MB linear mappings.  */
-struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
+/* A special kernel TSB for 4MB and 256MB linear mappings.
+ * Space is allocated for this right after the trap table
+ * in arch/sparc64/kernel/head.S
+ */
+extern struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
 #endif
 
 #define MAX_BANKS	32
@@ -190,12 +194,9 @@
 }
 
 #define PG_dcache_dirty		PG_arch_1
-#define PG_dcache_cpu_shift	24UL
-#define PG_dcache_cpu_mask	(256UL - 1UL)
-
-#if NR_CPUS > 256
-#error D-cache dirty tracking and thread_info->cpu need fixing for > 256 cpus
-#endif
+#define PG_dcache_cpu_shift	32UL
+#define PG_dcache_cpu_mask	\
+	((1UL<<ilog2(roundup_pow_of_two(NR_CPUS)))-1UL)
 
 #define dcache_dirty_cpu(page) \
 	(((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask)
@@ -557,26 +558,11 @@
 				       unsigned long pte,
 				       unsigned long mmu)
 {
-	register unsigned long func asm("%o5");
-	register unsigned long arg0 asm("%o0");
-	register unsigned long arg1 asm("%o1");
-	register unsigned long arg2 asm("%o2");
-	register unsigned long arg3 asm("%o3");
+	unsigned long ret = sun4v_mmu_map_perm_addr(vaddr, 0, pte, mmu);
 
-	func = HV_FAST_MMU_MAP_PERM_ADDR;
-	arg0 = vaddr;
-	arg1 = 0;
-	arg2 = pte;
-	arg3 = mmu;
-	__asm__ __volatile__("ta	0x80"
-			     : "=&r" (func), "=&r" (arg0),
-			       "=&r" (arg1), "=&r" (arg2),
-			       "=&r" (arg3)
-			     : "0" (func), "1" (arg0), "2" (arg1),
-			       "3" (arg2), "4" (arg3));
-	if (arg0 != 0) {
+	if (ret != 0) {
 		prom_printf("hypervisor_tlb_lock[%lx:%lx:%lx:%lx]: "
-			    "errors with %lx\n", vaddr, 0, pte, mmu, arg0);
+			    "errors with %lx\n", vaddr, 0, pte, mmu, ret);
 		prom_halt();
 	}
 }
@@ -1313,20 +1299,16 @@
 
 void __cpuinit sun4v_ktsb_register(void)
 {
-	register unsigned long func asm("%o5");
-	register unsigned long arg0 asm("%o0");
-	register unsigned long arg1 asm("%o1");
-	unsigned long pa;
+	unsigned long pa, ret;
 
 	pa = kern_base + ((unsigned long)&ktsb_descr[0] - KERNBASE);
 
-	func = HV_FAST_MMU_TSB_CTX0;
-	arg0 = NUM_KTSB_DESCR;
-	arg1 = pa;
-	__asm__ __volatile__("ta	%6"
-			     : "=&r" (func), "=&r" (arg0), "=&r" (arg1)
-			     : "0" (func), "1" (arg0), "2" (arg1),
-			       "i" (HV_FAST_TRAP));
+	ret = sun4v_mmu_tsb_ctx0(NUM_KTSB_DESCR, pa);
+	if (ret != 0) {
+		prom_printf("hypervisor_mmu_tsb_ctx0[%lx]: "
+			    "errors with %lx\n", pa, ret);
+		prom_halt();
+	}
 }
 
 /* paging_init() sets up the page tables */
@@ -1334,6 +1316,9 @@
 extern void cheetah_ecache_flush_init(void);
 extern void sun4v_patch_tlb_handlers(void);
 
+extern void cpu_probe(void);
+extern void central_probe(void);
+
 static unsigned long last_valid_pfn;
 pgd_t swapper_pg_dir[2048];
 
@@ -1345,9 +1330,24 @@
 	unsigned long end_pfn, pages_avail, shift, phys_base;
 	unsigned long real_end, i;
 
+	/* These build time checkes make sure that the dcache_dirty_cpu()
+	 * page->flags usage will work.
+	 *
+	 * When a page gets marked as dcache-dirty, we store the
+	 * cpu number starting at bit 32 in the page->flags.  Also,
+	 * functions like clear_dcache_dirty_cpu use the cpu mask
+	 * in 13-bit signed-immediate instruction fields.
+	 */
+	BUILD_BUG_ON(FLAGS_RESERVED != 32);
+	BUILD_BUG_ON(SECTIONS_WIDTH + NODES_WIDTH + ZONES_WIDTH +
+		     ilog2(roundup_pow_of_two(NR_CPUS)) > FLAGS_RESERVED);
+	BUILD_BUG_ON(NR_CPUS > 4096);
+
 	kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
 	kern_size = (unsigned long)&_end - (unsigned long)KERNBASE;
 
+	sstate_booting();
+
 	/* Invalidate both kernel TSBs.  */
 	memset(swapper_tsb, 0x40, sizeof(swapper_tsb));
 #ifndef CONFIG_DEBUG_PAGEALLOC
@@ -1416,8 +1416,13 @@
 
 	kernel_physical_mapping_init();
 
+	real_setup_per_cpu_areas();
+
 	prom_build_devicetree();
 
+	if (tlb_type == hypervisor)
+		sun4v_mdesc_init();
+
 	{
 		unsigned long zones_size[MAX_NR_ZONES];
 		unsigned long zholes_size[MAX_NR_ZONES];
@@ -1434,7 +1439,10 @@
 				    zholes_size);
 	}
 
-	device_scan();
+	prom_printf("Booting Linux...\n");
+
+	central_probe();
+	cpu_probe();
 }
 
 static void __init taint_real_pages(void)
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
index 0b42137..f3e0c14 100644
--- a/arch/sparc64/prom/misc.c
+++ b/arch/sparc64/prom/misc.c
@@ -15,6 +15,25 @@
 #include <asm/oplib.h>
 #include <asm/system.h>
 
+int prom_service_exists(const char *service_name)
+{
+	int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) |
+			    P1275_INOUT(1, 1), service_name);
+
+	if (err)
+		return 0;
+	return 1;
+}
+
+void prom_sun4v_guest_soft_state(void)
+{
+	const char *svc = "SUNW,soft-state-supported";
+
+	if (!prom_service_exists(svc))
+		return;
+	p1275_cmd(svc, P1275_INOUT(0, 0));
+}
+
 /* Reset and reboot the machine with the command 'bcommand'. */
 void prom_reboot(const char *bcommand)
 {
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 3ff4e1f..ac6dce2 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -298,7 +298,7 @@
 	mutex_init(&state->mutex);
 	crypto_init_queue(&state->queue, CRYPTD_MAX_QLEN);
 
-	state->task = kthread_create(fn, state, name);
+	state->task = kthread_run(fn, state, name);
 	if (IS_ERR(state->task))
 		return PTR_ERR(state->task);
 
@@ -316,6 +316,8 @@
 	struct cryptd_state *state = data;
 	int stop;
 
+	current->flags |= PF_NOFREEZE;
+
 	do {
 		struct crypto_async_request *req, *backlog;
 
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3ca9c61..af62514 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3783,6 +3783,7 @@
 	{ "FUJITSU MHT2060BH",	NULL,		ATA_HORKAGE_NONCQ },
 	/* NCQ is broken */
 	{ "Maxtor 6L250S0",     "BANC1G10",     ATA_HORKAGE_NONCQ },
+	{ "Maxtor 6B200M0",	"BANC1B10",	ATA_HORKAGE_NONCQ },
 	/* NCQ hard hangs device under heavier load, needs hard power cycle */
 	{ "Maxtor 6B250S0",	"BANC1B70",	ATA_HORKAGE_NONCQ },
 	/* Blacklist entries taken from Silicon Image 3124/3132
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index ef833a1..0b7ffa5 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -6,7 +6,7 @@
 #
 config DRM
 	tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
-	depends on (AGP || AGP=n) && PCI
+	depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG
 	help
 	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
 	  introduced in XFree86 4.0. If you say Y here, you need to select
diff --git a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c
index de37d5f..b33313b 100644
--- a/drivers/char/drm/drm_drawable.c
+++ b/drivers/char/drm/drm_drawable.c
@@ -172,38 +172,49 @@
 
 		bitfield_length = idx + 1;
 
-		if (idx != id / (8 * sizeof(*bitfield)))
-			bitfield = drm_alloc(bitfield_length *
-					     sizeof(*bitfield), DRM_MEM_BUFS);
+		bitfield = NULL;
 
-		if (!bitfield && bitfield_length) {
-			bitfield = dev->drw_bitfield;
-			bitfield_length = dev->drw_bitfield_length;
+		if (bitfield_length) {
+			if (bitfield_length != dev->drw_bitfield_length)
+				bitfield = drm_alloc(bitfield_length *
+						     sizeof(*bitfield),
+						     DRM_MEM_BUFS);
+
+			if (!bitfield) {
+				bitfield = dev->drw_bitfield;
+				bitfield_length = dev->drw_bitfield_length;
+			}
 		}
 	}
 
 	if (bitfield != dev->drw_bitfield) {
 		info_length = 8 * sizeof(*bitfield) * bitfield_length;
 
-		info = drm_alloc(info_length * sizeof(*info), DRM_MEM_BUFS);
+		if (info_length) {
+			info = drm_alloc(info_length * sizeof(*info),
+					 DRM_MEM_BUFS);
 
-		if (!info && info_length) {
-			info = dev->drw_info;
-			info_length = dev->drw_info_length;
-		}
+			if (!info) {
+				info = dev->drw_info;
+				info_length = dev->drw_info_length;
+			}
+		} else
+			info = NULL;
 
 		spin_lock_irqsave(&dev->drw_lock, irqflags);
 
-		memcpy(bitfield, dev->drw_bitfield, bitfield_length *
-		       sizeof(*bitfield));
+		if (bitfield)
+			memcpy(bitfield, dev->drw_bitfield, bitfield_length *
+			       sizeof(*bitfield));
 		drm_free(dev->drw_bitfield, sizeof(*bitfield) *
 			 dev->drw_bitfield_length, DRM_MEM_BUFS);
 		dev->drw_bitfield = bitfield;
 		dev->drw_bitfield_length = bitfield_length;
 
 		if (info != dev->drw_info) {
-			memcpy(info, dev->drw_info, info_length *
-			       sizeof(*info));
+			if (info)
+				memcpy(info, dev->drw_info, info_length *
+				       sizeof(*info));
 			drm_free(dev->drw_info, sizeof(*info) *
 				 dev->drw_info_length, DRM_MEM_BUFS);
 			dev->drw_info = info;
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 31cdde8..177ccc0 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -102,13 +102,20 @@
 	{0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
 	{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
+	{0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
 	{0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+	{0x1002, 0x5974, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+	{0x1002, 0x5975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
 	{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
 	{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
 	{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
 	{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
 	{0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
 	{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
+	{0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+	{0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+	{0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+	{0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
 	{0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index 78c1ae2..b92062a 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -582,7 +582,7 @@
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
-	dev_priv->swaps_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dev_priv->swaps_lock);
 	INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
 	dev_priv->swaps_pending = 0;
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 46c1b9774..0474cac 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -760,7 +760,7 @@
 
 static void extract_buf(struct entropy_store *r, __u8 *out)
 {
-	int i, x;
+	int i;
 	__u32 data[16], buf[5 + SHA_WORKSPACE_WORDS];
 
 	sha_init(buf);
@@ -772,9 +772,11 @@
 	 * attempts to find previous ouputs), unless the hash
 	 * function can be inverted.
 	 */
-	for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) {
-		sha_transform(buf, (__u8 *)r->pool+i, buf + 5);
-		add_entropy_words(r, &buf[x % 5], 1);
+	for (i = 0; i < r->poolinfo->poolwords; i += 16) {
+		/* hash blocks of 16 words = 512 bits */
+		sha_transform(buf, (__u8 *)(r->pool + i), buf + 5);
+		/* feed back portion of the resulting hash */
+		add_entropy_words(r, &buf[i % 5], 1);
 	}
 
 	/*
@@ -782,7 +784,7 @@
 	 * portion of the pool while mixing, and hash one
 	 * final time.
 	 */
-	__add_entropy_words(r, &buf[x % 5], 1, data);
+	__add_entropy_words(r, &buf[i % 5], 1, data);
 	sha_transform(buf, (__u8 *)data, buf + 5);
 
 	/*
@@ -1018,37 +1020,44 @@
 	return mask;
 }
 
+static int
+write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
+{
+	size_t bytes;
+	__u32 buf[16];
+	const char __user *p = buffer;
+
+	while (count > 0) {
+		bytes = min(count, sizeof(buf));
+		if (copy_from_user(&buf, p, bytes))
+			return -EFAULT;
+
+		count -= bytes;
+		p += bytes;
+
+		add_entropy_words(r, buf, (bytes + 3) / 4);
+	}
+
+	return 0;
+}
+
 static ssize_t
 random_write(struct file * file, const char __user * buffer,
 	     size_t count, loff_t *ppos)
 {
-	int ret = 0;
-	size_t bytes;
-	__u32 buf[16];
-	const char __user *p = buffer;
-	size_t c = count;
+	size_t ret;
+	struct inode *inode = file->f_path.dentry->d_inode;
 
-	while (c > 0) {
-		bytes = min(c, sizeof(buf));
+	ret = write_pool(&blocking_pool, buffer, count);
+	if (ret)
+		return ret;
+	ret = write_pool(&nonblocking_pool, buffer, count);
+	if (ret)
+		return ret;
 
-		bytes -= copy_from_user(&buf, p, bytes);
-		if (!bytes) {
-			ret = -EFAULT;
-			break;
-		}
-		c -= bytes;
-		p += bytes;
-
-		add_entropy_words(&input_pool, buf, (bytes + 3) / 4);
-	}
-	if (p == buffer) {
-		return (ssize_t)ret;
-	} else {
-		struct inode *inode = file->f_path.dentry->d_inode;
-	        inode->i_mtime = current_fs_time(inode->i_sb);
-		mark_inode_dirty(inode);
-		return (ssize_t)(p - buffer);
-	}
+	inode->i_mtime = current_fs_time(inode->i_sb);
+	mark_inode_dirty(inode);
+	return (ssize_t)count;
 }
 
 static int
@@ -1087,8 +1096,8 @@
 			return -EINVAL;
 		if (get_user(size, p++))
 			return -EFAULT;
-		retval = random_write(file, (const char __user *) p,
-				      size, &file->f_pos);
+		retval = write_pool(&input_pool, (const char __user *)p,
+				    size);
 		if (retval < 0)
 			return retval;
 		credit_entropy_store(&input_pool, ent_count);
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index 5932c72..396dade 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -18,7 +18,7 @@
 	  your IEEE 1394 adapter.
 
 	  To compile this driver as a module, say M here: the module will be
-	  called fw-core.
+	  called firewire-core.
 
 	  This is the "JUJU" FireWire stack, an alternative implementation
 	  designed for robustness and simplicity.  You can build either this
@@ -34,11 +34,11 @@
 	  is the only chipset in use, so say Y here.
 
 	  To compile this driver as a module, say M here:  The module will be
-	  called fw-ohci.
+	  called firewire-ohci.
 
 	  If you also build ohci1394 of the classic IEEE 1394 driver stack,
-	  blacklist either ohci1394 or fw-ohci to let hotplug load the desired
-	  driver.
+	  blacklist either ohci1394 or firewire-ohci to let hotplug load the
+	  desired driver.
 
 config FIREWIRE_SBP2
 	tristate "Support for storage devices (SBP-2 protocol driver)"
@@ -50,12 +50,12 @@
 	  like scanners.
 
 	  To compile this driver as a module, say M here:  The module will be
-	  called fw-sbp2.
+	  called firewire-sbp2.
 
 	  You should also enable support for disks, CD-ROMs, etc. in the SCSI
 	  configuration section.
 
 	  If you also build sbp2 of the classic IEEE 1394 driver stack,
-	  blacklist either sbp2 or fw-sbp2 to let hotplug load the desired
-	  driver.
+	  blacklist either sbp2 or firewire-sbp2 to let hotplug load the
+	  desired driver.
 
diff --git a/drivers/firewire/Makefile b/drivers/firewire/Makefile
index fc7d59d..a7c31e9 100644
--- a/drivers/firewire/Makefile
+++ b/drivers/firewire/Makefile
@@ -2,9 +2,11 @@
 # Makefile for the Linux IEEE 1394 implementation
 #
 
-fw-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \
-	fw-device.o fw-cdev.o
+firewire-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \
+                   fw-device.o fw-cdev.o
+firewire-ohci-y += fw-ohci.o
+firewire-sbp2-y += fw-sbp2.o
 
-obj-$(CONFIG_FIREWIRE) += fw-core.o
-obj-$(CONFIG_FIREWIRE_OHCI) += fw-ohci.o
-obj-$(CONFIG_FIREWIRE_SBP2) += fw-sbp2.o
+obj-$(CONFIG_FIREWIRE) += firewire-core.o
+obj-$(CONFIG_FIREWIRE_OHCI) += firewire-ohci.o
+obj-$(CONFIG_FIREWIRE_SBP2) += firewire-sbp2.o
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 0fa5bd5..3ab3585 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -365,7 +365,7 @@
 		    response->response.data, response->response.length);
 }
 
-static ssize_t ioctl_send_request(struct client *client, void *buffer)
+static int ioctl_send_request(struct client *client, void *buffer)
 {
 	struct fw_device *device = client->device;
 	struct fw_cdev_send_request *request = buffer;
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index c17342d..2e4cfa5 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -268,7 +268,7 @@
 
 	dma_sync_single_for_device(dev, ab_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
 
-	ctx->last_buffer->descriptor.branch_address = ab_bus | 1;
+	ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1);
 	ctx->last_buffer->next = ab;
 	ctx->last_buffer = ab;
 
@@ -417,7 +417,8 @@
 	ctx->current_buffer = ab.next;
 	ctx->pointer = ctx->current_buffer->data;
 
-	reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab.descriptor.branch_address);
+	reg_write(ctx->ohci, COMMAND_PTR(ctx->regs),
+		  le32_to_cpu(ab.descriptor.branch_address));
 	reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN);
 	flush_writes(ctx->ohci);
 
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 4d1cb5b..13eea47 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -620,7 +620,7 @@
 
 config SENSORS_APPLESMC
 	tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
-	depends on HWMON && INPUT && X86
+	depends on INPUT && X86
 	select NEW_LEDS
 	select LEDS_CLASS
 	default n
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 366f4a1..fd1281f 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -1206,11 +1206,13 @@
 	}
 
 	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
+	if (ret)
+		goto out_device;
 
 	/* Create key enumeration sysfs files */
 	ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
 	if (ret)
-		goto out_device;
+		goto out_name;
 
 	/* create fan files */
 	count = applesmc_get_fan_count();
@@ -1310,6 +1312,8 @@
 	sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
 out_key_enumeration:
 	sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+out_name:
+	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
 out_device:
 	platform_device_unregister(pdev);
 out_driver:
@@ -1335,6 +1339,7 @@
 	sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
 	sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
 	sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
 	platform_device_unregister(pdev);
 	platform_driver_unregister(&applesmc_driver);
 	release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 75e3911..0328382 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -176,6 +176,22 @@
 		goto exit_free;
 	}
 
+	/* Check if we have problem with errata AE18 of Core processors:
+	   Readings might stop update when processor visited too deep sleep,
+	   fixed for stepping D0 (6EC).
+	*/
+
+	if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) {
+		/* check for microcode update */
+		rdmsr_on_cpu(data->id, MSR_IA32_UCODE_REV, &eax, &edx);
+		if (edx < 0x39) {
+			dev_err(&pdev->dev,
+				"Errata AE18 not fixed, update BIOS or "
+				"microcode of the CPU!\n");
+			goto exit_free;
+		}
+	}
+
 	/* Some processors have Tjmax 85 following magic should detect it
 	   Intel won't disclose the information without signed NDA, but
 	   individuals cannot sign it. Catch(ed) 22.
@@ -193,6 +209,19 @@
 		}
 	}
 
+	/* Intel says that above should not work for desktop Core2 processors,
+	   but it seems to work. There is no other way how get the absolute
+	   readings. Warn the user about this. First check if are desktop,
+	   bit 50 of MSR_IA32_PLATFORM_ID should be 0.
+	*/
+
+	rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
+
+	if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
+		dev_warn(&pdev->dev, "Using undocumented features, absolute "
+			 "temperature might be wrong!\n");
+	}
+
 	platform_set_drvdata(pdev, data);
 
 	if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
@@ -330,9 +359,6 @@
 	int i, err = -ENODEV;
 	struct pdev_entry *p, *n;
 
-	printk(KERN_NOTICE DRVNAME ": This driver uses undocumented features "
-		"of Core CPU. Temperature might be wrong!\n");
-
 	/* quick check if we run Intel */
 	if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
 		goto exit;
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index c849c0c..d5ac422 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -53,8 +53,8 @@
 
 /* The DS1621 registers */
 #define DS1621_REG_TEMP			0xAA /* word, RO */
-#define DS1621_REG_TEMP_MIN		0xA1 /* word, RW */
-#define DS1621_REG_TEMP_MAX		0xA2 /* word, RW */
+#define DS1621_REG_TEMP_MIN		0xA2 /* word, RW */
+#define DS1621_REG_TEMP_MAX		0xA1 /* word, RW */
 #define DS1621_REG_CONF			0xAC /* byte, RW */
 #define DS1621_COM_START		0xEE /* no data */
 #define DS1621_COM_STOP			0x22 /* no data */
@@ -328,9 +328,9 @@
 
 		/* reset alarms if necessary */
 		new_conf = data->conf;
-		if (data->temp < data->temp_min)
+		if (data->temp > data->temp_min)
 			new_conf &= ~DS1621_ALARM_TEMP_LOW;
-		if (data->temp > data->temp_max)
+		if (data->temp < data->temp_max)
 			new_conf &= ~DS1621_ALARM_TEMP_HIGH;
 		if (data->conf != new_conf)
 			ds1621_write_value(client, DS1621_REG_CONF,
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index 5aab23b..f17e771 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -132,7 +132,9 @@
 		val &= 0x7f;
 		return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000);
 	default:		/* report 0 for unknown */
-		printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n");
+		if (vrm)
+			printk(KERN_WARNING "hwmon-vid: Requested unsupported "
+			       "VRM version (%u)\n", (unsigned int)vrm);
 		return 0;
 	}
 }
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index a5b774b..12cb40a 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -965,8 +965,10 @@
 	case W687THF_DEVID:
 		sio_data->type = w83687thf;
 		break;
+	case 0xff:	/* No device at all */
+		goto exit;
 	default:
-		pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%x)\n", val);
+		pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%02x)\n", val);
 		goto exit;
 	}
 
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 8a0a99b..28e7b91 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -837,20 +837,10 @@
 	.functionality	= i2c_pxa_functionality,
 };
 
-static struct pxa_i2c i2c_pxa = {
-	.lock	= __SPIN_LOCK_UNLOCKED(i2c_pxa.lock),
-	.adap	= {
-		.owner		= THIS_MODULE,
-		.algo		= &i2c_pxa_algorithm,
-		.name		= "pxa2xx-i2c.0",
-		.retries	= 5,
-	},
-};
-
 #define res_len(r)		((r)->end - (r)->start + 1)
 static int i2c_pxa_probe(struct platform_device *dev)
 {
-	struct pxa_i2c *i2c = &i2c_pxa;
+	struct pxa_i2c *i2c;
 	struct resource *res;
 	struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
 	int ret;
@@ -864,15 +854,20 @@
 	if (!request_mem_region(res->start, res_len(res), res->name))
 		return -ENOMEM;
 
-	i2c = kmalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
+	i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
 	if (!i2c) {
 		ret = -ENOMEM;
 		goto emalloc;
 	}
 
-	memcpy(i2c, &i2c_pxa, sizeof(struct pxa_i2c));
+	i2c->adap.owner   = THIS_MODULE;
+	i2c->adap.algo    = &i2c_pxa_algorithm;
+	i2c->adap.retries = 5;
+
+	spin_lock_init(&i2c->lock);
 	init_waitqueue_head(&i2c->wait);
-	i2c->adap.name[strlen(i2c->adap.name) - 1] = '0' + dev->id % 10;
+
+	sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id);
 
 	i2c->reg_base = ioremap(res->start, res_len(res));
 	if (!i2c->reg_base) {
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 2296d43..5f026b5 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -47,6 +47,7 @@
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/workqueue.h>
 
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
@@ -235,6 +236,9 @@
 /* This is called after an "ifdown" */
 static int ether1394_stop(struct net_device *dev)
 {
+	/* flush priv->wake */
+	flush_scheduled_work();
+
 	netif_stop_queue(dev);
 	return 0;
 }
@@ -531,6 +535,37 @@
 }
 
 /*
+ * Wake the queue up after commonly encountered transmit failure conditions are
+ * hopefully over.  Currently only tlabel exhaustion is accounted for.
+ */
+static void ether1394_wake_queue(struct work_struct *work)
+{
+	struct eth1394_priv *priv;
+	struct hpsb_packet *packet;
+
+	priv = container_of(work, struct eth1394_priv, wake);
+	packet = hpsb_alloc_packet(0);
+
+	/* This is really bad, but unjam the queue anyway. */
+	if (!packet)
+		goto out;
+
+	packet->host = priv->host;
+	packet->node_id = priv->wake_node;
+	/*
+	 * A transaction label is all we really want.  If we get one, it almost
+	 * always means we can get a lot more because the ieee1394 core recycled
+	 * a whole batch of tlabels, at last.
+	 */
+	if (hpsb_get_tlabel(packet) == 0)
+		hpsb_free_tlabel(packet);
+
+	hpsb_free_packet(packet);
+out:
+	netif_wake_queue(priv->wake_dev);
+}
+
+/*
  * This function is called every time a card is found. It is generally called
  * when the module is installed. This is where we add all of our ethernet
  * devices. One for each host.
@@ -564,16 +599,17 @@
 	}
 
 	SET_MODULE_OWNER(dev);
-#if 0
-	/* FIXME - Is this the correct parent device anyway? */
-	SET_NETDEV_DEV(dev, &host->device);
-#endif
+
+	/* This used to be &host->device in Linux 2.6.20 and before. */
+	SET_NETDEV_DEV(dev, host->device.parent);
 
 	priv = netdev_priv(dev);
 	INIT_LIST_HEAD(&priv->ip_node_list);
 	spin_lock_init(&priv->lock);
 	priv->host = host;
 	priv->local_fifo = fifo_addr;
+	INIT_WORK(&priv->wake, ether1394_wake_queue);
+	priv->wake_dev = dev;
 
 	hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi));
 	if (hi == NULL) {
@@ -1390,22 +1426,17 @@
 				       u64 addr, void *data, int tx_len)
 {
 	p->node_id = node;
-	p->data = NULL;
+
+	if (hpsb_get_tlabel(p))
+		return -EAGAIN;
 
 	p->tcode = TCODE_WRITEB;
-	p->header[1] = host->node_id << 16 | addr >> 32;
-	p->header[2] = addr & 0xffffffff;
-
 	p->header_size = 16;
 	p->expect_response = 1;
-
-	if (hpsb_get_tlabel(p)) {
-		ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n");
-		return -1;
-	}
 	p->header[0] =
 		p->node_id << 16 | p->tlabel << 10 | 1 << 8 | TCODE_WRITEB << 4;
-
+	p->header[1] = host->node_id << 16 | addr >> 32;
+	p->header[2] = addr & 0xffffffff;
 	p->header[3] = tx_len << 16;
 	p->data_size = (tx_len + 3) & ~3;
 	p->data = data;
@@ -1451,7 +1482,7 @@
 
 	packet = ether1394_alloc_common_packet(priv->host);
 	if (!packet)
-		return -1;
+		return -ENOMEM;
 
 	if (ptask->tx_type == ETH1394_GASP) {
 		int length = tx_len + 2 * sizeof(quadlet_t);
@@ -1462,7 +1493,7 @@
 					       ptask->addr, ptask->skb->data,
 					       tx_len)) {
 		hpsb_free_packet(packet);
-		return -1;
+		return -EAGAIN;
 	}
 
 	ptask->packet = packet;
@@ -1471,7 +1502,7 @@
 
 	if (hpsb_send_packet(packet) < 0) {
 		ether1394_free_packet(packet);
-		return -1;
+		return -EIO;
 	}
 
 	return 0;
@@ -1514,13 +1545,18 @@
 
 	ptask->outstanding_pkts--;
 	if (ptask->outstanding_pkts > 0 && !fail) {
-		int tx_len;
+		int tx_len, err;
 
 		/* Add the encapsulation header to the fragment */
 		tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload,
 					       &ptask->hdr);
-		if (ether1394_send_packet(ptask, tx_len))
+		err = ether1394_send_packet(ptask, tx_len);
+		if (err) {
+			if (err == -EAGAIN)
+				ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n");
+
 			ether1394_dg_complete(ptask, 1);
+		}
 	} else {
 		ether1394_dg_complete(ptask, fail);
 	}
@@ -1633,10 +1669,18 @@
 	/* Add the encapsulation header to the fragment */
 	tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr);
 	dev->trans_start = jiffies;
-	if (ether1394_send_packet(ptask, tx_len))
-		goto fail;
+	if (ether1394_send_packet(ptask, tx_len)) {
+		if (dest_node == (LOCAL_BUS | ALL_NODES))
+			goto fail;
 
-	netif_wake_queue(dev);
+		/* Most failures of ether1394_send_packet are recoverable. */
+		netif_stop_queue(dev);
+		priv->wake_node = dest_node;
+		schedule_work(&priv->wake);
+		kmem_cache_free(packet_task_cache, ptask);
+		return NETDEV_TX_BUSY;
+	}
+
 	return NETDEV_TX_OK;
 fail:
 	if (ptask)
@@ -1650,9 +1694,6 @@
 	priv->stats.tx_errors++;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	if (netif_queue_stopped(dev))
-		netif_wake_queue(dev);
-
 	/*
 	 * FIXME: According to a patch from 2003-02-26, "returning non-zero
 	 * causes serious problems" here, allegedly.  Before that patch,
diff --git a/drivers/ieee1394/eth1394.h b/drivers/ieee1394/eth1394.h
index a3439ee..4f3e2dd 100644
--- a/drivers/ieee1394/eth1394.h
+++ b/drivers/ieee1394/eth1394.h
@@ -66,6 +66,10 @@
 	int bc_dgl;			/* Outgoing broadcast datagram label */
 	struct list_head ip_node_list;	/* List of IP capable nodes	 */
 	struct unit_directory *ud_list[ALL_NODES]; /* Cached unit dir list */
+
+	struct work_struct wake;	/* Wake up after xmit failure	 */
+	struct net_device *wake_dev;	/* Stupid backlink for .wake	 */
+	nodeid_t wake_node;		/* Destination of failed xmit	 */
 };
 
 
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index d382500..f1d05ee 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -936,6 +936,7 @@
 	struct hpsb_packet *packet;
 	int header_length = req->req.misc & 0xffff;
 	int expect_response = req->req.misc >> 16;
+	size_t data_size;
 
 	if (header_length > req->req.length || header_length < 12 ||
 	    header_length > FIELD_SIZEOF(struct hpsb_packet, header)) {
@@ -945,7 +946,8 @@
 		return sizeof(struct raw1394_request);
 	}
 
-	packet = hpsb_alloc_packet(req->req.length - header_length);
+	data_size = req->req.length - header_length;
+	packet = hpsb_alloc_packet(data_size);
 	req->packet = packet;
 	if (!packet)
 		return -ENOMEM;
@@ -960,7 +962,7 @@
 
 	if (copy_from_user
 	    (packet->data, int2ptr(req->req.sendb) + header_length,
-	     packet->data_size)) {
+	     data_size)) {
 		req->req.error = RAW1394_ERROR_MEMFAULT;
 		req->req.length = 0;
 		queue_complete_req(req);
@@ -974,7 +976,7 @@
 	packet->host = fi->host;
 	packet->expect_response = expect_response;
 	packet->header_size = header_length;
-	packet->data_size = req->req.length - header_length;
+	packet->data_size = data_size;
 
 	req->req.length = 0;
 	hpsb_set_packet_complete_task(packet,
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 4cb6fa2..875eadd 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -70,6 +70,7 @@
 #include <linux/stringify.h>
 #include <linux/types.h>
 #include <linux/wait.h>
+#include <linux/workqueue.h>
 
 #include <asm/byteorder.h>
 #include <asm/errno.h>
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index e840434..40c004a 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -1297,26 +1297,29 @@
 
 	req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
 
-	/* Check for duplicate REQ and stale connections. */
+	/* Check for possible duplicate REQ. */
 	spin_lock_irqsave(&cm.lock, flags);
 	timewait_info = cm_insert_remote_id(cm_id_priv->timewait_info);
-	if (!timewait_info)
-		timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
-
 	if (timewait_info) {
 		cur_cm_id_priv = cm_get_id(timewait_info->work.local_id,
 					   timewait_info->work.remote_id);
-		cm_cleanup_timewait(cm_id_priv->timewait_info);
 		spin_unlock_irqrestore(&cm.lock, flags);
 		if (cur_cm_id_priv) {
 			cm_dup_req_handler(work, cur_cm_id_priv);
 			cm_deref_id(cur_cm_id_priv);
-		} else
-			cm_issue_rej(work->port, work->mad_recv_wc,
-				     IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
-				     NULL, 0);
-		listen_cm_id_priv = NULL;
-		goto out;
+		}
+		return NULL;
+	}
+
+	/* Check for stale connections. */
+	timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
+	if (timewait_info) {
+		cm_cleanup_timewait(cm_id_priv->timewait_info);
+		spin_unlock_irqrestore(&cm.lock, flags);
+		cm_issue_rej(work->port, work->mad_recv_wc,
+			     IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
+			     NULL, 0);
+		return NULL;
 	}
 
 	/* Find matching listen request. */
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 0276649..eef415b 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -2284,10 +2284,10 @@
 	struct mthca_next_seg *next;
 
 	/*
-	 * For SRQs, all WQEs generate a CQE, so we're always at the
-	 * end of the doorbell chain.
+	 * For SRQs, all receive WQEs generate a CQE, so we're always
+	 * at the end of the doorbell chain.
 	 */
-	if (qp->ibqp.srq) {
+	if (qp->ibqp.srq && !is_send) {
 		*new_wqe = 0;
 		return;
 	}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 158759e..285c143 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -156,7 +156,7 @@
  * - and then invoke a Destroy QP or Reset QP.
  *
  * We use the second option and wait for a completion on the
- * rx_drain_qp before destroying QPs attached to our SRQ.
+ * same CQ before destroying QPs attached to our SRQ.
  */
 
 enum ipoib_cm_state {
@@ -199,7 +199,6 @@
 	struct ib_srq  	       *srq;
 	struct ipoib_cm_rx_buf *srq_ring;
 	struct ib_cm_id        *id;
-	struct ib_qp           *rx_drain_qp;   /* generates WR described in 10.3.1 */
 	struct list_head        passive_ids;   /* state: LIVE */
 	struct list_head        rx_error_list; /* state: ERROR */
 	struct list_head        rx_flush_list; /* state: FLUSH, drain not started */
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index f133b56..076a0bb 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -69,8 +69,9 @@
 
 #define IPOIB_CM_RX_DRAIN_WRID 0x7fffffff
 
-static struct ib_recv_wr ipoib_cm_rx_drain_wr = {
-	.wr_id = IPOIB_CM_RX_DRAIN_WRID
+static struct ib_send_wr ipoib_cm_rx_drain_wr = {
+	.wr_id = IPOIB_CM_RX_DRAIN_WRID,
+	.opcode = IB_WR_SEND,
 };
 
 static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id,
@@ -163,16 +164,22 @@
 
 static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv* priv)
 {
-	struct ib_recv_wr *bad_wr;
+	struct ib_send_wr *bad_wr;
+	struct ipoib_cm_rx *p;
 
-	/* rx_drain_qp send queue depth is 1, so
+	/* We only reserved 1 extra slot in CQ for drain WRs, so
 	 * make sure we have at most 1 outstanding WR. */
 	if (list_empty(&priv->cm.rx_flush_list) ||
 	    !list_empty(&priv->cm.rx_drain_list))
 		return;
 
-	if (ib_post_recv(priv->cm.rx_drain_qp, &ipoib_cm_rx_drain_wr, &bad_wr))
-		ipoib_warn(priv, "failed to post rx_drain wr\n");
+	/*
+	 * QPs on flush list are error state.  This way, a "flush
+	 * error" WC will be immediately generated for each WR we post.
+	 */
+	p = list_entry(priv->cm.rx_flush_list.next, typeof(*p), list);
+	if (ib_post_send(p->qp, &ipoib_cm_rx_drain_wr, &bad_wr))
+		ipoib_warn(priv, "failed to post drain wr\n");
 
 	list_splice_init(&priv->cm.rx_flush_list, &priv->cm.rx_drain_list);
 }
@@ -199,10 +206,10 @@
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ib_qp_init_attr attr = {
 		.event_handler = ipoib_cm_rx_event_handler,
-		.send_cq = priv->cq, /* does not matter, we never send anything */
+		.send_cq = priv->cq, /* For drain WR */
 		.recv_cq = priv->cq,
 		.srq = priv->cm.srq,
-		.cap.max_send_wr = 1, /* FIXME: 0 Seems not to work */
+		.cap.max_send_wr = 1, /* For drain WR */
 		.cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */
 		.sq_sig_type = IB_SIGNAL_ALL_WR,
 		.qp_type = IB_QPT_RC,
@@ -242,6 +249,27 @@
 		ipoib_warn(priv, "failed to modify QP to RTR: %d\n", ret);
 		return ret;
 	}
+
+	/*
+	 * Current Mellanox HCA firmware won't generate completions
+	 * with error for drain WRs unless the QP has been moved to
+	 * RTS first. This work-around leaves a window where a QP has
+	 * moved to error asynchronously, but this will eventually get
+	 * fixed in firmware, so let's not error out if modify QP
+	 * fails.
+	 */
+	qp_attr.qp_state = IB_QPS_RTS;
+	ret = ib_cm_init_qp_attr(cm_id, &qp_attr, &qp_attr_mask);
+	if (ret) {
+		ipoib_warn(priv, "failed to init QP attr for RTS: %d\n", ret);
+		return 0;
+	}
+	ret = ib_modify_qp(qp, &qp_attr, qp_attr_mask);
+	if (ret) {
+		ipoib_warn(priv, "failed to modify QP to RTS: %d\n", ret);
+		return 0;
+	}
+
 	return 0;
 }
 
@@ -623,38 +651,11 @@
 int ipoib_cm_dev_open(struct net_device *dev)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
-	struct ib_qp_init_attr qp_init_attr = {
-		.send_cq = priv->cq,   /* does not matter, we never send anything */
-		.recv_cq = priv->cq,
-		.cap.max_send_wr = 1,  /* FIXME: 0 Seems not to work */
-		.cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */
-		.cap.max_recv_wr = 1,
-		.cap.max_recv_sge = 1, /* FIXME: 0 Seems not to work */
-		.sq_sig_type = IB_SIGNAL_ALL_WR,
-		.qp_type = IB_QPT_UC,
-	};
 	int ret;
 
 	if (!IPOIB_CM_SUPPORTED(dev->dev_addr))
 		return 0;
 
-	priv->cm.rx_drain_qp = ib_create_qp(priv->pd, &qp_init_attr);
-	if (IS_ERR(priv->cm.rx_drain_qp)) {
-		printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
-		ret = PTR_ERR(priv->cm.rx_drain_qp);
-		return ret;
-	}
-
-	/*
-	 * We put the QP in error state directly.  This way, a "flush
-	 * error" WC will be immediately generated for each WR we post.
-	 */
-	ret = ib_modify_qp(priv->cm.rx_drain_qp, &ipoib_cm_err_attr, IB_QP_STATE);
-	if (ret) {
-		ipoib_warn(priv, "failed to modify drain QP to error: %d\n", ret);
-		goto err_qp;
-	}
-
 	priv->cm.id = ib_create_cm_id(priv->ca, ipoib_cm_rx_handler, dev);
 	if (IS_ERR(priv->cm.id)) {
 		printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
@@ -676,8 +677,6 @@
 	ib_destroy_cm_id(priv->cm.id);
 err_cm:
 	priv->cm.id = NULL;
-err_qp:
-	ib_destroy_qp(priv->cm.rx_drain_qp);
 	return ret;
 }
 
@@ -740,7 +739,6 @@
 		kfree(p);
 	}
 
-	ib_destroy_qp(priv->cm.rx_drain_qp);
 	cancel_delayed_work(&priv->cm.stale_task);
 }
 
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 5595087..d31ece8 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -170,7 +170,7 @@
 /*
  * Clear the input buffer.
  */
-static void __init ps2_clear_input(struct ps2if *ps2if)
+static void __devinit ps2_clear_input(struct ps2if *ps2if)
 {
 	int maxread = 100;
 
@@ -228,7 +228,7 @@
 /*
  * Add one device to this driver.
  */
-static int ps2_probe(struct sa1111_dev *dev)
+static int __devinit ps2_probe(struct sa1111_dev *dev)
 {
 	struct ps2if *ps2if;
 	struct serio *serio;
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 58926da..f44c94a 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -113,7 +113,6 @@
 
 config PMAC_APM_EMU
 	tristate "APM emulation"
-	select SYS_SUPPORTS_APM_EMULATION
 	select APM_EMULATION
 	depends on ADB_PMU && PM
 
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index d25d3be..165f81d 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -436,7 +436,7 @@
 typedef struct _mpt_ioctl_events {
 	u32	event;		/* Specified by define above */
 	u32	eventContext;	/* Index or counter */
-	int	data[2];	/* First 8 bytes of Event Data */
+	u32	data[2];	/* First 8 bytes of Event Data */
 } MPT_IOCTL_EVENTS;
 
 /*
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index fa0f776..3bd94f1 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -2463,11 +2463,11 @@
 				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
 				ioc->events[idx].eventContext = ioc->eventContext;
 
-				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
-					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
-					(sc->device->channel << 8) || sc->device->id;
+				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
+					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
+					(sc->device->channel << 8) | sc->device->id;
 
-				ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
+				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
 
 				ioc->eventContext++;
 				if (hd->ioc->pcidev->vendor ==
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 30fd479..1798a9f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2280,7 +2280,6 @@
 config UCC_GETH
 	tristate "Freescale QE Gigabit Ethernet"
 	depends on QUICC_ENGINE
-	select UCC_FAST
 	help
 	  This driver supports the Gigabit Ethernet mode of the QUICC Engine,
 	  which is available on some Freescale SOCs.
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 9fe3a38..59b9943 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -4920,7 +4920,7 @@
 	pci_cmd |= PCI_COMMAND_PARITY;
 	pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
 	if (pci_set_mwi(pdev))
-		printk(KERN_WARNING PFX "Could enable MWI for %s\n",
+		printk(KERN_WARNING PFX "Could not enable MWI for %s\n",
 		       pci_name(pdev));
 
 	/*
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index 571d82f..7df23dc 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -566,6 +566,7 @@
 		bp->base.mem = ioremap_nocache(bar_start, bar_len);
 		if (!bp->base.mem) {
 			printk(KERN_ERR "%s: Cannot map MMIO\n", print_name);
+			err = -ENOMEM;
 			goto err_out_region;
 		}
 	} else {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index cbc7feb..9ec35b7 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1325,7 +1325,10 @@
 	spin_lock_init(&adapter->tx_queue_lock);
 #endif
 
-	atomic_set(&adapter->irq_sem, 1);
+	/* Explicitly disable IRQ since the NIC can be in any state. */
+	atomic_set(&adapter->irq_sem, 0);
+	e1000_irq_disable(adapter);
+
 	spin_lock_init(&adapter->stats_lock);
 
 	set_bit(__E1000_DOWN, &adapter->flags);
@@ -1431,6 +1434,10 @@
 	/* From here on the code is the same as e1000_up() */
 	clear_bit(__E1000_DOWN, &adapter->flags);
 
+#ifdef CONFIG_E1000_NAPI
+	netif_poll_enable(netdev);
+#endif
+
 	e1000_irq_enable(adapter);
 
 	/* fire a link status change interrupt to start the watchdog */
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 602872d..e85a933 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0058"
+#define DRV_VERSION	"EHEA_0061"
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
 	| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index f6e0cb1..152bb20 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -428,7 +428,7 @@
 				}
 				skb_copy_to_linear_data(skb, ((char*)cqe) + 64,
 					       cqe->num_bytes_transfered - 4);
-				ehea_fill_skb(dev, skb, cqe);
+				ehea_fill_skb(port->netdev, skb, cqe);
 			} else if (rq == 2) {  /* RQ2 */
 				skb = get_skb_by_index(skb_arr_rq2,
 						       skb_arr_rq2_len, cqe);
diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index dfbd580..f8d63d3 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -51,8 +51,8 @@
 
 	if (obj < bitmap->max) {
 		set_bit(obj, bitmap->table);
+		bitmap->last = (obj + 1) & (bitmap->max - 1);
 		obj |= bitmap->top;
-		bitmap->last = obj + 1;
 	} else
 		obj = -1;
 
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 832fd69..adfbe81 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -364,7 +364,7 @@
 			/* for SFP-module set SIGDET polarity to low */
 			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
 			ctrl |= PHY_M_FIB_SIGD_POL;
-			gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
 		}
 
 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
@@ -658,7 +658,7 @@
 	const u8 *addr = hw->dev[port]->dev_addr;
 
 	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
-	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE);
+	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
 
 	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
 
@@ -1432,7 +1432,7 @@
 		tcpsum = offset << 16;		/* sum start */
 		tcpsum |= offset + skb->csum_offset;	/* sum write */
 
-		ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+		ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
 		if (ip_hdr(skb)->protocol == IPPROTO_UDP)
 			ctrl |= UDPTCP;
 
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 5efb5af..b8c4a3b 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1149,7 +1149,7 @@
 	PHY_M_IS_JABBER		= 1<<0, /* Jabber */
 
 	PHY_M_DEF_MSK		= PHY_M_IS_LSP_CHANGE | PHY_M_IS_LST_CHANGE
-				 | PHY_M_IS_FIFO_ERROR,
+				 | PHY_M_IS_DUP_CHANGE,
 	PHY_M_AN_MSK	       = PHY_M_IS_AN_ERROR | PHY_M_IS_AN_COMPL,
 };
 
@@ -1732,28 +1732,6 @@
 
 /*	GPHY_CTRL		32 bit	GPHY Control Reg (YUKON only) */
 enum {
-	GPC_SEL_BDT	= 1<<28, /* Select Bi-Dir. Transfer for MDC/MDIO */
-	GPC_INT_POL_HI	= 1<<27, /* IRQ Polarity is Active HIGH */
-	GPC_75_OHM	= 1<<26, /* Use 75 Ohm Termination instead of 50 */
-	GPC_DIS_FC	= 1<<25, /* Disable Automatic Fiber/Copper Detection */
-	GPC_DIS_SLEEP	= 1<<24, /* Disable Energy Detect */
-	GPC_HWCFG_M_3	= 1<<23, /* HWCFG_MODE[3] */
-	GPC_HWCFG_M_2	= 1<<22, /* HWCFG_MODE[2] */
-	GPC_HWCFG_M_1	= 1<<21, /* HWCFG_MODE[1] */
-	GPC_HWCFG_M_0	= 1<<20, /* HWCFG_MODE[0] */
-	GPC_ANEG_0	= 1<<19, /* ANEG[0] */
-	GPC_ENA_XC	= 1<<18, /* Enable MDI crossover */
-	GPC_DIS_125	= 1<<17, /* Disable 125 MHz clock */
-	GPC_ANEG_3	= 1<<16, /* ANEG[3] */
-	GPC_ANEG_2	= 1<<15, /* ANEG[2] */
-	GPC_ANEG_1	= 1<<14, /* ANEG[1] */
-	GPC_ENA_PAUSE	= 1<<13, /* Enable Pause (SYM_OR_REM) */
-	GPC_PHYADDR_4	= 1<<12, /* Bit 4 of Phy Addr */
-	GPC_PHYADDR_3	= 1<<11, /* Bit 3 of Phy Addr */
-	GPC_PHYADDR_2	= 1<<10, /* Bit 2 of Phy Addr */
-	GPC_PHYADDR_1	= 1<<9,	 /* Bit 1 of Phy Addr */
-	GPC_PHYADDR_0	= 1<<8,	 /* Bit 0 of Phy Addr */
-						/* Bits  7..2:	reserved */
 	GPC_RST_CLR	= 1<<1,	/* Clear GPHY Reset */
 	GPC_RST_SET	= 1<<0,	/* Set   GPHY Reset */
 };
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 246fac0..3df3c60 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -311,7 +311,7 @@
 	local_info_t *local;
 	struct ieee80211_hdr_4addr *hdr;
 	u16 fc;
-	int hdr_len, res;
+	int prefix_len, postfix_len, hdr_len, res;
 
 	iface = netdev_priv(skb->dev);
 	local = iface->local;
@@ -337,10 +337,13 @@
 	if (skb == NULL)
 		return NULL;
 
-	if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
-	     skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
-	    pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
-			     crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
+	prefix_len = crypt->ops->extra_mpdu_prefix_len +
+		crypt->ops->extra_msdu_prefix_len;
+	postfix_len = crypt->ops->extra_mpdu_postfix_len +
+		crypt->ops->extra_msdu_postfix_len;
+	if ((skb_headroom(skb) < prefix_len ||
+	     skb_tailroom(skb) < postfix_len) &&
+	    pskb_expand_head(skb, prefix_len, postfix_len, GFP_ATOMIC)) {
 		kfree_skb(skb);
 		return NULL;
 	}
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index dd070cc..f49eb068 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -378,9 +378,10 @@
 	display_buffer((char *) skb->data, skb->len);
 #endif
 	/* take care of monitor mode and spy monitoring. */
-	if (unlikely(priv->iw_mode == IW_MODE_MONITOR))
+	if (unlikely(priv->iw_mode == IW_MODE_MONITOR)) {
+		skb->dev = ndev;
 		discard = islpci_monitor_rx(priv, &skb);
-	else {
+	} else {
 		if (unlikely(skb->data[2 * ETH_ALEN] == 0)) {
 			/* The packet has a rx_annex. Read it for spy monitoring, Then
 			 * remove it, while keeping the 2 leading MAC addr.
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6ccc2e9..1cff65f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1625,18 +1625,20 @@
 			quirk_nvidia_ck804_pcie_aer_ext_cap);
 
 #ifdef CONFIG_PCI_MSI
-/* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely
- * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
- * some other busses controlled by the chipset even if Linux is not aware of it.
- * Instead of setting the flag on all busses in the machine, simply disable MSI
- * globally.
+/* Some chipsets do not support MSI. We cannot easily rely on setting
+ * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
+ * some other busses controlled by the chipset even if Linux is not
+ * aware of it.  Instead of setting the flag on all busses in the
+ * machine, simply disable MSI globally.
  */
-static void __init quirk_svw_msi(struct pci_dev *dev)
+static void __init quirk_disable_all_msi(struct pci_dev *dev)
 {
 	pci_no_msi();
 	printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n");
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi);
 
 /* Disable MSI on chipsets that are known to not support it */
 static void __devinit quirk_disable_msi(struct pci_dev *dev)
@@ -1649,8 +1651,6 @@
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_msi);
 
 /* Go through the list of Hypertransport capabilities and
  * return 1 if a HT MSI capability is found and enabled */
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 948efc7..eb6abd3 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -336,16 +336,21 @@
 		enable_irq_wake(board->det_pin);
 		if (board->irq_pin)
 			enable_irq_wake(board->irq_pin);
-	} else {
-		disable_irq_wake(board->det_pin);
-		if (board->irq_pin)
-			disable_irq_wake(board->irq_pin);
 	}
 	return 0;
 }
 
 static int at91_cf_resume(struct platform_device *pdev)
 {
+	struct at91_cf_socket	*cf = platform_get_drvdata(pdev);
+	struct at91_cf_data	*board = cf->board;
+
+	if (device_may_wakeup(&pdev->dev)) {
+		disable_irq_wake(board->det_pin);
+		if (board->irq_pin)
+			disable_irq_wake(board->irq_pin);
+	}
+
 	pcmcia_socket_dev_resume(&pdev->dev);
 	return 0;
 }
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index a1dc8c4..0c081a6 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -14,9 +14,9 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/poll.h>
+#include <linux/mutex.h>
 
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
 #include <asm/atomic.h>
 #include <asm/ebcdic.h>
 
@@ -514,7 +514,7 @@
  * to transfer in a readbuffer, which is protected by the readbuffer_mutex.
  */
 static char readbuffer[PAGE_SIZE];
-static DECLARE_MUTEX(readbuffer_mutex);
+static DEFINE_MUTEX(readbuffer_mutex);
 
 static int dasd_eer_open(struct inode *inp, struct file *filp)
 {
@@ -579,7 +579,7 @@
 	struct eerbuffer *eerb;
 
 	eerb = (struct eerbuffer *) filp->private_data;
-	if (down_interruptible(&readbuffer_mutex))
+	if (mutex_lock_interruptible(&readbuffer_mutex))
 		return -ERESTARTSYS;
 
 	spin_lock_irqsave(&bufferlock, flags);
@@ -588,7 +588,7 @@
 		                  /* has been deleted             */
 		eerb->residual = 0;
 		spin_unlock_irqrestore(&bufferlock, flags);
-		up(&readbuffer_mutex);
+		mutex_unlock(&readbuffer_mutex);
 		return -EIO;
 	} else if (eerb->residual > 0) {
 		/* OK we still have a second half of a record to deliver */
@@ -602,7 +602,7 @@
 			if (!tc) {
 				/* no data available */
 				spin_unlock_irqrestore(&bufferlock, flags);
-				up(&readbuffer_mutex);
+				mutex_unlock(&readbuffer_mutex);
 				if (filp->f_flags & O_NONBLOCK)
 					return -EAGAIN;
 				rc = wait_event_interruptible(
@@ -610,7 +610,7 @@
 					eerb->head != eerb->tail);
 				if (rc)
 					return rc;
-				if (down_interruptible(&readbuffer_mutex))
+				if (mutex_lock_interruptible(&readbuffer_mutex))
 					return -ERESTARTSYS;
 				spin_lock_irqsave(&bufferlock, flags);
 			}
@@ -626,11 +626,11 @@
 	spin_unlock_irqrestore(&bufferlock, flags);
 
 	if (copy_to_user(buf, readbuffer, effective_count)) {
-		up(&readbuffer_mutex);
+		mutex_unlock(&readbuffer_mutex);
 		return -EFAULT;
 	}
 
-	up(&readbuffer_mutex);
+	mutex_unlock(&readbuffer_mutex);
 	return effective_count;
 }
 
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index f6ef90e..743944a 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -487,7 +487,7 @@
 } __attribute__ ((packed));
 
 static struct diag210 raw3270_init_diag210;
-static DECLARE_MUTEX(raw3270_init_sem);
+static DEFINE_MUTEX(raw3270_init_mutex);
 
 static int
 raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,
@@ -713,7 +713,7 @@
 {
 	int rc;
 
-	down(&raw3270_init_sem);
+	mutex_lock(&raw3270_init_mutex);
 	rp->view = &raw3270_init_view;
 	raw3270_init_view.dev = rp;
 	if (MACHINE_IS_VM)
@@ -722,7 +722,7 @@
 		rc = __raw3270_size_device(rp);
 	raw3270_init_view.dev = NULL;
 	rp->view = NULL;
-	up(&raw3270_init_sem);
+	mutex_unlock(&raw3270_init_mutex);
 	if (rc == 0) {	/* Found something. */
 		/* Try to find a model. */
 		rp->model = 0;
@@ -749,7 +749,7 @@
 {
 	int rc;
 
-	down(&raw3270_init_sem);
+	mutex_lock(&raw3270_init_mutex);
 	memset(&rp->init_request, 0, sizeof(rp->init_request));
 	memset(&rp->init_data, 0, sizeof(rp->init_data));
 	/* Store reset data stream to init_data/init_request */
@@ -764,7 +764,7 @@
 	rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request);
 	raw3270_init_view.dev = NULL;
 	rp->view = NULL;
-	up(&raw3270_init_sem);
+	mutex_unlock(&raw3270_init_mutex);
 	return rc;
 }
 
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index a8b373f..6b264bd 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -296,25 +296,19 @@
 		device_del(&cdev->dev);
 }
 
-static void
-ccw_device_remove_disconnected(struct ccw_device *cdev)
+static void ccw_device_remove_orphan_cb(struct device *dev)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+
+	ccw_device_unregister(cdev);
+	put_device(&cdev->dev);
+}
+
+static void ccw_device_remove_sch_cb(struct device *dev)
 {
 	struct subchannel *sch;
-	unsigned long flags;
-	/*
-	 * Forced offline in disconnected state means
-	 * 'throw away device'.
-	 */
-	if (ccw_device_is_orphan(cdev)) {
-		/* Deregister ccw device. */
-		spin_lock_irqsave(cdev->ccwlock, flags);
-		cdev->private->state = DEV_STATE_NOT_OPER;
-		spin_unlock_irqrestore(cdev->ccwlock, flags);
-		ccw_device_unregister(cdev);
-		put_device(&cdev->dev);
-		return ;
-	}
-	sch = to_subchannel(cdev->dev.parent);
+
+	sch = to_subchannel(dev);
 	css_sch_device_unregister(sch);
 	/* Reset intparm to zeroes. */
 	sch->schib.pmcw.intparm = 0;
@@ -322,6 +316,39 @@
 	put_device(&sch->dev);
 }
 
+static void
+ccw_device_remove_disconnected(struct ccw_device *cdev)
+{
+	unsigned long flags;
+	int rc;
+
+	/*
+	 * Forced offline in disconnected state means
+	 * 'throw away device'.
+	 */
+	if (ccw_device_is_orphan(cdev)) {
+		/*
+		 * Deregister ccw device.
+		 * Unfortunately, we cannot do this directly from the
+		 * attribute method.
+		 */
+		spin_lock_irqsave(cdev->ccwlock, flags);
+		cdev->private->state = DEV_STATE_NOT_OPER;
+		spin_unlock_irqrestore(cdev->ccwlock, flags);
+		rc = device_schedule_callback(&cdev->dev,
+					      ccw_device_remove_orphan_cb);
+		if (rc)
+			dev_info(&cdev->dev, "Couldn't unregister orphan\n");
+		return;
+	}
+	/* Deregister subchannel, which will kill the ccw device. */
+	rc = device_schedule_callback(cdev->dev.parent,
+				      ccw_device_remove_sch_cb);
+	if (rc)
+		dev_info(&cdev->dev,
+			 "Couldn't unregister disconnected device\n");
+}
+
 int
 ccw_device_set_offline(struct ccw_device *cdev)
 {
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 898ec3b..6bba809 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -688,6 +688,12 @@
 		ccw_device_done(cdev, DEV_STATE_BOXED);
 		break;
 	default:
+		cdev->private->flags.donotify = 0;
+		if (get_device(&cdev->dev)) {
+			PREPARE_WORK(&cdev->private->kick_work,
+				     ccw_device_call_sch_unregister);
+			queue_work(ccw_device_work, &cdev->private->kick_work);
+		}
 		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 		break;
 	}
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index ddff40c..821cde65 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -1127,6 +1127,7 @@
 	int retval = 0;
 	unsigned long flags;
 
+	zfcp_adapter_scsi_unregister(adapter);
 	device_unregister(&adapter->generic_services);
 	zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
 	dev_set_drvdata(&adapter->ccw_device->dev, NULL);
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 81680ef..1c8f71a 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -189,9 +189,7 @@
  * @ccw_device: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer and sets an adapter
- * into state offline. Setting an fcp device offline means that it will be
- * unregistered from the SCSI stack and that the adapter will be shut down
- * asynchronously.
+ * into state offline.
  */
 static int
 zfcp_ccw_set_offline(struct ccw_device *ccw_device)
@@ -202,7 +200,6 @@
 	adapter = dev_get_drvdata(&ccw_device->dev);
 	zfcp_erp_adapter_shutdown(adapter, 0);
 	zfcp_erp_wait(adapter);
-	zfcp_adapter_scsi_unregister(adapter);
 	zfcp_erp_thread_kill(adapter);
 	zfcp_adapter_debug_unregister(adapter);
 	up(&zfcp_data.config_sema);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index a8b0254..0eb31e1 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -156,44 +156,30 @@
 	kfree(fsf_req);
 }
 
-/**
- * zfcp_fsf_req_dismiss - dismiss a single fsf request
- */
-static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
-				 struct zfcp_fsf_req *fsf_req,
-				 unsigned int counter)
-{
-	u64 dbg_tmp[2];
-
-	dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
-	dbg_tmp[1] = (u64) counter;
-	debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
-	list_del(&fsf_req->list);
-	fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
-	zfcp_fsf_req_complete(fsf_req);
-}
-
-/**
- * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
+/*
+ * Never ever call this without shutting down the adapter first.
+ * Otherwise the adapter would continue using and corrupting s390 storage.
+ * Included BUG_ON() call to ensure this is done.
+ * ERP is supposed to be the only user of this function.
  */
 void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
 {
-	struct zfcp_fsf_req *request, *tmp;
+	struct zfcp_fsf_req *fsf_req, *tmp;
 	unsigned long flags;
 	LIST_HEAD(remove_queue);
-	unsigned int i, counter;
+	unsigned int i;
 
+	BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status));
 	spin_lock_irqsave(&adapter->req_list_lock, flags);
 	atomic_set(&adapter->reqs_active, 0);
-	for (i=0; i<REQUEST_LIST_SIZE; i++)
+	for (i = 0; i < REQUEST_LIST_SIZE; i++)
 		list_splice_init(&adapter->req_list[i], &remove_queue);
-
 	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
 
-	counter = 0;
-	list_for_each_entry_safe(request, tmp, &remove_queue, list) {
-		zfcp_fsf_req_dismiss(adapter, request, counter);
-		counter++;
+	list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
+		list_del(&fsf_req->list);
+		fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+		zfcp_fsf_req_complete(fsf_req);
 	}
 }
 
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 16e2d64..0acf6db 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -569,6 +569,9 @@
 	int retval = 0;
 	static unsigned int unique_id = 0;
 
+	if (adapter->scsi_host)
+		goto out;
+
 	/* register adapter as SCSI host with mid layer of SCSI stack */
 	adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template,
 					     sizeof (struct zfcp_adapter *));
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 262f01e..44e0398 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
+#include <linux/mm.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d28c14e..572034c 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1753,23 +1753,9 @@
 	  The ESP was an on-board SCSI controller used on Sun 3/80
 	  machines.  Say Y here to compile in support for it.
 
-config SCSI_ESP_CORE
-	tristate "ESP Scsi Driver Core"
-	depends on SCSI
-	select SCSI_SPI_ATTRS
-	help
-	  This is a core driver for NCR53c9x based scsi chipsets,
-	  also known as "ESP" for Emulex Scsi Processor or
-	  Enhanced Scsi Processor.  This driver does not exist by
-	  itself, there are front-end drivers which, when enabled,
-	  select and enable this driver.  One example is SCSI_SUNESP.
-	  These front-end drivers provide probing, DMA, and register
-	  access support for the core driver.
-
 config SCSI_SUNESP
 	tristate "Sparc ESP Scsi Driver"
 	depends on SBUS && SCSI
-	select SCSI_ESP_CORE
 	help
 	  This is the driver for the Sun ESP SCSI host adapter. The ESP
 	  chipset is present in most SPARC SBUS-based computers.
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 51e884f..b1b6327 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -106,8 +106,7 @@
 obj-$(CONFIG_MEGARAID_NEWGEN)	+= megaraid/
 obj-$(CONFIG_MEGARAID_SAS)	+= megaraid/
 obj-$(CONFIG_SCSI_ACARD)	+= atp870u.o
-obj-$(CONFIG_SCSI_ESP_CORE)	+= esp_scsi.o
-obj-$(CONFIG_SCSI_SUNESP)	+= sun_esp.o
+obj-$(CONFIG_SCSI_SUNESP)	+= esp_scsi.o	sun_esp.o
 obj-$(CONFIG_SCSI_GDTH)		+= gdth.o
 obj-$(CONFIG_SCSI_INITIO)	+= initio.o
 obj-$(CONFIG_SCSI_INIA100)	+= a100u2w.o
@@ -121,7 +120,7 @@
 obj-$(CONFIG_SCSI_3W_9XXX)	+= 3w-9xxx.o
 obj-$(CONFIG_SCSI_PPA)		+= ppa.o
 obj-$(CONFIG_SCSI_IMM)		+= imm.o
-obj-$(CONFIG_JAZZ_ESP)		+= NCR53C9x.o	jazz_esp.o
+obj-$(CONFIG_JAZZ_ESP)		+= esp_scsi.o	jazz_esp.o
 obj-$(CONFIG_SUN3X_ESP)		+= NCR53C9x.o	sun3x_esp.o
 obj-$(CONFIG_SCSI_FCAL)		+= fcal.o
 obj-$(CONFIG_SCSI_LASI700)	+= 53c700.o lasi700.o
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 1e82c69..8dcfe4e 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -146,7 +146,7 @@
 static int nondasd = -1;
 static int dacmode = -1;
 
-static int commit = -1;
+int aac_commit = -1;
 int startup_timeout = 180;
 int aif_timeout = 120;
 
@@ -154,7 +154,7 @@
 MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
 module_param(dacmode, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
-module_param(commit, int, S_IRUGO|S_IWUSR);
+module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
 module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS.");
@@ -173,6 +173,9 @@
 module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on");
 
+int aac_reset_devices = 0;
+module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
 
 static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
 		struct fib *fibptr) {
@@ -246,7 +249,7 @@
 	aac_fib_complete(fibptr);
 	/* Send a CT_COMMIT_CONFIG to enable discovery of devices */
 	if (status >= 0) {
-		if ((commit == 1) || commit_flag) {
+		if ((aac_commit == 1) || commit_flag) {
 			struct aac_commit_config * dinfo;
 			aac_fib_init(fibptr);
 			dinfo = (struct aac_commit_config *) fib_data(fibptr);
@@ -261,7 +264,7 @@
 				    1, 1,
 				    NULL, NULL);
 			aac_fib_complete(fibptr);
-		} else if (commit == 0) {
+		} else if (aac_commit == 0) {
 			printk(KERN_WARNING
 			  "aac_get_config_status: Foreign device configurations are being ignored\n");
 		}
@@ -340,7 +343,7 @@
 static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
 {
 	void *buf;
-	unsigned int transfer_len;
+	int transfer_len;
 	struct scatterlist *sg = scsicmd->request_buffer;
 
 	if (scsicmd->use_sg) {
@@ -351,7 +354,7 @@
 		transfer_len = min(scsicmd->request_bufflen, len + offset);
 	}
 	transfer_len -= offset;
-	if (buf && transfer_len)
+	if (buf && transfer_len > 0)
 		memcpy(buf + offset, data, transfer_len);
 
 	if (scsicmd->use_sg) 
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 45ca3e8..c81edf3 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1823,9 +1823,12 @@
 int aac_probe_container(struct aac_dev *dev, int cid);
 int _aac_rx_init(struct aac_dev *dev);
 int aac_rx_select_comm(struct aac_dev *dev, int comm);
+int aac_rx_deliver_producer(struct fib * fib);
 extern int numacb;
 extern int acbsize;
 extern char aac_driver_version[];
 extern int startup_timeout;
 extern int aif_timeout;
 extern int expose_physicals;
+extern int aac_reset_devices;
+extern int aac_commit;
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 291cd14..ae978a3 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -378,7 +378,7 @@
  *
  *	Will send a fib, returning 0 if successful.
  */
-static int aac_rx_deliver_producer(struct fib * fib)
+int aac_rx_deliver_producer(struct fib * fib)
 {
 	struct aac_dev *dev = fib->dev;
 	struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
@@ -488,6 +488,8 @@
 		return -EINVAL;
 	if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
 		return -ENODEV;
+	if (startup_timeout < 300)
+		startup_timeout = 300;
 	return 0;
 }
 
@@ -542,7 +544,7 @@
 	dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
 	dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;
 	dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
-	if ((((status & 0x0c) != 0x0c) || reset_devices) &&
+	if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) &&
 	  !aac_rx_restart_adapter(dev, 0))
 		++restart;
 	/*
@@ -594,6 +596,8 @@
 		}
 		msleep(1);
 	}
+	if (restart)
+		aac_commit = 1;
 	/*
 	 *	Fill in the common function dispatch table.
 	 */
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index f4b5e97..85b91bc 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -5,7 +5,7 @@
  * based on the old aacraid driver that is..
  * Adaptec aacraid device driver for Linux.
  *
- * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
+ * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -257,6 +257,11 @@
 			NULL, NULL, NULL, NULL, NULL);
 }
 
+static int aac_sa_restart_adapter(struct aac_dev *dev, int bled)
+{
+	return -EINVAL;
+}
+
 /**
  *	aac_sa_check_health
  *	@dev: device to check if healthy
@@ -366,7 +371,9 @@
 	dev->a_ops.adapter_notify = aac_sa_notify_adapter;
 	dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
 	dev->a_ops.adapter_check_health = aac_sa_check_health;
+	dev->a_ops.adapter_restart = aac_sa_restart_adapter;
 	dev->a_ops.adapter_intr = aac_sa_intr;
+	dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
 	dev->a_ops.adapter_ioremap = aac_sa_ioremap;
 
 	/*
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
index c328596..6066998 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
@@ -106,6 +106,7 @@
 static void add_conditional(symbol_t *symbol);
 static void add_version(const char *verstring);
 static int  is_download_const(expression_t *immed);
+void yyerror(const char *string);
 
 #define SRAM_SYMNAME "SRAM_BASE"
 #define SCB_SYMNAME "SCB_BASE"
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
index 439f760..ff46aa6 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
@@ -65,6 +65,7 @@
 static symbol_t *macro_symbol;
 
 static void add_macro_arg(const char *argtext, int position);
+void mmerror(const char *string);
 
 %}
 
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c
index 9a14a6d..c0d0b7d 100644
--- a/drivers/scsi/aic94xx/aic94xx_tmf.c
+++ b/drivers/scsi/aic94xx/aic94xx_tmf.c
@@ -290,6 +290,7 @@
 static inline int asd_clear_nexus(struct sas_task *task)
 {
 	int res = TMF_RESP_FUNC_FAILED;
+	int leftover;
 	struct asd_ascb *tascb = task->lldd_task;
 	unsigned long flags;
 
@@ -298,10 +299,12 @@
 		res = asd_clear_nexus_tag(task);
 	else
 		res = asd_clear_nexus_index(task);
-	wait_for_completion_timeout(&tascb->completion,
-				    AIC94XX_SCB_TIMEOUT);
+	leftover = wait_for_completion_timeout(&tascb->completion,
+					       AIC94XX_SCB_TIMEOUT);
 	ASD_DPRINTK("came back from clear nexus\n");
 	spin_lock_irqsave(&task->task_state_lock, flags);
+	if (leftover < 1)
+		res = TMF_RESP_FUNC_FAILED;
 	if (task->task_state_flags & SAS_TASK_STATE_DONE)
 		res = TMF_RESP_FUNC_COMPLETE;
 	spin_unlock_irqrestore(&task->task_state_lock, flags);
@@ -350,6 +353,7 @@
 	unsigned long flags;
 	struct asd_ascb *ascb = NULL;
 	struct scb *scb;
+	int leftover;
 
 	spin_lock_irqsave(&task->task_state_lock, flags);
 	if (task->task_state_flags & SAS_TASK_STATE_DONE) {
@@ -455,9 +459,11 @@
 		break;
 	case TF_TMF_TASK_DONE + 0xFF00:	/* done but not reported yet */
 		res = TMF_RESP_FUNC_FAILED;
-		wait_for_completion_timeout(&tascb->completion,
-					    AIC94XX_SCB_TIMEOUT);
+		leftover = wait_for_completion_timeout(&tascb->completion,
+						       AIC94XX_SCB_TIMEOUT);
 		spin_lock_irqsave(&task->task_state_lock, flags);
+		if (leftover < 1)
+			res = TMF_RESP_FUNC_FAILED;
 		if (task->task_state_flags & SAS_TASK_STATE_DONE)
 			res = TMF_RESP_FUNC_COMPLETE;
 		spin_unlock_irqrestore(&task->task_state_lock, flags);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 4baa79e..fa6ff29 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3954,6 +3954,13 @@
 		spin_unlock_irq(scsi_cmd->device->host->host_lock);
 		ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);
 		spin_lock_irq(scsi_cmd->device->host->host_lock);
+
+		list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
+			if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+				rc = -EIO;
+				break;
+			}
+		}
 	} else
 		rc = ipr_device_reset(ioa_cfg, res);
 	res->resetting_device = 0;
diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c
index 19dd4b9..81e497d 100644
--- a/drivers/scsi/jazz_esp.c
+++ b/drivers/scsi/jazz_esp.c
@@ -1,307 +1,244 @@
-/*
- * jazz_esp.c: Driver for SCSI chip on Mips Magnum Boards (JAZZ architecture)
+/* jazz_esp.c: ESP front-end for MIPS JAZZ systems.
  *
- * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
- *
- * jazz_esp is based on David S. Miller's ESP driver and cyber_esp
+ * Copyright (C) 2007 Thomas Bogendörfer (tsbogend@alpha.frankende)
  */
 
-#include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/delay.h>
 #include <linux/types.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/blkdev.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "NCR53C9x.h"
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/irq.h>
-#include <asm/jazz.h>
-#include <asm/jazzdma.h>
+#include <asm/io.h>
 #include <asm/dma.h>
 
-#include <asm/pgtable.h>
+#include <asm/jazz.h>
+#include <asm/jazzdma.h>
 
-static int  dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
-static int  dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_dump_state(struct NCR_ESP *esp);
-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
-static void dma_ints_off(struct NCR_ESP *esp);
-static void dma_ints_on(struct NCR_ESP *esp);
-static int  dma_irq_p(struct NCR_ESP *esp);
-static int  dma_ports_p(struct NCR_ESP *esp);
-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
-static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_advance_sg (struct scsi_cmnd *sp);
-static void dma_led_off(struct NCR_ESP *);
-static void dma_led_on(struct NCR_ESP *);
+#include <scsi/scsi_host.h>
 
+#include "esp_scsi.h"
 
-static volatile unsigned char cmd_buffer[16];
-				/* This is where all commands are put
-				 * before they are trasfered to the ESP chip
-				 * via PIO.
-				 */
+#define DRV_MODULE_NAME		"jazz_esp"
+#define PFX DRV_MODULE_NAME	": "
+#define DRV_VERSION		"1.000"
+#define DRV_MODULE_RELDATE	"May 19, 2007"
 
-static int jazz_esp_release(struct Scsi_Host *shost)
+static void jazz_esp_write8(struct esp *esp, u8 val, unsigned long reg)
 {
-	if (shost->irq)
-		free_irq(shost->irq, NULL);
-	if (shost->dma_channel != 0xff)
-		free_dma(shost->dma_channel);
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
-	scsi_unregister(shost);
+	*(volatile u8 *)(esp->regs + reg) = val;
+}
+
+static u8 jazz_esp_read8(struct esp *esp, unsigned long reg)
+{
+	return *(volatile u8 *)(esp->regs + reg);
+}
+
+static dma_addr_t jazz_esp_map_single(struct esp *esp, void *buf,
+				      size_t sz, int dir)
+{
+	return dma_map_single(esp->dev, buf, sz, dir);
+}
+
+static int jazz_esp_map_sg(struct esp *esp, struct scatterlist *sg,
+				  int num_sg, int dir)
+{
+	return dma_map_sg(esp->dev, sg, num_sg, dir);
+}
+
+static void jazz_esp_unmap_single(struct esp *esp, dma_addr_t addr,
+				  size_t sz, int dir)
+{
+	dma_unmap_single(esp->dev, addr, sz, dir);
+}
+
+static void jazz_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
+			      int num_sg, int dir)
+{
+	dma_unmap_sg(esp->dev, sg, num_sg, dir);
+}
+
+static int jazz_esp_irq_pending(struct esp *esp)
+{
+	if (jazz_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR)
+		return 1;
 	return 0;
 }
 
-/***************************************************************** Detection */
-static int jazz_esp_detect(struct scsi_host_template *tpnt)
+static void jazz_esp_reset_dma(struct esp *esp)
 {
-    struct NCR_ESP *esp;
-    struct ConfigDev *esp_dev;
+	vdma_disable ((int)esp->dma_regs);
+}
 
-    /*
-     * first assumption it is there:-)
-     */
-    if (1) {
-	esp_dev = NULL;
-	esp = esp_allocate(tpnt, esp_dev, 0);
-	
-	/* Do command transfer with programmed I/O */
-	esp->do_pio_cmds = 1;
-	
-	/* Required functions */
-	esp->dma_bytes_sent = &dma_bytes_sent;
-	esp->dma_can_transfer = &dma_can_transfer;
-	esp->dma_dump_state = &dma_dump_state;
-	esp->dma_init_read = &dma_init_read;
-	esp->dma_init_write = &dma_init_write;
-	esp->dma_ints_off = &dma_ints_off;
-	esp->dma_ints_on = &dma_ints_on;
-	esp->dma_irq_p = &dma_irq_p;
-	esp->dma_ports_p = &dma_ports_p;
-	esp->dma_setup = &dma_setup;
+static void jazz_esp_dma_drain(struct esp *esp)
+{
+	/* nothing to do */
+}
 
-	/* Optional functions */
-	esp->dma_barrier = NULL;
-	esp->dma_drain = NULL;
-	esp->dma_invalidate = NULL;
-	esp->dma_irq_entry = NULL;
-	esp->dma_irq_exit = NULL;
-	esp->dma_poll = NULL;
-	esp->dma_reset = NULL;
-	esp->dma_led_off = &dma_led_off;
-	esp->dma_led_on = &dma_led_on;
-	
-	/* virtual DMA functions */
-	esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
-	esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
-	esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one;
-	esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl;
-	esp->dma_advance_sg = &dma_advance_sg;
+static void jazz_esp_dma_invalidate(struct esp *esp)
+{
+	vdma_disable ((int)esp->dma_regs);
+}
 
+static void jazz_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
+				  u32 dma_count, int write, u8 cmd)
+{
+	BUG_ON(!(cmd & ESP_CMD_DMA));
 
-	/* SCSI chip speed */
+	jazz_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+	jazz_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+	vdma_disable ((int)esp->dma_regs);
+	if (write)
+		vdma_set_mode ((int)esp->dma_regs, DMA_MODE_READ);
+	else
+		vdma_set_mode ((int)esp->dma_regs, DMA_MODE_WRITE);
+
+	vdma_set_addr ((int)esp->dma_regs, addr);
+	vdma_set_count ((int)esp->dma_regs, dma_count);
+	vdma_enable ((int)esp->dma_regs);
+
+	scsi_esp_cmd(esp, cmd);
+}
+
+static int jazz_esp_dma_error(struct esp *esp)
+{
+	u32 enable = vdma_get_enable((int)esp->dma_regs);
+
+	if (enable & (R4030_MEM_INTR|R4030_ADDR_INTR))
+		return 1;
+
+	return 0;
+}
+
+static const struct esp_driver_ops jazz_esp_ops = {
+	.esp_write8	=	jazz_esp_write8,
+	.esp_read8	=	jazz_esp_read8,
+	.map_single	=	jazz_esp_map_single,
+	.map_sg		=	jazz_esp_map_sg,
+	.unmap_single	=	jazz_esp_unmap_single,
+	.unmap_sg	=	jazz_esp_unmap_sg,
+	.irq_pending	=	jazz_esp_irq_pending,
+	.reset_dma	=	jazz_esp_reset_dma,
+	.dma_drain	=	jazz_esp_dma_drain,
+	.dma_invalidate	=	jazz_esp_dma_invalidate,
+	.send_dma_cmd	=	jazz_esp_send_dma_cmd,
+	.dma_error	=	jazz_esp_dma_error,
+};
+
+static int __devinit esp_jazz_probe(struct platform_device *dev)
+{
+	struct scsi_host_template *tpnt = &scsi_esp_template;
+	struct Scsi_Host *host;
+	struct esp *esp;
+	struct resource *res;
+	int err;
+
+	host = scsi_host_alloc(tpnt, sizeof(struct esp));
+
+	err = -ENOMEM;
+	if (!host)
+		goto fail;
+
+	host->max_id = 8;
+	esp = host_to_esp(host);
+
+	esp->host = host;
+	esp->dev = dev;
+	esp->ops = &jazz_esp_ops;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		goto fail_unlink;
+
+	esp->regs = (void __iomem *)res->start;
+	if (!esp->regs)
+		goto fail_unlink;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+	if (!res)
+		goto fail_unlink;
+
+	esp->dma_regs = (void __iomem *)res->start;
+
+	esp->command_block = dma_alloc_coherent(esp->dev, 16,
+						&esp->command_block_dma,
+						GFP_KERNEL);
+	if (!esp->command_block)
+		goto fail_unmap_regs;
+
+	host->irq = platform_get_irq(dev, 0);
+	err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
+	if (err < 0)
+		goto fail_unmap_command_block;
+
+	esp->scsi_id = 7;
+	esp->host->this_id = esp->scsi_id;
+	esp->scsi_id_mask = (1 << esp->scsi_id);
 	esp->cfreq = 40000000;
 
-	/* 
-	 * we don't give the address of DMA channel, but the number
-	 * of DMA channel, so we can use the jazz DMA functions
-	 * 
-	 */
-	esp->dregs = (void *) JAZZ_SCSI_DMA;
-	
-	/* ESP register base */
-	esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE);
-	
-	/* Set the command buffer */
-	esp->esp_command = (volatile unsigned char *)cmd_buffer;
-	
-	/* get virtual dma address for command buffer */
-	esp->esp_command_dvma = vdma_alloc(CPHYSADDR(cmd_buffer), sizeof (cmd_buffer));
-	
-	esp->irq = JAZZ_SCSI_IRQ;
-	request_irq(JAZZ_SCSI_IRQ, esp_intr, IRQF_DISABLED, "JAZZ SCSI",
-	            esp->ehost);
+	dev_set_drvdata(&dev->dev, esp);
 
-	/*
-	 * FIXME, look if the scsi id is available from NVRAM
-	 */
-	esp->scsi_id = 7;
-		
-	/* Check for differential SCSI-bus */
-	/* What is this stuff? */
-	esp->diff = 0;
+	err = scsi_esp_register(esp, &dev->dev);
+	if (err)
+		goto fail_free_irq;
 
-	esp_initialize(esp);
-	
-	printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
-	esps_running = esps_in_use;
-	return esps_in_use;
-    }
-    return 0;
+	return 0;
+
+fail_free_irq:
+	free_irq(host->irq, esp);
+fail_unmap_command_block:
+	dma_free_coherent(esp->dev, 16,
+			  esp->command_block,
+			  esp->command_block_dma);
+fail_unmap_regs:
+fail_unlink:
+	scsi_host_put(host);
+fail:
+	return err;
 }
 
-/************************************************************* DMA Functions */
-static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
+static int __devexit esp_jazz_remove(struct platform_device *dev)
 {
-    return fifo_count;
+	struct esp *esp = dev_get_drvdata(&dev->dev);
+	unsigned int irq = esp->host->irq;
+
+	scsi_esp_unregister(esp);
+
+	free_irq(irq, esp);
+	dma_free_coherent(esp->dev, 16,
+			  esp->command_block,
+			  esp->command_block_dma);
+
+	scsi_host_put(esp->host);
+
+	return 0;
 }
 
-static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp)
-{
-    /*
-     * maximum DMA size is 1MB
-     */
-    unsigned long sz = sp->SCp.this_residual;
-    if(sz > 0x100000)
-	sz = 0x100000;
-    return sz;
-}
-
-static void dma_dump_state(struct NCR_ESP *esp)
-{
-    
-    ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n",
-	    esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_residue((int)esp->dregs)));
-}
-
-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
-{
-    dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length);
-    vdma_disable ((int)esp->dregs);
-    vdma_set_mode ((int)esp->dregs, DMA_MODE_READ);
-    vdma_set_addr ((int)esp->dregs, vaddress);
-    vdma_set_count ((int)esp->dregs, length);
-    vdma_enable ((int)esp->dregs);
-}
-
-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
-{
-    dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length);    
-    vdma_disable ((int)esp->dregs);    
-    vdma_set_mode ((int)esp->dregs, DMA_MODE_WRITE);
-    vdma_set_addr ((int)esp->dregs, vaddress);
-    vdma_set_count ((int)esp->dregs, length);
-    vdma_enable ((int)esp->dregs);    
-}
-
-static void dma_ints_off(struct NCR_ESP *esp)
-{
-    disable_irq(esp->irq);
-}
-
-static void dma_ints_on(struct NCR_ESP *esp)
-{
-    enable_irq(esp->irq);
-}
-
-static int dma_irq_p(struct NCR_ESP *esp)
-{
-    return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR);
-}
-
-static int dma_ports_p(struct NCR_ESP *esp)
-{
-    int enable = vdma_get_enable((int)esp->dregs);
-    
-    return (enable & R4030_CHNL_ENABLE);
-}
-
-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
-{
-    /* 
-     * On the Sparc, DMA_ST_WRITE means "move data from device to memory"
-     * so when (write) is true, it actually means READ!
-     */
-    if(write){
-	dma_init_read(esp, addr, count);
-    } else {
-	dma_init_write(esp, addr, count);
-    }
-}
-
-static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
-{
-    sp->SCp.have_data_in = vdma_alloc(CPHYSADDR(sp->SCp.buffer), sp->SCp.this_residual);
-    sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in);
-}
-
-static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
-{
-    int sz = sp->SCp.buffers_residual;
-    struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer;
-    
-    while (sz >= 0) {
-	sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length);
-	sz--;
-    }
-    sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address);
-}    
-
-static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
-{
-    vdma_free(sp->SCp.have_data_in);
-}
-
-static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
-{
-    int sz = sp->use_sg - 1;
-    struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
-			
-    while(sz >= 0) {
-	vdma_free(sg[sz].dma_address);
-	sz--;
-    }
-}
-
-static void dma_advance_sg (struct scsi_cmnd *sp)
-{
-    sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
-}
-
-#define JAZZ_HDC_LED   0xe000d100 /* FIXME, find correct address */
-
-static void dma_led_off(struct NCR_ESP *esp)
-{
-#if 0    
-    *(unsigned char *)JAZZ_HDC_LED = 0;
-#endif    
-}
-
-static void dma_led_on(struct NCR_ESP *esp)
-{    
-#if 0    
-    *(unsigned char *)JAZZ_HDC_LED = 1;
-#endif    
-}
-
-static struct scsi_host_template driver_template = {
-	.proc_name		= "jazz_esp",
-	.proc_info		= esp_proc_info,
-	.name			= "ESP 100/100a/200",
-	.detect			= jazz_esp_detect,
-	.slave_alloc		= esp_slave_alloc,
-	.slave_destroy		= esp_slave_destroy,
-	.release		= jazz_esp_release,
-	.info			= esp_info,
-	.queuecommand		= esp_queue,
-	.eh_abort_handler	= esp_abort,
-	.eh_bus_reset_handler	= esp_reset,
-	.can_queue		= 7,
-	.this_id		= 7,
-	.sg_tablesize		= SG_ALL,
-	.cmd_per_lun		= 1,
-	.use_clustering		= DISABLE_CLUSTERING,
+static struct platform_driver esp_jazz_driver = {
+	.probe		= esp_jazz_probe,
+	.remove		= __devexit_p(esp_jazz_remove),
+	.driver	= {
+		.name	= "jazz_esp",
+	},
 };
-#include "scsi_module.c"
+
+static int __init jazz_esp_init(void)
+{
+	return platform_driver_register(&esp_jazz_driver);
+}
+
+static void __exit jazz_esp_exit(void)
+{
+	platform_driver_unregister(&esp_jazz_driver);
+}
+
+MODULE_DESCRIPTION("JAZZ ESP SCSI driver");
+MODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(jazz_esp_init);
+module_exit(jazz_esp_exit);
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
index 5631c19..732446e 100644
--- a/drivers/scsi/libsrp.c
+++ b/drivers/scsi/libsrp.c
@@ -254,6 +254,7 @@
 
 		sg_init_one(&dummy, md, id->table_desc.len);
 		sg_dma_address(&dummy) = token;
+		sg_dma_len(&dummy) = id->table_desc.len;
 		err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE,
 			      id->table_desc.len);
 		if (err) {
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 7a81267..e2cf12e 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_sas.c
- * Version	: v00.00.03.10-rc1
+ * Version	: v00.00.03.10-rc5
  *
  * Authors:
  *	(email-id : megaraidlinux@lsi.com)
@@ -886,6 +886,7 @@
 		goto out_return_cmd;
 
 	cmd->scmd = scmd;
+	scmd->SCp.ptr = (char *)cmd;
 
 	/*
 	 * Issue the command to the FW
@@ -919,7 +920,7 @@
 	 * The RAID firmware may require extended timeouts.
 	 */
 	if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
-		sdev->timeout = 90 * HZ;
+		sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ;
 	return 0;
 }
 
@@ -981,8 +982,8 @@
 
 	instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
-	scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x\n",
-	       scmd->serial_number, scmd->cmnd[0]);
+	scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",
+		 scmd->serial_number, scmd->cmnd[0], scmd->retries);
 
 	if (instance->hw_crit_error) {
 		printk(KERN_ERR "megasas: cannot recover from previous reset "
@@ -1000,6 +1001,39 @@
 }
 
 /**
+ * megasas_reset_timer - quiesce the adapter if required
+ * @scmd:		scsi cmnd
+ *
+ * Sets the FW busy flag and reduces the host->can_queue if the
+ * cmd has not been completed within the timeout period.
+ */
+static enum
+scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
+{
+	struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
+	struct megasas_instance *instance;
+	unsigned long flags;
+
+	if (time_after(jiffies, scmd->jiffies_at_alloc +
+				(MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
+		return EH_NOT_HANDLED;
+	}
+
+	instance = cmd->instance;
+	if (!(instance->flag & MEGASAS_FW_BUSY)) {
+		/* FW is busy, throttle IO */
+		spin_lock_irqsave(instance->host->host_lock, flags);
+
+		instance->host->can_queue = 16;
+		instance->last_time = jiffies;
+		instance->flag |= MEGASAS_FW_BUSY;
+
+		spin_unlock_irqrestore(instance->host->host_lock, flags);
+	}
+	return EH_RESET_TIMER;
+}
+
+/**
  * megasas_reset_device -	Device reset handler entry point
  */
 static int megasas_reset_device(struct scsi_cmnd *scmd)
@@ -1112,6 +1146,7 @@
 	.eh_device_reset_handler = megasas_reset_device,
 	.eh_bus_reset_handler = megasas_reset_bus_host,
 	.eh_host_reset_handler = megasas_reset_bus_host,
+	.eh_timed_out = megasas_reset_timer,
 	.bios_param = megasas_bios_param,
 	.use_clustering = ENABLE_CLUSTERING,
 };
@@ -1215,9 +1250,8 @@
 	int exception = 0;
 	struct megasas_header *hdr = &cmd->frame->hdr;
 
-	if (cmd->scmd) {
-		cmd->scmd->SCp.ptr = (char *)0;
-	}
+	if (cmd->scmd)
+		cmd->scmd->SCp.ptr = NULL;
 
 	switch (hdr->cmd) {
 
@@ -1806,6 +1840,7 @@
 	u32 context;
 	struct megasas_cmd *cmd;
 	struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
+	unsigned long flags;
 
 	/* If we have already declared adapter dead, donot complete cmds */
 	if (instance->hw_crit_error)
@@ -1828,6 +1863,22 @@
 	}
 
 	*instance->consumer = producer;
+
+	/*
+	 * Check if we can restore can_queue
+	 */
+	if (instance->flag & MEGASAS_FW_BUSY
+		&& time_after(jiffies, instance->last_time + 5 * HZ)
+		&& atomic_read(&instance->fw_outstanding) < 17) {
+
+		spin_lock_irqsave(instance->host->host_lock, flags);
+		instance->flag &= ~MEGASAS_FW_BUSY;
+		instance->host->can_queue =
+				instance->max_fw_cmds - MEGASAS_INT_CMDS;
+
+		spin_unlock_irqrestore(instance->host->host_lock, flags);
+	}
+
 }
 
 /**
@@ -2398,6 +2449,8 @@
 	instance->init_id = MEGASAS_DEFAULT_INIT_ID;
 
 	megasas_dbg_lvl = 0;
+	instance->flag = 0;
+	instance->last_time = 0;
 
 	/*
 	 * Initialize MFI Firmware
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index e862992..4dffc91 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"00.00.03.10-rc1"
-#define MEGASAS_RELDATE				"Feb 14, 2007"
-#define MEGASAS_EXT_VERSION			"Wed Feb 14 10:14:25 PST 2007"
+#define MEGASAS_VERSION				"00.00.03.10-rc5"
+#define MEGASAS_RELDATE				"May 17, 2007"
+#define MEGASAS_EXT_VERSION			"Thu May 17 10:09:32 PDT 2007"
 
 /*
  * Device IDs
@@ -539,6 +539,8 @@
 
 #define MEGASAS_DBG_LVL				1
 
+#define MEGASAS_FW_BUSY				1
+
 /*
  * When SCSI mid-layer calls driver's reset routine, driver waits for
  * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
@@ -549,8 +551,8 @@
 #define MEGASAS_RESET_WAIT_TIME			180
 #define MEGASAS_INTERNAL_CMD_WAIT_TIME		180
 #define	MEGASAS_RESET_NOTICE_INTERVAL		5
-
 #define MEGASAS_IOCTL_CMD			0
+#define MEGASAS_DEFAULT_CMD_TIMEOUT		90
 
 /*
  * FW reports the maximum of number of commands that it can accept (maximum
@@ -1073,7 +1075,6 @@
 	struct megasas_register_set __iomem *reg_set;
 
 	s8 init_id;
-	u8 reserved[3];
 
 	u16 max_num_sge;
 	u16 max_fw_cmds;
@@ -1104,6 +1105,9 @@
 
 	struct megasas_instance_template *instancet;
 	struct tasklet_struct isr_tasklet;
+
+	u8 flag;
+	unsigned long last_time;
 };
 
 #define MEGASAS_IS_LOGICAL(scp)						\
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index 3b2e1a5..d953d43 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -4,6 +4,7 @@
  *
  */
 
+#include <linux/completion.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -50,16 +51,10 @@
 } *fcs __initdata;
 static int fcscount __initdata = 0;
 static atomic_t fcss __initdata = ATOMIC_INIT(0);
-DECLARE_MUTEX_LOCKED(fc_sem);
+static DECLARE_COMPLETION(fc_detect_complete);
 
 static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd);
 
-static void __init pluto_detect_timeout(unsigned long data)
-{
-	PLND(("Timeout\n"))
-	up(&fc_sem);
-}
-
 static void __init pluto_detect_done(Scsi_Cmnd *SCpnt)
 {
 	/* Do nothing */
@@ -69,7 +64,7 @@
 {
 	PLND(("Detect done %08lx\n", (long)SCpnt))
 	if (atomic_dec_and_test (&fcss))
-		up(&fc_sem);
+		complete(&fc_detect_complete);
 }
 
 int pluto_slave_configure(struct scsi_device *device)
@@ -96,7 +91,6 @@
 	int i, retry, nplutos;
 	fc_channel *fc;
 	struct scsi_device dev;
-	DEFINE_TIMER(fc_timer, pluto_detect_timeout, 0, 0);
 
 	tpnt->proc_name = "pluto";
 	fcscount = 0;
@@ -187,15 +181,11 @@
 			}
 		}
 	    
-		fc_timer.expires = jiffies + 10 * HZ;
-		add_timer(&fc_timer);
-		
-		down(&fc_sem);
+		wait_for_completion_timeout(&fc_detect_complete, 10 * HZ);
 		PLND(("Woken up\n"))
 		if (!atomic_read(&fcss))
 			break; /* All fc channels have answered us */
 	}
-	del_timer_sync(&fc_timer);
 
 	PLND(("Finished search\n"))
 	for (i = 0, nplutos = 0; i < fcscount; i++) {
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index ce63044..18dd5cc 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -209,6 +209,7 @@
 	{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"Promise", "", NULL, BLIST_SPARSELUN},
 	{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
 	{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
 	{"SEAGATE", "ST34555N", "0930", BLIST_NOTQ},	/* Chokes on tagged INQUIRY */
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 00e4666..3d8c9cb 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1789,7 +1789,7 @@
 static int sd_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
-	int ret;
+	int ret = 0;
 
 	if (!sdkp)
 		return 0;	/* this can happen */
@@ -1798,30 +1798,34 @@
 		sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
 		ret = sd_sync_cache(sdkp);
 		if (ret)
-			return ret;
+			goto done;
 	}
 
 	if (mesg.event == PM_EVENT_SUSPEND &&
 	    sdkp->device->manage_start_stop) {
 		sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
 		ret = sd_start_stop_device(sdkp, 0);
-		if (ret)
-			return ret;
 	}
 
-	return 0;
+done:
+	scsi_disk_put(sdkp);
+	return ret;
 }
 
 static int sd_resume(struct device *dev)
 {
 	struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+	int ret = 0;
 
 	if (!sdkp->device->manage_start_stop)
-		return 0;
+		goto done;
 
 	sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
+	ret = sd_start_stop_device(sdkp, 1);
 
-	return sd_start_stop_device(sdkp, 1);
+done:
+	scsi_disk_put(sdkp);
+	return ret;
 }
 
 /**
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 69be132..9ac83ab 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -32,11 +32,12 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
+#include <scsi/scsi_dbg.h>
 
 #define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "3.1.0.1"
+#define ST_DRIVER_VERSION "3.6.0000.1"
 #define ST_VER_MAJOR 		3
-#define ST_VER_MINOR 		1
+#define ST_VER_MINOR 		6
 #define ST_OEM 			0
 #define ST_BUILD_VER 		1
 
@@ -113,10 +114,6 @@
 	SG_CF_64B				= 0x40,	/* 64 bit item */
 	SG_CF_HOST				= 0x20,	/* sg in host memory */
 
-	ST_MAX_ARRAY_SUPPORTED			= 16,
-	ST_MAX_TARGET_NUM			= (ST_MAX_ARRAY_SUPPORTED+1),
-	ST_MAX_LUN_PER_TARGET			= 16,
-
 	st_shasta				= 0,
 	st_vsc					= 1,
 	st_vsc1					= 2,
@@ -586,7 +583,7 @@
 	u16 tag;
 	host = cmd->device->host;
 	id = cmd->device->id;
-	lun = cmd->device->channel; /* firmware lun issue work around */
+	lun = cmd->device->lun;
 	hba = (struct st_hba *) &host->hostdata[0];
 
 	switch (cmd->cmnd[0]) {
@@ -605,8 +602,26 @@
 			stex_invalid_field(cmd, done);
 		return 0;
 	}
+	case REPORT_LUNS:
+		/*
+		 * The shasta firmware does not report actual luns in the
+		 * target, so fail the command to force sequential lun scan.
+		 * Also, the console device does not support this command.
+		 */
+		if (hba->cardtype == st_shasta || id == host->max_id - 1) {
+			stex_invalid_field(cmd, done);
+			return 0;
+		}
+		break;
+	case TEST_UNIT_READY:
+		if (id == host->max_id - 1) {
+			cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+			done(cmd);
+			return 0;
+		}
+		break;
 	case INQUIRY:
-		if (id != ST_MAX_ARRAY_SUPPORTED)
+		if (id != host->max_id - 1)
 			break;
 		if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
 			stex_direct_copy(cmd, console_inq_page,
@@ -624,7 +639,7 @@
 			ver.oem = ST_OEM;
 			ver.build = ST_BUILD_VER;
 			ver.signature[0] = PASSTHRU_SIGNATURE;
-			ver.console_id = ST_MAX_ARRAY_SUPPORTED;
+			ver.console_id = host->max_id - 1;
 			ver.host_no = hba->host->host_no;
 			cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ?
 				DID_OK << 16 | COMMAND_COMPLETE << 8 :
@@ -645,13 +660,8 @@
 
 	req = stex_alloc_req(hba);
 
-	if (hba->cardtype == st_yosemite) {
-		req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id;
-		req->target = 0;
-	} else {
-		req->lun = lun;
-		req->target = id;
-	}
+	req->lun = lun;
+	req->target = id;
 
 	/* cdb */
 	memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
@@ -767,18 +777,6 @@
 			ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
 		else
 			ccb->srb_status = SRB_STATUS_SUCCESS;
-	} else if (ccb->cmd->cmnd[0] == REPORT_LUNS) {
-		u8 *report_lun_data = (u8 *)hba->copy_buffer;
-
-		count = STEX_EXTRA_SIZE;
-		stex_internal_copy(ccb->cmd, report_lun_data,
-			&count, ccb->sg_count, ST_FROM_CMD);
-		if (report_lun_data[2] || report_lun_data[3]) {
-			report_lun_data[2] = 0x00;
-			report_lun_data[3] = 0x08;
-			stex_internal_copy(ccb->cmd, report_lun_data,
-				&count, ccb->sg_count, ST_TO_CMD);
-		}
 	}
 }
 
@@ -995,6 +993,11 @@
 	u32 data;
 	int result = SUCCESS;
 	unsigned long flags;
+
+	printk(KERN_INFO DRV_NAME
+		"(%s): aborting command\n", pci_name(hba->pdev));
+	scsi_print_command(cmd);
+
 	base = hba->mmio_base;
 	spin_lock_irqsave(host->host_lock, flags);
 	if (tag < host->can_queue && hba->ccb[tag].cmd == cmd)
@@ -1051,7 +1054,12 @@
 	pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl);
 	pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET;
 	pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
-	msleep(1);
+
+	/*
+	 * 1 ms may be enough for 8-port controllers. But 16-port controllers
+	 * require more time to finish bus reset. Use 100 ms here for safety
+	 */
+	msleep(100);
 	pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
 	pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
 
@@ -1075,6 +1083,10 @@
 	unsigned long before;
 	hba = (struct st_hba *) &cmd->device->host->hostdata[0];
 
+	printk(KERN_INFO DRV_NAME
+		"(%s): resetting host\n", pci_name(hba->pdev));
+	scsi_print_command(cmd);
+
 	hba->mu_status = MU_STATE_RESETTING;
 
 	if (hba->cardtype == st_shasta)
@@ -1194,7 +1206,7 @@
 		goto out_scsi_host_put;
 	}
 
-	hba->mmio_base = ioremap(pci_resource_start(pdev, 0),
+	hba->mmio_base = ioremap_nocache(pci_resource_start(pdev, 0),
 		pci_resource_len(pdev, 0));
 	if ( !hba->mmio_base) {
 		printk(KERN_ERR DRV_NAME "(%s): memory map failed\n",
@@ -1229,12 +1241,18 @@
 	hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE;
 	hba->mu_status = MU_STATE_STARTING;
 
-	/* firmware uses id/lun pair for a logical drive, but lun would be
-	   always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use
-	   channel to map lun here */
-	host->max_channel = ST_MAX_LUN_PER_TARGET - 1;
-	host->max_id = ST_MAX_TARGET_NUM;
-	host->max_lun = 1;
+	if (hba->cardtype == st_shasta) {
+		host->max_lun = 8;
+		host->max_id = 16 + 1;
+	} else if (hba->cardtype == st_yosemite) {
+		host->max_lun = 128;
+		host->max_id = 1 + 1;
+	} else {
+		/* st_vsc and st_vsc1 */
+		host->max_lun = 1;
+		host->max_id = 128 + 1;
+	}
+	host->max_channel = 0;
 	host->unique_id = host->host_no;
 	host->max_cmd_len = STEX_CDB_LENGTH;
 
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 1a9a24b..00d1255 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -167,8 +167,9 @@
 	ignore_char:
 		status = readb(uap->port.membase + UART01x_FR);
 	}
+	spin_unlock(&port->lock);
 	tty_flip_buffer_push(tty);
-	return;
+	spin_lock(&port->lock);
 }
 
 static void pl010_tx_chars(struct uart_amba_port *uap)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 44639e7..954073c 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -153,8 +153,9 @@
 	ignore_char:
 		status = readw(uap->port.membase + UART01x_FR);
 	}
+	spin_unlock(&uap->port.lock);
 	tty_flip_buffer_push(tty);
-	return;
+	spin_lock(&uap->port.lock);
 }
 
 static void pl011_tx_chars(struct uart_amba_port *uap)
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index 698763b..8721afe 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -589,7 +589,7 @@
 	return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
-extern struct uart_driver ks8695_reg;
+static struct uart_driver ks8695_reg;
 
 static struct console ks8695_console = {
 	.name		= SERIAL_KS8695_DEVNAME,
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index e35d9ab..b45ba53 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -30,9 +30,9 @@
 sunserial_console_termios(struct console *con)
 {
 	char mode[16], buf[16], *s;
-	char *mode_prop = "ttyX-mode";
-	char *cd_prop = "ttyX-ignore-cd";
-	char *dtr_prop = "ttyX-rts-dtr-off";
+	char mode_prop[] = "ttyX-mode";
+	char cd_prop[]   = "ttyX-ignore-cd";
+	char dtr_prop[]  = "ttyX-rts-dtr-off";
 	char *ssp_console_modes_prop = "ssp-console-modes";
 	int baud, bits, stop, cflag;
 	char parity;
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 0985193..15b6e1c 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1239,7 +1239,7 @@
 #define SUNZILOG_CONSOLE()	(NULL)
 #endif
 
-static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
+static void __devinit sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
 {
 	int baud, brg;
 
@@ -1259,7 +1259,7 @@
 }
 
 #ifdef CONFIG_SERIO
-static void __init sunzilog_register_serio(struct uart_sunzilog_port *up)
+static void __devinit sunzilog_register_serio(struct uart_sunzilog_port *up)
 {
 	struct serio *serio = &up->serio;
 
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index e277258..8969e42 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1681,7 +1681,7 @@
 	spin_unlock_irq (&hcd_root_hub_lock);
 
 #ifdef CONFIG_PM
-	flush_workqueue(ksuspend_usb_wq);
+	cancel_work_sync(&hcd->wakeup_work);
 #endif
 
 	mutex_lock(&usb_bus_list_lock);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index caaa46f..24f10a1 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1158,6 +1158,30 @@
 	}
 }
 
+#ifdef	CONFIG_USB_SUSPEND
+
+static void usb_stop_pm(struct usb_device *udev)
+{
+	/* Synchronize with the ksuspend thread to prevent any more
+	 * autosuspend requests from being submitted, and decrement
+	 * the parent's count of unsuspended children.
+	 */
+	usb_pm_lock(udev);
+	if (udev->parent && !udev->discon_suspended)
+		usb_autosuspend_device(udev->parent);
+	usb_pm_unlock(udev);
+
+	/* Stop any autosuspend requests already submitted */
+	cancel_rearming_delayed_work(&udev->autosuspend);
+}
+
+#else
+
+static inline void usb_stop_pm(struct usb_device *udev)
+{ }
+
+#endif
+
 /**
  * usb_disconnect - disconnect a device (usbcore-internal)
  * @pdev: pointer to device being disconnected
@@ -1224,13 +1248,7 @@
 	*pdev = NULL;
 	spin_unlock_irq(&device_state_lock);
 
-	/* Decrement the parent's count of unsuspended children */
-	if (udev->parent) {
-		usb_pm_lock(udev);
-		if (!udev->discon_suspended)
-			usb_autosuspend_device(udev->parent);
-		usb_pm_unlock(udev);
-	}
+	usb_stop_pm(udev);
 
 	put_device(&udev->dev);
 }
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 80627b6..4a6299b 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -184,10 +184,6 @@
 
 	udev = to_usb_device(dev);
 
-#ifdef	CONFIG_USB_SUSPEND
-	cancel_delayed_work(&udev->autosuspend);
-	flush_workqueue(ksuspend_usb_wq);
-#endif
 	usb_destroy_configuration(udev);
 	usb_put_hcd(bus_to_hcd(udev->bus));
 	kfree(udev->product);
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index bd30aba..731d7a5 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1286,34 +1286,36 @@
 	if (regno >= fb->cmap.len || regno > 255)
 		return -EINVAL;
 
-	switch (fb->var.bits_per_pixel) {
-	case 8:
+	if (fb->var.bits_per_pixel <= 8) {
 		outb(regno, 0x3c8);
 
 		outb(red >> 10, 0x3c9);
 		outb(green >> 10, 0x3c9);
 		outb(blue >> 10, 0x3c9);
-		break;
-	case 16:
-		((u32 *) fb->pseudo_palette)[regno] =
+	} else if (regno < 16) {
+		switch (fb->var.bits_per_pixel) {
+		case 16:
+			((u32 *) fb->pseudo_palette)[regno] =
 				((red & 0xf800)) | ((green & 0xfc00) >> 5) |
 				((blue & 0xf800) >> 11);
-		break;
-	case 24:
-		((u32 *) fb->pseudo_palette)[regno] =
+			break;
+		case 24:
+			((u32 *) fb->pseudo_palette)[regno] =
 				((red & 0xff00) << 8) | ((green & 0xff00)) |
 				((blue & 0xff00) >> 8);
-		break;
+			break;
 #ifdef NO_32BIT_SUPPORT_YET
-	case 32:
-		((u32 *) fb->pseudo_palette)[regno] =
+		case 32:
+			((u32 *) fb->pseudo_palette)[regno] =
 				((transp & 0xff00) << 16) | ((red & 0xff00) << 8) |
 				((green & 0xff00)) | ((blue & 0xff00) >> 8);
-		break;
+			break;
 #endif
-	default:
-		return 1;
+		default:
+			return 1;
+		}
 	}
+
 	return 0;
 }
 
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 2dac3ad..2c55dd9 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -17,6 +17,8 @@
 #include <linux/rxrpc.h>
 #include <linux/key.h>
 #include <linux/workqueue.h>
+#include <linux/sched.h>
+
 #include "afs.h"
 #include "afs_vl.h"
 
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 0c542ec..00eee87 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -168,7 +168,7 @@
 	return dreq;
 }
 
-static void nfs_direct_req_release(struct kref *kref)
+static void nfs_direct_req_free(struct kref *kref)
 {
 	struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref);
 
@@ -177,6 +177,11 @@
 	kmem_cache_free(nfs_direct_cachep, dreq);
 }
 
+static void nfs_direct_req_release(struct nfs_direct_req *dreq)
+{
+	kref_put(&dreq->kref, nfs_direct_req_free);
+}
+
 /*
  * Collects and returns the final error value/byte-count.
  */
@@ -196,7 +201,6 @@
 		result = dreq->count;
 
 out:
-	kref_put(&dreq->kref, nfs_direct_req_release);
 	return (ssize_t) result;
 }
 
@@ -214,7 +218,7 @@
 	}
 	complete_all(&dreq->completion);
 
-	kref_put(&dreq->kref, nfs_direct_req_release);
+	nfs_direct_req_release(dreq);
 }
 
 /*
@@ -369,6 +373,7 @@
 	if (!result)
 		result = nfs_direct_wait(dreq);
 	rpc_clnt_sigunmask(clnt, &oldset);
+	nfs_direct_req_release(dreq);
 
 	return result;
 }
@@ -716,6 +721,7 @@
 	if (!result)
 		result = nfs_direct_wait(dreq);
 	rpc_clnt_sigunmask(clnt, &oldset);
+	nfs_direct_req_release(dreq);
 
 	return result;
 }
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 074791c..b532a73 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -140,7 +140,7 @@
 		if (!ni->name)
 			return -ENOMEM;
 		memcpy(ni->name, na->name, i);
-		ni->name[i] = 0;
+		ni->name[na->name_len] = 0;
 	}
 	return 0;
 }
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 3b481d5..9345a46 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -179,7 +179,7 @@
 			return ret;
 	}
 
-	ret = vmtruncate(inode, size);
+	ret = vmtruncate(inode, newsize);
 
 	return ret;
 }
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 4475588..7361861 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -701,7 +701,7 @@
 			else if (buffer_delay(bh))
 				acceptable = (type == IOMAP_DELAY);
 			else if (buffer_dirty(bh) && buffer_mapped(bh))
-				acceptable = (type == 0);
+				acceptable = (type == IOMAP_NEW);
 			else
 				break;
 		} while ((bh = bh->b_this_page) != head);
@@ -810,7 +810,7 @@
 			page_dirty--;
 			count++;
 		} else {
-			type = 0;
+			type = IOMAP_NEW;
 			if (buffer_mapped(bh) && all_bh && startio) {
 				lock_buffer(bh);
 				xfs_add_to_ioend(inode, bh, offset,
@@ -968,8 +968,8 @@
 
 	bh = head = page_buffers(page);
 	offset = page_offset(page);
-	flags = -1;
-	type = IOMAP_READ;
+	flags = BMAPI_READ;
+	type = IOMAP_NEW;
 
 	/* TODO: cleanup count and page_dirty */
 
@@ -999,14 +999,14 @@
 		 *
 		 * Third case, an unmapped buffer was found, and we are
 		 * in a path where we need to write the whole page out.
- 		 */
+		 */
 		if (buffer_unwritten(bh) || buffer_delay(bh) ||
 		    ((buffer_uptodate(bh) || PageUptodate(page)) &&
 		     !buffer_mapped(bh) && (unmapped || startio))) {
-		     	/*
+			/*
 			 * Make sure we don't use a read-only iomap
 			 */
-		     	if (flags == BMAPI_READ)
+			if (flags == BMAPI_READ)
 				iomap_valid = 0;
 
 			if (buffer_unwritten(bh)) {
@@ -1055,7 +1055,7 @@
 			 * That means it must already have extents allocated
 			 * underneath it. Map the extent by reading it.
 			 */
-			if (!iomap_valid || type != IOMAP_READ) {
+			if (!iomap_valid || flags != BMAPI_READ) {
 				flags = BMAPI_READ;
 				size = xfs_probe_cluster(inode, page, bh,
 								head, 1);
@@ -1066,7 +1066,15 @@
 				iomap_valid = xfs_iomap_valid(&iomap, offset);
 			}
 
-			type = IOMAP_READ;
+			/*
+			 * We set the type to IOMAP_NEW in case we are doing a
+			 * small write at EOF that is extending the file but
+			 * without needing an allocation. We need to update the
+			 * file size on I/O completion in this case so it is
+			 * the same case as having just allocated a new extent
+			 * that we are writing into for the first time.
+			 */
+			type = IOMAP_NEW;
 			if (!test_and_set_bit(BH_Lock, &bh->b_state)) {
 				ASSERT(buffer_mapped(bh));
 				if (iomap_valid)
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
index 4b6ef7f..3a0cbeb 100644
--- a/include/asm-alpha/bitops.h
+++ b/include/asm-alpha/bitops.h
@@ -313,32 +313,29 @@
  * fls: find last bit set.
  */
 #if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
-static inline int fls(int word)
+static inline int fls64(unsigned long word)
 {
-	return 64 - __kernel_ctlz(word & 0xffffffff);
+	return 64 - __kernel_ctlz(word);
 }
 #else
-#include <asm-generic/bitops/fls.h>
-#endif
-#include <asm-generic/bitops/fls64.h>
+extern const unsigned char __flsm1_tab[256];
 
-/* Compute powers of two for the given integer.  */
-static inline long floor_log2(unsigned long word)
+static inline int fls64(unsigned long x)
 {
-#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
-	return 63 - __kernel_ctlz(word);
-#else
-	long bit;
-	for (bit = -1; word ; bit++)
-		word >>= 1;
-	return bit;
-#endif
+	unsigned long t, a, r;
+
+	t = __kernel_cmpbge (x, 0x0101010101010101);
+	a = __flsm1_tab[t];
+	t = __kernel_extbl (x, a);
+	r = a*8 + __flsm1_tab[t] + (x != 0);
+
+	return r;
 }
+#endif
 
-static inline long ceil_log2(unsigned long word)
+static inline int fls(int x)
 {
-	long bit = floor_log2(word);
-	return bit + (word > (1UL << bit));
+	return fls64((unsigned int) x);
 }
 
 /*
@@ -353,9 +350,20 @@
 	return __kernel_ctpop(w);
 }
 
-#define hweight32(x)	(unsigned int) hweight64((x) & 0xfffffffful)
-#define hweight16(x)	(unsigned int) hweight64((x) & 0xfffful)
-#define hweight8(x)	(unsigned int) hweight64((x) & 0xfful)
+static inline unsigned int hweight32(unsigned int w)
+{
+	return hweight64(w);
+}
+
+static inline unsigned int hweight16(unsigned int w)
+{
+	return hweight64(w & 0xffff);
+}
+
+static inline unsigned int hweight8(unsigned int w)
+{
+	return hweight64(w & 0xff);
+}
 #else
 #include <asm-generic/bitops/hweight.h>
 #endif
diff --git a/include/asm-alpha/thread_info.h b/include/asm-alpha/thread_info.h
index f4defc2..48a22e3 100644
--- a/include/asm-alpha/thread_info.h
+++ b/include/asm-alpha/thread_info.h
@@ -76,12 +76,14 @@
 #define TIF_UAC_NOFIX		7
 #define TIF_UAC_SIGBUS		8
 #define TIF_MEMDIE		9
+#define TIF_RESTORE_SIGMASK	10	/* restore signal mask in do_signal */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 
 /* Work to do on interrupt/exception return.  */
 #define _TIF_WORK_MASK		(_TIF_NOTIFY_RESUME	\
diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
index e58a427..29bf2fd 100644
--- a/include/asm-alpha/unistd.h
+++ b/include/asm-alpha/unistd.h
@@ -233,6 +233,20 @@
 #define __NR_osf_memcntl	260	/* not implemented */
 #define __NR_osf_fdatasync	261	/* not implemented */
 
+/*
+ * Ignore legacy syscalls that we don't use.
+ */
+#define __IGNORE_alarm
+#define __IGNORE_creat
+#define __IGNORE_getegid
+#define __IGNORE_geteuid
+#define __IGNORE_getgid
+#define __IGNORE_getpid
+#define __IGNORE_getppid
+#define __IGNORE_getuid
+#define __IGNORE_pause
+#define __IGNORE_time
+#define __IGNORE_utime
 
 /*
  * Linux-specific system calls begin at 300
@@ -387,10 +401,42 @@
 #define __NR_inotify_init		444
 #define __NR_inotify_add_watch		445
 #define __NR_inotify_rm_watch		446
+#define __NR_fdatasync			447
+#define __NR_kexec_load			448
+#define __NR_migrate_pages		449
+#define __NR_openat			450
+#define __NR_mkdirat			451
+#define __NR_mknodat			452
+#define __NR_fchownat			453
+#define __NR_futimesat			454
+#define __NR_fstatat64			455
+#define __NR_unlinkat			456
+#define __NR_renameat			457
+#define __NR_linkat			458
+#define __NR_symlinkat			459
+#define __NR_readlinkat			460
+#define __NR_fchmodat			461
+#define __NR_faccessat			462
+#define __NR_pselect6			463
+#define __NR_ppoll			464
+#define __NR_unshare			465
+#define __NR_set_robust_list		466
+#define __NR_get_robust_list		467
+#define __NR_splice			468
+#define __NR_sync_file_range		469
+#define __NR_tee			470
+#define __NR_vmsplice			471
+#define __NR_move_pages			472
+#define __NR_getcpu			473
+#define __NR_epoll_pwait		474
+#define __NR_utimensat			475
+#define __NR_signalfd			476
+#define __NR_timerfd			477
+#define __NR_eventfd			478
 
 #ifdef __KERNEL__
 
-#define NR_SYSCALLS			447
+#define NR_SYSCALLS			479
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-arm/arch-ixp4xx/nas100d.h b/include/asm-arm/arch-ixp4xx/nas100d.h
index 84467a5..131e0a1 100644
--- a/include/asm-arm/arch-ixp4xx/nas100d.h
+++ b/include/asm-arm/arch-ixp4xx/nas100d.h
@@ -10,7 +10,7 @@
  * based on ixdp425.h:
  *	Copyright 2004 (c) MontaVista, Software, Inc.
  *
- * This file is licensed under  the terms of the GNU General Public
+ * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
@@ -36,31 +36,11 @@
 #define NAS100D_PCI_INTD_PIN	8
 #define NAS100D_PCI_INTE_PIN	7
 
-/* GPIO */
-
-#define NAS100D_GPIO0           0
-#define NAS100D_GPIO1           1
-#define NAS100D_GPIO2           2
-#define NAS100D_GPIO3           3
-#define NAS100D_GPIO4           4
-#define NAS100D_GPIO5           5
-#define NAS100D_GPIO6           6
-#define NAS100D_GPIO7           7
-#define NAS100D_GPIO8           8
-#define NAS100D_GPIO9           9
-#define NAS100D_GPIO10          10
-#define NAS100D_GPIO11          11
-#define NAS100D_GPIO12          12
-#define NAS100D_GPIO13          13
-#define NAS100D_GPIO14          14
-#define NAS100D_GPIO15          15
-
-
 /* Buttons */
 
-#define NAS100D_PB_GPIO         NAS100D_GPIO14
-#define NAS100D_RB_GPIO         NAS100D_GPIO4
-#define NAS100D_PO_GPIO         NAS100D_GPIO12   /* power off */
+#define NAS100D_PB_GPIO         14
+#define NAS100D_RB_GPIO         4
+#define NAS100D_PO_GPIO         12   /* power off */
 
 #define NAS100D_PB_IRQ          IRQ_IXP4XX_GPIO14
 #define NAS100D_RB_IRQ          IRQ_IXP4XX_GPIO4
diff --git a/include/asm-arm/arch-ixp4xx/nslu2.h b/include/asm-arm/arch-ixp4xx/nslu2.h
index 6b437f7..850fdc5 100644
--- a/include/asm-arm/arch-ixp4xx/nslu2.h
+++ b/include/asm-arm/arch-ixp4xx/nslu2.h
@@ -9,7 +9,7 @@
  * based on ixdp425.h:
  *	Copyright 2004 (c) MontaVista, Software, Inc.
  *
- * This file is licensed under  the terms of the GNU General Public
+ * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
@@ -34,36 +34,14 @@
 #define NSLU2_PCI_INTC_PIN	9
 #define NSLU2_PCI_INTD_PIN	8
 
-
 /* NSLU2 Timer */
 #define NSLU2_FREQ 66000000
-#define NSLU2_CLOCK_TICK_RATE (((NSLU2_FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
-#define NSLU2_CLOCK_TICKS_PER_USEC ((NSLU2_CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
-
-/* GPIO */
-
-#define NSLU2_GPIO0		0
-#define NSLU2_GPIO1		1
-#define NSLU2_GPIO2		2
-#define NSLU2_GPIO3		3
-#define NSLU2_GPIO4		4
-#define NSLU2_GPIO5		5
-#define NSLU2_GPIO6		6
-#define NSLU2_GPIO7		7
-#define NSLU2_GPIO8		8
-#define NSLU2_GPIO9		9
-#define NSLU2_GPIO10		10
-#define NSLU2_GPIO11		11
-#define NSLU2_GPIO12		12
-#define NSLU2_GPIO13		13
-#define NSLU2_GPIO14		14
-#define NSLU2_GPIO15		15
 
 /* Buttons */
 
-#define NSLU2_PB_GPIO		NSLU2_GPIO5
-#define NSLU2_PO_GPIO		NSLU2_GPIO8	/* power off */
-#define NSLU2_RB_GPIO		NSLU2_GPIO12
+#define NSLU2_PB_GPIO		5
+#define NSLU2_PO_GPIO		8	/* power off */
+#define NSLU2_RB_GPIO		12
 
 #define NSLU2_PB_IRQ		IRQ_IXP4XX_GPIO5
 #define NSLU2_RB_IRQ		IRQ_IXP4XX_GPIO12
@@ -79,16 +57,16 @@
 
 /* LEDs */
 
-#define NSLU2_LED_RED		NSLU2_GPIO0
-#define NSLU2_LED_GRN		NSLU2_GPIO1
+#define NSLU2_LED_RED_GPIO	0
+#define NSLU2_LED_GRN_GPIO	1
 
-#define NSLU2_LED_RED_BM	(1L << NSLU2_LED_RED)
-#define NSLU2_LED_GRN_BM	(1L << NSLU2_LED_GRN)
+#define NSLU2_LED_RED_BM	(1L << NSLU2_LED_RED_GPIO)
+#define NSLU2_LED_GRN_BM	(1L << NSLU2_LED_GRN_GPIO)
 
-#define NSLU2_LED_DISK1		NSLU2_GPIO3
-#define NSLU2_LED_DISK2		NSLU2_GPIO2
+#define NSLU2_LED_DISK1_GPIO	3
+#define NSLU2_LED_DISK2_GPIO	2
 
-#define NSLU2_LED_DISK1_BM	(1L << NSLU2_GPIO2)
-#define NSLU2_LED_DISK2_BM	(1L << NSLU2_GPIO3)
+#define NSLU2_LED_DISK1_BM	(1L << NSLU2_LED_DISK1_GPIO)
+#define NSLU2_LED_DISK2_BM	(1L << NSLU2_LED_DISK2_GPIO)
 
 
diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h
index ab194e5..2a44d3d 100644
--- a/include/asm-arm/arch-ixp4xx/platform.h
+++ b/include/asm-arm/arch-ixp4xx/platform.h
@@ -113,6 +113,7 @@
 extern void ixp4xx_map_io(void);
 extern void ixp4xx_init_irq(void);
 extern void ixp4xx_sys_init(void);
+extern void ixp4xx_timer_init(void);
 extern struct sys_timer ixp4xx_timer;
 extern void ixp4xx_pci_preinit(void);
 struct pci_sys_data;
diff --git a/include/asm-arm/arch-s3c2410/map.h b/include/asm-arm/arch-s3c2410/map.h
index 4505aef..19e77f0 100644
--- a/include/asm-arm/arch-s3c2410/map.h
+++ b/include/asm-arm/arch-s3c2410/map.h
@@ -153,6 +153,10 @@
 #define S3C2440_PA_AC97	   (0x5B000000)
 #define S3C2440_SZ_AC97	   SZ_1M
 
+/* S3C2443 High-speed SD/MMC */
+#define S3C2443_PA_HSMMC   (0x4A800000)
+#define S3C2443_SZ_HSMMC   (256)
+
 /* ISA style IO, for each machine to sort out mappings for, if it
  * implements it. We reserve two 16M regions for ISA.
  */
diff --git a/include/asm-arm/arch-s3c2410/regs-gpioj.h b/include/asm-arm/arch-s3c2410/regs-gpioj.h
index 02131a5..0362332 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpioj.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpioj.h
@@ -98,5 +98,9 @@
 #define S3C2440_GPJ12_OUTP      (0x01 << 24)
 #define S3C2440_GPJ12_CAMRESET  (0x02 << 24)
 
+#define S3C2443_GPJ13		S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 13)
+#define S3C2443_GPJ14		S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 14)
+#define S3C2443_GPJ15		S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 15)
+
 #endif	/* __ASM_ARCH_REGS_GPIOJ_H */
 
diff --git a/include/asm-arm/arch-s3c2410/regs-s3c2412.h b/include/asm-arm/arch-s3c2410/regs-s3c2412.h
new file mode 100644
index 0000000..8ca6a3b
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/regs-s3c2412.h
@@ -0,0 +1,21 @@
+/* linux/include/asm-arm/arch-s3c2410/regs-s3c2412.h
+ *
+ * Copyright 2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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.
+ *
+ * S3C2412 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2412_H
+#define __ASM_ARCH_REGS_S3C2412_H "s3c2412"
+
+#define S3C2412_SWRST		(S3C24XX_VA_CLKPWR + 0x30)
+#define S3C2412_SWRST_RESET	(0x533C2412)
+
+#endif	/* __ASM_ARCH_REGS_S3C2412_H */
+
diff --git a/include/asm-arm/ioctls.h b/include/asm-arm/ioctls.h
index bb9a7aa..a91d8a1 100644
--- a/include/asm-arm/ioctls.h
+++ b/include/asm-arm/ioctls.h
@@ -46,6 +46,10 @@
 #define TIOCSBRK	0x5427  /* BSD compatibility */
 #define TIOCCBRK	0x5428  /* BSD compatibility */
 #define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TCGETS2		_IOR('T',0x2A, struct termios2)
+#define TCSETS2		_IOW('T',0x2B, struct termios2)
+#define TCSETSW2	_IOW('T',0x2C, struct termios2)
+#define TCSETSF2	_IOW('T',0x2D, struct termios2)
 #define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
 #define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
 
diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
index fd2f9bf..c59fad1 100644
--- a/include/asm-arm/mach/arch.h
+++ b/include/asm-arm/mach/arch.h
@@ -49,7 +49,7 @@
  */
 #define MACHINE_START(_type,_name)			\
 static const struct machine_desc __mach_desc_##_type	\
- __attribute_used__					\
+ __used							\
  __attribute__((__section__(".arch.info.init"))) = {	\
 	.nr		= MACH_TYPE_##_type,		\
 	.name		= _name,
diff --git a/include/asm-arm/setup.h b/include/asm-arm/setup.h
index e540739..7bbf105 100644
--- a/include/asm-arm/setup.h
+++ b/include/asm-arm/setup.h
@@ -185,7 +185,7 @@
 
 #ifdef __KERNEL__
 
-#define __tag __attribute_used__ __attribute__((__section__(".taglist.init")))
+#define __tag __used __attribute__((__section__(".taglist.init")))
 #define __tagtable(tag, fn) \
 static struct tagtable __tagtable_##fn __tag = { tag, fn }
 
@@ -218,7 +218,7 @@
 };
 
 #define __early_param(name,fn)					\
-static struct early_params __early_##fn __attribute_used__	\
+static struct early_params __early_##fn __used			\
 __attribute__((__section__(".early_param.init"))) = { name, fn }
 
 #endif  /*  __KERNEL__  */
diff --git a/include/asm-arm/termbits.h b/include/asm-arm/termbits.h
index a3f4fe1..f784d11 100644
--- a/include/asm-arm/termbits.h
+++ b/include/asm-arm/termbits.h
@@ -15,6 +15,17 @@
 	cc_t c_cc[NCCS];		/* control characters */
 };
 
+struct termios2 {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+	speed_t c_ispeed;		/* input speed */
+	speed_t c_ospeed;		/* output speed */
+};
+
 struct ktermios {
 	tcflag_t c_iflag;		/* input mode flags */
 	tcflag_t c_oflag;		/* output mode flags */
@@ -128,6 +139,7 @@
 #define HUPCL	0002000
 #define CLOCAL	0004000
 #define CBAUDEX 0010000
+#define    BOTHER 0010000
 #define    B57600 0010001
 #define   B115200 0010002
 #define   B230400 0010003
@@ -143,10 +155,12 @@
 #define  B3000000 0010015
 #define  B3500000 0010016
 #define  B4000000 0010017
-#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CIBAUD	  002003600000		/* input baud rate */
 #define CMSPAR    010000000000		/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000		/* flow control */
 
+#define IBSHIFT	   16
+
 /* c_lflag bits */
 #define ISIG	0000001
 #define ICANON	0000002
diff --git a/include/asm-arm/termios.h b/include/asm-arm/termios.h
index 329c324..293e3f1 100644
--- a/include/asm-arm/termios.h
+++ b/include/asm-arm/termios.h
@@ -82,8 +82,10 @@
 	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
 })
 
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif	/* __KERNEL__ */
 
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
index ccd0de0..71be4fd 100644
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -138,6 +138,19 @@
 # define v6wbi_always_flags	(-1UL)
 #endif
 
+#ifdef CONFIG_CPU_TLB_V7
+# define v7wbi_possible_flags	v6wbi_tlb_flags
+# define v7wbi_always_flags	v6wbi_tlb_flags
+# ifdef _TLB
+#  define MULTI_TLB 1
+# else
+#  define _TLB v7wbi
+# endif
+#else
+# define v7wbi_possible_flags	0
+# define v7wbi_always_flags	(-1UL)
+#endif
+
 #ifndef _TLB
 #error Unknown TLB model
 #endif
diff --git a/include/asm-arm26/setup.h b/include/asm-arm26/setup.h
index 10fd07c..e825623 100644
--- a/include/asm-arm26/setup.h
+++ b/include/asm-arm26/setup.h
@@ -173,7 +173,7 @@
 	int (*parse)(const struct tag *);
 };
 
-#define __tag __attribute_used__ __attribute__((__section__(".taglist")))
+#define __tag __used __attribute__((__section__(".taglist")))
 #define __tagtable(tag, fn) \
 static struct tagtable __tagtable_##fn __tag = { tag, fn }
 
diff --git a/include/asm-m68k/mmzone.h b/include/asm-m68k/mmzone.h
new file mode 100644
index 0000000..e1f1ec7
--- /dev/null
+++ b/include/asm-m68k/mmzone.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_M68K_MMZONE_H_
+#define _ASM_M68K_MMZONE_H_
+
+extern pg_data_t pg_data_map[];
+
+#define NODE_DATA(nid)		(&pg_data_map[nid])
+#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
+
+#endif /* _ASM_M68K_MMZONE_H_ */
diff --git a/include/asm-m68k/module.h b/include/asm-m68k/module.h
index c6d75af..382d20a 100644
--- a/include/asm-m68k/module.h
+++ b/include/asm-m68k/module.h
@@ -1,7 +1,39 @@
 #ifndef _ASM_M68K_MODULE_H
 #define _ASM_M68K_MODULE_H
-struct mod_arch_specific { };
+
+struct mod_arch_specific {
+	struct m68k_fixup_info *fixup_start, *fixup_end;
+};
+
+#define MODULE_ARCH_INIT {				\
+	.fixup_start		= __start_fixup,	\
+	.fixup_end		= __stop_fixup,		\
+}
+
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+
+
+enum m68k_fixup_type {
+	m68k_fixup_memoffset,
+	m68k_fixup_vnode_shift,
+};
+
+struct m68k_fixup_info {
+	enum m68k_fixup_type type;
+	void *addr;
+};
+
+#define m68k_fixup(type, addr)			\
+	"	.section \".m68k_fixup\",\"aw\"\n"	\
+	"	.long " #type "," #addr "\n"	\
+	"	.previous\n"
+
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
+
+struct module;
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+			 struct m68k_fixup_info *end);
+
 #endif /* _ASM_M68K_MODULE_H */
diff --git a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h
index 61e4406..b5b78c0 100644
--- a/include/asm-m68k/motorola_pgtable.h
+++ b/include/asm-m68k/motorola_pgtable.h
@@ -130,7 +130,7 @@
 #define pte_present(pte)	(pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 #define pte_clear(mm,addr,ptep)		({ pte_val(*(ptep)) = 0; })
 
-#define pte_page(pte)		(mem_map + ((unsigned long)(__va(pte_val(pte)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pte_page(pte)		virt_to_page(__va(pte_val(pte)))
 #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
 #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 
@@ -143,7 +143,7 @@
 	while (--__i >= 0)			\
 		*__ptr++ = 0;			\
 })
-#define pmd_page(pmd)		(mem_map + ((unsigned long)(__va(pmd_val(pmd)) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pmd_page(pmd)		virt_to_page(__va(pmd_val(pmd)))
 
 
 #define pgd_none(pgd)		(!pgd_val(pgd))
@@ -223,10 +223,10 @@
 	return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
-#define pte_offset_map(pmdp,address) ((pte_t *)kmap(pmd_page(*pmdp)) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+#define pte_offset_map(pmdp,address) ((pte_t *)__pmd_page(*pmdp) + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
 #define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address)
-#define pte_unmap(pte) kunmap(pte)
-#define pte_unmap_nested(pte) kunmap(pte)
+#define pte_unmap(pte)		((void)0)
+#define pte_unmap_nested(pte)	((void)0)
 
 /*
  * Allocate and free page tables. The xxx_kernel() versions are
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h
index fcc165d..9e6d0d6 100644
--- a/include/asm-m68k/page.h
+++ b/include/asm-m68k/page.h
@@ -27,6 +27,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <asm/module.h>
+
 #define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
 #define free_user_page(page, addr)	free_page(addr)
 
@@ -114,18 +116,33 @@
 
 #ifndef __ASSEMBLY__
 
+extern unsigned long m68k_memoffset;
+
 #ifndef CONFIG_SUN3
 
 #define WANT_PAGE_VIRTUAL
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-extern unsigned long m68k_memoffset;
 
-#define __pa(vaddr)		((unsigned long)(vaddr)+m68k_memoffset)
-#define __va(paddr)		((void *)((unsigned long)(paddr)-m68k_memoffset))
-#else
-#define __pa(vaddr)		virt_to_phys((void *)(vaddr))
-#define __va(paddr)		phys_to_virt((unsigned long)(paddr))
-#endif
+static inline unsigned long ___pa(void *vaddr)
+{
+	unsigned long paddr;
+	asm (
+		"1:	addl #0,%0\n"
+		m68k_fixup(%c2, 1b+2)
+		: "=r" (paddr)
+		: "0" (vaddr), "i" (m68k_fixup_memoffset));
+	return paddr;
+}
+#define __pa(vaddr)	___pa((void *)(vaddr))
+static inline void *__va(unsigned long paddr)
+{
+	void *vaddr;
+	asm (
+		"1:	subl #0,%0\n"
+		m68k_fixup(%c2, 1b+2)
+		: "=r" (vaddr)
+		: "0" (paddr), "i" (m68k_fixup_memoffset));
+	return vaddr;
+}
 
 #else	/* !CONFIG_SUN3 */
 /* This #define is a horrible hack to suppress lots of warnings. --m */
@@ -161,11 +178,47 @@
 #define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT)
 
-#define virt_to_page(kaddr)	(mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT))
-#define page_to_virt(page)	((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+extern int m68k_virt_to_node_shift;
 
-#define pfn_to_page(pfn)	virt_to_page(pfn_to_virt(pfn))
-#define page_to_pfn(page)	virt_to_pfn(page_to_virt(page))
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
+#define __virt_to_node(addr)	(&pg_data_map[0])
+#else
+extern struct pglist_data *pg_data_table[];
+
+static inline __attribute_const__ int __virt_to_node_shift(void)
+{
+	int shift;
+
+	asm (
+		"1:	moveq	#0,%0\n"
+		m68k_fixup(%c1, 1b)
+		: "=d" (shift)
+		: "i" (m68k_fixup_vnode_shift));
+	return shift;
+}
+
+#define __virt_to_node(addr)	(pg_data_table[(unsigned long)(addr) >> __virt_to_node_shift()])
+#endif
+
+#define virt_to_page(addr) ({						\
+	pfn_to_page(virt_to_pfn(addr));					\
+})
+#define page_to_virt(page) ({						\
+	pfn_to_virt(page_to_pfn(page));					\
+})
+
+#define pfn_to_page(pfn) ({						\
+	unsigned long __pfn = (pfn);					\
+	struct pglist_data *pgdat;					\
+	pgdat = __virt_to_node((unsigned long)pfn_to_virt(__pfn));	\
+	pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn);		\
+})
+#define page_to_pfn(_page) ({						\
+	struct page *__p = (_page);					\
+	struct pglist_data *pgdat;					\
+	pgdat = &pg_data_map[page_to_nid(__p)];				\
+	((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn;		\
+})
 
 #define virt_addr_valid(kaddr)	((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
 #define pfn_valid(pfn)		virt_addr_valid(pfn_to_virt(pfn))
diff --git a/include/asm-m68k/pgalloc.h b/include/asm-m68k/pgalloc.h
index a9cfb4b..4cb1a57 100644
--- a/include/asm-m68k/pgalloc.h
+++ b/include/asm-m68k/pgalloc.h
@@ -8,11 +8,12 @@
 #include <asm/virtconvert.h>
 
 
-
 #ifdef CONFIG_SUN3
 #include <asm/sun3_pgalloc.h>
 #else
 #include <asm/motorola_pgalloc.h>
 #endif
 
+extern void m68k_setup_node(int node);
+
 #endif /* M68K_PGALLOC_H */
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index 555b87a..778a4c5 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -107,22 +107,7 @@
 /* 64-bit machines, beware!  SRB. */
 #define SIZEOF_PTR_LOG2			       2
 
-/*
- * Check if the addr/len goes up to the end of a physical
- * memory chunk.  Used for DMA functions.
- */
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-/*
- * It makes no sense to consider whether we cross a memory boundary if
- * we support just one physical chunk of memory.
- */
-static inline int mm_end_of_chunk(unsigned long addr, int len)
-{
-	return 0;
-}
-#else
-int mm_end_of_chunk (unsigned long addr, int len);
-#endif
+#define mm_end_of_chunk(addr, len)	0
 
 extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode);
 
diff --git a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h
index 5156a28..b9e62c1 100644
--- a/include/asm-m68k/sun3_pgtable.h
+++ b/include/asm-m68k/sun3_pgtable.h
@@ -132,8 +132,8 @@
 #define pfn_pte(pfn, pgprot) \
 ({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; })
 
-#define pte_page(pte)		(mem_map+((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT))
-#define pmd_page(pmd)		(mem_map+((__pmd_page(pmd) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define pte_page(pte)		virt_to_page(__pte_page(pte))
+#define pmd_page(pmd)		virt_to_page(__pmd_page(pmd))
 
 
 static inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); }
diff --git a/include/asm-m68k/virtconvert.h b/include/asm-m68k/virtconvert.h
index 83a87c9..dea32fb 100644
--- a/include/asm-m68k/virtconvert.h
+++ b/include/asm-m68k/virtconvert.h
@@ -8,56 +8,35 @@
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>
+#include <linux/mmzone.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#endif
-
 /*
  * Change virtual addresses to physical addresses and vv.
  */
-#ifndef CONFIG_SUN3
-extern unsigned long mm_vtop(unsigned long addr) __attribute_const__;
-extern unsigned long mm_ptov(unsigned long addr) __attribute_const__;
-#else
-static inline unsigned long mm_vtop(unsigned long vaddr)
-{
-	return __pa(vaddr);
-}
-
-static inline unsigned long mm_ptov(unsigned long paddr)
-{
-	return (unsigned long)__va(paddr);
-}
-#endif
-
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-static inline unsigned long virt_to_phys(void *vaddr)
-{
-	return (unsigned long)vaddr - PAGE_OFFSET + m68k_memory[0].addr;
-}
-
-static inline void * phys_to_virt(unsigned long paddr)
-{
-	return (void *)(paddr - m68k_memory[0].addr + PAGE_OFFSET);
-}
-#else
 static inline unsigned long virt_to_phys(void *address)
 {
-	return mm_vtop((unsigned long)address);
+	return __pa(address);
 }
 
 static inline void *phys_to_virt(unsigned long address)
 {
-	return (void *) mm_ptov(address);
+	return __va(address);
 }
-#endif
 
 /* Permanent address of a page. */
-#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
+#define page_to_phys(page) \
+	__pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT))
+#else
+#define page_to_phys(_page) ({						\
+	struct page *__page = _page;					\
+	struct pglist_data *pgdat;					\
+	pgdat = pg_data_table[page_to_nid(__page)];			\
+	page_to_pfn(__page) << PAGE_SHIFT;				\
+})
+#endif
 
 /*
  * IO bus memory addresses are 1:1 with the physical address,
diff --git a/include/asm-sh/cpu-sh4/freq.h b/include/asm-sh/cpu-sh4/freq.h
index 86564e7..39f41fc 100644
--- a/include/asm-sh/cpu-sh4/freq.h
+++ b/include/asm-sh/cpu-sh4/freq.h
@@ -24,6 +24,9 @@
 #define FRQMR1			0xffc80014
 #else
 #define FRQCR			0xffc00000
+#define FRQCR_PSTBY		0x0200
+#define FRQCR_PLLEN		0x0400
+#define FRQCR_CKOEN		0x0800
 #endif
 #define MIN_DIVISOR_NR		0
 #define MAX_DIVISOR_NR		3
diff --git a/include/asm-sh/dma.h b/include/asm-sh/dma.h
index faf3051..6034d4a 100644
--- a/include/asm-sh/dma.h
+++ b/include/asm-sh/dma.h
@@ -13,6 +13,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/wait.h>
+#include <linux/sched.h>
 #include <linux/sysdev.h>
 #include <asm/cpu/dma.h>
 
diff --git a/include/asm-sh/io.h b/include/asm-sh/io.h
index a0e55b0..aa80930 100644
--- a/include/asm-sh/io.h
+++ b/include/asm-sh/io.h
@@ -116,13 +116,13 @@
  * redefined by userlevel programs.
  */
 #ifdef __readb
-# define readb(a)	({ unsigned long r_ = __raw_readb(a); mb(); r_; })
+# define readb(a)	({ unsigned int r_ = __raw_readb(a); mb(); r_; })
 #endif
 #ifdef __raw_readw
-# define readw(a)	({ unsigned long r_ = __raw_readw(a); mb(); r_; })
+# define readw(a)	({ unsigned int r_ = __raw_readw(a); mb(); r_; })
 #endif
 #ifdef __raw_readl
-# define readl(a)	({ unsigned long r_ = __raw_readl(a); mb(); r_; })
+# define readl(a)	({ unsigned int r_ = __raw_readl(a); mb(); r_; })
 #endif
 
 #ifdef __raw_writeb
diff --git a/include/asm-sh/smp.h b/include/asm-sh/smp.h
index 71ecddf..caa7b93 100644
--- a/include/asm-sh/smp.h
+++ b/include/asm-sh/smp.h
@@ -15,7 +15,7 @@
 
 #ifdef CONFIG_SMP
 
-#include <asm/spinlock.h>
+#include <linux/spinlock.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
 
diff --git a/include/asm-sh/spinlock.h b/include/asm-sh/spinlock.h
index 2586eef..92f6e20 100644
--- a/include/asm-sh/spinlock.h
+++ b/include/asm-sh/spinlock.h
@@ -11,6 +11,7 @@
 #define __ASM_SH_SPINLOCK_H
 
 #include <asm/atomic.h>
+#include <asm/spinlock_types.h>
 
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
@@ -42,7 +43,7 @@
 
 static inline void __raw_spin_unlock(raw_spinlock_t *lock)
 {
-	assert_spin_locked(lock);
+	//assert_spin_locked(lock);
 
 	lock->lock = 0;
 }
@@ -88,6 +89,11 @@
 	__raw_spin_unlock(&rw->lock);
 }
 
+static inline int __raw_write_can_lock(raw_rwlock_t *rw)
+{
+	return (atomic_read(&rw->counter) == RW_LOCK_BIAS);
+}
+
 static inline int __raw_read_trylock(raw_rwlock_t *lock)
 {
 	atomic_t *count = (atomic_t*)lock;
diff --git a/include/asm-sh/spinlock_types.h b/include/asm-sh/spinlock_types.h
index 8c41b6c..5c58134 100644
--- a/include/asm-sh/spinlock_types.h
+++ b/include/asm-sh/spinlock_types.h
@@ -9,7 +9,9 @@
 	volatile unsigned long lock;
 } raw_spinlock_t;
 
-#define __SPIN_LOCK_UNLOCKED		{ 0 }
+#define __RAW_SPIN_LOCK_UNLOCKED	{ 1 }
+
+#include <asm/atomic.h>
 
 typedef struct {
 	raw_spinlock_t lock;
diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h
index 731fa56..bdca541 100644
--- a/include/asm-sparc/atomic.h
+++ b/include/asm-sparc/atomic.h
@@ -2,6 +2,7 @@
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
+ * Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
  *
  * Additions by Keith M Wesolowski (wesolows@foobazco.org) based
  * on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.
@@ -10,11 +11,48 @@
 #ifndef __ARCH_SPARC_ATOMIC__
 #define __ARCH_SPARC_ATOMIC__
 
+#include <linux/types.h>
 
 typedef struct { volatile int counter; } atomic_t;
 
 #ifdef __KERNEL__
 
+/* Emulate cmpxchg() the same way we emulate atomics,
+ * by hashing the object address and indexing into an array
+ * of spinlocks to get a bit of performance...
+ *
+ * See arch/sparc/lib/atomic32.c for implementation.
+ *
+ * Cribbed from <asm-parisc/atomic.h>
+ */
+#define __HAVE_ARCH_CMPXCHG	1
+
+/* bug catcher for when unsupported size is used - won't link */
+extern void __cmpxchg_called_with_bad_pointer(void);
+/* we only need to support cmpxchg of a u32 on sparc */
+extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
+
+/* don't worry...optimizer will get rid of most of this */
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
+{
+	switch(size) {
+	case 4:
+		return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_);
+	default:
+		__cmpxchg_called_with_bad_pointer();
+		break;
+	}
+	return old;
+}
+
+#define cmpxchg(ptr,o,n) ({						\
+	__typeof__(*(ptr)) _o_ = (o);					\
+	__typeof__(*(ptr)) _n_ = (n);					\
+	(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,	\
+			(unsigned long)_n_, sizeof(*(ptr)));		\
+})
+
 #define ATOMIC_INIT(i)  { (i) }
 
 extern int __atomic_add_return(int, atomic_t *);
diff --git a/include/asm-sparc64/bugs.h b/include/asm-sparc64/bugs.h
index 120422f..bf39d86 100644
--- a/include/asm-sparc64/bugs.h
+++ b/include/asm-sparc64/bugs.h
@@ -1,9 +1,8 @@
-/*  $Id: bugs.h,v 1.1 1996/12/26 13:25:20 davem Exp $
- *  include/asm-sparc64/bugs.h:  Sparc probes for various bugs.
+/* bugs.h: Sparc64 probes for various bugs.
  *
- *  Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
  */
-
+#include <asm/sstate.h>
 
 extern unsigned long loops_per_jiffy;
 
@@ -12,4 +11,5 @@
 #ifndef CONFIG_SMP
 	cpu_data(0).udelay_val = loops_per_jiffy;
 #endif
+	sstate_running();
 }
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h
index e89922d..03c385d 100644
--- a/include/asm-sparc64/cpudata.h
+++ b/include/asm-sparc64/cpudata.h
@@ -17,11 +17,11 @@
 typedef struct {
 	/* Dcache line 1 */
 	unsigned int	__softirq_pending; /* must be 1st, see rtrap.S */
-	unsigned int	__pad0_1;
-	unsigned int	__pad0_2;
-	unsigned int	__pad1;
+	unsigned int	__pad0;
 	unsigned long	clock_tick;	/* %tick's per second */
 	unsigned long	udelay_val;
+	unsigned int	__pad1;
+	unsigned int	__pad2;
 
 	/* Dcache line 2, rarely used */
 	unsigned int	dcache_size;
@@ -30,8 +30,8 @@
 	unsigned int	icache_line_size;
 	unsigned int	ecache_size;
 	unsigned int	ecache_line_size;
+	int		core_id;
 	unsigned int	__pad3;
-	unsigned int	__pad4;
 } cpuinfo_sparc;
 
 DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
@@ -76,12 +76,18 @@
 
 /* Dcache line 8: IRQ work list, and keep trap_block a power-of-2 in size.  */
 	unsigned int		irq_worklist;
-	unsigned int		__pad1;
-	unsigned long		__pad2[3];
+	unsigned int		cpu_mondo_qmask;
+	unsigned int		dev_mondo_qmask;
+	unsigned int		resum_qmask;
+	unsigned int		nonresum_qmask;
+	unsigned int		__pad2[3];
 } __attribute__((aligned(64)));
 extern struct trap_per_cpu trap_block[NR_CPUS];
 extern void init_cur_cpu_trap(struct thread_info *);
 extern void setup_tba(void);
+extern int ncpus_probed;
+
+extern unsigned long real_hard_smp_processor_id(void);
 
 struct cpuid_patch_entry {
 	unsigned int	addr;
@@ -122,6 +128,10 @@
 #define TRAP_PER_CPU_TSB_HUGE		0xd0
 #define TRAP_PER_CPU_TSB_HUGE_TEMP	0xd8
 #define TRAP_PER_CPU_IRQ_WORKLIST	0xe0
+#define TRAP_PER_CPU_CPU_MONDO_QMASK	0xe4
+#define TRAP_PER_CPU_DEV_MONDO_QMASK	0xe8
+#define TRAP_PER_CPU_RESUM_QMASK	0xec
+#define TRAP_PER_CPU_NONRESUM_QMASK	0xf0
 
 #define TRAP_BLOCK_SZ_SHIFT		8
 
@@ -192,7 +202,7 @@
  * the calculations done by the macro mid-stream.
  */
 #define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3)	\
-	ldub	[THR + TI_CPU], REG1;			\
+	lduh	[THR + TI_CPU], REG1;			\
 	sethi	%hi(__per_cpu_shift), REG3;		\
 	sethi	%hi(__per_cpu_base), REG2;		\
 	ldx	[REG3 + %lo(__per_cpu_shift)], REG3;	\
diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h
index a5558c8..4a43075 100644
--- a/include/asm-sparc64/hypervisor.h
+++ b/include/asm-sparc64/hypervisor.h
@@ -73,6 +73,8 @@
 #define HV_ENOTSUPPORTED		13 /* Function not supported       */
 #define HV_ENOMAP			14 /* No mapping found             */
 #define HV_ETOOMANY			15 /* Too many items specified     */
+#define HV_ECHANNEL			16 /* Invalid LDC channel          */
+#define HV_EBUSY			17 /* Resource busy                */
 
 /* mach_exit()
  * TRAP:	HV_FAST_TRAP
@@ -95,6 +97,10 @@
  */
 #define HV_FAST_MACH_EXIT		0x00
 
+#ifndef __ASSEMBLY__
+extern void sun4v_mach_exit(unsigned long exit_core);
+#endif
+
 /* Domain services.  */
 
 /* mach_desc()
@@ -120,7 +126,13 @@
  */
 #define HV_FAST_MACH_DESC		0x01
 
-/* mach_exit()
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mach_desc(unsigned long buffer_pa,
+				     unsigned long buf_len,
+				     unsigned long *real_buf_len);
+#endif
+
+/* mach_sir()
  * TRAP:	HV_FAST_TRAP
  * FUNCTION:	HV_FAST_MACH_SIR
  * ERRORS:	This service does not return.
@@ -135,53 +147,66 @@
  */
 #define HV_FAST_MACH_SIR		0x02
 
-/* mach_set_soft_state()
- * TRAP:	HV_FAST_TRAP
- * FUNCTION:	HV_FAST_MACH_SET_SOFT_STATE
- * ARG0:	software state
- * ARG1:	software state description pointer
- * RET0:	status
- * ERRORS:	EINVAL		software state not valid or software state
- *				description is not NULL terminated
- *		ENORADDR	software state description pointer is not a
- *				valid real address
- *		EBADALIGNED	software state description is not correctly
- *				aligned
- *
- * This allows the guest to report it's soft state to the hypervisor.  There
- * are two primary components to this state.  The first part states whether
- * the guest software is running or not.  The second containts optional
- * details specific to the software.
- *
- * The software state argument is defined below in HV_SOFT_STATE_*, and
- * indicates whether the guest is operating normally or in a transitional
- * state.
- *
- * The software state description argument is a real address of a data buffer
- * of size 32-bytes aligned on a 32-byte boundary.  It is treated as a NULL
- * terminated 7-bit ASCII string of up to 31 characters not including the
- * NULL termination.
- */
-#define HV_FAST_MACH_SET_SOFT_STATE	0x03
-#define  HV_SOFT_STATE_NORMAL		 0x01
-#define  HV_SOFT_STATE_TRANSITION	 0x02
+#ifndef __ASSEMBLY__
+extern void sun4v_mach_sir(void);
+#endif
 
-/* mach_get_soft_state()
+/* mach_set_watchdog()
  * TRAP:	HV_FAST_TRAP
- * FUNCTION:	HV_FAST_MACH_GET_SOFT_STATE
- * ARG0:	software state description pointer
+ * FUNCTION:	HV_FAST_MACH_SET_WATCHDOG
+ * ARG0:	timeout in milliseconds
  * RET0:	status
- * RET1:	software state
- * ERRORS:	ENORADDR	software state description pointer is not a
- *				valid real address
- *		EBADALIGNED	software state description is not correctly
- *				aligned
+ * RET1:	time remaining in milliseconds
  *
- * Retrieve the current value of the guest's software state.  The rules
- * for the software state pointer are the same as for mach_set_soft_state()
- * above.
+ * A guest uses this API to set a watchdog timer.  Once the gues has set
+ * the timer, it must call the timer service again either to disable or
+ * postpone the expiration.  If the timer expires before being reset or
+ * disabled, then the hypervisor take a platform specific action leading
+ * to guest termination within a bounded time period.  The platform action
+ * may include recovery actions such as reporting the expiration to a
+ * Service Processor, and/or automatically restarting the gues.
+ *
+ * The 'timeout' parameter is specified in milliseconds, however the
+ * implementated granularity is given by the 'watchdog-resolution'
+ * property in the 'platform' node of the guest's machine description.
+ * The largest allowed timeout value is specified by the
+ * 'watchdog-max-timeout' property of the 'platform' node.
+ *
+ * If the 'timeout' argument is not zero, the watchdog timer is set to
+ * expire after a minimum of 'timeout' milliseconds.
+ *
+ * If the 'timeout' argument is zero, the watchdog timer is disabled.
+ *
+ * If the 'timeout' value exceeds the value of the 'max-watchdog-timeout'
+ * property, the hypervisor leaves the watchdog timer state unchanged,
+ * and returns a status of EINVAL.
+ *
+ * The 'time remaining' return value is valid regardless of whether the
+ * return status is EOK or EINVAL.  A non-zero return value indicates the
+ * number of milliseconds that were remaining until the timer was to expire.
+ * If less than one millisecond remains, the return value is '1'.  If the
+ * watchdog timer was disabled at the time of the call, the return value is
+ * zero.
+ *
+ * If the hypervisor cannot support the exact timeout value requested, but
+ * can support a larger timeout value, the hypervisor may round the actual
+ * timeout to a value larger than the requested timeout, consequently the
+ * 'time remaining' return value may be larger than the previously requested
+ * timeout value.
+ *
+ * Any guest OS debugger should be aware that the watchdog service may be in
+ * use.  Consequently, it is recommended that the watchdog service is
+ * disabled upon debugger entry (e.g. reaching a breakpoint), and then
+ * re-enabled upon returning to normal execution.  The API has been designed
+ * with this in mind, and the 'time remaining' result of the disable call may
+ * be used directly as the timeout argument of the re-enable call.
  */
-#define HV_FAST_MACH_GET_SOFT_STATE	0x04
+#define HV_FAST_MACH_SET_WATCHDOG	0x05
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mach_set_watchdog(unsigned long timeout,
+					     unsigned long *orig_timeout);
+#endif
 
 /* CPU services.
  *
@@ -206,8 +231,8 @@
  * FUNCTION:	HV_FAST_CPU_START
  * ARG0:	CPU ID
  * ARG1:	PC
- * ARG1:	RTBA
- * ARG1:	target ARG0
+ * ARG2:	RTBA
+ * ARG3:	target ARG0
  * RET0:	status
  * ERRORS:	ENOCPU		Invalid CPU ID
  *		EINVAL		Target CPU ID is not in the stopped state
@@ -224,6 +249,13 @@
  */
 #define HV_FAST_CPU_START		0x10
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_cpu_start(unsigned long cpuid,
+				     unsigned long pc,
+				     unsigned long rtba,
+				     unsigned long arg0);
+#endif
+
 /* cpu_stop()
  * TRAP:	HV_FAST_TRAP
  * FUNCTION:	HV_FAST_CPU_STOP
@@ -245,6 +277,10 @@
  */
 #define HV_FAST_CPU_STOP		0x11
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_cpu_stop(unsigned long cpuid);
+#endif
+
 /* cpu_yield()
  * TRAP:	HV_FAST_TRAP
  * FUNCTION:	HV_FAST_CPU_YIELD
@@ -588,6 +624,11 @@
  */
 #define HV_FAST_MMU_TSB_CTX0		0x20
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions,
+					unsigned long tsb_desc_ra);
+#endif
+
 /* mmu_tsb_ctxnon0()
  * TRAP:	HV_FAST_TRAP
  * FUNCTION:	HV_FAST_MMU_TSB_CTXNON0
@@ -694,6 +735,13 @@
  */
 #define HV_FAST_MMU_MAP_PERM_ADDR	0x25
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
+					     unsigned long set_to_zero,
+					     unsigned long tte,
+					     unsigned long flags);
+#endif
+
 /* mmu_fault_area_conf()
  * TRAP:	HV_FAST_TRAP
  * FUNCTION:	HV_FAST_MMU_FAULT_AREA_CONF
@@ -892,6 +940,10 @@
  */
 #define HV_FAST_TOD_GET			0x50
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_tod_get(unsigned long *time);
+#endif
+
 /* tod_set()
  * TRAP:	HV_FAST_TRAP
  * FUNCTION:	HV_FAST_TOD_SET
@@ -905,6 +957,10 @@
  */
 #define HV_FAST_TOD_SET			0x51
 
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_tod_set(unsigned long time);
+#endif
+
 /* Console services */
 
 /* con_getchar()
@@ -988,6 +1044,133 @@
 				     unsigned long *bytes_written);
 #endif
 
+/* mach_set_soft_state()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_MACH_SET_SOFT_STATE
+ * ARG0:	software state
+ * ARG1:	software state description pointer
+ * RET0:	status
+ * ERRORS:	EINVAL		software state not valid or software state
+ *				description is not NULL terminated
+ *		ENORADDR	software state description pointer is not a
+ *				valid real address
+ *		EBADALIGNED	software state description is not correctly
+ *				aligned
+ *
+ * This allows the guest to report it's soft state to the hypervisor.  There
+ * are two primary components to this state.  The first part states whether
+ * the guest software is running or not.  The second containts optional
+ * details specific to the software.
+ *
+ * The software state argument is defined below in HV_SOFT_STATE_*, and
+ * indicates whether the guest is operating normally or in a transitional
+ * state.
+ *
+ * The software state description argument is a real address of a data buffer
+ * of size 32-bytes aligned on a 32-byte boundary.  It is treated as a NULL
+ * terminated 7-bit ASCII string of up to 31 characters not including the
+ * NULL termination.
+ */
+#define HV_FAST_MACH_SET_SOFT_STATE	0x70
+#define  HV_SOFT_STATE_NORMAL		 0x01
+#define  HV_SOFT_STATE_TRANSITION	 0x02
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
+					       unsigned long msg_string_ra);
+#endif
+
+/* mach_get_soft_state()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_MACH_GET_SOFT_STATE
+ * ARG0:	software state description pointer
+ * RET0:	status
+ * RET1:	software state
+ * ERRORS:	ENORADDR	software state description pointer is not a
+ *				valid real address
+ *		EBADALIGNED	software state description is not correctly
+ *				aligned
+ *
+ * Retrieve the current value of the guest's software state.  The rules
+ * for the software state pointer are the same as for mach_set_soft_state()
+ * above.
+ */
+#define HV_FAST_MACH_GET_SOFT_STATE	0x71
+
+/* svc_send()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_SVC_SEND
+ * ARG0:	service ID
+ * ARG1:	buffer real address
+ * ARG2:	buffer size
+ * RET0:	STATUS
+ * RET1:	sent_bytes
+ *
+ * Be careful, all output registers are clobbered by this operation,
+ * so for example it is not possible to save away a value in %o4
+ * across the trap.
+ */
+#define HV_FAST_SVC_SEND		0x80
+
+/* svc_recv()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_SVC_RECV
+ * ARG0:	service ID
+ * ARG1:	buffer real address
+ * ARG2:	buffer size
+ * RET0:	STATUS
+ * RET1:	recv_bytes
+ *
+ * Be careful, all output registers are clobbered by this operation,
+ * so for example it is not possible to save away a value in %o4
+ * across the trap.
+ */
+#define HV_FAST_SVC_RECV		0x81
+
+/* svc_getstatus()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_SVC_GETSTATUS
+ * ARG0:	service ID
+ * RET0:	STATUS
+ * RET1:	status bits
+ */
+#define HV_FAST_SVC_GETSTATUS		0x82
+
+/* svc_setstatus()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_SVC_SETSTATUS
+ * ARG0:	service ID
+ * ARG1:	bits to set
+ * RET0:	STATUS
+ */
+#define HV_FAST_SVC_SETSTATUS		0x83
+
+/* svc_clrstatus()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_SVC_CLRSTATUS
+ * ARG0:	service ID
+ * ARG1:	bits to clear
+ * RET0:	STATUS
+ */
+#define HV_FAST_SVC_CLRSTATUS		0x84
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_svc_send(unsigned long svc_id,
+				    unsigned long buffer,
+				    unsigned long buffer_size,
+				    unsigned long *sent_bytes);
+extern unsigned long sun4v_svc_recv(unsigned long svc_id,
+				    unsigned long buffer,
+				    unsigned long buffer_size,
+				    unsigned long *recv_bytes);
+extern unsigned long sun4v_svc_getstatus(unsigned long svc_id,
+					 unsigned long *status_bits);
+extern unsigned long sun4v_svc_setstatus(unsigned long svc_id,
+					 unsigned long status_bits);
+extern unsigned long sun4v_svc_clrstatus(unsigned long svc_id,
+					 unsigned long status_bits);
+#endif
+
 /* Trap trace services.
  *
  * The hypervisor provides a trap tracing capability for privileged
@@ -1379,6 +1562,113 @@
 extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid);
 #endif
 
+/* vintr_get_cookie()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_VINTR_GET_COOKIE
+ * ARG0:	device handle
+ * ARG1:	device ino
+ * RET0:	status
+ * RET1:	cookie
+ */
+#define HV_FAST_VINTR_GET_COOKIE	0xa7
+
+/* vintr_set_cookie()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_VINTR_SET_COOKIE
+ * ARG0:	device handle
+ * ARG1:	device ino
+ * ARG2:	cookie
+ * RET0:	status
+ */
+#define HV_FAST_VINTR_SET_COOKIE	0xa8
+
+/* vintr_get_valid()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_VINTR_GET_VALID
+ * ARG0:	device handle
+ * ARG1:	device ino
+ * RET0:	status
+ * RET1:	valid state
+ */
+#define HV_FAST_VINTR_GET_VALID		0xa9
+
+/* vintr_set_valid()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_VINTR_SET_VALID
+ * ARG0:	device handle
+ * ARG1:	device ino
+ * ARG2:	valid state
+ * RET0:	status
+ */
+#define HV_FAST_VINTR_SET_VALID		0xaa
+
+/* vintr_get_state()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_VINTR_GET_STATE
+ * ARG0:	device handle
+ * ARG1:	device ino
+ * RET0:	status
+ * RET1:	state
+ */
+#define HV_FAST_VINTR_GET_STATE		0xab
+
+/* vintr_set_state()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_VINTR_SET_STATE
+ * ARG0:	device handle
+ * ARG1:	device ino
+ * ARG2:	state
+ * RET0:	status
+ */
+#define HV_FAST_VINTR_SET_STATE		0xac
+
+/* vintr_get_target()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_VINTR_GET_TARGET
+ * ARG0:	device handle
+ * ARG1:	device ino
+ * RET0:	status
+ * RET1:	cpuid
+ */
+#define HV_FAST_VINTR_GET_TARGET	0xad
+
+/* vintr_set_target()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_VINTR_SET_TARGET
+ * ARG0:	device handle
+ * ARG1:	device ino
+ * ARG2:	cpuid
+ * RET0:	status
+ */
+#define HV_FAST_VINTR_SET_TARGET	0xae
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_vintr_get_cookie(unsigned long dev_handle,
+					    unsigned long dev_ino,
+					    unsigned long *cookie);
+extern unsigned long sun4v_vintr_set_cookie(unsigned long dev_handle,
+					    unsigned long dev_ino,
+					    unsigned long cookie);
+extern unsigned long sun4v_vintr_get_valid(unsigned long dev_handle,
+					   unsigned long dev_ino,
+					   unsigned long *valid);
+extern unsigned long sun4v_vintr_set_valid(unsigned long dev_handle,
+					   unsigned long dev_ino,
+					   unsigned long valid);
+extern unsigned long sun4v_vintr_get_state(unsigned long dev_handle,
+					   unsigned long dev_ino,
+					   unsigned long *state);
+extern unsigned long sun4v_vintr_set_state(unsigned long dev_handle,
+					   unsigned long dev_ino,
+					   unsigned long state);
+extern unsigned long sun4v_vintr_get_target(unsigned long dev_handle,
+					    unsigned long dev_ino,
+					    unsigned long *cpuid);
+extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle,
+					    unsigned long dev_ino,
+					    unsigned long cpuid);
+#endif
+
 /* PCI IO services.
  *
  * See the terminology descriptions in the device interrupt services
@@ -2037,6 +2327,346 @@
  */
 #define HV_FAST_PCI_MSG_SETVALID	0xd3
 
+/* Logical Domain Channel services.  */
+
+#define LDC_CHANNEL_DOWN		0
+#define LDC_CHANNEL_UP			1
+#define LDC_CHANNEL_RESETTING		2
+
+/* ldc_tx_qconf()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_TX_QCONF
+ * ARG0:	channel ID
+ * ARG1:	real address base of queue
+ * ARG2:	num entries in queue
+ * RET0:	status
+ *
+ * Configure transmit queue for the LDC endpoint specified by the
+ * given channel ID, to be placed at the given real address, and
+ * be of the given num entries.  Num entries must be a power of two.
+ * The real address base of the queue must be aligned on the queue
+ * size.  Each queue entry is 64-bytes, so for example, a 32 entry
+ * queue must be aligned on a 2048 byte real address boundary.
+ *
+ * Upon configuration of a valid transmit queue the head and tail
+ * pointers are set to a hypervisor specific identical value indicating
+ * that the queue initially is empty.
+ *
+ * The endpoint's transmit queue is un-configured if num entries is zero.
+ *
+ * The maximum number of entries for each queue for a specific cpu may be
+ * determined from the machine description.  A transmit queue may be
+ * specified even in the event that the LDC is down (peer endpoint has no
+ * receive queue specified).  Transmission will begin as soon as the peer
+ * endpoint defines a receive queue.
+ *
+ * It is recommended that a guest wait for a transmit queue to empty prior
+ * to reconfiguring it, or un-configuring it.  Re or un-configuring of a
+ * non-empty transmit queue behaves exactly as defined above, however it
+ * is undefined as to how many of the pending entries in the original queue
+ * will be delivered prior to the re-configuration taking effect.
+ * Furthermore, as the queue configuration causes a reset of the head and
+ * tail pointers there is no way for a guest to determine how many entries
+ * have been sent after the configuration operation.
+ */
+#define HV_FAST_LDC_TX_QCONF		0xe0
+
+/* ldc_tx_qinfo()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_TX_QINFO
+ * ARG0:	channel ID
+ * RET0:	status
+ * RET1:	real address base of queue
+ * RET2:	num entries in queue
+ *
+ * Return the configuration info for the transmit queue of LDC endpoint
+ * defined by the given channel ID.  The real address is the currently
+ * defined real address base of the defined queue, and num entries is the
+ * size of the queue in terms of number of entries.
+ *
+ * If the specified channel ID is a valid endpoint number, but no transmit
+ * queue has been defined this service will return success, but with num
+ * entries set to zero and the real address will have an undefined value.
+ */
+#define HV_FAST_LDC_TX_QINFO		0xe1
+
+/* ldc_tx_get_state()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_TX_GET_STATE
+ * ARG0:	channel ID
+ * RET0:	status
+ * RET1:	head offset
+ * RET2:	tail offset
+ * RET3:	channel state
+ *
+ * Return the transmit state, and the head and tail queue pointers, for
+ * the transmit queue of the LDC endpoint defined by the given channel ID.
+ * The head and tail values are the byte offset of the head and tail
+ * positions of the transmit queue for the specified endpoint.
+ */
+#define HV_FAST_LDC_TX_GET_STATE	0xe2
+
+/* ldc_tx_set_qtail()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_TX_SET_QTAIL
+ * ARG0:	channel ID
+ * ARG1:	tail offset
+ * RET0:	status
+ *
+ * Update the tail pointer for the transmit queue associated with the LDC
+ * endpoint defined by the given channel ID.  The tail offset specified
+ * must be aligned on a 64 byte boundary, and calculated so as to increase
+ * the number of pending entries on the transmit queue.  Any attempt to
+ * decrease the number of pending transmit queue entires is considered
+ * an invalid tail offset and will result in an EINVAL error.
+ *
+ * Since the tail of the transmit queue may not be moved backwards, the
+ * transmit queue may be flushed by configuring a new transmit queue,
+ * whereupon the hypervisor will configure the initial transmit head and
+ * tail pointers to be equal.
+ */
+#define HV_FAST_LDC_TX_SET_QTAIL	0xe3
+
+/* ldc_rx_qconf()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_RX_QCONF
+ * ARG0:	channel ID
+ * ARG1:	real address base of queue
+ * ARG2:	num entries in queue
+ * RET0:	status
+ *
+ * Configure receive queue for the LDC endpoint specified by the
+ * given channel ID, to be placed at the given real address, and
+ * be of the given num entries.  Num entries must be a power of two.
+ * The real address base of the queue must be aligned on the queue
+ * size.  Each queue entry is 64-bytes, so for example, a 32 entry
+ * queue must be aligned on a 2048 byte real address boundary.
+ *
+ * The endpoint's transmit queue is un-configured if num entries is zero.
+ *
+ * If a valid receive queue is specified for a local endpoint the LDC is
+ * in the up state for the purpose of transmission to this endpoint.
+ *
+ * The maximum number of entries for each queue for a specific cpu may be
+ * determined from the machine description.
+ *
+ * As receive queue configuration causes a reset of the queue's head and
+ * tail pointers there is no way for a gues to determine how many entries
+ * have been received between a preceeding ldc_get_rx_state() API call
+ * and the completion of the configuration operation.  It should be noted
+ * that datagram delivery is not guarenteed via domain channels anyway,
+ * and therefore any higher protocol should be resilient to datagram
+ * loss if necessary.  However, to overcome this specific race potential
+ * it is recommended, for example, that a higher level protocol be employed
+ * to ensure either retransmission, or ensure that no datagrams are pending
+ * on the peer endpoint's transmit queue prior to the configuration process.
+ */
+#define HV_FAST_LDC_RX_QCONF		0xe4
+
+/* ldc_rx_qinfo()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_RX_QINFO
+ * ARG0:	channel ID
+ * RET0:	status
+ * RET1:	real address base of queue
+ * RET2:	num entries in queue
+ *
+ * Return the configuration info for the receive queue of LDC endpoint
+ * defined by the given channel ID.  The real address is the currently
+ * defined real address base of the defined queue, and num entries is the
+ * size of the queue in terms of number of entries.
+ *
+ * If the specified channel ID is a valid endpoint number, but no receive
+ * queue has been defined this service will return success, but with num
+ * entries set to zero and the real address will have an undefined value.
+ */
+#define HV_FAST_LDC_RX_QINFO		0xe5
+
+/* ldc_rx_get_state()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_RX_GET_STATE
+ * ARG0:	channel ID
+ * RET0:	status
+ * RET1:	head offset
+ * RET2:	tail offset
+ * RET3:	channel state
+ *
+ * Return the receive state, and the head and tail queue pointers, for
+ * the receive queue of the LDC endpoint defined by the given channel ID.
+ * The head and tail values are the byte offset of the head and tail
+ * positions of the receive queue for the specified endpoint.
+ */
+#define HV_FAST_LDC_RX_GET_STATE	0xe6
+
+/* ldc_rx_set_qhead()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_RX_SET_QHEAD
+ * ARG0:	channel ID
+ * ARG1:	head offset
+ * RET0:	status
+ *
+ * Update the head pointer for the receive queue associated with the LDC
+ * endpoint defined by the given channel ID.  The head offset specified
+ * must be aligned on a 64 byte boundary, and calculated so as to decrease
+ * the number of pending entries on the receive queue.  Any attempt to
+ * increase the number of pending receive queue entires is considered
+ * an invalid head offset and will result in an EINVAL error.
+ *
+ * The receive queue may be flushed by setting the head offset equal
+ * to the current tail offset.
+ */
+#define HV_FAST_LDC_RX_SET_QHEAD	0xe7
+
+/* LDC Map Table Entry.  Each slot is defined by a translation table
+ * entry, as specified by the LDC_MTE_* bits below, and a 64-bit
+ * hypervisor invalidation cookie.
+ */
+#define LDC_MTE_PADDR	0x0fffffffffffe000 /* pa[55:13]          */
+#define LDC_MTE_COPY_W	0x0000000000000400 /* copy write access  */
+#define LDC_MTE_COPY_R	0x0000000000000200 /* copy read access   */
+#define LDC_MTE_IOMMU_W	0x0000000000000100 /* IOMMU write access */
+#define LDC_MTE_IOMMU_R	0x0000000000000080 /* IOMMU read access  */
+#define LDC_MTE_EXEC	0x0000000000000040 /* execute            */
+#define LDC_MTE_WRITE	0x0000000000000020 /* read               */
+#define LDC_MTE_READ	0x0000000000000010 /* write              */
+#define LDC_MTE_SZALL	0x000000000000000f /* page size bits     */
+#define LDC_MTE_SZ16GB	0x0000000000000007 /* 16GB page          */
+#define LDC_MTE_SZ2GB	0x0000000000000006 /* 2GB page           */
+#define LDC_MTE_SZ256MB	0x0000000000000005 /* 256MB page         */
+#define LDC_MTE_SZ32MB	0x0000000000000004 /* 32MB page          */
+#define LDC_MTE_SZ4MB	0x0000000000000003 /* 4MB page           */
+#define LDC_MTE_SZ512K	0x0000000000000002 /* 512K page          */
+#define LDC_MTE_SZ64K	0x0000000000000001 /* 64K page           */
+#define LDC_MTE_SZ8K	0x0000000000000000 /* 8K page            */
+
+#ifndef __ASSEMBLY__
+struct ldc_mtable_entry {
+	unsigned long	mte;
+	unsigned long	cookie;
+};
+#endif
+
+/* ldc_set_map_table()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_SET_MAP_TABLE
+ * ARG0:	channel ID
+ * ARG1:	table real address
+ * ARG2:	num entries
+ * RET0:	status
+ *
+ * Register the MTE table at the given table real address, with the
+ * specified num entries, for the LDC indicated by the given channel
+ * ID.
+ */
+#define HV_FAST_LDC_SET_MAP_TABLE	0xea
+
+/* ldc_get_map_table()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_GET_MAP_TABLE
+ * ARG0:	channel ID
+ * RET0:	status
+ * RET1:	table real address
+ * RET2:	num entries
+ *
+ * Return the configuration of the current mapping table registered
+ * for the given channel ID.
+ */
+#define HV_FAST_LDC_GET_MAP_TABLE	0xeb
+
+#define LDC_COPY_IN	0
+#define LDC_COPY_OUT	1
+
+/* ldc_copy()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_COPY
+ * ARG0:	channel ID
+ * ARG1:	LDC_COPY_* direction code
+ * ARG2:	target real address
+ * ARG3:	local real address
+ * ARG4:	length in bytes
+ * RET0:	status
+ * RET1:	actual length in bytes
+ */
+#define HV_FAST_LDC_COPY		0xec
+
+#define LDC_MEM_READ	1
+#define LDC_MEM_WRITE	2
+#define LDC_MEM_EXEC	4
+
+/* ldc_mapin()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_MAPIN
+ * ARG0:	channel ID
+ * ARG1:	cookie
+ * RET0:	status
+ * RET1:	real address
+ * RET2:	LDC_MEM_* permissions
+ */
+#define HV_FAST_LDC_MAPIN		0xed
+
+/* ldc_unmap()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_UNMAP
+ * ARG0:	real address
+ * RET0:	status
+ */
+#define HV_FAST_LDC_UNMAP		0xee
+
+/* ldc_revoke()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_LDC_REVOKE
+ * ARG0:	cookie
+ * ARG1:	ldc_mtable_entry cookie
+ * RET0:	status
+ */
+#define HV_FAST_LDC_REVOKE		0xef
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_ldc_tx_qconf(unsigned long channel,
+					unsigned long ra,
+					unsigned long num_entries);
+extern unsigned long sun4v_ldc_tx_qinfo(unsigned long channel,
+					unsigned long *ra,
+					unsigned long *num_entries);
+extern unsigned long sun4v_ldc_tx_get_state(unsigned long channel,
+					    unsigned long *head_off,
+					    unsigned long *tail_off,
+					    unsigned long *chan_state);
+extern unsigned long sun4v_ldc_tx_set_qtail(unsigned long channel,
+					    unsigned long tail_off);
+extern unsigned long sun4v_ldc_rx_qconf(unsigned long channel,
+					unsigned long ra,
+					unsigned long num_entries);
+extern unsigned long sun4v_ldc_rx_qinfo(unsigned long channel,
+					unsigned long *ra,
+					unsigned long *num_entries);
+extern unsigned long sun4v_ldc_rx_get_state(unsigned long channel,
+					    unsigned long *head_off,
+					    unsigned long *tail_off,
+					    unsigned long *chan_state);
+extern unsigned long sun4v_ldc_rx_set_qhead(unsigned long channel,
+					    unsigned long head_off);
+extern unsigned long sun4v_ldc_set_map_table(unsigned long channel,
+					     unsigned long ra,
+					     unsigned long num_entries);
+extern unsigned long sun4v_ldc_get_map_table(unsigned long channel,
+					     unsigned long *ra,
+					     unsigned long *num_entries);
+extern unsigned long sun4v_ldc_copy(unsigned long channel,
+				    unsigned long dir_code,
+				    unsigned long tgt_raddr,
+				    unsigned long lcl_raddr,
+				    unsigned long len,
+				    unsigned long *actual_len);
+extern unsigned long sun4v_ldc_mapin(unsigned long channel,
+				     unsigned long cookie,
+				     unsigned long *ra,
+				     unsigned long *perm);
+extern unsigned long sun4v_ldc_unmap(unsigned long ra);
+extern unsigned long sun4v_ldc_revoke(unsigned long cookie,
+				      unsigned long mte_cookie);
+#endif
+
 /* Performance counter services.  */
 
 #define HV_PERF_JBUS_PERF_CTRL_REG	0x00
@@ -2168,6 +2798,100 @@
  */
 #define HV_FAST_MMUSTAT_INFO		0x103
 
+/* NCS crypto services  */
+
+/* ncs_request() sub-function numbers */
+#define HV_NCS_QCONF			0x01
+#define HV_NCS_QTAIL_UPDATE		0x02
+
+#ifndef __ASSEMBLY__
+struct hv_ncs_queue_entry {
+	/* MAU Control Register */
+	unsigned long	mau_control;
+#define MAU_CONTROL_INV_PARITY	0x0000000000002000
+#define MAU_CONTROL_STRAND	0x0000000000001800
+#define MAU_CONTROL_BUSY	0x0000000000000400
+#define MAU_CONTROL_INT		0x0000000000000200
+#define MAU_CONTROL_OP		0x00000000000001c0
+#define MAU_CONTROL_OP_SHIFT	6
+#define MAU_OP_LOAD_MA_MEMORY	0x0
+#define MAU_OP_STORE_MA_MEMORY	0x1
+#define MAU_OP_MODULAR_MULT	0x2
+#define MAU_OP_MODULAR_REDUCE	0x3
+#define MAU_OP_MODULAR_EXP_LOOP	0x4
+#define MAU_CONTROL_LEN		0x000000000000003f
+#define MAU_CONTROL_LEN_SHIFT	0
+
+	/* Real address of bytes to load or store bytes
+	 * into/out-of the MAU.
+	 */
+	unsigned long	mau_mpa;
+
+	/* Modular Arithmetic MA Offset Register.  */
+	unsigned long	mau_ma;
+
+	/* Modular Arithmetic N Prime Register.  */
+	unsigned long	mau_np;
+};
+
+struct hv_ncs_qconf_arg {
+	unsigned long	mid;      /* MAU ID, 1 per core on Niagara */
+	unsigned long	base;     /* Real address base of queue */
+	unsigned long	end;	  /* Real address end of queue */
+	unsigned long	num_ents; /* Number of entries in queue */
+};
+
+struct hv_ncs_qtail_update_arg {
+	unsigned long	mid;      /* MAU ID, 1 per core on Niagara */
+	unsigned long	tail;     /* New tail index to use */
+	unsigned long	syncflag; /* only SYNCFLAG_SYNC is implemented */
+#define HV_NCS_SYNCFLAG_SYNC	0x00
+#define HV_NCS_SYNCFLAG_ASYNC	0x01
+};
+#endif
+
+/* ncs_request()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_NCS_REQUEST
+ * ARG0:	NCS sub-function
+ * ARG1:	sub-function argument real address
+ * ARG2:	size in bytes of sub-function argument
+ * RET0:	status
+ *
+ * The MAU chip of the Niagara processor is not directly accessible
+ * to privileged code, instead it is programmed indirectly via this
+ * hypervisor API.
+ *
+ * The interfaces defines a queue of MAU operations to perform.
+ * Privileged code registers a queue with the hypervisor by invoking
+ * this HVAPI with the HV_NCS_QCONF sub-function, which defines the
+ * base, end, and number of entries of the queue.  Each queue entry
+ * contains a MAU register struct block.
+ *
+ * The privileged code then proceeds to add entries to the queue and
+ * then invoke the HV_NCS_QTAIL_UPDATE sub-function.  Since only
+ * synchronous operations are supported by the current hypervisor,
+ * HV_NCS_QTAIL_UPDATE will run all the pending queue entries to
+ * completion and return HV_EOK, or return an error code.
+ *
+ * The real address of the sub-function argument must be aligned on at
+ * least an 8-byte boundary.
+ *
+ * The tail argument of HV_NCS_QTAIL_UPDATE is an index, not a byte
+ * offset, into the queue and must be less than or equal the 'num_ents'
+ * argument given in the HV_NCS_QCONF call.
+ */
+#define HV_FAST_NCS_REQUEST		0x110
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_ncs_request(unsigned long request,
+				       unsigned long arg_ra,
+				       unsigned long arg_size);
+#endif
+
+#define HV_FAST_FIRE_GET_PERFREG	0x120
+#define HV_FAST_FIRE_SET_PERFREG	0x121
+
 /* Function numbers for HV_CORE_TRAP.  */
 #define HV_CORE_SET_VER			0x00
 #define HV_CORE_PUTCHAR			0x01
@@ -2204,6 +2928,7 @@
 extern int sun4v_hvapi_get(unsigned long group,
 			   unsigned long *major,
 			   unsigned long *minor);
+extern void sun4v_hvapi_init(void);
 #endif
 
 #endif /* !(_SPARC64_HYPERVISOR_H) */
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h
index 627e339..9974c7b 100644
--- a/include/asm-sparc64/kdebug.h
+++ b/include/asm-sparc64/kdebug.h
@@ -32,7 +32,6 @@
 	DIE_TRAP,
 	DIE_TRAP_TL1,
 	DIE_CALL,
-	DIE_PAGE_FAULT,
 };
 
 #endif
diff --git a/include/asm-sparc64/mdesc.h b/include/asm-sparc64/mdesc.h
new file mode 100644
index 0000000..124eb8c
--- /dev/null
+++ b/include/asm-sparc64/mdesc.h
@@ -0,0 +1,39 @@
+#ifndef _SPARC64_MDESC_H
+#define _SPARC64_MDESC_H
+
+#include <linux/types.h>
+#include <asm/prom.h>
+
+struct mdesc_node;
+struct mdesc_arc {
+	const char		*name;
+	struct mdesc_node	*arc;
+};
+
+struct mdesc_node {
+	const char		*name;
+	u64			node;
+	unsigned int		unique_id;
+	unsigned int		num_arcs;
+	struct property		*properties;
+	struct mdesc_node	*hash_next;
+	struct mdesc_node	*allnodes_next;
+	struct mdesc_arc	arcs[0];
+};
+
+extern struct mdesc_node *md_find_node_by_name(struct mdesc_node *from,
+					       const char *name);
+#define md_for_each_node_by_name(__mn, __name) \
+	for (__mn = md_find_node_by_name(NULL, __name); __mn; \
+	     __mn = md_find_node_by_name(__mn, __name))
+
+extern struct property *md_find_property(const struct mdesc_node *mp,
+					 const char *name,
+					 int *lenp);
+extern const void *md_get_property(const struct mdesc_node *mp,
+				   const char *name,
+				   int *lenp);
+
+extern void sun4v_mdesc_init(void);
+
+#endif
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
index 6a0da3b..992f9f7 100644
--- a/include/asm-sparc64/oplib.h
+++ b/include/asm-sparc64/oplib.h
@@ -316,11 +316,8 @@
 			
 extern int prom_pathtoinode(const char *path);
 extern int prom_inst2pkg(int);
-
-/* CPU probing helpers.  */
-struct device_node;
-int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid);
-int cpu_find_by_mid(int mid, struct device_node **prom_node);
+extern int prom_service_exists(const char *service_name);
+extern void prom_sun4v_guest_soft_state(void);
 
 /* Client interface level routines. */
 extern void prom_set_trap_table(unsigned long tba);
diff --git a/include/asm-sparc64/percpu.h b/include/asm-sparc64/percpu.h
index ced8cbd..88db872 100644
--- a/include/asm-sparc64/percpu.h
+++ b/include/asm-sparc64/percpu.h
@@ -5,7 +5,8 @@
 
 #ifdef CONFIG_SMP
 
-extern void setup_per_cpu_areas(void);
+#define setup_per_cpu_areas()			do { } while (0)
+extern void real_setup_per_cpu_areas(void);
 
 extern unsigned long __per_cpu_base;
 extern unsigned long __per_cpu_shift;
@@ -34,6 +35,7 @@
 } while (0)
 #else /* ! SMP */
 
+#define real_setup_per_cpu_areas()		do { } while (0)
 #define DEFINE_PER_CPU(type, name) \
     __typeof__(type) per_cpu__##name
 
diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h
index ddad5f9..b4df304 100644
--- a/include/asm-sparc64/prom.h
+++ b/include/asm-sparc64/prom.h
@@ -90,6 +90,7 @@
 	const char *type, const char *compat);
 extern struct device_node *of_find_node_by_path(const char *path);
 extern struct device_node *of_find_node_by_phandle(phandle handle);
+extern struct device_node *of_find_node_by_cpuid(int cpuid);
 extern struct device_node *of_get_parent(const struct device_node *node);
 extern struct device_node *of_get_next_child(const struct device_node *node,
 					     struct device_node *prev);
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index 869d16f..f76e149 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -41,7 +41,7 @@
 extern int hard_smp_processor_id(void);
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
-extern void smp_setup_cpu_possible_map(void);
+extern void smp_fill_in_sib_core_maps(void);
 extern unsigned char boot_cpu_id;
 
 #endif /* !(__ASSEMBLY__) */
@@ -49,7 +49,7 @@
 #else
 
 #define hard_smp_processor_id()		0
-#define smp_setup_cpu_possible_map() do { } while (0)
+#define smp_fill_in_sib_core_maps() do { } while (0)
 #define boot_cpu_id	(0)
 
 #endif /* !(CONFIG_SMP) */
diff --git a/include/asm-sparc64/sstate.h b/include/asm-sparc64/sstate.h
new file mode 100644
index 0000000..a7c35db
--- /dev/null
+++ b/include/asm-sparc64/sstate.h
@@ -0,0 +1,13 @@
+#ifndef _SPARC64_SSTATE_H
+#define _SPARC64_SSTATE_H
+
+extern void sstate_booting(void);
+extern void sstate_running(void);
+extern void sstate_halt(void);
+extern void sstate_poweroff(void);
+extern void sstate_panic(void);
+extern void sstate_reboot(void);
+
+extern void sun4v_sstate_init(void);
+
+#endif /* _SPARC64_SSTATE_H */
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
index 2ebf7f2..98252cd 100644
--- a/include/asm-sparc64/thread_info.h
+++ b/include/asm-sparc64/thread_info.h
@@ -38,8 +38,8 @@
 	/* D$ line 1 */
 	struct task_struct	*task;
 	unsigned long		flags;
-	__u8			cpu;
 	__u8			fpsaved[7];
+	__u8			pad;
 	unsigned long		ksp;
 
 	/* D$ line 2 */
@@ -49,7 +49,7 @@
 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 	__u8			new_child;
 	__u8			syscall_noerror;
-	__u16			__pad;
+	__u16			cpu;
 
 	unsigned long		*utraps;
 
@@ -83,8 +83,7 @@
 #define TI_CURRENT_DS	(TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS)
 #define TI_FPDEPTH	(TI_FLAGS + TI_FLAG_BYTE_FPDEPTH)
 #define TI_WSAVED	(TI_FLAGS + TI_FLAG_BYTE_WSAVED)
-#define TI_CPU		0x00000010
-#define TI_FPSAVED	0x00000011
+#define TI_FPSAVED	0x00000010
 #define TI_KSP		0x00000018
 #define TI_FAULT_ADDR	0x00000020
 #define TI_KREGS	0x00000028
@@ -92,6 +91,7 @@
 #define TI_PRE_COUNT	0x00000038
 #define TI_NEW_CHILD	0x0000003c
 #define TI_SYS_NOERROR	0x0000003d
+#define TI_CPU		0x0000003e
 #define TI_UTRAPS	0x00000040
 #define TI_REG_WINDOW	0x00000048
 #define TI_RWIN_SPTRS	0x000003c8	
diff --git a/include/asm-sparc64/topology.h b/include/asm-sparc64/topology.h
index 98a6c61..e0d450d 100644
--- a/include/asm-sparc64/topology.h
+++ b/include/asm-sparc64/topology.h
@@ -6,4 +6,7 @@
 
 #include <asm-generic/topology.h>
 
+#define topology_core_id(cpu)			(cpu_data(cpu).core_id)
+#define topology_thread_siblings(cpu)		(cpu_sibling_map[cpu])
+
 #endif /* _ASM_SPARC64_TOPOLOGY_H */
diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h
index ab55ffc..76e4299 100644
--- a/include/asm-sparc64/tsb.h
+++ b/include/asm-sparc64/tsb.h
@@ -271,7 +271,7 @@
 #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
 	sethi		%hi(swapper_4m_tsb), REG1; \
 	or		REG1, %lo(swapper_4m_tsb), REG1; \
-	and		TAG, (KERNEL_TSB_NENTRIES - 1), REG2; \
+	and		TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
 	sllx		REG2, 4, REG2; \
 	add		REG1, REG2, REG2; \
 	KTSB_LOAD_QUAD(REG2, REG3); \
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 09ea01a..648bd1f 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -209,9 +209,8 @@
 	DEVCONF_RTR_PROBE_INTERVAL,
 	DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
 	DEVCONF_PROXY_NDP,
-	__DEVCONF_OPTIMISTIC_DAD,
-	DEVCONF_ACCEPT_SOURCE_ROUTE,
 	DEVCONF_OPTIMISTIC_DAD,
+	DEVCONF_ACCEPT_SOURCE_ROUTE,
 	DEVCONF_MAX
 };
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f671cd2..3a70f55 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -910,6 +910,17 @@
 	return 0;
 }
 
+/* same as netif_rx_complete, except that local_irq_save(flags)
+ * has already been issued
+ */
+static inline void __netif_rx_complete(struct net_device *dev)
+{
+	BUG_ON(!test_bit(__LINK_STATE_RX_SCHED, &dev->state));
+	list_del(&dev->poll_list);
+	smp_mb__before_clear_bit();
+	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
+}
+
 /* Remove interface from poll list: it must be in the poll list
  * on current cpu. This primitive is called by dev->poll(), when
  * it completes the work. The device cannot be out of poll list at this
@@ -920,10 +931,7 @@
 	unsigned long flags;
 
 	local_irq_save(flags);
-	BUG_ON(!test_bit(__LINK_STATE_RX_SCHED, &dev->state));
-	list_del(&dev->poll_list);
-	smp_mb__before_clear_bit();
-	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
+	__netif_rx_complete(dev);
 	local_irq_restore(flags);
 }
 
@@ -940,17 +948,6 @@
 	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
 }
 
-/* same as netif_rx_complete, except that local_irq_save(flags)
- * has already been issued
- */
-static inline void __netif_rx_complete(struct net_device *dev)
-{
-	BUG_ON(!test_bit(__LINK_STATE_RX_SCHED, &dev->state));
-	list_del(&dev->poll_list);
-	smp_mb__before_clear_bit();
-	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
-}
-
 static inline void netif_tx_lock(struct net_device *dev)
 {
 	spin_lock(&dev->_xmit_lock);
diff --git a/include/linux/timer.h b/include/linux/timer.h
index e0c5c16..c661710 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -69,6 +69,12 @@
 extern int mod_timer(struct timer_list *timer, unsigned long expires);
 
 /*
+ * The jiffies value which is added to now, when there is no timer
+ * in the timer wheel:
+ */
+#define NEXT_TIMER_MAX_DELTA	((1UL << 30) - 1)
+
+/*
  * Return when the next timer-wheel timeout occurs (in absolute jiffies),
  * locks the timer base:
  */
diff --git a/include/net/sock.h b/include/net/sock.h
index 689b886..dfeb8b1 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -218,13 +218,13 @@
 	atomic_t		sk_rmem_alloc;
 	atomic_t		sk_wmem_alloc;
 	atomic_t		sk_omem_alloc;
+	int			sk_sndbuf;
 	struct sk_buff_head	sk_receive_queue;
 	struct sk_buff_head	sk_write_queue;
 	struct sk_buff_head	sk_async_wait_queue;
 	int			sk_wmem_queued;
 	int			sk_forward_alloc;
 	gfp_t			sk_allocation;
-	int			sk_sndbuf;
 	int			sk_route_caps;
 	int			sk_gso_type;
 	int			sk_rcvlowat;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index e22b4f0..a8af9ae 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -254,6 +254,12 @@
 	return seq3 - seq2 >= seq1 - seq2;
 }
 
+static inline int tcp_too_many_orphans(struct sock *sk, int num)
+{
+	return (num > sysctl_tcp_max_orphans) ||
+		(sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
+		 atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]);
+}
 
 extern struct proto tcp_prot;
 
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 39ef925..90185e8 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -237,7 +237,6 @@
 extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);
 extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c);
 extern void km_state_notify(struct xfrm_state *x, struct km_event *c);
-#define XFRM_ACQ_EXPIRES	30
 
 struct xfrm_tmpl;
 extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
diff --git a/include/sound/version.h b/include/sound/version.h
index 50ee4fd..8e5b2f0 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by alsa/ksync script.  */
-#define CONFIG_SND_VERSION "1.0.14rc4"
-#define CONFIG_SND_DATE " (Wed May 16 09:45:46 2007 UTC)"
+#define CONFIG_SND_VERSION "1.0.14"
+#define CONFIG_SND_DATE " (Thu May 31 09:03:25 2007 UTC)"
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index f1bda23..fed5441 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -257,7 +257,8 @@
 		pos = get_symbol_pos(addr, symbolsize, offset);
 		/* Grab name */
 		kallsyms_expand_symbol(get_symbol_offset(pos), namebuf);
-		*modname = NULL;
+		if (modname)
+			*modname = NULL;
 		return namebuf;
 	}
 
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 3e7ebc4..52db9e3 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -247,6 +247,21 @@
 		if (cpu == tick_do_timer_cpu)
 			tick_do_timer_cpu = -1;
 
+		ts->idle_sleeps++;
+
+		/*
+		 * delta_jiffies >= NEXT_TIMER_MAX_DELTA signals that
+		 * there is no timer pending or at least extremly far
+		 * into the future (12 days for HZ=1000). In this case
+		 * we simply stop the tick timer:
+		 */
+		if (unlikely(delta_jiffies >= NEXT_TIMER_MAX_DELTA)) {
+			ts->idle_expires.tv64 = KTIME_MAX;
+			if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
+				hrtimer_cancel(&ts->sched_timer);
+			goto out;
+		}
+
 		/*
 		 * calculate the expiry time for the next timer wheel
 		 * timer
@@ -254,7 +269,6 @@
 		expires = ktime_add_ns(last_update, tick_period.tv64 *
 				       delta_jiffies);
 		ts->idle_expires = expires;
-		ts->idle_sleeps++;
 
 		if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
 			hrtimer_start(&ts->sched_timer, expires,
diff --git a/kernel/timer.c b/kernel/timer.c
index 5ec5490..1a69705 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -666,7 +666,7 @@
 static unsigned long __next_timer_interrupt(tvec_base_t *base)
 {
 	unsigned long timer_jiffies = base->timer_jiffies;
-	unsigned long expires = timer_jiffies + (LONG_MAX >> 1);
+	unsigned long expires = timer_jiffies + NEXT_TIMER_MAX_DELTA;
 	int index, slot, array, found = 0;
 	struct timer_list *nte;
 	tvec_t *varray[4];
@@ -752,6 +752,14 @@
 
 	tsdelta = ktime_to_timespec(hr_delta);
 	delta = timespec_to_jiffies(&tsdelta);
+
+	/*
+	 * Limit the delta to the max value, which is checked in
+	 * tick_nohz_stop_sched_tick():
+	 */
+	if (delta > NEXT_TIMER_MAX_DELTA)
+		delta = NEXT_TIMER_MAX_DELTA;
+
 	/*
 	 * Take rounding errors in to account and make sure, that it
 	 * expires in the next tick. Otherwise we go into an endless
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d897062..bd8e335 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2689,7 +2689,7 @@
 			map = alloc_bootmem_node(pgdat, size);
 		pgdat->node_mem_map = map + (pgdat->node_start_pfn - start);
 	}
-#ifdef CONFIG_FLATMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 	/*
 	 * With no DISCONTIG, the global mem_map is just set as node 0's
 	 */
diff --git a/mm/slub.c b/mm/slub.c
index 3e5aefc..238c5a6 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2435,6 +2435,7 @@
 	 */
 	create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node",
 		sizeof(struct kmem_cache_node), GFP_KERNEL);
+	kmalloc_caches[0].refcount = -1;
 #endif
 
 	/* Able to allocate the per node structures */
@@ -2482,6 +2483,12 @@
 	if (s->ctor)
 		return 1;
 
+	/*
+	 * We may have set a slab to be unmergeable during bootstrap.
+	 */
+	if (s->refcount < 0)
+		return 1;
+
 	return 0;
 }
 
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 91b0170..3fc6972 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -121,6 +121,7 @@
 {
 	struct net_bridge *br = (struct net_bridge *)_data;
 	unsigned long delay = hold_time(br);
+	unsigned long next_timer = jiffies + br->forward_delay;
 	int i;
 
 	spin_lock_bh(&br->hash_lock);
@@ -129,14 +130,21 @@
 		struct hlist_node *h, *n;
 
 		hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) {
-			if (!f->is_static &&
-			    time_before_eq(f->ageing_timer + delay, jiffies))
+			unsigned long this_timer;
+			if (f->is_static)
+				continue;
+			this_timer = f->ageing_timer + delay;
+			if (time_before_eq(this_timer, jiffies))
 				fdb_delete(f);
+			else if (this_timer < next_timer)
+				next_timer = this_timer;
 		}
 	}
 	spin_unlock_bh(&br->hash_lock);
 
-	mod_timer(&br->gc_timer, jiffies + HZ/10);
+	/* Add HZ/4 to ensure we round the jiffies upwards to be after the next
+	 * timer, otherwise we might round down and will have no-op run. */
+	mod_timer(&br->gc_timer, round_jiffies(next_timer + HZ/4));
 }
 
 /* Completely flush all dynamic entries in forwarding database.*/
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 0e035d6..e38034a 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -178,7 +178,8 @@
 		br_send_config_bpdu(p, &bpdu);
 		p->topology_change_ack = 0;
 		p->config_pending = 0;
-		mod_timer(&p->hold_timer, jiffies + BR_HOLD_TIME);
+		mod_timer(&p->hold_timer,
+			  round_jiffies(jiffies + BR_HOLD_TIME));
 	}
 }
 
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c
index 24e0ca4..77f5255 100644
--- a/net/bridge/br_stp_timer.c
+++ b/net/bridge/br_stp_timer.c
@@ -42,7 +42,7 @@
 	if (br->dev->flags & IFF_UP) {
 		br_config_bpdu_generation(br);
 
-		mod_timer(&br->hello_timer, jiffies + br->hello_time);
+		mod_timer(&br->hello_timer, round_jiffies(jiffies + br->hello_time));
 	}
 	spin_unlock(&br->lock);
 }
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index f34aca0..6d5ea97 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -25,6 +25,7 @@
 extern u32 sysctl_xfrm_aevent_etime;
 extern u32 sysctl_xfrm_aevent_rseqth;
 extern int sysctl_xfrm_larval_drop;
+extern u32 sysctl_xfrm_acq_expires;
 #endif
 
 ctl_table core_table[] = {
@@ -127,6 +128,14 @@
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec
 	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "xfrm_acq_expires",
+		.data		= &sysctl_xfrm_acq_expires,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 #endif /* CONFIG_XFRM */
 #endif /* CONFIG_NET */
 	{
diff --git a/net/core/utils.c b/net/core/utils.c
index adecfd2..2030bb8 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -139,16 +139,16 @@
 	while(1) {
 		int c;
 		c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
-		if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM))) {
+		if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK))) {
 			goto out;
 		}
-		if (c & (IN6PTON_DOT | IN6PTON_DELIM)) {
+		if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
 			if (w == 0)
 				goto out;
 			*d++ = w & 0xff;
 			w = 0;
 			i++;
-			if (c & IN6PTON_DELIM) {
+			if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
 				if (i != 4)
 					goto out;
 				break;
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index 7ec6610..17ad278 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -140,7 +140,7 @@
 
 	dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
 	if (!dev) {
-		IEEE80211_ERROR("Unable to network device.\n");
+		IEEE80211_ERROR("Unable to allocate network device.\n");
 		goto failed;
 	}
 	ieee = netdev_priv(dev);
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index e9cdc66..c308756 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -33,7 +33,10 @@
 	struct ieee80211softmac_device *softmac;
 	struct net_device *dev;
 
-	dev = alloc_ieee80211(sizeof(struct ieee80211softmac_device) + sizeof_priv);
+	dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv);
+	if (!dev)
+		return NULL;
+
 	softmac = ieee80211_priv(dev);
 	softmac->dev = dev;
 	softmac->ieee = netdev_priv(dev);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 837f295..9ad1f62 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -250,8 +250,6 @@
 	return -EINVAL;
 }
 
-#ifndef CONFIG_IP_NOSIOCRT
-
 static inline __be32 sk_extract_addr(struct sockaddr *addr)
 {
 	return ((struct sockaddr_in *) addr)->sin_addr.s_addr;
@@ -443,15 +441,6 @@
 	return -EINVAL;
 }
 
-#else
-
-int ip_rt_ioctl(unsigned int cmd, void *arg)
-{
-	return -EINVAL;
-}
-
-#endif
-
 struct nla_policy rtm_ipv4_policy[RTA_MAX+1] __read_mostly = {
 	[RTA_DST]		= { .type = NLA_U32 },
 	[RTA_SRC]		= { .type = NLA_U32 },
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index bd4c295..7663145 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1674,9 +1674,8 @@
 	}
 	if (sk->sk_state != TCP_CLOSE) {
 		sk_stream_mem_reclaim(sk);
-		if (atomic_read(sk->sk_prot->orphan_count) > sysctl_tcp_max_orphans ||
-		    (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
-		     atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) {
+		if (tcp_too_many_orphans(sk,
+				atomic_read(sk->sk_prot->orphan_count))) {
 			if (net_ratelimit())
 				printk(KERN_INFO "TCP: too many of orphaned "
 				       "sockets\n");
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index 3938d5d..760165a 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -80,7 +80,8 @@
 
 	kfifo_put(tcpw.fifo, tbuf, len);
 	wake_up(&tcpw.wait);
-}
+} __attribute__ ((format (printf, 1, 2)));
+
 
 /*
  * Hook inserted to be called before each receive packet.
@@ -95,7 +96,7 @@
 	/* Only update if port matches */
 	if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port)
 	    && (full || tp->snd_cwnd != tcpw.lastcwnd)) {
-		printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u\n",
+		printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u %u\n",
 		       NIPQUAD(inet->saddr), ntohs(inet->sport),
 		       NIPQUAD(inet->daddr), ntohs(inet->dport),
 		       skb->len, tp->snd_nxt, tp->snd_una,
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 2ca97b2..e613401 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -78,9 +78,7 @@
 	if (sk->sk_err_soft)
 		orphans <<= 1;
 
-	if (orphans >= sysctl_tcp_max_orphans ||
-	    (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
-	     atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) {
+	if (tcp_too_many_orphans(sk, orphans)) {
 		if (net_ratelimit())
 			printk(KERN_INFO "Out of socket memory\n");
 
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 5ceca95..fa1902d 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -139,10 +139,8 @@
 	nf_reset(skb);
 
 	if (decaps) {
-		if (!(skb->dev->flags&IFF_LOOPBACK)) {
-			dst_release(skb->dst);
-			skb->dst = NULL;
-		}
+		dst_release(skb->dst);
+		skb->dst = NULL;
 		netif_rx(skb);
 		return 0;
 	} else {
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index a2f2e6a..9963700 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -85,6 +85,8 @@
 	top_iph->saddr = x->props.saddr.a4;
 	top_iph->daddr = x->id.daddr.a4;
 
+	skb->protocol = htons(ETH_P_IP);
+
 	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
 	return 0;
 }
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index b696c84..128f94c 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -247,7 +247,7 @@
 	memcpy(tmp_base, top_iph, sizeof(tmp_base));
 
 	tmp_ext = NULL;
-	extlen = skb_transport_offset(skb) + sizeof(struct ipv6hdr);
+	extlen = skb_transport_offset(skb) - sizeof(struct ipv6hdr);
 	if (extlen) {
 		extlen += sizeof(*tmp_ext);
 		tmp_ext = kmalloc(extlen, GFP_ATOMIC);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index ca08ee8..662a7d9 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -619,14 +619,6 @@
 
 	ins = &fn->leaf;
 
-	if (fn->fn_flags&RTN_TL_ROOT &&
-	    fn->leaf == &ip6_null_entry &&
-	    !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){
-		fn->leaf = rt;
-		rt->u.dst.rt6_next = NULL;
-		goto out;
-	}
-
 	for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) {
 		/*
 		 *	Search for duplicates
@@ -666,7 +658,6 @@
 	 *	insert node
 	 */
 
-out:
 	rt->u.dst.rt6_next = iter;
 	*ins = rt;
 	rt->rt6i_node = fn;
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index d7ed8aa..c858537 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -104,10 +104,8 @@
 	nf_reset(skb);
 
 	if (decaps) {
-		if (!(skb->dev->flags&IFF_LOOPBACK)) {
-			dst_release(skb->dst);
-			skb->dst = NULL;
-		}
+		dst_release(skb->dst);
+		skb->dst = NULL;
 		netif_rx(skb);
 		return -1;
 	} else {
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index a6c0cdf..9fc95bc 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -80,6 +80,7 @@
 	top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
 	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
 	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+	skb->protocol = htons(ETH_P_IPV6);
 	return 0;
 }
 
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 6e36df6..4e84f24 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -2474,6 +2474,8 @@
 	if (sdata->type == IEEE80211_IF_TYPE_STA &&
 	    !local->user_space_mlme)
 		netif_carrier_off(dev);
+	else
+		netif_carrier_on(dev);
 
 	netif_start_queue(dev);
 	return 0;
@@ -3278,8 +3280,10 @@
 			return TXRX_DROP;
 		}
 	}
-	while ((skb = __skb_dequeue(&entry->skb_list)))
+	while ((skb = __skb_dequeue(&entry->skb_list))) {
 		memcpy(skb_put(rx->skb, skb->len), skb->data, skb->len);
+		dev_kfree_skb(skb);
+	}
 
 	/* Complete frame has been reassembled - process it now */
 	rx->fragmented = 1;
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 3e07e9d..9f30ae4 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -1155,6 +1155,8 @@
 	if (status_code != WLAN_STATUS_SUCCESS) {
 		printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
 		       dev->name, status_code);
+		if (status_code == WLAN_STATUS_REASSOC_NO_ASSOC)
+			ifsta->prev_bssid_set = 0;
 		return;
 	}
 
@@ -2995,7 +2997,7 @@
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
-	struct ieee80211_sub_if_data *sdata = NULL;
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
 	/* TODO: Could consider removing the least recently used entry and
 	 * allow new one to be added. */
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 02e401c..f8b8301 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -83,22 +83,6 @@
 #include <net/inet_common.h>
 #endif
 
-#define CONFIG_SOCK_PACKET	1
-
-/*
-   Proposed replacement for SIOC{ADD,DEL}MULTI and
-   IFF_PROMISC, IFF_ALLMULTI flags.
-
-   It is more expensive, but I believe,
-   it is really correct solution: reentereble, safe and fault tolerant.
-
-   IFF_PROMISC/IFF_ALLMULTI/SIOC{ADD/DEL}MULTI are faked by keeping
-   reference count and global flag, so that real status is
-   (gflag|(count != 0)), so that we can use obsolete faulty interface
-   not harming clever users.
- */
-#define CONFIG_PACKET_MULTICAST	1
-
 /*
    Assumptions:
    - if device has no dev->hard_header routine, it adds and removes ll header
@@ -159,7 +143,6 @@
 
 /* Private packet socket structures. */
 
-#ifdef CONFIG_PACKET_MULTICAST
 struct packet_mclist
 {
 	struct packet_mclist	*next;
@@ -179,7 +162,7 @@
 	unsigned short	mr_alen;
 	unsigned char	mr_address[MAX_ADDR_LEN];
 };
-#endif
+
 #ifdef CONFIG_PACKET_MMAP
 static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing);
 #endif
@@ -205,9 +188,7 @@
 				origdev:1;
 	int			ifindex;	/* bound device		*/
 	__be16			num;
-#ifdef CONFIG_PACKET_MULTICAST
 	struct packet_mclist	*mclist;
-#endif
 #ifdef CONFIG_PACKET_MMAP
 	atomic_t		mapped;
 	unsigned int            pg_vec_order;
@@ -263,7 +244,6 @@
 
 static const struct proto_ops packet_ops;
 
-#ifdef CONFIG_SOCK_PACKET
 static const struct proto_ops packet_ops_spkt;
 
 static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct packet_type *pt, struct net_device *orig_dev)
@@ -435,7 +415,6 @@
 		dev_put(dev);
 	return err;
 }
-#endif
 
 static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
 				      unsigned int res)
@@ -851,9 +830,7 @@
 		__sock_put(sk);
 	}
 
-#ifdef CONFIG_PACKET_MULTICAST
 	packet_flush_mclist(sk);
-#endif
 
 #ifdef CONFIG_PACKET_MMAP
 	if (po->pg_vec) {
@@ -936,8 +913,6 @@
  *	Bind a packet socket to a device
  */
 
-#ifdef CONFIG_SOCK_PACKET
-
 static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
 	struct sock *sk=sock->sk;
@@ -960,7 +935,6 @@
 	}
 	return err;
 }
-#endif
 
 static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
@@ -1012,11 +986,8 @@
 
 	if (!capable(CAP_NET_RAW))
 		return -EPERM;
-	if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW
-#ifdef CONFIG_SOCK_PACKET
-	    && sock->type != SOCK_PACKET
-#endif
-	    )
+	if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
+	    sock->type != SOCK_PACKET)
 		return -ESOCKTNOSUPPORT;
 
 	sock->state = SS_UNCONNECTED;
@@ -1027,10 +998,9 @@
 		goto out;
 
 	sock->ops = &packet_ops;
-#ifdef CONFIG_SOCK_PACKET
 	if (sock->type == SOCK_PACKET)
 		sock->ops = &packet_ops_spkt;
-#endif
+
 	sock_init_data(sock, sk);
 
 	po = pkt_sk(sk);
@@ -1046,10 +1016,10 @@
 
 	spin_lock_init(&po->bind_lock);
 	po->prot_hook.func = packet_rcv;
-#ifdef CONFIG_SOCK_PACKET
+
 	if (sock->type == SOCK_PACKET)
 		po->prot_hook.func = packet_rcv_spkt;
-#endif
+
 	po->prot_hook.af_packet_priv = sk;
 
 	if (proto) {
@@ -1169,7 +1139,6 @@
 	return err;
 }
 
-#ifdef CONFIG_SOCK_PACKET
 static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
 			       int *uaddr_len, int peer)
 {
@@ -1190,7 +1159,6 @@
 
 	return 0;
 }
-#endif
 
 static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
 			  int *uaddr_len, int peer)
@@ -1221,7 +1189,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_PACKET_MULTICAST
 static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int what)
 {
 	switch (i->type) {
@@ -1349,7 +1316,6 @@
 	}
 	rtnl_unlock();
 }
-#endif
 
 static int
 packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
@@ -1362,7 +1328,6 @@
 		return -ENOPROTOOPT;
 
 	switch(optname)	{
-#ifdef CONFIG_PACKET_MULTICAST
 	case PACKET_ADD_MEMBERSHIP:
 	case PACKET_DROP_MEMBERSHIP:
 	{
@@ -1383,7 +1348,7 @@
 			ret = packet_mc_drop(sk, &mreq);
 		return ret;
 	}
-#endif
+
 #ifdef CONFIG_PACKET_MMAP
 	case PACKET_RX_RING:
 	{
@@ -1506,11 +1471,10 @@
 
 		switch (msg) {
 		case NETDEV_UNREGISTER:
-#ifdef CONFIG_PACKET_MULTICAST
 			if (po->mclist)
 				packet_dev_mclist(dev, po->mclist, -1);
-			// fallthrough
-#endif
+			/* fallthrough */
+
 		case NETDEV_DOWN:
 			if (dev->ifindex == po->ifindex) {
 				spin_lock(&po->bind_lock);
@@ -1856,7 +1820,6 @@
 #endif
 
 
-#ifdef CONFIG_SOCK_PACKET
 static const struct proto_ops packet_ops_spkt = {
 	.family =	PF_PACKET,
 	.owner =	THIS_MODULE,
@@ -1877,7 +1840,6 @@
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
 };
-#endif
 
 static const struct proto_ops packet_ops = {
 	.family =	PF_PACKET,
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b8bab89..64a3751 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -26,10 +26,11 @@
 #include <net/xfrm.h>
 #include <net/ip.h>
 #include <linux/audit.h>
+#include <linux/cache.h>
 
 #include "xfrm_hash.h"
 
-int sysctl_xfrm_larval_drop;
+int sysctl_xfrm_larval_drop __read_mostly;
 
 DEFINE_MUTEX(xfrm_cfg_mutex);
 EXPORT_SYMBOL(xfrm_cfg_mutex);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9955ff4..372f06e 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -21,18 +21,21 @@
 #include <linux/cache.h>
 #include <asm/uaccess.h>
 #include <linux/audit.h>
+#include <linux/cache.h>
 
 #include "xfrm_hash.h"
 
 struct sock *xfrm_nl;
 EXPORT_SYMBOL(xfrm_nl);
 
-u32 sysctl_xfrm_aevent_etime = XFRM_AE_ETIME;
+u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME;
 EXPORT_SYMBOL(sysctl_xfrm_aevent_etime);
 
-u32 sysctl_xfrm_aevent_rseqth = XFRM_AE_SEQT_SIZE;
+u32 sysctl_xfrm_aevent_rseqth __read_mostly = XFRM_AE_SEQT_SIZE;
 EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth);
 
+u32 sysctl_xfrm_acq_expires __read_mostly = 30;
+
 /* Each xfrm_state may be linked to two tables:
 
    1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
@@ -622,8 +625,8 @@
 				h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
 				hlist_add_head(&x->byspi, xfrm_state_byspi+h);
 			}
-			x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
-			x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
+			x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
+			x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
 			add_timer(&x->timer);
 			xfrm_state_num++;
 			xfrm_hash_grow_check(x->bydst.next != NULL);
@@ -772,9 +775,9 @@
 		x->props.family = family;
 		x->props.mode = mode;
 		x->props.reqid = reqid;
-		x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
+		x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
 		xfrm_state_hold(x);
-		x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
+		x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
 		add_timer(&x->timer);
 		hlist_add_head(&x->bydst, xfrm_state_bydst+h);
 		h = xfrm_src_hash(daddr, saddr, family);
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index e1ed595..cb59f99 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -1250,7 +1250,7 @@
 			evoice->substream = substream;
 		}
 	} else {
-		if (!evoice) {
+		if (evoice) {
 			snd_ali_free_voice(codec, evoice);
 			pvoice->extra = evoice = NULL;
 		}
@@ -1267,7 +1267,7 @@
 	struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL;
 
 	snd_pcm_lib_free_pages(substream);
-	if (!evoice) {
+	if (evoice) {
 		snd_ali_free_voice(codec, evoice);
 		pvoice->extra = NULL;
 	}
@@ -1356,7 +1356,7 @@
 				 VOL,
 				 CTRL,
 				 EC);
-	if (!evoice) {
+	if (evoice) {
 		evoice->count = pvoice->count;
 		evoice->eso = pvoice->count << 1;
 		ESO = evoice->eso - 1;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 8e89d56..f87f8f0 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -713,6 +713,19 @@
 	return info->amp_caps;
 }
 
+int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
+			      unsigned int caps)
+{
+	struct hda_amp_info *info;
+
+	info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, dir, 0));
+	if (!info)
+		return -EINVAL;
+	info->amp_caps = caps;
+	info->status |= INFO_AMP_CAPS;
+	return 0;
+}
+
 /*
  * read the current volume to info
  * if the cache exists, read the cache value.
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index be12b88..f91ea5e 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -277,5 +277,7 @@
 	return codec->wcaps[nid - codec->start_nid];
 }
 
+int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
+			      unsigned int caps);
 
 #endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index a5a4b2bd..bef214b 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -705,6 +705,17 @@
 		.get = conexant_mux_enum_get,
 		.put = conexant_mux_enum_put,
 	},
+	/* Audio input controls */
+	HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
+	HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
+	HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
+	HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
+	HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
 	{ } /* end */
 };
 
@@ -947,6 +958,23 @@
 	snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits);
 }
 
+/* mute internal speaker if HP is plugged */
+static void cxt5047_hp2_automute(struct hda_codec *codec)
+{
+	struct conexant_spec *spec = codec->spec;
+	unsigned int bits;
+
+	spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+
+	bits = spec->hp_present ? 0x80 : 0;
+	snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits);
+	/* Mute/Unmute PCM 2 for good measure - some systems need this */
+	snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits);
+}
+
 /* toggle input of built-in and mic jack appropriately */
 static void cxt5047_hp_automic(struct hda_codec *codec)
 {
@@ -985,6 +1013,21 @@
 	}
 }
 
+/* unsolicited event for HP jack sensing - non-EAPD systems */
+static void cxt5047_hp2_unsol_event(struct hda_codec *codec,
+				  unsigned int res)
+{
+	res >>= 26;
+	switch (res) {
+	case CONEXANT_HP_EVENT:
+		cxt5047_hp2_automute(codec);
+		break;
+	case CONEXANT_MIC_EVENT:
+		cxt5047_hp_automic(codec);
+		break;
+	}
+}
+
 static struct snd_kcontrol_new cxt5047_mixers[] = {
 	HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
 	HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT),
@@ -1300,19 +1343,20 @@
 	spec->channel_mode = cxt5047_modes,
 
 	codec->patch_ops = conexant_patch_ops;
-	codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
 
 	board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
 						  cxt5047_models,
 						  cxt5047_cfg_tbl);
 	switch (board_config) {
 	case CXT5047_LAPTOP:
+		codec->patch_ops.unsol_event = cxt5047_hp2_unsol_event;
 		break;
 	case CXT5047_LAPTOP_HP:
 		spec->input_mux = &cxt5047_hp_capture_source;
 		spec->num_init_verbs = 2;
 		spec->init_verbs[1] = cxt5047_hp_init_verbs;
 		spec->mixers[0] = cxt5047_hp_mixers;
+		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
 		codec->patch_ops.init = cxt5047_hp_init;
 		break;
 	case CXT5047_LAPTOP_EAPD:
@@ -1320,12 +1364,14 @@
 		spec->num_init_verbs = 2;
 		spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
 		spec->mixers[0] = cxt5047_toshiba_mixers;
+		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
 		break;
 #ifdef CONFIG_SND_DEBUG
 	case CXT5047_TEST:
 		spec->input_mux = &cxt5047_test_capture_source;
 		spec->mixers[0] = cxt5047_test_mixer;
 		spec->init_verbs[0] = cxt5047_test_init_verbs;
+		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
 #endif	
 	}
 	return 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 34ac634..4776de9 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -6379,8 +6379,10 @@
 	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
+	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
+	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
 	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
 	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
 	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
@@ -6391,6 +6393,7 @@
 	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
 	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
 	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
+	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
 	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
 	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
@@ -8765,7 +8768,6 @@
 	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
 	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
 	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
-	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST),
 	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
 	SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
 	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
@@ -9473,6 +9475,7 @@
 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
 	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
+	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST),
 	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
 	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
 
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 6fcda9b..43f537e 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -304,6 +304,8 @@
  	{ .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 },
  	{ .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 },
  	{ .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 },
+	/* Asus A8J Modem (SM56) */
+	{ .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 },
 	{}
 };
 
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index a6a0a80..e3964fc 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -51,6 +51,7 @@
 	STAC_925x_REF,
 	STAC_M2_2,
 	STAC_MA6,
+	STAC_PA6,
 	STAC_925x_MODELS
 };
 
@@ -152,6 +153,10 @@
         0x02,
 };
 
+static hda_nid_t stac925x_dmic_nids[1] = {
+	0x15, 
+};
+
 static hda_nid_t stac922x_adc_nids[2] = {
         0x06, 0x07,
 };
@@ -469,6 +474,14 @@
 		      "Dell Precision M90", STAC_REF),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
 		      "unknown Dell", STAC_REF),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
+		      "Dell Inspiron 640m", STAC_REF),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
+		      "Dell Inspiron 1501", STAC_REF),
+
+	/* Panasonic */
+	SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
+
 	{} /* terminator */
 };
 
@@ -482,29 +495,38 @@
 	0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
 };
 
+static unsigned int stac925x_PA6_pin_configs[8] = {
+	0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
+	0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e,
+};
+
 static unsigned int stac925xM2_2_pin_configs[8] = {
-	0x40c003f3, 0x424503f2, 0x041800f4, 0x02a19020,
-	0x50a103F0, 0x90100210, 0x400003f1, 0x9033032e,
+	0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020,
+	0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e,
 };
 
 static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
 	[STAC_REF] = ref925x_pin_configs,
 	[STAC_M2_2] = stac925xM2_2_pin_configs,
 	[STAC_MA6] = stac925x_MA6_pin_configs,
+	[STAC_PA6] = stac925x_PA6_pin_configs,
 };
 
 static const char *stac925x_models[STAC_925x_MODELS] = {
 	[STAC_REF] = "ref",
 	[STAC_M2_2] = "m2-2",
 	[STAC_MA6] = "m6",
+	[STAC_PA6] = "pa6",
 };
 
 static struct snd_pci_quirk stac925x_cfg_tbl[] = {
 	/* SigmaTel reference board */
 	SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
+	SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
 	SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
 	SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
 	SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
+	SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6),
 	SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
 	{} /* terminator */
 };
@@ -1742,6 +1764,21 @@
 	unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
 			0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
 
+	if (pin_ctl & AC_PINCTL_IN_EN) {
+		/*
+		 * we need to check the current set-up direction of
+		 * shared input pins since they can be switched via
+		 * "xxx as Output" mixer switch
+		 */
+		struct sigmatel_spec *spec = codec->spec;
+		struct auto_pin_cfg *cfg = &spec->autocfg;
+		if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
+		     spec->line_switch) ||
+		    (nid == cfg->input_pins[AUTO_PIN_MIC] &&
+		     spec->mic_switch))
+			return;
+	}
+
 	/* if setting pin direction bits, clear the current
 	   direction bits first */
 	if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
@@ -1911,7 +1948,8 @@
 							stac925x_cfg_tbl);
  again:
 	if (spec->board_config < 0) {
-		snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x, using BIOS defaults\n");
+		snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," 
+				      "using BIOS defaults\n");
 		err = stac92xx_save_bios_config_regs(codec);
 		if (err < 0) {
 			stac92xx_free(codec);
@@ -1929,7 +1967,18 @@
 	spec->adc_nids = stac925x_adc_nids;
 	spec->mux_nids = stac925x_mux_nids;
 	spec->num_muxes = 1;
-	spec->num_dmics = 0;
+	switch (codec->vendor_id) {
+	case 0x83847632: /* STAC9202  */
+	case 0x83847633: /* STAC9202D */
+	case 0x83847636: /* STAC9251  */
+	case 0x83847637: /* STAC9251D */
+		spec->num_dmics = 1;
+		spec->dmic_nids = stac925x_dmic_nids;
+		break;
+	default:
+		spec->num_dmics = 0;
+		break;
+	}
 
 	spec->init = stac925x_core_init;
 	spec->mixer = stac925x_mixer;
@@ -2110,6 +2159,13 @@
 
 	codec->patch_ops = stac92xx_patch_ops;
 
+	/* Fix Mux capture level; max to 2 */
+	snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
+				  (0 << AC_AMPCAP_OFFSET_SHIFT) |
+				  (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+				  (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+				  (0 << AC_AMPCAP_MUTE_SHIFT));
+
 	return 0;
 }
 
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index 21dc697..bfbdc3c 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -337,6 +337,8 @@
 	if (prtd == NULL)
 		return -ENOMEM;
 
+	spin_lock_init(&prtd->lock);
+
 	runtime->private_data = prtd;
 	return 0;
 }