Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
diff --git a/.gitignore b/.gitignore
index e1d5c17..9eb4b77 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@
 # Top-level generic files
 #
 tags
+TAGS
 vmlinux*
 System.map
 Module.symvers
diff --git a/CREDITS b/CREDITS
index 5329ead..ccd4f9f 100644
--- a/CREDITS
+++ b/CREDITS
@@ -45,7 +45,7 @@
 S: Sydney, Australia
 
 N: Tigran A. Aivazian
-E: tigran@veritas.com
+E: tigran@aivazian.fsnet.co.uk
 W: http://www.moses.uklinux.net/patches
 D: BFS filesystem
 D: Intel IA32 CPU microcode update support
@@ -3511,14 +3511,12 @@
 
 N: David Weinehall
 E: tao@acc.umu.se
+P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36  E1D1 D14E 8526 DC47 CA16
 W: http://www.acc.umu.se/~tao/
-W: http://www.acc.umu.se/~mcalinux/
+D: v2.0 kernel maintainer
 D: Fixes for the NE/2-driver
 D: Miscellaneous MCA-support
 D: Cleanup of the Config-files
-S: Axtorpsvagen 40:20
-S: S-903 37  UMEA
-S: Sweden
 
 N: Matt Welsh
 E: mdw@metalab.unc.edu
diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power
index d882f80..dcff4d0 100644
--- a/Documentation/ABI/testing/sysfs-power
+++ b/Documentation/ABI/testing/sysfs-power
@@ -21,7 +21,7 @@
 		these states.
 
 What:		/sys/power/disk
-Date:		August 2006
+Date:		September 2006
 Contact:	Rafael J. Wysocki <rjw@sisk.pl>
 Description:
 		The /sys/power/disk file controls the operating mode of the
@@ -39,6 +39,19 @@
 		'reboot' - the memory image will be saved by the kernel and
 		the system will be rebooted.
 
+		Additionally, /sys/power/disk can be used to turn on one of the
+		two testing modes of the suspend-to-disk mechanism: 'testproc'
+		or 'test'.  If the suspend-to-disk mechanism is in the
+		'testproc' mode, writing 'disk' to /sys/power/state will cause
+		the kernel to disable nonboot CPUs and freeze tasks, wait for 5
+		seconds, unfreeze tasks and enable nonboot CPUs.  If it is in
+		the 'test' mode, writing 'disk' to /sys/power/state will cause
+		the kernel to disable nonboot CPUs and freeze tasks, shrink
+		memory, suspend devices, wait for 5 seconds, resume devices,
+		unfreeze tasks and enable nonboot CPUs.  Then, we are able to
+		look in the log messages and work out, for example, which code
+		is being slow and which device drivers are misbehaving.
+
 		The suspend-to-disk method may be chosen by writing to this
 		file one of the accepted strings:
 
@@ -46,6 +59,8 @@
 		'platform'
 		'shutdown'
 		'reboot'
+		'testproc'
+		'test'
 
 		It will only change to 'firmware' or 'platform' if the system
 		supports that.
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 66e1cf7..db9499a 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -9,7 +9,7 @@
 DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
 	    kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
 	    procfs-guide.xml writing_usb_driver.xml \
-	    kernel-api.xml journal-api.xml lsm.xml usb.xml \
+	    kernel-api.xml filesystems.xml lsm.xml usb.xml \
 	    gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
 	    genericirq.xml
 
diff --git a/Documentation/DocBook/journal-api.tmpl b/Documentation/DocBook/filesystems.tmpl
similarity index 78%
rename from Documentation/DocBook/journal-api.tmpl
rename to Documentation/DocBook/filesystems.tmpl
index 2077f9a..39fa2ab 100644
--- a/Documentation/DocBook/journal-api.tmpl
+++ b/Documentation/DocBook/filesystems.tmpl
@@ -2,9 +2,106 @@
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
 	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
 
-<book id="LinuxJBDAPI">
+<book id="Linux-filesystems-API">
  <bookinfo>
+  <title>Linux Filesystems API</title>
+
+  <legalnotice>
+   <para>
+     This documentation is free software; you can redistribute
+     it and/or modify it under the terms of the GNU General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later
+     version.
+   </para>
+
+   <para>
+     This program is distributed in the hope that it will be
+     useful, but WITHOUT ANY WARRANTY; without even the implied
+     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+     See the GNU General Public License for more details.
+   </para>
+
+   <para>
+     You should have received a copy of the GNU General Public
+     License along with this program; if not, write to the Free
+     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+     MA 02111-1307 USA
+   </para>
+
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="vfs">
+     <title>The Linux VFS</title>
+     <sect1><title>The Filesystem types</title>
+!Iinclude/linux/fs.h
+     </sect1>
+     <sect1><title>The Directory Cache</title>
+!Efs/dcache.c
+!Iinclude/linux/dcache.h
+     </sect1>
+     <sect1><title>Inode Handling</title>
+!Efs/inode.c
+!Efs/bad_inode.c
+     </sect1>
+     <sect1><title>Registration and Superblocks</title>
+!Efs/super.c
+     </sect1>
+     <sect1><title>File Locks</title>
+!Efs/locks.c
+!Ifs/locks.c
+     </sect1>
+     <sect1><title>Other Functions</title>
+!Efs/mpage.c
+!Efs/namei.c
+!Efs/buffer.c
+!Efs/bio.c
+!Efs/seq_file.c
+!Efs/filesystems.c
+!Efs/fs-writeback.c
+!Efs/block_dev.c
+     </sect1>
+  </chapter>
+
+  <chapter id="proc">
+     <title>The proc filesystem</title>
+
+     <sect1><title>sysctl interface</title>
+!Ekernel/sysctl.c
+     </sect1>
+
+     <sect1><title>proc filesystem interface</title>
+!Ifs/proc/base.c
+     </sect1>
+  </chapter>
+
+  <chapter id="sysfs">
+     <title>The Filesystem for Exporting Kernel Objects</title>
+!Efs/sysfs/file.c
+!Efs/sysfs/symlink.c
+!Efs/sysfs/bin.c
+  </chapter>
+
+  <chapter id="debugfs">
+     <title>The debugfs filesystem</title>
+
+     <sect1><title>debugfs interface</title>
+!Efs/debugfs/inode.c
+!Efs/debugfs/file.c
+     </sect1>
+  </chapter>
+
+  <chapter id="LinuxJDBAPI">
+  <chapterinfo>
   <title>The Linux Journalling API</title>
+
   <authorgroup>
   <author>
      <firstname>Roger</firstname>
@@ -14,9 +111,9 @@
       <email>rgammans@computer-surgery.co.uk</email>
      </address>
     </affiliation>
-     </author> 
+     </author>
   </authorgroup>
-  
+
   <authorgroup>
    <author>
     <firstname>Stephen</firstname>
@@ -33,50 +130,21 @@
    <year>2002</year>
    <holder>Roger Gammans</holder>
   </copyright>
+  </chapterinfo>
 
-<legalnotice>
-   <para>
-     This documentation is free software; you can redistribute
-     it and/or modify it under the terms of the GNU General Public
-     License as published by the Free Software Foundation; either
-     version 2 of the License, or (at your option) any later
-     version.
-   </para>
-      
-   <para>
-     This program is distributed in the hope that it will be
-     useful, but WITHOUT ANY WARRANTY; without even the implied
-     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-     See the GNU General Public License for more details.
-   </para>
-      
-   <para>
-     You should have received a copy of the GNU General Public
-     License along with this program; if not, write to the Free
-     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-     MA 02111-1307 USA
-   </para>
-      
-   <para>
-     For more details see the file COPYING in the source
-     distribution of Linux.
-   </para>
-  </legalnotice>
- </bookinfo>
+  <title>The Linux Journalling API</title>
 
-<toc></toc>
-
-  <chapter id="Overview">
+    <sect1>
      <title>Overview</title>
-  <sect1>
+    <sect2>
      <title>Details</title>
 <para>
-The journalling layer is  easy to use. You need to 
+The journalling layer is  easy to use. You need to
 first of all create a journal_t data structure. There are
 two calls to do this dependent on how you decide to allocate the physical
-media on which the journal resides. The journal_init_inode() call 
+media on which the journal resides. The journal_init_inode() call
 is for journals stored in filesystem inodes, or the journal_init_dev()
-call can be use for journal stored on a raw device (in a continuous range 
+call can be use for journal stored on a raw device (in a continuous range
 of blocks). A journal_t is a typedef for a struct pointer, so when
 you are finally finished make sure you call journal_destroy() on it
 to free up any used kernel memory.
@@ -91,27 +159,26 @@
 <para>
 Most of the time however your journal file will already have been created, but
 before you load it you must call journal_wipe() to empty the journal file.
-Hang on, you say , what if the filesystem wasn't cleanly umount()'d . Well, it is the 
+Hang on, you say , what if the filesystem wasn't cleanly umount()'d . Well, it is the
 job of the client file system to detect this and skip the call to journal_wipe().
 </para>
 
 <para>
 In either case the next call should be to journal_load() which prepares the
-journal file for use. Note that journal_wipe(..,0) calls journal_skip_recovery() 
+journal file for use. Note that journal_wipe(..,0) calls journal_skip_recovery()
 for you if it detects any outstanding transactions in the journal and similarly
 journal_load() will call journal_recover() if necessary.
 I would advise reading fs/ext3/super.c for examples on this stage.
-[RGG: Why is the journal_wipe() call necessary - doesn't this needlessly 
-complicate the API. Or isn't a good idea for the journal layer to hide 
+[RGG: Why is the journal_wipe() call necessary - doesn't this needlessly
+complicate the API. Or isn't a good idea for the journal layer to hide
 dirty mounts from the client fs]
 </para>
 
 <para>
-Now you can go ahead and start modifying the underlying 
+Now you can go ahead and start modifying the underlying
 filesystem. Almost.
 </para>
 
-
 <para>
 
 You still need to actually journal your filesystem changes, this
@@ -138,10 +205,10 @@
 need to call journal_get_{create,write,undo}_access() as appropriate,
 this allows the journalling layer to copy the unmodified data if it
 needs to. After all the buffer may be part of a previously uncommitted
-transaction. 
+transaction.
 At this point you are at last ready to modify a buffer, and once
 you are have done so you need to call journal_dirty_{meta,}data().
-Or if you've asked for access to a buffer you now know is now longer 
+Or if you've asked for access to a buffer you now know is now longer
 required to be pushed back on the device you can call journal_forget()
 in much the same way as you might have used bforget() in the past.
 </para>
@@ -156,7 +223,6 @@
 you can then call journal_destroy() to clean up your in-core journal object.
 </para>
 
-
 <para>
 Unfortunately there a couple of ways the journal layer can cause a deadlock.
 The first thing to note is that each task can only have
@@ -164,19 +230,19 @@
 commits until the outermost journal_stop(). This means
 you must complete the transaction at the end of each file/inode/address
 etc. operation you perform, so that the journalling system isn't re-entered
-on another journal. Since transactions can't be nested/batched 
+on another journal. Since transactions can't be nested/batched
 across differing journals, and another filesystem other than
 yours (say ext3) may be modified in a later syscall.
 </para>
 
 <para>
-The second case to bear in mind is that journal_start() can 
-block if there isn't enough space in the journal for your transaction 
+The second case to bear in mind is that journal_start() can
+block if there isn't enough space in the journal for your transaction
 (based on the passed nblocks param) - when it blocks it merely(!) needs to
-wait for transactions to complete and be committed from other tasks, 
-so essentially we are waiting for journal_stop(). So to avoid 
+wait for transactions to complete and be committed from other tasks,
+so essentially we are waiting for journal_stop(). So to avoid
 deadlocks you must treat journal_start/stop() as if they
-were semaphores and include them in your semaphore ordering rules to prevent 
+were semaphores and include them in your semaphore ordering rules to prevent
 deadlocks. Note that journal_extend() has similar blocking behaviour to
 journal_start() so you can deadlock here just as easily as on journal_start().
 </para>
@@ -184,7 +250,7 @@
 <para>
 Try to reserve the right number of blocks the first time. ;-). This will
 be the maximum number of blocks you are going to touch in this transaction.
-I advise having a look at at least ext3_jbd.h to see the basis on which 
+I advise having a look at at least ext3_jbd.h to see the basis on which
 ext3 uses to make these decisions.
 </para>
 
@@ -193,13 +259,13 @@
 why? Because, if you undo a delete, you need to ensure you haven't reused any
 of the freed blocks in a later transaction. One simple way of doing this
 is make sure any blocks you allocate only have checkpointed transactions
-listed against them. Ext3 does this in ext3_test_allocatable(). 
+listed against them. Ext3 does this in ext3_test_allocatable().
 </para>
 
 <para>
 Lock is also providing through journal_{un,}lock_updates(),
 ext3 uses this when it wants a window with a clean and stable fs for a moment.
-eg. 
+eg.
 </para>
 
 <programlisting>
@@ -230,19 +296,19 @@
 		struct journal_callback for_jbd;
 		// Stuff for myfs allocated together.
 		myfs_inode*    i_commited;
-	
+
 	}
 </programlisting>
 
 <para>
-this would be useful if you needed to know when data was committed to a 
+this would be useful if you needed to know when data was committed to a
 particular inode.
 </para>
 
-</sect1>
+    </sect2>
 
-<sect1>
-<title>Summary</title>
+    <sect2>
+     <title>Summary</title>
 <para>
 Using the journal is a matter of wrapping the different context changes,
 being each mount, each modification (transaction) and each changed buffer
@@ -260,15 +326,15 @@
   if (clean) journal_wipe();
   journal_load();
 
-   foreach(transaction) { /*transactions must be 
+   foreach(transaction) { /*transactions must be
                             completed before
-                            a syscall returns to 
+                            a syscall returns to
                             userspace*/
 
           handle_t * xct=journal_start(my_jnrl);
           foreach(bh) {
                 journal_get_{create,write,undo}_access(xact,bh);
-                if ( myfs_modify(bh) ) { /* returns true 
+                if ( myfs_modify(bh) ) { /* returns true
                                         if makes changes */
                            journal_dirty_{meta,}data(xact,bh);
                 } else {
@@ -279,55 +345,57 @@
    }
    journal_destroy(my_jrnl);
 </programlisting>
-</sect1>
+    </sect2>
 
-</chapter>
+    </sect1>
 
-  <chapter id="adt">
+    <sect1>
      <title>Data Types</title>
-     <para>	
+     <para>
 	The journalling layer uses typedefs to 'hide' the concrete definitions
 	of the structures used. As a client of the JBD layer you can
 	just rely on the using the pointer as a magic cookie  of some sort.
-	
-	Obviously the hiding is not enforced as this is 'C'.
-	</para>
-	<sect1><title>Structures</title>
-!Iinclude/linux/jbd.h
-	</sect1>
-</chapter>
 
-  <chapter id="calls">
+	Obviously the hiding is not enforced as this is 'C'.
+     </para>
+	<sect2><title>Structures</title>
+!Iinclude/linux/jbd.h
+	</sect2>
+    </sect1>
+
+    <sect1>
      <title>Functions</title>
-     <para>	
+     <para>
 	The functions here are split into two groups those that
 	affect a journal as a whole, and those which are used to
 	manage transactions
-</para>
-	<sect1><title>Journal Level</title>
+     </para>
+	<sect2><title>Journal Level</title>
 !Efs/jbd/journal.c
 !Ifs/jbd/recovery.c
-	</sect1>
-	<sect1><title>Transasction Level</title>
-!Efs/jbd/transaction.c	
-	</sect1>
-</chapter>
-<chapter>
+	</sect2>
+	<sect2><title>Transasction Level</title>
+!Efs/jbd/transaction.c
+	</sect2>
+    </sect1>
+    <sect1>
      <title>See also</title>
 	<para>
-	<citation>
+	  <citation>
 	   <ulink url="ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/journal-design.ps.gz">
-	   	Journaling the Linux ext2fs Filesystem,LinuxExpo 98, Stephen Tweedie
+	   	Journaling the Linux ext2fs Filesystem, LinuxExpo 98, Stephen Tweedie
 	   </ulink>
-	   </citation>
-	   </para>
-	   <para>
+	  </citation>
+	</para>
+	<para>
 	   <citation>
 	   <ulink url="http://olstrans.sourceforge.net/release/OLS2000-ext3/OLS2000-ext3.html">
-	   	Ext3 Journalling FileSystem , OLS 2000, Dr. Stephen Tweedie
+	   	Ext3 Journalling FileSystem, OLS 2000, Dr. Stephen Tweedie
 	   </ulink>
 	   </citation>
-	   </para>
-</chapter>
+	</para>
+    </sect1>
+
+  </chapter>
 
 </book>
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 2b5ac60..a166675 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -182,66 +182,6 @@
      </sect1>
   </chapter>
 
-  <chapter id="vfs">
-     <title>The Linux VFS</title>
-     <sect1><title>The Filesystem types</title>
-!Iinclude/linux/fs.h
-     </sect1>
-     <sect1><title>The Directory Cache</title>
-!Efs/dcache.c
-!Iinclude/linux/dcache.h
-     </sect1>
-     <sect1><title>Inode Handling</title>
-!Efs/inode.c
-!Efs/bad_inode.c
-     </sect1>
-     <sect1><title>Registration and Superblocks</title>
-!Efs/super.c
-     </sect1>
-     <sect1><title>File Locks</title>
-!Efs/locks.c
-!Ifs/locks.c
-     </sect1>
-     <sect1><title>Other Functions</title>
-!Efs/mpage.c
-!Efs/namei.c
-!Efs/buffer.c
-!Efs/bio.c
-!Efs/seq_file.c
-!Efs/filesystems.c
-!Efs/fs-writeback.c
-!Efs/block_dev.c
-     </sect1>
-  </chapter>
-
-  <chapter id="proc">
-     <title>The proc filesystem</title>
- 
-     <sect1><title>sysctl interface</title>
-!Ekernel/sysctl.c
-     </sect1>
-
-     <sect1><title>proc filesystem interface</title>
-!Ifs/proc/base.c
-     </sect1>
-  </chapter>
-
-  <chapter id="sysfs">
-     <title>The Filesystem for Exporting Kernel Objects</title>
-!Efs/sysfs/file.c
-!Efs/sysfs/symlink.c
-!Efs/sysfs/bin.c
-  </chapter>
-
-  <chapter id="debugfs">
-     <title>The debugfs filesystem</title>
- 
-     <sect1><title>debugfs interface</title>
-!Efs/debugfs/inode.c
-!Efs/debugfs/file.c
-     </sect1>
-  </chapter>
-
   <chapter id="relayfs">
      <title>relay interface support</title>
 
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index b11792a..bf2b0e2 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -49,7 +49,7 @@
 	}
 
 /* Maximum size of response requested or message sent */
-#define MAX_MSG_SIZE	256
+#define MAX_MSG_SIZE	1024
 /* Maximum number of cpus expected to be specified in a cpumask */
 #define MAX_CPUS	32
 /* Maximum length of pathname to log file */
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 1ac3c74..d52c4aa 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -53,18 +53,6 @@
 
 ---------------------------
 
-What:	sys_sysctl
-When:	January 2007
-Why:	The same information is available through /proc/sys and that is the
-	interface user space prefers to use. And there do not appear to be
-	any existing user in user space of sys_sysctl.  The additional
-	maintenance overhead of keeping a set of binary names gets
-	in the way of doing a good job of maintaining this interface.
-
-Who:	Eric Biederman <ebiederm@xmission.com>
-
----------------------------
-
 What:	PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
 When:	November 2005
 Files:	drivers/pcmcia/: pcmcia_ioctl.c
diff --git a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt
index 511b423..fde829a 100644
--- a/Documentation/filesystems/udf.txt
+++ b/Documentation/filesystems/udf.txt
@@ -7,8 +7,17 @@
 please report them to linux_udf@hpesjro.fc.hp.com, which is the
 developer's list.
 
-Write support requires a block driver which supports writing. The current
-scsi and ide cdrom drivers do not support writing.
+Write support requires a block driver which supports writing.  Currently
+dvd+rw drives and media support true random sector writes, and so a udf
+filesystem on such devices can be directly mounted read/write.  CD-RW
+media however, does not support this.  Instead the media can be formatted
+for packet mode using the utility cdrwtool, then the pktcdvd driver can
+be bound to the underlying cd device to provide the required buffering
+and read-modify-write cycles to allow the filesystem random sector writes
+while providing the hardware with only full packet writes.  While not
+required for dvd+rw media, use of the pktcdvd driver often enhances
+performance due to very poor read-modify-write support supplied internally
+by drive firmware.
 
 -------------------------------------------------------------------------------
 The following mount options are supported:
diff --git a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt
index c65233d..284e7e1 100644
--- a/Documentation/kernel-doc-nano-HOWTO.txt
+++ b/Documentation/kernel-doc-nano-HOWTO.txt
@@ -17,7 +17,7 @@
   special place-holders for where the extracted documentation should
   go.
 
-- scripts/docproc.c
+- scripts/basic/docproc.c
 
   This is a program for converting SGML template files into SGML
   files. When a file is referenced it is searched for symbols
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index dd00fd5..6747384 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -164,6 +164,10 @@
 	acpi_skip_timer_override [HW,ACPI]
 			Recognize and ignore IRQ0/pin2 Interrupt Override.
 			For broken nForce2 BIOS resulting in XT-PIC timer.
+	acpi_use_timer_override [HW,ACPI}
+			Use timer override. For some broken Nvidia NF5 boards
+			that require a timer override, but don't have
+			HPET
 
 	acpi_dbg_layer=	[HW,ACPI]
 			Format: <int>
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index ba26201..d71faff 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -442,9 +442,10 @@
 	kp.fault_handler = handler_fault;
 	kp.symbol_name = "do_fork";
 
-	if ((ret = register_kprobe(&kp) < 0)) {
+	ret = register_kprobe(&kp);
+	if (ret < 0) {
 		printk("register_kprobe failed, returned %d\n", ret);
-		return -1;
+		return ret;
 	}
 	printk("kprobe registered\n");
 	return 0;
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 7f790f6..7751704 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -1016,7 +1016,7 @@
 
  (*) set_mb(var, value)
 
-     This assigns the value to the variable and then inserts at least a write
+     This assigns the value to the variable and then inserts a full memory
      barrier after it, depending on the function.  It isn't guaranteed to
      insert anything more than a compiler barrier in a UP compilation.
 
diff --git a/Documentation/mips/time.README b/Documentation/mips/time.README
index 69ddc5c..a4ce603 100644
--- a/Documentation/mips/time.README
+++ b/Documentation/mips/time.README
@@ -38,19 +38,14 @@
 
   a) Implements functions required by Linux common code:
 	time_init
-	do_gettimeofday
-	do_settimeofday
 
   b) provides an abstraction of RTC and null RTC implementation as default.
 	extern unsigned long (*rtc_get_time)(void);
 	extern int (*rtc_set_time)(unsigned long);
 
-  c) a set of gettimeoffset functions for different CPUs and different
-     needs.
-
-  d) high-level and low-level timer interrupt routines where the timer 
-     interrupt source  may or may not be the CPU timer.  The high-level 
-     routine is dispatched through do_IRQ() while the low-level is 
+  c) high-level and low-level timer interrupt routines where the timer
+     interrupt source  may or may not be the CPU timer.  The high-level
+     routine is dispatched through do_IRQ() while the low-level is
      dispatched in assemably code (usually int-handler.S)
 
 
@@ -63,7 +58,7 @@
   a) board_time_init - a function pointer.  Invoked at the beginnig of
      time_init().  It is optional.
 	1. (optional) set up RTC routines
-	2. (optional) calibrate and set the mips_counter_frequency
+	2. (optional) calibrate and set the mips_hpt_frequency
 
   b) plat_timer_setup - a function pointer.  Invoked at the end of time_init()
 	1. (optional) over-ride any decisions made in time_init()
@@ -72,9 +67,8 @@
 
   c) (optional) board-specific RTC routines.
 
-  d) (optional) mips_counter_frequency - It must be definied if the board
-     is using CPU counter for timer interrupt or it is using fixed rate
-     gettimeoffset().
+  d) (optional) mips_hpt_frequency - It must be definied if the board
+     is using CPU counter for timer interrupt.
 
 
 PORTING GUIDE
@@ -89,22 +83,12 @@
      If the answer is no, you need a timer to provide the timer interrupt
      at 100 HZ speed.
 
-     You cannot use the fast gettimeoffset functions, i.e.,
-
-	unsigned long fixed_rate_gettimeoffset(void);
-	unsigned long calibrate_div32_gettimeoffset(void);
-	unsigned long calibrate_div64_gettimeoffset(void);
-
-    You can use null_gettimeoffset() will gives the same time resolution as
-    jiffy.  Or you can implement your own gettimeoffset (probably based on 
-    some ad hoc hardware on your machine.)
-
   c) The following sub steps assume your CPU has counter register.
      Do you plan to use the CPU counter register as the timer interrupt
      or use an exnternal timer?
 
      In order to use CPU counter register as the timer interrupt source, you
-     must know the counter speed (mips_counter_frequency).  It is usually the
+     must know the counter speed (mips_hpt_frequency).  It is usually the
      same as the CPU speed or an integral divisor of it.
 
   d) decide on whether you want to use high-level or low-level timer
@@ -121,10 +105,10 @@
   if needed.
 
   board_time_init() -
-  	a) (optional) set up RTC routines, 
-        b) (optional) calibrate and set the mips_counter_frequency
- 	    (only needed if you intended to use fixed_rate_gettimeoffset
- 	     or use cpu counter as timer interrupt source)
+  	a) (optional) set up RTC routines,
+        b) (optional) calibrate and set the mips_hpt_frequency
+ 	    (only needed if you intended to use cpu counter as timer interrupt
+ 	     source)
 
   plat_timer_setup() -
  	a) (optional) over-write any choices made above by time_init().
@@ -154,8 +138,8 @@
 For example, you may define your own timer interrupt routine, which does
 some of its own processing and then calls timer_interrupt().
 
-You can also over-ride any of the built-in functions (gettimeoffset,
-RTC routines and/or timer interrupt routine).
+You can also over-ride any of the built-in functions (RTC routines
+and/or timer interrupt routine).
 
 
 PORTING NOTES FOR SMP
@@ -187,10 +171,3 @@
 
 	You can also do the low-level version of those interrupt routines,
 	following similar dispatching routes described above.
-
-Note about do_gettimeoffset():
-
-  It is very likely the CPU counter registers are not sync'ed up in a SMP box.
-  Therefore you cannot really use the many of the existing routines that
-  are based on CPU counter.  You should wirte your own gettimeoffset rouinte
-  if you want intra-jiffy resolution.
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
index a66bec2..74311d7 100644
--- a/Documentation/power/interface.txt
+++ b/Documentation/power/interface.txt
@@ -30,6 +30,17 @@
 that is known a priori. But, the user may choose 'shutdown' or
 'reboot' as alternatives. 
 
+Additionally, /sys/power/disk can be used to turn on one of the two testing
+modes of the suspend-to-disk mechanism: 'testproc' or 'test'.  If the
+suspend-to-disk mechanism is in the 'testproc' mode, writing 'disk' to
+/sys/power/state will cause the kernel to disable nonboot CPUs and freeze
+tasks, wait for 5 seconds, unfreeze tasks and enable nonboot CPUs.  If it is
+in the 'test' mode, writing 'disk' to /sys/power/state will cause the kernel
+to disable nonboot CPUs and freeze tasks, shrink memory, suspend devices, wait
+for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs.  Then,
+we are able to look in the log messages and work out, for example, which code
+is being slow and which device drivers are misbehaving.
+
 Reading from this file will display what the mode is currently set
 to. Writing to this file will accept one of
 
@@ -37,6 +48,8 @@
        'platform'
        'shutdown'
        'reboot'
+       'testproc'
+       'test'
 
 It will only change to 'firmware' or 'platform' if the system supports
 it. 
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt
index 2a58f98..7cf1ec5 100644
--- a/Documentation/rtc.txt
+++ b/Documentation/rtc.txt
@@ -1,12 +1,49 @@
 
-	Real Time Clock Driver for Linux
-	================================
+	Real Time Clock (RTC) Drivers for Linux
+	=======================================
+
+When Linux developers talk about a "Real Time Clock", they usually mean
+something that tracks wall clock time and is battery backed so that it
+works even with system power off.  Such clocks will normally not track
+the local time zone or daylight savings time -- unless they dual boot
+with MS-Windows -- but will instead be set to Coordinated Universal Time
+(UTC, formerly "Greenwich Mean Time").
+
+The newest non-PC hardware tends to just count seconds, like the time(2)
+system call reports, but RTCs also very commonly represent time using
+the Gregorian calendar and 24 hour time, as reported by gmtime(3).
+
+Linux has two largely-compatible userspace RTC API families you may
+need to know about:
+
+    *	/dev/rtc ... is the RTC provided by PC compatible systems,
+	so it's not very portable to non-x86 systems.
+
+    *	/dev/rtc0, /dev/rtc1 ... are part of a framework that's
+	supported by a wide variety of RTC chips on all systems.
+
+Programmers need to understand that the PC/AT functionality is not
+always available, and some systems can do much more.  That is, the
+RTCs use the same API to make requests in both RTC frameworks (using
+different filenames of course), but the hardware may not offer the
+same functionality.  For example, not every RTC is hooked up to an
+IRQ, so they can't all issue alarms; and where standard PC RTCs can
+only issue an alarm up to 24 hours in the future, other hardware may
+be able to schedule one any time in the upcoming century.
+
+
+	Old PC/AT-Compatible driver:  /dev/rtc
+	--------------------------------------
 
 All PCs (even Alpha machines) have a Real Time Clock built into them.
 Usually they are built into the chipset of the computer, but some may
 actually have a Motorola MC146818 (or clone) on the board. This is the
 clock that keeps the date and time while your computer is turned off.
 
+ACPI has standardized that MC146818 functionality, and extended it in
+a few ways (enabling longer alarm periods, and wake-from-hibernate).
+That functionality is NOT exposed in the old driver.
+
 However it can also be used to generate signals from a slow 2Hz to a
 relatively fast 8192Hz, in increments of powers of two. These signals
 are reported by interrupt number 8. (Oh! So *that* is what IRQ 8 is
@@ -63,223 +100,331 @@
 perhaps more useful to include a small test program that demonstrates
 how to use them, and demonstrates the features of the driver. This is
 probably a lot more useful to people interested in writing applications
-that will be using this driver.
+that will be using this driver.  See the code at the end of this document.
 
-						Paul Gortmaker
+(The original /dev/rtc driver was written by Paul Gortmaker.)
+
+
+	New portable "RTC Class" drivers:  /dev/rtcN
+	--------------------------------------------
+
+Because Linux supports many non-ACPI and non-PC platforms, some of which
+have more than one RTC style clock, it needed a more portable solution
+than expecting a single battery-backed MC146818 clone on every system.
+Accordingly, a new "RTC Class" framework has been defined.  It offers
+three different userspace interfaces:
+
+    *	/dev/rtcN ... much the same as the older /dev/rtc interface
+
+    *	/sys/class/rtc/rtcN ... sysfs attributes support readonly
+	access to some RTC attributes.
+
+    *	/proc/driver/rtc ... the first RTC (rtc0) may expose itself
+	using a procfs interface.  More information is (currently) shown
+	here than through sysfs.
+
+The RTC Class framework supports a wide variety of RTCs, ranging from those
+integrated into embeddable system-on-chip (SOC) processors to discrete chips
+using I2C, SPI, or some other bus to communicate with the host CPU.  There's
+even support for PC-style RTCs ... including the features exposed on newer PCs
+through ACPI.
+
+The new framework also removes the "one RTC per system" restriction.  For
+example, maybe the low-power battery-backed RTC is a discrete I2C chip, but
+a high functionality RTC is integrated into the SOC.  That system might read
+the system clock from the discrete RTC, but use the integrated one for all
+other tasks, because of its greater functionality.
+
+The ioctl() calls supported by /dev/rtc are also supported by the RTC class
+framework.  However, because the chips and systems are not standardized,
+some PC/AT functionality might not be provided.  And in the same way, some
+newer features -- including those enabled by ACPI -- are exposed by the
+RTC class framework, but can't be supported by the older driver.
+
+    *	RTC_RD_TIME, RTC_SET_TIME ... every RTC supports at least reading
+	time, returning the result as a Gregorian calendar date and 24 hour
+	wall clock time.  To be most useful, this time may also be updated.
+
+    *	RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... when the RTC
+	is connected to an IRQ line, it can often issue an alarm IRQ up to
+	24 hours in the future.
+
+    *	RTC_WKALM_SET, RTC_WKALM_READ ... RTCs that can issue alarms beyond
+	the next 24 hours use a slightly more powerful API, which supports
+	setting the longer alarm time and enabling its IRQ using a single
+	request (using the same model as EFI firmware).
+
+    *	RTC_UIE_ON, RTC_UIE_OFF ... if the RTC offers IRQs, it probably
+	also offers update IRQs whenever the "seconds" counter changes.
+	If needed, the RTC framework can emulate this mechanism.
+
+    *	RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ ... another
+	feature often accessible with an IRQ line is a periodic IRQ, issued
+	at settable frequencies (usually 2^N Hz).
+
+In many cases, the RTC alarm can be a system wake event, used to force
+Linux out of a low power sleep state (or hibernation) back to a fully
+operational state.  For example, a system could enter a deep power saving
+state until it's time to execute some scheduled tasks.
+
 
 -------------------- 8< ---------------- 8< -----------------------------
 
 /*
- *	Real Time Clock Driver Test/Example Program
+ *      Real Time Clock Driver Test/Example Program
  *
- *	Compile with:
- *		gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest
+ *      Compile with:
+ *		     gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest
  *
- *	Copyright (C) 1996, Paul Gortmaker.
+ *      Copyright (C) 1996, Paul Gortmaker.
  *
- *	Released under the GNU General Public License, version 2,
- *	included herein by reference.
+ *      Released under the GNU General Public License, version 2,
+ *      included herein by reference.
  *
  */
 
 #include <stdio.h>
-#include <stdlib.h>
 #include <linux/rtc.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <errno.h>
 
-int main(void) {
 
-int i, fd, retval, irqcount = 0;
-unsigned long tmp, data;
-struct rtc_time rtc_tm;
+/*
+ * This expects the new RTC class driver framework, working with
+ * clocks that will often not be clones of what the PC-AT had.
+ * Use the command line to specify another RTC if you need one.
+ */
+static const char default_rtc[] = "/dev/rtc0";
 
-fd = open ("/dev/rtc", O_RDONLY);
 
-if (fd ==  -1) {
-	perror("/dev/rtc");
-	exit(errno);
-}
+int main(int argc, char **argv)
+{
+	int i, fd, retval, irqcount = 0;
+	unsigned long tmp, data;
+	struct rtc_time rtc_tm;
+	const char *rtc = default_rtc;
 
-fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n");
+	switch (argc) {
+	case 2:
+		rtc = argv[1];
+		/* FALLTHROUGH */
+	case 1:
+		break;
+	default:
+		fprintf(stderr, "usage:  rtctest [rtcdev]\n");
+		return 1;
+	}
 
-/* Turn on update interrupts (one per second) */
-retval = ioctl(fd, RTC_UIE_ON, 0);
-if (retval == -1) {
-	perror("ioctl");
-	exit(errno);
-}
+	fd = open(rtc, O_RDONLY);
 
-fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading /dev/rtc:");
-fflush(stderr);
-for (i=1; i<6; i++) {
-	/* This read will block */
-	retval = read(fd, &data, sizeof(unsigned long));
-	if (retval == -1) {
-		perror("read");
+	if (fd ==  -1) {
+		perror(rtc);
 		exit(errno);
 	}
-	fprintf(stderr, " %d",i);
-	fflush(stderr);
-	irqcount++;
-}
 
-fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:");
-fflush(stderr);
-for (i=1; i<6; i++) {
-	struct timeval tv = {5, 0};	/* 5 second timeout on select */
-	fd_set readfds;
+	fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n");
 
-	FD_ZERO(&readfds);
-	FD_SET(fd, &readfds);
-	/* The select will wait until an RTC interrupt happens. */
-	retval = select(fd+1, &readfds, NULL, NULL, &tv);
+	/* Turn on update interrupts (one per second) */
+	retval = ioctl(fd, RTC_UIE_ON, 0);
 	if (retval == -1) {
-		perror("select");
-		exit(errno);
-	}
-	/* This read won't block unlike the select-less case above. */
-	retval = read(fd, &data, sizeof(unsigned long));
-	if (retval == -1) {
-		perror("read");
-		exit(errno);
-	}
-	fprintf(stderr, " %d",i);
-	fflush(stderr);
-	irqcount++;
-}
-
-/* Turn off update interrupts */
-retval = ioctl(fd, RTC_UIE_OFF, 0);
-if (retval == -1) {
-	perror("ioctl");
-	exit(errno);
-}
-
-/* Read the RTC time/date */
-retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
-if (retval == -1) {
-	perror("ioctl");
-	exit(errno);
-}
-
-fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
-	rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
-	rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
-
-/* Set the alarm to 5 sec in the future, and check for rollover */
-rtc_tm.tm_sec += 5;
-if (rtc_tm.tm_sec >= 60) {
-	rtc_tm.tm_sec %= 60;
-	rtc_tm.tm_min++;
-}
-if  (rtc_tm.tm_min == 60) {
-	rtc_tm.tm_min = 0;
-	rtc_tm.tm_hour++;
-}
-if  (rtc_tm.tm_hour == 24)
-	rtc_tm.tm_hour = 0;
-
-retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
-if (retval == -1) {
-	perror("ioctl");
-	exit(errno);
-}
-
-/* Read the current alarm settings */
-retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
-if (retval == -1) {
-	perror("ioctl");
-	exit(errno);
-}
-
-fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n",
-	rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
-
-/* Enable alarm interrupts */
-retval = ioctl(fd, RTC_AIE_ON, 0);
-if (retval == -1) {
-	perror("ioctl");
-	exit(errno);
-}
-
-fprintf(stderr, "Waiting 5 seconds for alarm...");
-fflush(stderr);
-/* This blocks until the alarm ring causes an interrupt */
-retval = read(fd, &data, sizeof(unsigned long));
-if (retval == -1) {
-	perror("read");
-	exit(errno);
-}
-irqcount++;
-fprintf(stderr, " okay. Alarm rang.\n");
-
-/* Disable alarm interrupts */
-retval = ioctl(fd, RTC_AIE_OFF, 0);
-if (retval == -1) {
-	perror("ioctl");
-	exit(errno);
-}
-
-/* Read periodic IRQ rate */
-retval = ioctl(fd, RTC_IRQP_READ, &tmp);
-if (retval == -1) {
-	perror("ioctl");
-	exit(errno);
-}
-fprintf(stderr, "\nPeriodic IRQ rate was %ldHz.\n", tmp);
-
-fprintf(stderr, "Counting 20 interrupts at:");
-fflush(stderr);
-
-/* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
-for (tmp=2; tmp<=64; tmp*=2) {
-
-	retval = ioctl(fd, RTC_IRQP_SET, tmp);
-	if (retval == -1) {
+		if (errno == ENOTTY) {
+			fprintf(stderr,
+				"\n...Update IRQs not supported.\n");
+			goto test_READ;
+		}
 		perror("ioctl");
 		exit(errno);
 	}
 
-	fprintf(stderr, "\n%ldHz:\t", tmp);
+	fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:",
+			rtc);
 	fflush(stderr);
-
-	/* Enable periodic interrupts */
-	retval = ioctl(fd, RTC_PIE_ON, 0);
-	if (retval == -1) {
-		perror("ioctl");
-		exit(errno);
-	}
-
-	for (i=1; i<21; i++) {
-		/* This blocks */
+	for (i=1; i<6; i++) {
+		/* This read will block */
 		retval = read(fd, &data, sizeof(unsigned long));
 		if (retval == -1) {
-			perror("read");
-			exit(errno);
+		        perror("read");
+		        exit(errno);
 		}
 		fprintf(stderr, " %d",i);
 		fflush(stderr);
 		irqcount++;
 	}
 
-	/* Disable periodic interrupts */
-	retval = ioctl(fd, RTC_PIE_OFF, 0);
+	fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:");
+	fflush(stderr);
+	for (i=1; i<6; i++) {
+		struct timeval tv = {5, 0};     /* 5 second timeout on select */
+		fd_set readfds;
+
+		FD_ZERO(&readfds);
+		FD_SET(fd, &readfds);
+		/* The select will wait until an RTC interrupt happens. */
+		retval = select(fd+1, &readfds, NULL, NULL, &tv);
+		if (retval == -1) {
+		        perror("select");
+		        exit(errno);
+		}
+		/* This read won't block unlike the select-less case above. */
+		retval = read(fd, &data, sizeof(unsigned long));
+		if (retval == -1) {
+		        perror("read");
+		        exit(errno);
+		}
+		fprintf(stderr, " %d",i);
+		fflush(stderr);
+		irqcount++;
+	}
+
+	/* Turn off update interrupts */
+	retval = ioctl(fd, RTC_UIE_OFF, 0);
 	if (retval == -1) {
 		perror("ioctl");
 		exit(errno);
 	}
+
+test_READ:
+	/* Read the RTC time/date */
+	retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
+	if (retval == -1) {
+		perror("ioctl");
+		exit(errno);
+	}
+
+	fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
+		rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
+		rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
+
+	/* Set the alarm to 5 sec in the future, and check for rollover */
+	rtc_tm.tm_sec += 5;
+	if (rtc_tm.tm_sec >= 60) {
+		rtc_tm.tm_sec %= 60;
+		rtc_tm.tm_min++;
+	}
+	if  (rtc_tm.tm_min == 60) {
+		rtc_tm.tm_min = 0;
+		rtc_tm.tm_hour++;
+	}
+	if  (rtc_tm.tm_hour == 24)
+		rtc_tm.tm_hour = 0;
+
+	retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
+	if (retval == -1) {
+		if (errno == ENOTTY) {
+			fprintf(stderr,
+				"\n...Alarm IRQs not supported.\n");
+			goto test_PIE;
+		}
+		perror("ioctl");
+		exit(errno);
+	}
+
+	/* Read the current alarm settings */
+	retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
+	if (retval == -1) {
+		perror("ioctl");
+		exit(errno);
+	}
+
+	fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n",
+		rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
+
+	/* Enable alarm interrupts */
+	retval = ioctl(fd, RTC_AIE_ON, 0);
+	if (retval == -1) {
+		perror("ioctl");
+		exit(errno);
+	}
+
+	fprintf(stderr, "Waiting 5 seconds for alarm...");
+	fflush(stderr);
+	/* This blocks until the alarm ring causes an interrupt */
+	retval = read(fd, &data, sizeof(unsigned long));
+	if (retval == -1) {
+		perror("read");
+		exit(errno);
+	}
+	irqcount++;
+	fprintf(stderr, " okay. Alarm rang.\n");
+
+	/* Disable alarm interrupts */
+	retval = ioctl(fd, RTC_AIE_OFF, 0);
+	if (retval == -1) {
+		perror("ioctl");
+		exit(errno);
+	}
+
+test_PIE:
+	/* Read periodic IRQ rate */
+	retval = ioctl(fd, RTC_IRQP_READ, &tmp);
+	if (retval == -1) {
+		/* not all RTCs support periodic IRQs */
+		if (errno == ENOTTY) {
+			fprintf(stderr, "\nNo periodic IRQ support\n");
+			return 0;
+		}
+		perror("ioctl");
+		exit(errno);
+	}
+	fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp);
+
+	fprintf(stderr, "Counting 20 interrupts at:");
+	fflush(stderr);
+
+	/* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
+	for (tmp=2; tmp<=64; tmp*=2) {
+
+		retval = ioctl(fd, RTC_IRQP_SET, tmp);
+		if (retval == -1) {
+			/* not all RTCs can change their periodic IRQ rate */
+			if (errno == ENOTTY) {
+				fprintf(stderr,
+					"\n...Periodic IRQ rate is fixed\n");
+				goto done;
+			}
+		        perror("ioctl");
+		        exit(errno);
+		}
+
+		fprintf(stderr, "\n%ldHz:\t", tmp);
+		fflush(stderr);
+
+		/* Enable periodic interrupts */
+		retval = ioctl(fd, RTC_PIE_ON, 0);
+		if (retval == -1) {
+		        perror("ioctl");
+		        exit(errno);
+		}
+
+		for (i=1; i<21; i++) {
+		        /* This blocks */
+		        retval = read(fd, &data, sizeof(unsigned long));
+		        if (retval == -1) {
+				       perror("read");
+				       exit(errno);
+		        }
+		        fprintf(stderr, " %d",i);
+		        fflush(stderr);
+		        irqcount++;
+		}
+
+		/* Disable periodic interrupts */
+		retval = ioctl(fd, RTC_PIE_OFF, 0);
+		if (retval == -1) {
+		        perror("ioctl");
+		        exit(errno);
+		}
+	}
+
+done:
+	fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");
+
+	close(fd);
+
+	return 0;
 }
-
-fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");
-fprintf(stderr, "\nTyping \"cat /proc/interrupts\" will show %d more events on IRQ 8.\n\n",
-								 irqcount);
-
-close(fd);
-return 0;
-
-} /* end main */
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 138673a..3472d9c 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -753,7 +753,7 @@
     position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
     single_cmd  - Use single immediate commands to communicate with
 		codecs (for debugging only)
-    disable_msi - Disable Message Signaled Interrupt (MSI)
+    enable_msi	- Enable Message Signaled Interrupt (MSI) (default = off)
 
     This module supports one card and autoprobe.
 
diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt
index 8dc2bac..50436e1 100644
--- a/Documentation/usb/usb-serial.txt
+++ b/Documentation/usb/usb-serial.txt
@@ -428,12 +428,6 @@
   See http://www.uuhaus.de/linux/palmconnect.html for up-to-date
   information on this driver.
 
-AIRcable USB Dongle Bluetooth driver
-  If there is the cdc_acm driver loaded in the system, you will find that the
-  cdc_acm claims the device before AIRcable can. This is simply corrected
-  by unloading both modules and then loading the aircable module before
-  cdc_acm module
-
 Generic Serial driver
 
   If your device is not one of the above listed devices, compatible with
diff --git a/Documentation/watchdog/src/watchdog-simple.c b/Documentation/watchdog/src/watchdog-simple.c
index 85cf17c..47801bc 100644
--- a/Documentation/watchdog/src/watchdog-simple.c
+++ b/Documentation/watchdog/src/watchdog-simple.c
@@ -1,4 +1,6 @@
+#include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <fcntl.h>
 
 int main(int argc, const char *argv[]) {
diff --git a/MAINTAINERS b/MAINTAINERS
index d708702..e182992 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -353,6 +353,12 @@
 M:	rpurdie@rpsys.net
 S:	Maintained
 
+ARM/HP JORNADA 7XX MACHINE SUPPORT
+P:      Kristoffer Ericson
+M:      kristoffer_e1@hotmail.com
+W:      www.jlime.com
+S:      Maintained
+
 ARM/TOSA MACHINE SUPPORT
 P:	Dirk Opfer
 M:	dirk@opfer-online.de
@@ -493,7 +499,7 @@
 
 BFS FILE SYSTEM
 P:	Tigran A. Aivazian
-M:	tigran@veritas.com
+M:	tigran@aivazian.fsnet.co.uk
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
@@ -1513,7 +1519,7 @@
 
 INTEL IA32 MICROCODE UPDATE SUPPORT
 P:	Tigran Aivazian
-M:	tigran@veritas.com
+M:	tigran@aivazian.fsnet.co.uk
 S:	Maintained
 
 INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
@@ -3072,6 +3078,13 @@
 W:	http://www.linux-projects.org
 S:	Maintained
 
+USB GADGET/PERIPHERAL SUBSYSTEM
+P:	David Brownell
+M:	dbrownell@users.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+W:	http://www.linux-usb.org/gadget
+S:	Maintained
+
 USB HID/HIDBP DRIVERS
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
@@ -3255,10 +3268,11 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
-USB "USBNET" DRIVER
+USB "USBNET" DRIVER FRAMEWORK
 P:	David Brownell
 M:	dbrownell@users.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
+W:	http://www.linux-usb.org/usbnet
 S:	Maintained
 
 USB W996[87]CF DRIVER
diff --git a/Makefile b/Makefile
index 62a1343..aef9625 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 19
-EXTRAVERSION =-rc2
+EXTRAVERSION =
 NAME=Avast! A bilge rat!
 
 # *DOCUMENTATION*
@@ -499,6 +499,7 @@
 
 ifdef CONFIG_UNWIND_INFO
 CFLAGS		+= -fasynchronous-unwind-tables
+LDFLAGS_vmlinux	+= --eh-frame-hdr
 endif
 
 ifdef CONFIG_DEBUG_INFO
diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c
index 990ac61..f7dd081 100644
--- a/arch/alpha/kernel/srm_env.c
+++ b/arch/alpha/kernel/srm_env.c
@@ -2,7 +2,7 @@
  * srm_env.c - Access to SRM environment
  *             variables through linux' procfs
  *
- * Copyright (C) 2001-2002 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+ * (C) 2001,2002,2006 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
  *
  * This driver is at all a modified version of Erik Mouw's
  * Documentation/DocBook/procfs_example.c, so: thank
@@ -21,7 +21,7 @@
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  * PURPOSE.  See the GNU General Public License for more
  * details.
- * 
+ *
  * You should have received a copy of the GNU General Public
  * License along with this program; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place,
@@ -29,33 +29,6 @@
  *
  */
 
-/*
- * Changelog
- * ~~~~~~~~~
- *
- * Thu, 22 Aug 2002 15:10:43 +0200
- * 	- Update Config.help entry. I got a number of emails asking
- * 	  me to tell their senders if they could make use of this
- * 	  piece of code... So: "SRM is something like BIOS for your
- * 	  Alpha"
- * 	- Update code formatting a bit to better conform CodingStyle
- * 	  rules.
- * 	- So this is v0.0.5, with no changes (except formatting)
- * 	
- * Wed, 22 May 2002 00:11:21 +0200
- * 	- Fix typo on comment (SRC -> SRM)
- * 	- Call this "Version 0.0.4"
- *
- * Tue,  9 Apr 2002 18:44:40 +0200
- * 	- Implement access by variable name and additionally
- * 	  by number. This is done by creating two subdirectories
- * 	  where one holds all names (like the old directory
- * 	  did) and the other holding 256 files named like "0",
- * 	  "1" and so on.
- * 	- Call this "Version 0.0.3"
- *
- */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -67,7 +40,7 @@
 #define BASE_DIR	"srm_environment"	/* Subdir in /proc/		*/
 #define NAMED_DIR	"named_variables"	/* Subdir for known variables	*/
 #define NUMBERED_DIR	"numbered_variables"	/* Subdir for all variables	*/
-#define VERSION		"0.0.5"			/* Module version		*/
+#define VERSION		"0.0.6"			/* Module version		*/
 #define NAME		"srm_env"		/* Module name			*/
 
 MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
@@ -106,7 +79,6 @@
 static srm_env_t	srm_numbered_entries[256];
 
 
-
 static int
 srm_env_read(char *page, char **start, off_t off, int count, int *eof,
 		void *data)
@@ -115,21 +87,23 @@
 	unsigned long	ret;
 	srm_env_t	*entry;
 
-	if(off != 0)
-		return -EFAULT;
+	if (off != 0) {
+		*eof = 1;
+		return 0;
+	}
 
 	entry	= (srm_env_t *) data;
 	ret	= callback_getenv(entry->id, page, count);
 
-	if((ret >> 61) == 0)
+	if ((ret >> 61) == 0) {
 		nbytes = (int) ret;
-	else
+		*eof = 1;
+	} else
 		nbytes = -EFAULT;
 
 	return nbytes;
 }
 
-
 static int
 srm_env_write(struct file *file, const char __user *buffer, unsigned long count,
 		void *data)
@@ -155,7 +129,7 @@
 
 	ret1 = callback_setenv(entry->id, buf, count);
 	if ((ret1 >> 61) == 0) {
-		do 
+		do
 			ret2 = callback_save_env();
 		while((ret2 >> 61) == 1);
 		res = (int) ret1;
@@ -172,14 +146,14 @@
 	srm_env_t	*entry;
 	unsigned long	var_num;
 
-	if(base_dir) {
+	if (base_dir) {
 		/*
 		 * Remove named entries
 		 */
-		if(named_dir) {
+		if (named_dir) {
 			entry = srm_named_entries;
-			while(entry->name != NULL && entry->id != 0) {
-				if(entry->proc_entry) {
+			while (entry->name != NULL && entry->id != 0) {
+				if (entry->proc_entry) {
 					remove_proc_entry(entry->name,
 							named_dir);
 					entry->proc_entry = NULL;
@@ -192,11 +166,11 @@
 		/*
 		 * Remove numbered entries
 		 */
-		if(numbered_dir) {
-			for(var_num = 0; var_num <= 255; var_num++) {
+		if (numbered_dir) {
+			for (var_num = 0; var_num <= 255; var_num++) {
 				entry =	&srm_numbered_entries[var_num];
 
-				if(entry->proc_entry) {
+				if (entry->proc_entry) {
 					remove_proc_entry(entry->name,
 							numbered_dir);
 					entry->proc_entry	= NULL;
@@ -212,7 +186,6 @@
 	return;
 }
 
-
 static int __init
 srm_env_init(void)
 {
@@ -222,7 +195,7 @@
 	/*
 	 * Check system
 	 */
-	if(!alpha_using_srm) {
+	if (!alpha_using_srm) {
 		printk(KERN_INFO "%s: This Alpha system doesn't "
 				"know about SRM (or you've booted "
 				"SRM->MILO->Linux, which gets "
@@ -233,14 +206,14 @@
 	/*
 	 * Init numbers
 	 */
-	for(var_num = 0; var_num <= 255; var_num++)
+	for (var_num = 0; var_num <= 255; var_num++)
 		sprintf(number[var_num], "%ld", var_num);
 
 	/*
 	 * Create base directory
 	 */
 	base_dir = proc_mkdir(BASE_DIR, NULL);
-	if(base_dir == NULL) {
+	if (!base_dir) {
 		printk(KERN_ERR "Couldn't create base dir /proc/%s\n",
 				BASE_DIR);
 		goto cleanup;
@@ -251,7 +224,7 @@
 	 * Create per-name subdirectory
 	 */
 	named_dir = proc_mkdir(NAMED_DIR, base_dir);
-	if(named_dir == NULL) {
+	if (!named_dir) {
 		printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n",
 				BASE_DIR, NAMED_DIR);
 		goto cleanup;
@@ -262,7 +235,7 @@
 	 * Create per-number subdirectory
 	 */
 	numbered_dir = proc_mkdir(NUMBERED_DIR, base_dir);
-	if(numbered_dir == NULL) {
+	if (!numbered_dir) {
 		printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n",
 				BASE_DIR, NUMBERED_DIR);
 		goto cleanup;
@@ -274,10 +247,10 @@
 	 * Create all named nodes
 	 */
 	entry = srm_named_entries;
-	while(entry->name != NULL && entry->id != 0) {
+	while (entry->name && entry->id) {
 		entry->proc_entry = create_proc_entry(entry->name,
 				0644, named_dir);
-		if(entry->proc_entry == NULL)
+		if (!entry->proc_entry)
 			goto cleanup;
 
 		entry->proc_entry->data		= (void *) entry;
@@ -291,13 +264,13 @@
 	/*
 	 * Create all numbered nodes
 	 */
-	for(var_num = 0; var_num <= 255; var_num++) {
+	for (var_num = 0; var_num <= 255; var_num++) {
 		entry = &srm_numbered_entries[var_num];
 		entry->name = number[var_num];
 
 		entry->proc_entry = create_proc_entry(entry->name,
 				0644, numbered_dir);
-		if(entry->proc_entry == NULL)
+		if (!entry->proc_entry)
 			goto cleanup;
 
 		entry->id			= var_num;
@@ -318,7 +291,6 @@
 	return -ENOMEM;
 }
 
-
 static void __exit
 srm_env_exit(void)
 {
@@ -328,7 +300,5 @@
 	return;
 }
 
-
 module_init(srm_env_init);
 module_exit(srm_env_exit);
-
diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 71470e9..76bf071 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -48,13 +48,7 @@
   . = ALIGN(8);
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index adb05de..ce00c57 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -879,6 +879,8 @@
 
 source "drivers/scsi/Kconfig"
 
+source "drivers/ata/Kconfig"
+
 source "drivers/md/Kconfig"
 
 source "drivers/message/fusion/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2a0b2c8..6f4f8bf 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -174,11 +174,13 @@
 
 # Default target when executing plain make
 ifeq ($(CONFIG_XIP_KERNEL),y)
-all: xipImage
+KBUILD_IMAGE := xipImage
 else
-all: zImage
+KBUILD_IMAGE := zImage
 endif
 
+all:	$(KBUILD_IMAGE)
+
 boot := arch/arm/boot
 
 #	Update machine arch and proc symlinks if something which affects
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 028bdc9..2e635b8 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -662,7 +662,8 @@
 EXPORT_SYMBOL(dma_unmap_single);
 EXPORT_SYMBOL(dma_map_sg);
 EXPORT_SYMBOL(dma_unmap_sg);
-EXPORT_SYMBOL(dma_sync_single);
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+EXPORT_SYMBOL(dma_sync_single_for_device);
 EXPORT_SYMBOL(dma_sync_sg);
 EXPORT_SYMBOL(dmabounce_register_dev);
 EXPORT_SYMBOL(dmabounce_unregister_dev);
diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig
index 089c9d5..b1cd331 100644
--- a/arch/arm/configs/assabet_defconfig
+++ b/arch/arm/configs/assabet_defconfig
@@ -184,6 +184,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_APM is not set
 
 #
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig
index c82e466..b430414 100644
--- a/arch/arm/configs/at91rm9200dk_defconfig
+++ b/arch/arm/configs/at91rm9200dk_defconfig
@@ -577,7 +577,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
index b983fc5..d96fc83 100644
--- a/arch/arm/configs/at91rm9200ek_defconfig
+++ b/arch/arm/configs/at91rm9200ek_defconfig
@@ -558,7 +558,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards
diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig
index 15e6b0b..3de5c64 100644
--- a/arch/arm/configs/ateb9200_defconfig
+++ b/arch/arm/configs/ateb9200_defconfig
@@ -217,7 +217,7 @@
 # Power management options
 #
 CONFIG_PM=y
-CONFIG_PM_LEGACY=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 # CONFIG_APM is not set
 
diff --git a/arch/arm/configs/bast_defconfig b/arch/arm/configs/bast_defconfig
deleted file mode 100644
index 4a8564f..0000000
--- a/arch/arm/configs/bast_defconfig
+++ /dev/null
@@ -1,947 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 02:24:16 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-CONFIG_ARCH_S3C2410=y
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-
-#
-# S3C24XX Implementations
-#
-CONFIG_ARCH_BAST=y
-# CONFIG_ARCH_H1940 is not set
-# CONFIG_MACH_N30 is not set
-# CONFIG_ARCH_SMDK2410 is not set
-# CONFIG_ARCH_S3C2440 is not set
-CONFIG_MACH_VR1000=y
-# CONFIG_MACH_RX3715 is not set
-# CONFIG_MACH_OTOM is not set
-# CONFIG_MACH_NEXCODER_2440 is not set
-CONFIG_CPU_S3C2410=y
-
-#
-# S3C2410 Boot
-#
-# CONFIG_S3C2410_BOOT_WATCHDOG is not set
-
-#
-# S3C2410 Setup
-#
-CONFIG_S3C2410_DMA=y
-# CONFIG_S3C2410_DMA_DEBUG is not set
-# CONFIG_S3C2410_PM_DEBUG is not set
-# CONFIG_S3C2410_PM_CHECK is not set
-CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM920T=y
-CONFIG_CPU_32v4=y
-CONFIG_CPU_ABRT_EV4T=y
-CONFIG_CPU_CACHE_V4WT=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_THUMB is not set
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-
-#
-# Bus support
-#
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-# CONFIG_PREEMPT is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-CONFIG_PM=y
-CONFIG_APM=y
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
-# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_16=y
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_XIP is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-CONFIG_MTD_BAST=y
-CONFIG_MTD_BAST_MAXSIZE=4
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_S3C2410=y
-# CONFIG_MTD_NAND_S3C2410_DEBUG is not set
-# CONFIG_MTD_NAND_S3C2410_HWECC is not set
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=y
-# CONFIG_PARPORT_PC is not set
-# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_GSC is not set
-CONFIG_PARPORT_1284=y
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDE_BAST=y
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_SMC91X is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PARKBD is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_SERIAL_NONSTANDARD=y
-# CONFIG_COMPUTONE is not set
-# CONFIG_ROCKETPORT is not set
-# CONFIG_CYCLADES is not set
-# CONFIG_DIGIEPCA is not set
-# CONFIG_MOXA_INTELLIO is not set
-# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_ISI is not set
-# CONFIG_SYNCLINKMP is not set
-# CONFIG_N_HDLC is not set
-# CONFIG_RISCOM8 is not set
-# CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
-# CONFIG_STALDRV is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=8
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_S3C2410=y
-CONFIG_SERIAL_S3C2410_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-CONFIG_PRINTER=y
-# CONFIG_LP_CONSOLE is not set
-CONFIG_PPDEV=y
-# CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_S3C2410_WATCHDOG=y
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_S3C2410_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=m
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-CONFIG_I2C_S3C2410=y
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
-CONFIG_I2C_SENSOR=m
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-CONFIG_SENSORS_LM75=m
-# CONFIG_SENSORS_LM77 is not set
-CONFIG_SENSORS_LM78=m
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-CONFIG_SENSORS_LM85=m
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-CONFIG_SENSORS_EEPROM=m
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
-# CONFIG_FB_SOFT_CURSOR is not set
-CONFIG_FB_MODE_HELPERS=y
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
-# CONFIG_JFFS_PROC_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-# CONFIG_MINIX_SUBPARTITION is not set
-CONFIG_SOLARIS_X86_PARTITION=y
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_MAGIC_SYSRQ is not set
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=y
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_ERRORS is not set
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
-CONFIG_DEBUG_S3C2410_PORT=y
-CONFIG_DEBUG_S3C2410_UART=0
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig
index f81a600..09b7acd 100644
--- a/arch/arm/configs/cerfcube_defconfig
+++ b/arch/arm/configs/cerfcube_defconfig
@@ -194,6 +194,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_APM is not set
 
 #
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 074c47a..a375891 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -219,7 +219,7 @@
 # Power management options
 #
 CONFIG_PM=y
-CONFIG_PM_LEGACY=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 CONFIG_APM=y
 
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index 3c3461e..c41c04f 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -208,6 +208,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 CONFIG_APM=y
 
 #
diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig
index a2d6fd3..20e6825 100644
--- a/arch/arm/configs/csb337_defconfig
+++ b/arch/arm/configs/csb337_defconfig
@@ -615,7 +615,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards
diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig
index 2a1ac6c..df8595a 100644
--- a/arch/arm/configs/csb637_defconfig
+++ b/arch/arm/configs/csb637_defconfig
@@ -615,7 +615,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index 7a0da0b..8f986e9 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -194,6 +194,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_APM is not set
 
 #
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index d1ba7fd..692ab57 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -190,6 +190,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_APM is not set
 
 #
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index 4975b91..fac7c3b 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -206,10 +206,8 @@
 #
 # Power management options
 #
-CONFIG_PM=y
-CONFIG_PM_LEGACY=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_APM=y
+# CONFIG_PM is not set
+# CONFIG_APM is not set
 
 #
 # Networking
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index ad1048d..80a6fd9 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -182,6 +182,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_APM is not set
 
 #
diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig
index 54fcd75..a4cdafc 100644
--- a/arch/arm/configs/kafa_defconfig
+++ b/arch/arm/configs/kafa_defconfig
@@ -560,7 +560,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
 # CONFIG_NVRAM is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig
index c3a9328..a1cc34f 100644
--- a/arch/arm/configs/lart_defconfig
+++ b/arch/arm/configs/lart_defconfig
@@ -180,6 +180,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 CONFIG_APM=m
 
 #
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig
index 3d35255..df8168e 100644
--- a/arch/arm/configs/neponset_defconfig
+++ b/arch/arm/configs/neponset_defconfig
@@ -190,6 +190,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 CONFIG_APM=y
 
 #
diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
index 05adb0b..b0efd4c 100644
--- a/arch/arm/configs/omap_h2_1610_defconfig
+++ b/arch/arm/configs/omap_h2_1610_defconfig
@@ -257,7 +257,7 @@
 # Power management options
 #
 CONFIG_PM=y
-CONFIG_PM_LEGACY=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 # CONFIG_APM is not set
 
diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig
index cb1d94f..9b9f215 100644
--- a/arch/arm/configs/onearm_defconfig
+++ b/arch/arm/configs/onearm_defconfig
@@ -607,7 +607,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig
new file mode 100644
index 0000000..ffd905f
--- /dev/null
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -0,0 +1,994 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.19-rc3
+# Wed Oct 25 14:12:00 2006
+#
+CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+CONFIG_ARCH_REALVIEW=y
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# RealView platform type
+#
+CONFIG_MACH_REALVIEW_EB=y
+CONFIG_REALVIEW_MPCORE=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_ARM926T is not set
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_GIC=y
+CONFIG_ICST307=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+CONFIG_LOCAL_TIMERS=y
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+# CONFIG_APM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ARM_INTEGRATOR=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_ARMCLCD=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_ARMAACI=m
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_ARMMMCI=y
+# CONFIG_MMC_TIFM_SD is not set
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_PL031=y
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_RWSEMS=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index a832226..c0152393 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,9 +1,10 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Wed Sep 20 20:27:31 2006
+# Linux kernel version: 2.6.19-rc4
+# Fri Nov  3 17:41:31 2006
 #
 CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -29,17 +30,20 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -62,7 +66,8 @@
 # Loadable module support
 #
 CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
@@ -70,6 +75,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -120,6 +126,7 @@
 #
 # S3C24XX Implementations
 #
+# CONFIG_MACH_AML_M5900 is not set
 CONFIG_MACH_ANUBIS=y
 CONFIG_MACH_OSIRIS=y
 CONFIG_ARCH_BAST=y
@@ -178,6 +185,8 @@
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_COPY_V4WB=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
@@ -249,8 +258,9 @@
 # Power management options
 #
 CONFIG_PM=y
-CONFIG_PM_LEGACY=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
 CONFIG_APM=y
 
 #
@@ -266,6 +276,7 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -286,10 +297,12 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -377,6 +390,7 @@
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -418,6 +432,8 @@
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -512,6 +528,7 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -606,6 +623,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -628,6 +646,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -734,7 +753,6 @@
 # CONFIG_USBPCWATCHDOG is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
-CONFIG_S3C2410_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
@@ -747,7 +765,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -792,12 +809,26 @@
 #
 # SPI support
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=m
+# CONFIG_SPI_BUTTERFLY is not set
+CONFIG_SPI_S3C24XX_GPIO=m
+CONFIG_SPI_S3C24XX=m
+
+#
+# SPI Protocol Masters
+#
 
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -820,6 +851,7 @@
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
 CONFIG_SENSORS_LM75=m
 # CONFIG_SENSORS_LM77 is not set
 CONFIG_SENSORS_LM78=m
@@ -834,6 +866,7 @@
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
@@ -845,25 +878,31 @@
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # LED devices
 #
-# CONFIG_NEW_LEDS is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
 
 #
 # LED drivers
 #
+CONFIG_LEDS_S3C24XX=m
 
 #
 # LED Triggers
 #
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -876,6 +915,7 @@
 #
 CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
+# CONFIG_FB_DDC is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
@@ -951,7 +991,6 @@
 #
 # may also be needed; see USB_STORAGE Help for more information
 #
-# CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -1007,6 +1046,7 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -1014,11 +1054,12 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1039,7 +1080,37 @@
 # Real Time Clock
 #
 CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+CONFIG_RTC_DRV_S3C=y
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
 # File systems
@@ -1051,6 +1122,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1058,6 +1130,7 @@
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
@@ -1089,6 +1162,7 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -1219,6 +1293,7 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
@@ -1238,9 +1313,10 @@
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_WAITQ is not set
@@ -1262,10 +1338,6 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
diff --git a/arch/arm/configs/simpad_defconfig b/arch/arm/configs/simpad_defconfig
index 2e5a616..140056a 100644
--- a/arch/arm/configs/simpad_defconfig
+++ b/arch/arm/configs/simpad_defconfig
@@ -180,6 +180,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 CONFIG_APM=y
 
 #
diff --git a/arch/arm/configs/smdk2410_defconfig b/arch/arm/configs/smdk2410_defconfig
deleted file mode 100644
index 4d123d3..0000000
--- a/arch/arm/configs/smdk2410_defconfig
+++ /dev/null
@@ -1,735 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:42:40 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-CONFIG_ARCH_S3C2410=y
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-
-#
-# S3C24XX Implementations
-#
-# CONFIG_ARCH_BAST is not set
-# CONFIG_ARCH_H1940 is not set
-# CONFIG_MACH_N30 is not set
-CONFIG_ARCH_SMDK2410=y
-# CONFIG_ARCH_S3C2440 is not set
-# CONFIG_MACH_VR1000 is not set
-# CONFIG_MACH_RX3715 is not set
-# CONFIG_MACH_OTOM is not set
-# CONFIG_MACH_NEXCODER_2440 is not set
-CONFIG_CPU_S3C2410=y
-
-#
-# S3C2410 Boot
-#
-
-#
-# S3C2410 Setup
-#
-# CONFIG_S3C2410_DMA is not set
-CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM920T=y
-CONFIG_CPU_32v4=y
-CONFIG_CPU_ABRT_EV4T=y
-CONFIG_CPU_CACHE_V4WT=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-
-#
-# Bus support
-#
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-# CONFIG_PREEMPT is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=1f04 mem=32M"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_FPE_NWFPE is not set
-# CONFIG_FPE_FASTFPE is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_PARTITIONS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_SMC91X is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_S3C2410=y
-CONFIG_SERIAL_S3C2410_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_S3C2410_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-CONFIG_FB_VIRTUAL=y
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MSDOS_PARTITION is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_MAGIC_SYSRQ is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=y
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_ERRORS is not set
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
-CONFIG_DEBUG_S3C2410_PORT=y
-CONFIG_DEBUG_S3C2410_UART=0
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
-CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index d1ace3a..bd03238 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -207,6 +207,7 @@
 # Power management options
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
 CONFIG_APM=y
 
 #
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index 96b7a77..f7bf6ef 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -200,7 +200,7 @@
 # Power management options
 #
 CONFIG_PM=y
-CONFIG_PM_LEGACY=y
+# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 # CONFIG_APM is not set
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 6bbd93d..29efc9f 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -357,6 +357,9 @@
 #ifndef CONFIG_VFP
 	elf_hwcap &= ~HWCAP_VFP;
 #endif
+#ifndef CONFIG_IWMMXT
+	elf_hwcap &= ~HWCAP_IWMMXT;
+#endif
 
 	cpu_proc_init();
 }
@@ -854,6 +857,7 @@
 	"vfp",
 	"edsp",
 	"java",
+	"iwmmxt",
 	NULL
 };
 
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 421329f..070bcb7 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -7,6 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
@@ -19,6 +20,7 @@
 #include <linux/cpu.h>
 #include <linux/smp.h>
 #include <linux/seq_file.h>
+#include <linux/irq.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
@@ -449,6 +451,7 @@
 	return smp_call_function_on_cpu(func, info, retry, wait,
 					cpu_online_map);
 }
+EXPORT_SYMBOL_GPL(smp_call_function);
 
 void show_ipi_list(struct seq_file *p)
 {
@@ -474,25 +477,26 @@
 	seq_putc(p, '\n');
 }
 
-static void ipi_timer(struct pt_regs *regs)
+static void ipi_timer(void)
 {
-	int user = user_mode(regs);
-
 	irq_enter();
-	profile_tick(CPU_PROFILING, regs);
-	update_process_times(user);
+	profile_tick(CPU_PROFILING);
+	update_process_times(user_mode(get_irq_regs()));
 	irq_exit();
 }
 
 #ifdef CONFIG_LOCAL_TIMERS
 asmlinkage void do_local_timer(struct pt_regs *regs)
 {
+	struct pt_regs *old_regs = set_irq_regs(regs);
 	int cpu = smp_processor_id();
 
 	if (local_timer_ack()) {
 		irq_stat[cpu].local_timer_irqs++;
-		ipi_timer(regs);
+		ipi_timer();
 	}
+
+	set_irq_regs(old_regs);
 }
 #endif
 
@@ -551,6 +555,7 @@
 {
 	unsigned int cpu = smp_processor_id();
 	struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
+	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	ipi->ipi_count++;
 
@@ -574,7 +579,7 @@
 
 			switch (nextmsg) {
 			case IPI_TIMER:
-				ipi_timer(regs);
+				ipi_timer();
 				break;
 
 			case IPI_RESCHEDULE:
@@ -599,6 +604,8 @@
 			}
 		} while (msgs);
 	}
+
+	set_irq_regs(old_regs);
 }
 
 void smp_send_reschedule(int cpu)
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index c03cab5..6ff5e3f 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -220,10 +220,10 @@
 #ifdef CONFIG_LEDS_TIMER
 static inline void do_leds(void)
 {
-	static unsigned int count = 50;
+	static unsigned int count = HZ/2;
 
 	if (--count == 0) {
-		count = 50;
+		count = HZ/2;
 		leds_event(led_timer);
 	}
 }
@@ -327,13 +327,12 @@
  */
 void timer_tick(void)
 {
-	struct pt_regs *regs = get_irq_regs();
 	profile_tick(CPU_PROFILING);
 	do_leds();
 	do_set_rtc();
 	do_timer(1);
 #ifndef CONFIG_SMP
-	update_process_times(user_mode(regs));
+	update_process_times(user_mode(get_irq_regs()));
 #endif
 }
 
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 3ca574e..a8fa75e 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -45,13 +45,7 @@
 			*(.early_param.init)
 		__early_end = .;
 		__initcall_start = .;
-			*(.initcall1.init)
-			*(.initcall2.init)
-			*(.initcall3.init)
-			*(.initcall4.init)
-			*(.initcall5.init)
-			*(.initcall6.init)
-			*(.initcall7.init)
+			INITCALLS
 		__initcall_end = .;
 		__con_initcall_start = .;
 			*(.con_initcall.init)
diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
index c648bfb..db38afb 100644
--- a/arch/arm/mach-ebsa110/io.c
+++ b/arch/arm/mach-ebsa110/io.c
@@ -28,7 +28,7 @@
 #include <asm/io.h>
 #include <asm/page.h>
 
-static void __iomem *__isamem_convert_addr(void __iomem *addr)
+static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr)
 {
 	u32 ret, a = (u32 __force) addr;
 
@@ -63,7 +63,7 @@
 /*
  * read[bwl] and write[bwl]
  */
-u8 __readb(void __iomem *addr)
+u8 __readb(const volatile void __iomem *addr)
 {
 	void __iomem *a = __isamem_convert_addr(addr);
 	u32 ret;
@@ -75,7 +75,7 @@
 	return ret;
 }
 
-u16 __readw(void __iomem *addr)
+u16 __readw(const volatile void __iomem *addr)
 {
 	void __iomem *a = __isamem_convert_addr(addr);
 
@@ -85,7 +85,7 @@
 	return __raw_readw(a);
 }
 
-u32 __readl(void __iomem *addr)
+u32 __readl(const volatile void __iomem *addr)
 {
 	void __iomem *a = __isamem_convert_addr(addr);
 	u32 ret;
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index a2c94a4..2499a77 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -85,7 +85,7 @@
 		irq = IRQ_IOP32X_XINT0;
 	} else if (PCI_SLOT(dev->devfn) == 2) {
 		/* RTL8110SB #2 */
-		irq = IRQ_IOP32X_XINT1;
+		irq = IRQ_IOP32X_XINT3;
 	} else if (PCI_SLOT(dev->devfn) == 3) {
 		/* Sil3512 */
 		irq = IRQ_IOP32X_XINT2;
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
index 9ee6383..0fdd03a 100644
--- a/arch/arm/mach-ixp2000/ixdp2400.c
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -135,11 +135,11 @@
 	if (ixdp2x00_master_npu()) {
 		dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN);
 		pci_remove_bus_device(dev);
-		pci_dev_put(dev)
+		pci_dev_put(dev);
 	} else {
 		dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN);
 		pci_remove_bus_device(dev);
-		pci_dev_put(dev)
+		pci_dev_put(dev);
 
 		ixdp2x00_slave_pci_postinit();
 	}
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index c7513f6..fbe288a 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -86,7 +86,8 @@
 	IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
 };
 
-static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
+/* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */
+static unsigned long long ixp4xx_irq_edge = 0;
 
 /*
  * IRQ -> GPIO mapping table
@@ -135,7 +136,11 @@
 	default:
 		return -EINVAL;
 	}
-	ixp4xx_config_irq(irq, irq_type);
+
+	if (irq_type == IXP4XX_IRQ_EDGE)
+		ixp4xx_irq_edge |= (1 << irq);
+	else
+		ixp4xx_irq_edge &= ~(1 << irq);
 
 	if (line >= 8) {	/* pins 8-15 */
 		line -= 8;
@@ -167,14 +172,6 @@
 		*IXP4XX_ICMR &= ~(1 << irq);
 }
 
-static void ixp4xx_irq_unmask(unsigned int irq)
-{
-	if (cpu_is_ixp46x() && irq >= 32)
-		*IXP4XX_ICMR2 |= (1 << (irq - 32));
-	else
-		*IXP4XX_ICMR |= (1 << irq);
-}
-
 static void ixp4xx_irq_ack(unsigned int irq)
 {
 	int line = (irq < 32) ? irq2gpio[irq] : -1;
@@ -187,41 +184,25 @@
  * Level triggered interrupts on GPIO lines can only be cleared when the
  * interrupt condition disappears.
  */
-static void ixp4xx_irq_level_unmask(unsigned int irq)
+static void ixp4xx_irq_unmask(unsigned int irq)
 {
-	ixp4xx_irq_ack(irq);
-	ixp4xx_irq_unmask(irq);
+	if (!(ixp4xx_irq_edge & (1 << irq)))
+		ixp4xx_irq_ack(irq);
+
+	if (cpu_is_ixp46x() && irq >= 32)
+		*IXP4XX_ICMR2 |= (1 << (irq - 32));
+	else
+		*IXP4XX_ICMR |= (1 << irq);
 }
 
-static struct irqchip ixp4xx_irq_level_chip = {
-	.ack		= ixp4xx_irq_mask,
-	.mask		= ixp4xx_irq_mask,
-	.unmask		= ixp4xx_irq_level_unmask,
-	.set_type	= ixp4xx_set_irq_type,
-};
-
-static struct irqchip ixp4xx_irq_edge_chip = {
+static struct irqchip ixp4xx_irq_chip = {
+	.name		= "IXP4xx",
 	.ack		= ixp4xx_irq_ack,
 	.mask		= ixp4xx_irq_mask,
 	.unmask		= ixp4xx_irq_unmask,
 	.set_type	= ixp4xx_set_irq_type,
 };
 
-static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type)
-{
-	switch (type) {
-	case IXP4XX_IRQ_LEVEL:
-		set_irq_chip(irq, &ixp4xx_irq_level_chip);
-		set_irq_handler(irq, do_level_IRQ);
-		break;
-	case IXP4XX_IRQ_EDGE:
-		set_irq_chip(irq, &ixp4xx_irq_edge_chip);
-		set_irq_handler(irq, do_edge_IRQ);
-		break;
-	}
-	set_irq_flags(irq, IRQF_VALID);
-}
-
 void __init ixp4xx_init_irq(void)
 {
 	int i = 0;
@@ -241,8 +222,11 @@
 	}
 
         /* Default to all level triggered */
-	for(i = 0; i < NR_IRQS; i++)
-		ixp4xx_config_irq(i, IXP4XX_IRQ_LEVEL);
+	for(i = 0; i < NR_IRQS; i++) {
+		set_irq_chip(i, &ixp4xx_irq_chip);
+		set_irq_handler(i, do_level_IRQ);
+		set_irq_flags(i, IRQF_VALID);
+	}
 }
 
 
diff --git a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig
index 558a34f..147b019 100644
--- a/arch/arm/mach-lh7a40x/Kconfig
+++ b/arch/arm/mach-lh7a40x/Kconfig
@@ -14,7 +14,7 @@
 	bool "LPD7A400 Card Engine"
 	select ARCH_LH7A400
 #	select IDE_POLL
-	select HAS_TOUCHSCREEN_ADS7843_LH7
+#	select HAS_TOUCHSCREEN_ADS7843_LH7
 	help
 	  Say Y here if you are using Logic Product Development's
 	  LPD7A400 CardEngine.  For the time being, the LPD7A400 and
@@ -24,7 +24,7 @@
 	bool "LPD7A404 Card Engine"
 	select ARCH_LH7A404
 #	select IDE_POLL
-	select HAS_TOUCHSCREEN_ADC_LH7
+#	select HAS_TOUCHSCREEN_ADC_LH7
 	help
 	  Say Y here if you are using Logic Product Development's
 	  LPD7A404 CardEngine. For the time being, the LPD7A400 and
diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c
index 3d73c1e..429c796 100644
--- a/arch/arm/mach-pnx4008/core.c
+++ b/arch/arm/mach-pnx4008/core.c
@@ -133,10 +133,79 @@
 	},
 };
 
+static struct platform_device nand_flash_device = {
+	.name = "pnx4008-flash",
+	.id = -1,
+	.dev = {
+		.coherent_dma_mask = 0xFFFFFFFF,
+	},
+};
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32) 0;
+
+static struct resource ohci_resources[] = {
+	{
+		.start = IO_ADDRESS(PNX4008_USB_CONFIG_BASE),
+		.end = IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0x100),
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = USB_HOST_INT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ohci_device = {
+	.name = "pnx4008-usb-ohci",
+	.id = -1,
+	.dev = {
+		.dma_mask = &ohci_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+		},
+	.num_resources = ARRAY_SIZE(ohci_resources),
+	.resource = ohci_resources,
+};
+
+static struct platform_device sdum_device = {
+	.name = "pnx4008-sdum",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+	},
+};
+
+static struct platform_device rgbfb_device = {
+	.name = "pnx4008-rgbfb",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+	}
+};
+
+struct resource watchdog_resources[] = {
+	{
+		.start = PNX4008_WDOG_BASE,
+		.end = PNX4008_WDOG_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device watchdog_device = {
+	.name = "pnx4008-watchdog",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(watchdog_resources),
+	.resource = watchdog_resources,
+};
+
 static struct platform_device *devices[] __initdata = {
 	&spipnx_1,
 	&spipnx_2,
 	&serial_device,
+	&ohci_device,
+	&nand_flash_device,
+	&sdum_device,
+	&rgbfb_device,
+	&watchdog_device,
 };
 
 
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
index db6393c..ba34654 100644
--- a/arch/arm/mach-s3c2410/gpio.c
+++ b/arch/arm/mach-s3c2410/gpio.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
- * S3C2410 GPIO support
+ * S3C24XX GPIO support
  *
  * 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
@@ -163,3 +163,22 @@
 }
 
 EXPORT_SYMBOL(s3c2410_modify_misccr);
+
+int s3c2410_gpio_getirq(unsigned int pin)
+{
+	if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
+		return -1;	/* not valid interrupts */
+
+	if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
+		return -1;	/* not valid pin */
+
+	if (pin < S3C2410_GPF4)
+		return (pin - S3C2410_GPF0) + IRQ_EINT0;
+
+	if (pin < S3C2410_GPG0)
+		return (pin - S3C2410_GPF4) + IRQ_EINT4;
+
+	return (pin - S3C2410_GPG0) + IRQ_EINT8;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/arch/arm/mach-s3c2410/s3c2410-gpio.c b/arch/arm/mach-s3c2410/s3c2410-gpio.c
index a2098f6..ec3a276 100644
--- a/arch/arm/mach-s3c2410/s3c2410-gpio.c
+++ b/arch/arm/mach-s3c2410/s3c2410-gpio.c
@@ -69,22 +69,3 @@
 }
 
 EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
-
-int s3c2410_gpio_getirq(unsigned int pin)
-{
-	if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
-		return -1;	/* not valid interrupts */
-
-	if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
-		return -1;	/* not valid pin */
-
-	if (pin < S3C2410_GPF4)
-		return (pin - S3C2410_GPF0) + IRQ_EINT0;
-
-	if (pin < S3C2410_GPG0)
-		return (pin - S3C2410_GPF4) + IRQ_EINT4;
-
-	return (pin - S3C2410_GPG0) + IRQ_EINT8;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
index 90a4130..78f4c13 100644
--- a/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -83,7 +83,7 @@
 		.refresh	= 64000,
 		.cas_latency	= 3,
 	}, {    /* Samsung K4S281632B-1H */
-	        .name           = "K4S281632b-1H",
+	        .name           = "K4S281632B-1H",
 		.rows           = 12,
 		.tck            = 10,
 		.trp            = 20,
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 50e6b6b..b797217 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -476,6 +476,9 @@
 
 /*
  * Make an area consistent for devices.
+ * Note: Drivers should NOT use this function directly, as it will break
+ * platforms with CONFIG_DMABOUNCE.
+ * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
 void consistent_sync(void *vaddr, size_t size, int direction)
 {
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 22217fe..b5814b4 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -32,40 +32,51 @@
 extern unsigned long phys_initrd_size;
 
 /*
- * The sole use of this is to pass memory configuration
- * data from paging_init to mem_init.
+ * This is used to pass memory configuration data from paging_init
+ * to mem_init, and by show_mem() to skip holes in the memory map.
  */
-static struct meminfo meminfo __initdata = { 0, };
+static struct meminfo meminfo = { 0, };
+
+#define for_each_nodebank(iter,mi,no)			\
+	for (iter = 0; iter < mi->nr_banks; iter++)	\
+		if (mi->bank[iter].node == no)
 
 void show_mem(void)
 {
 	int free = 0, total = 0, reserved = 0;
-	int shared = 0, cached = 0, slab = 0, node;
+	int shared = 0, cached = 0, slab = 0, node, i;
+	struct meminfo * mi = &meminfo;
 
 	printk("Mem-info:\n");
 	show_free_areas();
 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 
 	for_each_online_node(node) {
-		struct page *page, *end;
+		for_each_nodebank (i,mi,node) {
+			unsigned int pfn1, pfn2;
+			struct page *page, *end;
 
-		page = NODE_MEM_MAP(node);
-		end  = page + NODE_DATA(node)->node_spanned_pages;
+			pfn1 = mi->bank[i].start >> PAGE_SHIFT;
+			pfn2 = (mi->bank[i].size + mi->bank[i].start) >> PAGE_SHIFT;
 
-		do {
-			total++;
-			if (PageReserved(page))
-				reserved++;
-			else if (PageSwapCache(page))
-				cached++;
-			else if (PageSlab(page))
-				slab++;
-			else if (!page_count(page))
-				free++;
-			else
-				shared += page_count(page) - 1;
-			page++;
-		} while (page < end);
+			page = NODE_MEM_MAP(node) + pfn1;
+			end  = NODE_MEM_MAP(node) + pfn2;
+
+			do {
+				total++;
+				if (PageReserved(page))
+					reserved++;
+				else if (PageSwapCache(page))
+					cached++;
+				else if (PageSlab(page))
+					slab++;
+				else if (!page_count(page))
+					free++;
+				else
+					shared += page_count(page) - 1;
+				page++;
+			} while (page < end);
+		}
 	}
 
 	printk("%d pages of RAM\n", total);
@@ -76,10 +87,6 @@
 	printk("%d pages swap cached\n", cached);
 }
 
-#define for_each_nodebank(iter,mi,no)			\
-	for (iter = 0; iter < mi->nr_banks; iter++)	\
-		if (mi->bank[iter].node == no)
-
 /*
  * FIXME: We really want to avoid allocating the bootmap bitmap
  * over the top of the initrd.  Hopefully, this is located towards
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index e8b377d..2749c1f 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -909,7 +909,7 @@
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_IWMMXT
 	.long	cpu_pxa270_name
 	.long	xscale_processor_functions
 	.long	v4wbi_tlb_fns
diff --git a/arch/arm/oprofile/op_counter.h b/arch/arm/oprofile/op_counter.h
index 8c5351d..ca942a6 100644
--- a/arch/arm/oprofile/op_counter.h
+++ b/arch/arm/oprofile/op_counter.h
@@ -10,8 +10,6 @@
 #ifndef OP_COUNTER_H
 #define OP_COUNTER_H
 
-#define OP_MAX_COUNTER 5
-
 /* Per performance monitor configuration as set via
  * oprofilefs.
  */
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index 4fc05ee..e44b9ed 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -56,7 +56,7 @@
 {
 	int bits = 31 - fls(vd->significand >> 32);
 	if (bits == 31)
-		bits = 62 - fls(vd->significand);
+		bits = 63 - fls(vd->significand);
 
 	vfp_double_dump("normalise_denormal: in", vd);
 
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index a657a28..f08eafb 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -148,6 +148,7 @@
 	/*
 	 * These are arranged in priority order, least to highest.
 	 */
+	RAISE(FPSCR_DZC, FPSCR_DZE, FPE_FLTDIV);
 	RAISE(FPSCR_IXC, FPSCR_IXE, FPE_FLTRES);
 	RAISE(FPSCR_UFC, FPSCR_UFE, FPE_FLTUND);
 	RAISE(FPSCR_OFC, FPSCR_OFE, FPE_FLTOVF);
diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile
index cefc95a..7b842e9 100644
--- a/arch/avr32/Makefile
+++ b/arch/avr32/Makefile
@@ -7,7 +7,7 @@
 
 # Default target when executing plain make
 .PHONY: all
-all: uImage vmlinux.elf linux.lst
+all: uImage vmlinux.elf
 
 KBUILD_DEFCONFIG	:= atstk1002_defconfig
 
@@ -21,9 +21,7 @@
 CFLAGS		+= $(cpuflags-y)
 AFLAGS		+= $(cpuflags-y)
 
-CHECKFLAGS	+= -D__avr32__
-
-LIBGCC		:= $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+CHECKFLAGS	+= -D__avr32__ -D__BIG_ENDIAN
 
 head-$(CONFIG_LOADER_U_BOOT)		+= arch/avr32/boot/u-boot/head.o
 head-y					+= arch/avr32/kernel/head.o
@@ -32,7 +30,7 @@
 core-$(CONFIG_LOADER_U_BOOT)		+= arch/avr32/boot/u-boot/
 core-y					+= arch/avr32/kernel/
 core-y					+= arch/avr32/mm/
-libs-y					+= arch/avr32/lib/ #$(LIBGCC)
+libs-y					+= arch/avr32/lib/
 
 archincdir-$(CONFIG_PLATFORM_AT32AP)	:= arch-at32ap
 
@@ -48,6 +46,8 @@
 
 archprepare: include/asm-avr32/.arch
 
+CLEAN_FILES += include/asm-avr32/.arch include/asm-avr32/arch
+
 BOOT_TARGETS := vmlinux.elf vmlinux.bin uImage uImage.srec
 
 .PHONY: $(BOOT_TARGETS) install
@@ -71,14 +71,19 @@
 install: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
 
-linux.s: vmlinux
+vmlinux.s: vmlinux
 	$(call if_changed,disasm)
 
-linux.lst: vmlinux
+vmlinux.lst: vmlinux
 	$(call if_changed,listing)
 
+CLEAN_FILES += vmlinux.s vmlinux.lst
+
+archclean:
+	$(Q)$(MAKE) $(clean)=$(boot)
+
 define archhelp
   @echo '* vmlinux.elf		- ELF image with load address 0'
   @echo '  vmlinux.cso		- PathFinder CSO image'
-  @echo '  uImage		- Create a bootable image for U-Boot'
+  @echo '* uImage		- Create a bootable image for U-Boot'
 endef
diff --git a/arch/avr32/boards/atstk1000/setup.c b/arch/avr32/boards/atstk1000/setup.c
index 191ab85..272c011 100644
--- a/arch/avr32/boards/atstk1000/setup.c
+++ b/arch/avr32/boards/atstk1000/setup.c
@@ -21,15 +21,6 @@
 
 struct lcdc_platform_data __initdata atstk1000_fb0_data;
 
-asmlinkage void __init board_early_init(void)
-{
-	extern void sdram_init(void);
-
-#ifdef CONFIG_LOADER_STANDALONE
-	sdram_init();
-#endif
-}
-
 void __init board_setup_fbmem(unsigned long fbmem_start,
 			      unsigned long fbmem_size)
 {
diff --git a/arch/avr32/boot/images/Makefile b/arch/avr32/boot/images/Makefile
index ccd74eee..219720a 100644
--- a/arch/avr32/boot/images/Makefile
+++ b/arch/avr32/boot/images/Makefile
@@ -37,14 +37,12 @@
 			    --change-section-lma .data-0x80000000 \
 			    --change-section-lma .init-0x80000000 \
 			    --change-section-lma .bss-0x80000000 \
-			    --change-section-lma .initrd-0x80000000 \
 			    --change-section-lma __param-0x80000000 \
 			    --change-section-lma __ksymtab-0x80000000 \
 			    --change-section-lma __ksymtab_gpl-0x80000000 \
 			    --change-section-lma __kcrctab-0x80000000 \
 			    --change-section-lma __kcrctab_gpl-0x80000000 \
 			    --change-section-lma __ksymtab_strings-0x80000000 \
-			    --change-section-lma .got-0x80000000 \
 			    --set-start 0xa0000000
 $(obj)/vmlinux.elf: vmlinux FORCE
 	$(call if_changed,objcopy)
@@ -59,4 +57,4 @@
 	sh $(srctree)/install-kernel.sh $<
 
 # Generated files to be removed upon make clean
-clean-files	:= vmlinux* uImage uImage.srec
+clean-files	:= vmlinux.elf vmlinux.bin vmlinux.gz uImage uImage.srec
diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig
index 6c2c5e0..ae92a14 100644
--- a/arch/avr32/configs/atstk1002_defconfig
+++ b/arch/avr32/configs/atstk1002_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Tue Jul 11 12:41:36 2006
+# Linux kernel version: 2.6.19-rc2
+# Fri Oct 20 11:52:37 2006
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -25,16 +26,23 @@
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+# CONFIG_UTS_NS is not set
+CONFIG_AUDIT=y
 # CONFIG_IKCONFIG is not set
-# CONFIG_RELAY is not set
+CONFIG_RELAY=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_TASK_XACCT is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,14 +51,15 @@
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 # CONFIG_BASE_FULL is not set
-# CONFIG_FUTEX is not set
-# CONFIG_EPOLL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-# CONFIG_SLAB is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=1
-CONFIG_SLOB=y
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -65,6 +74,7 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -166,10 +176,12 @@
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -199,7 +211,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -212,7 +223,6 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_TCPPROBE is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
@@ -239,7 +249,84 @@
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
 
 #
 # Parallel port support
@@ -260,11 +347,18 @@
 CONFIG_BLK_DEV_RAM=m
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -274,6 +368,12 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -305,14 +405,11 @@
 #
 # PHY device support
 #
-# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MACB=y
+# CONFIG_NET_ETHERNET is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -341,10 +438,11 @@
 CONFIG_PPP_ASYNC=m
 # CONFIG_PPP_SYNC_TTY is not set
 CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_BSDCOMP=m
 # CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -417,7 +515,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -427,23 +524,13 @@
 #
 # SPI support
 #
-CONFIG_SPI=y
-# CONFIG_SPI_DEBUG is not set
-CONFIG_SPI_MASTER=y
-
-#
-# SPI Master Controller Drivers
-#
-CONFIG_SPI_ATMEL=m
-# CONFIG_SPI_BITBANG is not set
-
-#
-# SPI Protocol Masters
-#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
 
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -452,14 +539,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -470,28 +552,8 @@
 # Graphics support
 #
 # CONFIG_FIRMWARE_EDID is not set
-CONFIG_FB=m
-CONFIG_FB_CFB_FILLRECT=m
-CONFIG_FB_CFB_COPYAREA=m
-CONFIG_FB_CFB_IMAGEBLIT=m
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_BACKLIGHT is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-CONFIG_FB_SIDSA=m
-CONFIG_FB_SIDSA_DEFAULT_BPP=24
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
-CONFIG_LCD_CLASS_DEVICE=m
-CONFIG_LCD_DEVICE=y
-CONFIG_LCD_LTV350QV=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -561,18 +623,21 @@
 #
 # File systems
 #
-CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS=m
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
-CONFIG_ROMFS_FS=m
-# CONFIG_INOTIFY is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
@@ -600,8 +665,10 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_CONFIGFS_FS=m
@@ -616,6 +683,16 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -626,26 +703,10 @@
 #
 # Network File Systems
 #
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -665,7 +726,7 @@
 CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=m
+# CONFIG_NLS_CODEPAGE_850 is not set
 # CONFIG_NLS_CODEPAGE_852 is not set
 # CONFIG_NLS_CODEPAGE_855 is not set
 # CONFIG_NLS_CODEPAGE_857 is not set
@@ -705,13 +766,17 @@
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_RWSEMS is not set
@@ -722,11 +787,13 @@
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
-CONFIG_KPROBES=y
+# CONFIG_KPROBES is not set
 
 #
 # Security options
@@ -740,15 +807,13 @@
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
-CONFIG_CRC32=m
+CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c
index 04f767a..372e3f8 100644
--- a/arch/avr32/kernel/avr32_ksyms.c
+++ b/arch/avr32/kernel/avr32_ksyms.c
@@ -7,6 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/io.h>
 #include <linux/module.h>
 
 #include <asm/checksum.h>
@@ -53,3 +54,11 @@
 EXPORT_SYMBOL(find_first_bit);
 EXPORT_SYMBOL(find_next_bit);
 EXPORT_SYMBOL(generic_find_next_zero_le_bit);
+
+/* I/O primitives (lib/io-*.S) */
+EXPORT_SYMBOL(__raw_readsb);
+EXPORT_SYMBOL(__raw_readsw);
+EXPORT_SYMBOL(__raw_readsl);
+EXPORT_SYMBOL(__raw_writesb);
+EXPORT_SYMBOL(__raw_writesw);
+EXPORT_SYMBOL(__raw_writesl);
diff --git a/arch/avr32/kernel/head.S b/arch/avr32/kernel/head.S
index 773b7ad..6163bd0 100644
--- a/arch/avr32/kernel/head.S
+++ b/arch/avr32/kernel/head.S
@@ -30,9 +30,6 @@
 	mov	r7, 0
 #endif
 
-	/* Set up the PIO, SDRAM controller, early printk, etc. */
-	rcall	board_early_init
-
 	/* Start the show */
 	lddpc   pc, kernel_start_addr
 
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index 6caf9e8..ca41fc1 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -109,7 +109,7 @@
 	void *addr = (void *)regs->pc;
 	int ret = 0;
 
-	pr_debug("kprobe_handler: kprobe_running=%d\n",
+	pr_debug("kprobe_handler: kprobe_running=%p\n",
 		 kprobe_running());
 
 	/*
diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c
index dfc32f2..b599eae 100644
--- a/arch/avr32/kernel/module.c
+++ b/arch/avr32/kernel/module.c
@@ -263,7 +263,7 @@
 			 * value of PC.  Just subtract the value of
 			 * GOT, and we're done.
 			 */
-			pr_debug("GOTPC: PC=0x%lx, got_offset=0x%lx, core=0x%p\n",
+			pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n",
 				 relocation, module->arch.got_offset,
 				 module->module_core);
 			relocation -= ((unsigned long)module->module_core
@@ -282,7 +282,7 @@
 			    && (relocation & 0xffff0000) != 0xffff0000)
 				return reloc_overflow(module, "R_AVR32_GOT16S",
 						      relocation);
-			pr_debug("GOT reloc @ 0x%lx -> %lu\n",
+			pr_debug("GOT reloc @ 0x%x -> %u\n",
 				 rel->r_offset, relocation);
 			value = *location;
 			value = ((value & 0xffff0000)
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 3c89e59..f2e81cd 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -157,7 +157,7 @@
 	unsigned long tmp;
 	int ret;
 
-	pr_debug("arch_ptrace(%ld, %ld, %#lx, %#lx)\n",
+	pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n",
 		 request, child->pid, addr, data);
 
 	pr_debug("ptrace: Enabling monitor mode...\n");
diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S
index 7589a9b..890286a 100644
--- a/arch/avr32/kernel/syscall-stubs.S
+++ b/arch/avr32/kernel/syscall-stubs.S
@@ -100,3 +100,12 @@
 	rcall	sys_splice
 	sub	sp, -4
 	popm	pc
+
+	.global	__sys_epoll_pwait
+	.type	__sys_epoll_pwait,@function
+__sys_epoll_pwait:
+	pushm	lr
+	st.w	--sp, ARG6
+	rcall	sys_epoll_pwait
+	sub	sp, -4
+	popm	pc
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S
index 63b2069..db8f8b5 100644
--- a/arch/avr32/kernel/syscall_table.S
+++ b/arch/avr32/kernel/syscall_table.S
@@ -286,4 +286,5 @@
 	.long	sys_sync_file_range
 	.long	sys_tee
 	.long	sys_vmsplice
+	.long	__sys_epoll_pwait	/* 265 */
 	.long	sys_ni_syscall		/* r8 is saturated at nr_syscalls */
diff --git a/arch/avr32/kernel/vmlinux.lds.c b/arch/avr32/kernel/vmlinux.lds.c
index cdd627c..5c4424e 100644
--- a/arch/avr32/kernel/vmlinux.lds.c
+++ b/arch/avr32/kernel/vmlinux.lds.c
@@ -38,13 +38,7 @@
 		__setup_end = .;
 		. = ALIGN(4);
 		__initcall_start = .;
-			*(.initcall1.init)
-			*(.initcall2.init)
-			*(.initcall3.init)
-			*(.initcall4.init)
-			*(.initcall5.init)
-			*(.initcall6.init)
-			*(.initcall7.init)
+			INITCALLS
 		__initcall_end = .;
 		__con_initcall_start = .;
 			*(.con_initcall.init)
diff --git a/arch/avr32/lib/Makefile b/arch/avr32/lib/Makefile
index 09ac43e..084d95b 100644
--- a/arch/avr32/lib/Makefile
+++ b/arch/avr32/lib/Makefile
@@ -7,4 +7,5 @@
 lib-y	+= delay.o memset.o memcpy.o findbit.o
 lib-y	+= csum_partial.o csum_partial_copy_generic.o
 lib-y	+= io-readsw.o io-readsl.o io-writesw.o io-writesl.o
+lib-y	+= io-readsb.o io-writesb.o
 lib-y	+= __avr32_lsl64.o __avr32_lsr64.o __avr32_asr64.o
diff --git a/arch/avr32/lib/findbit.S b/arch/avr32/lib/findbit.S
index 2b4856f..c6b91de 100644
--- a/arch/avr32/lib/findbit.S
+++ b/arch/avr32/lib/findbit.S
@@ -136,6 +136,7 @@
 	/* offset is not word-aligned. Handle the first (32 - r10) bits */
 	ldswp.w	r8, r12[0]
 	sub	r12, -4
+	com	r8
 	lsr	r8, r8, r10
 	brne	.L_found
 
@@ -146,7 +147,7 @@
 
 	/* Main loop. offset must be word-aligned */
 1:	ldswp.w	r8, r12[0]
-	cp.w	r8, 0
+	com	r8
 	brne	.L_found
 	sub	r12, -4
 	sub	r9, 32
diff --git a/arch/avr32/lib/io-readsb.S b/arch/avr32/lib/io-readsb.S
new file mode 100644
index 0000000..2be5da7
--- /dev/null
+++ b/arch/avr32/lib/io-readsb.S
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * 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.
+ */
+
+	.text
+.Lnot_word_aligned:
+1:	ld.ub	r8, r12[0]
+	sub	r10, 1
+	st.b	r11++, r8
+	reteq	r12
+	tst	r11, r9
+	brne	1b
+
+	/* fall through */
+
+	.global	__raw_readsb
+	.type	__raw_readsb,@function
+__raw_readsb:
+	cp.w	r10, 0
+	mov	r9, 3
+	reteq	r12
+
+	tst	r11, r9
+	brne	.Lnot_word_aligned
+
+	sub	r10, 4
+	brlt	2f
+
+1:	ldins.b	r8:t, r12[0]
+	ldins.b	r8:u, r12[0]
+	ldins.b	r8:l, r12[0]
+	ldins.b r8:b, r12[0]
+	st.w	r11++, r8
+	sub	r10, 4
+	brge	1b
+
+2:	sub	r10, -4
+	reteq	r12
+
+3:	ld.uh	r8, r12[0]
+	sub	r10, 1
+	st.b	r11++, r8
+	brne	3b
+
+	retal	r12
diff --git a/arch/avr32/lib/io-writesb.S b/arch/avr32/lib/io-writesb.S
new file mode 100644
index 0000000..b4ebaac
--- /dev/null
+++ b/arch/avr32/lib/io-writesb.S
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * 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.
+ */
+
+	.text
+.Lnot_word_aligned:
+1:	ld.ub	r8, r11++
+	sub	r10, 1
+	st.b	r12[0], r8
+	reteq	r12
+	tst	r11, r9
+	brne	1b
+
+	/* fall through */
+
+	.global	__raw_writesb
+	.type	__raw_writesb,@function
+__raw_writesb:
+	cp.w	r10, 0
+	mov	r9, 3
+	reteq	r12
+
+	tst	r11, r9
+	brne	.Lnot_word_aligned
+
+	sub	r10, 4
+	brlt	2f
+
+1:	ld.w	r8, r11++
+	bfextu	r9, r8, 24, 8
+	st.b	r12[0], r9
+	bfextu	r9, r8, 16, 8
+	st.b	r12[0], r9
+	bfextu	r9, r8, 8, 8
+	st.b	r12[0], r9
+	st.b	r12[0], r8
+	sub	r10, 4
+	brge	1b
+
+2:	sub	r10, -4
+	reteq	r12
+
+3:	ld.ub	r8, r11++
+	sub	r10, 1
+	st.b	r12[0], r8
+	brne	3b
+
+	retal	r12
diff --git a/arch/avr32/mach-at32ap/hsmc.h b/arch/avr32/mach-at32ap/hsmc.h
index 5681276..d1d48e2 100644
--- a/arch/avr32/mach-at32ap/hsmc.h
+++ b/arch/avr32/mach-at32ap/hsmc.h
@@ -120,8 +120,8 @@
 
 /* Register access macros */
 #define hsmc_readl(port,reg)						\
-	readl((port)->regs + HSMC_##reg)
+	__raw_readl((port)->regs + HSMC_##reg)
 #define hsmc_writel(port,reg,value)					\
-	writel((value), (port)->regs + HSMC_##reg)
+	__raw_writel((value), (port)->regs + HSMC_##reg)
 
 #endif /* __ASM_AVR32_HSMC_H__ */
diff --git a/arch/avr32/mach-at32ap/intc.h b/arch/avr32/mach-at32ap/intc.h
index d289ca2..4d3664e 100644
--- a/arch/avr32/mach-at32ap/intc.h
+++ b/arch/avr32/mach-at32ap/intc.h
@@ -321,7 +321,9 @@
 #define INTC_MKBF(name, value)       (((value) & ((1 << INTC_##name##_SIZE) - 1)) << INTC_##name##_OFFSET)
 #define INTC_GETBF(name, value)      (((value) >> INTC_##name##_OFFSET) & ((1 << INTC_##name##_SIZE) - 1))
 
-#define intc_readl(port,reg)         readl((port)->regs + INTC_##reg)
-#define intc_writel(port,reg,value)  writel((value), (port)->regs + INTC_##reg)
+#define intc_readl(port,reg)					\
+	__raw_readl((port)->regs + INTC_##reg)
+#define intc_writel(port,reg,value)				\
+	__raw_writel((value), (port)->regs + INTC_##reg)
 
 #endif /* __ASM_AVR32_PERIHP_INTC_H__ */
diff --git a/arch/avr32/mach-at32ap/pio.h b/arch/avr32/mach-at32ap/pio.h
index cfea123..50fa3ac 100644
--- a/arch/avr32/mach-at32ap/pio.h
+++ b/arch/avr32/mach-at32ap/pio.h
@@ -170,8 +170,10 @@
 #define PIO_BFINS(name,value,old)              (((old) & ~(((1 << PIO_##name##_SIZE) - 1) << PIO_##name##_OFFSET)) | PIO_BF(name,value))
 
 /* Register access macros */
-#define pio_readl(port,reg)                    readl((port)->regs + PIO_##reg)
-#define pio_writel(port,reg,value)             writel((value), (port)->regs + PIO_##reg)
+#define pio_readl(port,reg)					\
+	__raw_readl((port)->regs + PIO_##reg)
+#define pio_writel(port,reg,value)				\
+	__raw_writel((value), (port)->regs + PIO_##reg)
 
 void at32_init_pio(struct platform_device *pdev);
 
diff --git a/arch/avr32/mach-at32ap/sm.h b/arch/avr32/mach-at32ap/sm.h
index 2756582..cad02b5 100644
--- a/arch/avr32/mach-at32ap/sm.h
+++ b/arch/avr32/mach-at32ap/sm.h
@@ -234,7 +234,9 @@
 #define SM_BFINS(name,value,old)                (((old) & ~(((1 << SM_##name##_SIZE) - 1) << SM_##name##_OFFSET)) | SM_BF(name,value))
 
 /* Register access macros */
-#define sm_readl(port,reg)                      readl((port)->regs + SM_##reg)
-#define sm_writel(port,reg,value)               writel((value), (port)->regs + SM_##reg)
+#define sm_readl(port,reg)					\
+	__raw_readl((port)->regs + SM_##reg)
+#define sm_writel(port,reg,value)				\
+	__raw_writel((value), (port)->regs + SM_##reg)
 
 #endif /* __ASM_AVR32_SM_H__ */
diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c
index 3e6c410..70da689 100644
--- a/arch/avr32/mm/init.c
+++ b/arch/avr32/mm/init.c
@@ -206,7 +206,7 @@
 
 	if (mem_ramdisk) {
 #ifdef CONFIG_BLK_DEV_INITRD
-		initrd_start = __va(mem_ramdisk->addr);
+		initrd_start = (unsigned long)__va(mem_ramdisk->addr);
 		initrd_end = initrd_start + mem_ramdisk->size;
 
 		print_memory_map("RAMDISK images", mem_ramdisk);
diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c
index 8cfec65..3437c82 100644
--- a/arch/avr32/mm/ioremap.c
+++ b/arch/avr32/mm/ioremap.c
@@ -77,6 +77,8 @@
 
 	if ((unsigned long)addr >= P4SEG)
 		return;
+	if (PXSEG(addr) == P2SEG)
+		return;
 
 	p = remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr));
 	if (unlikely(!p)) {
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index ba096eb..2449637 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -2051,7 +2051,6 @@
 	spin_lock_irqsave(&cryptocop_process_lock, process_flags);
 
 	/* Empty the job queue. */
-	spin_lock_irqsave(&cryptocop_process_lock, process_flags);
 	for (i = 0; i < cryptocop_prio_no_prios; i++){
 		if (!list_empty(&(cryptocop_job_queues[i].jobs))){
 			list_for_each_safe(node, tmp, &(cryptocop_job_queues[i].jobs)) {
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index f474534..9c1fb12 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -44,13 +44,7 @@
 
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index 6406c38..756325d 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -118,13 +118,7 @@
 	. = ALIGN(0x4) ;
 	___setup_end = .;
 	___initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
+		INITCALLS
 	___initcall_end = .;
 	___con_initcall_start = .;
 		*(.con_initcall.init)
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 7cc0b18..0677908 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -42,6 +42,10 @@
 # temporary until string.h is fixed
 cflags-y += -ffreestanding
 
+# this works around some issues with generating unwind tables in older gccs
+# newer gccs do it by default
+cflags-y += -maccumulate-outgoing-args
+
 # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
 # a lot more stack due to the lack of sharing of stacklots:
 CFLAGS				+= $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
@@ -51,8 +55,8 @@
 AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
 
 # is .cfi_signal_frame supported too?
-cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
+AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
 
 CFLAGS += $(cflags-y)
 
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 60c0c02..97aacd6 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc1
-# Thu Oct  5 13:04:53 2006
+# Linux kernel version: 2.6.19-rc2-git4
+# Sat Oct 21 03:38:56 2006
 #
 CONFIG_X86_32=y
 CONFIG_GENERIC_TIME=y
@@ -380,8 +380,8 @@
 CONFIG_INET6_XFRM_MODE_TUNNEL=y
 # CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -483,6 +483,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -1024,6 +1031,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -1032,12 +1040,6 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-# CONFIG_TIFM_CORE is not set
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -1169,7 +1171,6 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1215,6 +1216,7 @@
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1284,6 +1286,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1307,6 +1310,7 @@
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1384,7 +1388,6 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
 # CONFIG_9P_FS is not set
-CONFIG_GENERIC_ACL=y
 
 #
 # Partition Types
@@ -1437,10 +1440,6 @@
 CONFIG_NLS_UTF8=y
 
 #
-# Distributed Lock Manager
-#
-
-#
 # Instrumentation Support
 #
 CONFIG_PROFILING=y
@@ -1480,6 +1479,7 @@
 CONFIG_UNWIND_INFO=y
 CONFIG_STACK_UNWIND=y
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 CONFIG_EARLY_PRINTK=y
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index ab974ff..d12fb97 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -70,7 +70,7 @@
 
 #define PREFIX			"ACPI: "
 
-int acpi_noirq __initdata;	/* skip ACPI IRQ initialization */
+int acpi_noirq;				/* skip ACPI IRQ initialization */
 int acpi_pci_disabled __initdata;	/* skip ACPI PCI scan and IRQ initialization */
 int acpi_ht __initdata = 1;	/* enable HT */
 
@@ -82,6 +82,7 @@
 acpi_interrupt_flags acpi_sci_flags __initdata;
 int acpi_sci_override_gsi __initdata;
 int acpi_skip_timer_override __initdata;
+int acpi_use_timer_override __initdata;
 
 #ifdef CONFIG_X86_LOCAL_APIC
 static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
@@ -1300,6 +1301,13 @@
 	return 0;
 }
 early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override);
+
+static int __init parse_acpi_use_timer_override(char *arg)
+{
+	acpi_use_timer_override = 1;
+	return 0;
+}
+early_param("acpi_use_timer_override", parse_acpi_use_timer_override);
 #endif /* CONFIG_X86_IO_APIC */
 
 static int __init setup_acpi_sci(char *s)
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c
index fe799b1..c984169 100644
--- a/arch/i386/kernel/acpi/earlyquirk.c
+++ b/arch/i386/kernel/acpi/earlyquirk.c
@@ -27,11 +27,17 @@
 #ifdef CONFIG_ACPI
 	/* According to Nvidia all timer overrides are bogus unless HPET
 	   is enabled. */
-	if (vendor == PCI_VENDOR_ID_NVIDIA) {
+	if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
 		nvidia_hpet_detected = 0;
 		acpi_table_parse(ACPI_HPET, nvidia_hpet_check);
 		if (nvidia_hpet_detected == 0) {
 			acpi_skip_timer_override = 1;
+			  printk(KERN_INFO "Nvidia board "
+                       "detected. Ignoring ACPI "
+                       "timer override.\n");
+                printk(KERN_INFO "If you got timer trouble "
+			 	 "try acpi_use_timer_override\n");
+
 		}
 	}
 #endif
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 2af6585..a60358f 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -198,7 +198,7 @@
  *   (APM) BIOS Interface Specification, Revision 1.2, February 1996.
  *
  * [This document is available from Microsoft at:
- *    http://www.microsoft.com/hwdev/busbios/amp_12.htm]
+ *    http://www.microsoft.com/whdc/archive/amp_12.mspx]
  */
 
 #include <linux/module.h>
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index be9d883..ca31f18 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -317,7 +317,7 @@
 	movl %eax,%gs
 	lldt %ax
 	cld			# gcc2 wants the direction flag cleared at all times
-	pushl %eax		# fake return address
+	pushl $0		# fake return address for unwinder
 #ifdef CONFIG_SMP
 	movb ready, %cl
 	movb $1, ready
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 350192d..3b7a63e 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -91,6 +91,46 @@
 	int apic, pin, next;
 } irq_2_pin[PIN_MAP_SIZE];
 
+struct io_apic {
+	unsigned int index;
+	unsigned int unused[3];
+	unsigned int data;
+};
+
+static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
+{
+	return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
+		+ (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK);
+}
+
+static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+	writel(reg, &io_apic->index);
+	return readl(&io_apic->data);
+}
+
+static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+	writel(reg, &io_apic->index);
+	writel(value, &io_apic->data);
+}
+
+/*
+ * Re-write a value: to be used for read-modify-write
+ * cycles where the read already set up the index register.
+ *
+ * Older SiS APIC requires we rewrite the index register
+ */
+static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
+{
+	volatile struct io_apic *io_apic = io_apic_base(apic);
+	if (sis_apic_bug)
+		writel(reg, &io_apic->index);
+	writel(value, &io_apic->data);
+}
+
 union entry_union {
 	struct { u32 w1, w2; };
 	struct IO_APIC_route_entry entry;
@@ -107,12 +147,34 @@
 	return eu.entry;
 }
 
+/*
+ * When we write a new IO APIC routing entry, we need to write the high
+ * word first! If the mask bit in the low word is clear, we will enable
+ * the interrupt, and we need to make sure the entry is fully populated
+ * before that happens.
+ */
 static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
 {
 	unsigned long flags;
 	union entry_union eu;
 	eu.entry = e;
 	spin_lock_irqsave(&ioapic_lock, flags);
+	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
+	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+/*
+ * When we mask an IO APIC routing entry, we need to write the low
+ * word first, in order to set the mask bit before we change the
+ * high bits!
+ */
+static void ioapic_mask_entry(int apic, int pin)
+{
+	unsigned long flags;
+	union entry_union eu = { .entry.mask = 1 };
+
+	spin_lock_irqsave(&ioapic_lock, flags);
 	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
 	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -234,9 +296,7 @@
 	/*
 	 * Disable it in the IO-APIC irq-routing table:
 	 */
-	memset(&entry, 0, sizeof(entry));
-	entry.mask = 1;
-	ioapic_write_entry(apic, pin, entry);
+	ioapic_mask_entry(apic, pin);
 }
 
 static void clear_IO_APIC (void)
@@ -1227,9 +1287,11 @@
 			trigger == IOAPIC_LEVEL)
 		set_irq_chip_and_handler_name(irq, &ioapic_chip,
 					 handle_fasteoi_irq, "fasteoi");
-	else
+	else {
+		irq_desc[irq].status |= IRQ_DELAYED_DISABLE;
 		set_irq_chip_and_handler_name(irq, &ioapic_chip,
 					 handle_edge_irq, "edge");
+	}
 	set_intr_gate(vector, interrupt[irq]);
 }
 
@@ -2564,18 +2626,16 @@
 
 static void target_ht_irq(unsigned int irq, unsigned int dest)
 {
-	u32 low, high;
-	low  = read_ht_irq_low(irq);
-	high = read_ht_irq_high(irq);
+	struct ht_irq_msg msg;
+	fetch_ht_irq_msg(irq, &msg);
 
-	low  &= ~(HT_IRQ_LOW_DEST_ID_MASK);
-	high &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
+	msg.address_lo &= ~(HT_IRQ_LOW_DEST_ID_MASK);
+	msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
 
-	low  |= HT_IRQ_LOW_DEST_ID(dest);
-	high |= HT_IRQ_HIGH_DEST_ID(dest);
+	msg.address_lo |= HT_IRQ_LOW_DEST_ID(dest);
+	msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest);
 
-	write_ht_irq_low(irq, low);
-	write_ht_irq_high(irq, high);
+	write_ht_irq_msg(irq, &msg);
 }
 
 static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
@@ -2613,7 +2673,7 @@
 
 	vector = assign_irq_vector(irq);
 	if (vector >= 0) {
-		u32 low, high;
+		struct ht_irq_msg msg;
 		unsigned dest;
 		cpumask_t tmp;
 
@@ -2621,9 +2681,10 @@
 		cpu_set(vector >> 8, tmp);
 		dest = cpu_mask_to_apicid(tmp);
 
-		high = 	HT_IRQ_HIGH_DEST_ID(dest);
+		msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
 
-		low =	HT_IRQ_LOW_BASE |
+		msg.address_lo =
+			HT_IRQ_LOW_BASE |
 			HT_IRQ_LOW_DEST_ID(dest) |
 			HT_IRQ_LOW_VECTOR(vector) |
 			((INT_DEST_MODE == 0) ?
@@ -2635,8 +2696,7 @@
 				HT_IRQ_LOW_MT_ARBITRATED) |
 			HT_IRQ_LOW_IRQ_MASKED;
 
-		write_ht_irq_low(irq, low);
-		write_ht_irq_high(irq, high);
+		write_ht_irq_msg(irq, &msg);
 
 		set_irq_chip_and_handler_name(irq, &ht_irq_chip,
 					      handle_edge_irq, "edge");
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index d98e44b..fc79e1e 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -361,8 +361,11 @@
 	asm volatile ( ".global kretprobe_trampoline\n"
 			"kretprobe_trampoline: \n"
 			"	pushf\n"
-			/* skip cs, eip, orig_eax, es, ds */
-			"	subl $20, %esp\n"
+			/* skip cs, eip, orig_eax */
+			"	subl $12, %esp\n"
+			"	pushl %gs\n"
+			"	pushl %ds\n"
+			"	pushl %es\n"
 			"	pushl %eax\n"
 			"	pushl %ebp\n"
 			"	pushl %edi\n"
@@ -373,10 +376,10 @@
 			"	movl %esp, %eax\n"
 			"	call trampoline_handler\n"
 			/* move eflags to cs */
-			"	movl 48(%esp), %edx\n"
-			"	movl %edx, 44(%esp)\n"
+			"	movl 52(%esp), %edx\n"
+			"	movl %edx, 48(%esp)\n"
 			/* save true return address on eflags */
-			"	movl %eax, 48(%esp)\n"
+			"	movl %eax, 52(%esp)\n"
 			"	popl %ebx\n"
 			"	popl %ecx\n"
 			"	popl %edx\n"
@@ -384,8 +387,8 @@
 			"	popl %edi\n"
 			"	popl %ebp\n"
 			"	popl %eax\n"
-			/* skip eip, orig_eax, es, ds */
-			"	addl $16, %esp\n"
+			/* skip eip, orig_eax, es, ds, gs */
+			"	addl $20, %esp\n"
 			"	popf\n"
 			"	ret\n");
 }
@@ -404,6 +407,10 @@
 	INIT_HLIST_HEAD(&empty_rp);
 	spin_lock_irqsave(&kretprobe_lock, flags);
 	head = kretprobe_inst_table_head(current);
+	/* fixup registers */
+	regs->xcs = __KERNEL_CS;
+	regs->eip = trampoline_address;
+	regs->orig_eax = 0xffffffff;
 
 	/*
 	 * It is possible to have multiple instances associated with a given
@@ -425,6 +432,7 @@
 
 		if (ri->rp && ri->rp->handler){
 			__get_cpu_var(current_kprobe) = &ri->rp->kp;
+			get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
 			ri->rp->handler(ri, regs);
 			__get_cpu_var(current_kprobe) = NULL;
 		}
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
index c4d0291..23f5984 100644
--- a/arch/i386/kernel/microcode.c
+++ b/arch/i386/kernel/microcode.c
@@ -577,7 +577,7 @@
 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
 	mutex_lock(&microcode_mutex);
 	collect_cpu_info(cpu);
-	if (uci->valid)
+	if (uci->valid && system_state == SYSTEM_RUNNING)
 		cpu_request_microcode(cpu);
 	mutex_unlock(&microcode_mutex);
 	set_cpus_allowed(current, old);
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 3e8e3ad..eaafe23 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -219,11 +219,11 @@
 	int cpu;
 
 	/* Enable NMI watchdog for newer systems.
-           Actually it should be safe for most systems before 2004 too except
-	   for some IBM systems that corrupt registers when NMI happens
-	   during SMM. Unfortunately we don't have more exact information
- 	   on these and use this coarse check. */
-	if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004)
+	   Probably safe on most older systems too, but let's be careful.
+	   IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM
+	   which hangs the system. Disable watchdog for all thinkpads */
+	if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 &&
+		!dmi_name_in_vendors("ThinkPad"))
 		nmi_watchdog = NMI_LOCAL_APIC;
 
 	if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 57d3759..dd53c58 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -205,7 +205,7 @@
 void cpu_idle_wait(void)
 {
 	unsigned int cpu, this_cpu = get_cpu();
-	cpumask_t map;
+	cpumask_t map, tmp = current->cpus_allowed;
 
 	set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
 	put_cpu();
@@ -227,6 +227,8 @@
 		}
 		cpus_and(map, map, cpu_online_map);
 	} while (!cpus_empty(map));
+
+	set_cpus_allowed(current, tmp);
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
@@ -336,7 +338,6 @@
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
 	struct pt_regs regs;
-	int err;
 
 	memset(&regs, 0, sizeof(regs));
 
@@ -351,10 +352,7 @@
 	regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
 
 	/* Ok, create the new process.. */
-	err = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-	if (err == 0) /* terminate kernel stack */
-		task_pt_regs(current)->eip = 0;
-	return err;
+	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
 }
 EXPORT_SYMBOL(kernel_thread);
 
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 519e63c..141041d 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -846,7 +846,7 @@
 static int __init
 efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
 {
-	memory_present(0, start, end);
+	memory_present(0, PFN_UP(start), PFN_DOWN(end));
 	return 0;
 }
 
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 00489b7..fe9c5e8 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -129,15 +129,19 @@
 
 #ifdef	CONFIG_FRAME_POINTER
 	while (valid_stack_ptr(tinfo, (void *)ebp)) {
+		unsigned long new_ebp;
 		addr = *(unsigned long *)(ebp + 4);
 		ops->address(data, addr);
 		/*
 		 * break out of recursive entries (such as
-		 * end_of_stack_stop_unwind_function):
+		 * end_of_stack_stop_unwind_function). Also,
+		 * we can never allow a frame pointer to
+		 * move downwards!
 	 	 */
-		if (ebp == *(unsigned long *)ebp)
+	 	new_ebp = *(unsigned long *)ebp;
+		if (new_ebp <= ebp)
 			break;
-		ebp = *(unsigned long *)ebp;
+		ebp = new_ebp;
 	}
 #else
 	while (valid_stack_ptr(tinfo, stack)) {
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 1e7ac1c..c6f84a0 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -51,6 +51,7 @@
   __tracedata_end = .;
 
   /* writeable */
+  . = ALIGN(4096);
   .data : AT(ADDR(.data) - LOAD_OFFSET) {	/* Data */
 	*(.data)
 	CONSTRUCTORS
@@ -126,13 +127,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
index 07097ed..38c2b13 100644
--- a/arch/i386/mach-visws/visws_apic.c
+++ b/arch/i386/mach-visws/visws_apic.c
@@ -122,7 +122,7 @@
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
-static struct hw_interrupt_type cobalt_irq_type = {
+static struct irq_chip cobalt_irq_type = {
 	.typename =	"Cobalt-APIC",
 	.startup =	startup_cobalt_irq,
 	.shutdown =	disable_cobalt_irq,
@@ -159,7 +159,7 @@
 	spin_unlock_irqrestore(&cobalt_lock, flags);
 }
 
-static struct hw_interrupt_type piix4_master_irq_type = {
+static struct irq_chip piix4_master_irq_type = {
 	.typename =	"PIIX4-master",
 	.startup =	startup_piix4_master_irq,
 	.ack =		ack_cobalt_irq,
@@ -167,9 +167,8 @@
 };
 
 
-static struct hw_interrupt_type piix4_virtual_irq_type = {
+static struct irq_chip piix4_virtual_irq_type = {
 	.typename =	"PIIX4-virtual",
-	.startup =	startup_8259A_irq,
 	.shutdown =	disable_8259A_irq,
 	.enable =	enable_8259A_irq,
 	.disable =	disable_8259A_irq,
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 6d5ace8..cdfcf97 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -343,7 +343,6 @@
 
 void pcibios_disable_device (struct pci_dev *dev)
 {
-	pcibios_disable_resources(dev);
 	if (pcibios_disable_irq)
 		pcibios_disable_irq(dev);
 }
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 908b410..c1949ff 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -343,6 +343,61 @@
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_MCH_PC1,	pcie_rootport_aspm_quirk );
 
 /*
+ * Fixup to mark boot BIOS video selected by BIOS before it changes
+ *
+ * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
+ *
+ * The standard boot ROM sequence for an x86 machine uses the BIOS
+ * to select an initial video card for boot display. This boot video
+ * card will have it's BIOS copied to C0000 in system RAM.
+ * IORESOURCE_ROM_SHADOW is used to associate the boot video
+ * card with this copy. On laptops this copy has to be used since
+ * the main ROM may be compressed or combined with another image.
+ * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
+ * is marked here since the boot video device will be the only enabled
+ * video device at this point.
+ */
+
+static void __devinit pci_fixup_video(struct pci_dev *pdev)
+{
+	struct pci_dev *bridge;
+	struct pci_bus *bus;
+	u16 config;
+
+	if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+		return;
+
+	/* Is VGA routed to us? */
+	bus = pdev->bus;
+	while (bus) {
+		bridge = bus->self;
+
+		/*
+		 * From information provided by
+		 * "David Miller" <davem@davemloft.net>
+		 * The bridge control register is valid for PCI header
+		 * type BRIDGE, or CARDBUS. Host to PCI controllers use
+		 * PCI header type NORMAL.
+		 */
+		if (bridge
+		    &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+		       ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) {
+			pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+						&config);
+			if (!(config & PCI_BRIDGE_CTL_VGA))
+				return;
+		}
+		bus = bus->parent;
+	}
+	pci_read_config_word(pdev, PCI_COMMAND, &config);
+	if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+		pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
+		printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
+
+/*
  * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
  *
  * We pretend to bring them out of full D3 state, and restore the proper
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
index 10154a2..9858029 100644
--- a/arch/i386/pci/i386.c
+++ b/arch/i386/pci/i386.c
@@ -242,15 +242,6 @@
 	return 0;
 }
 
-void pcibios_disable_resources(struct pci_dev *dev)
-{
-	u16 cmd;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-	pci_write_config_word(dev, PCI_COMMAND, cmd);
-}
-
 /*
  *  If we set up a device for bus mastering, we need to check the latency
  *  timer as certain crappy BIOSes forget to set it properly.
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index dbc4aae..6916399 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -255,13 +255,13 @@
  */
 static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 {
-	static const unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+	static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
 	return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
 }
 
 static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
 {
-	static const unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+	static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
 	write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
 	return 1;
 }
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index d0c3da3..c6b6d9b 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -154,38 +154,6 @@
 	.write =	pci_mmcfg_write,
 };
 
-
-static __init void pci_mmcfg_insert_resources(void)
-{
-#define PCI_MMCFG_RESOURCE_NAME_LEN 19
-	int i;
-	struct resource *res;
-	char *names;
-	unsigned num_buses;
-
-	res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
-			pci_mmcfg_config_num, GFP_KERNEL);
-
-	if (!res) {
-		printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
-		return;
-	}
-
-	names = (void *)&res[pci_mmcfg_config_num];
-	for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
-		num_buses = pci_mmcfg_config[i].end_bus_number -
-		    pci_mmcfg_config[i].start_bus_number + 1;
-		res->name = names;
-		snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
-			pci_mmcfg_config[i].pci_segment_group_number);
-		res->start = pci_mmcfg_config[i].base_address;
-		res->end = res->start + (num_buses << 20) - 1;
-		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-		insert_resource(&iomem_resource, res);
-		names += PCI_MMCFG_RESOURCE_NAME_LEN;
-	}
-}
-
 /* K8 systems have some devices (typically in the builtin northbridge)
    that are only accessible using type1
    Normally this can be expressed in the MCFG by not listing them
@@ -222,8 +190,6 @@
 	}
 }
 
-
-
 void __init pci_mmcfg_init(int type)
 {
 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
@@ -251,5 +217,4 @@
 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 
 	unreachable_devices();
-	pci_mmcfg_insert_resources();
 }
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
index ad065ce..a0a2518 100644
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -43,7 +43,6 @@
 
 void pcibios_resource_survey(void);
 int pcibios_enable_resources(struct pci_dev *, int);
-void pcibios_disable_resources(struct pci_dev *);
 
 /* pci-pc.c */
 
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 70f7eb9..683b12c 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -341,6 +341,7 @@
 	bool "NUMA support"
 	depends on !IA64_HP_SIM && !FLATMEM
 	default y if IA64_SGI_SN2
+	select ACPI_NUMA if ACPI
 	help
 	  Say Y to compile the kernel to support NUMA (Non-Uniform Memory
 	  Access).  This option is for configuring high-end multiprocessor
@@ -483,6 +484,15 @@
 
 source "drivers/Kconfig"
 
+config MSPEC
+	tristate "Memory special operations driver"
+	depends on IA64
+	select IA64_UNCACHED_ALLOCATOR
+	help
+	  If you have an ia64 and you want to enable memory special
+	  operations support (formerly known as fetchop), say Y here,
+	  otherwise say N.
+
 source "fs/Kconfig"
 
 source "lib/Kconfig"
diff --git a/arch/ia64/hp/sim/Kconfig b/arch/ia64/hp/sim/Kconfig
index 18ccb12..f92306b 100644
--- a/arch/ia64/hp/sim/Kconfig
+++ b/arch/ia64/hp/sim/Kconfig
@@ -13,8 +13,8 @@
 	depends on HP_SIMSERIAL
 
 config HP_SIMSCSI
-	tristate "Simulated SCSI disk"
-	depends on SCSI
+	bool "Simulated SCSI disk"
+	depends on SCSI=y
 
 endmenu
 
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c
index 8145547..c2f58ff 100644
--- a/arch/ia64/hp/sim/hpsim_irq.c
+++ b/arch/ia64/hp/sim/hpsim_irq.c
@@ -27,7 +27,7 @@
 }
 
 static struct hw_interrupt_type irq_type_hp_sim = {
-	.typename =	"hpsim",
+	.name =		"hpsim",
 	.startup =	hpsim_irq_startup,
 	.shutdown =	hpsim_irq_noop,
 	.enable =	hpsim_irq_noop,
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 9bf15fe..60d6495 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -426,7 +426,7 @@
 #define iosapic_ack_level_irq		nop
 
 struct hw_interrupt_type irq_type_iosapic_level = {
-	.typename =	"IO-SAPIC-level",
+	.name =		"IO-SAPIC-level",
 	.startup =	iosapic_startup_level_irq,
 	.shutdown =	iosapic_shutdown_level_irq,
 	.enable =	iosapic_enable_level_irq,
@@ -473,7 +473,7 @@
 #define iosapic_end_edge_irq		nop
 
 struct hw_interrupt_type irq_type_iosapic_edge = {
-	.typename =	"IO-SAPIC-edge",
+	.name =		"IO-SAPIC-edge",
 	.startup =	iosapic_startup_edge_irq,
 	.shutdown =	iosapic_disable_edge_irq,
 	.enable =	iosapic_enable_edge_irq,
@@ -664,7 +664,7 @@
 			printk(KERN_WARNING
 			       "%s: changing vector %d from %s to %s\n",
 			       __FUNCTION__, vector,
-			       idesc->chip->typename, irq_type->typename);
+			       idesc->chip->name, irq_type->name);
 		idesc->chip = irq_type;
 	}
 	return 0;
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index f07c086..54d55e4 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -76,7 +76,7 @@
 			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 		}
 #endif
-		seq_printf(p, " %14s", irq_desc[i].chip->typename);
+		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
@@ -197,7 +197,7 @@
 			struct pt_regs *old_regs = set_irq_regs(NULL);
 
 			vectors_in_migration[irq]=0;
-			__do_IRQ(irq);
+			generic_handle_irq(irq);
 			set_irq_regs(old_regs);
 		}
 	}
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 9c6dafa..ba3ba8b 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -186,7 +186,7 @@
 			ia64_setreg(_IA64_REG_CR_TPR, vector);
 			ia64_srlz_d();
 
-			__do_IRQ(local_vector_to_irq(vector));
+			generic_handle_irq(local_vector_to_irq(vector));
 
 			/*
 			 * Disable interrupts and send EOI:
@@ -242,7 +242,7 @@
 			 * Probably could shared code.
 			 */
 			vectors_in_migration[local_vector_to_irq(vector)]=0;
-			__do_IRQ(local_vector_to_irq(vector));
+			generic_handle_irq(local_vector_to_irq(vector));
 			set_irq_regs(old_regs);
 
 			/*
diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c
index 1ab58b0..c2f07be 100644
--- a/arch/ia64/kernel/irq_lsapic.c
+++ b/arch/ia64/kernel/irq_lsapic.c
@@ -34,7 +34,7 @@
 }
 
 struct hw_interrupt_type irq_type_ia64_lsapic = {
-	.typename =	"LSAPIC",
+	.name =		"LSAPIC",
 	.startup =	lsapic_noop_startup,
 	.shutdown =	lsapic_noop,
 	.enable =	lsapic_noop,
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index a45009d..afc1403 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -435,6 +435,50 @@
 }
 
 /**
+ * get_target_identifier - Get the valid Cache or Bus check target identifier.
+ * @peidx:	pointer of index of processor error section
+ *
+ * Return value:
+ *	target address on Success / 0 on Failue
+ */
+static u64
+get_target_identifier(peidx_table_t *peidx)
+{
+	u64 target_address = 0;
+	sal_log_mod_error_info_t *smei;
+	pal_cache_check_info_t *pcci;
+	int i, level = 9;
+
+	/*
+	 * Look through the cache checks for a valid target identifier
+	 * If more than one valid target identifier, return the one
+	 * with the lowest cache level.
+	 */
+	for (i = 0; i < peidx_cache_check_num(peidx); i++) {
+		smei = (sal_log_mod_error_info_t *)peidx_cache_check(peidx, i);
+		if (smei->valid.target_identifier && smei->target_identifier) {
+			pcci = (pal_cache_check_info_t *)&(smei->check_info);
+			if (!target_address || (pcci->level < level)) {
+				target_address = smei->target_identifier;
+				level = pcci->level;
+				continue;
+			}
+		}
+	}
+	if (target_address)
+		return target_address;
+
+	/*
+	 * Look at the bus check for a valid target identifier
+	 */
+	smei = peidx_bus_check(peidx, 0);
+	if (smei && smei->valid.target_identifier)
+		return smei->target_identifier;
+
+	return 0;
+}
+
+/**
  * recover_from_read_error - Try to recover the errors which type are "read"s.
  * @slidx:	pointer of index of SAL error record
  * @peidx:	pointer of index of processor error section
@@ -450,13 +494,14 @@
 			peidx_table_t *peidx, pal_bus_check_info_t *pbci,
 			struct ia64_sal_os_state *sos)
 {
-	sal_log_mod_error_info_t *smei;
+	u64 target_identifier;
 	pal_min_state_area_t *pmsa;
 	struct ia64_psr *psr1, *psr2;
 	ia64_fptr_t *mca_hdlr_bh = (ia64_fptr_t*)mca_handler_bhhook;
 
 	/* Is target address valid? */
-	if (!pbci->tv)
+	target_identifier = get_target_identifier(peidx);
+	if (!target_identifier)
 		return fatal_mca("target address not valid");
 
 	/*
@@ -487,32 +532,28 @@
 	pmsa = sos->pal_min_state;
 	if (psr1->cpl != 0 ||
 	   ((psr2->cpl != 0) && mca_recover_range(pmsa->pmsa_iip))) {
-		smei = peidx_bus_check(peidx, 0);
-		if (smei->valid.target_identifier) {
-			/*
-			 *  setup for resume to bottom half of MCA,
-			 * "mca_handler_bhhook"
-			 */
-			/* pass to bhhook as argument (gr8, ...) */
-			pmsa->pmsa_gr[8-1] = smei->target_identifier;
-			pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip;
-			pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr;
-			/* set interrupted return address (but no use) */
-			pmsa->pmsa_br0 = pmsa->pmsa_iip;
-			/* change resume address to bottom half */
-			pmsa->pmsa_iip = mca_hdlr_bh->fp;
-			pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp;
-			/* set cpl with kernel mode */
-			psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
-			psr2->cpl = 0;
-			psr2->ri  = 0;
-			psr2->bn  = 1;
-			psr2->i  = 0;
+		/*
+		 *  setup for resume to bottom half of MCA,
+		 * "mca_handler_bhhook"
+		 */
+		/* pass to bhhook as argument (gr8, ...) */
+		pmsa->pmsa_gr[8-1] = target_identifier;
+		pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip;
+		pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr;
+		/* set interrupted return address (but no use) */
+		pmsa->pmsa_br0 = pmsa->pmsa_iip;
+		/* change resume address to bottom half */
+		pmsa->pmsa_iip = mca_hdlr_bh->fp;
+		pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp;
+		/* set cpl with kernel mode */
+		psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
+		psr2->cpl = 0;
+		psr2->ri  = 0;
+		psr2->bn  = 1;
+		psr2->i  = 0;
 
-			return mca_recovered("user memory corruption. "
+		return mca_recovered("user memory corruption. "
 				"kill affected process - recovered.");
-		}
-
 	}
 
 	return fatal_mca("kernel context not recovered, iip 0x%lx\n",
diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c
index 642fdc7..20bad78 100644
--- a/arch/ia64/kernel/sal.c
+++ b/arch/ia64/kernel/sal.c
@@ -223,12 +223,13 @@
  */
 static int sal_cache_flush_drops_interrupts;
 
-static void __init
+void __init
 check_sal_cache_flush (void)
 {
 	unsigned long flags;
 	int cpu;
-	u64 vector;
+	u64 vector, cache_type = 3;
+	struct ia64_sal_retval isrv;
 
 	cpu = get_cpu();
 	local_irq_save(flags);
@@ -243,7 +244,10 @@
 	while (!ia64_get_irr(IA64_TIMER_VECTOR))
 		cpu_relax();
 
-	ia64_sal_cache_flush(3);
+	SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
+
+	if (isrv.status)
+		printk(KERN_ERR "SAL_CAL_FLUSH failed with %ld\n", isrv.status);
 
 	if (ia64_get_irr(IA64_TIMER_VECTOR)) {
 		vector = ia64_get_ivr();
@@ -331,7 +335,6 @@
 		p += SAL_DESC_SIZE(*p);
 	}
 
-	check_sal_cache_flush();
 }
 
 int
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index c4caa80..d10404a 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -457,6 +457,8 @@
 	cpu_init();	/* initialize the bootstrap CPU */
 	mmu_context_init();	/* initialize context_id bitmap */
 
+	check_sal_cache_flush();
+
 #ifdef CONFIG_ACPI
 	acpi_boot_init();
 #endif
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index 657ac99..6ab95cea 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -108,7 +108,7 @@
 }
 
 irqreturn_t
-handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
+handle_IPI (int irq, void *dev_id)
 {
 	int this_cpu = get_cpu();
 	unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation);
@@ -328,10 +328,14 @@
 smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wait)
 {
 	struct call_data_struct data;
-	int cpus = num_online_cpus()-1;
+	int cpus;
 
-	if (!cpus)
+	spin_lock(&call_lock);
+	cpus = num_online_cpus() - 1;
+	if (!cpus) {
+		spin_unlock(&call_lock);
 		return 0;
+	}
 
 	/* Can deadlock when called with interrupts disabled */
 	WARN_ON(irqs_disabled());
@@ -343,8 +347,6 @@
 	if (wait)
 		atomic_set(&data.finished, 0);
 
-	spin_lock(&call_lock);
-
 	call_data = &data;
 	mb();	/* ensure store to call_data precedes setting of IPI_CALL_FUNC */
 	send_IPI_allbutself(IPI_CALL_FUNC);
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index b3b2e38..d6083a0 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -128,13 +128,7 @@
   .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET)
 	{
 	  __initcall_start = .;
-	  *(.initcall1.init)
-	  *(.initcall2.init)
-	  *(.initcall3.init)
-	  *(.initcall4.init)
-	  *(.initcall5.init)
-	  *(.initcall6.init)
-	  *(.initcall7.init)
+	INITCALLS
 	  __initcall_end = .;
 	}
 
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index eee5c1cf..f3a9585 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -70,8 +70,10 @@
  * Don't actually need to do any preparation, but need to make sure
  * the address is in the right region.
  */
-int prepare_hugepage_range(unsigned long addr, unsigned long len)
+int prepare_hugepage_range(unsigned long addr, unsigned long len, pgoff_t pgoff)
 {
+	if (pgoff & (~HPAGE_MASK >> PAGE_SHIFT))
+		return -EINVAL;
 	if (len & ~HPAGE_MASK)
 		return -EINVAL;
 	if (addr & ~HPAGE_MASK)
diff --git a/arch/ia64/pci/Makefile b/arch/ia64/pci/Makefile
index e66889e..fb14dc5 100644
--- a/arch/ia64/pci/Makefile
+++ b/arch/ia64/pci/Makefile
@@ -1,4 +1,4 @@
 #
 # Makefile for the ia64-specific parts of the pci bus
 #
-obj-y		:= pci.o
+obj-y		:= pci.o fixup.o
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
new file mode 100644
index 0000000..245dc1f
--- /dev/null
+++ b/arch/ia64/pci/fixup.c
@@ -0,0 +1,69 @@
+/*
+ * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
+ * Derived from fixup.c of i386 tree.
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+
+/*
+ * Fixup to mark boot BIOS video selected by BIOS before it changes
+ *
+ * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
+ *
+ * The standard boot ROM sequence for an x86 machine uses the BIOS
+ * to select an initial video card for boot display. This boot video
+ * card will have it's BIOS copied to C0000 in system RAM.
+ * IORESOURCE_ROM_SHADOW is used to associate the boot video
+ * card with this copy. On laptops this copy has to be used since
+ * the main ROM may be compressed or combined with another image.
+ * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
+ * is marked here since the boot video device will be the only enabled
+ * video device at this point.
+ */
+
+static void __devinit pci_fixup_video(struct pci_dev *pdev)
+{
+	struct pci_dev *bridge;
+	struct pci_bus *bus;
+	u16 config;
+
+	if ((strcmp(platform_name, "dig") != 0)
+	    && (strcmp(platform_name, "hpzx1")  != 0))
+		return;
+	/* Maybe, this machine supports legacy memory map. */
+
+	if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+		return;
+
+	/* Is VGA routed to us? */
+	bus = pdev->bus;
+	while (bus) {
+		bridge = bus->self;
+
+		/*
+		 * From information provided by
+		 * "David Miller" <davem@davemloft.net>
+		 * The bridge control register is valid for PCI header
+		 * type BRIDGE, or CARDBUS. Host to PCI controllers use
+		 * PCI header type NORMAL.
+		 */
+		if (bridge
+		    &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+		       ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) {
+			pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+						&config);
+			if (!(config & PCI_BRIDGE_CTL_VGA))
+				return;
+		}
+		bus = bus->parent;
+	}
+	pci_read_config_word(pdev, PCI_COMMAND, &config);
+	if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+		pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
+		printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index 7f73ad4..ff1c556 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -381,14 +381,13 @@
 		 * bcopy to the destination.
 		 */
 
-		/* Add the leader from source */
-		headBteLen = len + (src & L1_CACHE_MASK);
-		/* Add the trailing bytes from footer. */
-		headBteLen += L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK);
-		headBteSource = src & ~L1_CACHE_MASK;
 		headBcopySrcOffset = src & L1_CACHE_MASK;
 		headBcopyDest = dest;
 		headBcopyLen = len;
+
+		headBteSource = src - headBcopySrcOffset;
+		/* Add the leading and trailing bytes from source */
+		headBteLen = L1_CACHE_ALIGN(len + headBcopySrcOffset);
 	}
 
 	if (headBcopyLen > 0) {
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 7bb6ad1..0b49459 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -201,7 +201,7 @@
 }
 
 struct hw_interrupt_type irq_type_sn = {
-	.typename	= "SN hub",
+	.name		= "SN hub",
 	.startup	= sn_startup_irq,
 	.shutdown	= sn_shutdown_irq,
 	.enable		= sn_enable_irq,
diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S
index 13c7bb6..358b9ce 100644
--- a/arch/m32r/kernel/vmlinux.lds.S
+++ b/arch/m32r/kernel/vmlinux.lds.S
@@ -83,13 +83,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index 69d1d3d..d279445 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -54,13 +54,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index 65cc39c..2550b4a 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -48,13 +48,7 @@
 	__setup_end = .;
 	__initcall_start = .;
 	.initcall.init : {
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
+		INITCALLS
 	}
 	__initcall_end = .;
 	__con_initcall_start = .;
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index bde9811..7b21959 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -62,7 +62,7 @@
 void (*mach_kbd_leds) (unsigned int);
 /* machine dependent irq functions */
 void (*mach_init_IRQ) (void);
-irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
+irq_handler_t mach_default_handler;
 int (*mach_get_irq_list) (struct seq_file *, void *);
 void (*mach_process_int) (int irq, struct pt_regs *fp);
 void (*mach_trap_init) (void);
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
index c5667bd..9226264 100644
--- a/arch/m68knommu/kernel/time.c
+++ b/arch/m68knommu/kernel/time.c
@@ -54,7 +54,7 @@
 	update_process_times(user_mode(regs));
 #endif
 	if (current->pid)
-		profile_tick(CPU_PROFILING, regs);
+		profile_tick(CPU_PROFILING);
 
 	/*
 	 * If we have an externally synchronized Linux clock, then update
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index ccd2ceb..58afa8b 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -140,13 +140,7 @@
 		*(.init.setup)
 		__setup_end = .;
 		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
+		INITCALLS
 		__initcall_end = .;
 		__con_initcall_start = .;
 		*(.con_initcall.init)
diff --git a/arch/m68knommu/platform/5307/ints.c b/arch/m68knommu/platform/5307/ints.c
index b4b5509..a57239e 100644
--- a/arch/m68knommu/platform/5307/ints.c
+++ b/arch/m68knommu/platform/5307/ints.c
@@ -33,7 +33,7 @@
 /*
  *	This table stores the address info for each vector handler.
  */
-irq_handler_t irq_list[SYS_IRQS];
+struct irq_entry irq_list[SYS_IRQS];
 
 #define NUM_IRQ_NODES 16
 static irq_node_t nodes[NUM_IRQ_NODES];
@@ -44,7 +44,7 @@
 unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
 
-static irqreturn_t default_irq_handler(int irq, void *ptr, struct pt_regs *regs)
+static irqreturn_t default_irq_handler(int irq, void *ptr)
 {
 #if 1
 	printk(KERN_INFO "%s(%d): default irq handler vec=%d [0x%x]\n",
@@ -70,7 +70,7 @@
 
 	for (i = 0; i < SYS_IRQS; i++) {
 		if (mach_default_handler)
-			irq_list[i].handler = (*mach_default_handler)[i];
+			irq_list[i].handler = mach_default_handler;
 		else
 			irq_list[i].handler = default_irq_handler;
 		irq_list[i].flags   = IRQ_FLG_STD;
@@ -100,7 +100,7 @@
 
 int request_irq(
 	unsigned int irq,
-	irqreturn_t (*handler)(int, void *, struct pt_regs *),
+	irq_handler_t handler,
 	unsigned long flags,
 	const char *devname,
 	void *dev_id)
@@ -157,7 +157,7 @@
 	}
 
 	if (mach_default_handler)
-		irq_list[irq].handler = (*mach_default_handler)[irq];
+		irq_list[irq].handler = mach_default_handler;
 	else
 		irq_list[irq].handler = default_irq_handler;
 	irq_list[irq].flags   = IRQ_FLG_STD;
@@ -168,8 +168,7 @@
 EXPORT_SYMBOL(free_irq);
 
 
-int sys_request_irq(unsigned int irq, 
-                    irqreturn_t (*handler)(int, void *, struct pt_regs *), 
+int sys_request_irq(unsigned int irq, irq_handler_t handler, 
                     unsigned long flags, const char *devname, void *dev_id)
 {
 	if (irq > IRQ7) {
@@ -211,7 +210,7 @@
 		printk(KERN_WARNING "%s: Removing probably wrong IRQ %d from %s\n",
 		       __FUNCTION__, irq, irq_list[irq].devname);
 
-	irq_list[irq].handler = (*mach_default_handler)[irq];
+	irq_list[irq].handler = mach_default_handler;
 	irq_list[irq].flags   = 0;
 	irq_list[irq].dev_id  = NULL;
 	irq_list[irq].devname = NULL;
@@ -241,7 +240,7 @@
 	if (vec >= VEC_INT1 && vec <= VEC_INT7) {
 		vec -= VEC_SPUR;
 		kstat_cpu(0).irqs[vec]++;
-		irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
+		irq_list[vec].handler(vec, irq_list[vec].dev_id);
 	} else {
 		if (mach_process_int)
 			mach_process_int(vec, fp);
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 14af6cc..1443024 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -425,9 +425,8 @@
 	select SWAP_IO_SPACE
 	select SYS_HAS_CPU_RM7000
 	select SYS_SUPPORTS_32BIT_KERNEL
-	select SYS_SUPPORTS_64BIT_KERNEL
+	select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
 	select SYS_SUPPORTS_BIG_ENDIAN
-	select ARCH_SPARSEMEM_ENABLE
 	help
 	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
 	  Momentum Computer <http://www.momenco.com/>.
@@ -560,6 +559,7 @@
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_NUMA
+	select SYS_SUPPORTS_SMP
 	help
 	  This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
 	  workstations.  To compile a Linux kernel that runs on these, say Y
@@ -1633,9 +1633,6 @@
 
 config ARCH_SPARSEMEM_ENABLE
 	bool
-
-config ARCH_SPARSEMEM_ENABLE
-	bool
 	select SPARSEMEM_STATIC
 
 config NUMA
@@ -1690,6 +1687,7 @@
 	depends on SMP
 	default "64" if SGI_IP27
 	default "2"
+	default "8" if MIPS_MT_SMTC
 	help
 	  This allows you to specify the maximum number of CPUs which this
 	  kernel will support.  The maximum supported value is 32 for 32-bit
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 641aa30..d580d46 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -63,7 +63,9 @@
 ifdef CONFIG_BUILD_ELF64
 cflags-y		+= $(call cc-option,-mno-explicit-relocs)
 else
-cflags-y		+= $(call cc-option,-msym32)
+# -msym32 can not be used for modules since they are loaded into XKSEG
+CFLAGS_MODULE		+= $(call cc-option,-mno-explicit-relocs)
+CFLAGS_KERNEL		+= $(call cc-option,-msym32)
 endif
 endif
 
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
index b4b010a..6fce60a 100644
--- a/arch/mips/au1000/common/prom.c
+++ b/arch/mips/au1000/common/prom.c
@@ -47,7 +47,7 @@
 extern char **prom_argv, **prom_envp;
 
 
-char * prom_getcmdline(void)
+char * __init_or_module prom_getcmdline(void)
 {
 	return &(arcs_cmdline[0]);
 }
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 377ae0d..919172db 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -43,7 +43,7 @@
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/time.h>
 
-extern char * __init prom_getcmdline(void);
+extern char * prom_getcmdline(void);
 extern void __init board_setup(void);
 extern void au1000_restart(char *);
 extern void au1000_halt(void);
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index 94f0919..fa1c62f 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -53,9 +53,6 @@
 int	no_au1xxx_32khz;
 extern int allow_au1k_wait; /* default off for CP0 Counter */
 
-/* Cycle counter value at the previous timer interrupt.. */
-static unsigned int timerhi = 0, timerlo = 0;
-
 #ifdef CONFIG_PM
 #if HZ < 100 || HZ > 1000
 #error "unsupported HZ value! Must be in [100,1000]"
@@ -82,7 +79,6 @@
 void mips_timer_interrupt(void)
 {
 	int irq = 63;
-	unsigned long count;
 
 	irq_enter();
 	kstat_this_cpu.irqs[irq]++;
@@ -91,10 +87,6 @@
 		goto null;
 
 	do {
-		count = read_c0_count();
-		timerhi += (count < timerlo);   /* Wrap around */
-		timerlo = count;
-
 		kstat_this_cpu.irqs[irq]++;
 		do_timer(1);
 #ifndef CONFIG_SMP
@@ -231,7 +223,6 @@
  */
 unsigned long cal_r4koff(void)
 {
-	unsigned long count;
 	unsigned long cpu_speed;
 	unsigned long flags;
 	unsigned long counter;
@@ -258,7 +249,7 @@
 
 #if defined(CONFIG_AU1000_USE32K)
 		{
-			unsigned long start, end;
+			unsigned long start, end, count;
 
 			start = au_readl(SYS_RTCREAD);
 			start += 2;
@@ -282,7 +273,6 @@
 #else
 		cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) *
 			AU1000_SRC_CLK;
-		count = cpu_speed / 2;
 #endif
 	}
 	else {
@@ -291,98 +281,15 @@
 		 * NOTE: some old silicon doesn't allow reading the PLL.
 		 */
 		cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
-		count = cpu_speed / 2;
 		no_au1xxx_32khz = 1;
 	}
-	mips_hpt_frequency = count;
+	mips_hpt_frequency = cpu_speed;
 	// Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)
 	set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
 	spin_unlock_irqrestore(&time_lock, flags);
 	return (cpu_speed / HZ);
 }
 
-/* This is for machines which generate the exact clock. */
-#define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff)
-
-static unsigned long
-div64_32(unsigned long v1, unsigned long v2, unsigned long v3)
-{
-	unsigned long r0;
-	do_div64_32(r0, v1, v2, v3);
-	return r0;
-}
-
-static unsigned long do_fast_cp0_gettimeoffset(void)
-{
-	u32 count;
-	unsigned long res, tmp;
-	unsigned long r0;
-
-	/* Last jiffy when do_fast_gettimeoffset() was called. */
-	static unsigned long last_jiffies=0;
-	unsigned long quotient;
-
-	/*
-	 * Cached "1/(clocks per usec)*2^32" value.
-	 * It has to be recalculated once each jiffy.
-	 */
-	static unsigned long cached_quotient=0;
-
-	tmp = jiffies;
-
-	quotient = cached_quotient;
-
-	if (tmp && last_jiffies != tmp) {
-		last_jiffies = tmp;
-		if (last_jiffies != 0) {
-			r0 = div64_32(timerhi, timerlo, tmp);
-			quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0);
-			cached_quotient = quotient;
-		}
-	}
-
-	/* Get last timer tick in absolute kernel time */
-	count = read_c0_count();
-
-	/* .. relative to previous jiffy (32 bits is enough) */
-	count -= timerlo;
-
-	__asm__("multu\t%1,%2\n\t"
-		"mfhi\t%0"
-		: "=r" (res)
-		: "r" (count), "r" (quotient)
-		: "hi", "lo", GCC_REG_ACCUM);
-
-	/*
-	 * Due to possible jiffies inconsistencies, we need to check
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (res >= USECS_PER_JIFFY)
-		res = USECS_PER_JIFFY-1;
-
-	return res;
-}
-
-#ifdef CONFIG_PM
-static unsigned long do_fast_pm_gettimeoffset(void)
-{
-	unsigned long pc0;
-	unsigned long offset;
-
-	pc0 = au_readl(SYS_TOYREAD);
-	au_sync();
-	offset = pc0 - last_pc0;
-	if (offset > 2*MATCH20_INC) {
-		printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n",
-				(unsigned)offset, (unsigned)last_pc0,
-				(unsigned)last_match20, (unsigned)pc0);
-	}
-	offset = (unsigned long)((offset * 305) / 10);
-	return offset;
-}
-#endif
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
 	unsigned int est_freq;
@@ -420,7 +327,6 @@
 		unsigned int c0_status;
 
 		printk("WARNING: no 32KHz clock found.\n");
-		do_gettimeoffset = do_fast_cp0_gettimeoffset;
 
 		/* Ensure we get CPO_COUNTER interrupts.
 		*/
@@ -445,19 +351,11 @@
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
 		startup_match20_interrupt(counter0_irq);
 
-		do_gettimeoffset = do_fast_pm_gettimeoffset;
-
 		/* We can use the real 'wait' instruction.
 		*/
 		allow_au1k_wait = 1;
 	}
 
-#else
-	/* We have to do this here instead of in timer_init because
-	 * the generic code in arch/mips/kernel/time.c will write
-	 * over our function pointer.
-	 */
-	do_gettimeoffset = do_fast_cp0_gettimeoffset;
 #endif
 }
 
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 4cf0c06..69e424e 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -160,11 +160,6 @@
 	return ioasic_read(IO_REG_FCTR);
 }
 
-static void dec_ioasic_hpt_init(unsigned int count)
-{
-	ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count);
-}
-
 
 void __init dec_time_init(void)
 {
@@ -174,11 +169,9 @@
 	mips_timer_state = dec_timer_state;
 	mips_timer_ack = dec_timer_ack;
 
-	if (!cpu_has_counter && IOASIC) {
+	if (!cpu_has_counter && IOASIC)
 		/* For pre-R4k systems we use the I/O ASIC's counter.  */
 		mips_hpt_read = dec_ioasic_hpt_read;
-		mips_hpt_init = dec_ioasic_hpt_init;
-	}
 
 	/* Set up the rate of periodic DS1287 interrupts.  */
 	CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A);
diff --git a/arch/mips/emma2rh/common/irq_emma2rh.c b/arch/mips/emma2rh/common/irq_emma2rh.c
index 7c93086..197ed4c 100644
--- a/arch/mips/emma2rh/common/irq_emma2rh.c
+++ b/arch/mips/emma2rh/common/irq_emma2rh.c
@@ -97,7 +97,7 @@
 		irq_desc[i].status = IRQ_DISABLED;
 		irq_desc[i].action = NULL;
 		irq_desc[i].depth = 1;
-		irq_desc[i].handler = &emma2rh_irq_controller;
+		irq_desc[i].chip = &emma2rh_irq_controller;
 	}
 
 	emma2rh_irq_base = irq_base;
diff --git a/arch/mips/emma2rh/markeins/irq_markeins.c b/arch/mips/emma2rh/markeins/irq_markeins.c
index f23ae9f..0b36eb0 100644
--- a/arch/mips/emma2rh/markeins/irq_markeins.c
+++ b/arch/mips/emma2rh/markeins/irq_markeins.c
@@ -86,7 +86,7 @@
 		irq_desc[i].status = IRQ_DISABLED;
 		irq_desc[i].action = NULL;
 		irq_desc[i].depth = 2;
-		irq_desc[i].handler = &emma2rh_sw_irq_controller;
+		irq_desc[i].chip = &emma2rh_sw_irq_controller;
 	}
 
 	emma2rh_sw_irq_base = irq_base;
@@ -166,7 +166,7 @@
 		irq_desc[i].status = IRQ_DISABLED;
 		irq_desc[i].action = NULL;
 		irq_desc[i].depth = 2;
-		irq_desc[i].handler = &emma2rh_gpio_irq_controller;
+		irq_desc[i].chip = &emma2rh_gpio_irq_controller;
 	}
 
 	emma2rh_gpio_irq_base = irq_base;
diff --git a/arch/mips/emma2rh/markeins/platform.c b/arch/mips/emma2rh/markeins/platform.c
index 15cc61d..1156770 100644
--- a/arch/mips/emma2rh/markeins/platform.c
+++ b/arch/mips/emma2rh/markeins/platform.c
@@ -44,18 +44,45 @@
 #define I2C_EMMA2RH "emma2rh-iic" /* must be in sync with IIC driver */
 
 static struct resource i2c_emma_resources_0[] = {
-	{ NULL, EMMA2RH_IRQ_PIIC0, EMMA2RH_IRQ_PIIC0, IORESOURCE_IRQ },
-	{ NULL, KSEG1ADDR(EMMA2RH_PIIC0_BASE), KSEG1ADDR(EMMA2RH_PIIC0_BASE + 0x1000), 0 },
+	{
+		.name	= NULL,
+		.start	= EMMA2RH_IRQ_PIIC0,
+		.end	= EMMA2RH_IRQ_PIIC0,
+		.flags	= IORESOURCE_IRQ
+	}, {
+		.name	= NULL,
+		.start	= EMMA2RH_PIIC0_BASE,
+		.end	= EMMA2RH_PIIC0_BASE + 0x1000,
+		.flags	= 0
+	},
 };
 
 struct resource i2c_emma_resources_1[] = {
-	{ NULL, EMMA2RH_IRQ_PIIC1, EMMA2RH_IRQ_PIIC1, IORESOURCE_IRQ },
-	{ NULL, KSEG1ADDR(EMMA2RH_PIIC1_BASE), KSEG1ADDR(EMMA2RH_PIIC1_BASE + 0x1000), 0 },
+	{
+		.name	= NULL,
+		.start	= EMMA2RH_IRQ_PIIC1,
+		.end	= EMMA2RH_IRQ_PIIC1,
+		.flags	= IORESOURCE_IRQ
+	}, {
+		.name	= NULL,
+		.start	= EMMA2RH_PIIC1_BASE,
+		.end	= EMMA2RH_PIIC1_BASE + 0x1000,
+		.flags	= 0
+	},
 };
 
 struct resource i2c_emma_resources_2[] = {
-	{ NULL, EMMA2RH_IRQ_PIIC2, EMMA2RH_IRQ_PIIC2, IORESOURCE_IRQ },
-	{ NULL, KSEG1ADDR(EMMA2RH_PIIC2_BASE), KSEG1ADDR(EMMA2RH_PIIC2_BASE + 0x1000), 0 },
+	{
+		.name	= NULL,
+		.start	= EMMA2RH_IRQ_PIIC2,
+		.end	= EMMA2RH_IRQ_PIIC2,
+		.flags	= IORESOURCE_IRQ
+	}, {
+		.name	= NULL,
+		.start	= EMMA2RH_PIIC2_BASE,
+		.end	= EMMA2RH_PIIC2_BASE + 0x1000,
+		.flags	= 0
+	},
 };
 
 struct platform_device i2c_emma_devices[] = {
@@ -83,32 +110,29 @@
 #define EMMA2RH_SERIAL_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST
 
 static struct  plat_serial8250_port platform_serial_ports[] = {
-       [0] = {
-         .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3),
-         .irq = EMMA2RH_IRQ_PFUR0,
-         .uartclk = EMMA2RH_SERIAL_CLOCK,
-         .regshift = 4,
-         .iotype = UPIO_MEM,
-         .flags = EMMA2RH_SERIAL_FLAGS,
-       },
-       [1] = {
-         .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3),
-         .irq = EMMA2RH_IRQ_PFUR1,
-         .uartclk = EMMA2RH_SERIAL_CLOCK,
-         .regshift = 4,
-         .iotype = UPIO_MEM,
-         .flags = EMMA2RH_SERIAL_FLAGS,
-       },
-       [2] = {
-         .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3),
-         .irq = EMMA2RH_IRQ_PFUR2,
-         .uartclk = EMMA2RH_SERIAL_CLOCK,
-         .regshift = 4,
-         .iotype = UPIO_MEM,
-         .flags = EMMA2RH_SERIAL_FLAGS,
-       },
-       [3] = {
-	 .flags = 0,
+	[0] = {
+		.membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3),
+		.irq = EMMA2RH_IRQ_PFUR0,
+		.uartclk = EMMA2RH_SERIAL_CLOCK,
+		.regshift = 4,
+		.iotype = UPIO_MEM,
+		.flags = EMMA2RH_SERIAL_FLAGS,
+       }, [1] = {
+		.membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3),
+		.irq = EMMA2RH_IRQ_PFUR1,
+		.uartclk = EMMA2RH_SERIAL_CLOCK,
+		.regshift = 4,
+		.iotype = UPIO_MEM,
+		.flags = EMMA2RH_SERIAL_FLAGS,
+       }, [2] = {
+		.membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3),
+		.irq = EMMA2RH_IRQ_PFUR2,
+		.uartclk = EMMA2RH_SERIAL_CLOCK,
+		.regshift = 4,
+		.iotype = UPIO_MEM,
+		.flags = EMMA2RH_SERIAL_FLAGS,
+       }, [3] = {
+		.flags = 0,
        },
 };
 
diff --git a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c
index c83ae6a..c47eeb7 100644
--- a/arch/mips/gt64120/common/time.c
+++ b/arch/mips/gt64120/common/time.c
@@ -64,14 +64,14 @@
  * as *irq (=irq0 in ../kernel/time.c).  We will do our own timer interrupt
  * handling.
  */
-void gt64120_time_init(void)
+void __init plat_timer_setup(struct irqaction *irq)
 {
 	static struct irqaction timer;
 
 	/* Disable timer first */
 	GT_WRITE(GT_TC_CONTROL_OFS, 0);
 	/* Load timer value for 100 Hz */
-	GT_WRITE(GT_TC3_OFS, Sys_clock / 100);
+	GT_WRITE(GT_TC3_OFS, Sys_clock / HZ);
 
 	/*
 	 * Create the IRQ structure entry for the timer.  Since we're too early
diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c
index 91c2d3f..99c8d42 100644
--- a/arch/mips/gt64120/ev64120/setup.c
+++ b/arch/mips/gt64120/ev64120/setup.c
@@ -68,7 +68,6 @@
  * Initializes basic routines and structures pointers, memory size (as
  * given by the bios and saves the command line.
  */
-extern void gt64120_time_init(void);
 
 void __init plat_mem_setup(void)
 {
@@ -76,7 +75,6 @@
 	_machine_halt = galileo_machine_halt;
 	pm_power_off = galileo_machine_power_off;
 
-	board_time_init = gt64120_time_init;
 	set_io_port_base(KSEG1);
 }
 
diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c
index 0e5bbee..94f94eb 100644
--- a/arch/mips/gt64120/momenco_ocelot/setup.c
+++ b/arch/mips/gt64120/momenco_ocelot/setup.c
@@ -70,7 +70,6 @@
 extern void momenco_ocelot_halt(void);
 extern void momenco_ocelot_power_off(void);
 
-extern void gt64120_time_init(void);
 extern void momenco_ocelot_irq_setup(void);
 
 static char reset_reason;
@@ -156,8 +155,6 @@
 	void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
 	unsigned int tmpword;
 
-	board_time_init = gt64120_time_init;
-
 	_machine_restart = momenco_ocelot_restart;
 	_machine_halt = momenco_ocelot_halt;
 	pm_power_off = momenco_ocelot_power_off;
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c
index 39a0243..de4a238 100644
--- a/arch/mips/jmr3927/rbhma3100/irq.c
+++ b/arch/mips/jmr3927/rbhma3100/irq.c
@@ -288,6 +288,8 @@
 
 static void jmr3927_spurious(void)
 {
+	struct pt_regs * regs = get_irq_regs();
+
 #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
 	tx_branch_likely_bug_fixup();
 #endif
@@ -297,6 +299,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
+	struct pt_regs * regs = get_irq_regs();
 	int irq;
 
 #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 0254340..16e5dfe 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -170,12 +170,20 @@
 	while (1);
 }
 
+static unsigned int jmr3927_hpt_read(void)
+{
+	/* We assume this function is called xtime_lock held. */
+	return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr;
+}
+
 #define USE_RTC_DS1742
 #ifdef USE_RTC_DS1742
 extern void rtc_ds1742_init(unsigned long base);
 #endif
 static void __init jmr3927_time_init(void)
 {
+	mips_hpt_read = jmr3927_hpt_read;
+	mips_hpt_frequency = JMR3927_TIMER_CLK;
 #ifdef USE_RTC_DS1742
 	if (jmr3927_have_nvram()) {
 	        rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR);
@@ -183,12 +191,8 @@
 #endif
 }
 
-unsigned long jmr3927_do_gettimeoffset(void);
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
-	do_gettimeoffset = jmr3927_do_gettimeoffset;
-
 	jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ;
 	jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE;
 	jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD;
@@ -200,34 +204,6 @@
 
 #define USECS_PER_JIFFY (1000000/HZ)
 
-unsigned long jmr3927_do_gettimeoffset(void)
-{
-       unsigned long count;
-       unsigned long res = 0;
-
-       /* MUST read TRR before TISR. */
-       count = jmr3927_tmrptr->trr;
-
-       if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) {
-               /* timer interrupt is pending.  use Max value. */
-               res = USECS_PER_JIFFY - 1;
-       } else {
-               /* convert to usec */
-               /* res = count / (JMR3927_TIMER_CLK / 1000000); */
-               res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000);
-
-               /*
-                * Due to possible jiffies inconsistencies, we need to check
-                * the result so that we'll get a timer that is monotonic.
-                */
-               if (res >= USECS_PER_JIFFY)
-                       res = USECS_PER_JIFFY-1;
-       }
-
-       return res;
-}
-
-
 //#undef DO_WRITE_THROUGH
 #define DO_WRITE_THROUGH
 #define DO_ENABLE_CACHE
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index cd9cec9..6bfbbed 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -6,7 +6,7 @@
 
 obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 		   ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \
-		   time.o traps.o unaligned.o
+		   time.o topology.o traps.o unaligned.o
 
 binfmt_irix-objs	:= irixelf.o irixinv.o irixioctl.o irixsig.o	\
 			   irix5sys.o sysirix.o
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index e9ce5b3..ff88b06 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -22,7 +22,7 @@
 #define offset(string, ptr, member) \
 	__asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
 #define constant(string, member) \
-	__asm__("\n@@@" string "%x0" : : "ri" (member))
+	__asm__("\n@@@" string "%X0" : : "ri" (member))
 #define size(string, size) \
 	__asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
 #define linefeed text("")
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 417c08a..f10b6a1 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -83,7 +83,10 @@
 FEXPORT(restore_all)			# restore full frame
 #ifdef CONFIG_MIPS_MT_SMTC
 /* Detect and execute deferred IPI "interrupts" */
+	LONG_L	s0, TI_REGS($28)
+	LONG_S	sp, TI_REGS($28)
 	jal	deferred_smtc_ipi
+	LONG_S	s0, TI_REGS($28)
 /* Re-arm any temporarily masked interrupts not explicitly "acked" */
 	mfc0	v0, CP0_TCSTATUS
 	ori	v1, v0, TCSTATUS_IXMT
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 8c6db0f..ddc1b71 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -189,7 +189,8 @@
 
 	MTC0		zero, CP0_CONTEXT	# clear context register
 	PTR_LA		$28, init_thread_union
-	PTR_ADDIU	sp, $28, _THREAD_SIZE - 32
+	PTR_LI		sp, _THREAD_SIZE - 32
+	PTR_ADDU	sp, $28
 	set_saved_sp	sp, t0, t1
 	PTR_SUBU	sp, 4 * SZREG		# init stack pointer
 
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index dd24434..9b0e49d 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -26,6 +26,48 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
+static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
+
+int __devinit allocate_irqno(void)
+{
+	int irq;
+
+again:
+	irq = find_first_zero_bit(irq_map, NR_IRQS);
+
+	if (irq >= NR_IRQS)
+		return -ENOSPC;
+
+	if (test_and_set_bit(irq, irq_map))
+		goto again;
+
+	return irq;
+}
+
+EXPORT_SYMBOL_GPL(allocate_irqno);
+
+/*
+ * Allocate the 16 legacy interrupts for i8259 devices.  This happens early
+ * in the kernel initialization so treating allocation failure as BUG() is
+ * ok.
+ */
+void __init alloc_legacy_irqno(void)
+{
+	int i;
+
+	for (i = 0; i <= 16; i++)
+		BUG_ON(test_and_set_bit(i, irq_map));
+}
+
+void __devinit free_irqno(unsigned int irq)
+{
+	smp_mb__before_clear_bit();
+	clear_bit(irq, irq_map);
+	smp_mb__after_clear_bit();
+}
+
+EXPORT_SYMBOL_GPL(free_irqno);
+
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
  * each architecture has to answer this themselves.
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index d5c8b82..cc566cf 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -85,7 +85,12 @@
 	move	$28, a2
 	cpu_restore_nonscratch a1
 
+#if (_THREAD_SIZE - 32) < 0x10000
 	PTR_ADDIU	t0, $28, _THREAD_SIZE - 32
+#else
+	PTR_LI		t0, _THREAD_SIZE - 32
+	PTR_ADDU	t0, $28
+#endif
 	set_saved_sp	t0, t1, t2
 #ifdef CONFIG_MIPS_MT_SMTC
 	/* Read-modify-writes of Status must be atomic on a VPE */
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 720fac3..a95f37d 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -654,6 +654,8 @@
 	sys	sys_set_robust_list	2
 	sys	sys_get_robust_list	3	/* 4310 */
 	sys	sys_ni_syscall		0
+	sys	sys_getcpu		3
+	sys	sys_epoll_pwait		6
 	.endm
 
 	/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 3a34f62..8fb0f60 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -469,3 +469,5 @@
 	PTR	sys_set_robust_list
 	PTR	sys_get_robust_list
 	PTR	sys_ni_syscall			/* 5270 */
+	PTR	sys_getcpu
+	PTR	sys_epoll_pwait
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 67b92a1..0da5ca2 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -395,3 +395,5 @@
 	PTR	compat_sys_set_robust_list
 	PTR	compat_sys_get_robust_list
 	PTR	sys_ni_syscall
+	PTR	sys_getcpu
+	PTR	sys_epoll_pwait
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 2875c4a..b9d00ca 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -517,4 +517,6 @@
 	PTR	compat_sys_set_robust_list
 	PTR	compat_sys_get_robust_list	/* 4310 */
 	PTR	sys_ni_syscall
+	PTR	sys_getcpu
+	PTR	sys_epoll_pwait
 	.size	sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index fdbb508..8f6e896 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -223,7 +223,11 @@
 
 #else  /* !CONFIG_BLK_DEV_INITRD */
 
-#define init_initrd()		0
+static unsigned long __init init_initrd(void)
+{
+	return 0;
+}
+
 #define finalize_initrd()	do {} while (0)
 
 #endif
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 3b5f3b6..2ac19a6c 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -140,15 +140,90 @@
 	.name		= "IPI_call"
 };
 
+static void __init smp_copy_vpe_config(void)
+{
+	write_vpe_c0_status(
+		(read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
+
+	/* set config to be the same as vpe0, particularly kseg0 coherency alg */
+	write_vpe_c0_config( read_c0_config());
+
+	/* make sure there are no software interrupts pending */
+	write_vpe_c0_cause(0);
+
+	/* Propagate Config7 */
+	write_vpe_c0_config7(read_c0_config7());
+
+	write_vpe_c0_count(read_c0_count());
+}
+
+static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0,
+	unsigned int ncpu)
+{
+	if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT))
+		return ncpu;
+
+	/* Deactivate all but VPE 0 */
+	if (tc != 0) {
+		unsigned long tmp = read_vpe_c0_vpeconf0();
+
+		tmp &= ~VPECONF0_VPA;
+
+		/* master VPE */
+		tmp |= VPECONF0_MVP;
+		write_vpe_c0_vpeconf0(tmp);
+
+		/* Record this as available CPU */
+		cpu_set(tc, phys_cpu_present_map);
+		__cpu_number_map[tc]	= ++ncpu;
+		__cpu_logical_map[ncpu]	= tc;
+	}
+
+	/* Disable multi-threading with TC's */
+	write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
+
+	if (tc != 0)
+		smp_copy_vpe_config();
+
+	return ncpu;
+}
+
+static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0)
+{
+	unsigned long tmp;
+
+	if (!tc)
+		return;
+
+	/* bind a TC to each VPE, May as well put all excess TC's
+	   on the last VPE */
+	if (tc >= (((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1))
+		write_tc_c0_tcbind(read_tc_c0_tcbind() | ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT));
+	else {
+		write_tc_c0_tcbind(read_tc_c0_tcbind() | tc);
+
+		/* and set XTC */
+		write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (tc << VPECONF0_XTC_SHIFT));
+	}
+
+	tmp = read_tc_c0_tcstatus();
+
+	/* mark not allocated and not dynamically allocatable */
+	tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+	tmp |= TCSTATUS_IXMT;		/* interrupt exempt */
+	write_tc_c0_tcstatus(tmp);
+
+	write_tc_c0_tchalt(TCHALT_H);
+}
+
 /*
  * Common setup before any secondaries are started
  * Make sure all CPU's are in a sensible state before we boot any of the
  * secondarys
  */
-void plat_smp_setup(void)
+void __init plat_smp_setup(void)
 {
-	unsigned long val;
-	int i, num;
+	unsigned int mvpconf0, ntc, tc, ncpu = 0;
 
 #ifdef CONFIG_MIPS_MT_FPAFF
 	/* If we have an FPU, enroll ourselves in the FPU-full mask */
@@ -167,75 +242,16 @@
 	/* Put MVPE's into 'configuration state' */
 	set_c0_mvpcontrol(MVPCONTROL_VPC);
 
-	val = read_c0_mvpconf0();
+	mvpconf0 = read_c0_mvpconf0();
+	ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT;
 
 	/* we'll always have more TC's than VPE's, so loop setting everything
 	   to a sensible state */
-	for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) {
-		settc(i);
+	for (tc = 0; tc <= ntc; tc++) {
+		settc(tc);
 
-		/* VPE's */
-		if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) {
-
-			/* deactivate all but vpe0 */
-			if (i != 0) {
-				unsigned long tmp = read_vpe_c0_vpeconf0();
-
-				tmp &= ~VPECONF0_VPA;
-
-				/* master VPE */
-				tmp |= VPECONF0_MVP;
-				write_vpe_c0_vpeconf0(tmp);
-
-				/* Record this as available CPU */
-				cpu_set(i, phys_cpu_present_map);
-				__cpu_number_map[i]	= ++num;
-				__cpu_logical_map[num]	= i;
-			}
-
-			/* disable multi-threading with TC's */
-			write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
-
-			if (i != 0) {
-				write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
-
-				/* set config to be the same as vpe0, particularly kseg0 coherency alg */
-				write_vpe_c0_config( read_c0_config());
-
-				/* make sure there are no software interrupts pending */
-				write_vpe_c0_cause(0);
-
-				/* Propagate Config7 */
-				write_vpe_c0_config7(read_c0_config7());
-			}
-
-		}
-
-		/* TC's */
-
-		if (i != 0) {
-			unsigned long tmp;
-
-			/* bind a TC to each VPE, May as well put all excess TC's
-			   on the last VPE */
-			if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) )
-				write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) );
-			else {
-				write_tc_c0_tcbind( read_tc_c0_tcbind() | i);
-
-				/* and set XTC */
-				write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT));
-			}
-
-			tmp = read_tc_c0_tcstatus();
-
-			/* mark not allocated and not dynamically allocatable */
-			tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
-			tmp |= TCSTATUS_IXMT;		/* interrupt exempt */
-			write_tc_c0_tcstatus(tmp);
-
-			write_tc_c0_tchalt(TCHALT_H);
-		}
+		smp_tc_init(tc, mvpconf0);
+		ncpu = smp_vpe_init(tc, mvpconf0, ncpu);
 	}
 
 	/* Release config state */
@@ -243,7 +259,7 @@
 
 	/* We'll wait until starting the secondaries before starting MVPE */
 
-	printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
+	printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu);
 }
 
 void __init plat_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index db80957..49db516 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -463,28 +463,5 @@
 	smp_on_each_tlb(flush_tlb_one_ipi, (void *) vaddr);
 }
 
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
-
-static int __init topology_init(void)
-{
-	int i, ret;
-
-#ifdef CONFIG_NUMA
-	for_each_online_node(i)
-		register_one_node(i);
-#endif /* CONFIG_NUMA */
-
-	for_each_present_cpu(i) {
-		ret = register_cpu(&per_cpu(cpu_devices, i), i);
-		if (ret)
-			printk(KERN_WARNING "topology_init: register_cpu %d "
-			       "failed (%d)\n", i, ret);
-	}
-
-	return 0;
-}
-
-subsys_initcall(topology_init);
-
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(flush_tlb_one);
diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S
index 1cb9441..921207c 100644
--- a/arch/mips/kernel/smtc-asm.S
+++ b/arch/mips/kernel/smtc-asm.S
@@ -101,7 +101,9 @@
 	lw	t0,PT_PADSLOT5(sp)
 	/* Argument from sender passed in stack pad slot 4 */
 	lw	a0,PT_PADSLOT4(sp)
-	PTR_LA	ra, _ret_from_irq
+	LONG_L	s0, TI_REGS($28)
+	LONG_S	sp, TI_REGS($28)
+	PTR_LA	ra, ret_from_irq
 	jr	t0
 
 /*
@@ -119,7 +121,10 @@
 	subu	t1,sp,PT_SIZE
 	sw	ra,PT_EPC(t1)
 	sw	a0,PT_PADSLOT4(t1)
+	LONG_L	s0, TI_REGS($28)
+	LONG_S	sp, TI_REGS($28)
 	la	t2,ipi_decode
+	LONG_S	s0, TI_REGS($28)
 	sw	t2,PT_PADSLOT5(t1)
 	/* Save pre-disable value of TCStatus */
 	sw	t0,PT_TCSTATUS(t1)
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index cc1f747..3b78caf 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -476,6 +476,7 @@
 			write_vpe_c0_compare(0);
 			/* Propagate Config7 */
 			write_vpe_c0_config7(read_c0_config7());
+			write_vpe_c0_count(read_c0_count());
 		}
 		/* enable multi-threading within VPE */
 		write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE);
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index debe86c..e535f86 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -11,6 +11,7 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
+#include <linux/clocksource.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -67,15 +68,9 @@
 int (*rtc_mips_set_mmss)(unsigned long);
 
 
-/* usecs per counter cycle, shifted to left by 32 bits */
-static unsigned int sll32_usecs_per_cycle;
-
 /* how many counter cycles in a jiffy */
 static unsigned long cycles_per_jiffy __read_mostly;
 
-/* Cycle counter value at the previous timer interrupt.. */
-static unsigned int timerhi, timerlo;
-
 /* expirelo is the count value for next CPU timer interrupt */
 static unsigned int expirelo;
 
@@ -93,7 +88,7 @@
 	return 0;
 }
 
-static void null_hpt_init(unsigned int count)
+static void __init null_hpt_init(void)
 {
 	/* nothing */
 }
@@ -128,186 +123,18 @@
 	return read_c0_count();
 }
 
-/* For use solely as a high precision timer.  */
-static void c0_hpt_init(unsigned int count)
-{
-	write_c0_count(read_c0_count() - count);
-}
-
 /* For use both as a high precision timer and an interrupt source.  */
-static void c0_hpt_timer_init(unsigned int count)
+static void __init c0_hpt_timer_init(void)
 {
-	count = read_c0_count() - count;
-	expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy;
-	write_c0_count(expirelo - cycles_per_jiffy);
+	expirelo = read_c0_count() + cycles_per_jiffy;
 	write_c0_compare(expirelo);
-	write_c0_count(count);
 }
 
 int (*mips_timer_state)(void);
 void (*mips_timer_ack)(void);
 unsigned int (*mips_hpt_read)(void);
-void (*mips_hpt_init)(unsigned int);
-
-/*
- * Gettimeoffset routines.  These routines returns the time duration
- * since last timer interrupt in usecs.
- *
- * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset.
- * Otherwise use calibrate_gettimeoffset()
- *
- * If the CPU does not have the counter register, you can either supply
- * your own gettimeoffset() routine, or use null_gettimeoffset(), which
- * gives the same resolution as HZ.
- */
-
-static unsigned long null_gettimeoffset(void)
-{
-	return 0;
-}
-
-
-/* The function pointer to one of the gettimeoffset funcs.  */
-unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset;
-
-
-static unsigned long fixed_rate_gettimeoffset(void)
-{
-	u32 count;
-	unsigned long res;
-
-	/* Get last timer tick in absolute kernel time */
-	count = mips_hpt_read();
-
-	/* .. relative to previous jiffy (32 bits is enough) */
-	count -= timerlo;
-
-	__asm__("multu	%1,%2"
-		: "=h" (res)
-		: "r" (count), "r" (sll32_usecs_per_cycle)
-		: "lo", GCC_REG_ACCUM);
-
-	/*
-	 * Due to possible jiffies inconsistencies, we need to check
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (res >= USECS_PER_JIFFY)
-		res = USECS_PER_JIFFY - 1;
-
-	return res;
-}
-
-
-/*
- * Cached "1/(clocks per usec) * 2^32" value.
- * It has to be recalculated once each jiffy.
- */
-static unsigned long cached_quotient;
-
-/* Last jiffy when calibrate_divXX_gettimeoffset() was called. */
-static unsigned long last_jiffies;
-
-/*
- * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej.
- */
-static unsigned long calibrate_div32_gettimeoffset(void)
-{
-	u32 count;
-	unsigned long res, tmp;
-	unsigned long quotient;
-
-	tmp = jiffies;
-
-	quotient = cached_quotient;
-
-	if (last_jiffies != tmp) {
-		last_jiffies = tmp;
-		if (last_jiffies != 0) {
-			unsigned long r0;
-			do_div64_32(r0, timerhi, timerlo, tmp);
-			do_div64_32(quotient, USECS_PER_JIFFY,
-				    USECS_PER_JIFFY_FRAC, r0);
-			cached_quotient = quotient;
-		}
-	}
-
-	/* Get last timer tick in absolute kernel time */
-	count = mips_hpt_read();
-
-	/* .. relative to previous jiffy (32 bits is enough) */
-	count -= timerlo;
-
-	__asm__("multu  %1,%2"
-		: "=h" (res)
-		: "r" (count), "r" (quotient)
-		: "lo", GCC_REG_ACCUM);
-
-	/*
-	 * Due to possible jiffies inconsistencies, we need to check
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (res >= USECS_PER_JIFFY)
-		res = USECS_PER_JIFFY - 1;
-
-	return res;
-}
-
-static unsigned long calibrate_div64_gettimeoffset(void)
-{
-	u32 count;
-	unsigned long res, tmp;
-	unsigned long quotient;
-
-	tmp = jiffies;
-
-	quotient = cached_quotient;
-
-	if (last_jiffies != tmp) {
-		last_jiffies = tmp;
-		if (last_jiffies) {
-			unsigned long r0;
-			__asm__(".set	push\n\t"
-				".set	mips3\n\t"
-				"lwu	%0,%3\n\t"
-				"dsll32	%1,%2,0\n\t"
-				"or	%1,%1,%0\n\t"
-				"ddivu	$0,%1,%4\n\t"
-				"mflo	%1\n\t"
-				"dsll32	%0,%5,0\n\t"
-				"or	%0,%0,%6\n\t"
-				"ddivu	$0,%0,%1\n\t"
-				"mflo	%0\n\t"
-				".set	pop"
-				: "=&r" (quotient), "=&r" (r0)
-				: "r" (timerhi), "m" (timerlo),
-				  "r" (tmp), "r" (USECS_PER_JIFFY),
-				  "r" (USECS_PER_JIFFY_FRAC)
-				: "hi", "lo", GCC_REG_ACCUM);
-			cached_quotient = quotient;
-		}
-	}
-
-	/* Get last timer tick in absolute kernel time */
-	count = mips_hpt_read();
-
-	/* .. relative to previous jiffy (32 bits is enough) */
-	count -= timerlo;
-
-	__asm__("multu	%1,%2"
-		: "=h" (res)
-		: "r" (count), "r" (quotient)
-		: "lo", GCC_REG_ACCUM);
-
-	/*
-	 * Due to possible jiffies inconsistencies, we need to check
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (res >= USECS_PER_JIFFY)
-		res = USECS_PER_JIFFY - 1;
-
-	return res;
-}
-
+void (*mips_hpt_init)(void) __initdata = null_hpt_init;
+unsigned int mips_hpt_mask = 0xffffffff;
 
 /* last time when xtime and rtc are sync'ed up */
 static long last_rtc_update;
@@ -334,18 +161,10 @@
  */
 irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
-	unsigned long j;
-	unsigned int count;
-
 	write_seqlock(&xtime_lock);
 
-	count = mips_hpt_read();
 	mips_timer_ack();
 
-	/* Update timerhi/timerlo for intra-jiffy calibration. */
-	timerhi += count < timerlo;			/* Wrap around */
-	timerlo = count;
-
 	/*
 	 * call the generic timer interrupt handling
 	 */
@@ -368,47 +187,6 @@
 		}
 	}
 
-	/*
-	 * If jiffies has overflown in this timer_interrupt, we must
-	 * update the timer[hi]/[lo] to make fast gettimeoffset funcs
-	 * quotient calc still valid. -arca
-	 *
-	 * The first timer interrupt comes late as interrupts are
-	 * enabled long after timers are initialized.  Therefore the
-	 * high precision timer is fast, leading to wrong gettimeoffset()
-	 * calculations.  We deal with it by setting it based on the
-	 * number of its ticks between the second and the third interrupt.
-	 * That is still somewhat imprecise, but it's a good estimate.
-	 * --macro
-	 */
-	j = jiffies;
-	if (j < 4) {
-		static unsigned int prev_count;
-		static int hpt_initialized;
-
-		switch (j) {
-		case 0:
-			timerhi = timerlo = 0;
-			mips_hpt_init(count);
-			break;
-		case 2:
-			prev_count = count;
-			break;
-		case 3:
-			if (!hpt_initialized) {
-				unsigned int c3 = 3 * (count - prev_count);
-
-				timerhi = 0;
-				timerlo = c3;
-				mips_hpt_init(count - c3);
-				hpt_initialized = 1;
-			}
-			break;
-		default:
-			break;
-		}
-	}
-
 	write_sequnlock(&xtime_lock);
 
 	/*
@@ -476,12 +254,11 @@
  * 1) board_time_init() -
  * 	a) (optional) set up RTC routines,
  *      b) (optional) calibrate and set the mips_hpt_frequency
- *	    (only needed if you intended to use fixed_rate_gettimeoffset
- *	     or use cpu counter as timer interrupt source)
+ *	    (only needed if you intended to use cpu counter as timer interrupt
+ *	     source)
  * 2) setup xtime based on rtc_mips_get_time().
- * 3) choose a appropriate gettimeoffset routine.
- * 4) calculate a couple of cached variables for later usage
- * 5) plat_timer_setup() -
+ * 3) calculate a couple of cached variables for later usage
+ * 4) plat_timer_setup() -
  *	a) (optional) over-write any choices made above by time_init().
  *	b) machine specific code should setup the timer irqaction.
  *	c) enable the timer interrupt
@@ -533,13 +310,48 @@
 	} while (--i);
 	hpt_end = mips_hpt_read();
 
-	hpt_count = hpt_end - hpt_start;
+	hpt_count = (hpt_end - hpt_start) & mips_hpt_mask;
 	hz = HZ;
 	frequency = (u64)hpt_count * (u64)hz;
 
 	return frequency >> log_2_loops;
 }
 
+static cycle_t read_mips_hpt(void)
+{
+	return (cycle_t)mips_hpt_read();
+}
+
+static struct clocksource clocksource_mips = {
+	.name		= "MIPS",
+	.read		= read_mips_hpt,
+	.is_continuous	= 1,
+};
+
+static void __init init_mips_clocksource(void)
+{
+	u64 temp;
+	u32 shift;
+
+	if (!mips_hpt_frequency || mips_hpt_read == null_hpt_read)
+		return;
+
+	/* Calclate a somewhat reasonable rating value */
+	clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
+	/* Find a shift value */
+	for (shift = 32; shift > 0; shift--) {
+		temp = (u64) NSEC_PER_SEC << shift;
+		do_div(temp, mips_hpt_frequency);
+		if ((temp >> 32) == 0)
+			break;
+	}
+	clocksource_mips.shift = shift;
+	clocksource_mips.mult = (u32)temp;
+	clocksource_mips.mask = mips_hpt_mask;
+
+	clocksource_register(&clocksource_mips);
+}
+
 void __init time_init(void)
 {
 	if (board_time_init)
@@ -555,41 +367,21 @@
 	                        -xtime.tv_sec, -xtime.tv_nsec);
 
 	/* Choose appropriate high precision timer routines.  */
-	if (!cpu_has_counter && !mips_hpt_read) {
+	if (!cpu_has_counter && !mips_hpt_read)
 		/* No high precision timer -- sorry.  */
 		mips_hpt_read = null_hpt_read;
-		mips_hpt_init = null_hpt_init;
-	} else if (!mips_hpt_frequency && !mips_timer_state) {
+	else if (!mips_hpt_frequency && !mips_timer_state) {
 		/* A high precision timer of unknown frequency.  */
-		if (!mips_hpt_read) {
+		if (!mips_hpt_read)
 			/* No external high precision timer -- use R4k.  */
 			mips_hpt_read = c0_hpt_read;
-			mips_hpt_init = c0_hpt_init;
-		}
-
-		if (cpu_has_mips32r1 || cpu_has_mips32r2 ||
-		    (current_cpu_data.isa_level == MIPS_CPU_ISA_I) ||
-		    (current_cpu_data.isa_level == MIPS_CPU_ISA_II))
-			/*
-			 * We need to calibrate the counter but we don't have
-			 * 64-bit division.
-			 */
-			do_gettimeoffset = calibrate_div32_gettimeoffset;
-		else
-			/*
-			 * We need to calibrate the counter but we *do* have
-			 * 64-bit division.
-			 */
-			do_gettimeoffset = calibrate_div64_gettimeoffset;
 	} else {
 		/* We know counter frequency.  Or we can get it.  */
 		if (!mips_hpt_read) {
 			/* No external high precision timer -- use R4k.  */
 			mips_hpt_read = c0_hpt_read;
 
-			if (mips_timer_state)
-				mips_hpt_init = c0_hpt_init;
-			else {
+			if (!mips_timer_state) {
 				/* No external timer interrupt -- use R4k.  */
 				mips_hpt_init = c0_hpt_timer_init;
 				mips_timer_ack = c0_timer_ack;
@@ -598,16 +390,9 @@
 		if (!mips_hpt_frequency)
 			mips_hpt_frequency = calibrate_hpt();
 
-		do_gettimeoffset = fixed_rate_gettimeoffset;
-
 		/* Calculate cache parameters.  */
 		cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ;
 
-		/* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq  */
-		do_div64_32(sll32_usecs_per_cycle,
-			    1000000, mips_hpt_frequency / 2,
-			    mips_hpt_frequency);
-
 		/* Report the high precision timer rate for a reference.  */
 		printk("Using %u.%03u MHz high precision timer.\n",
 		       ((mips_hpt_frequency + 500) / 1000) / 1000,
@@ -619,7 +404,7 @@
 		mips_timer_ack = null_timer_ack;
 
 	/* This sets up the high precision timer for the first interrupt.  */
-	mips_hpt_init(mips_hpt_read());
+	mips_hpt_init();
 
 	/*
 	 * Call board specific timer interrupt setup.
@@ -633,6 +418,8 @@
 	 * is not invoked accidentally.
 	 */
 	plat_timer_setup(&timer_irqaction);
+
+	init_mips_clocksource();
 }
 
 #define FEBRUARY		2
diff --git a/arch/mips/kernel/topology.c b/arch/mips/kernel/topology.c
new file mode 100644
index 0000000..660e44e
--- /dev/null
+++ b/arch/mips/kernel/topology.c
@@ -0,0 +1,29 @@
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/node.h>
+#include <linux/nodemask.h>
+#include <linux/percpu.h>
+
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
+
+static int __init topology_init(void)
+{
+	int i, ret;
+
+#ifdef CONFIG_NUMA
+	for_each_online_node(i)
+		register_one_node(i);
+#endif /* CONFIG_NUMA */
+
+	for_each_present_cpu(i) {
+		ret = register_cpu(&per_cpu(cpu_devices, i), i);
+		if (ret)
+			printk(KERN_WARNING "topology_init: register_cpu %d "
+			       "failed (%d)\n", i, ret);
+	}
+
+	return 0;
+}
+
+subsys_initcall(topology_init);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index cce8313..9fda1b8 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1111,7 +1111,7 @@
 static void mips_srs_init(void)
 {
 	shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
-	printk(KERN_INFO "%d MIPSR2 register sets available\n",
+	printk(KERN_INFO "%ld MIPSR2 register sets available\n",
 	       shadow_registers.sr_supported);
 	shadow_registers.sr_allocated = 1;	/* Set 0 used by kernel */
 }
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 0bb9cd8..79f0317 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -50,6 +50,16 @@
   /* writeable */
   .data : {			/* Data */
     . = . + DATAOFFSET;		/* for CONFIG_MAPPED_KERNEL */
+    /*
+     * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which
+     * limits the maximum alignment to at most 32kB and results in the following
+     * warning:
+     *
+     *  CC      arch/mips/kernel/init_task.o
+     * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’
+     * is greater than maximum object file alignment.  Using 32768
+     */
+    . = ALIGN(_PAGE_SIZE);
     *(.data.init_task)
 
     *(.data)
@@ -91,13 +101,7 @@
 
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
 
diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c
index be8261b..594df1a 100644
--- a/arch/mips/lib-64/dump_tlb.c
+++ b/arch/mips/lib-64/dump_tlb.c
@@ -149,7 +149,7 @@
 	printk("Addr                 == %08lx\n", addr);
 	printk("tasks->mm.pgd        == %08lx\n", (unsigned long) t->mm->pgd);
 
-	page_dir = pgd_offset(t->mm, 0);
+	page_dir = pgd_offset(t->mm, 0UL);
 	printk("page_dir == %016lx\n", (unsigned long) page_dir);
 
 	pgd = pgd_offset(t->mm, addr);
@@ -184,13 +184,13 @@
 	dump_list_process(current, address);
 }
 
-unsigned int vtop(void *address)
+unsigned long vtop(void *address)
 {
 	pgd_t	*pgd;
 	pud_t	*pud;
 	pmd_t	*pmd;
 	pte_t	*pte;
-	unsigned int addr, paddr;
+	unsigned long addr, paddr;
 
 	addr = (unsigned long) address;
 	pgd = pgd_offset(current->mm, addr);
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
index be80c5d..eeed944 100644
--- a/arch/mips/mips-boards/generic/memory.c
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -176,7 +176,7 @@
 		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
 			continue;
 
-		addr = boot_mem_map.map[i].addr;
+		addr = PAGE_ALIGN(boot_mem_map.map[i].addr);
 		while (addr < boot_mem_map.map[i].addr
 			      + boot_mem_map.map[i].size) {
 			ClearPageReserved(virt_to_page(__va(addr)));
diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c
index 9337f6c..3192a14 100644
--- a/arch/mips/mips-boards/generic/pci.c
+++ b/arch/mips/mips-boards/generic/pci.c
@@ -90,7 +90,7 @@
 void __init mips_pcibios_init(void)
 {
 	struct pci_controller *controller;
-	unsigned long start, end, map, start1, end1, map1, map2, map3, mask;
+	resource_size_t start, end, map, start1, end1, map1, map2, map3, mask;
 
 	switch (mips_revision_corid) {
 	case MIPS_REVISION_CORID_QED_RM5261:
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index 6f8a9fe..d817c60 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -187,7 +187,7 @@
 }
 
 /*
- * Estimate CPU frequency.  Sets mips_counter_frequency as a side-effect
+ * Estimate CPU frequency.  Sets mips_hpt_frequency as a side-effect
  */
 static unsigned int __init estimate_cpu_frequency(void)
 {
@@ -208,7 +208,8 @@
 		count = 6000000;
 #endif
 #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA)
-	unsigned int flags;
+	unsigned long flags;
+	unsigned int start;
 
 	local_irq_save(flags);
 
@@ -217,13 +218,13 @@
 	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 
 	/* Start r4k counter. */
-	write_c0_count(0);
+	start = read_c0_count();
 
 	/* Read counter exactly on falling edge of update flag */
 	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
 	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 
-	count = read_c0_count();
+	count = read_c0_count() - start;
 
 	/* restore interrupts */
 	local_irq_restore(flags);
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index ab460f8..282f3e5 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -159,7 +159,7 @@
 				BONITO_PCIMEMBASECFG |=
 					(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
 					 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
-				printk("Disabled Bonito IOBC coherency\n");
+				printk("Enabled Bonito IOBC coherency\n");
 			}
 		}
 		else
diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c
index c566b9b..24a4ed0 100644
--- a/arch/mips/mips-boards/sim/sim_time.c
+++ b/arch/mips/mips-boards/sim/sim_time.c
@@ -102,7 +102,7 @@
 
 
 /*
- * Estimate CPU frequency.  Sets mips_counter_frequency as a side-effect
+ * Estimate CPU frequency.  Sets mips_hpt_frequency as a side-effect
  */
 static unsigned int __init estimate_cpu_frequency(void)
 {
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 5537558..3a8afd4 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/init.h>
+#include <linux/hardirq.h>
 
 #include <asm/asm.h>
 #include <asm/bootinfo.h>
@@ -49,6 +50,15 @@
 static unsigned int icache_range_cutoff;
 static unsigned int dcache_range_cutoff;
 
+static inline void sb1_on_each_cpu(void (*func) (void *info), void *info,
+				   int retry, int wait)
+{
+	preempt_disable();
+	smp_call_function(func, info, retry, wait);
+	func(info);
+	preempt_enable();
+}
+
 /*
  * The dcache is fully coherent to the system, with one
  * big caveat:  the instruction stream.  In other words,
@@ -226,13 +236,32 @@
 	args.vma = vma;
 	args.addr = addr;
 	args.pfn = pfn;
-	on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1);
+	sb1_on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1);
 }
 #else
 void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
 	__attribute__((alias("local_sb1_flush_cache_page")));
 #endif
 
+#ifdef CONFIG_SMP
+static void sb1_flush_cache_data_page_ipi(void *info)
+{
+	unsigned long start = (unsigned long)info;
+
+	__sb1_writeback_inv_dcache_range(start, start + PAGE_SIZE);
+}
+
+static void sb1_flush_cache_data_page(unsigned long addr)
+{
+	if (in_atomic())
+		__sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE);
+	else
+		on_each_cpu(sb1_flush_cache_data_page_ipi, (void *) addr, 1, 1);
+}
+#else
+void sb1_flush_cache_data_page(unsigned long)
+	__attribute__((alias("local_sb1_flush_cache_data_page")));
+#endif
 
 /*
  * Invalidate all caches on this CPU
@@ -249,7 +278,7 @@
 
 static void sb1___flush_cache_all(void)
 {
-	on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1);
+	sb1_on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1);
 }
 #else
 void sb1___flush_cache_all(void)
@@ -299,7 +328,7 @@
 
 	args.start = start;
 	args.end = end;
-	on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1);
+	sb1_on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1);
 }
 #else
 void sb1_flush_icache_range(unsigned long start, unsigned long end)
@@ -326,7 +355,7 @@
 
 static void sb1_flush_cache_sigtramp(unsigned long addr)
 {
-	on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1);
+	sb1_on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1);
 }
 #else
 void sb1_flush_cache_sigtramp(unsigned long addr)
@@ -444,7 +473,6 @@
 void sb1_cache_init(void)
 {
 	extern char except_vec2_sb1;
-	extern char handle_vec2_sb1;
 
 	/* Special cache error handler for SB1 */
 	set_uncached_handler (0x100, &except_vec2_sb1, 0x80);
@@ -473,7 +501,7 @@
 
 	flush_cache_sigtramp = sb1_flush_cache_sigtramp;
 	local_flush_data_cache_page = (void *) sb1_nop;
-	flush_data_cache_page = (void *) sb1_nop;
+	flush_data_cache_page = sb1_flush_cache_data_page;
 
 	/* Full flush */
 	__flush_cache_all = sb1___flush_cache_all;
@@ -497,5 +525,5 @@
 	:
 	: "memory");
 
-	flush_cache_all();
+	local_sb1___flush_cache_all();
 }
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 88b72c9..2de4d3c 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -30,11 +30,34 @@
 #include <asm/cachectl.h>
 #include <asm/cpu.h>
 #include <asm/dma.h>
+#include <asm/kmap_types.h>
 #include <asm/mmu_context.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
+#include <asm/fixmap.h>
+
+/* Atomicity and interruptability */
+#ifdef CONFIG_MIPS_MT_SMTC
+
+#include <asm/mipsmtregs.h>
+
+#define ENTER_CRITICAL(flags) \
+	{ \
+	unsigned int mvpflags; \
+	local_irq_save(flags);\
+	mvpflags = dvpe()
+#define EXIT_CRITICAL(flags) \
+	evpe(mvpflags); \
+	local_irq_restore(flags); \
+	}
+#else
+
+#define ENTER_CRITICAL(flags) local_irq_save(flags)
+#define EXIT_CRITICAL(flags) local_irq_restore(flags)
+
+#endif /* CONFIG_MIPS_MT_SMTC */
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
@@ -80,13 +103,142 @@
 	return 1UL << order;
 }
 
-#ifdef CONFIG_HIGHMEM
-pte_t *kmap_pte;
-pgprot_t kmap_prot;
+/*
+ * These are almost like kmap_atomic / kunmap_atmic except they take an
+ * additional address argument as the hint.
+ */
 
 #define kmap_get_fixmap_pte(vaddr)					\
 	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
 
+#ifdef CONFIG_MIPS_MT_SMTC
+static pte_t *kmap_coherent_pte;
+static void __init kmap_coherent_init(void)
+{
+	unsigned long vaddr;
+
+	/* cache the first coherent kmap pte */
+	vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
+	kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
+}
+#else
+static inline void kmap_coherent_init(void) {}
+#endif
+
+static inline void *kmap_coherent(struct page *page, unsigned long addr)
+{
+	enum fixed_addresses idx;
+	unsigned long vaddr, flags, entrylo;
+	unsigned long old_ctx;
+	pte_t pte;
+	int tlbidx;
+
+	inc_preempt_count();
+	idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
+#ifdef CONFIG_MIPS_MT_SMTC
+	idx += FIX_N_COLOURS * smp_processor_id();
+#endif
+	vaddr = __fix_to_virt(FIX_CMAP_END - idx);
+	pte = mk_pte(page, PAGE_KERNEL);
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+	entrylo = pte.pte_high;
+#else
+	entrylo = pte_val(pte) >> 6;
+#endif
+
+	ENTER_CRITICAL(flags);
+	old_ctx = read_c0_entryhi();
+	write_c0_entryhi(vaddr & (PAGE_MASK << 1));
+	write_c0_entrylo0(entrylo);
+	write_c0_entrylo1(entrylo);
+#ifdef CONFIG_MIPS_MT_SMTC
+	set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
+	/* preload TLB instead of local_flush_tlb_one() */
+	mtc0_tlbw_hazard();
+	tlb_probe();
+	tlb_probe_hazard();
+	tlbidx = read_c0_index();
+	mtc0_tlbw_hazard();
+	if (tlbidx < 0)
+		tlb_write_random();
+	else
+		tlb_write_indexed();
+#else
+	tlbidx = read_c0_wired();
+	write_c0_wired(tlbidx + 1);
+	write_c0_index(tlbidx);
+	mtc0_tlbw_hazard();
+	tlb_write_indexed();
+#endif
+	tlbw_use_hazard();
+	write_c0_entryhi(old_ctx);
+	EXIT_CRITICAL(flags);
+
+	return (void*) vaddr;
+}
+
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
+static inline void kunmap_coherent(struct page *page)
+{
+#ifndef CONFIG_MIPS_MT_SMTC
+	unsigned int wired;
+	unsigned long flags, old_ctx;
+
+	ENTER_CRITICAL(flags);
+	old_ctx = read_c0_entryhi();
+	wired = read_c0_wired() - 1;
+	write_c0_wired(wired);
+	write_c0_index(wired);
+	write_c0_entryhi(UNIQUE_ENTRYHI(wired));
+	write_c0_entrylo0(0);
+	write_c0_entrylo1(0);
+	mtc0_tlbw_hazard();
+	tlb_write_indexed();
+	tlbw_use_hazard();
+	write_c0_entryhi(old_ctx);
+	EXIT_CRITICAL(flags);
+#endif
+	dec_preempt_count();
+	preempt_check_resched();
+}
+
+void copy_to_user_page(struct vm_area_struct *vma,
+	struct page *page, unsigned long vaddr, void *dst, const void *src,
+	unsigned long len)
+{
+	if (cpu_has_dc_aliases) {
+		void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+		memcpy(vto, src, len);
+		kunmap_coherent(page);
+	} else
+		memcpy(dst, src, len);
+	if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)
+		flush_cache_page(vma, vaddr, page_to_pfn(page));
+}
+
+EXPORT_SYMBOL(copy_to_user_page);
+
+void copy_from_user_page(struct vm_area_struct *vma,
+	struct page *page, unsigned long vaddr, void *dst, const void *src,
+	unsigned long len)
+{
+	if (cpu_has_dc_aliases) {
+		void *vfrom =
+			kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+		memcpy(dst, vfrom, len);
+		kunmap_coherent(page);
+	} else
+		memcpy(dst, src, len);
+}
+
+EXPORT_SYMBOL(copy_from_user_page);
+
+
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
 static void __init kmap_init(void)
 {
 	unsigned long kmap_vstart;
@@ -97,11 +249,12 @@
 
 	kmap_prot = PAGE_KERNEL;
 }
+#endif /* CONFIG_HIGHMEM */
 
-#ifdef CONFIG_32BIT
 void __init fixrange_init(unsigned long start, unsigned long end,
 	pgd_t *pgd_base)
 {
+#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC)
 	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
@@ -122,7 +275,7 @@
 			for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
 				if (pmd_none(*pmd)) {
 					pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-					set_pmd(pmd, __pmd(pte));
+					set_pmd(pmd, __pmd((unsigned long)pte));
 					if (pte != pte_offset_kernel(pmd, 0))
 						BUG();
 				}
@@ -132,9 +285,8 @@
 		}
 		j = 0;
 	}
+#endif
 }
-#endif /* CONFIG_32BIT */
-#endif /* CONFIG_HIGHMEM */
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 extern void pagetable_init(void);
@@ -175,6 +327,7 @@
 #ifdef CONFIG_HIGHMEM
 	kmap_init();
 #endif
+	kmap_coherent_init();
 
 	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 	low = max_low_pfn;
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
index b7c7492..d41fc58 100644
--- a/arch/mips/mm/pg-r4k.c
+++ b/arch/mips/mm/pg-r4k.c
@@ -270,6 +270,20 @@
 	emit_instruction(mi);
 }
 
+static inline void build_addiu_a2(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 6;		/* $a2 */
+	mi.i_format.rt         = 6;		/* $a2 */
+	mi.i_format.simmediate = offset;
+
+	emit_instruction(mi);
+}
+
 static inline void build_addiu_a1(unsigned long offset)
 {
 	union mips_instruction mi;
@@ -333,6 +347,7 @@
 void __init build_clear_page(void)
 {
 	unsigned int loop_start;
+	unsigned long off;
 
 	epc = (unsigned int *) &clear_page_array;
 	instruction_pending = 0;
@@ -369,7 +384,12 @@
 		}
 	}
 
-	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+        off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0);
+	if (off > 0x7fff) {
+		build_addiu_a2_a0(off >> 1);
+		build_addiu_a2(off >> 1);
+	} else
+		build_addiu_a2_a0(off);
 
 	if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
 		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
@@ -420,12 +440,18 @@
 void __init build_copy_page(void)
 {
 	unsigned int loop_start;
+	unsigned long off;
 
 	epc = (unsigned int *) &copy_page_array;
 	store_offset = load_offset = 0;
 	instruction_pending = 0;
 
-	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+	off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0);
+	if (off > 0x7fff) {
+		build_addiu_a2_a0(off >> 1);
+		build_addiu_a2(off >> 1);
+	} else
+		build_addiu_a2_a0(off);
 
 	if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
 		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
index 4bdaa05..4a61e62 100644
--- a/arch/mips/mm/pgtable-32.c
+++ b/arch/mips/mm/pgtable-32.c
@@ -31,9 +31,10 @@
 
 void __init pagetable_init(void)
 {
-#ifdef CONFIG_HIGHMEM
 	unsigned long vaddr;
-	pgd_t *pgd, *pgd_base;
+	pgd_t *pgd_base;
+#ifdef CONFIG_HIGHMEM
+	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
@@ -44,7 +45,6 @@
 	pgd_init((unsigned long)swapper_pg_dir
 		 + sizeof(pgd_t) * USER_PTRS_PER_PGD);
 
-#ifdef CONFIG_HIGHMEM
 	pgd_base = swapper_pg_dir;
 
 	/*
@@ -53,6 +53,7 @@
 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
 	fixrange_init(vaddr, 0, pgd_base);
 
+#ifdef CONFIG_HIGHMEM
 	/*
 	 * Permanent kmaps:
 	 */
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
index 44b5e97f..8d600d3 100644
--- a/arch/mips/mm/pgtable-64.c
+++ b/arch/mips/mm/pgtable-64.c
@@ -8,6 +8,7 @@
  */
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <asm/fixmap.h>
 #include <asm/pgtable.h>
 
 void pgd_init(unsigned long page)
@@ -52,7 +53,17 @@
 
 void __init pagetable_init(void)
 {
+	unsigned long vaddr;
+	pgd_t *pgd_base;
+
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
 	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
+
+	pgd_base = swapper_pg_dir;
+	/*
+	 * Fixed mappings:
+	 */
+	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+	fixrange_init(vaddr, 0, pgd_base);
 }
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 6f8b25c..fec318a 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -102,7 +102,7 @@
 	insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
 	insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
 	insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
-	insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
+	insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
 	insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
 	insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
 	insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
@@ -145,6 +145,7 @@
 	{ insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
 	{ insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
 	{ insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE },
+	{ insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE },
 	{ insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD },
 	{ insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 },
 	{ insn_j, M(j_op,0,0,0,0,0), JIMM },
@@ -385,6 +386,7 @@
 I_u2u1u3(_dsll32);
 I_u2u1u3(_dsra);
 I_u2u1u3(_dsrl);
+I_u2u1u3(_dsrl32);
 I_u3u1u2(_dsubu);
 I_0(_eret);
 I_u1(_j);
@@ -996,7 +998,12 @@
 #endif
 
 	l_vmalloc_done(l, *p);
-	i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */
+
+	if (PGDIR_SHIFT - 3 < 32)		/* get pgd offset in bytes */
+		i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
+	else
+		i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
+
 	i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
 	i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
 	i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
@@ -1073,7 +1080,7 @@
 
 static __init void build_adjust_context(u32 **p, unsigned int ctx)
 {
-	unsigned int shift = 4 - (PTE_T_LOG2 + 1);
+	unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12;
 	unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
 
 	switch (current_cpu_data.cputype) {
diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile
index 8bcea64d..d5a090a 100644
--- a/arch/mips/momentum/ocelot_3/Makefile
+++ b/arch/mips/momentum/ocelot_3/Makefile
@@ -5,4 +5,4 @@
 # removes any old dependencies. DON'T put your own dependencies here
 # unless it's something special (ie not a .c file).
 #
-obj-y	 += irq.o prom.o reset.o setup.o
+obj-y	 += irq.o platform.o prom.o reset.o setup.o
diff --git a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h b/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h
index 227e429..5710a90 100644
--- a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h
+++ b/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h
@@ -51,7 +51,9 @@
 
 extern unsigned long ocelot_fpga_base;
 
-#define OCELOT_FPGA_WRITE(x, y) writeb(x, ocelot_fpga_base + OCELOT_3_REG_##y)
-#define OCELOT_FPGA_READ(x) readb(ocelot_fpga_base + OCELOT_3_REG_##x)
+#define __FPGA_REG_TO_ADDR(reg)						\
+	((void *) ocelot_fpga_base + OCELOT_3_REG_##reg)
+#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg))
+#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg))
 
 #endif
diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c
new file mode 100644
index 0000000..eefe584
--- /dev/null
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -0,0 +1,235 @@
+#include <linux/delay.h>
+#include <linux/if_ether.h>
+#include <linux/ioport.h>
+#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
+
+#include "ocelot_3_fpga.h"
+
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
+
+static struct resource mv643xx_eth_shared_resources[] = {
+	[0] = {
+		.name   = "ethernet shared base",
+		.start  = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
+		.end    = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
+		                       MV643XX_ETH_SHARED_REGS_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device mv643xx_eth_shared_device = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv643xx_eth_shared_resources),
+	.resource	= mv643xx_eth_shared_resources,
+};
+
+#define MV_SRAM_BASE			0xfe000000UL
+#define MV_SRAM_SIZE			(256 * 1024)
+
+#define MV_SRAM_RXRING_SIZE		(MV_SRAM_SIZE / 4)
+#define MV_SRAM_TXRING_SIZE		(MV_SRAM_SIZE / 4)
+
+#define MV_SRAM_BASE_ETH0		MV_SRAM_BASE
+#define MV_SRAM_BASE_ETH1		(MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
+
+#define MV64x60_IRQ_ETH_0 48
+#define MV64x60_IRQ_ETH_1 49
+#define MV64x60_IRQ_ETH_2 50
+
+#ifdef CONFIG_MV643XX_ETH_0
+
+static struct resource mv64x60_eth0_resources[] = {
+	[0] = {
+		.name	= "eth0 irq",
+		.start	= MV64x60_IRQ_ETH_0,
+		.end	= MV64x60_IRQ_ETH_0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static char eth0_mac_addr[ETH_ALEN];
+
+static struct mv643xx_eth_platform_data eth0_pd = {
+	.mac_addr	= eth0_mac_addr,
+
+	.tx_sram_addr	= MV_SRAM_BASE_ETH0,
+	.tx_sram_size	= MV_SRAM_TXRING_SIZE,
+	.tx_queue_size	= MV_SRAM_TXRING_SIZE / 16,
+
+	.rx_sram_addr	= MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
+	.rx_sram_size	= MV_SRAM_RXRING_SIZE,
+	.rx_queue_size	= MV_SRAM_RXRING_SIZE / 16,
+};
+
+static struct platform_device eth0_device = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth0_resources),
+	.resource	= mv64x60_eth0_resources,
+	.dev = {
+		.platform_data = &eth0_pd,
+	},
+};
+#endif /* CONFIG_MV643XX_ETH_0 */
+
+#ifdef CONFIG_MV643XX_ETH_1
+
+static struct resource mv64x60_eth1_resources[] = {
+	[0] = {
+		.name	= "eth1 irq",
+		.start	= MV64x60_IRQ_ETH_1,
+		.end	= MV64x60_IRQ_ETH_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static char eth1_mac_addr[ETH_ALEN];
+
+static struct mv643xx_eth_platform_data eth1_pd = {
+	.mac_addr	= eth1_mac_addr,
+
+	.tx_sram_addr	= MV_SRAM_BASE_ETH1,
+	.tx_sram_size	= MV_SRAM_TXRING_SIZE,
+	.tx_queue_size	= MV_SRAM_TXRING_SIZE / 16,
+
+	.rx_sram_addr	= MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
+	.rx_sram_size	= MV_SRAM_RXRING_SIZE,
+	.rx_queue_size	= MV_SRAM_RXRING_SIZE / 16,
+};
+
+static struct platform_device eth1_device = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth1_resources),
+	.resource	= mv64x60_eth1_resources,
+	.dev = {
+		.platform_data = &eth1_pd,
+	},
+};
+#endif /* CONFIG_MV643XX_ETH_1 */
+
+#ifdef CONFIG_MV643XX_ETH_2
+
+static struct resource mv64x60_eth2_resources[] = {
+	[0] = {
+		.name	= "eth2 irq",
+		.start	= MV64x60_IRQ_ETH_2,
+		.end	= MV64x60_IRQ_ETH_2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static char eth2_mac_addr[ETH_ALEN];
+
+static struct mv643xx_eth_platform_data eth2_pd = {
+	.mac_addr	= eth2_mac_addr,
+};
+
+static struct platform_device eth2_device = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth2_resources),
+	.resource	= mv64x60_eth2_resources,
+	.dev = {
+		.platform_data = &eth2_pd,
+	},
+};
+#endif /* CONFIG_MV643XX_ETH_2 */
+
+static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
+	&mv643xx_eth_shared_device,
+#ifdef CONFIG_MV643XX_ETH_0
+	&eth0_device,
+#endif
+#ifdef CONFIG_MV643XX_ETH_1
+	&eth1_device,
+#endif
+#ifdef CONFIG_MV643XX_ETH_2
+	&eth2_device,
+#endif
+};
+
+static u8 __init exchange_bit(u8 val, u8 cs)
+{
+	/* place the data */
+	OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
+	udelay(1);
+
+	/* turn the clock on */
+	OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
+	udelay(1);
+
+	/* turn the clock off and read-strobe */
+	OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
+
+	/* return the data */
+	return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
+}
+
+static void __init get_mac(char dest[6])
+{
+	u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	int i,j;
+
+	for (i = 0; i < 12; i++)
+		exchange_bit(read_opcode[i], 1);
+
+	for (j = 0; j < 6; j++) {
+		dest[j] = 0;
+		for (i = 0; i < 8; i++) {
+			dest[j] <<= 1;
+			dest[j] |= exchange_bit(0, 1);
+		}
+	}
+
+	/* turn off CS */
+	exchange_bit(0,0);
+}
+
+/*
+ * Copy and increment ethernet MAC address by a small value.
+ *
+ * This is useful for systems where the only one MAC address is stored in
+ * non-volatile memory for multiple ports.
+ */
+static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
+	unsigned int add)
+{
+	int i;
+
+	BUG_ON(add >= 256);
+
+	for (i = ETH_ALEN; i >= 0; i--) {
+		dst[i] = src[i] + add;
+		add = dst[i] < src[i];		/* compute carry */
+	}
+
+	WARN_ON(add);
+}
+
+static int __init mv643xx_eth_add_pds(void)
+{
+	unsigned char mac[ETH_ALEN];
+	int ret;
+
+	get_mac(mac);
+#ifdef CONFIG_MV643XX_ETH_0
+	eth_mac_add(eth1_mac_addr, mac, 0);
+#endif
+#ifdef CONFIG_MV643XX_ETH_1
+	eth_mac_add(eth1_mac_addr, mac, 1);
+#endif
+#ifdef CONFIG_MV643XX_ETH_2
+	eth_mac_add(eth2_mac_addr, mac, 2);
+#endif
+	ret = platform_add_devices(mv643xx_eth_pd_devs,
+			ARRAY_SIZE(mv643xx_eth_pd_devs));
+
+	return ret;
+}
+
+device_initcall(mv643xx_eth_add_pds);
+
+#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c
index 296d945..6ce9b7f 100644
--- a/arch/mips/momentum/ocelot_3/prom.c
+++ b/arch/mips/momentum/ocelot_3/prom.c
@@ -34,64 +34,11 @@
 extern unsigned long marvell_base;
 extern unsigned long cpu_clock;
 
-#ifdef CONFIG_MV643XX_ETH
-extern unsigned char prom_mac_addr_base[6];
-#endif
-
 const char *get_system_type(void)
 {
 	return "Momentum Ocelot-3";
 }
 
-#ifdef CONFIG_MV643XX_ETH
-void burn_clocks(void)
-{
-	int i;
-
-	/* this loop should burn at least 1us -- this should be plenty */
-	for (i = 0; i < 0x10000; i++)
-		;
-}
-
-u8 exchange_bit(u8 val, u8 cs)
-{
-	/* place the data */
-	OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
-	burn_clocks();
-
-	/* turn the clock on */
-	OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
-	burn_clocks();
-
-	/* turn the clock off and read-strobe */
-	OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
-
-	/* return the data */
-	return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1);
-}
-
-void get_mac(char dest[6])
-{
-	u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-	int i,j;
-
-	for (i = 0; i < 12; i++)
-		exchange_bit(read_opcode[i], 1);
-
-	for (j = 0; j < 6; j++) {
-		dest[j] = 0;
-		for (i = 0; i < 8; i++) {
-			dest[j] <<= 1;
-			dest[j] |= exchange_bit(0, 1);
-		}
-	}
-
-	/* turn off CS */
-	exchange_bit(0,0);
-}
-#endif
-
-
 #ifdef CONFIG_64BIT
 
 unsigned long signext(unsigned long addr)
@@ -228,11 +175,6 @@
 	mips_machgroup = MACH_GROUP_MOMENCO;
 	mips_machtype = MACH_MOMENCO_OCELOT_3;
 
-#ifdef CONFIG_MV643XX_ETH
-	/* get the base MAC address for on-board ethernet ports */
-	get_mac(prom_mac_addr_base);
-#endif
-
 #ifndef CONFIG_64BIT
 	debug_vectors->printf("Booting Linux kernel...\n");
 #endif
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
index 7d74f8c..ff0829f 100644
--- a/arch/mips/momentum/ocelot_3/setup.c
+++ b/arch/mips/momentum/ocelot_3/setup.c
@@ -4,7 +4,7 @@
  * BRIEF MODULE DESCRIPTION
  * Momentum Computer Ocelot-3 board dependent boot routines
  *
- * Copyright (C) 1996, 1997, 01, 05  Ralf Baechle
+ * Copyright (C) 1996, 1997, 01, 05 - 06  Ralf Baechle
  * Copyright (C) 2000 RidgeRun, Inc.
  * Copyright (C) 2001 Red Hat, Inc.
  * Copyright (C) 2002 Momentum Computer
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile
index 94802b4..d69161a 100644
--- a/arch/mips/momentum/ocelot_c/Makefile
+++ b/arch/mips/momentum/ocelot_c/Makefile
@@ -2,7 +2,7 @@
 # Makefile for Momentum Computer's Ocelot-C and -CS boards.
 #
 
-obj-y	 		+= cpci-irq.o irq.o prom.o reset.o \
+obj-y	 		+= cpci-irq.o irq.o platform.o prom.o reset.o \
 			   setup.o uart-irq.o
 
 obj-$(CONFIG_KGDB)	+= dbg_io.o
diff --git a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h
index 7228cd1..f0f5581 100644
--- a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h
+++ b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h
@@ -53,7 +53,9 @@
 #define OCELOT_C_REG_INTSET		0xe
 #define OCELOT_C_REG_INTCLR		0xf
 
-#define OCELOT_FPGA_WRITE(x, y) writeb(x, OCELOT_C_CS0_ADDR + OCELOT_C_REG_##y)
-#define OCELOT_FPGA_READ(x) readb(OCELOT_C_CS0_ADDR + OCELOT_C_REG_##x)
+#define __FPGA_REG_TO_ADDR(reg)						\
+	((void *) OCELOT_C_CS0_ADDR + OCELOT_C_REG_##reg)
+#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg))
+#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg))
 
 #endif
diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c
new file mode 100644
index 0000000..6c495b2
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/platform.c
@@ -0,0 +1,201 @@
+#include <linux/delay.h>
+#include <linux/if_ether.h>
+#include <linux/ioport.h>
+#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
+
+#include "ocelot_c_fpga.h"
+
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
+
+static struct resource mv643xx_eth_shared_resources[] = {
+	[0] = {
+		.name   = "ethernet shared base",
+		.start  = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
+		.end    = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
+		                       MV643XX_ETH_SHARED_REGS_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device mv643xx_eth_shared_device = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv643xx_eth_shared_resources),
+	.resource	= mv643xx_eth_shared_resources,
+};
+
+#define MV_SRAM_BASE			0xfe000000UL
+#define MV_SRAM_SIZE			(256 * 1024)
+
+#define MV_SRAM_RXRING_SIZE		(MV_SRAM_SIZE / 4)
+#define MV_SRAM_TXRING_SIZE		(MV_SRAM_SIZE / 4)
+
+#define MV_SRAM_BASE_ETH0		MV_SRAM_BASE
+#define MV_SRAM_BASE_ETH1		(MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
+
+#define MV64x60_IRQ_ETH_0 48
+#define MV64x60_IRQ_ETH_1 49
+
+#ifdef CONFIG_MV643XX_ETH_0
+
+static struct resource mv64x60_eth0_resources[] = {
+	[0] = {
+		.name	= "eth0 irq",
+		.start	= MV64x60_IRQ_ETH_0,
+		.end	= MV64x60_IRQ_ETH_0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static char eth0_mac_addr[ETH_ALEN];
+
+static struct mv643xx_eth_platform_data eth0_pd = {
+	.mac_addr	= eth0_mac_addr,
+
+	.tx_sram_addr	= MV_SRAM_BASE_ETH0,
+	.tx_sram_size	= MV_SRAM_TXRING_SIZE,
+	.tx_queue_size	= MV_SRAM_TXRING_SIZE / 16,
+
+	.rx_sram_addr	= MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
+	.rx_sram_size	= MV_SRAM_RXRING_SIZE,
+	.rx_queue_size	= MV_SRAM_RXRING_SIZE / 16,
+};
+
+static struct platform_device eth0_device = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth0_resources),
+	.resource	= mv64x60_eth0_resources,
+	.dev = {
+		.platform_data = &eth0_pd,
+	},
+};
+#endif /* CONFIG_MV643XX_ETH_0 */
+
+#ifdef CONFIG_MV643XX_ETH_1
+
+static struct resource mv64x60_eth1_resources[] = {
+	[0] = {
+		.name	= "eth1 irq",
+		.start	= MV64x60_IRQ_ETH_1,
+		.end	= MV64x60_IRQ_ETH_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static char eth1_mac_addr[ETH_ALEN];
+
+static struct mv643xx_eth_platform_data eth1_pd = {
+	.mac_addr	= eth1_mac_addr,
+
+	.tx_sram_addr	= MV_SRAM_BASE_ETH1,
+	.tx_sram_size	= MV_SRAM_TXRING_SIZE,
+	.tx_queue_size	= MV_SRAM_TXRING_SIZE / 16,
+
+	.rx_sram_addr	= MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
+	.rx_sram_size	= MV_SRAM_RXRING_SIZE,
+	.rx_queue_size	= MV_SRAM_RXRING_SIZE / 16,
+};
+
+static struct platform_device eth1_device = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth1_resources),
+	.resource	= mv64x60_eth1_resources,
+	.dev = {
+		.platform_data = &eth1_pd,
+	},
+};
+#endif /* CONFIG_MV643XX_ETH_1 */
+
+static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
+	&mv643xx_eth_shared_device,
+#ifdef CONFIG_MV643XX_ETH_0
+	&eth0_device,
+#endif
+#ifdef CONFIG_MV643XX_ETH_1
+	&eth1_device,
+#endif
+	/* The third port is not wired up on the Ocelot C */
+};
+
+static u8 __init exchange_bit(u8 val, u8 cs)
+{
+	/* place the data */
+	OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
+	udelay(1);
+
+	/* turn the clock on */
+	OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
+	udelay(1);
+
+	/* turn the clock off and read-strobe */
+	OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
+
+	/* return the data */
+	return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
+}
+
+static void __init get_mac(char dest[6])
+{
+	u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	int i,j;
+
+	for (i = 0; i < 12; i++)
+		exchange_bit(read_opcode[i], 1);
+
+	for (j = 0; j < 6; j++) {
+		dest[j] = 0;
+		for (i = 0; i < 8; i++) {
+			dest[j] <<= 1;
+			dest[j] |= exchange_bit(0, 1);
+		}
+	}
+
+	/* turn off CS */
+	exchange_bit(0,0);
+}
+
+/*
+ * Copy and increment ethernet MAC address by a small value.
+ *
+ * This is useful for systems where the only one MAC address is stored in
+ * non-volatile memory for multiple ports.
+ */
+static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
+	unsigned int add)
+{
+	int i;
+
+	BUG_ON(add >= 256);
+
+	for (i = ETH_ALEN; i >= 0; i--) {
+		dst[i] = src[i] + add;
+		add = dst[i] < src[i];		/* compute carry */
+	}
+
+	WARN_ON(add);
+}
+
+static int __init mv643xx_eth_add_pds(void)
+{
+	unsigned char mac[ETH_ALEN];
+	int ret;
+
+	get_mac(mac);
+#ifdef CONFIG_MV643XX_ETH_0
+	eth_mac_add(eth1_mac_addr, mac, 0);
+#endif
+#ifdef CONFIG_MV643XX_ETH_1
+	eth_mac_add(eth1_mac_addr, mac, 1);
+#endif
+	ret = platform_add_devices(mv643xx_eth_pd_devs,
+			ARRAY_SIZE(mv643xx_eth_pd_devs));
+
+	return ret;
+}
+
+device_initcall(mv643xx_eth_add_pds);
+
+#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c
index 4c50a14..d0b77e1 100644
--- a/arch/mips/momentum/ocelot_c/prom.c
+++ b/arch/mips/momentum/ocelot_c/prom.c
@@ -29,11 +29,7 @@
 struct callvectors* debug_vectors;
 
 extern unsigned long marvell_base;
-extern unsigned long cpu_clock;
-
-#ifdef CONFIG_MV643XX_ETH
-extern unsigned char prom_mac_addr_base[6];
-#endif
+extern unsigned int cpu_clock;
 
 const char *get_system_type(void)
 {
@@ -44,55 +40,6 @@
 #endif
 }
 
-#ifdef CONFIG_MV643XX_ETH
-static void burn_clocks(void)
-{
-	int i;
-
-	/* this loop should burn at least 1us -- this should be plenty */
-	for (i = 0; i < 0x10000; i++)
-		;
-}
-
-static u8 exchange_bit(u8 val, u8 cs)
-{
-	/* place the data */
-	OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
-	burn_clocks();
-
-	/* turn the clock on */
-	OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
-	burn_clocks();
-
-	/* turn the clock off and read-strobe */
-	OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
-
-	/* return the data */
-	return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1);
-}
-
-void get_mac(char dest[6])
-{
-	u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-	int i,j;
-
-	for (i = 0; i < 12; i++)
-		exchange_bit(read_opcode[i], 1);
-
-	for (j = 0; j < 6; j++) {
-		dest[j] = 0;
-		for (i = 0; i < 8; i++) {
-			dest[j] <<= 1;
-			dest[j] |= exchange_bit(0, 1);
-		}
-	}
-
-	/* turn off CS */
-	exchange_bit(0,0);
-}
-#endif
-
-
 #ifdef CONFIG_64BIT
 
 unsigned long signext(unsigned long addr)
@@ -226,11 +173,6 @@
 	mips_machgroup = MACH_GROUP_MOMENCO;
 	mips_machtype = MACH_MOMENCO_OCELOT_C;
 
-#ifdef CONFIG_MV643XX_ETH
-	/* get the base MAC address for on-board ethernet ports */
-	get_mac(prom_mac_addr_base);
-#endif
-
 #ifndef CONFIG_64BIT
 	debug_vectors->printf("Booting Linux kernel...\n");
 #endif
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
index 9c0c462..0b6b233 100644
--- a/arch/mips/momentum/ocelot_c/setup.c
+++ b/arch/mips/momentum/ocelot_c/setup.c
@@ -69,8 +69,7 @@
 #include "ocelot_c_fpga.h"
 
 unsigned long marvell_base;
-extern unsigned long mv64340_sram_base;
-unsigned long cpu_clock;
+unsigned int cpu_clock;
 
 /* These functions are used for rebooting or halting the machine*/
 extern void momenco_ocelot_restart(char *command);
@@ -119,7 +118,6 @@
 	add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M);
 
 	marvell_base = 0xfffffffff4000000;
-	mv64340_sram_base = 0xfffffffffe000000;
 #else
 	/* marvell and extra space */
 	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K);
@@ -129,7 +127,6 @@
 	add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M);
 
 	marvell_base = 0xf4000000;
-	mv64340_sram_base = 0xfe000000;
 #endif
 }
 
@@ -346,22 +343,20 @@
 	}
 }
 
-#ifndef CONFIG_64BIT
-/* This needs to be one of the first initcalls, because no I/O port access
-   can work before this */
+/*
+ * This needs to be one of the first initcalls, because no I/O port access
+ * can work before this
+ */
 static int io_base_ioremap(void)
 {
-	/* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */
-	void *io_remap_range = ioremap(0xc0000000, 0x30000000);
+	void __iomem * io_remap_range = ioremap(0xc0000000UL, 0x10000);
 
-	if (!io_remap_range) {
+	if (!io_remap_range)
 		panic("Could not ioremap I/O port range");
-	}
-	printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range);
-	set_io_port_base(io_remap_range - 0xc0000000);
+
+	set_io_port_base((unsigned long) io_remap_range);
 
 	return 0;
 }
 
 module_init(io_base_ioremap);
-#endif
diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c
index 7b5cc66..e5576bd 100644
--- a/arch/mips/momentum/ocelot_g/gt-irq.c
+++ b/arch/mips/momentum/ocelot_g/gt-irq.c
@@ -27,7 +27,7 @@
  * be handled and ack'ed differently than other MIPS interrupts.
  */
 
-#if CURRENTLY_UNUSED
+#if 0
 
 struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
 void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
@@ -95,7 +95,7 @@
 		return 0;
 	return 1;
 }
-#endif				/*  UNUSED  */
+#endif /* 0 */
 
 /*
  * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#.
@@ -196,7 +196,7 @@
 
 void gt64240_irq_init(void)
 {
-#if CURRENTLY_UNUSED
+#if 0
 	int i, j;
 
 	/* Reset irq handlers pointers to NULL */
@@ -208,5 +208,5 @@
 			irq_handlers[i][j].data = NULL;
 		}
 	}
-#endif
+#endif /* 0 */
 }
diff --git a/arch/mips/momentum/ocelot_g/ocelot_pld.h b/arch/mips/momentum/ocelot_g/ocelot_pld.h
index fcb8275..95e0534 100644
--- a/arch/mips/momentum/ocelot_g/ocelot_pld.h
+++ b/arch/mips/momentum/ocelot_g/ocelot_pld.h
@@ -23,8 +23,8 @@
 #define OCELOT_REG_INTSET (12)
 #define OCELOT_REG_INTCLR (13)
 
-#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y)
-#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x)
-
+#define __PLD_REG_TO_ADDR(reg) ((void *) OCELOT_CS0_ADDR + OCELOT_REG_##reg)
+#define OCELOT_PLD_WRITE(x, reg) writeb(x, __PLD_REG_TO_ADDR(reg))
+#define OCELOT_PLD_READ(reg) readb(__PLD_REG_TO_ADDR(reg))
 
 #endif /* __MOMENCO_OCELOT_PLD_H__ */
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c
index 56ec470..d288f7b 100644
--- a/arch/mips/momentum/ocelot_g/setup.c
+++ b/arch/mips/momentum/ocelot_g/setup.c
@@ -57,6 +57,7 @@
 #include <asm/gt64240.h>
 #include <asm/irq.h>
 #include <asm/pci.h>
+#include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <linux/bootmem.h>
@@ -160,6 +161,10 @@
 	printk("Done\n");
 }
 
+void __init plat_timer_setup(struct irqaction *irq)
+{
+}
+
 void __init plat_mem_setup(void)
 {
 	void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache);
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index dd0aec9..1fb240c 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -31,16 +31,18 @@
 #define M_COUNTER_OVERFLOW		(1UL      << 31)
 
 #ifdef CONFIG_MIPS_MT_SMP
-#define WHAT	(M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id()))
+#define WHAT		(M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id()))
+#define vpe_id()	smp_processor_id()
 #else
-#define WHAT	0
+#define WHAT		0
+#define vpe_id()	smp_processor_id()
 #endif
 
 #define __define_perf_accessors(r, n, np)				\
 									\
 static inline unsigned int r_c0_ ## r ## n(void)			\
 {									\
-	unsigned int cpu = smp_processor_id();				\
+	unsigned int cpu = vpe_id();					\
 									\
 	switch (cpu) {							\
 	case 0:								\
@@ -55,7 +57,7 @@
 									\
 static inline void w_c0_ ## r ## n(unsigned int value)			\
 {									\
-	unsigned int cpu = smp_processor_id();				\
+	unsigned int cpu = vpe_id();					\
 									\
 	switch (cpu) {							\
 	case 0:								\
@@ -218,7 +220,7 @@
 {
 	int counters = __n_counters();
 
-#ifndef CONFIG_SMP
+#ifdef CONFIG_MIPS_MT_SMP
 	if (current_cpu_data.cputype == CPU_34K)
 		return counters >> 1;
 #endif
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 3cf0dd4..70cb55b 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -26,7 +26,7 @@
 obj-$(CONFIG_LASAT)		+= pci-lasat.o
 obj-$(CONFIG_MIPS_ATLAS)	+= fixup-atlas.o
 obj-$(CONFIG_MIPS_COBALT)	+= fixup-cobalt.o
-obj-$(CONFIG_MIPS_EV64120)	+= fixup-ev64120.o
+obj-$(CONFIG_MIPS_EV64120)	+= pci-ev64120.o
 obj-$(CONFIG_SOC_AU1500)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_AU1550)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_PNX8550)	+= fixup-pnx8550.o ops-pnx8550.o
diff --git a/arch/mips/pci/fixup-ev64120.c b/arch/mips/pci/fixup-ev64120.c
deleted file mode 100644
index 8dbb90d..0000000
--- a/arch/mips/pci/fixup-ev64120.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <linux/pci.h>
-#include <linux/init.h>
-
-int pci_range_ck(unsigned char bus, unsigned char dev)
-{
-	if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8))
-		return 0;
-
-	return -1;
-}
-
-/*
- * After detecting all agents over the PCI , this function is called
- * in order to give an interrupt number for each PCI device starting
- * from IRQ 20. It does also enables master for each device.
- */
-void __devinit pcibios_fixup_bus(struct pci_bus *bus)
-{
-	unsigned int irq = 20;
-	struct pci_bus *current_bus = bus;
-	struct pci_dev *dev;
-	struct list_head *devices_link;
-
-	list_for_each(devices_link, &(current_bus->devices)) {
-		dev = pci_dev_b(devices_link);
-		if (dev != NULL) {
-			dev->irq = irq++;
-
-			/* Assign an interrupt number for the device */
-			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-			pcibios_set_master(dev);
-		}
-	}
-}
diff --git a/arch/mips/pci/pci-ev64120.c b/arch/mips/pci/pci-ev64120.c
new file mode 100644
index 0000000..9cd859e
--- /dev/null
+++ b/arch/mips/pci/pci-ev64120.c
@@ -0,0 +1,21 @@
+#include <linux/pci.h>
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq;
+
+	if (!pin)
+		return 0;
+
+	irq = allocate_irqno();
+	if (irq < 0)
+		return 0;
+
+	return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c
index 0af655b..65c440e 100644
--- a/arch/mips/philips/pnx8550/common/time.c
+++ b/arch/mips/philips/pnx8550/common/time.c
@@ -41,8 +41,8 @@
  * 1) board_time_init() -
  * 	a) (optional) set up RTC routines,
  *      b) (optional) calibrate and set the mips_hpt_frequency
- *	    (only needed if you intended to use fixed_rate_gettimeoffset
- *	     or use cpu counter as timer interrupt source)
+ *	    (only needed if you intended to use cpu counter as timer interrupt
+ *	     source)
  */
 
 void pnx8550_time_init(void)
diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
index 416da22..85b14c7 100644
--- a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
+++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
@@ -74,7 +74,7 @@
 int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd,
 		   int size, unsigned int *addr)
 {
-	int loop = 0, bytes, i;
+	int loop, bytes = 0, i;
 	unsigned int *write_data, data, *read_data;
 	unsigned long reg_val, val;
 
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index 65fa3a2..3cc0436 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -3,9 +3,7 @@
 
 #include <asm/pmon.h>
 #include <asm/titan_dep.h>
-
-extern unsigned int (*mips_hpt_read)(void);
-extern void (*mips_hpt_init)(unsigned int);
+#include <asm/time.h>
 
 #define LAUNCHSTACK_SIZE 256
 
@@ -101,7 +99,7 @@
  */
 void prom_init_secondary(void)
 {
-	mips_hpt_init(mips_hpt_read());
+	mips_hpt_init();
 
 	set_c0_status(ST0_CO | ST0_IE | ST0_IM);
 }
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index f01ba1f..270ecd3 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -354,29 +354,6 @@
 	.end		= end_bridge_irq,
 };
 
-static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
-
-int allocate_irqno(void)
-{
-	int irq;
-
-again:
-	irq = find_first_zero_bit(irq_map, NR_IRQS);
-
-	if (irq >= NR_IRQS)
-		return -ENOSPC;
-
-	if (test_and_set_bit(irq, irq_map))
-		goto again;
-
-	return irq;
-}
-
-void free_irqno(unsigned int irq)
-{
-	clear_bit(irq, irq_map);
-}
-
 void __devinit register_bridge_irq(unsigned int irq)
 {
 	irq_desc[irq].status	= IRQ_DISABLED;
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index 4e870fc..5e82a26 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -134,13 +134,6 @@
 	irq_exit();
 }
 
-unsigned long ip27_do_gettimeoffset(void)
-{
-	unsigned long ct_cur1;
-	ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
-	return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
-}
-
 /* Includes for ioc3_init().  */
 #include <asm/sn/types.h>
 #include <asm/sn/sn0/addrs.h>
@@ -221,8 +214,6 @@
 	.name		= "timer"
 };
 
-extern int allocate_irqno(void);
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
 	int irqno  = allocate_irqno();
@@ -248,12 +239,17 @@
 	setup_irq(irqno, &rt_irqaction);
 }
 
+static unsigned int ip27_hpt_read(void)
+{
+	return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
+}
+
 void __init ip27_time_init(void)
 {
+	mips_hpt_read = ip27_hpt_read;
+	mips_hpt_frequency = CYCLES_PER_SEC;
 	xtime.tv_sec = get_m48t35_time();
 	xtime.tv_nsec = 0;
-
-	do_gettimeoffset = ip27_do_gettimeoffset;
 }
 
 void __init cpu_time_init(void)
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
index bf12af4..e136bde 100644
--- a/arch/mips/sibyte/bcm1480/time.c
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -47,6 +47,12 @@
 #define IMR_IP3_VAL	K_BCM1480_INT_MAP_I1
 #define IMR_IP4_VAL	K_BCM1480_INT_MAP_I2
 
+#ifdef CONFIG_SIMULATION
+#define BCM1480_HPT_VALUE	50000
+#else
+#define BCM1480_HPT_VALUE	1000000
+#endif
+
 extern int bcm1480_steal_irq(int irq);
 
 void bcm1480_time_init(void)
@@ -59,11 +65,6 @@
 		BUG();
 	}
 
-	if (!cpu) {
-		/* Use our own gettimeoffset() routine */
-		do_gettimeoffset = bcm1480_gettimeoffset;
-	}
-
 	bcm1480_mask_irq(cpu, irq);
 
 	/* Map the timer interrupt to ip[4] of this cpu */
@@ -74,11 +75,7 @@
 	/* Disable the timer and set up the count */
 	__raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
 	__raw_writeq(
-#ifndef CONFIG_SIMULATION
-		1000000/HZ
-#else
-		50000/HZ
-#endif
+		BCM1480_HPT_VALUE/HZ
 		, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
 
 	/* Set the timer running */
@@ -122,16 +119,16 @@
 	}
 }
 
-/*
- * We use our own do_gettimeoffset() instead of the generic one,
- * because the generic one does not work for SMP case.
- * In addition, since we use general timer 0 for system time,
- * we can get accurate intra-jiffy offset without calibration.
- */
-unsigned long bcm1480_gettimeoffset(void)
+static unsigned int bcm1480_hpt_read(void)
 {
+	/* We assume this function is called xtime_lock held. */
 	unsigned long count =
 		__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+	return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count;
+}
 
-	return 1000000/HZ - count;
+void __init bcm1480_hpt_setup(void)
+{
+	mips_hpt_read = bcm1480_hpt_read;
+	mips_hpt_frequency = BCM1480_HPT_VALUE;
 }
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index 0ccf179..bcb74f2 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -47,15 +47,11 @@
 
 #define SB1250_HPT_NUM		3
 #define SB1250_HPT_VALUE	M_SCD_TIMER_CNT /* max value */
-#define SB1250_HPT_SHIFT	((sizeof(unsigned int)*8)-V_SCD_TIMER_WIDTH)
 
 
 extern int sb1250_steal_irq(int irq);
 
 static unsigned int sb1250_hpt_read(void);
-static void sb1250_hpt_init(unsigned int);
-
-static unsigned int hpt_offset;
 
 void __init sb1250_hpt_setup(void)
 {
@@ -69,13 +65,9 @@
 		__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
 			     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
 
-		/*
-		 * we need to fill 32 bits, so just use the upper 23 bits and pretend
-		 * the timer is going 512Mhz instead of 1Mhz
-		 */
-		mips_hpt_frequency = V_SCD_TIMER_FREQ << SB1250_HPT_SHIFT;
-		mips_hpt_init = sb1250_hpt_init;
+		mips_hpt_frequency = V_SCD_TIMER_FREQ;
 		mips_hpt_read = sb1250_hpt_read;
+		mips_hpt_mask = M_SCD_TIMER_INIT;
 	}
 }
 
@@ -149,11 +141,7 @@
 
 /*
  * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
- * again. There's no easy way to set to a specific value so store init value
- * in hpt_offset and subtract each time.
- *
- * Note: Timer isn't full 32bits so shift it into the upper part making
- *       it appear to run at a higher frequency.
+ * again.
  */
 static unsigned int sb1250_hpt_read(void)
 {
@@ -161,13 +149,5 @@
 
 	count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT))));
 
-	count = (SB1250_HPT_VALUE - count) << SB1250_HPT_SHIFT;
-
-	return count - hpt_offset;
-}
-
-static void sb1250_hpt_init(unsigned int count)
-{
-	hpt_offset = count;
-	return;
+	return SB1250_HPT_VALUE - count;
 }
diff --git a/arch/mips/tx4927/common/smsc_fdc37m81x.c b/arch/mips/tx4927/common/smsc_fdc37m81x.c
new file mode 100644
index 0000000..33f517b
--- /dev/null
+++ b/arch/mips/tx4927/common/smsc_fdc37m81x.c
@@ -0,0 +1,172 @@
+/*
+ * Interface for smsc fdc48m81x Super IO chip
+ *
+ * Author: MontaVista Software, Inc. source@mvista.com
+ *
+ * 2001-2003 (c) MontaVista Software, Inc. 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.
+ *
+ * Copyright 2004 (c) MontaVista Software, Inc.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/tx4927/smsc_fdc37m81x.h>
+
+#define DEBUG
+
+/* Common Registers */
+#define SMSC_FDC37M81X_CONFIG_INDEX  0x00
+#define SMSC_FDC37M81X_CONFIG_DATA   0x01
+#define SMSC_FDC37M81X_CONF          0x02
+#define SMSC_FDC37M81X_INDEX         0x03
+#define SMSC_FDC37M81X_DNUM          0x07
+#define SMSC_FDC37M81X_DID           0x20
+#define SMSC_FDC37M81X_DREV          0x21
+#define SMSC_FDC37M81X_PCNT          0x22
+#define SMSC_FDC37M81X_PMGT          0x23
+#define SMSC_FDC37M81X_OSC           0x24
+#define SMSC_FDC37M81X_CONFPA0       0x26
+#define SMSC_FDC37M81X_CONFPA1       0x27
+#define SMSC_FDC37M81X_TEST4         0x2B
+#define SMSC_FDC37M81X_TEST5         0x2C
+#define SMSC_FDC37M81X_TEST1         0x2D
+#define SMSC_FDC37M81X_TEST2         0x2E
+#define SMSC_FDC37M81X_TEST3         0x2F
+
+/* Logical device numbers */
+#define SMSC_FDC37M81X_FDD           0x00
+#define SMSC_FDC37M81X_SERIAL1       0x04
+#define SMSC_FDC37M81X_SERIAL2       0x05
+#define SMSC_FDC37M81X_KBD           0x07
+
+/* Logical device Config Registers */
+#define SMSC_FDC37M81X_ACTIVE        0x30
+#define SMSC_FDC37M81X_BASEADDR0     0x60
+#define SMSC_FDC37M81X_BASEADDR1     0x61
+#define SMSC_FDC37M81X_INT           0x70
+#define SMSC_FDC37M81X_INT2          0x72
+#define SMSC_FDC37M81X_MODE          0xF0
+
+/* Chip Config Values */
+#define SMSC_FDC37M81X_CONFIG_ENTER  0x55
+#define SMSC_FDC37M81X_CONFIG_EXIT   0xaa
+#define SMSC_FDC37M81X_CHIP_ID       0x4d
+
+static unsigned long g_smsc_fdc37m81x_base = 0;
+
+static inline unsigned char smsc_fdc37m81x_rd(unsigned char index)
+{
+	outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+
+	return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
+}
+
+static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data)
+{
+	outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+	outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
+}
+
+void smsc_fdc37m81x_config_beg(void)
+{
+	if (g_smsc_fdc37m81x_base) {
+		outb(SMSC_FDC37M81X_CONFIG_ENTER,
+		     g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+	}
+}
+
+void smsc_fdc37m81x_config_end(void)
+{
+	if (g_smsc_fdc37m81x_base)
+		outb(SMSC_FDC37M81X_CONFIG_EXIT,
+		     g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+}
+
+u8 smsc_fdc37m81x_config_get(u8 reg)
+{
+	u8 val = 0;
+
+	if (g_smsc_fdc37m81x_base)
+		val = smsc_fdc37m81x_rd(reg);
+
+	return val;
+}
+
+void smsc_fdc37m81x_config_set(u8 reg, u8 val)
+{
+	if (g_smsc_fdc37m81x_base)
+		smsc_dc37m81x_wr(reg, val);
+}
+
+unsigned long __init smsc_fdc37m81x_init(unsigned long port)
+{
+	const int field = sizeof(unsigned long) * 2;
+	u8 chip_id;
+
+	if (g_smsc_fdc37m81x_base)
+		printk("smsc_fdc37m81x_init() stepping on old base=0x%0*lx\n",
+		       field, g_smsc_fdc37m81x_base);
+
+	g_smsc_fdc37m81x_base = port;
+
+	smsc_fdc37m81x_config_beg();
+
+	chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID);
+	if (chip_id == SMSC_FDC37M81X_CHIP_ID)
+		smsc_fdc37m81x_config_end();
+	else {
+		printk("smsc_fdc37m81x_init() unknow chip id 0x%02x\n",
+		       chip_id);
+		g_smsc_fdc37m81x_base = 0;
+	}
+
+	return g_smsc_fdc37m81x_base;
+}
+
+#ifdef DEBUG
+void smsc_fdc37m81x_config_dump_one(char *key, u8 dev, u8 reg)
+{
+	printk("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg,
+	       smsc_fdc37m81x_rd(reg));
+}
+
+void smsc_fdc37m81x_config_dump(void)
+{
+	u8 orig;
+	char *fname = "smsc_fdc37m81x_config_dump()";
+
+	smsc_fdc37m81x_config_beg();
+
+	orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM);
+
+	printk("%s: common\n", fname);
+	smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+				       SMSC_FDC37M81X_DNUM);
+	smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+				       SMSC_FDC37M81X_DID);
+	smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+				       SMSC_FDC37M81X_DREV);
+	smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+				       SMSC_FDC37M81X_PCNT);
+	smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+				       SMSC_FDC37M81X_PMGT);
+
+	printk("%s: keyboard\n", fname);
+	smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD);
+	smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+				       SMSC_FDC37M81X_ACTIVE);
+	smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+				       SMSC_FDC37M81X_INT);
+	smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+				       SMSC_FDC37M81X_INT2);
+	smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+				       SMSC_FDC37M81X_LDCR_F0);
+
+	smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig);
+
+	smsc_fdc37m81x_config_end();
+}
+#endif
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
index 4658b2a..941c441 100644
--- a/arch/mips/tx4927/common/tx4927_setup.c
+++ b/arch/mips/tx4927/common/tx4927_setup.c
@@ -112,8 +112,6 @@
 	return;
 }
 
-indent: Standard input:25: Error:Unexpected end of file
-
 void
 dump_cp0(char *key)
 {
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
index b926e6a..08b20cd 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
@@ -36,14 +36,18 @@
 
 static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
 
-static void txx9_spi_interrupt(int irq, void *dev_id)
+static irqreturn_t txx9_spi_interrupt(int irq, void *dev_id)
 {
 	/* disable rx intr */
 	tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
 	wake_up(&txx9_spi_wait);
+
+	return IRQ_HANDLED;
 }
+
 static struct irqaction txx9_spi_action = {
-	txx9_spi_interrupt, 0, 0, "spi", NULL, NULL,
+	.handler	= txx9_spi_interrupt,
+	.name		= "spi",
 };
 
 void __init txx9_spi_irqinit(int irc_irq)
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index b3677fc..7b943b4 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -153,13 +153,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 8b69104..0673dbe 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -740,7 +740,7 @@
 
 config ARCH_SPARSEMEM_DEFAULT
 	def_bool y
-	depends on SMP && PPC_PSERIES
+	depends on (SMP && PPC_PSERIES) || PPC_CELL
 
 config ARCH_POPULATES_NODE_MAP
 	def_bool y
@@ -751,6 +751,15 @@
 	def_bool y
 	depends on MEMORY_HOTPLUG
 
+# Some NUMA nodes have memory ranges that span
+# other nodes.  Even though a pfn is valid and
+# between a node's start and end pfns, it may not
+# reside on that node.  See memmap_init_zone()
+# for details.
+config NODES_SPAN_OTHER_NODES
+	def_bool y
+	depends on NEED_MULTIPLE_NODES
+
 config PPC_64K_PAGES
 	bool "64k page size"
 	depends on PPC64
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 37ddfca..4b2be61 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -115,7 +115,7 @@
 quiet_cmd_wrap	= WRAP    $@
       cmd_wrap	=$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux
 quiet_cmd_wrap_initrd = WRAP    $@
-      cmd_wrap_initrd =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
+      cmd_wrap_initrd =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
 				-i $(obj)/ramdisk.image.gz vmlinux
 
 $(obj)/zImage.chrp: vmlinux $(wrapperbits)
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index eab7318..b5fb1fe 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -179,11 +179,11 @@
 fi
 
 if [ -n "$initrd" ]; then
-    addsec $tmp "$initrd" initrd
+    addsec $tmp "$initrd" $isection
 fi
 
 if [ -n "$dtb" ]; then
-    addsec $tmp "$dtb" dtb
+    addsec $tmp "$dtb" .kernel:dtb
 fi
 
 if [ "$platform" != "miboot" ]; then
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S
index 4b6bb3f..4be3c64 100644
--- a/arch/powerpc/boot/zImage.lds.S
+++ b/arch/powerpc/boot/zImage.lds.S
@@ -21,6 +21,11 @@
     __got2_end = .;
   }
 
+  . = ALIGN(8);
+  _dtb_start = .;
+  .kernel:dtb : { *(.kernel:dtb) }
+  _dtb_end = .;
+
   . = ALIGN(4096);
   _vmlinux_start =  .;
   .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index 892d5dd..0aba06d 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -254,6 +254,7 @@
 CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -275,7 +276,9 @@
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=y
 CONFIG_INET6_XFRM_MODE_TUNNEL=y
+# CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
 CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -406,6 +409,12 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -738,7 +747,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -802,6 +810,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -810,14 +819,9 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -923,6 +927,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -930,6 +935,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1129,6 +1135,7 @@
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 9828663..d2833c1 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -184,6 +184,7 @@
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
 # CONFIG_PPC_64K_PAGES is not set
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 8b133af..7af23c4 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -38,7 +38,6 @@
 obj-$(CONFIG_TAU)		+= tau_6xx.o
 obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
 obj32-$(CONFIG_MODULES)		+= module_32.o
-obj-$(CONFIG_E500)		+= perfmon_fsl_booke.o
 
 ifeq ($(CONFIG_PPC_MERGE),y)
 
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index 995fcef..93f21aa 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -182,7 +182,7 @@
 	prop = get_property(np, "linux,bootx-linebytes", NULL);
 	if (prop == NULL)
 		prop = get_property(np, "linebytes", NULL);
-	if (prop)
+	if (prop && *prop != 0xffffffffu)
 		pitch = *prop;
 	if (pitch == 1)
 		pitch = 0x1000;
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 95382f9..bfd499e 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -18,6 +18,7 @@
 
 #include <asm/oprofile_impl.h>
 #include <asm/cputable.h>
+#include <asm/prom.h>		/* for PTRRELOC on ARCH=ppc */
 
 struct cpu_spec* cur_cpu_spec = NULL;
 EXPORT_SYMBOL(cur_cpu_spec);
@@ -73,7 +74,7 @@
 #define PPC_FEATURE_SPE_COMP	0
 #endif
 
-struct cpu_spec	cpu_specs[] = {
+static struct cpu_spec cpu_specs[] = {
 #ifdef CONFIG_PPC64
 	{	/* Power3 */
 		.pvr_mask		= 0xffff0000,
@@ -227,6 +228,21 @@
 		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.platform		= "ppc970",
 	},
+	{	/* PPC970GX */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00450000,
+		.cpu_name		= "PPC970GX",
+		.cpu_features		= CPU_FTRS_PPC970,
+		.cpu_user_features	= COMMON_USER_POWER4 |
+			PPC_FEATURE_HAS_ALTIVEC_COMP,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.num_pmcs		= 8,
+		.cpu_setup		= __setup_cpu_ppc970,
+		.oprofile_cpu_type	= "ppc64/970",
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.platform		= "ppc970",
+	},
 	{	/* Power5 GR */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x003a0000,
@@ -1152,3 +1168,71 @@
 #endif /* !CLASSIC_PPC */
 #endif /* CONFIG_PPC32 */
 };
+
+struct cpu_spec *identify_cpu(unsigned long offset)
+{
+	struct cpu_spec *s = cpu_specs;
+	struct cpu_spec **cur = &cur_cpu_spec;
+	unsigned int pvr = mfspr(SPRN_PVR);
+	int i;
+
+	s = PTRRELOC(s);
+	cur = PTRRELOC(cur);
+
+	if (*cur != NULL)
+		return PTRRELOC(*cur);
+
+	for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
+		if ((pvr & s->pvr_mask) == s->pvr_value) {
+			*cur = cpu_specs + i;
+#ifdef CONFIG_PPC64
+			/* ppc64 expects identify_cpu to also call setup_cpu
+			 * for that processor. I will consolidate that at a
+			 * later time, for now, just use our friend #ifdef.
+			 * we also don't need to PTRRELOC the function pointer
+			 * on ppc64 as we are running at 0 in real mode.
+			 */
+			if (s->cpu_setup) {
+				s->cpu_setup(offset, s);
+			}
+#endif /* CONFIG_PPC64 */
+			return s;
+		}
+	BUG();
+	return NULL;
+}
+
+void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
+{
+	struct fixup_entry {
+		unsigned long	mask;
+		unsigned long	value;
+		long		start_off;
+		long		end_off;
+	} *fcur, *fend;
+
+	fcur = fixup_start;
+	fend = fixup_end;
+
+	for (; fcur < fend; fcur++) {
+		unsigned int *pstart, *pend, *p;
+
+		if ((value & fcur->mask) == fcur->value)
+			continue;
+
+		/* These PTRRELOCs will disappear once the new scheme for
+		 * modules and vdso is implemented
+		 */
+		pstart = ((unsigned int *)fcur) + (fcur->start_off / 4);
+		pend = ((unsigned int *)fcur) + (fcur->end_off / 4);
+
+		for (p = pstart; p < pend; p++) {
+			*p = 0x60000000u;
+			asm volatile ("dcbst 0, %0" : : "r" (p));
+		}
+		asm volatile ("sync" : : : "memory");
+		for (p = pstart; p < pend; p++)
+			asm volatile ("icbi 0,%0" : : "r" (p));
+		asm volatile ("sync; isync" : : : "memory");
+	}
+}
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 645c7f1..e720729 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -487,7 +487,7 @@
 	rlwimi	r13,r12,16,0x20
 	mfcr	r12
 	cmpwi	r13,0x2c
-	beq	.do_stab_bolted_pSeries
+	beq	do_stab_bolted_pSeries
 	mtcrf	0x80,r12
 	mfspr	r12,SPRN_SPRG2
 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
@@ -600,7 +600,7 @@
 	STD_EXCEPTION_PSERIES(., performance_monitor)
 
 	.align	7
-_GLOBAL(do_stab_bolted_pSeries)
+do_stab_bolted_pSeries:
 	mtcrf	0x80,r12
 	mfspr	r12,SPRN_SPRG2
 	EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
@@ -1046,7 +1046,7 @@
 	li	r5,0
 	std	r4,_DAR(r1)
 	std	r5,_DSISR(r1)
-	b	.handle_page_fault
+	b	handle_page_fault
 
 unrecov_user_slb:
 	EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
@@ -1174,12 +1174,13 @@
 	.globl fp_unavailable_common
 fp_unavailable_common:
 	EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
-	bne	.load_up_fpu		/* if from user, just load it up */
+	bne	1f			/* if from user, just load it up */
 	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	ENABLE_INTS
 	bl	.kernel_fp_unavailable_exception
 	BUG_OPCODE
+1:	b	.load_up_fpu
 
 	.align	7
 	.globl altivec_unavailable_common
@@ -1279,10 +1280,10 @@
 	std	r4,_DSISR(r1)
 
 	andis.	r0,r4,0xa450		/* weird error? */
-	bne-	.handle_page_fault	/* if not, try to insert a HPTE */
+	bne-	handle_page_fault	/* if not, try to insert a HPTE */
 BEGIN_FTR_SECTION
 	andis.	r0,r4,0x0020		/* Is it a segment table fault? */
-	bne-	.do_ste_alloc		/* If so handle it */
+	bne-	do_ste_alloc		/* If so handle it */
 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 
 	/*
@@ -1324,7 +1325,7 @@
 	 * because ret_from_except_lite will check for and handle pending
 	 * interrupts if necessary.
 	 */
-	beq	.ret_from_except_lite
+	beq	13f
 	/* For a hash failure, we don't bother re-enabling interrupts */
 	ble-	12f
 
@@ -1346,14 +1347,14 @@
 END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 
 /* Here we have a page fault that hash_page can't handle. */
-_GLOBAL(handle_page_fault)
+handle_page_fault:
 	ENABLE_INTS
 11:	ld	r4,_DAR(r1)
 	ld	r5,_DSISR(r1)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_page_fault
 	cmpdi	r3,0
-	beq+	.ret_from_except_lite
+	beq+	13f
 	bl	.save_nvgprs
 	mr	r5,r3
 	addi	r3,r1,STACK_FRAME_OVERHEAD
@@ -1370,12 +1371,14 @@
 	bl	.low_hash_fault
 	b	.ret_from_except
 
+13:	b	.ret_from_except_lite
+
 	/* here we have a segment miss */
-_GLOBAL(do_ste_alloc)
+do_ste_alloc:
 	bl	.ste_allocate		/* try to insert stab entry */
 	cmpdi	r3,0
-	beq+	fast_exception_return
-	b	.handle_page_fault
+	bne-	handle_page_fault
+	b	fast_exception_return
 
 /*
  * r13 points to the PACA, r9 contains the saved CR,
@@ -1580,11 +1583,6 @@
 	li	r0,0
 	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
 
-	LOAD_REG_IMMEDIATE(r3,cpu_specs)
-	LOAD_REG_IMMEDIATE(r4,cur_cpu_spec)
-	li	r5,0
-	bl	.identify_cpu
-
 	LOAD_REG_IMMEDIATE(r2,__toc_start)
 	addi	r2,r2,0x4000
 	addi	r2,r2,0x4000
@@ -1646,6 +1644,8 @@
 	cmpwi	r0,0x3c		/* 970FX */
 	beq	1f
 	cmpwi	r0,0x44		/* 970MP */
+	beq	1f
+	cmpwi	r0,0x45		/* 970GX */
 	bne	2f
 1:	bl	.__cpu_preinit_ppc970
 2:
@@ -1964,13 +1964,6 @@
 	addi	r2,r2,0x4000
 	add	r2,r2,r26
 
-	LOAD_REG_IMMEDIATE(r3, cpu_specs)
-	add	r3,r3,r26
-	LOAD_REG_IMMEDIATE(r4,cur_cpu_spec)
-	add	r4,r4,r26
-	mr	r5,r26
-	bl	.identify_cpu
-
 	/* Do very early kernel initializations, including initial hash table,
 	 * stab and slb setup before we turn on relocation.	*/
 
@@ -2000,13 +1993,6 @@
 	li	r0,0
 	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
 
-	/* Apply the CPUs-specific fixups (nop out sections not relevant
-	 * to this CPU
-	 */
-	li	r3,0
-	bl	.do_cpu_ftr_fixups
-	bl	.do_fw_ftr_fixups
-
 	/* ptr to current */
 	LOAD_REG_IMMEDIATE(r4, init_task)
 	std	r4,PACACURRENT(r13)
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index f88a2a6..ba6b725 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -47,6 +47,17 @@
 static int novmerge = 1;
 #endif
 
+static inline unsigned long iommu_num_pages(unsigned long vaddr,
+					    unsigned long slen)
+{
+	unsigned long npages;
+
+	npages = IOMMU_PAGE_ALIGN(vaddr + slen) - (vaddr & IOMMU_PAGE_MASK);
+	npages >>= IOMMU_PAGE_SHIFT;
+
+	return npages;
+}
+
 static int __init setup_iommu(char *str)
 {
 	if (!strcmp(str, "novmerge"))
@@ -178,10 +189,10 @@
 	}
 
 	entry += tbl->it_offset;	/* Offset into real TCE table */
-	ret = entry << PAGE_SHIFT;	/* Set the return dma address */
+	ret = entry << IOMMU_PAGE_SHIFT;	/* Set the return dma address */
 
 	/* Put the TCEs in the HW table */
-	ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & PAGE_MASK,
+	ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & IOMMU_PAGE_MASK,
 			 direction);
 
 
@@ -203,7 +214,7 @@
 	unsigned long entry, free_entry;
 	unsigned long i;
 
-	entry = dma_addr >> PAGE_SHIFT;
+	entry = dma_addr >> IOMMU_PAGE_SHIFT;
 	free_entry = entry - tbl->it_offset;
 
 	if (((free_entry + npages) > tbl->it_size) ||
@@ -270,7 +281,7 @@
 	/* Init first segment length for backout at failure */
 	outs->dma_length = 0;
 
-	DBG("mapping %d elements:\n", nelems);
+	DBG("sg mapping %d elements:\n", nelems);
 
 	spin_lock_irqsave(&(tbl->it_lock), flags);
 
@@ -285,9 +296,8 @@
 		}
 		/* Allocate iommu entries for that segment */
 		vaddr = (unsigned long)page_address(s->page) + s->offset;
-		npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK);
-		npages >>= PAGE_SHIFT;
-		entry = iommu_range_alloc(tbl, npages, &handle, mask >> PAGE_SHIFT, 0);
+		npages = iommu_num_pages(vaddr, slen);
+		entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
 
 		DBG("  - vaddr: %lx, size: %lx\n", vaddr, slen);
 
@@ -301,14 +311,14 @@
 
 		/* Convert entry to a dma_addr_t */
 		entry += tbl->it_offset;
-		dma_addr = entry << PAGE_SHIFT;
-		dma_addr |= s->offset;
+		dma_addr = entry << IOMMU_PAGE_SHIFT;
+		dma_addr |= (s->offset & ~IOMMU_PAGE_MASK);
 
-		DBG("  - %lx pages, entry: %lx, dma_addr: %lx\n",
+		DBG("  - %lu pages, entry: %lx, dma_addr: %lx\n",
 			    npages, entry, dma_addr);
 
 		/* Insert into HW table */
-		ppc_md.tce_build(tbl, entry, npages, vaddr & PAGE_MASK, direction);
+		ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK, direction);
 
 		/* If we are in an open segment, try merging */
 		if (segstart != s) {
@@ -323,7 +333,7 @@
 				DBG("    can't merge, new segment.\n");
 			} else {
 				outs->dma_length += s->length;
-				DBG("    merged, new len: %lx\n", outs->dma_length);
+				DBG("    merged, new len: %ux\n", outs->dma_length);
 			}
 		}
 
@@ -367,9 +377,8 @@
 		if (s->dma_length != 0) {
 			unsigned long vaddr, npages;
 
-			vaddr = s->dma_address & PAGE_MASK;
-			npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr)
-				>> PAGE_SHIFT;
+			vaddr = s->dma_address & IOMMU_PAGE_MASK;
+			npages = iommu_num_pages(s->dma_address, s->dma_length);
 			__iommu_free(tbl, vaddr, npages);
 			s->dma_address = DMA_ERROR_CODE;
 			s->dma_length = 0;
@@ -398,8 +407,7 @@
 
 		if (sglist->dma_length == 0)
 			break;
-		npages = (PAGE_ALIGN(dma_handle + sglist->dma_length)
-			  - (dma_handle & PAGE_MASK)) >> PAGE_SHIFT;
+		npages = iommu_num_pages(dma_handle,sglist->dma_length);
 		__iommu_free(tbl, dma_handle, npages);
 		sglist++;
 	}
@@ -532,12 +540,11 @@
 	BUG_ON(direction == DMA_NONE);
 
 	uaddr = (unsigned long)vaddr;
-	npages = PAGE_ALIGN(uaddr + size) - (uaddr & PAGE_MASK);
-	npages >>= PAGE_SHIFT;
+	npages = iommu_num_pages(uaddr, size);
 
 	if (tbl) {
 		dma_handle = iommu_alloc(tbl, vaddr, npages, direction,
-					 mask >> PAGE_SHIFT, 0);
+					 mask >> IOMMU_PAGE_SHIFT, 0);
 		if (dma_handle == DMA_ERROR_CODE) {
 			if (printk_ratelimit())  {
 				printk(KERN_INFO "iommu_alloc failed, "
@@ -545,7 +552,7 @@
 						tbl, vaddr, npages);
 			}
 		} else
-			dma_handle |= (uaddr & ~PAGE_MASK);
+			dma_handle |= (uaddr & ~IOMMU_PAGE_MASK);
 	}
 
 	return dma_handle;
@@ -554,11 +561,14 @@
 void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
 		size_t size, enum dma_data_direction direction)
 {
+	unsigned int npages;
+
 	BUG_ON(direction == DMA_NONE);
 
-	if (tbl)
-		iommu_free(tbl, dma_handle, (PAGE_ALIGN(dma_handle + size) -
-					(dma_handle & PAGE_MASK)) >> PAGE_SHIFT);
+	if (tbl) {
+		npages = iommu_num_pages(dma_handle, size);
+		iommu_free(tbl, dma_handle, npages);
+	}
 }
 
 /* Allocates a contiguous real buffer and creates mappings over it.
@@ -570,11 +580,11 @@
 {
 	void *ret = NULL;
 	dma_addr_t mapping;
-	unsigned int npages, order;
+	unsigned int order;
+	unsigned int nio_pages, io_order;
 	struct page *page;
 
 	size = PAGE_ALIGN(size);
-	npages = size >> PAGE_SHIFT;
 	order = get_order(size);
 
  	/*
@@ -598,8 +608,10 @@
 	memset(ret, 0, size);
 
 	/* Set up tces to cover the allocated range */
-	mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL,
-			      mask >> PAGE_SHIFT, order);
+	nio_pages = size >> IOMMU_PAGE_SHIFT;
+	io_order = get_iommu_order(size);
+	mapping = iommu_alloc(tbl, ret, nio_pages, DMA_BIDIRECTIONAL,
+			      mask >> IOMMU_PAGE_SHIFT, io_order);
 	if (mapping == DMA_ERROR_CODE) {
 		free_pages((unsigned long)ret, order);
 		return NULL;
@@ -611,12 +623,13 @@
 void iommu_free_coherent(struct iommu_table *tbl, size_t size,
 			 void *vaddr, dma_addr_t dma_handle)
 {
-	unsigned int npages;
-
 	if (tbl) {
+		unsigned int nio_pages;
+
 		size = PAGE_ALIGN(size);
-		npages = size >> PAGE_SHIFT;
-		iommu_free(tbl, dma_handle, npages);
+		nio_pages = size >> IOMMU_PAGE_SHIFT;
+		iommu_free(tbl, dma_handle, nio_pages);
+		size = PAGE_ALIGN(size);
 		free_pages((unsigned long)vaddr, get_order(size));
 	}
 }
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 88fd73f..412bea3 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -102,80 +102,6 @@
 	blr
 
 /*
- * identify_cpu,
- * called with r3 = data offset and r4 = CPU number
- * doesn't change r3
- */
-_GLOBAL(identify_cpu)
-	addis	r8,r3,cpu_specs@ha
-	addi	r8,r8,cpu_specs@l
-	mfpvr	r7
-1:
-	lwz	r5,CPU_SPEC_PVR_MASK(r8)
-	and	r5,r5,r7
-	lwz	r6,CPU_SPEC_PVR_VALUE(r8)
-	cmplw	0,r6,r5
-	beq	1f
-	addi	r8,r8,CPU_SPEC_ENTRY_SIZE
-	b	1b
-1:
-	addis	r6,r3,cur_cpu_spec@ha
-	addi	r6,r6,cur_cpu_spec@l
-	sub	r8,r8,r3
-	stw	r8,0(r6)
-	blr
-
-/*
- * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
- * and writes nop's over sections of code that don't apply for this cpu.
- * r3 = data offset (not changed)
- */
-_GLOBAL(do_cpu_ftr_fixups)
-	/* Get CPU 0 features */
-	addis	r6,r3,cur_cpu_spec@ha
-	addi	r6,r6,cur_cpu_spec@l
-	lwz	r4,0(r6)
-	add	r4,r4,r3
-	lwz	r4,CPU_SPEC_FEATURES(r4)
-
-	/* Get the fixup table */
-	addis	r6,r3,__start___ftr_fixup@ha
-	addi	r6,r6,__start___ftr_fixup@l
-	addis	r7,r3,__stop___ftr_fixup@ha
-	addi	r7,r7,__stop___ftr_fixup@l
-
-	/* Do the fixup */
-1:	cmplw	0,r6,r7
-	bgelr
-	addi	r6,r6,16
-	lwz	r8,-16(r6)	/* mask */
-	and	r8,r8,r4
-	lwz	r9,-12(r6)	/* value */
-	cmplw	0,r8,r9
-	beq	1b
-	lwz	r8,-8(r6)	/* section begin */
-	lwz	r9,-4(r6)	/* section end */
-	subf.	r9,r8,r9
-	beq	1b
-	/* write nops over the section of code */
-	/* todo: if large section, add a branch at the start of it */
-	srwi	r9,r9,2
-	mtctr	r9
-	add	r8,r8,r3
-	lis	r0,0x60000000@h	/* nop */
-3:	stw	r0,0(r8)
-	andi.	r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
-	beq	2f
-	dcbst	0,r8		/* suboptimal, but simpler */
-	sync
-	icbi	0,r8
-2:	addi	r8,r8,4
-	bdnz	3b
-	sync			/* additional sync needed on g4 */
-	isync
-	b	1b
-
-/*
  * call_setup_cpu - call the setup_cpu function for this cpu
  * r3 = data offset, r24 = cpu number
  *
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index c70e207..21fd2c6 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -246,130 +246,6 @@
 	isync
 	blr
 
-/*
- * identify_cpu and calls setup_cpu
- * In:	r3 = base of the cpu_specs array
- *	r4 = address of cur_cpu_spec
- *	r5 = relocation offset
- */
-_GLOBAL(identify_cpu)
-	mfpvr	r7
-1:
-	lwz	r8,CPU_SPEC_PVR_MASK(r3)
-	and	r8,r8,r7
-	lwz	r9,CPU_SPEC_PVR_VALUE(r3)
-	cmplw	0,r9,r8
-	beq	1f
-	addi	r3,r3,CPU_SPEC_ENTRY_SIZE
-	b	1b
-1:
-	sub	r0,r3,r5
-	std	r0,0(r4)
-	ld	r4,CPU_SPEC_SETUP(r3)
-	cmpdi	0,r4,0
-	add	r4,r4,r5
-	beqlr
-	ld	r4,0(r4)
-	add	r4,r4,r5
-	mtctr	r4
-	/* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */
-	mr	r4,r3
-	mr	r3,r5
-	bctr
-
-/*
- * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
- * and writes nop's over sections of code that don't apply for this cpu.
- * r3 = data offset (not changed)
- */
-_GLOBAL(do_cpu_ftr_fixups)
-	/* Get CPU 0 features */
-	LOAD_REG_IMMEDIATE(r6,cur_cpu_spec)
-	sub	r6,r6,r3
-	ld	r4,0(r6)
-	sub	r4,r4,r3
-	ld	r4,CPU_SPEC_FEATURES(r4)
-	/* Get the fixup table */
-	LOAD_REG_IMMEDIATE(r6,__start___ftr_fixup)
-	sub	r6,r6,r3
-	LOAD_REG_IMMEDIATE(r7,__stop___ftr_fixup)
-	sub	r7,r7,r3
-	/* Do the fixup */
-1:	cmpld	r6,r7
-	bgelr
-	addi	r6,r6,32
-	ld	r8,-32(r6)	/* mask */
-	and	r8,r8,r4
-	ld	r9,-24(r6)	/* value */
-	cmpld	r8,r9
-	beq	1b
-	ld	r8,-16(r6)	/* section begin */
-	ld	r9,-8(r6)	/* section end */
-	subf.	r9,r8,r9
-	beq	1b
-	/* write nops over the section of code */
-	/* todo: if large section, add a branch at the start of it */
-	srwi	r9,r9,2
-	mtctr	r9
-	sub	r8,r8,r3
-	lis	r0,0x60000000@h	/* nop */
-3:	stw	r0,0(r8)
-	andi.	r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
-	beq	2f
-	dcbst	0,r8		/* suboptimal, but simpler */
-	sync
-	icbi	0,r8
-2:	addi	r8,r8,4
-	bdnz	3b
-	sync			/* additional sync needed on g4 */
-	isync
-	b	1b
-
-/*
- * do_fw_ftr_fixups - goes through the list of firmware feature fixups
- * and writes nop's over sections of code that don't apply for this firmware.
- * r3 = data offset (not changed)
- */
-_GLOBAL(do_fw_ftr_fixups)
-	/* Get firmware features */
-	LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features)
-	sub	r6,r6,r3
-	ld	r4,0(r6)
-	/* Get the fixup table */
-	LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup)
-	sub	r6,r6,r3
-	LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup)
-	sub	r7,r7,r3
-	/* Do the fixup */
-1:	cmpld	r6,r7
-	bgelr
-	addi	r6,r6,32
-	ld	r8,-32(r6)	/* mask */
-	and	r8,r8,r4
-	ld	r9,-24(r6)	/* value */
-	cmpld	r8,r9
-	beq	1b
-	ld	r8,-16(r6)	/* section begin */
-	ld	r9,-8(r6)	/* section end */
-	subf.	r9,r8,r9
-	beq	1b
-	/* write nops over the section of code */
-	/* todo: if large section, add a branch at the start of it */
-	srwi	r9,r9,2
-	mtctr	r9
-	sub	r8,r8,r3
-	lis	r0,0x60000000@h	/* nop */
-3:	stw	r0,0(r8)
-BEGIN_FTR_SECTION
-	dcbst	0,r8		/* suboptimal, but simpler */
-	sync
-	icbi	0,r8
-END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE)
-	addi	r8,r8,4
-	bdnz	3b
-	sync			/* additional sync needed on g4 */
-	isync
-	b	1b
 
 #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
 /*
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
index 92f4e5f..e2c3c6a 100644
--- a/arch/powerpc/kernel/module_32.c
+++ b/arch/powerpc/kernel/module_32.c
@@ -24,6 +24,8 @@
 #include <linux/kernel.h>
 #include <linux/cache.h>
 
+#include "setup.h"
+
 #if 0
 #define DEBUGP printk
 #else
@@ -269,33 +271,50 @@
 	return 0;
 }
 
+static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
+				    const Elf_Shdr *sechdrs,
+				    const char *name)
+{
+	char *secstrings;
+	unsigned int i;
+
+	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+	for (i = 1; i < hdr->e_shnum; i++)
+		if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
+			return &sechdrs[i];
+	return NULL;
+}
+
 int module_finalize(const Elf_Ehdr *hdr,
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
 {
-	char *secstrings;
-	unsigned int i;
+	const Elf_Shdr *sect;
 
 	me->arch.bug_table = NULL;
 	me->arch.num_bugs = 0;
 
 	/* Find the __bug_table section, if present */
-	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-	for (i = 1; i < hdr->e_shnum; i++) {
-		if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
-			continue;
-		me->arch.bug_table = (void *) sechdrs[i].sh_addr;
-		me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
-		break;
+	sect = find_section(hdr, sechdrs, "__bug_table");
+	if (sect != NULL) {
+		me->arch.bug_table = (void *) sect->sh_addr;
+		me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry);
 	}
 
-	/*
+ 	/*
 	 * Strictly speaking this should have a spinlock to protect against
 	 * traversals, but since we only traverse on BUG()s, a spinlock
 	 * could potentially lead to deadlock and thus be counter-productive.
 	 */
 	list_add(&me->arch.bug_list, &module_bug_list);
 
+	/* Apply feature fixups */
+	sect = find_section(hdr, sechdrs, "__ftr_fixup");
+	if (sect != NULL)
+		do_feature_fixups(cur_cpu_spec->cpu_features,
+				  (void *)sect->sh_addr,
+				  (void *)sect->sh_addr + sect->sh_size);
+
 	return 0;
 }
 
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index ba34001..8dd1f0a 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -22,6 +22,9 @@
 #include <linux/vmalloc.h>
 #include <asm/module.h>
 #include <asm/uaccess.h>
+#include <asm/firmware.h>
+
+#include "setup.h"
 
 /* FIXME: We don't do .init separately.  To do this, we'd need to have
    a separate r2 value in the init and core section, and stub between
@@ -400,6 +403,11 @@
 				| (value & 0x03fffffc);
 			break;
 
+		case R_PPC64_REL64:
+			/* 64 bits relative (used by features fixups) */
+			*location = value - (unsigned long)location;
+			break;
+
 		default:
 			printk("%s: Unknown ADD relocation: %lu\n",
 			       me->name,
@@ -413,23 +421,33 @@
 
 LIST_HEAD(module_bug_list);
 
-int module_finalize(const Elf_Ehdr *hdr,
-		const Elf_Shdr *sechdrs, struct module *me)
+static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
+				    const Elf_Shdr *sechdrs,
+				    const char *name)
 {
 	char *secstrings;
 	unsigned int i;
 
+	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+	for (i = 1; i < hdr->e_shnum; i++)
+		if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
+			return &sechdrs[i];
+	return NULL;
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+		const Elf_Shdr *sechdrs, struct module *me)
+{
+	const Elf_Shdr *sect;
+
 	me->arch.bug_table = NULL;
 	me->arch.num_bugs = 0;
 
 	/* Find the __bug_table section, if present */
-	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-	for (i = 1; i < hdr->e_shnum; i++) {
-		if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
-			continue;
-		me->arch.bug_table = (void *) sechdrs[i].sh_addr;
-		me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
-		break;
+	sect = find_section(hdr, sechdrs, "__bug_table");
+	if (sect != NULL) {
+		me->arch.bug_table = (void *) sect->sh_addr;
+		me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry);
 	}
 
 	/*
@@ -439,6 +457,19 @@
 	 */
 	list_add(&me->arch.bug_list, &module_bug_list);
 
+	/* Apply feature fixups */
+	sect = find_section(hdr, sechdrs, "__ftr_fixup");
+	if (sect != NULL)
+		do_feature_fixups(cur_cpu_spec->cpu_features,
+				  (void *)sect->sh_addr,
+				  (void *)sect->sh_addr + sect->sh_size);
+
+	sect = find_section(hdr, sechdrs, "__fw_ftr_fixup");
+	if (sect != NULL)
+		do_feature_fixups(powerpc_firmware_features,
+				  (void *)sect->sh_addr,
+				  (void *)sect->sh_addr + sect->sh_size);
+
 	return 0;
 }
 
diff --git a/arch/powerpc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c
deleted file mode 100644
index e0dcf2b..0000000
--- a/arch/powerpc/kernel/perfmon_fsl_booke.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/* arch/powerpc/kernel/perfmon_fsl_booke.c
- * Freescale Book-E Performance Monitor code
- *
- * Author: Andy Fleming
- * Copyright (c) 2004 Freescale Semiconductor, Inc
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/prctl.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/reg.h>
-#include <asm/xmon.h>
-#include <asm/pmc.h>
-
-static inline u32 get_pmlca(int ctr);
-static inline void set_pmlca(int ctr, u32 pmlca);
-
-static inline u32 get_pmlca(int ctr)
-{
-	u32 pmlca;
-
-	switch (ctr) {
-		case 0:
-			pmlca = mfpmr(PMRN_PMLCA0);
-			break;
-		case 1:
-			pmlca = mfpmr(PMRN_PMLCA1);
-			break;
-		case 2:
-			pmlca = mfpmr(PMRN_PMLCA2);
-			break;
-		case 3:
-			pmlca = mfpmr(PMRN_PMLCA3);
-			break;
-		default:
-			panic("Bad ctr number\n");
-	}
-
-	return pmlca;
-}
-
-static inline void set_pmlca(int ctr, u32 pmlca)
-{
-	switch (ctr) {
-		case 0:
-			mtpmr(PMRN_PMLCA0, pmlca);
-			break;
-		case 1:
-			mtpmr(PMRN_PMLCA1, pmlca);
-			break;
-		case 2:
-			mtpmr(PMRN_PMLCA2, pmlca);
-			break;
-		case 3:
-			mtpmr(PMRN_PMLCA3, pmlca);
-			break;
-		default:
-			panic("Bad ctr number\n");
-	}
-}
-
-void init_pmc_stop(int ctr)
-{
-	u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU |
-			PMLCA_FCM1 | PMLCA_FCM0);
-	u32 pmlcb = 0;
-
-	switch (ctr) {
-		case 0:
-			mtpmr(PMRN_PMLCA0, pmlca);
-			mtpmr(PMRN_PMLCB0, pmlcb);
-			break;
-		case 1:
-			mtpmr(PMRN_PMLCA1, pmlca);
-			mtpmr(PMRN_PMLCB1, pmlcb);
-			break;
-		case 2:
-			mtpmr(PMRN_PMLCA2, pmlca);
-			mtpmr(PMRN_PMLCB2, pmlcb);
-			break;
-		case 3:
-			mtpmr(PMRN_PMLCA3, pmlca);
-			mtpmr(PMRN_PMLCB3, pmlcb);
-			break;
-		default:
-			panic("Bad ctr number!\n");
-	}
-}
-
-void set_pmc_event(int ctr, int event)
-{
-	u32 pmlca;
-
-	pmlca = get_pmlca(ctr);
-
-	pmlca = (pmlca & ~PMLCA_EVENT_MASK) |
-		((event << PMLCA_EVENT_SHIFT) &
-		 PMLCA_EVENT_MASK);
-
-	set_pmlca(ctr, pmlca);
-}
-
-void set_pmc_user_kernel(int ctr, int user, int kernel)
-{
-	u32 pmlca;
-
-	pmlca = get_pmlca(ctr);
-
-	if(user)
-		pmlca &= ~PMLCA_FCU;
-	else
-		pmlca |= PMLCA_FCU;
-
-	if(kernel)
-		pmlca &= ~PMLCA_FCS;
-	else
-		pmlca |= PMLCA_FCS;
-
-	set_pmlca(ctr, pmlca);
-}
-
-void set_pmc_marked(int ctr, int mark0, int mark1)
-{
-	u32 pmlca = get_pmlca(ctr);
-
-	if(mark0)
-		pmlca &= ~PMLCA_FCM0;
-	else
-		pmlca |= PMLCA_FCM0;
-
-	if(mark1)
-		pmlca &= ~PMLCA_FCM1;
-	else
-		pmlca |= PMLCA_FCM1;
-
-	set_pmlca(ctr, pmlca);
-}
-
-void pmc_start_ctr(int ctr, int enable)
-{
-	u32 pmlca = get_pmlca(ctr);
-
-	pmlca &= ~PMLCA_FC;
-
-	if (enable)
-		pmlca |= PMLCA_CE;
-	else
-		pmlca &= ~PMLCA_CE;
-
-	set_pmlca(ctr, pmlca);
-}
-
-void pmc_start_ctrs(int enable)
-{
-	u32 pmgc0 = mfpmr(PMRN_PMGC0);
-
-	pmgc0 &= ~PMGC0_FAC;
-	pmgc0 |= PMGC0_FCECE;
-
-	if (enable)
-		pmgc0 |= PMGC0_PMIE;
-	else
-		pmgc0 &= ~PMGC0_PMIE;
-
-	mtpmr(PMRN_PMGC0, pmgc0);
-}
-
-void pmc_stop_ctrs(void)
-{
-	u32 pmgc0 = mfpmr(PMRN_PMGC0);
-
-	pmgc0 |= PMGC0_FAC;
-
-	pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE);
-
-	mtpmr(PMRN_PMGC0, pmgc0);
-}
-
-void dump_pmcs(void)
-{
-	printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
-	printk("pmc\t\tpmlca\t\tpmlcb\n");
-	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
-			mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
-	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
-			mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
-	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
-			mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
-	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
-			mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
-}
-
-EXPORT_SYMBOL(init_pmc_stop);
-EXPORT_SYMBOL(set_pmc_event);
-EXPORT_SYMBOL(set_pmc_user_kernel);
-EXPORT_SYMBOL(set_pmc_marked);
-EXPORT_SYMBOL(pmc_start_ctr);
-EXPORT_SYMBOL(pmc_start_ctrs);
-EXPORT_SYMBOL(pmc_stop_ctrs);
-EXPORT_SYMBOL(dump_pmcs);
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index a0a2efa..3d8f6f4 100644
--- a/arch/powerpc/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -71,7 +71,7 @@
 	}
 
 	pmc_owner_caller = __builtin_return_address(0);
-	perf_irq = new_perf_irq ? : dummy_perf;
+	perf_irq = new_perf_irq ? new_perf_irq : dummy_perf;
 
  out:
 	spin_unlock(&pmc_owner_lock);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 865b964..bdb412d 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1014,7 +1014,7 @@
 /** Checks if the given "compat" string matches one of the strings in
  * the device's "compatible" property
  */
-int device_is_compatible(struct device_node *device, const char *compat)
+int device_is_compatible(const struct device_node *device, const char *compat)
 {
 	const char* cp;
 	int cplen, l;
@@ -1491,7 +1491,8 @@
 __initcall(prom_reconfig_setup);
 #endif
 
-struct property *of_find_property(struct device_node *np, const char *name,
+struct property *of_find_property(const struct device_node *np,
+				  const char *name,
 				  int *lenp)
 {
 	struct property *pp;
@@ -1512,7 +1513,8 @@
  * Find a property with a given name for a given node
  * and return the value.
  */
-const void *get_property(struct device_node *np, const char *name, int *lenp)
+const void *get_property(const struct device_node *np, const char *name,
+			 int *lenp)
 {
 	struct property *pp = of_find_property(np,name,lenp);
 	return pp ? pp->value : NULL;
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 1442b63..6f6fc97 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -72,6 +72,10 @@
 #define VALIDATE_BUF_SIZE 4096    
 #define RTAS_MSG_MAXLEN   64
 
+/* Quirk - RTAS requires 4k list length and block size */
+#define RTAS_BLKLIST_LENGTH 4096
+#define RTAS_BLK_SIZE 4096
+
 struct flash_block {
 	char *data;
 	unsigned long length;
@@ -83,7 +87,7 @@
  * into a version/length and translate the pointers
  * to absolute.
  */
-#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
+#define FLASH_BLOCKS_PER_NODE ((RTAS_BLKLIST_LENGTH - 16) / sizeof(struct flash_block))
 struct flash_block_list {
 	unsigned long num_blocks;
 	struct flash_block_list *next;
@@ -96,6 +100,9 @@
 
 static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
 
+/* Use slab cache to guarantee 4k alignment */
+static kmem_cache_t *flash_block_cache = NULL;
+
 #define FLASH_BLOCK_LIST_VERSION (1UL)
 
 /* Local copy of the flash block list.
@@ -153,7 +160,7 @@
 				return FLASH_IMG_NULL_DATA;
 			}
 			block_size = f->blocks[i].length;
-			if (block_size <= 0 || block_size > PAGE_SIZE) {
+			if (block_size <= 0 || block_size > RTAS_BLK_SIZE) {
 				return FLASH_IMG_BAD_LEN;
 			}
 			image_size += block_size;
@@ -177,9 +184,9 @@
 
 	while (f) {
 		for (i = 0; i < f->num_blocks; i++)
-			free_page((unsigned long)(f->blocks[i].data));
+			kmem_cache_free(flash_block_cache, f->blocks[i].data);
 		next = f->next;
-		free_page((unsigned long)f);
+		kmem_cache_free(flash_block_cache, f);
 		f = next;
 	}
 }
@@ -278,6 +285,12 @@
 	return msglen;
 }
 
+/* constructor for flash_block_cache */
+void rtas_block_ctor(void *ptr, kmem_cache_t *cache, unsigned long flags)
+{
+	memset(ptr, 0, RTAS_BLK_SIZE);
+}
+
 /* We could be much more efficient here.  But to keep this function
  * simple we allocate a page to the block list no matter how small the
  * count is.  If the system is low on memory it will be just as well
@@ -302,7 +315,7 @@
 	 * proc file
 	 */
 	if (uf->flist == NULL) {
-		uf->flist = (struct flash_block_list *) get_zeroed_page(GFP_KERNEL);
+		uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
 		if (!uf->flist)
 			return -ENOMEM;
 	}
@@ -313,21 +326,21 @@
 	next_free = fl->num_blocks;
 	if (next_free == FLASH_BLOCKS_PER_NODE) {
 		/* Need to allocate another block_list */
-		fl->next = (struct flash_block_list *)get_zeroed_page(GFP_KERNEL);
+		fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
 		if (!fl->next)
 			return -ENOMEM;
 		fl = fl->next;
 		next_free = 0;
 	}
 
-	if (count > PAGE_SIZE)
-		count = PAGE_SIZE;
-	p = (char *)get_zeroed_page(GFP_KERNEL);
+	if (count > RTAS_BLK_SIZE)
+		count = RTAS_BLK_SIZE;
+	p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
 	if (!p)
 		return -ENOMEM;
 	
 	if(copy_from_user(p, buffer, count)) {
-		free_page((unsigned long)p);
+		kmem_cache_free(flash_block_cache, p);
 		return -EFAULT;
 	}
 	fl->blocks[next_free].data = p;
@@ -791,6 +804,16 @@
 		goto cleanup;
 
 	rtas_flash_term_hook = rtas_flash_firmware;
+
+	flash_block_cache = kmem_cache_create("rtas_flash_cache",
+				RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
+				rtas_block_ctor, NULL);
+	if (!flash_block_cache) {
+		printk(KERN_ERR "%s: failed to create block cache\n",
+				__FUNCTION__);
+		rc = -ENOMEM;
+		goto cleanup;
+	}
 	return 0;
 
 cleanup:
@@ -805,6 +828,10 @@
 void __exit rtas_flash_cleanup(void)
 {
 	rtas_flash_term_hook = NULL;
+
+	if (flash_block_cache)
+		kmem_cache_destroy(flash_block_cache);
+
 	remove_flash_pde(firmware_flash_pde);
 	remove_flash_pde(firmware_update_pde);
 	remove_flash_pde(validate_pde);
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 191d0ab..a4c2964 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -91,6 +91,7 @@
 unsigned long __init early_init(unsigned long dt_ptr)
 {
 	unsigned long offset = reloc_offset();
+	struct cpu_spec *spec;
 
 	/* First zero the BSS -- use memset_io, some platforms don't have
 	 * caches on yet */
@@ -100,8 +101,11 @@
 	 * Identify the CPU type and fix up code sections
 	 * that depend on which cpu we have.
 	 */
-	identify_cpu(offset, 0);
-	do_cpu_ftr_fixups(offset);
+	spec = identify_cpu(offset);
+
+	do_feature_fixups(spec->cpu_features,
+			  PTRRELOC(&__start___ftr_fixup),
+			  PTRRELOC(&__stop___ftr_fixup));
 
 	return KERNELBASE + offset;
 }
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 4b2e32e..1627896 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -170,6 +170,9 @@
 
 void __init early_setup(unsigned long dt_ptr)
 {
+	/* Identify CPU type */
+	identify_cpu(0);
+
 	/* Assume we're on cpu 0 for now. Don't write to the paca yet! */
 	setup_paca(0);
 
@@ -348,6 +351,14 @@
 {
 	DBG(" -> setup_system()\n");
 
+	/* Apply the CPUs-specific and firmware specific fixups to kernel
+	 * text (nop out sections not relevant to this CPU or this firmware)
+	 */
+	do_feature_fixups(cur_cpu_spec->cpu_features,
+			  &__start___ftr_fixup, &__stop___ftr_fixup);
+	do_feature_fixups(powerpc_firmware_features,
+			  &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
+
 	/*
 	 * Unflatten the device-tree passed by prom_init or kexec
 	 */
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 5b59bc1..46a24de 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -220,11 +220,8 @@
  */
 struct cpu_purr_data {
 	int	initialized;			/* thread is running */
-	u64	tb0;			/* timebase at origin time */
-	u64	purr0;			/* PURR at origin time */
 	u64	tb;			/* last TB value read */
 	u64	purr;			/* last PURR value read */
-	u64	stolen;			/* stolen time so far */
 	spinlock_t lock;
 };
 
@@ -234,10 +231,8 @@
 {
 	struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
 
-	p->tb0 = mftb();
-	p->purr0 = mfspr(SPRN_PURR);
-	p->tb = p->tb0;
-	p->purr = 0;
+	p->tb = mftb();
+	p->purr = mfspr(SPRN_PURR);
 	wmb();
 	p->initialized = 1;
 }
@@ -258,37 +253,24 @@
 
 void calculate_steal_time(void)
 {
-	u64 tb, purr, t0;
+	u64 tb, purr;
 	s64 stolen;
-	struct cpu_purr_data *p0, *pme, *phim;
-	int cpu;
+	struct cpu_purr_data *pme;
 
 	if (!cpu_has_feature(CPU_FTR_PURR))
 		return;
-	cpu = smp_processor_id();
-	pme = &per_cpu(cpu_purr_data, cpu);
+	pme = &per_cpu(cpu_purr_data, smp_processor_id());
 	if (!pme->initialized)
 		return;		/* this can happen in early boot */
-	p0 = &per_cpu(cpu_purr_data, cpu & ~1);
-	phim = &per_cpu(cpu_purr_data, cpu ^ 1);
-	spin_lock(&p0->lock);
+	spin_lock(&pme->lock);
 	tb = mftb();
-	purr = mfspr(SPRN_PURR) - pme->purr0;
-	if (!phim->initialized || !cpu_online(cpu ^ 1)) {
-		stolen = (tb - pme->tb) - (purr - pme->purr);
-	} else {
-		t0 = pme->tb0;
-		if (phim->tb0 < t0)
-			t0 = phim->tb0;
-		stolen = phim->tb - t0 - phim->purr - purr - p0->stolen;
-	}
-	if (stolen > 0) {
+	purr = mfspr(SPRN_PURR);
+	stolen = (tb - pme->tb) - (purr - pme->purr);
+	if (stolen > 0)
 		account_steal_time(current, stolen);
-		p0->stolen += stolen;
-	}
 	pme->tb = tb;
 	pme->purr = purr;
-	spin_unlock(&p0->lock);
+	spin_unlock(&pme->lock);
 }
 
 /*
@@ -297,30 +279,17 @@
  */
 static void snapshot_purr(void)
 {
-	int cpu;
-	u64 purr;
-	struct cpu_purr_data *p0, *pme, *phim;
+	struct cpu_purr_data *pme;
 	unsigned long flags;
 
 	if (!cpu_has_feature(CPU_FTR_PURR))
 		return;
-	cpu = smp_processor_id();
-	pme = &per_cpu(cpu_purr_data, cpu);
-	p0 = &per_cpu(cpu_purr_data, cpu & ~1);
-	phim = &per_cpu(cpu_purr_data, cpu ^ 1);
-	spin_lock_irqsave(&p0->lock, flags);
-	pme->tb = pme->tb0 = mftb();
-	purr = mfspr(SPRN_PURR);
-	if (!phim->initialized) {
-		pme->purr = 0;
-		pme->purr0 = purr;
-	} else {
-		/* set p->purr and p->purr0 for no change in p0->stolen */
-		pme->purr = phim->tb - phim->tb0 - phim->purr - p0->stolen;
-		pme->purr0 = purr - pme->purr;
-	}
+	pme = &per_cpu(cpu_purr_data, smp_processor_id());
+	spin_lock_irqsave(&pme->lock, flags);
+	pme->tb = mftb();
+	pme->purr = mfspr(SPRN_PURR);
 	pme->initialized = 1;
-	spin_unlock_irqrestore(&p0->lock, flags);
+	spin_unlock_irqrestore(&pme->lock, flags);
 }
 
 #endif /* CONFIG_PPC_SPLPAR */
@@ -1045,48 +1014,6 @@
 	set_dec(tb_ticks_per_jiffy);
 }
 
-#ifdef CONFIG_RTC_CLASS
-static int set_rtc_class_time(struct rtc_time *tm)
-{
-	int err;
-	struct class_device *class_dev =
-		rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
-
-	if (class_dev == NULL)
-		return -ENODEV;
-
-	err = rtc_set_time(class_dev, tm);
-
-	rtc_class_close(class_dev);
-
-	return 0;
-}
-
-static void get_rtc_class_time(struct rtc_time *tm)
-{
-	int err;
-	struct class_device *class_dev =
-		rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
-
-	if (class_dev == NULL)
-		return;
-
-	err = rtc_read_time(class_dev, tm);
-
-	rtc_class_close(class_dev);
-
-	return;
-}
-
-int __init rtc_class_hookup(void)
-{
-	ppc_md.get_rtc_time = get_rtc_class_time;
-	ppc_md.set_rtc_time = set_rtc_class_time;
-
-	return 0;
-}
-#endif /* CONFIG_RTC_CLASS */
-
 
 #define FEBRUARY	2
 #define	STARTOFTIME	1970
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 5ed4c2c..c66b477 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -843,7 +843,7 @@
 
 void alignment_exception(struct pt_regs *regs)
 {
-	int fixed = 0;
+	int sig, code, fixed = 0;
 
 	/* we don't implement logging of alignment exceptions */
 	if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
@@ -857,14 +857,16 @@
 
 	/* Operand address was bad */
 	if (fixed == -EFAULT) {
-		if (user_mode(regs))
-			_exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
-		else
-			/* Search exception table */
-			bad_page_fault(regs, regs->dar, SIGSEGV);
-		return;
+		sig = SIGSEGV;
+		code = SEGV_ACCERR;
+	} else {
+		sig = SIGBUS;
+		code = BUS_ADRALN;
 	}
-	_exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+	if (user_mode(regs))
+		_exception(sig, regs, code, regs->dar);
+	else
+		bad_page_fault(regs, regs->dar, sig);
 }
 
 void StackOverflow(struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 1a7e19c..c913ad5 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -36,6 +36,8 @@
 #include <asm/vdso.h>
 #include <asm/vdso_datapage.h>
 
+#include "setup.h"
+
 #undef DEBUG
 
 #ifdef DEBUG
@@ -586,6 +588,43 @@
 	return 0;
 }
 
+
+static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
+				      struct lib64_elfinfo *v64)
+{
+	void *start32;
+	unsigned long size32;
+
+#ifdef CONFIG_PPC64
+	void *start64;
+	unsigned long size64;
+
+	start64 = find_section64(v64->hdr, "__ftr_fixup", &size64);
+	if (start64)
+		do_feature_fixups(cur_cpu_spec->cpu_features,
+				  start64, start64 + size64);
+
+	start64 = find_section64(v64->hdr, "__fw_ftr_fixup", &size64);
+	if (start64)
+		do_feature_fixups(powerpc_firmware_features,
+				  start64, start64 + size64);
+#endif /* CONFIG_PPC64 */
+
+	start32 = find_section32(v32->hdr, "__ftr_fixup", &size32);
+	if (start32)
+		do_feature_fixups(cur_cpu_spec->cpu_features,
+				  start32, start32 + size32);
+
+#ifdef CONFIG_PPC64
+	start32 = find_section32(v32->hdr, "__fw_ftr_fixup", &size32);
+	if (start32)
+		do_feature_fixups(powerpc_firmware_features,
+				  start32, start32 + size32);
+#endif /* CONFIG_PPC64 */
+
+	return 0;
+}
+
 static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32,
 				       struct lib64_elfinfo *v64)
 {
@@ -634,6 +673,9 @@
 	if (vdso_fixup_datapage(&v32, &v64))
 		return -1;
 
+	if (vdso_fixup_features(&v32, &v64))
+		return -1;
+
 	if (vdso_fixup_alt_funcs(&v32, &v64))
 		return -1;
 
@@ -714,6 +756,7 @@
 	 * Setup the syscall map in the vDOS
 	 */
 	vdso_setup_syscall_map();
+
 	/*
 	 * Initialize the vDSO images in memory, that is do necessary
 	 * fixups of vDSO symbols, locate trampolines, etc...
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 6187af2..26e138c 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -32,6 +32,18 @@
   PROVIDE (_etext = .);
   PROVIDE (etext = .);
 
+  . = ALIGN(8);
+  __ftr_fixup : {
+    *(__ftr_fixup)
+  }
+
+#ifdef CONFIG_PPC64
+  . = ALIGN(8);
+  __fw_ftr_fixup : {
+    *(__fw_ftr_fixup)
+  }
+#endif
+
   /* Other stuff is appended to the text segment: */
   .rodata		: { *(.rodata .rodata.* .gnu.linkonce.r.*) }
   .rodata1		: { *(.rodata1) }
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index 56e76ff..40ffd9b 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -229,8 +229,10 @@
 	xor	r0,r8,r8		/* create dependency */
 	add	r3,r3,r0
 
-	/* Get TB & offset it */
-	mftb	r7
+	/* Get TB & offset it. We use the MFTB macro which will generate
+	 * workaround code for Cell.
+	 */
+	MFTB(r7)
 	ld	r9,CFG_TB_ORIG_STAMP(r3)
 	subf	r7,r9,r7
 
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S
index 4a2b6dc..2d70f35 100644
--- a/arch/powerpc/kernel/vdso64/vdso64.lds.S
+++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S
@@ -31,6 +31,16 @@
   PROVIDE (_etext = .);
   PROVIDE (etext = .);
 
+  . = ALIGN(8);
+  __ftr_fixup : {
+    *(__ftr_fixup)
+  }
+
+  . = ALIGN(8);
+  __fw_ftr_fixup : {
+    *(__fw_ftr_fixup)
+  }
+
   /* Other stuff is appended to the text segment: */
   .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
   .rodata1        : { *(.rodata1) }
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index cb87e71..ed00787 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -92,9 +92,9 @@
 				&tbl->it_index, &offset, &size);
 
 		/* TCE table size - measured in tce entries */
-		tbl->it_size = size >> PAGE_SHIFT;
+		tbl->it_size = size >> IOMMU_PAGE_SHIFT;
 		/* offset for VIO should always be 0 */
-		tbl->it_offset = offset >> PAGE_SHIFT;
+		tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
 		tbl->it_busno = 0;
 		tbl->it_type = TCE_VB;
 
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index cb0e8d4..e8342d8 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -108,13 +108,7 @@
 
 	.initcall.init : {
 		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
+		INITCALLS
 		__initcall_end = .;
 		}
 
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 9590ba7..7e8ded0 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/kernel.h>
+#include <linux/kprobes.h>
 #include <linux/ptrace.h>
 #include <asm/sstep.h>
 #include <asm/processor.h>
@@ -25,7 +26,7 @@
 /*
  * Determine whether a conditional branch instruction would branch.
  */
-static int branch_taken(unsigned int instr, struct pt_regs *regs)
+static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs)
 {
 	unsigned int bo = (instr >> 21) & 0x1f;
 	unsigned int bi;
@@ -51,7 +52,7 @@
  * or -1 if the instruction is one that should not be stepped,
  * such as an rfid, or a mtmsrd that would clear MSR_RI.
  */
-int emulate_step(struct pt_regs *regs, unsigned int instr)
+int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 {
 	unsigned int opcode, rd;
 	unsigned long int imm;
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 5615acc..506d897 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -480,9 +480,6 @@
 
 	mm->context.high_htlb_areas |= newareas;
 
-	/* update the paca copy of the context struct */
-	get_paca()->context = mm->context;
-
 	/* the context change must make it to memory before the flush,
 	 * so that further SLB misses do the right thing. */
 	mb();
@@ -494,11 +491,15 @@
 	return 0;
 }
 
-int prepare_hugepage_range(unsigned long addr, unsigned long len)
+int prepare_hugepage_range(unsigned long addr, unsigned long len, pgoff_t pgoff)
 {
 	int err = 0;
 
-	if ( (addr+len) < addr )
+	if (pgoff & (~HPAGE_MASK >> PAGE_SHIFT))
+		return -EINVAL;
+	if (len & ~HPAGE_MASK)
+		return -EINVAL;
+	if (addr & ~HPAGE_MASK)
 		return -EINVAL;
 
 	if (addr < 0x100000000UL)
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 3145d61..0b5df9c 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -13,4 +13,4 @@
 oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
 oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
 oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
-oprofile-$(CONFIG_PPC32) += op_model_7450.o
+oprofile-$(CONFIG_6xx) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index fd0bbbe..63bbef3 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -34,6 +34,11 @@
 	model->handle_interrupt(regs, ctr);
 }
 
+static void op_powerpc_cpu_setup(void *dummy)
+{
+	model->cpu_setup(ctr);
+}
+
 static int op_powerpc_setup(void)
 {
 	int err;
@@ -47,7 +52,7 @@
 	model->reg_setup(ctr, &sys, model->num_counters);
 
 	/* Configure the registers on all cpus.  */
-	on_each_cpu(model->cpu_setup, NULL, 0, 1);
+	on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1);
 
 	return 0;
 }
@@ -142,7 +147,8 @@
 		case PPC_OPROFILE_POWER4:
 			model = &op_model_power4;
 			break;
-#else
+#endif
+#ifdef CONFIG_6xx
 		case PPC_OPROFILE_G4:
 			model = &op_model_7450;
 			break;
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c
index d8ee3ae..f481c0e 100644
--- a/arch/powerpc/oprofile/op_model_7450.c
+++ b/arch/powerpc/oprofile/op_model_7450.c
@@ -81,7 +81,7 @@
 
 /* Configures the counters on this CPU based on the global
  * settings */
-static void fsl7450_cpu_setup(void *unused)
+static void fsl7450_cpu_setup(struct op_counter_config *ctr)
 {
 	/* freeze all counters */
 	pmc_stop_ctrs();
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index e29dede..0b3c31f 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -32,42 +32,152 @@
 static int num_counters;
 static int oprofile_running;
 
-static inline unsigned int ctr_read(unsigned int i)
+static void init_pmc_stop(int ctr)
 {
-	switch(i) {
+	u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU |
+			PMLCA_FCM1 | PMLCA_FCM0);
+	u32 pmlcb = 0;
+
+	switch (ctr) {
 		case 0:
-			return mfpmr(PMRN_PMC0);
+			mtpmr(PMRN_PMLCA0, pmlca);
+			mtpmr(PMRN_PMLCB0, pmlcb);
+			break;
 		case 1:
-			return mfpmr(PMRN_PMC1);
+			mtpmr(PMRN_PMLCA1, pmlca);
+			mtpmr(PMRN_PMLCB1, pmlcb);
+			break;
 		case 2:
-			return mfpmr(PMRN_PMC2);
+			mtpmr(PMRN_PMLCA2, pmlca);
+			mtpmr(PMRN_PMLCB2, pmlcb);
+			break;
 		case 3:
-			return mfpmr(PMRN_PMC3);
+			mtpmr(PMRN_PMLCA3, pmlca);
+			mtpmr(PMRN_PMLCB3, pmlcb);
+			break;
 		default:
-			return 0;
+			panic("Bad ctr number!\n");
 	}
 }
 
-static inline void ctr_write(unsigned int i, unsigned int val)
+static void set_pmc_event(int ctr, int event)
 {
-	switch(i) {
-		case 0:
-			mtpmr(PMRN_PMC0, val);
-			break;
-		case 1:
-			mtpmr(PMRN_PMC1, val);
-			break;
-		case 2:
-			mtpmr(PMRN_PMC2, val);
-			break;
-		case 3:
-			mtpmr(PMRN_PMC3, val);
-			break;
-		default:
-			break;
-	}
+	u32 pmlca;
+
+	pmlca = get_pmlca(ctr);
+
+	pmlca = (pmlca & ~PMLCA_EVENT_MASK) |
+		((event << PMLCA_EVENT_SHIFT) &
+		 PMLCA_EVENT_MASK);
+
+	set_pmlca(ctr, pmlca);
 }
 
+static void set_pmc_user_kernel(int ctr, int user, int kernel)
+{
+	u32 pmlca;
+
+	pmlca = get_pmlca(ctr);
+
+	if(user)
+		pmlca &= ~PMLCA_FCU;
+	else
+		pmlca |= PMLCA_FCU;
+
+	if(kernel)
+		pmlca &= ~PMLCA_FCS;
+	else
+		pmlca |= PMLCA_FCS;
+
+	set_pmlca(ctr, pmlca);
+}
+
+static void set_pmc_marked(int ctr, int mark0, int mark1)
+{
+	u32 pmlca = get_pmlca(ctr);
+
+	if(mark0)
+		pmlca &= ~PMLCA_FCM0;
+	else
+		pmlca |= PMLCA_FCM0;
+
+	if(mark1)
+		pmlca &= ~PMLCA_FCM1;
+	else
+		pmlca |= PMLCA_FCM1;
+
+	set_pmlca(ctr, pmlca);
+}
+
+static void pmc_start_ctr(int ctr, int enable)
+{
+	u32 pmlca = get_pmlca(ctr);
+
+	pmlca &= ~PMLCA_FC;
+
+	if (enable)
+		pmlca |= PMLCA_CE;
+	else
+		pmlca &= ~PMLCA_CE;
+
+	set_pmlca(ctr, pmlca);
+}
+
+static void pmc_start_ctrs(int enable)
+{
+	u32 pmgc0 = mfpmr(PMRN_PMGC0);
+
+	pmgc0 &= ~PMGC0_FAC;
+	pmgc0 |= PMGC0_FCECE;
+
+	if (enable)
+		pmgc0 |= PMGC0_PMIE;
+	else
+		pmgc0 &= ~PMGC0_PMIE;
+
+	mtpmr(PMRN_PMGC0, pmgc0);
+}
+
+static void pmc_stop_ctrs(void)
+{
+	u32 pmgc0 = mfpmr(PMRN_PMGC0);
+
+	pmgc0 |= PMGC0_FAC;
+
+	pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE);
+
+	mtpmr(PMRN_PMGC0, pmgc0);
+}
+
+static void dump_pmcs(void)
+{
+	printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
+	printk("pmc\t\tpmlca\t\tpmlcb\n");
+	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
+			mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
+	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
+			mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
+	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
+			mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
+	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
+			mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
+}
+
+static void fsl_booke_cpu_setup(struct op_counter_config *ctr)
+{
+	int i;
+
+	/* freeze all counters */
+	pmc_stop_ctrs();
+
+	for (i = 0;i < num_counters;i++) {
+		init_pmc_stop(i);
+
+		set_pmc_event(i, ctr[i].event);
+
+		set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
+	}
+}
 
 static void fsl_booke_reg_setup(struct op_counter_config *ctr,
 			     struct op_system_config *sys,
@@ -77,23 +187,14 @@
 
 	num_counters = num_ctrs;
 
-	/* freeze all counters */
-	pmc_stop_ctrs();
-
 	/* Our counters count up, and "count" refers to
 	 * how much before the next interrupt, and we interrupt
 	 * on overflow.  So we calculate the starting value
 	 * which will give us "count" until overflow.
 	 * Then we set the events on the enabled counters */
-	for (i = 0; i < num_counters; ++i) {
+	for (i = 0; i < num_counters; ++i)
 		reset_value[i] = 0x80000000UL - ctr[i].count;
 
-		init_pmc_stop(i);
-
-		set_pmc_event(i, ctr[i].event);
-
-		set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
-	}
 }
 
 static void fsl_booke_start(struct op_counter_config *ctr)
@@ -105,8 +206,8 @@
 	for (i = 0; i < num_counters; ++i) {
 		if (ctr[i].enabled) {
 			ctr_write(i, reset_value[i]);
-			/* Set Each enabled counterd to only
-			 * count when the Mark bit is not set */
+			/* Set each enabled counter to only
+			 * count when the Mark bit is *not* set */
 			set_pmc_marked(i, 1, 0);
 			pmc_start_ctr(i, 1);
 		} else {
@@ -177,6 +278,7 @@
 
 struct op_powerpc_model op_model_fsl_booke = {
 	.reg_setup		= fsl_booke_reg_setup,
+	.cpu_setup		= fsl_booke_cpu_setup,
 	.start			= fsl_booke_start,
 	.stop			= fsl_booke_stop,
 	.handle_interrupt	= fsl_booke_handle_interrupt,
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index 506f6b7..356709d 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -76,13 +76,13 @@
 {
 	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) ||
 	    __is_processor(PV_970) || __is_processor(PV_970FX) ||
-	    __is_processor(PV_970MP))
+	    __is_processor(PV_970MP) || __is_processor(PV_970GX))
 		return 1;
 
 	return 0;
 }
 
-static void power4_cpu_setup(void *unused)
+static void power4_cpu_setup(struct op_counter_config *ctr)
 {
 	unsigned int mmcr0 = mmcr0_val;
 	unsigned long mmcra = mmcra_val;
diff --git a/arch/powerpc/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c
index 042f8f4..19c5ee0 100644
--- a/arch/powerpc/oprofile/op_model_rs64.c
+++ b/arch/powerpc/oprofile/op_model_rs64.c
@@ -102,7 +102,7 @@
 	/* XXX setup user and kernel profiling */
 }
 
-static void rs64_cpu_setup(void *unused)
+static void rs64_cpu_setup(struct op_counter_config *ctr)
 {
 	unsigned int mmcr0;
 
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 54dea9d4..a43ac71 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -24,6 +24,7 @@
 #include <linux/root_dev.h>
 #include <linux/initrd.h>
 
+#include <asm/of_device.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
 #include <asm/time.h>
@@ -136,6 +137,24 @@
 #endif
 }
 
+static int __init mpc832x_declare_of_platform_devices(void)
+{
+	struct device_node *np;
+
+	for (np = NULL; (np = of_find_compatible_node(np, "network",
+					"ucc_geth")) != NULL;) {
+		int ucc_num;
+		char bus_id[BUS_ID_SIZE];
+
+		ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1;
+		snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num);
+		of_platform_device_create(np, bus_id, NULL);
+	}
+
+	return 0;
+}
+device_initcall(mpc832x_declare_of_platform_devices);
+
 void __init mpc832x_sys_init_IRQ(void)
 {
 
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index 5446bab..e2bcaaf 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -108,10 +108,6 @@
 	return 1;
 }
 
-#ifdef CONFIG_RTC_CLASS
-late_initcall(rtc_class_hookup);
-#endif
-
 define_machine(mpc834x_itx) {
 	.name			= "MPC834x ITX",
 	.probe			= mpc834x_itx_probe,
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index d0fb959..7aa809d 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -655,14 +655,19 @@
 
 	for (i=0; i < 3; i++) {
 		ret = of_irq_map_one(np, i, &oirq);
-		if (ret)
+		if (ret) {
+			pr_debug("spu_new: failed to get irq %d\n", i);
 			goto err;
-
+		}
 		ret = -EINVAL;
+		pr_debug("  irq %d no 0x%x on %s\n", i, oirq.specifier[0],
+			 oirq.controller->full_name);
 		spu->irqs[i] = irq_create_of_mapping(oirq.controller,
 					oirq.specifier, oirq.size);
-		if (spu->irqs[i] == NO_IRQ)
+		if (spu->irqs[i] == NO_IRQ) {
+			pr_debug("spu_new: failed to map it !\n");
 			goto err;
+		}
 	}
 	return 0;
 
@@ -681,7 +686,7 @@
 	struct resource resource = { };
 	int ret;
 
-	ret = of_address_to_resource(node, 0, &resource);
+	ret = of_address_to_resource(node, nr, &resource);
 	if (ret)
 		goto out;
 
@@ -704,22 +709,42 @@
 
 	ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store,
 					&spu->local_store_phys);
-	if (ret)
+	if (ret) {
+		pr_debug("spu_new: failed to map %s resource 0\n",
+			 node->full_name);
 		goto out;
+	}
 	ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem,
 					&spu->problem_phys);
-	if (ret)
+	if (ret) {
+		pr_debug("spu_new: failed to map %s resource 1\n",
+			 node->full_name);
 		goto out_unmap;
+	}
 	ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2,
 					NULL);
-	if (ret)
+	if (ret) {
+		pr_debug("spu_new: failed to map %s resource 2\n",
+			 node->full_name);
 		goto out_unmap;
+	}
 
 	if (!firmware_has_feature(FW_FEATURE_LPAR))
 		ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1,
 					NULL);
-	if (ret)
+	if (ret) {
+		pr_debug("spu_new: failed to map %s resource 3\n",
+			 node->full_name);
 		goto out_unmap;
+	}
+	pr_debug("spu_new: %s maps:\n", node->full_name);
+	pr_debug("  local store   : 0x%016lx -> 0x%p\n",
+		 spu->local_store_phys, spu->local_store);
+	pr_debug("  problem state : 0x%016lx -> 0x%p\n",
+		 spu->problem_phys, spu->problem);
+	pr_debug("  priv2         :                       0x%p\n", spu->priv2);
+	pr_debug("  priv1         :                       0x%p\n", spu->priv1);
+
 	return 0;
 
 out_unmap:
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 0de8e11..533e272 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -385,7 +385,7 @@
 	udata = (void __user *)buf;
 
 	spu_acquire(ctx);
-	for (count = 0; count <= len; count += 4, udata++) {
+	for (count = 0; (count + 4) <= len; count += 4, udata++) {
 		int ret;
 		ret = ctx->ops->mbox_read(ctx, &mbox_data);
 		if (ret == 0)
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index efc452e..d805ffe 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -147,7 +147,7 @@
 
 static u32 spu_hw_signal2_read(struct spu_context *ctx)
 {
-	return in_be32(&ctx->spu->problem->signal_notify1);
+	return in_be32(&ctx->spu->problem->signal_notify2);
 }
 
 static void spu_hw_signal2_write(struct spu_context *ctx, u32 data)
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index cae3d13..49b8dab 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -477,8 +477,10 @@
 		       " address, polling\n");
 
 	i8259_init(pic, chrp_int_ack);
-	if (ppc_md.get_irq == NULL)
+	if (ppc_md.get_irq == NULL) {
 		ppc_md.get_irq = i8259_irq;
+		irq_set_default_host(i8259_get_host());
+	}
 	if (chrp_mpic != NULL) {
 		cascade_irq = irq_of_parse_and_map(pic, 0);
 		if (cascade_irq == NO_IRQ)
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index f4cbbcf..218817d 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -43,9 +43,6 @@
 	u64 rc;
 	u64 tce, rpn;
 
-	index <<= TCE_PAGE_FACTOR;
-	npages <<= TCE_PAGE_FACTOR;
-
 	while (npages--) {
 		rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
 		tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
@@ -75,9 +72,6 @@
 {
 	u64 rc;
 
-	npages <<= TCE_PAGE_FACTOR;
-	index <<= TCE_PAGE_FACTOR;
-
 	while (npages--) {
 		rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0);
 		if (rc)
@@ -136,10 +130,9 @@
 		panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);
 
 	/* itc_size is in pages worth of table, it_size is in # of entries */
-	tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) /
-			TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR;
+	tbl->it_size = (parms->itc_size * TCE_PAGE_SIZE) / TCE_ENTRY_SIZE;
 	tbl->it_busno = parms->itc_busno;
-	tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR;
+	tbl->it_offset = parms->itc_offset;
 	tbl->it_index = parms->itc_index;
 	tbl->it_blocksize = 1;
 	tbl->it_type = virtbus ? TCE_VB : TCE_PCI;
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index a0ff7ba..6f73469 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -694,6 +694,11 @@
 {
 	unsigned long phys_mem_size;
 
+	/* Identify CPU type. This is done again by the common code later
+	 * on but calling this function multiple times is fine.
+	 */
+	identify_cpu(0);
+
 	powerpc_firmware_features |= FW_FEATURE_ISERIES;
 	powerpc_firmware_features |= FW_FEATURE_LPAR;
 
diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S
index 1174ca1..adee28d 100644
--- a/arch/powerpc/platforms/powermac/sleep.S
+++ b/arch/powerpc/platforms/powermac/sleep.S
@@ -45,7 +45,8 @@
 	.section .text
 	.align	5
 
-#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)
+#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) || \
+    (defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32))
 
 /* This gets called by via-pmu.c late during the sleep process.
  * The PMU was already send the sleep command and will shut us down
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index d24ba54..556c279 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -57,9 +57,6 @@
 	u64 *tcep;
 	u64 rpn;
 
-	index <<= TCE_PAGE_FACTOR;
-	npages <<= TCE_PAGE_FACTOR;
-
 	proto_tce = TCE_PCI_READ; // Read allowed
 
 	if (direction != DMA_TO_DEVICE)
@@ -82,9 +79,6 @@
 {
 	u64 *tcep;
 
-	npages <<= TCE_PAGE_FACTOR;
-	index <<= TCE_PAGE_FACTOR;
-
 	tcep = ((u64 *)tbl->it_base) + index;
 
 	while (npages--)
@@ -95,7 +89,6 @@
 {
 	u64 *tcep;
 
-	index <<= TCE_PAGE_FACTOR;
 	tcep = ((u64 *)tbl->it_base) + index;
 
 	return *tcep;
@@ -109,9 +102,6 @@
 	u64 proto_tce, tce;
 	u64 rpn;
 
-	tcenum <<= TCE_PAGE_FACTOR;
-	npages <<= TCE_PAGE_FACTOR;
-
 	rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
 	proto_tce = TCE_PCI_READ;
 	if (direction != DMA_TO_DEVICE)
@@ -146,7 +136,7 @@
 	u64 rpn;
 	long l, limit;
 
-	if (TCE_PAGE_FACTOR == 0 && npages == 1)
+	if (npages == 1)
 		return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
 					   direction);
 
@@ -164,9 +154,6 @@
 		__get_cpu_var(tce_page) = tcep;
 	}
 
-	tcenum <<= TCE_PAGE_FACTOR;
-	npages <<= TCE_PAGE_FACTOR;
-
 	rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
 	proto_tce = TCE_PCI_READ;
 	if (direction != DMA_TO_DEVICE)
@@ -207,9 +194,6 @@
 {
 	u64 rc;
 
-	tcenum <<= TCE_PAGE_FACTOR;
-	npages <<= TCE_PAGE_FACTOR;
-
 	while (npages--) {
 		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
 
@@ -229,9 +213,6 @@
 {
 	u64 rc;
 
-	tcenum <<= TCE_PAGE_FACTOR;
-	npages <<= TCE_PAGE_FACTOR;
-
 	rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);
 
 	if (rc && printk_ratelimit()) {
@@ -248,7 +229,6 @@
 	u64 rc;
 	unsigned long tce_ret;
 
-	tcenum <<= TCE_PAGE_FACTOR;
 	rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret);
 
 	if (rc && printk_ratelimit()) {
@@ -289,7 +269,7 @@
 	tbl->it_busno = phb->bus->number;
 
 	/* Units of tce entries */
-	tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
+	tbl->it_offset = phb->dma_window_base_cur >> IOMMU_PAGE_SHIFT;
 
 	/* Test if we are going over 2GB of DMA space */
 	if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
@@ -300,7 +280,7 @@
 	phb->dma_window_base_cur += phb->dma_window_size;
 
 	/* Set the tce table size - measured in entries */
-	tbl->it_size = phb->dma_window_size >> PAGE_SHIFT;
+	tbl->it_size = phb->dma_window_size >> IOMMU_PAGE_SHIFT;
 
 	tbl->it_index = 0;
 	tbl->it_blocksize = 16;
@@ -325,8 +305,8 @@
 	tbl->it_base   = 0;
 	tbl->it_blocksize  = 16;
 	tbl->it_type = TCE_PCI;
-	tbl->it_offset = offset >> PAGE_SHIFT;
-	tbl->it_size = size >> PAGE_SHIFT;
+	tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
+	tbl->it_size = size >> IOMMU_PAGE_SHIFT;
 }
 
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
@@ -522,8 +502,6 @@
 	const void *dma_window = NULL;
 	struct pci_dn *pci;
 
-	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
-
 	/* dev setup for LPAR is a little tricky, since the device tree might
 	 * contain the dma-window properties per-device and not neccesarily
 	 * for the bus. So we need to search upwards in the tree until we
@@ -532,6 +510,9 @@
 	 */
 	dn = pci_device_to_OF_node(dev);
 
+	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n",
+	     dev, pci_name(dev), dn->full_name);
+
 	for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
 	     pdn = pdn->parent) {
 		dma_window = get_property(pdn, "ibm,dma-window", NULL);
diff --git a/arch/powerpc/sysdev/dart.h b/arch/powerpc/sysdev/dart.h
index 1c8817c..ff202ed 100644
--- a/arch/powerpc/sysdev/dart.h
+++ b/arch/powerpc/sysdev/dart.h
@@ -72,7 +72,6 @@
 
 #define DART_PAGE_SHIFT		12
 #define DART_PAGE_SIZE		(1 << DART_PAGE_SHIFT)
-#define DART_PAGE_FACTOR	(PAGE_SHIFT - DART_PAGE_SHIFT)
 
 
 #endif /* _POWERPC_SYSDEV_DART_H */
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 03b4477..572b784 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -156,9 +156,6 @@
 
 	DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);
 
-	index <<= DART_PAGE_FACTOR;
-	npages <<= DART_PAGE_FACTOR;
-
 	dp = ((unsigned int*)tbl->it_base) + index;
 
 	/* On U3, all memory is contigous, so we can move this
@@ -199,9 +196,6 @@
 
 	DBG("dart: free at: %lx, %lx\n", index, npages);
 
-	index <<= DART_PAGE_FACTOR;
-	npages <<= DART_PAGE_FACTOR;
-
 	dp  = ((unsigned int *)tbl->it_base) + index;
 
 	while (npages--)
@@ -281,7 +275,7 @@
 	iommu_table_dart.it_busno = 0;
 	iommu_table_dart.it_offset = 0;
 	/* it_size is in number of entries */
-	iommu_table_dart.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR;
+	iommu_table_dart.it_size = dart_tablesize / sizeof(u32);
 
 	/* Initialize the common IOMMU code */
 	iommu_table_dart.it_base = (unsigned long)dart_vbase;
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 0450265..ad87adc9 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -224,6 +224,11 @@
 	.xlate = i8259_host_xlate,
 };
 
+struct irq_host *i8259_get_host(void)
+{
+	return i8259_host;
+}
+
 /**
  * i8259_init - Initialize the legacy controller
  * @node: device node of the legacy PIC (can be NULL, but then, it will match
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index bc4d4a7..746f78c 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -473,9 +473,9 @@
 	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
 	if (flow_type & IRQ_TYPE_LEVEL_LOW)  {
 		desc->status |= IRQ_LEVEL;
-		set_irq_handler(virq, handle_level_irq);
+		desc->handle_irq = handle_level_irq;
 	} else {
-		set_irq_handler(virq, handle_edge_irq);
+		desc->handle_irq = handle_edge_irq;
 	}
 
 	/* only EXT IRQ senses are programmable on ipic
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 2bae632..e422322 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -122,8 +122,7 @@
 				mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
 		}
 
-		out_be32(&qe_immr->cp.cecdr,
-			 immrbar_virt_to_phys((void *)cmd_input));
+		out_be32(&qe_immr->cp.cecdr, cmd_input);
 		out_be32(&qe_immr->cp.cecr,
 			 (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
 			  mcn_protocol << mcn_shift));
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
index 916c9e5..ac12a44 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -207,6 +207,7 @@
 		case QE_CLK18:	source = 8; break;
 		case QE_CLK7:	source = 9; break;
 		case QE_CLK8:	source = 10; break;
+		case QE_CLK16:	source = 11; break;
 		default:	source = -1; break;
 		}
 		break;
@@ -222,6 +223,7 @@
 		case QE_CLK22:	source = 8; break;
 		case QE_CLK7:	source = 9; break;
 		case QE_CLK8:	source = 10; break;
+		case QE_CLK16:	source = 11; break;
 		default: 	source = -1; break;
 		}
 		break;
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
index c2be734..75fa310 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -163,7 +163,7 @@
 
 	/* check if the UCC port number is in range. */
 	if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
-		uccf_err("ucc_fast_init: Illagal UCC number!");
+		uccf_err("ucc_fast_init: Illegal UCC number!");
 		return -EINVAL;
 	}
 
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
index 1fb88ef..a49da6b 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
@@ -152,7 +152,7 @@
 
 	/* check if the UCC port number is in range. */
 	if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) {
-		uccs_err("ucc_slow_init: Illagal UCC number!");
+		uccs_err("ucc_slow_init: Illegal UCC number!");
 		return -EINVAL;
 	}
 
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c
index 11de090..97f37ef 100644
--- a/arch/powerpc/sysdev/tsi108_dev.c
+++ b/arch/powerpc/sysdev/tsi108_dev.c
@@ -48,7 +48,7 @@
 	tsi = of_find_node_by_type(NULL, "tsi-bridge");
 	if (tsi) {
 		unsigned int size;
-		void *prop = get_property(tsi, "reg", &size);
+		const void *prop = get_property(tsi, "reg", &size);
 		tsi108_csr_base = of_translate_address(tsi, prop);
 		of_node_put(tsi);
 	};
@@ -79,7 +79,7 @@
 		hw_info tsi_eth_data;
 		unsigned int *id;
 		unsigned int *phy_id;
-		void *mac_addr;
+		const void *mac_addr;
 		phandle *ph;
 
 		memset(r, 0, sizeof(r));
diff --git a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S
index 0c02155..1bbbcd2 100644
--- a/arch/ppc/boot/simple/relocate.S
+++ b/arch/ppc/boot/simple/relocate.S
@@ -154,8 +154,8 @@
 
 start_ldr:
 /* Clear all of BSS and set up stack for C calls */
-	lis	r3,edata@h
-	ori	r3,r3,edata@l
+	lis	r3,__bss_start@h
+	ori	r3,r3,__bss_start@l
 	lis	r4,end@h
 	ori	r4,r4,end@l
 	subi	r3,r3,4
@@ -163,7 +163,7 @@
 	li	r0,0
 50:	stwu	r0,4(r3)
 	cmpw	cr0,r3,r4
-	bne	50b
+	blt	50b
 90:	mr	r9,r1		/* Save old stack pointer (in case it matters) */
 	lis	r1,.stack@h
 	ori	r1,r1,.stack@l
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 5f66840..d319f9b 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -110,80 +110,6 @@
 	blr
 
 /*
- * identify_cpu,
- * called with r3 = data offset and r4 = CPU number
- * doesn't change r3
- */
-_GLOBAL(identify_cpu)
-	addis	r8,r3,cpu_specs@ha
-	addi	r8,r8,cpu_specs@l
-	mfpvr	r7
-1:
-	lwz	r5,CPU_SPEC_PVR_MASK(r8)
-	and	r5,r5,r7
-	lwz	r6,CPU_SPEC_PVR_VALUE(r8)
-	cmplw	0,r6,r5
-	beq	1f
-	addi	r8,r8,CPU_SPEC_ENTRY_SIZE
-	b	1b
-1:
-	addis	r6,r3,cur_cpu_spec@ha
-	addi	r6,r6,cur_cpu_spec@l
-	sub	r8,r8,r3
-	stw	r8,0(r6)
-	blr
-
-/*
- * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
- * and writes nop's over sections of code that don't apply for this cpu.
- * r3 = data offset (not changed)
- */
-_GLOBAL(do_cpu_ftr_fixups)
-	/* Get CPU 0 features */
-	addis	r6,r3,cur_cpu_spec@ha
-	addi	r6,r6,cur_cpu_spec@l
-	lwz	r4,0(r6)
-	add	r4,r4,r3
-	lwz	r4,CPU_SPEC_FEATURES(r4)
-
-	/* Get the fixup table */
-	addis	r6,r3,__start___ftr_fixup@ha
-	addi	r6,r6,__start___ftr_fixup@l
-	addis	r7,r3,__stop___ftr_fixup@ha
-	addi	r7,r7,__stop___ftr_fixup@l
-
-	/* Do the fixup */
-1:	cmplw	0,r6,r7
-	bgelr
-	addi	r6,r6,16
-	lwz	r8,-16(r6)	/* mask */
-	and	r8,r8,r4
-	lwz	r9,-12(r6)	/* value */
-	cmplw	0,r8,r9
-	beq	1b
-	lwz	r8,-8(r6)	/* section begin */
-	lwz	r9,-4(r6)	/* section end */
-	subf.	r9,r8,r9
-	beq	1b
-	/* write nops over the section of code */
-	/* todo: if large section, add a branch at the start of it */
-	srwi	r9,r9,2
-	mtctr	r9
-	add	r8,r8,r3
-	lis	r0,0x60000000@h	/* nop */
-3:	stw	r0,0(r8)
-	andi.	r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
-	beq	2f
-	dcbst	0,r8		/* suboptimal, but simpler */
-	sync
-	icbi	0,r8
-2:	addi	r8,r8,4
-	bdnz	3b
-	sync			/* additional sync needed on g4 */
-	isync
-	b	1b
-
-/*
  * call_setup_cpu - call the setup_cpu function for this cpu
  * r3 = data offset, r24 = cpu number
  *
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 75fe138..27faeca 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -38,6 +38,7 @@
 #include <asm/nvram.h>
 #include <asm/xmon.h>
 #include <asm/ocp.h>
+#include <asm/prom.h>
 
 #define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \
 		      defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \
@@ -53,8 +54,6 @@
 
 extern void platform_init(unsigned long r3, unsigned long r4,
 		unsigned long r5, unsigned long r6, unsigned long r7);
-extern void identify_cpu(unsigned long offset, unsigned long cpu);
-extern void do_cpu_ftr_fixups(unsigned long offset);
 extern void reloc_got2(unsigned long offset);
 
 extern void ppc6xx_idle(void);
@@ -301,6 +300,7 @@
 {
  	unsigned long phys;
 	unsigned long offset = reloc_offset();
+	struct cpu_spec *spec;
 
  	/* Default */
  	phys = offset + KERNELBASE;
@@ -313,8 +313,10 @@
 	 * Identify the CPU type and fix up code sections
 	 * that depend on which cpu we have.
 	 */
-	identify_cpu(offset, 0);
-	do_cpu_ftr_fixups(offset);
+	spec = identify_cpu(offset);
+	do_feature_fixups(spec->cpu_features,
+			  PTRRELOC(&__start___ftr_fixup),
+			  PTRRELOC(&__stop___ftr_fixup));
 
 	return phys;
 }
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index aafc8e8..9661a91 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -708,7 +708,7 @@
 
 void alignment_exception(struct pt_regs *regs)
 {
-	int fixed;
+	int sig, code, fixed = 0;
 
 	fixed = fix_alignment(regs);
 	if (fixed == 1) {
@@ -717,14 +717,16 @@
 		return;
 	}
 	if (fixed == -EFAULT) {
-		/* fixed == -EFAULT means the operand address was bad */
-		if (user_mode(regs))
-			_exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
-		else
-			bad_page_fault(regs, regs->dar, SIGSEGV);
-		return;
+		sig = SIGSEGV;
+		code = SEGV_ACCERR;
+	} else {
+		sig = SIGBUS;
+		code = BUS_ADRALN;
 	}
-	_exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+	if (user_mode(regs))
+		_exception(sig, regs, code, regs->dar);
+	else
+		bad_page_fault(regs, regs->dar, sig);
 }
 
 void StackOverflow(struct pt_regs *regs)
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 095fd33..16e8661 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -115,13 +115,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
 
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 608193c..245b81b 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -236,9 +236,6 @@
 	  This allows you to specify the maximum frame size a function may
 	  have without the compiler complaining about it.
 
-config ARCH_POPULATES_NODE_MAP
-	def_bool y
-
 source "mm/Kconfig"
 
 comment "I/O subsystem configuration"
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index 45c9fa7..af1e8fc 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -310,6 +310,7 @@
 	if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) {
 		return -EFAULT;
 	}
+	interval = 0;
 	sscanf(buf, "%i", &interval);
 	if (interval <= 0) {
 		P_ERROR("Timer CPU interval has to be > 0!\n");
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index c313e9a..7cd51e7 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -119,7 +119,6 @@
 CONFIG_CHECK_STACK=y
 CONFIG_STACK_GUARD=256
 # CONFIG_WARN_STACK is not set
-CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 2001767..5b33f82 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -757,7 +757,9 @@
 			    put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)))
 				error = -EFAULT;
 		}
-		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
+		if (copy_to_user(args->__unused, tmp.__unused,
+				 sizeof(tmp.__unused)))
+			error = -EFAULT;
 	}
 	return error;
 }
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index d49b876..861888a 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -169,12 +169,12 @@
 		compat_old_sigset_t mask;
 		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
 		    __get_user(sa_handler, &act->sa_handler) ||
-		    __get_user(sa_restorer, &act->sa_restorer))
+		    __get_user(sa_restorer, &act->sa_restorer) ||
+		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+		    __get_user(mask, &act->sa_mask))
 			return -EFAULT;
 		new_ka.sa.sa_handler = (__sighandler_t) sa_handler;
 		new_ka.sa.sa_restorer = (void (*)(void)) sa_restorer;
-		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		__get_user(mask, &act->sa_mask);
 		siginitset(&new_ka.sa.sa_mask, mask);
         }
 
@@ -185,10 +185,10 @@
 		sa_restorer = (unsigned long) old_ka.sa.sa_restorer;
 		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
 		    __put_user(sa_handler, &oact->sa_handler) ||
-		    __put_user(sa_restorer, &oact->sa_restorer))
+		    __put_user(sa_restorer, &oact->sa_restorer) ||
+		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
 			return -EFAULT;
-		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
         }
 
 	return ret;
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index cb0efae..71e54ef 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1664,4 +1664,4 @@
 	llgtr	%r2,%r2			# unsigned *
 	llgtr	%r3,%r3			# unsigned *
 	llgtr	%r4,%r4			# struct getcpu_cache *
-	jg	sys_tee
+	jg	sys_getcpu
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 49f2b68..2aa13e8 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -70,6 +70,7 @@
 #define CHUNK_READ_WRITE 0
 #define CHUNK_READ_ONLY 1
 volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
+unsigned long __initdata zholes_size[MAX_NR_ZONES];
 static unsigned long __initdata memory_end;
 
 /*
@@ -357,6 +358,21 @@
  */
 void (*pm_power_off)(void) = machine_power_off;
 
+static void __init
+add_memory_hole(unsigned long start, unsigned long end)
+{
+	unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT;
+
+	if (end <= dma_pfn)
+		zholes_size[ZONE_DMA] += end - start + 1;
+	else if (start > dma_pfn)
+		zholes_size[ZONE_NORMAL] += end - start + 1;
+	else {
+		zholes_size[ZONE_DMA] += dma_pfn - start + 1;
+		zholes_size[ZONE_NORMAL] += end - dma_pfn;
+	}
+}
+
 static int __init early_parse_mem(char *p)
 {
 	memory_end = memparse(p, &p);
@@ -434,7 +450,7 @@
 		lc->extended_save_area_addr = (__u32)
 			__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
 		/* enable extended save area */
-		ctl_set_bit(14, 29);
+		__ctl_set_bit(14, 29);
 	}
 #endif
 	set_prefix((u32)(unsigned long) lc);
@@ -478,6 +494,7 @@
 {
         unsigned long bootmap_size;
 	unsigned long start_pfn, end_pfn, init_pfn;
+	unsigned long last_rw_end;
 	int i;
 
 	/*
@@ -533,27 +550,39 @@
 	/*
 	 * Register RAM areas with the bootmem allocator.
 	 */
+	last_rw_end = start_pfn;
 
 	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
-		unsigned long start_chunk, end_chunk, pfn;
+		unsigned long start_chunk, end_chunk;
 
 		if (memory_chunk[i].type != CHUNK_READ_WRITE)
 			continue;
-		start_chunk = PFN_DOWN(memory_chunk[i].addr);
-		end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size) - 1;
-		end_chunk = min(end_chunk, end_pfn);
-		if (start_chunk >= end_chunk)
-			continue;
-		add_active_range(0, start_chunk, end_chunk);
-		pfn = max(start_chunk, start_pfn);
-		for (; pfn <= end_chunk; pfn++)
-			page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY);
+		start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1);
+		start_chunk >>= PAGE_SHIFT;
+		end_chunk = (memory_chunk[i].addr + memory_chunk[i].size);
+		end_chunk >>= PAGE_SHIFT;
+		if (start_chunk < start_pfn)
+			start_chunk = start_pfn;
+		if (end_chunk > end_pfn)
+			end_chunk = end_pfn;
+		if (start_chunk < end_chunk) {
+			/* Initialize storage key for RAM pages */
+			for (init_pfn = start_chunk ; init_pfn < end_chunk;
+			     init_pfn++)
+				page_set_storage_key(init_pfn << PAGE_SHIFT,
+						     PAGE_DEFAULT_KEY);
+			free_bootmem(start_chunk << PAGE_SHIFT,
+				     (end_chunk - start_chunk) << PAGE_SHIFT);
+			if (last_rw_end < start_chunk)
+				add_memory_hole(last_rw_end, start_chunk - 1);
+			last_rw_end = end_chunk;
+		}
 	}
 
 	psw_set_key(PAGE_DEFAULT_KEY);
 
-	free_bootmem_with_active_regions(0, max_pfn);
-	reserve_bootmem(0, PFN_PHYS(start_pfn));
+	if (last_rw_end < end_pfn - 1)
+		add_memory_hole(last_rw_end, end_pfn - 1);
 
 	/*
 	 * Reserve the bootmem bitmap itself as well. We do this in two
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 4392a77..4c8a795 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -80,10 +80,10 @@
 		old_sigset_t mask;
 		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
 		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
+		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+		    __get_user(mask, &act->sa_mask))
 			return -EFAULT;
-		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		__get_user(mask, &act->sa_mask);
 		siginitset(&new_ka.sa.sa_mask, mask);
 	}
 
@@ -92,10 +92,10 @@
 	if (!ret && oact) {
 		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
 		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
 			return -EFAULT;
-		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
 	}
 
 	return ret;
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 66375a5..92ecffb 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -462,7 +462,8 @@
 		local_irq_enable();
 
 	if (regs->psw.mask & PSW_MASK_PSTATE) {
-		get_user(*((__u16 *) opcode), (__u16 __user *) location);
+		if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
+			return;
 		if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
 			if (current->ptrace & PT_PTRACED)
 				force_sig(SIGTRAP, current);
@@ -470,20 +471,25 @@
 				signal = SIGILL;
 #ifdef CONFIG_MATHEMU
 		} else if (opcode[0] == 0xb3) {
-			get_user(*((__u16 *) (opcode+2)), location+1);
+			if (get_user(*((__u16 *) (opcode+2)), location+1))
+				return;
 			signal = math_emu_b3(opcode, regs);
                 } else if (opcode[0] == 0xed) {
-			get_user(*((__u32 *) (opcode+2)),
-				 (__u32 __user *)(location+1));
+			if (get_user(*((__u32 *) (opcode+2)),
+				     (__u32 __user *)(location+1)))
+				return;
 			signal = math_emu_ed(opcode, regs);
 		} else if (*((__u16 *) opcode) == 0xb299) {
-			get_user(*((__u16 *) (opcode+2)), location+1);
+			if (get_user(*((__u16 *) (opcode+2)), location+1))
+				return;
 			signal = math_emu_srnm(opcode, regs);
 		} else if (*((__u16 *) opcode) == 0xb29c) {
-			get_user(*((__u16 *) (opcode+2)), location+1);
+			if (get_user(*((__u16 *) (opcode+2)), location+1))
+				return;
 			signal = math_emu_stfpc(opcode, regs);
 		} else if (*((__u16 *) opcode) == 0xb29d) {
-			get_user(*((__u16 *) (opcode+2)), location+1);
+			if (get_user(*((__u16 *) (opcode+2)), location+1))
+				return;
 			signal = math_emu_lfpc(opcode, regs);
 #endif
 		} else
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index af9e69a0..fe0f2e9 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -83,13 +83,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index d998917..e1881c3 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -84,6 +84,7 @@
         printk("%d pages swap cached\n",cached);
 }
 
+extern unsigned long __initdata zholes_size[];
 /*
  * paging_init() sets up the page tables
  */
@@ -100,15 +101,16 @@
         unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE;
         static const int ssm_mask = 0x04000000L;
 	unsigned long ro_start_pfn, ro_end_pfn;
-	unsigned long max_zone_pfns[MAX_NR_ZONES];
+	unsigned long zones_size[MAX_NR_ZONES];
 
 	ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata);
 	ro_end_pfn = PFN_UP((unsigned long)&__end_rodata);
 
-	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
-	max_zone_pfns[ZONE_DMA] = max_low_pfn;
-	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
-	free_area_init_nodes(max_zone_pfns);
+	memset(zones_size, 0, sizeof(zones_size));
+	zones_size[ZONE_DMA] = max_low_pfn;
+	free_area_init_node(0, &contig_page_data, zones_size,
+			    __pa(PAGE_OFFSET) >> PAGE_SHIFT,
+			    zholes_size);
 
 	/* unmap whole virtual address space */
 	
@@ -168,16 +170,26 @@
         unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) |
           _KERN_REGION_TABLE;
 	static const int ssm_mask = 0x04000000L;
+	unsigned long zones_size[MAX_NR_ZONES];
+	unsigned long dma_pfn, high_pfn;
 	unsigned long ro_start_pfn, ro_end_pfn;
-	unsigned long max_zone_pfns[MAX_NR_ZONES];
 
+	memset(zones_size, 0, sizeof(zones_size));
+	dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT;
+	high_pfn = max_low_pfn;
 	ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata);
 	ro_end_pfn = PFN_UP((unsigned long)&__end_rodata);
 
-	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
-	max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS);
-	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
-	free_area_init_nodes(max_zone_pfns);
+	if (dma_pfn > high_pfn)
+		zones_size[ZONE_DMA] = high_pfn;
+	else {
+		zones_size[ZONE_DMA] = dma_pfn;
+		zones_size[ZONE_NORMAL] = high_pfn - dma_pfn;
+	}
+
+	/* Initialize mem_map[].  */
+	free_area_init_node(0, &contig_page_data, zones_size,
+			    __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
 
 	/*
 	 * map whole physical memory to virtual memory (identity mapping) 
diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c
index 2191791..d146cda 100644
--- a/arch/sh/boards/hp6xx/hp6xx_apm.c
+++ b/arch/sh/boards/hp6xx/hp6xx_apm.c
@@ -14,7 +14,7 @@
 #include <asm/io.h>
 #include <asm/apm.h>
 #include <asm/adc.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 
 #define SH7709_PGDR			0xa400012c
 
diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c
index 83d3272..d194773 100644
--- a/arch/sh/boards/hp6xx/pm.c
+++ b/arch/sh/boards/hp6xx/pm.c
@@ -12,7 +12,7 @@
 #include <linux/time.h>
 #include <asm/io.h>
 #include <asm/hd64461.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 #include <asm/cpu/dac.h>
 #include <asm/pm.h>
 
diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c
index 2d3a5b4..b5a9664 100644
--- a/arch/sh/boards/hp6xx/setup.c
+++ b/arch/sh/boards/hp6xx/setup.c
@@ -13,7 +13,7 @@
 #include <asm/hd64461.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 #include <asm/cpu/dac.h>
 
 #define	SCPCR	0xa4000116
diff --git a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c
index 51f3f65..bb9aa0d 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/io.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/io.c
@@ -15,7 +15,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <asm/io.h>
-#include <asm/hs7751rvoip/hs7751rvoip.h>
+#include <asm/hs7751rvoip.h>
 #include <asm/addrspace.h>
 
 extern void *area6_io8_base;	/* Area 6 8bit I/O Base address */
diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c
index c617b18..943f93a 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/irq.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c
@@ -14,7 +14,7 @@
 #include <linux/irq.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/hs7751rvoip/hs7751rvoip.h>
+#include <asm/hs7751rvoip.h>
 
 static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7};
 
diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c
index 0414c15..f7d0e30 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/setup.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c
@@ -10,22 +10,21 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
 #include <linux/pm.h>
+#include <asm/hs7751rvoip.h>
 #include <asm/io.h>
-#include <asm/hs7751rvoip/hs7751rvoip.h>
 #include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/irq.h>
+
+static struct ipr_data hs77501rvoip_ipr_map[] = {
+#if defined(CONFIG_HS7751RVOIP_CODEC)
+	{ DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+#endif
+};
 
 static void __init hs7751rvoip_init_irq(void)
 {
-#if defined(CONFIG_HS7751RVOIP_CODEC)
-	make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-	make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-#endif
+	make_ipr_irq(hs77501rvoip_ipr_map, ARRAY_SIZE(hs77501rvoip_ipr_map));
 
 	init_hs7751rvoip_IRQ();
 }
diff --git a/arch/sh/boards/renesas/r7780rp/io.c b/arch/sh/boards/renesas/r7780rp/io.c
index db92d6e..311cccc 100644
--- a/arch/sh/boards/renesas/r7780rp/io.c
+++ b/arch/sh/boards/renesas/r7780rp/io.c
@@ -11,7 +11,7 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <asm/r7780rp.h>
 #include <asm/addrspace.h>
 #include <asm/io.h>
 
diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c
index b544772..aa15ec5 100644
--- a/arch/sh/boards/renesas/r7780rp/irq.c
+++ b/arch/sh/boards/renesas/r7780rp/irq.c
@@ -10,7 +10,8 @@
  */
 #include <linux/init.h>
 #include <linux/irq.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <asm/r7780rp.h>
 
 #ifdef CONFIG_SH_R7780MP
 static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
@@ -32,7 +33,7 @@
 }
 
 static struct irq_chip r7780rp_irq_chip __read_mostly = {
-	.name		= "r7780rp",
+	.name		= "R7780RP",
 	.mask		= disable_r7780rp_irq,
 	.unmask		= enable_r7780rp_irq,
 	.mask_ack	= disable_r7780rp_irq,
@@ -47,8 +48,8 @@
 
 	for (i = 0; i < 15; i++) {
 		disable_irq_nosync(i);
-		set_irq_chip_and_handler(i, &r7780rp_irq_chip,
-					 handle_level_irq);
+		set_irq_chip_and_handler_name(i, &r7780rp_irq_chip,
+					      handle_level_irq, "level");
 		enable_r7780rp_irq(i);
 	}
 }
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index b941aa0..c331cae 100644
--- a/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -13,7 +13,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <asm/machvec.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <asm/r7780rp.h>
 #include <asm/clock.h>
 #include <asm/io.h>
 
diff --git a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c
index 135aa0b..f2507a8 100644
--- a/arch/sh/boards/renesas/rts7751r2d/io.c
+++ b/arch/sh/boards/renesas/rts7751r2d/io.c
@@ -11,8 +11,8 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/pci.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <asm/rts7751r2d.h>
 #include <asm/addrspace.h>
 
 /*
diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c
index c915e7a..cb0eb20 100644
--- a/arch/sh/boards/renesas/rts7751r2d/irq.c
+++ b/arch/sh/boards/renesas/rts7751r2d/irq.c
@@ -8,12 +8,10 @@
  * Modified for RTS7751R2D by
  * Atom Create Engineering Co., Ltd. 2002.
  */
-
 #include <linux/init.h>
 #include <linux/irq.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
+#include <linux/io.h>
+#include <asm/rts7751r2d.h>
 
 #if defined(CONFIG_RTS7751R2D_REV11)
 static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0};
diff --git a/arch/sh/boards/renesas/rts7751r2d/led.c b/arch/sh/boards/renesas/rts7751r2d/led.c
index a7ce66c..509f548 100644
--- a/arch/sh/boards/renesas/rts7751r2d/led.c
+++ b/arch/sh/boards/renesas/rts7751r2d/led.c
@@ -8,13 +8,9 @@
  *
  * This file contains Renesas Technology Sales RTS7751R2D specific LED code.
  */
-
-#include <asm/io.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
-
-#ifdef CONFIG_HEARTBEAT
-
+#include <linux/io.h>
 #include <linux/sched.h>
+#include <asm/rts7751r2d.h>
 
 /* Cycle the LED's in the clasic Knightriger/Sun pattern */
 void heartbeat_rts7751r2d(void)
@@ -46,10 +42,3 @@
 	else
 		bit--;
 }
-#endif /* CONFIG_HEARTBEAT */
-
-void rts7751r2d_led(unsigned short value)
-{
-	ctrl_outw(value, PA_OUTPORT);
-}
-
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index 20597a6..5c042d3 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -12,9 +12,9 @@
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
 #include <linux/pm.h>
-#include <asm/io.h>
 #include <asm/machvec.h>
 #include <asm/mach/rts7751r2d.h>
+#include <asm/io.h>
 #include <asm/voyagergx.h>
 
 extern void heartbeat_rts7751r2d(void);
diff --git a/arch/sh/boards/renesas/sh7710voipgw/setup.c b/arch/sh/boards/renesas/sh7710voipgw/setup.c
index e57e7af..180810b 100644
--- a/arch/sh/boards/renesas/sh7710voipgw/setup.c
+++ b/arch/sh/boards/renesas/sh7710voipgw/setup.c
@@ -13,6 +13,51 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
+static struct ipr_data sh7710voipgw_ipr_map[] = {
+	{ TIMER2_IRQ, TIMER2_IPR_ADDR, TIMER2_IPR_POS, TIMER2_PRIORITY },
+	{ WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY },
+
+	/* SCIF0 */
+	{ SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+	{ SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+	{ SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+	{ SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+
+	/* DMAC-1 */
+	{ DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+
+	/* DMAC-2 */
+	{ DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+	{ DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+
+	/* IPSEC */
+	{ IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY },
+
+	/* EDMAC */
+	{ EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, EDMAC0_PRIORITY },
+	{ EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, EDMAC1_PRIORITY },
+	{ EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, EDMAC2_PRIORITY },
+
+	/* SIOF0 */
+	{ SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+	{ SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+	{ SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+	{ SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+
+	/* SIOF1 */
+	{ SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
+	{ SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
+	{ SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
+	{ SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
+
+	/* SLIC IRQ's */
+	{ IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY },
+	{ IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY },
+};
+
 /*
  * Initialize IRQ setting
  */
@@ -37,65 +82,7 @@
 	 */
 	ctrl_outw(0x2aa, INTC_ICR1);
 
-	/* Now make IPR interrupts */
-	make_ipr_irq(TIMER2_IRQ, TIMER2_IPR_ADDR,
-			TIMER2_IPR_POS, TIMER2_PRIORITY);
-	make_ipr_irq(WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY);
-
-	/* SCIF0 */
-	make_ipr_irq(SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
-			SCIF0_PRIORITY);
-	make_ipr_irq(SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
-			SCIF0_PRIORITY);
-	make_ipr_irq(SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
-			SCIF0_PRIORITY);
-	make_ipr_irq(SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
-			SCIF0_PRIORITY);
-
-	/* DMAC-1 */
-	make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-	make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-	make_ipr_irq(DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-	make_ipr_irq(DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-
-	/* DMAC-2 */
-	make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
-	make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
-
-	/* IPSEC */
-	make_ipr_irq(IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY);
-
-	/* EDMAC */
-	make_ipr_irq(EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS,
-			EDMAC0_PRIORITY);
-	make_ipr_irq(EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS,
-			EDMAC1_PRIORITY);
-	make_ipr_irq(EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS,
-			EDMAC2_PRIORITY);
-
-	/* SIOF0 */
-	make_ipr_irq(SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
-			SIOF0_PRIORITY);
-	make_ipr_irq(SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
-			SIOF0_PRIORITY);
-	make_ipr_irq(SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
-			SIOF0_PRIORITY);
-	make_ipr_irq(SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
-			SIOF0_PRIORITY);
-
-	/* SIOF1 */
-	make_ipr_irq(SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
-			SIOF1_PRIORITY);
-	make_ipr_irq(SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
-			SIOF1_PRIORITY);
-	make_ipr_irq(SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
-			SIOF1_PRIORITY);
-	make_ipr_irq(SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
-			SIOF1_PRIORITY);
-
-	/* SLIC IRQ's */
-	make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
-	make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
+	make_ipr_irq(sh7710voipgw_ipr_map, ARRAY_SIZE(sh7710voipgw_ipr_map));
 }
 
 /*
diff --git a/arch/sh/boards/se/7300/irq.c b/arch/sh/boards/se/7300/irq.c
index ad1034f..1279d77 100644
--- a/arch/sh/boards/se/7300/irq.c
+++ b/arch/sh/boards/se/7300/irq.c
@@ -13,6 +13,17 @@
 #include <asm/io.h>
 #include <asm/se7300.h>
 
+static struct ipr_data se7300_ipr_map[] = {
+	/* PC_IRQ[0-3] -> IRQ0 (32) */
+	{ IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ },
+	/* A_IRQ[0-3] -> IRQ1 (33) */
+	{ IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ },
+	{ SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+	{ DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+};
+
 /*
  * Initialize IRQ setting
  */
@@ -23,14 +34,7 @@
 	ctrl_outw(0xa000, INTC_ICR1);	        /* IRQ mode; IRQ0,1 enable.    */
 	ctrl_outw(0x0000, PORT_PFCR);	        /* use F for IRQ[3:0] and SIU. */
 
-	/* PC_IRQ[0-3] -> IRQ0 (32) */
-	make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ);
-	/* A_IRQ[0-3] -> IRQ1 (33) */
-	make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ);
-	make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
-	make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
+	make_ipr_irq(se7300_ipr_map, ARRAY_SIZE(se7300_ipr_map));
 
 	ctrl_outw(0x2000, PA_MRSHPC + 0x0c);	/* mrshpc irq enable */
 }
diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c
index 2c62b8e..e7200c5 100644
--- a/arch/sh/boards/se/73180/irq.c
+++ b/arch/sh/boards/se/73180/irq.c
@@ -87,13 +87,38 @@
 	return irq;
 }
 
+static struct ipr_data se73180_siof0_ipr_map[] = {
+	{ SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+};
+static struct ipr_data se73180_vpu_ipr_map[] = {
+	{ VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8 },
+};
+static struct ipr_data se73180_other_ipr_map[] = {
+	{ DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+	{ IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+	{ IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+	{ IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+	{ IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+	{ SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+	{ SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY },
+
+	/* VIO interrupt */
+	{ CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+	{ BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+	{ VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+
+	{ LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY },
+};
+
 /*
  * Initialize IRQ setting
  */
 void __init
 init_73180se_IRQ(void)
 {
-	make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
+	make_ipr_irq(se73180_siof0_ipr_map, ARRAY_SIZE(se73180_siof0_ipr_map));
 
 	ctrl_outw(0x2000, 0xb03fffec);	/* mrshpc irq enable */
 	ctrl_outw(0x2000, 0xb07fffec);	/* mrshpc irq enable */
@@ -101,27 +126,11 @@
 	ctrl_outw(2 << ((7 - 5) * 2), INTC_ICR1);	/* low-level irq */
 	make_intreq_irq(10);
 
-	make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8);
+	make_ipr_irq(se73180_vpu_ipr_map, ARRAY_SIZE(se73180_vpu_ipr_map));
 
 	ctrl_outb(0x0f, INTC_IMCR5);	/* enable SCIF IRQ */
 
-	make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
-	make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
-	make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
-		     IIC0_PRIORITY);
-	make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
-		     IIC0_PRIORITY);
-	make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
-	make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
-	make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY);
+	make_ipr_irq(se73180_other_ipr_map, ARRAY_SIZE(se73180_other_ipr_map));
 
-	/* VIO interrupt */
-	make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-	make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-	make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-
-	make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY);
 	ctrl_outw(0x2000, PA_MRSHPC + 0x0c);	/* mrshpc irq enable */
 }
diff --git a/arch/sh/boards/se/7343/irq.c b/arch/sh/boards/se/7343/irq.c
index 288b62f..360153e 100644
--- a/arch/sh/boards/se/7343/irq.c
+++ b/arch/sh/boards/se/7343/irq.c
@@ -102,6 +102,51 @@
 static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade",
 				NULL, NULL};
 
+static struct ipr_data se7343_irq5_ipr_map[] = {
+	{ IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY },
+};
+static struct ipr_data se7343_siof0_vpu_ipr_map[] = {
+	{ SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+	{ VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8 },
+};
+static struct ipr_data se7343_other_ipr_map[] = {
+	{ DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+	{ DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+
+	/* I2C block */
+	{ IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+	{ IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+	{ IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+	{ IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+
+	{ IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY },
+	{ IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY },
+	{ IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY },
+	{ IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY },
+
+	/* SIOF */
+	{ SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+
+	/* SIU */
+	{ SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY },
+
+	/* VIO interrupt */
+	{ CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+	{ BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+	{ VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+
+	/*MFI interrupt*/
+
+	{ MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY },
+
+	/* LCD controller */
+	{ LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY },
+};
+
 /*
  * Initialize IRQ setting
  */
@@ -138,54 +183,17 @@
 	/* Setup all external interrupts to be active low */
 	ctrl_outw(0xaaaa, INTC_ICR1);
 
-	make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY);
+	make_ipr_irq(se7343_irq5_ipr_map, ARRAY_SIZE(se7343_irq5_ipr_map));
+
 	setup_irq(IRQ5_IRQ, &irq5);
 	/* Set port control to use IRQ5 */
 	*(u16 *)0xA4050108 &= ~0xc;
 
-	make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
-	make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8);
+	make_ipr_irq(se7343_siof0_vpu_ipr_map, ARRAY_SIZE(se7343_siof0_vpu_ipr_map));
 
 	ctrl_outb(0x0f, INTC_IMCR5);	/* enable SCIF IRQ */
 
-	make_ipr_irq(DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
-	make_ipr_irq(DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
+	make_ipr_irq(se7343_other_ipr_map, ARRAY_SIZE(se7343_other_ipr_map));
 
-	/* I2C block */
-	make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
-	make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
-		     IIC0_PRIORITY);
-	make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
-		     IIC0_PRIORITY);
-	make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
-
-	make_ipr_irq(IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
-	make_ipr_irq(IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
-		     IIC1_PRIORITY);
-	make_ipr_irq(IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
-		     IIC1_PRIORITY);
-	make_ipr_irq(IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
-
-	/* SIOF */
-	make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
-
-	/* SIU */
-	make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY);
-
-	/* VIO interrupt */
-	make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-	make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-	make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-
-	/*MFI interrupt*/
-
-	make_ipr_irq(MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY);
-
-	/* LCD controller */
-	make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY);
 	ctrl_outw(0x2000, PA_MRSHPC + 0x0c);	/* mrshpc irq enable */
 }
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c
index cff6700..fcd7cd7 100644
--- a/arch/sh/boards/se/770x/irq.c
+++ b/arch/sh/boards/se/770x/irq.c
@@ -13,6 +13,48 @@
 #include <asm/io.h>
 #include <asm/se.h>
 
+static struct ipr_data se770x_ipr_map[] = {
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
+	/* This is default value */
+	{ 0xf-0x2, BCR_ILCRA, 2, 0x2 },
+	{ 0xf-0xa, BCR_ILCRA, 1, 0xa },
+	{ 0xf-0x5, BCR_ILCRB, 0, 0x5 },
+	{ 0xf-0x8, BCR_ILCRC, 1, 0x8 },
+	{ 0xf-0xc, BCR_ILCRC, 0, 0xc },
+	{ 0xf-0xe, BCR_ILCRD, 3, 0xe },
+	{ 0xf-0x3, BCR_ILCRD, 1, 0x3 }, /* LAN */
+	{ 0xf-0xd, BCR_ILCRE, 2, 0xd },
+	{ 0xf-0x9, BCR_ILCRE, 1, 0x9 },
+	{ 0xf-0x1, BCR_ILCRE, 0, 0x1 },
+	{ 0xf-0xf, BCR_ILCRF, 3, 0xf },
+	{ 0xf-0xb, BCR_ILCRF, 1, 0xb },
+	{ 0xf-0x7, BCR_ILCRG, 3, 0x7 },
+	{ 0xf-0x6, BCR_ILCRG, 2, 0x6 },
+	{ 0xf-0x4, BCR_ILCRG, 1, 0x4 },
+#else
+	{ 14, BCR_ILCRA, 2, 0x0f-14 },
+	{ 12, BCR_ILCRA, 1, 0x0f-12 },
+	{  8, BCR_ILCRB, 1, 0x0f- 8 },
+	{  6, BCR_ILCRC, 3, 0x0f- 6 },
+	{  5, BCR_ILCRC, 2, 0x0f- 5 },
+	{  4, BCR_ILCRC, 1, 0x0f- 4 },
+	{  3, BCR_ILCRC, 0, 0x0f- 3 },
+	{  1, BCR_ILCRD, 3, 0x0f- 1 },
+
+	{ 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */
+
+	{  0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */
+	{ 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */
+	{  9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */
+	{  7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */
+
+	/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+	/* NOTE: #2 and #13 are not used on PC */
+	{ 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */
+	{  2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */
+#endif
+};
+
 /*
  * Initialize IRQ setting
  */
@@ -38,42 +80,6 @@
 	ctrl_outw(0, BCR_ILCRE);
 	ctrl_outw(0, BCR_ILCRF);
 	ctrl_outw(0, BCR_ILCRG);
-	/* This is default value */
-	make_ipr_irq(0xf-0x2, BCR_ILCRA, 2, 0x2);
-	make_ipr_irq(0xf-0xa, BCR_ILCRA, 1, 0xa);
-	make_ipr_irq(0xf-0x5, BCR_ILCRB, 0, 0x5);
-	make_ipr_irq(0xf-0x8, BCR_ILCRC, 1, 0x8);
-	make_ipr_irq(0xf-0xc, BCR_ILCRC, 0, 0xc);
-	make_ipr_irq(0xf-0xe, BCR_ILCRD, 3, 0xe);
-	make_ipr_irq(0xf-0x3, BCR_ILCRD, 1, 0x3); /* LAN */
-	make_ipr_irq(0xf-0xd, BCR_ILCRE, 2, 0xd);
-	make_ipr_irq(0xf-0x9, BCR_ILCRE, 1, 0x9);
-	make_ipr_irq(0xf-0x1, BCR_ILCRE, 0, 0x1);
-	make_ipr_irq(0xf-0xf, BCR_ILCRF, 3, 0xf);
-	make_ipr_irq(0xf-0xb, BCR_ILCRF, 1, 0xb);
-	make_ipr_irq(0xf-0x7, BCR_ILCRG, 3, 0x7);
-	make_ipr_irq(0xf-0x6, BCR_ILCRG, 2, 0x6);
-	make_ipr_irq(0xf-0x4, BCR_ILCRG, 1, 0x4);
-#else
-        make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
-        make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
-        make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
-        make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
-        make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
-        make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
-        make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
-        make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
-
-        make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
-
-        make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
-        make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
-        make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
-        make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
-
-        /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
-        /* NOTE: #2 and #13 are not used on PC */
-        make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
-        make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
 #endif
+	make_ipr_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map));
 }
diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c
index c607b0a..e4c63a4 100644
--- a/arch/sh/boards/se/7751/irq.c
+++ b/arch/sh/boards/se/7751/irq.c
@@ -14,53 +14,50 @@
 #include <asm/irq.h>
 #include <asm/se7751.h>
 
+static struct ipr_data se7751_ipr_map[] = {
+  /* Leave old Solution Engine code in for reference. */
+#if defined(CONFIG_SH_SOLUTION_ENGINE)
+	/*
+	 * Super I/O (Just mimic PC):
+	 *  1: keyboard
+	 *  3: serial 0
+	 *  4: serial 1
+	 *  5: printer
+	 *  6: floppy
+	 *  8: rtc
+	 * 12: mouse
+	 * 14: ide0
+	 */
+	{ 14, BCR_ILCRA, 2, 0x0f-14 },
+	{ 12, BCR_ILCRA, 1, 0x0f-12 },
+	{  8, BCR_ILCRB, 1, 0x0f- 8 },
+	{  6, BCR_ILCRC, 3, 0x0f- 6 },
+	{  5, BCR_ILCRC, 2, 0x0f- 5 },
+	{  4, BCR_ILCRC, 1, 0x0f- 4 },
+	{  3, BCR_ILCRC, 0, 0x0f- 3 },
+	{  1, BCR_ILCRD, 3, 0x0f- 1 },
+
+	{ 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */
+
+	{  0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */
+	{ 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */
+	{  9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */
+	{  7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */
+
+	/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+	/* NOTE: #2 and #13 are not used on PC */
+	{ 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */
+	{  2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */
+#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
+	{ 13, BCR_ILCRD, 3, 2 },
+	/* Add additional entries here as drivers are added and tested. */
+#endif
+};
+
 /*
  * Initialize IRQ setting
  */
 void __init init_7751se_IRQ(void)
 {
-
-  /* Leave old Solution Engine code in for reference. */
-#if defined(CONFIG_SH_SOLUTION_ENGINE)
-        /*
-         * Super I/O (Just mimic PC):
-         *  1: keyboard
-         *  3: serial 0
-         *  4: serial 1
-         *  5: printer
-         *  6: floppy
-         *  8: rtc
-         * 12: mouse
-         * 14: ide0
-         */
-        make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
-        make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
-        make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
-        make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
-        make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
-        make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
-        make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
-        make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
-
-        make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
-
-        make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
-        make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
-        make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
-        make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
-
-        /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
-        /* NOTE: #2 and #13 are not used on PC */
-        make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
-        make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
-
-#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
-
-        make_ipr_irq(13, BCR_ILCRD, 3, 2);
-
-        /* Add additional calls to make_ipr_irq() as drivers are added
-         * and tested.
-         */
-#endif
-
+	make_ipr_irq(se7751_ipr_map, ARRAY_SIZE(se7751_ipr_map));
 }
diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c
index 137e2ba..5ad1e19 100644
--- a/arch/sh/boards/sh03/setup.c
+++ b/arch/sh/boards/sh03/setup.c
@@ -14,14 +14,17 @@
 #include <asm/sh03/sh03.h>
 #include <asm/addrspace.h>
 
+static struct ipr_data sh03_ipr_map[] = {
+	{ IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY },
+	{ IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY },
+	{ IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY },
+	{ IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY },
+};
+
 static void __init init_sh03_IRQ(void)
 {
 	ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
-
-	make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
-	make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
-	make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
-	make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
+	make_ipr_irq(sh03_ipr_map, ARRAY_SIZE(sh03_ipr_map));
 }
 
 extern void *cf_io_base;
diff --git a/arch/sh/boards/shmin/setup.c b/arch/sh/boards/shmin/setup.c
index 2f0c197..a31a1d1 100644
--- a/arch/sh/boards/shmin/setup.c
+++ b/arch/sh/boards/shmin/setup.c
@@ -7,7 +7,7 @@
  */
 #include <linux/init.h>
 #include <asm/machvec.h>
-#include <asm/shmin/shmin.h>
+#include <asm/shmin.h>
 #include <asm/clock.h>
 #include <asm/irq.h>
 #include <asm/io.h>
diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c
index 540d0bf..650fb36 100644
--- a/arch/sh/boards/snapgear/setup.c
+++ b/arch/sh/boards/snapgear/setup.c
@@ -68,6 +68,13 @@
  * IRL3 = crypto
  */
 
+static struct ipr_data snapgear_ipr_map[] = {
+	make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
+	make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
+	make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
+	make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
+};
+
 static void __init init_snapgear_IRQ(void)
 {
 	/* enable individual interrupt mode for externals */
@@ -75,10 +82,7 @@
 
 	printk("Setup SnapGear IRQ/IPR ...\n");
 
-	make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
-	make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
-	make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
-	make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
+	make_ipr_irq(snapgear_ipr_map, ARRAY_SIZE(snapgear_ipr_map));
 }
 
 /*
diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c
index 52b66d8..a6046d9 100644
--- a/arch/sh/boards/titan/setup.c
+++ b/arch/sh/boards/titan/setup.c
@@ -9,15 +9,19 @@
 
 extern void __init pcibios_init_platform(void);
 
+static struct ipr_data titan_ipr_map[] = {
+	{ TITAN_IRQ_WAN,	IRL0_IPR_ADDR,	IRL0_IPR_POS,	IRL0_PRIORITY },
+	{ TITAN_IRQ_LAN,	IRL1_IPR_ADDR,	IRL1_IPR_POS,	IRL1_PRIORITY },
+	{ TITAN_IRQ_MPCIA,	IRL2_IPR_ADDR,	IRL2_IPR_POS,	IRL2_PRIORITY },
+	{ TITAN_IRQ_USB,	IRL3_IPR_ADDR,	IRL3_IPR_POS,	IRL3_PRIORITY },
+};
+
 static void __init init_titan_irq(void)
 {
 	/* enable individual interrupt mode for externals */
 	ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
 
-	make_ipr_irq( TITAN_IRQ_WAN,   IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); /* PCIRQ0 */
-	make_ipr_irq( TITAN_IRQ_LAN,   IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); /* PCIRQ1 */
-	make_ipr_irq( TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); /* PCIRQ2 */
-	make_ipr_irq( TITAN_IRQ_USB,   IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); /* PCIRQ3 */
+	make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map));
 }
 
 struct sh_machine_vector mv_titan __initmv = {
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
index bf1b28f..f7ea700 100644
--- a/arch/sh/cchips/voyagergx/irq.c
+++ b/arch/sh/cchips/voyagergx/irq.c
@@ -17,29 +17,18 @@
 
     Copyright 2003 (c) Lineo uSolutions,Inc.
 */
-/* -------------------------------------------------------------------- */
-
-#undef DEBUG
-
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <linux/io.h>
 #include <asm/voyagergx.h>
+#include <asm/rts7751r2d.h>
 
 static void disable_voyagergx_irq(unsigned int irq)
 {
 	unsigned long val;
 	unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
 
-    	pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+    	pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
         val = inl(VOYAGER_INT_MASK);
         val &= ~mask;
         outl(val, VOYAGER_INT_MASK);
@@ -50,7 +39,7 @@
         unsigned long val;
         unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
 
-        pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+        pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
         val = inl(VOYAGER_INT_MASK);
         val |= mask;
         outl(val, VOYAGER_INT_MASK);
@@ -137,7 +126,7 @@
 		} else {
 			printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val);
 		}
-		pr_debug("voyagergx_irq_demux %d \n", i);
+		pr_debug("voyagergx_irq_demux %ld\n", i);
 #else
 		for (bit = 1, i = 0 ; i < VOYAGER_IRQ_NUM ; bit <<= 1, i++)
 			if (val & bit)
@@ -185,4 +174,3 @@
 
 	setup_irq(IRQ_VOYAGER, &irq0);
 }
-
diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig
index 2470364..34e2046 100644
--- a/arch/sh/configs/r7780rp_defconfig
+++ b/arch/sh/configs/r7780rp_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 11:32:47 2006
+# Linux kernel version: 2.6.19-rc3
+# Tue Oct 31 12:32:06 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -178,7 +179,7 @@
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_32BIT=y
+# CONFIG_32BIT is not set
 CONFIG_VSYSCALL=y
 CONFIG_HUGETLB_PAGE_SIZE_64K=y
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
@@ -229,9 +230,7 @@
 #
 # DMA support
 #
-CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=6
-# CONFIG_NR_DMA_CHANNELS_BOOL is not set
+# CONFIG_SH_DMA is not set
 
 #
 # Companion Chips
@@ -259,7 +258,7 @@
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 # CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/hda1"
+CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/sda1"
 
 #
 # Bus options
@@ -336,6 +335,7 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -441,76 +441,28 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
-CONFIG_IDE=m
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-CONFIG_BLK_DEV_IDE_SATA=y
-CONFIG_BLK_DEV_IDEDISK=m
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-CONFIG_BLK_DEV_IDESCSI=m
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=m
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=m
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_AEC62XX=m
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-CONFIG_BLK_DEV_PDC202XX_NEW=m
-# CONFIG_BLK_DEV_SVWKS is not set
-CONFIG_BLK_DEV_SIIMAGE=m
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
+CONFIG_SCSI=y
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
 # SCSI support type (disk, tape, CD-ROM)
 #
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
@@ -561,6 +513,7 @@
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -570,7 +523,55 @@
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
 #
-# CONFIG_ATA is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -840,7 +841,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -856,6 +856,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -868,14 +869,9 @@
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -959,7 +955,29 @@
 #
 # Real Time Clock
 #
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
 # DMA Engine support
@@ -984,6 +1002,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -991,6 +1010,7 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_ROMFS_FS is not set
@@ -1027,7 +1047,8 @@
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1159,6 +1180,7 @@
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
 CONFIG_FORCED_INLINING=y
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1178,9 +1200,9 @@
 #
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1191,7 +1213,7 @@
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
 CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 5e81754..41049cf 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 12:59:14 2006
+# Linux kernel version: 2.6.19-rc3
+# Mon Oct 30 18:04:49 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -23,7 +24,7 @@
 # General setup
 #
 CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
@@ -236,8 +237,8 @@
 CONFIG_HZ=250
 # CONFIG_KEXEC is not set
 # CONFIG_SMP is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 
 #
@@ -247,7 +248,7 @@
 CONFIG_BOOT_LINK_OFFSET=0x009e0000
 # CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf"
+CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw"
 
 #
 # Bus options
@@ -334,6 +335,7 @@
 CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=m
 CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -355,9 +357,10 @@
 CONFIG_INET6_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_TRANSPORT=y
 CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=y
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
@@ -714,6 +717,12 @@
 CONFIG_ATA_OVER_ETH=m
 
 #
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
@@ -778,9 +787,9 @@
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -1095,7 +1104,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -1124,14 +1132,9 @@
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -1177,9 +1180,9 @@
 # USB Host Controller Drivers
 #
 CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -1235,7 +1238,6 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1246,11 +1248,20 @@
 #
 # USB Network Adapters
 #
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
 CONFIG_USB_MON=y
 
 #
@@ -1285,6 +1296,7 @@
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
 # CONFIG_USB_SERIAL_MOS7840 is not set
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
@@ -1316,6 +1328,7 @@
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1357,7 +1370,26 @@
 #
 # Real Time Clock
 #
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_SH=m
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
 # DMA Engine support
@@ -1380,8 +1412,12 @@
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4DEV_FS=m
+# CONFIG_EXT4DEV_FS_XATTR is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
@@ -1393,9 +1429,10 @@
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_ROMFS_FS=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
@@ -1480,7 +1517,12 @@
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1583,9 +1625,10 @@
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
+# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1605,7 +1648,7 @@
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
@@ -1615,7 +1658,7 @@
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index d8ece20..6607860 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -19,23 +19,34 @@
 #include <asm/io.h>
 #include "dma-sh.h"
 
-static inline unsigned int get_dmte_irq(unsigned int chan)
-{
-	unsigned int irq = 0;
 
+
+#ifdef CONFIG_CPU_SH4
+static struct ipr_data dmae_ipr_map[] = {
+	{ DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+};
+#endif
+static struct ipr_data dmte_ipr_map[] = {
 	/*
 	 * Normally we could just do DMTE0_IRQ + chan outright, though in the
 	 * case of the 7751R, the DMTE IRQs for channels > 4 start right above
 	 * the SCIF
 	 */
-	if (chan < 4) {
-		irq = DMTE0_IRQ + chan;
-	} else {
-#ifdef DMTE4_IRQ
-		irq = DMTE4_IRQ + chan - 4;
-#endif
-	}
+	{ DMTE0_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE0_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE0_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE0_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE4_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE4_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE4_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+	{ DMTE4_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+};
 
+static inline unsigned int get_dmte_irq(unsigned int chan)
+{
+	unsigned int irq = 0;
+	if (chan < ARRAY_SIZE(dmte_ipr_map))
+		irq = dmte_ipr_map[chan].irq;
 	return irq;
 }
 
@@ -258,17 +269,16 @@
 	int i;
 
 #ifdef CONFIG_CPU_SH4
-	make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
+	make_ipr_irq(dmae_ipr_map, ARRAY_SIZE(dmae_ipr_map));
 	i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0);
 	if (unlikely(i < 0))
 		return i;
 #endif
 
-	for (i = 0; i < info->nr_channels; i++) {
-		int irq = get_dmte_irq(i);
-
-		make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-	}
+	i = info->nr_channels;
+	if (i > ARRAY_SIZE(dmte_ipr_map))
+		i = ARRAY_SIZE(dmte_ipr_map);
+	make_ipr_irq(dmte_ipr_map, i);
 
 	/*
 	 * Initialize DMAOR, and clean up any error flags that may have
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
index 6e3ba9c6..eeea157 100644
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -13,7 +13,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <asm/r7780rp.h>
 #include <asm/io.h>
 #include "pci-sh4.h"
 
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
index b68824c..4a518d9 100644
--- a/arch/sh/drivers/pci/ops-rts7751r2d.c
+++ b/arch/sh/drivers/pci/ops-rts7751r2d.c
@@ -10,28 +10,24 @@
  *
  * PCI initialization for the Renesas SH7751R RTS7751R2D board
  */
-
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/module.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <asm/rts7751r2d.h>
 #include "pci-sh4.h"
 
+static u8 rts7751r2d_irq_tab[] __initdata = {
+	IRQ_PCISLOT1,
+	IRQ_PCISLOT2,
+	IRQ_PCMCIA,
+	IRQ_PCIETH,
+};
+
 int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
 {
-        switch (slot) {
-	case 0: return IRQ_PCISLOT1;	/* PCI Extend slot #1 */
-	case 1: return IRQ_PCISLOT2;	/* PCI Extend slot #2 */
-	case 2: return IRQ_PCMCIA;	/* PCI Cardbus Bridge */
-	case 3: return IRQ_PCIETH;	/* Realtek Ethernet controller */
-	default:
-		printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
-		return -1;
-	}
+	return rts7751r2d_irq_tab[slot];
 }
 
 static struct resource sh7751_io_resource = {
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c
index d4b2bb7..74ca576 100644
--- a/arch/sh/kernel/cpu/irq/intc2.c
+++ b/arch/sh/kernel/cpu/irq/intc2.c
@@ -11,10 +11,9 @@
  * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780.
  */
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 #include <asm/system.h>
-#include <asm/io.h>
 
 static void disable_intc2_irq(unsigned int irq)
 {
@@ -31,7 +30,7 @@
 }
 
 static struct irq_chip intc2_irq_chip = {
-	.typename	= "intc2",
+	.name		= "INTC2",
 	.mask		= disable_intc2_irq,
 	.unmask		= enable_intc2_irq,
 	.mask_ack	= disable_intc2_irq,
@@ -45,150 +44,36 @@
  *    PIO1 which is INTPRI00[19,16] and INTMSK00[13]
  * would be:               ^     ^             ^  ^
  *                         |     |             |  |
- *    make_intc2_irq(84,   0,   16,            0, 13);
+ *     { 84,		   0,   16,            0, 13 },
+ *
+ * in the intc2_data table.
  */
-void make_intc2_irq(struct intc2_data *p)
-{
-	unsigned int flags;
-	unsigned long ipr;
-
-	disable_irq_nosync(p->irq);
-
-	/* Set the priority level */
-	local_irq_save(flags);
-
-	ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset);
-	ipr &= ~(0xf << p->ipr_shift);
-	ipr |= p->priority << p->ipr_shift;
-	ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset);
-
-	local_irq_restore(flags);
-
-	set_irq_chip_and_handler(p->irq, &intc2_irq_chip, handle_level_irq);
-	set_irq_chip_data(p->irq, p);
-
-	enable_intc2_irq(p->irq);
-}
-
-static struct intc2_data intc2_irq_table[] = {
-#if defined(CONFIG_CPU_SUBTYPE_ST40)
-	{64,  0,  0, 0,  0, 13},	/* PCI serr */
-	{65,  0,  4, 0,  1, 13},	/* PCI err */
-	{66,  0,  4, 0,  2, 13},	/* PCI ad */
-	{67,  0,  4, 0,  3, 13},	/* PCI pwd down */
-	{72,  0,  8, 0,  5, 13},	/* DMAC INT0 */
-	{73,  0,  8, 0,  6, 13},	/* DMAC INT1 */
-	{74,  0,  8, 0,  7, 13},	/* DMAC INT2 */
-	{75,  0,  8, 0,  8, 13},	/* DMAC INT3 */
-	{76,  0,  8, 0,  9, 13},	/* DMAC INT4 */
-	{78,  0,  8, 0, 11, 13},	/* DMAC ERR */
-	{80,  0, 12, 0, 12, 13},	/* PIO0 */
-	{84,  0, 16, 0, 13, 13},	/* PIO1 */
-	{88,  0, 20, 0, 14, 13},	/* PIO2 */
-	{112, 4,  0, 4,  0, 13},	/* Mailbox */
- #ifdef CONFIG_CPU_SUBTYPE_ST40GX1
-	{116, 4,  4, 4,  4, 13},	/* SSC0 */
-	{120, 4,  8, 4,  8, 13},	/* IR Blaster */
-	{124, 4, 12, 4, 12, 13},	/* USB host */
-	{128, 4, 16, 4, 16, 13},	/* Video processor BLITTER */
-	{132, 4, 20, 4, 20, 13},	/* UART0 */
-	{134, 4, 20, 4, 22, 13},	/* UART2 */
-	{136, 4, 24, 4, 24, 13},	/* IO_PIO0 */
-	{140, 4, 28, 4, 28, 13},	/* EMPI */
-	{144, 8,  0, 8,  0, 13},	/* MAFE */
-	{148, 8,  4, 8,  4, 13},	/* PWM */
-	{152, 8,  8, 8,  8, 13},	/* SSC1 */
-	{156, 8, 12, 8, 12, 13},	/* IO_PIO1 */
-	{160, 8, 16, 8, 16, 13},	/* USB target */
-	{164, 8, 20, 8, 20, 13},	/* UART1 */
-	{168, 8, 24, 8, 24, 13},	/* Teletext */
-	{172, 8, 28, 8, 28, 13},	/* VideoSync VTG */
-	{173, 8, 28, 8, 29, 13},	/* VideoSync DVP0 */
-	{174, 8, 28, 8, 30, 13},	/* VideoSync DVP1 */
-#endif
-#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-/*
- * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0
- */
-	/* INTPRIO0 | INTMSK0 */
-	{48,  0, 28, 0, 31,  3},	/* IRQ 4 */
-	{49,  0, 24, 0, 30,  3},	/* IRQ 3 */
-	{50,  0, 20, 0, 29,  3},	/* IRQ 2 */
-	{51,  0, 16, 0, 28,  3},	/* IRQ 1 */
-	/* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */
-	/* INTPRIO4 | INTMSK0 */
-	{56,  4, 28, 0, 25,  3},	/* HCAN2_CHAN0 */
-	{57,  4, 24, 0, 24,  3},	/* HCAN2_CHAN1 */
-	{58,  4, 20, 0, 23,  3},	/* I2S_CHAN0   */
-	{59,  4, 16, 0, 22,  3},	/* I2S_CHAN1   */
-	{60,  4, 12, 0, 21,  3},	/* AC97_CHAN0  */
-	{61,  4,  8, 0, 20,  3},	/* AC97_CHAN1  */
-	{62,  4,  4, 0, 19,  3},	/* I2C_CHAN0   */
-	{63,  4,  0, 0, 18,  3},	/* I2C_CHAN1   */
-	/* INTPRIO8 | INTMSK0 */
-	{52,  8, 16, 0, 11,  3},	/* SCIF0_ERI_IRQ */
-	{53,  8, 16, 0, 10,  3},	/* SCIF0_RXI_IRQ */
-	{54,  8, 16, 0,  9,  3},	/* SCIF0_BRI_IRQ */
-	{55,  8, 16, 0,  8,  3},	/* SCIF0_TXI_IRQ */
-	{64,  8, 28, 0, 17,  3},	/* USBHI_IRQ */
-	{65,  8, 24, 0, 16,  3},	/* LCDC      */
-	/* 66, 67 unused */
-	{68,  8, 20, 0, 14, 13},	/* DMABRGI0_IRQ */
-	{69,  8, 20, 0, 13, 13},	/* DMABRGI1_IRQ */
-	{70,  8, 20, 0, 12, 13},	/* DMABRGI2_IRQ */
-	/* 71 unused */
-	{72,  8, 12, 0,  7,  3},	/* SCIF1_ERI_IRQ */
-	{73,  8, 12, 0,  6,  3},	/* SCIF1_RXI_IRQ */
-	{74,  8, 12, 0,  5,  3},	/* SCIF1_BRI_IRQ */
-	{75,  8, 12, 0,  4,  3},	/* SCIF1_TXI_IRQ */
-	{76,  8,  8, 0,  3,  3},	/* SCIF2_ERI_IRQ */
-	{77,  8,  8, 0,  2,  3},	/* SCIF2_RXI_IRQ */
-	{78,  8,  8, 0,  1,  3},	/* SCIF2_BRI_IRQ */
-	{79,  8,  8, 0,  0,  3},	/* SCIF2_TXI_IRQ */
-	/*          | INTMSK4 */
-	{80,  8,  4, 4, 23,  3},	/* SIM_ERI */
-	{81,  8,  4, 4, 22,  3},	/* SIM_RXI */
-	{82,  8,  4, 4, 21,  3},	/* SIM_TXI */
-	{83,  8,  4, 4, 20,  3},	/* SIM_TEI */
-	{84,  8,  0, 4, 19,  3},	/* HSPII */
-	/* INTPRIOC | INTMSK4 */
-	/* 85-87 unused/reserved */
-	{88, 12, 20, 4, 18,  3},	/* MMCI0 */
-	{89, 12, 20, 4, 17,  3},	/* MMCI1 */
-	{90, 12, 20, 4, 16,  3},	/* MMCI2 */
-	{91, 12, 20, 4, 15,  3},	/* MMCI3 */
-	{92, 12, 12, 4,  6,  3},	/* MFI (unsure, bug? in my 7760 manual*/
-	/* 93-107 reserved/undocumented */
-	{108,12,  4, 4,  1,  3},	/* ADC  */
-	{109,12,  0, 4,  0,  3},	/* CMTI */
-	/* 110-111 reserved/unused */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
-	{ TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2},
-	{ 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
-	{ 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
-	{ 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
-	{ SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
-	{ SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
-	{ SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
-	{ SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
-
-	{ SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
-	{ SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
-	{ SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
-	{ SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
-
-	{ PCIC0_IRQ, 0x10,  8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY },
-	{ PCIC1_IRQ, 0x10,  0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY },
-	{ PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY },
-	{ PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY },
-	{ PCIC4_IRQ, 0x14,  8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY },
-#endif
-};
-
-void __init init_IRQ_intc2(void)
+void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++)
-		make_intc2_irq(intc2_irq_table + i);
+	for (i = 0; i < nr_irqs; i++) {
+		unsigned long ipr, flags;
+		struct intc2_data *p = table + i;
+
+		disable_irq_nosync(p->irq);
+
+		/* Set the priority level */
+		local_irq_save(flags);
+
+		ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET +
+			       p->ipr_offset);
+		ipr &= ~(0xf << p->ipr_shift);
+		ipr |= p->priority << p->ipr_shift;
+		ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET +
+			  p->ipr_offset);
+
+		local_irq_restore(flags);
+
+		set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip,
+					      handle_level_irq, "level");
+		set_irq_chip_data(p->irq, p);
+
+		enable_intc2_irq(p->irq);
+	}
 }
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 8944abd..a008956 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -23,93 +23,81 @@
 #include <asm/io.h>
 #include <asm/machvec.h>
 
-struct ipr_data {
-	unsigned int addr;	/* Address of Interrupt Priority Register */
-	int shift;		/* Shifts of the 16-bit data */
-	int priority;		/* The priority */
-};
 
 static void disable_ipr_irq(unsigned int irq)
 {
 	struct ipr_data *p = get_irq_chip_data(irq);
+	int shift = p->shift*4;
 	/* Set the priority in IPR to 0 */
-	ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
+	ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr);
 }
 
 static void enable_ipr_irq(unsigned int irq)
 {
 	struct ipr_data *p = get_irq_chip_data(irq);
+	int shift = p->shift*4;
 	/* Set priority in IPR back to original value */
-	ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
+	ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr);
 }
 
 static struct irq_chip ipr_irq_chip = {
-	.name		= "ipr",
+	.name		= "IPR",
 	.mask		= disable_ipr_irq,
 	.unmask		= enable_ipr_irq,
 	.mask_ack	= disable_ipr_irq,
 };
 
-void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
+void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
 {
-	struct ipr_data ipr_data;
+	int i;
 
-	disable_irq_nosync(irq);
-
-	ipr_data.addr = addr;
-	ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */
-	ipr_data.priority = priority;
-
-	set_irq_chip_and_handler(irq, &ipr_irq_chip, handle_level_irq);
-	set_irq_chip_data(irq, &ipr_data);
-
-	enable_ipr_irq(irq);
+	for (i = 0; i < nr_irqs; i++) {
+		unsigned int irq = table[i].irq;
+		disable_irq_nosync(irq);
+		set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
+				      handle_level_irq, "level");
+		set_irq_chip_data(irq, &table[i]);
+		enable_ipr_irq(irq);
+	}
 }
+EXPORT_SYMBOL(make_ipr_irq);
 
-/* XXX: This needs to die a horrible death.. */
-void __init init_IRQ(void)
-{
+static struct ipr_data sys_ipr_map[] = {
 #ifndef CONFIG_CPU_SUBTYPE_SH7780
-	make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
-	make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
+	{ TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY },
+	{ TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY },
 #ifdef RTC_IRQ
-	make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
+	{ RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY },
 #endif
-
 #ifdef SCI_ERI_IRQ
-	make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
-	make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
-	make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
+	{ SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
+	{ SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
+	{ SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
 #endif
-
 #ifdef SCIF1_ERI_IRQ
-	make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-	make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-	make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-	make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
+	{ SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+	{ SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+	{ SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+	{ SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
 #endif
-
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
-	make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY);
-	make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-	make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
+	{ SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+	{ DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+	{ VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
 #endif
-
 #ifdef SCIF_ERI_IRQ
-	make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-	make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-	make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-	make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+	{ SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+	{ SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+	{ SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+	{ SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
 #endif
-
 #ifdef IRDA_ERI_IRQ
-	make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-	make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-	make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-	make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+	{ IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+	{ IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+	{ IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+	{ IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
 #endif
-
 #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
     defined(CONFIG_CPU_SUBTYPE_SH7706) || \
     defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
@@ -123,14 +111,19 @@
 	 * You should set corresponding bits of PFC to "00"
 	 * to enable these interrupts.
 	 */
-	make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY);
-	make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
-	make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
-	make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY);
-	make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY);
-	make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY);
+	{ IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY },
+	{ IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY },
+	{ IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY },
+	{ IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY },
+	{ IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY },
+	{ IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY },
 #endif
 #endif
+};
+
+void __init init_IRQ(void)
+{
+	make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map));
 
 #ifdef CONFIG_CPU_HAS_PINT_IRQ
 	init_IRQ_pint();
@@ -152,5 +145,3 @@
 	return irq;
 }
 #endif
-
-EXPORT_SYMBOL(make_ipr_irq);
diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c
index 17f47b3..f600077 100644
--- a/arch/sh/kernel/cpu/irq/pint.c
+++ b/arch/sh/kernel/cpu/irq/pint.c
@@ -84,12 +84,16 @@
 	disable_pint_irq(irq);
 }
 
+static struct ipr_data pint_ipr_map[] = {
+	{ PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY },
+	{ PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY },
+};
+
 void __init init_IRQ_pint(void)
 {
 	int i;
 
-	make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY);
-	make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY);
+	make_ipr_irq(pint_ipr_map, ARRAY_SIZE(pint_ipr_map));
 
 	enable_irq(PINT0_IRQ);
 	enable_irq(PINT8_IRQ);
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index 6be46f0..ba3082d 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -4,7 +4,7 @@
  *  The SH-3 exception vector table.
 
  *  Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- *  Copyright (C) 2003  Paul Mundt
+ *  Copyright (C) 2003 - 2006  Paul Mundt
  *
  * 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
@@ -49,3 +49,10 @@
 #endif
 ENTRY(user_break_point_trap)
 	.long	break_point_trap	/* 1E0 */
+
+	/*
+	 * Pad the remainder of the table out, exceptions residing in far
+	 * away offsets can be manually inserted in to their appropriate
+	 * location via set_exception_table_{evt,vec}().
+	 */
+	.balign 4096,0,4096
diff --git a/arch/sh/kernel/cpu/sh4/ex.S b/arch/sh/kernel/cpu/sh4/ex.S
index 3f4cd04..ac8ab57 100644
--- a/arch/sh/kernel/cpu/sh4/ex.S
+++ b/arch/sh/kernel/cpu/sh4/ex.S
@@ -4,7 +4,7 @@
  *  The SH-4 exception vector table.
 
  *  Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- *  Copyright (C) 2003  Paul Mundt
+ *  Copyright (C) 2003 - 2006  Paul Mundt
  *
  * 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
@@ -53,3 +53,10 @@
 #endif
 ENTRY(user_break_point_trap)
 	.long	break_point_trap	/* 1E0 */
+
+	/*
+	 * Pad the remainder of the table out, exceptions residing in far
+	 * away offsets can be manually inserted in to their appropriate
+	 * location via set_exception_table_{evt,vec}().
+	 */
+	.balign	4096,0,4096
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 97f1c9a..07e5377 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -51,3 +51,66 @@
 				    ARRAY_SIZE(sh7760_devices));
 }
 __initcall(sh7760_devices_setup);
+
+/*
+ * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0
+ */
+static struct intc2_data intc2_irq_table[] = {
+	/* INTPRIO0 | INTMSK0 */
+	{48,  0, 28, 0, 31,  3},	/* IRQ 4 */
+	{49,  0, 24, 0, 30,  3},	/* IRQ 3 */
+	{50,  0, 20, 0, 29,  3},	/* IRQ 2 */
+	{51,  0, 16, 0, 28,  3},	/* IRQ 1 */
+	/* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */
+	/* INTPRIO4 | INTMSK0 */
+	{56,  4, 28, 0, 25,  3},	/* HCAN2_CHAN0 */
+	{57,  4, 24, 0, 24,  3},	/* HCAN2_CHAN1 */
+	{58,  4, 20, 0, 23,  3},	/* I2S_CHAN0   */
+	{59,  4, 16, 0, 22,  3},	/* I2S_CHAN1   */
+	{60,  4, 12, 0, 21,  3},	/* AC97_CHAN0  */
+	{61,  4,  8, 0, 20,  3},	/* AC97_CHAN1  */
+	{62,  4,  4, 0, 19,  3},	/* I2C_CHAN0   */
+	{63,  4,  0, 0, 18,  3},	/* I2C_CHAN1   */
+	/* INTPRIO8 | INTMSK0 */
+	{52,  8, 16, 0, 11,  3},	/* SCIF0_ERI_IRQ */
+	{53,  8, 16, 0, 10,  3},	/* SCIF0_RXI_IRQ */
+	{54,  8, 16, 0,  9,  3},	/* SCIF0_BRI_IRQ */
+	{55,  8, 16, 0,  8,  3},	/* SCIF0_TXI_IRQ */
+	{64,  8, 28, 0, 17,  3},	/* USBHI_IRQ */
+	{65,  8, 24, 0, 16,  3},	/* LCDC      */
+	/* 66, 67 unused */
+	{68,  8, 20, 0, 14, 13},	/* DMABRGI0_IRQ */
+	{69,  8, 20, 0, 13, 13},	/* DMABRGI1_IRQ */
+	{70,  8, 20, 0, 12, 13},	/* DMABRGI2_IRQ */
+	/* 71 unused */
+	{72,  8, 12, 0,  7,  3},	/* SCIF1_ERI_IRQ */
+	{73,  8, 12, 0,  6,  3},	/* SCIF1_RXI_IRQ */
+	{74,  8, 12, 0,  5,  3},	/* SCIF1_BRI_IRQ */
+	{75,  8, 12, 0,  4,  3},	/* SCIF1_TXI_IRQ */
+	{76,  8,  8, 0,  3,  3},	/* SCIF2_ERI_IRQ */
+	{77,  8,  8, 0,  2,  3},	/* SCIF2_RXI_IRQ */
+	{78,  8,  8, 0,  1,  3},	/* SCIF2_BRI_IRQ */
+	{79,  8,  8, 0,  0,  3},	/* SCIF2_TXI_IRQ */
+	/*          | INTMSK4 */
+	{80,  8,  4, 4, 23,  3},	/* SIM_ERI */
+	{81,  8,  4, 4, 22,  3},	/* SIM_RXI */
+	{82,  8,  4, 4, 21,  3},	/* SIM_TXI */
+	{83,  8,  4, 4, 20,  3},	/* SIM_TEI */
+	{84,  8,  0, 4, 19,  3},	/* HSPII */
+	/* INTPRIOC | INTMSK4 */
+	/* 85-87 unused/reserved */
+	{88, 12, 20, 4, 18,  3},	/* MMCI0 */
+	{89, 12, 20, 4, 17,  3},	/* MMCI1 */
+	{90, 12, 20, 4, 16,  3},	/* MMCI2 */
+	{91, 12, 20, 4, 15,  3},	/* MMCI3 */
+	{92, 12, 12, 4,  6,  3},	/* MFI (unsure, bug? in my 7760 manual*/
+	/* 93-107 reserved/undocumented */
+	{108,12,  4, 4,  1,  3},	/* ADC  */
+	{109,12,  0, 4,  0,  3},	/* CMTI */
+	/* 110-111 reserved/unused */
+};
+
+void __init init_IRQ_intc2(void)
+{
+	make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
+}
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/arch/sh/kernel/cpu/sh4/setup-sh7780.c
index 72493f2..814ddb2 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7780.c
@@ -77,3 +77,30 @@
 				    ARRAY_SIZE(sh7780_devices));
 }
 __initcall(sh7780_devices_setup);
+
+static struct intc2_data intc2_irq_table[] = {
+	{ TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2 },
+	{ 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+	{ 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+	{ 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+	{ SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+	{ SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+	{ SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+	{ SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+
+	{ SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+	{ SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+	{ SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+	{ SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+
+	{ PCIC0_IRQ, 0x10,  8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY },
+	{ PCIC1_IRQ, 0x10,  0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY },
+	{ PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY },
+	{ PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY },
+	{ PCIC4_IRQ, 0x14,  8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY },
+};
+
+void __init init_IRQ_intc2(void)
+{
+	make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
+}
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index acf2602..944128c 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -54,7 +54,7 @@
 		for_each_online_cpu(j)
 			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
-		seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
+		seq_printf(p, "-%-8s", irq_desc[i].name);
 		seq_printf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 91516dc..a52b13a 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -105,7 +105,7 @@
 {
 	printk("\n");
 	printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
-	print_symbol("PC is at %s\n", regs->pc);
+	print_symbol("PC is at %s\n", instruction_pointer(regs));
 	printk("PC  : %08lx SP  : %08lx SR  : %08lx ",
 	       regs->pc, regs->regs[15], regs->sr);
 #ifdef CONFIG_MMU
@@ -130,15 +130,7 @@
 	printk("MACH: %08lx MACL: %08lx GBR : %08lx PR  : %08lx\n",
 	       regs->mach, regs->macl, regs->gbr, regs->pr);
 
-	/*
-	 * If we're in kernel mode, dump the stack too..
-	 */
-	if (!user_mode(regs)) {
-		extern void show_task(unsigned long *sp);
-		unsigned long sp = regs->regs[15];
-
-		show_task((unsigned long *)sp);
-	}
+	show_trace(NULL, (unsigned long *)regs->regs[15], regs);
 }
 
 /*
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S
index 768334e..ca81976 100644
--- a/arch/sh/kernel/syscalls.S
+++ b/arch/sh/kernel/syscalls.S
@@ -351,3 +351,6 @@
 	.long sys_sync_file_range
 	.long sys_tee			/* 315 */
 	.long sys_vmsplice
+	.long sys_move_pages
+	.long sys_getcpu
+	.long sys_epoll_pwait
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index c2c597e..53dfa55 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -1,38 +1,25 @@
-/* $Id: traps.c,v 1.17 2004/05/02 01:46:30 sugioka Exp $
- *
- *  linux/arch/sh/traps.c
+/*
+ * 'traps.c' handles hardware traps and faults after we have saved some
+ * state in 'entry.S'.
  *
  *  SuperH version: Copyright (C) 1999 Niibe Yutaka
  *                  Copyright (C) 2000 Philipp Rumpf
  *                  Copyright (C) 2000 David Howells
- *                  Copyright (C) 2002, 2003 Paul Mundt
+ *                  Copyright (C) 2002 - 2006 Paul Mundt
+ *
+ * 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.
  */
-
-/*
- * 'Traps.c' handles hardware traps and faults after we have saved some
- * state in 'entry.S'.
- */
-#include <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
 #include <linux/ptrace.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
-
+#include <linux/io.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <asm/processor.h>
-#include <asm/sections.h>
 
 #ifdef CONFIG_SH_KGDB
 #include <asm/kgdb.h>
@@ -53,13 +40,32 @@
 #define TRAP_ILLEGAL_SLOT_INST	13
 #endif
 
-/*
- * These constants are for searching for possible module text
- * segments.  VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
- * a guess of how much space is likely to be vmalloced.
- */
-#define VMALLOC_OFFSET (8*1024*1024)
-#define MODULE_RANGE (8*1024*1024)
+static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
+{
+	unsigned long p;
+	int i;
+
+	printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
+
+	for (p = bottom & ~31; p < top; ) {
+		printk("%04lx: ", p & 0xffff);
+
+		for (i = 0; i < 8; i++, p += 4) {
+			unsigned int val;
+
+			if (p < bottom || p >= top)
+				printk("         ");
+			else {
+				if (__get_user(val, (unsigned int __user *)p)) {
+					printk("\n");
+					return;
+				}
+				printk("%08x ", val);
+			}
+		}
+		printk("\n");
+	}
+}
 
 DEFINE_SPINLOCK(die_lock);
 
@@ -69,14 +75,28 @@
 
 	console_verbose();
 	spin_lock_irq(&die_lock);
+	bust_spinlocks(1);
+
 	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+
 	CHK_REMOTE_DEBUG(regs);
+	print_modules();
 	show_regs(regs);
+
+	printk("Process: %s (pid: %d, stack limit = %p)\n",
+	       current->comm, current->pid, task_stack_page(current) + 1);
+
+	if (!user_mode(regs) || in_interrupt())
+		dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
+		 	 (unsigned long)task_stack_page(current));
+
+	bust_spinlocks(0);
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
 }
 
-static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+static inline void die_if_kernel(const char *str, struct pt_regs *regs,
+				 long err)
 {
 	if (!user_mode(regs))
 		die(str, regs, err);
@@ -93,8 +113,7 @@
  */
 static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
 {
-	if (!user_mode(regs))
-	{
+	if (!user_mode(regs)) {
 		const struct exception_table_entry *fixup;
 		fixup = search_exception_tables(regs->pc);
 		if (fixup) {
@@ -550,7 +569,10 @@
 #define is_dsp_inst(regs)	(0)
 #endif /* CONFIG_SH_DSP */
 
-extern int do_fpu_inst(unsigned short, struct pt_regs*);
+/* arch/sh/kernel/cpu/sh4/fpu.c */
+extern int do_fpu_inst(unsigned short, struct pt_regs *);
+extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5,
+		unsigned long r6, unsigned long r7, struct pt_regs regs);
 
 asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
 				unsigned long r6, unsigned long r7,
@@ -709,14 +731,20 @@
 		     : "memory");
 }
 
-void __init trap_init(void)
+void *set_exception_table_vec(unsigned int vec, void *handler)
 {
 	extern void *exception_handling_table[];
+	void *old_handler;
+	
+	old_handler = exception_handling_table[vec];
+	exception_handling_table[vec] = handler;
+	return old_handler;
+}
 
-	exception_handling_table[TRAP_RESERVED_INST]
-		= (void *)do_reserved_inst;
-	exception_handling_table[TRAP_ILLEGAL_SLOT_INST]
-		= (void *)do_illegal_slot_inst;
+void __init trap_init(void)
+{
+	set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst);
+	set_exception_table_vec(TRAP_ILLEGAL_SLOT_INST, do_illegal_slot_inst);
 
 #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \
     defined(CONFIG_SH_FPU_EMU)
@@ -725,21 +753,42 @@
 	 * reserved. They'll be handled in the math-emu case, or faulted on
 	 * otherwise.
 	 */
-	/* entry 64 corresponds to EXPEVT=0x800 */
-	exception_handling_table[64] = (void *)do_reserved_inst;
-	exception_handling_table[65] = (void *)do_illegal_slot_inst;
+	set_exception_table_evt(0x800, do_reserved_inst);
+	set_exception_table_evt(0x820, do_illegal_slot_inst);
+#elif defined(CONFIG_SH_FPU)
+	set_exception_table_evt(0x800, do_fpu_state_restore);
+	set_exception_table_evt(0x820, do_fpu_state_restore);
 #endif
 		
 	/* Setup VBR for boot cpu */
 	per_cpu_trap_init();
 }
 
+void show_trace(struct task_struct *tsk, unsigned long *sp,
+		struct pt_regs *regs)
+{
+	unsigned long addr;
+
+	if (regs && user_mode(regs))
+		return;
+
+	printk("\nCall trace: ");
+#ifdef CONFIG_KALLSYMS
+	printk("\n");
+#endif
+
+	while (!kstack_end(sp)) {
+		addr = *sp++;
+		if (kernel_text_address(addr))
+			print_ip_sym(addr);
+	}
+
+	printk("\n");
+}
+
 void show_stack(struct task_struct *tsk, unsigned long *sp)
 {
-	unsigned long *stack, addr;
-	unsigned long module_start = VMALLOC_START;
-	unsigned long module_end = VMALLOC_END;
-	int i = 1;
+	unsigned long stack;
 
 	if (!tsk)
 		tsk = current;
@@ -748,38 +797,10 @@
 	else
 		sp = (unsigned long *)tsk->thread.sp;
 
-	stack = sp;
-
-	printk("\nCall trace: ");
-#ifdef CONFIG_KALLSYMS
-	printk("\n");
-#endif
-
-	while (!kstack_end(stack)) {
-		addr = *stack++;
-		if (((addr >= (unsigned long)_text) &&
-		     (addr <= (unsigned long)_etext)) ||
-		    ((addr >= module_start) && (addr <= module_end))) {
-			/*
-			 * For 80-columns display, 6 entry is maximum.
-			 * NOTE: '[<8c00abcd>] ' consumes 13 columns .
-			 */
-#ifndef CONFIG_KALLSYMS
-			if (i && ((i % 6) == 0))
-				printk("\n       ");
-#endif
-			printk("[<%08lx>] ", addr);
-			print_symbol("%s\n", addr);
-			i++;
-		}
-	}
-
-	printk("\n");
-}
-
-void show_task(unsigned long *sp)
-{
-	show_stack(NULL, sp);
+	stack = (unsigned long)sp;
+	dump_mem("Stack: ", stack, THREAD_SIZE +
+		 (unsigned long)task_stack_page(tsk));
+	show_trace(tsk, sp, NULL);
 }
 
 void dump_stack(void)
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 5eb9309..77b4026 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -76,13 +76,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/sh64/kernel/vmlinux.lds.S b/arch/sh64/kernel/vmlinux.lds.S
index a8fcc3a..95c4d75 100644
--- a/arch/sh64/kernel/vmlinux.lds.S
+++ b/arch/sh64/kernel/vmlinux.lds.S
@@ -108,13 +108,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : C_PHYS(.initcall.init) {
-  	*(.initcall1.init)
-  	*(.initcall2.init)
-  	*(.initcall3.init)
-  	*(.initcall4.init)
-  	*(.initcall5.init)
-  	*(.initcall6.init)
-  	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
index 75ac24d..ba58c3a 100644
--- a/arch/sparc/kernel/ebus.c
+++ b/arch/sparc/kernel/ebus.c
@@ -237,12 +237,12 @@
 	dev->ofdev.node = dp;
 	dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
 	dev->ofdev.dev.bus = &ebus_bus_type;
-	strcpy(dev->ofdev.dev.bus_id, dp->path_component_name);
+	sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
 
 	/* Register with core */
 	if (of_device_register(&dev->ofdev) != 0)
 		printk(KERN_DEBUG "ebus: device registration error for %s!\n",
-		       dev->ofdev.dev.bus_id);
+		       dp->path_component_name);
 
 	if ((dp = dp->child) != NULL) {
 		dev->children = (struct linux_ebus_child *)
@@ -332,12 +332,12 @@
 		ebus->ofdev.node = dp;
 		ebus->ofdev.dev.parent = &pdev->dev;
 		ebus->ofdev.dev.bus = &ebus_bus_type;
-		strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name);
+		sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
 
 		/* Register with core */
 		if (of_device_register(&ebus->ofdev) != 0)
 			printk(KERN_DEBUG "ebus: device registration error for %s!\n",
-			       ebus->ofdev.dev.bus_id);
+			       dp->path_component_name);
 
 
 		nd = dp->child;
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index a4edff4..831f540 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -32,13 +32,12 @@
 #include <asm/mxcc.h>
 #include <asm/thread_info.h>
 #include <asm/param.h>
+#include <asm/unistd.h>
 
 #include <asm/asmmacro.h>
 
 #define curptr      g6
 
-#define NR_SYSCALLS 300      /* Each OS is different... */
-
 /* These are just handy. */
 #define _SV	save	%sp, -STACKFRAME_SZ, %sp
 #define _RS     restore 
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
index 74bef2a..46200c4 100644
--- a/arch/sparc/kernel/of_device.c
+++ b/arch/sparc/kernel/of_device.c
@@ -651,7 +651,7 @@
 	if (!parent)
 		strcpy(op->dev.bus_id, "root");
 	else
-		strcpy(op->dev.bus_id, dp->path_component_name);
+		sprintf(op->dev.bus_id, "%08x", dp->node);
 
 	if (of_device_register(op)) {
 		printk("%s: Could not register of device.\n",
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index 10df38e..ea75ca5 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -78,7 +78,7 @@
 /*285*/	.long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
 /*290*/	.long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
 /*295*/	.long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
-/*300*/	.long sys_set_robust_list, sys_get_robust_list
+/*300*/	.long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages
 
 #ifdef CONFIG_SUNOS_EMUL
 	/* Now the SunOS syscall table. */
@@ -190,6 +190,7 @@
 /*290*/	.long sunos_nosys, sunos_nosys, sunos_nosys
 	.long sunos_nosys, sunos_nosys, sunos_nosys
 	.long sunos_nosys, sunos_nosys, sunos_nosys
-	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys
+/*300*/	.long sunos_nosys, sunos_nosys, sunos_nosys
 
 #endif
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 1dd78c8..5cc5ff7 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -49,13 +49,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c
index b66336d..e724c54 100644
--- a/arch/sparc64/kernel/central.c
+++ b/arch/sparc64/kernel/central.c
@@ -126,6 +126,10 @@
 		int board;
 		u32 tmp;
 
+		if (dp->parent &&
+		    dp->parent->parent != NULL)
+			continue;
+
 		fhc = (struct linux_fhc *)
 			central_alloc_bootmem(sizeof(struct linux_fhc));
 		if (fhc == NULL)
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index 2df25c2..35bf895 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -389,12 +389,12 @@
 	dev->ofdev.node = dp;
 	dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
 	dev->ofdev.dev.bus = &ebus_bus_type;
-	strcpy(dev->ofdev.dev.bus_id, dp->path_component_name);
+	sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
 
 	/* Register with core */
 	if (of_device_register(&dev->ofdev) != 0)
 		printk(KERN_DEBUG "ebus: device registration error for %s!\n",
-		       dev->ofdev.dev.bus_id);
+		       dp->path_component_name);
 
 	dp = dp->child;
 	if (dp) {
@@ -494,12 +494,12 @@
 		ebus->ofdev.node = dp;
 		ebus->ofdev.dev.parent = &pdev->dev;
 		ebus->ofdev.dev.bus = &ebus_bus_type;
-		strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name);
+		sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
 
 		/* Register with core */
 		if (of_device_register(&ebus->ofdev) != 0)
 			printk(KERN_DEBUG "ebus: device registration error for %s!\n",
-			       ebus->ofdev.dev.bus_id);
+			       dp->path_component_name);
 
 
 		child = dp->child;
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 0aaa35f..6f28bec 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -22,11 +22,10 @@
 #include <asm/auxio.h>
 #include <asm/sfafsr.h>
 #include <asm/pil.h>
+#include <asm/unistd.h>
 
 #define curptr      g6
 
-#define NR_SYSCALLS 300      /* Each OS is different... */
-
 	.text
 	.align		32
 
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index 0f3aec7..f028e68 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -115,12 +115,12 @@
 		isa_dev->ofdev.node = dp;
 		isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev;
 		isa_dev->ofdev.dev.bus = &isa_bus_type;
-		strcpy(isa_dev->ofdev.dev.bus_id, dp->path_component_name);
+		sprintf(isa_dev->ofdev.dev.bus_id, "isa[%08x]", dp->node);
 
 		/* Register with core */
 		if (of_device_register(&isa_dev->ofdev) != 0) {
 			printk(KERN_DEBUG "isa: device registration error for %s!\n",
-			       isa_dev->ofdev.dev.bus_id);
+			       dp->path_component_name);
 			kfree(isa_dev);
 			goto next_sibling;
 		}
@@ -191,12 +191,12 @@
 		isa_br->ofdev.node = dp;
 		isa_br->ofdev.dev.parent = &pdev->dev;
 		isa_br->ofdev.dev.bus = &isa_bus_type;
-		strcpy(isa_br->ofdev.dev.bus_id, dp->path_component_name);
+		sprintf(isa_br->ofdev.dev.bus_id, "isa%d", index);
 
 		/* Register with core */
 		if (of_device_register(&isa_br->ofdev) != 0) {
 			printk(KERN_DEBUG "isa: device registration error for %s!\n",
-			       isa_br->ofdev.dev.bus_id);
+			       dp->path_component_name);
 			kfree(isa_br);
 			return;
 		}
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index d3dfb2a..8cc14fc 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -402,16 +402,22 @@
 		*sizec = 1;
 }
 
-static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+/*
+ * FHC/Central bus specific translator.
+ *
+ * This is just needed to hard-code the address and size cell
+ * counts.  'fhc' and 'central' nodes lack the #address-cells and
+ * #size-cells properties, and if you walk to the root on such
+ * Enterprise boxes all you'll get is a #size-cells of 2 which is
+ * not what we want to use.
+ */
+static int of_bus_fhc_match(struct device_node *np)
 {
-	return of_bus_default_map(addr, range, na, ns, pna);
+	return !strcmp(np->name, "fhc") ||
+		!strcmp(np->name, "central");
 }
 
-static unsigned int of_bus_sbus_get_flags(u32 *addr)
-{
-	return IORESOURCE_MEM;
-}
-
+#define of_bus_fhc_count_cells of_bus_sbus_count_cells
 
 /*
  * Array of bus specific translators
@@ -433,8 +439,17 @@
 		.addr_prop_name = "reg",
 		.match = of_bus_sbus_match,
 		.count_cells = of_bus_sbus_count_cells,
-		.map = of_bus_sbus_map,
-		.get_flags = of_bus_sbus_get_flags,
+		.map = of_bus_default_map,
+		.get_flags = of_bus_default_get_flags,
+	},
+	/* FHC */
+	{
+		.name = "fhc",
+		.addr_prop_name = "reg",
+		.match = of_bus_fhc_match,
+		.count_cells = of_bus_fhc_count_cells,
+		.map = of_bus_default_map,
+		.get_flags = of_bus_default_get_flags,
 	},
 	/* Default */
 	{
@@ -846,7 +861,7 @@
 	if (!parent)
 		strcpy(op->dev.bus_id, "root");
 	else
-		sprintf(op->dev.bus_id, "%s@%08x", dp->name, dp->node);
+		sprintf(op->dev.bus_id, "%08x", dp->node);
 
 	if (of_device_register(op)) {
 		printk("%s: Could not register of device.\n",
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 82e5455..2e7f142 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -281,7 +281,7 @@
 
 	spin_lock_irqsave(&iommu->lock, flags);
 
-	free_npages(iommu, dvma, npages);
+	free_npages(iommu, dvma - iommu->page_table_map_base, npages);
 
 	spin_unlock_irqrestore(&iommu->lock, flags);
 
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index e21cd6a..0917c24 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -793,7 +793,7 @@
 	return virt_irq;
 }
 
-static void schizo_irq_trans_init(struct device_node *dp)
+static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo)
 {
 	struct linux_prom64_registers *regs;
 	struct schizo_irq_data *irq_data;
@@ -807,11 +807,24 @@
 	dp->irq_trans->data = irq_data;
 
 	irq_data->pbm_regs = regs[0].phys_addr;
-	irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL;
+	if (is_tomatillo)
+		irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL;
+	else
+		irq_data->sync_reg = 0UL;
 	irq_data->portid = of_getintprop_default(dp, "portid", 0);
 	irq_data->chip_version = of_getintprop_default(dp, "version#", 0);
 }
 
+static void schizo_irq_trans_init(struct device_node *dp)
+{
+	__schizo_irq_trans_init(dp, 0);
+}
+
+static void tomatillo_irq_trans_init(struct device_node *dp)
+{
+	__schizo_irq_trans_init(dp, 1);
+}
+
 static unsigned int pci_sun4v_irq_build(struct device_node *dp,
 					unsigned int devino,
 					void *_data)
@@ -1050,8 +1063,8 @@
 	{ "pci108e,8001", schizo_irq_trans_init },
 	{ "SUNW,schizo+", schizo_irq_trans_init },
 	{ "pci108e,8002", schizo_irq_trans_init },
-	{ "SUNW,tomatillo", schizo_irq_trans_init },
-	{ "pci108e,a801", schizo_irq_trans_init },
+	{ "SUNW,tomatillo", tomatillo_irq_trans_init },
+	{ "pci108e,a801", tomatillo_irq_trans_init },
 	{ "SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
 };
 #endif
@@ -1079,23 +1092,22 @@
 
 static void irq_trans_init(struct device_node *dp)
 {
-	const char *model;
 #ifdef CONFIG_PCI
+	const char *model;
 	int i;
 #endif
 
+#ifdef CONFIG_PCI
 	model = of_get_property(dp, "model", NULL);
 	if (!model)
 		model = of_get_property(dp, "compatible", NULL);
-	if (!model)
-		return;
+	if (model) {
+		for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
+			struct irq_trans *t = &pci_irq_trans_table[i];
 
-#ifdef CONFIG_PCI
-	for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
-		struct irq_trans *t = &pci_irq_trans_table[i];
-
-		if (!strcmp(model, t->name))
-			return t->init(dp);
+			if (!strcmp(model, t->name))
+				return t->init(dp);
+		}
 	}
 #endif
 #ifdef CONFIG_SBUS
@@ -1103,8 +1115,9 @@
 	    !strcmp(dp->name, "sbi"))
 		return sbus_irq_trans_init(dp);
 #endif
-	if (!strcmp(dp->name, "central"))
-		return central_irq_trans_init(dp->child);
+	if (!strcmp(dp->name, "fhc") &&
+	    !strcmp(dp->parent->name, "central"))
+		return central_irq_trans_init(dp);
 	if (!strcmp(dp->name, "virtual-devices"))
 		return sun4v_vdev_irq_trans_init(dp);
 }
@@ -1516,7 +1529,7 @@
 	return buf;
 }
 
-static struct device_node * __init create_node(phandle node)
+static struct device_node * __init create_node(phandle node, struct device_node *parent)
 {
 	struct device_node *dp;
 
@@ -1525,6 +1538,7 @@
 
 	dp = prom_early_alloc(sizeof(*dp));
 	dp->unique_id = unique_id++;
+	dp->parent = parent;
 
 	kref_init(&dp->kref);
 
@@ -1543,12 +1557,11 @@
 {
 	struct device_node *dp;
 
-	dp = create_node(node);
+	dp = create_node(node, parent);
 	if (dp) {
 		*(*nextp) = dp;
 		*nextp = &dp->allnext;
 
-		dp->parent = parent;
 		dp->path_component_name = build_path_component(dp);
 		dp->full_name = build_full_name(dp);
 
@@ -1564,7 +1577,7 @@
 {
 	struct device_node **nextp;
 
-	allnodes = create_node(prom_root_node);
+	allnodes = create_node(prom_root_node, NULL);
 	allnodes->path_component_name = "";
 	allnodes->full_name = "/";
 
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 419a63f..9a80267 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -79,7 +79,7 @@
 	.word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64
 /*290*/	.word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
 	.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
-/*300*/	.word compat_sys_set_robust_list, compat_sys_get_robust_list
+/*300*/	.word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages
 
 #endif /* CONFIG_COMPAT */
 
@@ -149,7 +149,7 @@
 	.word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
 /*290*/	.word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
 	.word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
-/*300*/	.word sys_set_robust_list, sys_get_robust_list
+/*300*/	.word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -262,5 +262,7 @@
 /*290*/	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
-	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys
+/*300*/	.word sunos_nosys, sunos_nosys, sunos_nosys
+
 #endif
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 68420e2..fe1796c 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -87,6 +87,7 @@
 		       i + 1,
 		       p->trapstack[i].tstate, p->trapstack[i].tpc,
 		       p->trapstack[i].tnpc, p->trapstack[i].tt);
+		print_symbol("TRAPLOG: TPC<%s>\n", p->trapstack[i].tpc);
 	}
 }
 
@@ -1134,6 +1135,9 @@
 	printk("%s" "ERROR(%d): TPC[%lx] TNPC[%lx] O7[%lx] TSTATE[%lx]\n",
 	       (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
 	       regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate);
+	printk("%s" "ERROR(%d): ",
+	       (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id());
+	print_symbol("TPC<%s>\n", regs->tpc);
 	printk("%s" "ERROR(%d): M_SYND(%lx),  E_SYND(%lx)%s%s\n",
 	       (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
 	       (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT,
@@ -1741,6 +1745,7 @@
 		       smp_processor_id(),
 		       (type & 0x1) ? 'I' : 'D',
 		       regs->tpc);
+		print_symbol(KERN_EMERG "TPC<%s>\n", regs->tpc);
 		panic("Irrecoverable Cheetah+ parity error.");
 	}
 
@@ -1748,6 +1753,7 @@
 	       smp_processor_id(),
 	       (type & 0x1) ? 'I' : 'D',
 	       regs->tpc);
+	print_symbol(KERN_WARNING "TPC<%s>\n", regs->tpc);
 }
 
 struct sun4v_error_entry {
@@ -1946,6 +1952,7 @@
 
 	printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n",
 	       regs->tpc, tl);
+	print_symbol(KERN_EMERG "SUN4V-ITLB: TPC<%s>\n", regs->tpc);
 	printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] "
 	       "pte[%lx] error[%lx]\n",
 	       sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx,
@@ -1966,6 +1973,7 @@
 
 	printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n",
 	       regs->tpc, tl);
+	print_symbol(KERN_EMERG "SUN4V-DTLB: TPC<%s>\n", regs->tpc);
 	printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] "
 	       "pte[%lx] error[%lx]\n",
 	       sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx,
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index b097379..bd9de8c 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -57,13 +57,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/um/Makefile b/arch/um/Makefile
index c8016a9..5d5ed72 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -64,9 +64,14 @@
 
 AFLAGS += $(ARCH_INCLUDE)
 
-USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
-USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
-	$(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64
+USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\
+	$(patsubst -I%,,$(CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \
+	-D_FILE_OFFSET_BITS=64
+
+include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
+
+#This will adjust *FLAGS accordingly to the platform.
+include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
 
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
@@ -74,15 +79,11 @@
 # errnos.
 # These apply to kernelspace only.
 
-CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
-	-Dmktime=kernel_mktime
+KERNEL_DEFINES = -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
+	-Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES)
+CFLAGS += $(KERNEL_DEFINES)
 CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
 
-include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
-
-#This will adjust *FLAGS accordingly to the platform.
-include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
-
 # These are needed for clean and mrproper, since in that case .config is not
 # included; the values here are meaningless
 
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index b65ca11..c9f1c5b 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -16,7 +16,6 @@
 ifeq ("$(origin SUBARCH)", "command line")
 ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
 CFLAGS			+= $(call cc-option,-m32)
-USER_CFLAGS		+= $(call cc-option,-m32)
 AFLAGS			+= $(call cc-option,-m32)
 LINK-y			+= $(call cc-option,-m32)
 UML_OBJCOPYFLAGS	+= -F $(ELF_FORMAT)
@@ -25,7 +24,7 @@
 endif
 endif
 
-CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
+ARCH_KERNEL_DEFINES += -U__$(SUBARCH)__ -U$(SUBARCH)
 
 # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
 include $(srctree)/arch/i386/Makefile.cpu
@@ -38,4 +37,3 @@
 cflags-y += -ffreestanding
 
 CFLAGS += $(cflags-y)
-USER_CFLAGS += $(cflags-y)
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index d278682..69ecea6 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -8,8 +8,8 @@
 
 #We #undef __x86_64__ for kernelspace, not for userspace where
 #it's needed for headers to work!
-CFLAGS += -U__$(SUBARCH)__ $(_extra_flags_)
-USER_CFLAGS += $(_extra_flags_)
+ARCH_KERNEL_DEFINES = -U__$(SUBARCH)__
+CFLAGS += $(_extra_flags_)
 
 CHECKFLAGS  += -m64
 AFLAGS += -m64
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index d08bd03..7b17216 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -79,7 +79,7 @@
 	/* long to avoid size mismatch warnings from gcc */
 	long fd;
 	struct mconsole_entry *new;
-	struct mc_request req;
+	static struct mc_request req;	/* that's OK */
 
 	fd = (long) dev_id;
 	while (mconsole_get_request(fd, &req)){
@@ -91,6 +91,7 @@
 				mconsole_reply(&req, "Out of memory", 1, 0);
 			else {
 				new->request = req;
+				new->request.regs = get_irq_regs()->regs;
 				list_add(&new->list, &mc_requests);
 			}
 		}
@@ -314,9 +315,21 @@
 {
 	deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
 	os_set_fd_block(req->originating_fd, 1);
-	mconsole_reply(req, "", 0, 0);
-	while(mconsole_get_request(req->originating_fd, req)){
-		if(req->cmd->handler == mconsole_go) break;
+	mconsole_reply(req, "stopped", 0, 0);
+	while (mconsole_get_request(req->originating_fd, req)) {
+		if (req->cmd->handler == mconsole_go)
+			break;
+		if (req->cmd->handler == mconsole_stop) {
+			mconsole_reply(req, "Already stopped", 1, 0);
+			continue;
+		}
+		if (req->cmd->handler == mconsole_sysrq) {
+			struct pt_regs *old_regs;
+			old_regs = set_irq_regs((struct pt_regs *)&req->regs);
+			mconsole_sysrq(req);
+			set_irq_regs(old_regs);
+			continue;
+		}
 		(*req->cmd->handler)(req);
 	}
 	os_set_fd_block(req->originating_fd, 0);
@@ -673,9 +686,7 @@
 static void sysrq_proc(void *arg)
 {
 	char *op = arg;
-	struct pt_regs *old_regs = set_irq_regs(&current->thread.regs);
 	handle_sysrq(*op, NULL);
-	set_irq_regs(old_regs);
 }
 
 void mconsole_sysrq(struct mc_request *req)
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 17068eb..75aef6f 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -14,6 +14,7 @@
 #include <sys/un.h>
 #include <unistd.h>
 #include "user.h"
+#include "sysdep/ptrace.h"
 #include "mconsole.h"
 #include "umid.h"
 #include "user_util.h"
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index bc458f5..49c047b 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -106,10 +106,15 @@
 
 #define DRIVER_NAME "uml-blkdev"
 
+/* Can be taken in interrupt context, and is passed to the block layer to lock
+ * the request queue. Kernel side code knows that. */
 static DEFINE_SPINLOCK(ubd_io_lock);
-static DEFINE_SPINLOCK(ubd_lock);
 
-static void (*do_ubd)(void);
+static DEFINE_MUTEX(ubd_lock);
+
+/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and
+ * probably it doesn't make sense even for that. */
+static int do_ubd;
 
 static int ubd_open(struct inode * inode, struct file * filp);
 static int ubd_release(struct inode * inode, struct file * file);
@@ -117,7 +122,7 @@
 		     unsigned int cmd, unsigned long arg);
 static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
-#define MAX_DEV (8)
+#define MAX_DEV (16)
 
 static struct block_device_operations ubd_blops = {
         .owner		= THIS_MODULE,
@@ -150,8 +155,9 @@
 static struct openflags global_openflags = OPEN_FLAGS;
 
 struct cow {
-	/* This is the backing file, actually */
+	/* backing file name */
 	char *file;
+	/* backing file fd */
 	int fd;
 	unsigned long *bitmap;
 	unsigned long bitmap_len;
@@ -160,14 +166,16 @@
 };
 
 struct ubd {
+	/* name (and fd, below) of the file opened for writing, either the
+	 * backing or the cow file. */
 	char *file;
 	int count;
 	int fd;
 	__u64 size;
 	struct openflags boot_openflags;
 	struct openflags openflags;
-	int shared;
-	int no_cow;
+	unsigned shared:1;
+	unsigned no_cow:1;
 	struct cow cow;
 	struct platform_device pdev;
 };
@@ -192,18 +200,7 @@
         .cow =			DEFAULT_COW, \
 }
 
-struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
-
-static int ubd0_init(void)
-{
-	struct ubd *dev = &ubd_dev[0];
-
-	if(dev->file == NULL)
-		dev->file = "root_fs";
-	return(0);
-}
-
-__initcall(ubd0_init);
+struct ubd ubd_devs[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
 
 /* Only changed by fake_ide_setup which is a setup */
 static int fake_ide = 0;
@@ -277,7 +274,7 @@
 			return(-1);
 		*ptr = end;
 	}
-	else if (('a' <= *str) && (*str <= 'h')) {
+	else if (('a' <= *str) && (*str <= 'z')) {
 		n = *str - 'a';
 		str++;
 		*ptr = str;
@@ -285,9 +282,13 @@
 	return(n);
 }
 
+/* If *index_out == -1 at exit, the passed option was a general one;
+ * otherwise, the str pointer is used (and owned) inside ubd_devs array, so it
+ * should not be freed on exit.
+ */
 static int ubd_setup_common(char *str, int *index_out)
 {
-	struct ubd *dev;
+	struct ubd *ubd_dev;
 	struct openflags flags = global_openflags;
 	char *backing_file;
 	int n, err, i;
@@ -311,7 +312,7 @@
 		}
 
 		err = 1;
- 		spin_lock(&ubd_lock);
+ 		mutex_lock(&ubd_lock);
  		if(fake_major != MAJOR_NR){
  			printk(KERN_ERR "Can't assign a fake major twice\n");
  			goto out1;
@@ -323,7 +324,7 @@
 		       major);
  		err = 0;
  	out1:
- 		spin_unlock(&ubd_lock);
+ 		mutex_unlock(&ubd_lock);
 		return(err);
 	}
 
@@ -340,10 +341,10 @@
 	}
 
 	err = 1;
-	spin_lock(&ubd_lock);
+	mutex_lock(&ubd_lock);
 
-	dev = &ubd_dev[n];
-	if(dev->file != NULL){
+	ubd_dev = &ubd_devs[n];
+	if(ubd_dev->file != NULL){
 		printk(KERN_ERR "ubd_setup : device already configured\n");
 		goto out;
 	}
@@ -360,10 +361,10 @@
 			flags.s = 1;
 			break;
 		case 'd':
-			dev->no_cow = 1;
+			ubd_dev->no_cow = 1;
 			break;
 		case 'c':
-			dev->shared = 1;
+			ubd_dev->shared = 1;
 			break;
 		case '=':
 			str++;
@@ -390,7 +391,7 @@
 	}
 
 	if(backing_file){
-		if(dev->no_cow)
+		if(ubd_dev->no_cow)
 			printk(KERN_ERR "Can't specify both 'd' and a "
 			       "cow file\n");
 		else {
@@ -398,11 +399,11 @@
 			backing_file++;
 		}
 	}
-	dev->file = str;
-	dev->cow.file = backing_file;
-	dev->boot_openflags = flags;
+	ubd_dev->file = str;
+	ubd_dev->cow.file = backing_file;
+	ubd_dev->boot_openflags = flags;
 out:
-	spin_unlock(&ubd_lock);
+	mutex_unlock(&ubd_lock);
 	return(err);
 }
 
@@ -472,8 +473,9 @@
 
 /* Changed by ubd_handler, which is serialized because interrupts only
  * happen on CPU 0.
+ * XXX: currently unused.
  */
-int intr_count = 0;
+static int intr_count = 0;
 
 /* call ubd_finish if you need to serialize */
 static void __ubd_finish(struct request *req, int error)
@@ -493,6 +495,8 @@
 	end_request(req, 1);
 }
 
+/* Callable only from interrupt context - otherwise you need to do
+ * spin_lock_irq()/spin_lock_irqsave() */
 static inline void ubd_finish(struct request *req, int error)
 {
  	spin_lock(&ubd_io_lock);
@@ -500,14 +504,15 @@
 	spin_unlock(&ubd_io_lock);
 }
 
-/* Called without ubd_io_lock held */
+/* XXX - move this inside ubd_intr. */
+/* Called without ubd_io_lock held, and only in interrupt context. */
 static void ubd_handler(void)
 {
 	struct io_thread_req req;
 	struct request *rq = elv_next_request(ubd_queue);
 	int n;
 
-	do_ubd = NULL;
+	do_ubd = 0;
 	intr_count++;
 	n = os_read_file(thread_fd, &req, sizeof(req));
 	if(n != sizeof(req)){
@@ -521,7 +526,9 @@
 
 	ubd_finish(rq, req.error);
 	reactivate_fd(thread_fd, UBD_IRQ);	
+	spin_lock(&ubd_io_lock);
 	do_ubd_request(ubd_queue);
+	spin_unlock(&ubd_io_lock);
 }
 
 static irqreturn_t ubd_intr(int irq, void *dev)
@@ -541,87 +548,90 @@
 
 __uml_exitcall(kill_io_thread);
 
-static int ubd_file_size(struct ubd *dev, __u64 *size_out)
+static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
 {
 	char *file;
 
-	file = dev->cow.file ? dev->cow.file : dev->file;
+	file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
 	return(os_file_size(file, size_out));
 }
 
-static void ubd_close(struct ubd *dev)
+static void ubd_close_dev(struct ubd *ubd_dev)
 {
-	os_close_file(dev->fd);
-	if(dev->cow.file == NULL)
+	os_close_file(ubd_dev->fd);
+	if(ubd_dev->cow.file == NULL)
 		return;
 
-	os_close_file(dev->cow.fd);
-	vfree(dev->cow.bitmap);
-	dev->cow.bitmap = NULL;
+	os_close_file(ubd_dev->cow.fd);
+	vfree(ubd_dev->cow.bitmap);
+	ubd_dev->cow.bitmap = NULL;
 }
 
-static int ubd_open_dev(struct ubd *dev)
+static int ubd_open_dev(struct ubd *ubd_dev)
 {
 	struct openflags flags;
 	char **back_ptr;
 	int err, create_cow, *create_ptr;
+	int fd;
 
-	dev->openflags = dev->boot_openflags;
+	ubd_dev->openflags = ubd_dev->boot_openflags;
 	create_cow = 0;
-	create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
-	back_ptr = dev->no_cow ? NULL : &dev->cow.file;
-	dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared,
-				back_ptr, &dev->cow.bitmap_offset,
-				&dev->cow.bitmap_len, &dev->cow.data_offset,
+	create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL;
+	back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file;
+
+	fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared,
+				back_ptr, &ubd_dev->cow.bitmap_offset,
+				&ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset,
 				create_ptr);
 
-	if((dev->fd == -ENOENT) && create_cow){
-		dev->fd = create_cow_file(dev->file, dev->cow.file,
-					  dev->openflags, 1 << 9, PAGE_SIZE,
-					  &dev->cow.bitmap_offset,
-					  &dev->cow.bitmap_len,
-					  &dev->cow.data_offset);
-		if(dev->fd >= 0){
+	if((fd == -ENOENT) && create_cow){
+		fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file,
+					  ubd_dev->openflags, 1 << 9, PAGE_SIZE,
+					  &ubd_dev->cow.bitmap_offset,
+					  &ubd_dev->cow.bitmap_len,
+					  &ubd_dev->cow.data_offset);
+		if(fd >= 0){
 			printk(KERN_INFO "Creating \"%s\" as COW file for "
-			       "\"%s\"\n", dev->file, dev->cow.file);
+			       "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file);
 		}
 	}
 
-	if(dev->fd < 0){
-		printk("Failed to open '%s', errno = %d\n", dev->file,
-		       -dev->fd);
-		return(dev->fd);
+	if(fd < 0){
+		printk("Failed to open '%s', errno = %d\n", ubd_dev->file,
+		       -fd);
+		return fd;
 	}
+	ubd_dev->fd = fd;
 
-	if(dev->cow.file != NULL){
+	if(ubd_dev->cow.file != NULL){
 		err = -ENOMEM;
-		dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
-		if(dev->cow.bitmap == NULL){
+		ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len);
+		if(ubd_dev->cow.bitmap == NULL){
 			printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
 			goto error;
 		}
 		flush_tlb_kernel_vm();
 
-		err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
-				      dev->cow.bitmap_offset,
-				      dev->cow.bitmap_len);
+		err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
+				      ubd_dev->cow.bitmap_offset,
+				      ubd_dev->cow.bitmap_len);
 		if(err < 0)
 			goto error;
 
-		flags = dev->openflags;
+		flags = ubd_dev->openflags;
 		flags.w = 0;
-		err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL,
+		err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL,
 				    NULL, NULL, NULL, NULL);
 		if(err < 0) goto error;
-		dev->cow.fd = err;
+		ubd_dev->cow.fd = err;
 	}
 	return(0);
  error:
-	os_close_file(dev->fd);
+	os_close_file(ubd_dev->fd);
 	return(err);
 }
 
-static int ubd_new_disk(int major, u64 size, int unit,
+static int ubd_disk_register(int major, u64 size, int unit,
 			struct gendisk **disk_out)
 			
 {
@@ -642,13 +652,13 @@
 
 	/* sysfs register (not for ide fake devices) */
 	if (major == MAJOR_NR) {
-		ubd_dev[unit].pdev.id   = unit;
-		ubd_dev[unit].pdev.name = DRIVER_NAME;
-		platform_device_register(&ubd_dev[unit].pdev);
-		disk->driverfs_dev = &ubd_dev[unit].pdev.dev;
+		ubd_devs[unit].pdev.id   = unit;
+		ubd_devs[unit].pdev.name = DRIVER_NAME;
+		platform_device_register(&ubd_devs[unit].pdev);
+		disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
 	}
 
-	disk->private_data = &ubd_dev[unit];
+	disk->private_data = &ubd_devs[unit];
 	disk->queue = ubd_queue;
 	add_disk(disk);
 
@@ -660,25 +670,25 @@
 
 static int ubd_add(int n)
 {
-	struct ubd *dev = &ubd_dev[n];
+	struct ubd *ubd_dev = &ubd_devs[n];
 	int err;
 
 	err = -ENODEV;
-	if(dev->file == NULL)
+	if(ubd_dev->file == NULL)
 		goto out;
 
-	err = ubd_file_size(dev, &dev->size);
+	err = ubd_file_size(ubd_dev, &ubd_dev->size);
 	if(err < 0)
 		goto out;
 
-	dev->size = ROUND_BLOCK(dev->size);
+	ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
 
-	err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
+	err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
 	if(err)
 		goto out;
 
 	if(fake_major != MAJOR_NR)
-		ubd_new_disk(fake_major, dev->size, n,
+		ubd_disk_register(fake_major, ubd_dev->size, n,
 			     &fake_gendisk[n]);
 
 	/* perhaps this should also be under the "if (fake_major)" above */
@@ -693,32 +703,41 @@
 
 static int ubd_config(char *str)
 {
-	int n, err;
+	int n, ret;
 
 	str = kstrdup(str, GFP_KERNEL);
-	if(str == NULL){
+	if (str == NULL) {
 		printk(KERN_ERR "ubd_config failed to strdup string\n");
-		return(1);
+		ret = 1;
+		goto out;
 	}
-	err = ubd_setup_common(str, &n);
-	if(err){
-		kfree(str);
-		return(-1);
+	ret = ubd_setup_common(str, &n);
+	if (ret) {
+		ret = -1;
+		goto err_free;
 	}
-	if(n == -1) return(0);
+	if (n == -1) {
+		ret = 0;
+		goto err_free;
+	}
 
- 	spin_lock(&ubd_lock);
-	err = ubd_add(n);
-	if(err)
-		ubd_dev[n].file = NULL;
- 	spin_unlock(&ubd_lock);
+ 	mutex_lock(&ubd_lock);
+	ret = ubd_add(n);
+	if (ret)
+		ubd_devs[n].file = NULL;
+ 	mutex_unlock(&ubd_lock);
 
-	return(err);
+out:
+ 	return ret;
+
+err_free:
+	kfree(str);
+	goto out;
 }
 
 static int ubd_get_config(char *name, char *str, int size, char **error_out)
 {
-	struct ubd *dev;
+	struct ubd *ubd_dev;
 	int n, len = 0;
 
 	n = parse_unit(&name);
@@ -727,24 +746,24 @@
 		return(-1);
 	}
 
-	dev = &ubd_dev[n];
-	spin_lock(&ubd_lock);
+	ubd_dev = &ubd_devs[n];
+	mutex_lock(&ubd_lock);
 
-	if(dev->file == NULL){
+	if(ubd_dev->file == NULL){
 		CONFIG_CHUNK(str, size, len, "", 1);
 		goto out;
 	}
 
-	CONFIG_CHUNK(str, size, len, dev->file, 0);
+	CONFIG_CHUNK(str, size, len, ubd_dev->file, 0);
 
-	if(dev->cow.file != NULL){
+	if(ubd_dev->cow.file != NULL){
 		CONFIG_CHUNK(str, size, len, ",", 0);
-		CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
+		CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1);
 	}
 	else CONFIG_CHUNK(str, size, len, "", 1);
 
  out:
-	spin_unlock(&ubd_lock);
+	mutex_unlock(&ubd_lock);
 	return(len);
 }
 
@@ -760,22 +779,22 @@
 
 static int ubd_remove(int n)
 {
-	struct ubd *dev;
+	struct ubd *ubd_dev;
 	int err = -ENODEV;
 
-	spin_lock(&ubd_lock);
+	mutex_lock(&ubd_lock);
 
 	if(ubd_gendisk[n] == NULL)
 		goto out;
 
-	dev = &ubd_dev[n];
+	ubd_dev = &ubd_devs[n];
 
-	if(dev->file == NULL)
+	if(ubd_dev->file == NULL)
 		goto out;
 
 	/* you cannot remove a open disk */
 	err = -EBUSY;
-	if(dev->count > 0)
+	if(ubd_dev->count > 0)
 		goto out;
 
 	del_gendisk(ubd_gendisk[n]);
@@ -788,14 +807,15 @@
 		fake_gendisk[n] = NULL;
 	}
 
-	platform_device_unregister(&dev->pdev);
-	*dev = ((struct ubd) DEFAULT_UBD);
+	platform_device_unregister(&ubd_dev->pdev);
+	*ubd_dev = ((struct ubd) DEFAULT_UBD);
 	err = 0;
 out:
-	spin_unlock(&ubd_lock);
+	mutex_unlock(&ubd_lock);
 	return err;
 }
 
+/* All these are called by mconsole in process context and without ubd-specific locks. */
 static struct mc_device ubd_mc = {
 	.name		= "ubd",
 	.config		= ubd_config,
@@ -804,7 +824,7 @@
 	.remove		= ubd_remove,
 };
 
-static int ubd_mc_init(void)
+static int __init ubd_mc_init(void)
 {
 	mconsole_register_dev(&ubd_mc);
 	return 0;
@@ -812,13 +832,24 @@
 
 __initcall(ubd_mc_init);
 
+static int __init ubd0_init(void)
+{
+	struct ubd *ubd_dev = &ubd_devs[0];
+
+	if(ubd_dev->file == NULL)
+		ubd_dev->file = "root_fs";
+	return(0);
+}
+
+__initcall(ubd0_init);
+
 static struct platform_driver ubd_driver = {
 	.driver = {
 		.name  = DRIVER_NAME,
 	},
 };
 
-int ubd_init(void)
+static int __init ubd_init(void)
 {
         int i;
 
@@ -846,7 +877,7 @@
 
 late_initcall(ubd_init);
 
-int ubd_driver_init(void){
+static int __init ubd_driver_init(void){
 	unsigned long stack;
 	int err;
 
@@ -867,7 +898,7 @@
 		return(0);
 	}
 	err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
-			     IRQF_DISABLED, "ubd", ubd_dev);
+			     IRQF_DISABLED, "ubd", ubd_devs);
 	if(err != 0)
 		printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
 	return 0;
@@ -878,24 +909,24 @@
 static int ubd_open(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
-	struct ubd *dev = disk->private_data;
+	struct ubd *ubd_dev = disk->private_data;
 	int err = 0;
 
-	if(dev->count == 0){
-		err = ubd_open_dev(dev);
+	if(ubd_dev->count == 0){
+		err = ubd_open_dev(ubd_dev);
 		if(err){
 			printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
-			       disk->disk_name, dev->file, -err);
+			       disk->disk_name, ubd_dev->file, -err);
 			goto out;
 		}
 	}
-	dev->count++;
-	set_disk_ro(disk, !dev->openflags.w);
+	ubd_dev->count++;
+	set_disk_ro(disk, !ubd_dev->openflags.w);
 
 	/* This should no more be needed. And it didn't work anyway to exclude
 	 * read-write remounting of filesystems.*/
-	/*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
-	        if(--dev->count == 0) ubd_close(dev);
+	/*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){
+	        if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev);
 	        err = -EROFS;
 	}*/
  out:
@@ -905,10 +936,10 @@
 static int ubd_release(struct inode * inode, struct file * file)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
-	struct ubd *dev = disk->private_data;
+	struct ubd *ubd_dev = disk->private_data;
 
-	if(--dev->count == 0)
-		ubd_close(dev);
+	if(--ubd_dev->count == 0)
+		ubd_close_dev(ubd_dev);
 	return(0);
 }
 
@@ -976,12 +1007,12 @@
 static int prepare_request(struct request *req, struct io_thread_req *io_req)
 {
 	struct gendisk *disk = req->rq_disk;
-	struct ubd *dev = disk->private_data;
+	struct ubd *ubd_dev = disk->private_data;
 	__u64 offset;
 	int len;
 
 	/* This should be impossible now */
-	if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
+	if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){
 		printk("Write attempted on readonly ubd device %s\n",
 		       disk->disk_name);
 		end_request(req, 0);
@@ -991,8 +1022,8 @@
 	offset = ((__u64) req->sector) << 9;
 	len = req->current_nr_sectors << 9;
 
-	io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
-	io_req->fds[1] = dev->fd;
+	io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd;
+	io_req->fds[1] = ubd_dev->fd;
 	io_req->cow_offset = -1;
 	io_req->offset = offset;
 	io_req->length = len;
@@ -1001,13 +1032,13 @@
 
 	io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
 	io_req->offsets[0] = 0;
-	io_req->offsets[1] = dev->cow.data_offset;
+	io_req->offsets[1] = ubd_dev->cow.data_offset;
 	io_req->buffer = req->buffer;
 	io_req->sectorsize = 1 << 9;
 
-	if(dev->cow.file != NULL)
-		cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
-			   dev->cow.bitmap_len);
+	if(ubd_dev->cow.file != NULL)
+		cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset,
+			   ubd_dev->cow.bitmap_len);
 
 	return(0);
 }
@@ -1033,7 +1064,7 @@
 			return;
 		err = prepare_request(req, &io_req);
 		if(!err){
-			do_ubd = ubd_handler;
+			do_ubd = 1;
 			n = os_write_file(thread_fd, (char *) &io_req,
 					 sizeof(io_req));
 			if(n != sizeof(io_req))
@@ -1045,18 +1076,18 @@
 
 static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	struct ubd *dev = bdev->bd_disk->private_data;
+	struct ubd *ubd_dev = bdev->bd_disk->private_data;
 
 	geo->heads = 128;
 	geo->sectors = 32;
-	geo->cylinders = dev->size / (128 * 32 * 512);
+	geo->cylinders = ubd_dev->size / (128 * 32 * 512);
 	return 0;
 }
 
 static int ubd_ioctl(struct inode * inode, struct file * file,
 		     unsigned int cmd, unsigned long arg)
 {
-	struct ubd *dev = inode->i_bdev->bd_disk->private_data;
+	struct ubd *ubd_dev = inode->i_bdev->bd_disk->private_data;
 	struct hd_driveid ubd_id = {
 		.cyls		= 0,
 		.heads		= 128,
@@ -1066,7 +1097,7 @@
 	switch (cmd) {
 		struct cdrom_volctrl volume;
 	case HDIO_GET_IDENTITY:
-		ubd_id.cyls = dev->size / (128 * 32 * 512);
+		ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
 		if(copy_to_user((char __user *) arg, (char *) &ubd_id,
 				 sizeof(ubd_id)))
 			return(-EFAULT);
@@ -1353,8 +1384,8 @@
  */
 int kernel_fd = -1;
 
-/* Only changed by the io thread */
-int io_count = 0;
+/* Only changed by the io thread. XXX: currently unused. */
+static int io_count = 0;
 
 int io_thread(void *arg)
 {
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 58f67d3..2666815 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -61,6 +61,7 @@
 
 	struct mconsole_request request;
 	struct mconsole_command *cmd;
+	union uml_pt_regs regs;
 };
 
 extern char mconsole_socket_name[];
diff --git a/arch/um/include/mconsole_kern.h b/arch/um/include/mconsole_kern.h
index d0b6901..1ea6d928 100644
--- a/arch/um/include/mconsole_kern.h
+++ b/arch/um/include/mconsole_kern.h
@@ -14,6 +14,7 @@
 	struct mc_request request;
 };
 
+/* All these methods are called in process context. */
 struct mc_device {
 	struct list_head list;
 	char *name;
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 6516f6d..13a86bd 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -233,6 +233,8 @@
 				    void (*op)(void *to, const void *from,
 					       int n), int *faulted_out);
 
+/* execvp.c */
+extern int execvp_noalloc(char *buf, const char *file, char *const argv[]);
 /* helper.c */
 extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
 		      unsigned long *stack_out);
diff --git a/arch/um/include/sysdep-i386/barrier.h b/arch/um/include/sysdep-i386/barrier.h
new file mode 100644
index 0000000..b58d52c
--- /dev/null
+++ b/arch/um/include/sysdep-i386/barrier.h
@@ -0,0 +1,9 @@
+#ifndef __SYSDEP_I386_BARRIER_H
+#define __SYSDEP_I386_BARRIER_H
+
+/* Copied from include/asm-i386 for use by userspace.  i386 has the option
+ * of using mfence, but I'm just using this, which works everywhere, for now.
+ */
+#define mb() asm volatile("lock; addl $0,0(%esp)")
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/barrier.h b/arch/um/include/sysdep-x86_64/barrier.h
new file mode 100644
index 0000000..7b610be
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/barrier.h
@@ -0,0 +1,7 @@
+#ifndef __SYSDEP_X86_64_BARRIER_H
+#define __SYSDEP_X86_64_BARRIER_H
+
+/* Copied from include/asm-x86_64 for use by userspace. */
+#define mb() 	asm volatile("mfence":::"memory")
+
+#endif
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 68ed24d..e36f92b 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -14,6 +14,7 @@
    * is remapped.*/
   __binary_start = .;
   . = ALIGN(4096);		/* Init code and data */
+  _text = .;
   _stext = .;
   __init_begin = .;
   .init.text : {
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index 9882342..b919535 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -176,7 +176,6 @@
 int signal_index[32];
 int nsignals = 0;
 int debug_trace = 0;
-extern int io_nsignals, io_count, intr_count;
 
 extern void signal_usr1(int sig);
 
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 8eca47a..f630127 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -25,6 +25,7 @@
   . = ALIGN(4096);		/* Init code and data */
 #endif
 
+  _text = .;
   _stext = .;
   __init_begin = .;
   .init.text : {
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index b418392..2f8c794 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,8 +3,8 @@
 # Licensed under the GPL
 #
 
-obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \
-	signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \
+obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
+	sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \
 	user_syms.o util.o drivers/ sys-$(SUBARCH)/
 
 obj-$(CONFIG_MODE_SKAS) += skas/
@@ -15,9 +15,9 @@
 obj-$(CONFIG_TTY_LOG) += tty_log.o
 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
 
-USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \
-	process.o sigio.o signal.o start_up.o time.o trap.o tty.o tls.o \
-	uaccess.o umid.o util.o
+USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
+	main.o mem.o process.o sigio.o signal.o start_up.o time.o trap.o tty.o \
+	tls.o uaccess.o umid.o util.o
 
 CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
 
diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c
new file mode 100644
index 0000000..66e583a
--- /dev/null
+++ b/arch/um/os-Linux/execvp.c
@@ -0,0 +1,149 @@
+/* Copyright (C) 2006 by Paolo Giarrusso - modified from glibc' execvp.c.
+   Original copyright notice follows:
+
+   Copyright (C) 1991,92,1995-99,2002,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+#include <unistd.h>
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+#ifndef TEST
+#include "um_malloc.h"
+#else
+#include <stdio.h>
+#define um_kmalloc malloc
+#endif
+#include "os.h"
+
+/* Execute FILE, searching in the `PATH' environment variable if it contains
+   no slashes, with arguments ARGV and environment from `environ'.  */
+int execvp_noalloc(char *buf, const char *file, char *const argv[])
+{
+	if (*file == '\0') {
+		return -ENOENT;
+	}
+
+	if (strchr (file, '/') != NULL) {
+		/* Don't search when it contains a slash.  */
+		execv(file, argv);
+	} else {
+		int got_eacces;
+		size_t len, pathlen;
+		char *name, *p;
+		char *path = getenv("PATH");
+		if (path == NULL)
+			path = ":/bin:/usr/bin";
+
+		len = strlen(file) + 1;
+		pathlen = strlen(path);
+		/* Copy the file name at the top.  */
+		name = memcpy(buf + pathlen + 1, file, len);
+		/* And add the slash.  */
+		*--name = '/';
+
+		got_eacces = 0;
+		p = path;
+		do {
+			char *startp;
+
+			path = p;
+			//Let's avoid this GNU extension.
+			//p = strchrnul (path, ':');
+			p = strchr(path, ':');
+			if (!p)
+				p = strchr(path, '\0');
+
+			if (p == path)
+				/* Two adjacent colons, or a colon at the beginning or the end
+				   of `PATH' means to search the current directory.  */
+				startp = name + 1;
+			else
+				startp = memcpy(name - (p - path), path, p - path);
+
+			/* Try to execute this name.  If it works, execv will not return.  */
+			execv(startp, argv);
+
+			/*
+			if (errno == ENOEXEC) {
+			}
+			*/
+
+			switch (errno) {
+				case EACCES:
+					/* Record the we got a `Permission denied' error.  If we end
+					   up finding no executable we can use, we want to diagnose
+					   that we did find one but were denied access.  */
+					got_eacces = 1;
+				case ENOENT:
+				case ESTALE:
+				case ENOTDIR:
+					/* Those errors indicate the file is missing or not executable
+					   by us, in which case we want to just try the next path
+					   directory.  */
+				case ENODEV:
+				case ETIMEDOUT:
+					/* Some strange filesystems like AFS return even
+					   stranger error numbers.  They cannot reasonably mean
+					   anything else so ignore those, too.  */
+				case ENOEXEC:
+					/* We won't go searching for the shell
+					 * if it is not executable - the Linux
+					 * kernel already handles this enough,
+					 * for us. */
+					break;
+
+				default:
+					/* Some other error means we found an executable file, but
+					   something went wrong executing it; return the error to our
+					   caller.  */
+					return -errno;
+			}
+		} while (*p++ != '\0');
+
+		/* We tried every element and none of them worked.  */
+		if (got_eacces)
+			/* At least one failure was due to permissions, so report that
+			   error.  */
+			return -EACCES;
+	}
+
+	/* Return the error from the last attempt (probably ENOENT).  */
+	return -errno;
+}
+#ifdef TEST
+int main(int argc, char**argv)
+{
+	char buf[PATH_MAX];
+	int ret;
+	argc--;
+	if (!argc) {
+		fprintf(stderr, "Not enough arguments\n");
+		return 1;
+	}
+	argv++;
+	if (ret = execvp_noalloc(buf, argv[0], argv)) {
+		errno = -ret;
+		perror("execvp_noalloc");
+	}
+	return 0;
+}
+#endif
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index d13299c..c7ad630 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -8,18 +8,21 @@
 #include <unistd.h>
 #include <errno.h>
 #include <sched.h>
+#include <limits.h>
 #include <sys/signal.h>
 #include <sys/wait.h>
 #include "user.h"
 #include "kern_util.h"
 #include "user_util.h"
 #include "os.h"
+#include "um_malloc.h"
 
 struct helper_data {
 	void (*pre_exec)(void*);
 	void *pre_data;
 	char **argv;
 	int fd;
+	char *buf;
 };
 
 /* Debugging aid, changed only from gdb */
@@ -41,9 +44,8 @@
 	}
 	if (data->pre_exec != NULL)
 		(*data->pre_exec)(data->pre_data);
-	execvp(argv[0], argv);
-	errval = -errno;
-	printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno);
+	errval = execvp_noalloc(data->buf, argv[0], argv);
+	printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval);
 	os_write_file(data->fd, &errval, sizeof(errval));
 	kill(os_getpid(), SIGKILL);
 	return 0;
@@ -84,11 +86,13 @@
 	data.pre_data = pre_data;
 	data.argv = argv;
 	data.fd = fds[1];
+	data.buf = __cant_sleep() ? um_kmalloc_atomic(PATH_MAX) :
+					um_kmalloc(PATH_MAX);
 	pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
 	if (pid < 0) {
 		ret = -errno;
 		printk("run_helper : clone failed, errno = %d\n", errno);
-		goto out_close;
+		goto out_free2;
 	}
 
 	close(fds[1]);
@@ -109,6 +113,8 @@
 		CATCH_EINTR(waitpid(pid, NULL, 0));
 	}
 
+out_free2:
+	kfree(data.buf);
 out_close:
 	if (fds[1] != -1)
 		close(fds[1]);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 51f0893..c692a19 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -7,7 +7,6 @@
 #include <stdio.h>
 #include <errno.h>
 #include <signal.h>
-#include <linux/unistd.h>
 #include <sys/mman.h>
 #include <sys/wait.h>
 #include <sys/mman.h>
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 6b81739..b897e85 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -15,6 +15,7 @@
 #include "user.h"
 #include "signal_kern.h"
 #include "sysdep/sigcontext.h"
+#include "sysdep/barrier.h"
 #include "sigcontext.h"
 #include "mode.h"
 #include "os.h"
@@ -34,8 +35,12 @@
 #define SIGALRM_BIT 2
 #define SIGALRM_MASK (1 << SIGALRM_BIT)
 
-static int signals_enabled = 1;
-static int pending = 0;
+/* These are used by both the signal handlers and
+ * block/unblock_signals.  I don't want modifications cached in a
+ * register - they must go straight to memory.
+ */
+static volatile int signals_enabled = 1;
+static volatile int pending = 0;
 
 void sig_handler(int sig, struct sigcontext *sc)
 {
@@ -152,6 +157,12 @@
 void block_signals(void)
 {
 	signals_enabled = 0;
+	/* This must return with signals disabled, so this barrier
+	 * ensures that writes are flushed out before the return.
+	 * This might matter if gcc figures out how to inline this and
+	 * decides to shuffle this code into the caller.
+	 */
+	mb();
 }
 
 void unblock_signals(void)
@@ -171,9 +182,23 @@
 		 */
 		signals_enabled = 1;
 
+		/* Setting signals_enabled and reading pending must
+		 * happen in this order.
+		 */
+		mb();
+
 		save_pending = pending;
-		if(save_pending == 0)
+		if(save_pending == 0){
+			/* This must return with signals enabled, so
+			 * this barrier ensures that writes are
+			 * flushed out before the return.  This might
+			 * matter if gcc figures out how to inline
+			 * this (unlikely, given its size) and decides
+			 * to shuffle this code into the caller.
+			 */
+			mb();
 			return;
+		}
 
 		pending = 0;
 
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index cb9ab54..9b34fe6 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -14,7 +14,7 @@
 #include <sys/mman.h>
 #include <sys/user.h>
 #include <sys/time.h>
-#include <asm/unistd.h>
+#include <sys/syscall.h>
 #include <asm/types.h>
 #include "user.h"
 #include "sysdep/ptrace.h"
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index 6e945ab..2565320 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -1,6 +1,9 @@
 #include <errno.h>
 #include <linux/unistd.h>
+
 #include <sys/syscall.h>
+#include <unistd.h>
+
 #include "sysdep/tls.h"
 #include "user_util.h"
 
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
index a2de258..16215b9 100644
--- a/arch/um/os-Linux/tls.c
+++ b/arch/um/os-Linux/tls.c
@@ -1,4 +1,5 @@
 #include <errno.h>
+#include <unistd.h>
 #include <sys/ptrace.h>
 #include <sys/syscall.h>
 #include <asm/ldt.h>
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
index 8e55cd5..1b0ad0e4 100644
--- a/arch/um/sys-i386/unmap.c
+++ b/arch/um/sys-i386/unmap.c
@@ -5,17 +5,20 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
-#include <sys/syscall.h>
 
+static int errno;
+
+static inline _syscall2(int,munmap,void *,start,size_t,len)
+static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-	if (syscall(__NR_munmap, to, size) < 0){
+	if(munmap(to, size) < 0){
 		return(-1);
 	}
-	if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
+	if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
 		return(-1);
 	}
-	if (syscall(__NR_munmap, from, size) < 0){
+	if(munmap(from, size) < 0){
 		return(-1);
 	}
 	return(0);
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
index 57c9286..f4a4bff 100644
--- a/arch/um/sys-x86_64/unmap.c
+++ b/arch/um/sys-x86_64/unmap.c
@@ -5,17 +5,20 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
-#include <sys/syscall.h>
 
+static int errno;
+
+static inline _syscall2(int,munmap,void *,start,size_t,len)
+static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-	if (syscall(__NR_munmap, to, size) < 0){
+	if(munmap(to, size) < 0){
 		return(-1);
 	}
-	if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
+	if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
 		return(-1);
 	}
-	if (syscall(__NR_munmap, from, size) < 0){
+	if(munmap(from, size) < 0){
 		return(-1);
 	}
 	return(0);
diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S
index 6339921..88d087f 100644
--- a/arch/v850/kernel/vmlinux.lds.S
+++ b/arch/v850/kernel/vmlinux.lds.S
@@ -140,13 +140,7 @@
 		___setup_end = . ;					      \
 		___initcall_start = . ;					      \
 			*(.initcall.init)				      \
-			*(.initcall1.init)				      \
-			*(.initcall2.init)				      \
-			*(.initcall3.init)				      \
-			*(.initcall4.init)				      \
-			*(.initcall5.init)				      \
-			*(.initcall6.init)				      \
-			*(.initcall7.init)				      \
+			INITCALLS					      \
 		. = ALIGN (4) ;						      \
 		___initcall_end = . ;					      \
 		___con_initcall_start = .;				      \
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 1c0f18d..6e38d4d 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -54,6 +54,10 @@
 cflags-y += $(call cc-option,-funit-at-a-time)
 # prevent gcc from generating any FP code by mistake
 cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
+# this works around some issues with generating unwind tables in older gccs
+# newer gccs do it by default
+cflags-y += -maccumulate-outgoing-args
+
 # do binutils support CFI?
 cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
 AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
@@ -62,8 +66,8 @@
 cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
 AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
 
-cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector )
-cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector-all )
+cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector )
+cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector-all )
 
 CFLAGS += $(cflags-y)
 CFLAGS_KERNEL += $(cflags-kernel-y)
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
index c3bfd22..770940c 100644
--- a/arch/x86_64/boot/setup.S
+++ b/arch/x86_64/boot/setup.S
@@ -836,13 +836,12 @@
 	.word	0x9200				# data read/write
 	.word	0x00CF				# granularity = 4096, 386
 						#  (+5th nibble of limit)
+gdt_end:
 idt_48:
 	.word	0				# idt limit = 0
 	.word	0, 0				# idt base = 0L
 gdt_48:
-	.word	0x8000				# gdt limit=2048,
-						#  256 GDT entries
-
+	.word	gdt_end-gdt-1			# gdt limit
 	.word	0, 0				# gdt base (filled in later)
 
 # Include video setup & detection code
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 47bfba6e..0f5d44e 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc1
-# Thu Oct  5 13:04:43 2006
+# Linux kernel version: 2.6.19-rc2-git4
+# Sat Oct 21 03:38:52 2006
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -335,8 +335,8 @@
 # CONFIG_INET6_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -438,6 +438,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -1008,6 +1015,7 @@
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -1059,12 +1067,6 @@
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-# CONFIG_TIFM_CORE is not set
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -1196,7 +1198,6 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1242,6 +1243,7 @@
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1318,6 +1320,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1341,6 +1344,7 @@
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1418,7 +1422,6 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
 # CONFIG_9P_FS is not set
-CONFIG_GENERIC_ACL=y
 
 #
 # Partition Types
@@ -1471,10 +1474,6 @@
 CONFIG_NLS_UTF8=y
 
 #
-# Distributed Lock Manager
-#
-
-#
 # Instrumentation Support
 #
 CONFIG_PROFILING=y
@@ -1512,6 +1511,7 @@
 CONFIG_UNWIND_INFO=y
 CONFIG_STACK_UNWIND=y
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 # CONFIG_DEBUG_RODATA is not set
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index a6ba995..0e0a266 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -579,6 +579,11 @@
 	regs->rsp = (unsigned long) frame;
 	regs->rip = (unsigned long) ka->sa.sa_handler;
 
+	/* Make -mregparm=3 work */
+	regs->rax = sig;
+	regs->rdx = (unsigned long) &frame->info;
+	regs->rcx = (unsigned long) &frame->uc;
+
 	asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 
 	asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 
 	
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
index 3a7561d..04566fe 100644
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -244,6 +244,8 @@
 	case PTRACE_DETACH:
 	case PTRACE_SYSCALL:
 	case PTRACE_SETOPTIONS:
+	case PTRACE_SET_THREAD_AREA:
+	case PTRACE_GET_THREAD_AREA:
 		return sys_ptrace(request, pid, addr, data); 
 
 	default:
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index b3f0908..6fe191c 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -54,13 +54,13 @@
 
 	/* various gunk below that needed for SMP startup */
 	if (addr < 0x8000) { 
-		*addrp = 0x8000;
+		*addrp = PAGE_ALIGN(0x8000);
 		return 1; 
 	}
 
 	/* direct mapping tables of the kernel */
 	if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) { 
-		*addrp = table_end << PAGE_SHIFT; 
+		*addrp = PAGE_ALIGN(table_end << PAGE_SHIFT);
 		return 1;
 	} 
 
@@ -68,18 +68,18 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (LOADER_TYPE && INITRD_START && last >= INITRD_START && 
 	    addr < INITRD_START+INITRD_SIZE) { 
-		*addrp = INITRD_START + INITRD_SIZE; 
+		*addrp = PAGE_ALIGN(INITRD_START + INITRD_SIZE);
 		return 1;
 	} 
 #endif
 	/* kernel code */
-	if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) {
-		*addrp = __pa_symbol(&_end);
+	if (last >= __pa_symbol(&_text) && addr < __pa_symbol(&_end)) {
+		*addrp = PAGE_ALIGN(__pa_symbol(&_end));
 		return 1;
 	}
 
 	if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
-		*addrp = ebda_addr + ebda_size;
+		*addrp = PAGE_ALIGN(ebda_addr + ebda_size);
 		return 1;
 	}
 
@@ -152,7 +152,7 @@
 			continue; 
 		while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
 			;
-		last = addr + size;
+		last = PAGE_ALIGN(addr) + size;
 		if (last > ei->addr + ei->size)
 			continue;
 		if (last > end) 
@@ -278,7 +278,7 @@
 								>> PAGE_SHIFT;
 
 		/* Skip map entries smaller than a page */
-		if (ei_startpfn > ei_endpfn)
+		if (ei_startpfn >= ei_endpfn)
 			continue;
 
 		/* Check if end_pfn_map should be updated */
@@ -594,7 +594,9 @@
 		 * size before original memory map is
 		 * reset.
 		 */
+		e820_register_active_regions(0, 0, -1UL);
 		saved_max_pfn = e820_end_of_ram();
+		remove_all_active_ranges();
 #endif
 		end_pfn_map = 0;
 		e820.nr_map = 0;
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c
index 208e38a..68273bf 100644
--- a/arch/x86_64/kernel/early-quirks.c
+++ b/arch/x86_64/kernel/early-quirks.c
@@ -45,7 +45,13 @@
 	/*
 	 * All timer overrides on Nvidia are
 	 * wrong unless HPET is enabled.
+	 * Unfortunately that's not true on many Asus boards.
+	 * We don't know yet how to detect this automatically, but
+	 * at least allow a command line override.
 	 */
+	if (acpi_use_timer_override)
+		return;
+
 	nvidia_hpet_detected = 0;
 	acpi_table_parse(ACPI_HPET, nvidia_hpet_check);
 	if (nvidia_hpet_detected == 0) {
@@ -53,6 +59,8 @@
 		printk(KERN_INFO "Nvidia board "
 		       "detected. Ignoring ACPI "
 		       "timer override.\n");
+		printk(KERN_INFO "If you got timer trouble "
+			"try acpi_use_timer_override\n");
 	}
 #endif
 	/* RED-PEN skip them on mptables too? */
@@ -61,10 +69,11 @@
 
 static void ati_bugs(void)
 {
-#if 1 /* for testing */
-	printk("ATI board detected\n");
-#endif
-	/* No bugs right now */
+	if (timer_over_8254 == 1) {
+		timer_over_8254 = 0;
+		printk(KERN_INFO
+	 	"ATI board detected. Disabling timer routing over 8254.\n");
+	}
 }
 
 struct chipset {
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index e22ecd5..47b6d903 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -224,7 +224,7 @@
 		return 0;
 	early_console_initialized = 1;
 
-	if (!strcmp(buf,"keep"))
+	if (strstr(buf, "keep"))
 		keep_early = 1;
 
 	if (!strncmp(buf, "serial", 6)) {
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 38a7b2d..7d401b0 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -315,6 +315,8 @@
 	LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
 	cmpq $__NR_syscall_max,%rax
+	movq $-ENOSYS,%rcx
+	cmova %rcx,%rax
 	ja  1f
 	movq %r10,%rcx	/* fixup for C */
 	call *sys_call_table(,%rax,8)
@@ -535,8 +537,6 @@
 1:	incl	%gs:pda_irqcount
 	cmoveq %gs:pda_irqstackptr,%rsp
 	push    %rbp			# backlink for old unwinder
-	CFI_ADJUST_CFA_OFFSET 8
-	CFI_REL_OFFSET rbp,0
 	/*
 	 * We entered an interrupt context - irqs are off:
 	 */
@@ -980,11 +980,6 @@
 	call do_fork
 	movq %rax,RAX(%rsp)
 	xorl %edi,%edi
-	test %rax,%rax
-	jnz  1f
-	/* terminate stack in child */
-	movq %rdi,RIP(%rsp)
-1:
 
 	/*
 	 * It isn't worth to check for reschedule here,
@@ -1176,7 +1171,6 @@
 	incl %gs:pda_irqcount
 	cmove %gs:pda_irqstackptr,%rsp
 	push  %rbp			# backlink for old unwinder
-	CFI_ADJUST_CFA_OFFSET    8
 	call __do_softirq
 	leaveq
 	CFI_DEF_CFA_REGISTER	rsp
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c
index 0dfc223..7c01db8 100644
--- a/arch/x86_64/kernel/genapic_flat.c
+++ b/arch/x86_64/kernel/genapic_flat.c
@@ -153,7 +153,7 @@
 
 static cpumask_t physflat_target_cpus(void)
 {
-	return cpumask_of_cpu(0);
+	return cpu_online_map;
 }
 
 static cpumask_t physflat_vector_allocation_domain(int cpu)
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 49e94f7..c80081a 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -57,13 +57,13 @@
 
 static int disable_timer_pin_1 __initdata;
 
-int timer_over_8254 __initdata = 0;
+int timer_over_8254 __initdata = 1;
 
 /* Where if anywhere is the i8259 connect in external int mode */
 static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 
 static DEFINE_SPINLOCK(ioapic_lock);
-static DEFINE_SPINLOCK(vector_lock);
+DEFINE_SPINLOCK(vector_lock);
 
 /*
  * # of IRQ routing registers
@@ -88,6 +88,52 @@
 	short apic, pin, next;
 } irq_2_pin[PIN_MAP_SIZE];
 
+struct io_apic {
+	unsigned int index;
+	unsigned int unused[3];
+	unsigned int data;
+};
+
+static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
+{
+	return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
+		+ (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK);
+}
+
+static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+	writel(reg, &io_apic->index);
+	return readl(&io_apic->data);
+}
+
+static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+	writel(reg, &io_apic->index);
+	writel(value, &io_apic->data);
+}
+
+/*
+ * Re-write a value: to be used for read-modify-write
+ * cycles where the read already set up the index register.
+ */
+static inline void io_apic_modify(unsigned int apic, unsigned int value)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+	writel(value, &io_apic->data);
+}
+
+/*
+ * Synchronize the IO-APIC and the CPU by doing
+ * a dummy read from the IO-APIC
+ */
+static inline void io_apic_sync(unsigned int apic)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+	readl(&io_apic->data);
+}
+
 #define __DO_ACTION(R, ACTION, FINAL)					\
 									\
 {									\
@@ -126,12 +172,34 @@
 	return eu.entry;
 }
 
+/*
+ * When we write a new IO APIC routing entry, we need to write the high
+ * word first! If the mask bit in the low word is clear, we will enable
+ * the interrupt, and we need to make sure the entry is fully populated
+ * before that happens.
+ */
 static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
 {
 	unsigned long flags;
 	union entry_union eu;
 	eu.entry = e;
 	spin_lock_irqsave(&ioapic_lock, flags);
+	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
+	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+/*
+ * When we mask an IO APIC routing entry, we need to write the low
+ * word first, in order to set the mask bit before we change the
+ * high bits!
+ */
+static void ioapic_mask_entry(int apic, int pin)
+{
+	unsigned long flags;
+	union entry_union eu = { .entry.mask = 1 };
+
+	spin_lock_irqsave(&ioapic_lock, flags);
 	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
 	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -256,9 +324,7 @@
 	/*
 	 * Disable it in the IO-APIC irq-routing table:
 	 */
-	memset(&entry, 0, sizeof(entry));
-	entry.mask = 1;
-	ioapic_write_entry(apic, pin, entry);
+	ioapic_mask_entry(apic, pin);
 }
 
 static void clear_IO_APIC (void)
@@ -612,15 +678,15 @@
 	 * Also, we've got to be careful not to trash gate
 	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
 	 */
-	static struct {
-		int vector;
-		int offset;
-	} pos[NR_CPUS] = { [ 0 ... NR_CPUS - 1] = {FIRST_DEVICE_VECTOR, 0} };
+	static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
 	int old_vector = -1;
 	int cpu;
 
 	BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
 
+	/* Only try and allocate irqs on cpus that are present */
+	cpus_and(mask, mask, cpu_online_map);
+
 	if (irq_vector[irq] > 0)
 		old_vector = irq_vector[irq];
 	if (old_vector > 0) {
@@ -630,15 +696,15 @@
 	}
 
 	for_each_cpu_mask(cpu, mask) {
-		cpumask_t domain;
-		int first, new_cpu;
+		cpumask_t domain, new_mask;
+		int new_cpu;
 		int vector, offset;
 
 		domain = vector_allocation_domain(cpu);
-		first = first_cpu(domain);
+		cpus_and(new_mask, domain, cpu_online_map);
 
-		vector = pos[first].vector;
-		offset = pos[first].offset;
+		vector = current_vector;
+		offset = current_offset;
 next:
 		vector += 8;
 		if (vector >= FIRST_SYSTEM_VECTOR) {
@@ -646,24 +712,24 @@
 			offset = (offset + 1) % 8;
 			vector = FIRST_DEVICE_VECTOR + offset;
 		}
-		if (unlikely(pos[first].vector == vector))
+		if (unlikely(current_vector == vector))
 			continue;
 		if (vector == IA32_SYSCALL_VECTOR)
 			goto next;
-		for_each_cpu_mask(new_cpu, domain)
-			if (per_cpu(vector_irq, cpu)[vector] != -1)
+		for_each_cpu_mask(new_cpu, new_mask)
+			if (per_cpu(vector_irq, new_cpu)[vector] != -1)
 				goto next;
 		/* Found one! */
-		for_each_cpu_mask(new_cpu, domain) {
-			pos[cpu].vector = vector;
-			pos[cpu].offset = offset;
-		}
+		current_vector = vector;
+		current_offset = offset;
 		if (old_vector >= 0) {
+			cpumask_t old_mask;
 			int old_cpu;
-			for_each_cpu_mask(old_cpu, irq_domain[irq])
+			cpus_and(old_mask, irq_domain[irq], cpu_online_map);
+			for_each_cpu_mask(old_cpu, old_mask)
 				per_cpu(vector_irq, old_cpu)[old_vector] = -1;
 		}
-		for_each_cpu_mask(new_cpu, domain)
+		for_each_cpu_mask(new_cpu, new_mask)
 			per_cpu(vector_irq, new_cpu)[vector] = irq;
 		irq_vector[irq] = vector;
 		irq_domain[irq] = domain;
@@ -684,6 +750,30 @@
 	return vector;
 }
 
+void __setup_vector_irq(int cpu)
+{
+	/* Initialize vector_irq on a new cpu */
+	/* This function must be called with vector_lock held */
+	int irq, vector;
+
+	/* Mark the inuse vectors */
+	for (irq = 0; irq < NR_IRQ_VECTORS; ++irq) {
+		if (!cpu_isset(cpu, irq_domain[irq]))
+			continue;
+		vector = irq_vector[irq];
+		per_cpu(vector_irq, cpu)[vector] = irq;
+	}
+	/* Mark the free vectors */
+	for (vector = 0; vector < NR_VECTORS; ++vector) {
+		irq = per_cpu(vector_irq, cpu)[vector];
+		if (irq < 0)
+			continue;
+		if (!cpu_isset(cpu, irq_domain[irq]))
+			per_cpu(vector_irq, cpu)[vector] = -1;
+	}
+}
+
+
 extern void (*interrupt[NR_IRQS])(void);
 
 static struct irq_chip ioapic_chip;
@@ -698,9 +788,11 @@
 			trigger == IOAPIC_LEVEL)
 		set_irq_chip_and_handler_name(irq, &ioapic_chip,
 					      handle_fasteoi_irq, "fasteoi");
-	else
+	else {
+		irq_desc[irq].status |= IRQ_DELAYED_DISABLE;
 		set_irq_chip_and_handler_name(irq, &ioapic_chip,
 					      handle_edge_irq, "edge");
+	}
 }
 
 static void __init setup_IO_APIC_irqs(void)
@@ -1255,12 +1347,15 @@
 {
 	cpumask_t mask;
 	unsigned vector;
+	unsigned long flags;
 
+	spin_lock_irqsave(&vector_lock, flags);
 	vector = irq_vector[irq];
 	cpus_clear(mask);
-	cpu_set(vector >> 8, mask);
+	cpu_set(first_cpu(irq_domain[irq]), mask);
 
-	send_IPI_mask(mask, vector & 0xff);
+	send_IPI_mask(mask, vector);
+	spin_unlock_irqrestore(&vector_lock, flags);
 
 	return 1;
 }
@@ -1860,18 +1955,16 @@
 
 static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
 {
-	u32 low, high;
-	low  = read_ht_irq_low(irq);
-	high = read_ht_irq_high(irq);
+	struct ht_irq_msg msg;
+	fetch_ht_irq_msg(irq, &msg);
 
-	low  &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK);
-	high &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
+	msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK);
+	msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
 
-	low  |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest);
-	high |= HT_IRQ_HIGH_DEST_ID(dest);
+	msg.address_lo |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest);
+	msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest);
 
-	write_ht_irq_low(irq, low);
-	write_ht_irq_high(irq, high);
+	write_ht_irq_msg(irq, &msg);
 }
 
 static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
@@ -1892,7 +1985,7 @@
 
 	dest = cpu_mask_to_apicid(tmp);
 
-	target_ht_irq(irq, dest, vector & 0xff);
+	target_ht_irq(irq, dest, vector);
 	set_native_irq_info(irq, mask);
 }
 #endif
@@ -1915,14 +2008,15 @@
 
 	vector = assign_irq_vector(irq, TARGET_CPUS, &tmp);
 	if (vector >= 0) {
-		u32 low, high;
+		struct ht_irq_msg msg;
 		unsigned dest;
 
 		dest = cpu_mask_to_apicid(tmp);
 
-		high = 	HT_IRQ_HIGH_DEST_ID(dest);
+		msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
 
-		low =	HT_IRQ_LOW_BASE |
+		msg.address_lo =
+			HT_IRQ_LOW_BASE |
 			HT_IRQ_LOW_DEST_ID(dest) |
 			HT_IRQ_LOW_VECTOR(vector) |
 			((INT_DEST_MODE == 0) ?
@@ -1931,10 +2025,10 @@
 			HT_IRQ_LOW_RQEOI_EDGE |
 			((INT_DELIVERY_MODE != dest_LowestPrio) ?
 				HT_IRQ_LOW_MT_FIXED :
-				HT_IRQ_LOW_MT_ARBITRATED);
+				HT_IRQ_LOW_MT_ARBITRATED) |
+			HT_IRQ_LOW_IRQ_MASKED;
 
-		write_ht_irq_low(irq, low);
-		write_ht_irq_high(irq, high);
+		write_ht_irq_msg(irq, &msg);
 
 		set_irq_chip_and_handler_name(irq, &ht_irq_chip,
 					      handle_edge_irq, "edge");
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index b3296cc..37a7708 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -52,7 +52,8 @@
 #define ONE_BASED_CHASSIS_NUM   1
 
 /* register offsets inside the host bridge space */
-#define PHB_CSR_OFFSET		0x0110
+#define CALGARY_CONFIG_REG	0x0108
+#define PHB_CSR_OFFSET		0x0110 /* Channel Status */
 #define PHB_PLSSR_OFFSET	0x0120
 #define PHB_CONFIG_RW_OFFSET	0x0160
 #define PHB_IOBASE_BAR_LOW	0x0170
@@ -83,6 +84,8 @@
 #define TAR_VALID		0x0000000000000008UL
 /* CSR (Channel/DMA Status Register) */
 #define CSR_AGENT_MASK		0xffe0ffff
+/* CCR (Calgary Configuration Register) */
+#define CCR_2SEC_TIMEOUT        0x000000000000000EUL
 
 #define MAX_NUM_OF_PHBS		8 /* how many PHBs in total? */
 #define MAX_NUM_CHASSIS		8 /* max number of chassis */
@@ -732,6 +735,38 @@
 	}
 }
 
+static void __init calgary_increase_split_completion_timeout(void __iomem *bbar,
+	unsigned char busnum)
+{
+	u64 val64;
+	void __iomem *target;
+	unsigned long phb_shift = -1;
+	u64 mask;
+
+	switch (busno_to_phbid(busnum)) {
+	case 0: phb_shift = (63 - 19);
+		break;
+	case 1: phb_shift = (63 - 23);
+		break;
+	case 2: phb_shift = (63 - 27);
+		break;
+	case 3: phb_shift = (63 - 35);
+		break;
+	default:
+		BUG_ON(busno_to_phbid(busnum));
+	}
+
+	target = calgary_reg(bbar, CALGARY_CONFIG_REG);
+	val64 = be64_to_cpu(readq(target));
+
+	/* zero out this PHB's timer bits */
+	mask = ~(0xFUL << phb_shift);
+	val64 &= mask;
+	val64 |= (CCR_2SEC_TIMEOUT << phb_shift);
+	writeq(cpu_to_be64(val64), target);
+	readq(target); /* flush */
+}
+
 static void __init calgary_enable_translation(struct pci_dev *dev)
 {
 	u32 val32;
@@ -756,6 +791,13 @@
 	writel(cpu_to_be32(val32), target);
 	readl(target); /* flush */
 
+	/*
+	 * Give split completion a longer timeout on bus 1 for aic94xx
+	 * http://bugzilla.kernel.org/show_bug.cgi?id=7180
+	 */
+	if (busnum == 1)
+		calgary_increase_split_completion_timeout(bbar, busnum);
+
 	init_timer(&tbl->watchdog_timer);
 	tbl->watchdog_timer.function = &calgary_watchdog;
 	tbl->watchdog_timer.data = (unsigned long)dev;
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 49f7fac..7451a4c 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -88,9 +88,8 @@
 
 static void __exit_idle(void)
 {
-	if (read_pda(isidle) == 0)
+	if (test_and_clear_bit_pda(0, isidle) == 0)
 		return;
-	write_pda(isidle, 0);
 	atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
 }
 
@@ -145,7 +144,7 @@
 void cpu_idle_wait(void)
 {
 	unsigned int cpu, this_cpu = get_cpu();
-	cpumask_t map;
+	cpumask_t map, tmp = current->cpus_allowed;
 
 	set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
 	put_cpu();
@@ -168,6 +167,8 @@
 		}
 		cpus_and(map, map, cpu_online_map);
 	} while (!cpus_empty(map));
+
+	set_cpus_allowed(current, tmp);
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index 4f67697..9f74c88 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -376,9 +376,8 @@
 	/* prevent preemption and reschedule on another processor */
 	int me = get_cpu();
 	if (cpu == me) {
-		WARN_ON(1);
 		put_cpu();
-		return -EBUSY;
+		return 0;
 	}
 	spin_lock_bh(&call_lock);
 	__smp_call_function_single(cpu, func, info, nonatomic, wait);
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 7b7a687..62c2e74 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -581,12 +581,16 @@
 	 * smp_call_function().
 	 */
 	lock_ipi_call_lock();
+	spin_lock(&vector_lock);
 
+	/* Setup the per cpu irq handling data structures */
+	__setup_vector_irq(smp_processor_id());
 	/*
 	 * Allow the master to continue.
 	 */
 	cpu_set(smp_processor_id(), cpu_online_map);
 	per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+	spin_unlock(&vector_lock);
 	unlock_ipi_call_lock();
 
 	cpu_idle();
@@ -799,7 +803,6 @@
 				cpu, node);
 	}
 
-
 	alternatives_smp_switch(1);
 
 	c_idle.idle = get_idle_for_cpu(cpu);
@@ -1246,8 +1249,10 @@
 	local_irq_disable();
 	remove_siblinginfo(cpu);
 
+	spin_lock(&vector_lock);
 	/* It's now safe to remove this processor from the online map */
 	cpu_clear(cpu, cpu_online_map);
+	spin_unlock(&vector_lock);
 	remove_cpu_from_maps();
 	fixup_irqs(cpu_online_map);
 	return 0;
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 1ba5a44..e3ef544 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -876,15 +876,6 @@
 	timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
 };
 
-static int __cpuinit
-time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu)
-{
-	unsigned cpu = (unsigned long) hcpu;
-	if (action == CPU_ONLINE)
-		vsyscall_set_cpu(cpu);
-	return NOTIFY_DONE;
-}
-
 void __init time_init(void)
 {
 	if (nohpet)
@@ -925,8 +916,6 @@
 	vxtime.last_tsc = get_cycles_sync();
 	set_cyc2ns_scale(cpu_khz);
 	setup_irq(0, &irq0);
-	hotcpu_notifier(time_cpu_notifier, 0);
-	time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id());
 
 #ifndef CONFIG_SMP
 	time_init_gtod();
@@ -948,7 +937,7 @@
  	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
 #ifdef CONFIG_ACPI
 		/* But TSC doesn't tick in C3 so don't use it there */
-		if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
+		if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000)
 			return 1;
 #endif
  		return 0;
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 7819022a..0d65b22 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -242,12 +242,19 @@
  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
  */
 
+static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
+{
+	void *t = (void *)tinfo;
+        return p > t && p < t + THREAD_SIZE - 3;
+}
+
 void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack,
 		struct stacktrace_ops *ops, void *data)
 {
 	const unsigned cpu = smp_processor_id();
 	unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
 	unsigned used = 0;
+	struct thread_info *tinfo;
 
 	if (!tsk)
 		tsk = current;
@@ -290,6 +297,12 @@
 		if (tsk && tsk != current)
 			stack = (unsigned long *)tsk->thread.rsp;
 	}
+	/*
+	 * Align the stack pointer on word boundary, later loops
+	 * rely on that (and corruption / debug info bugs can cause
+	 * unaligned values here):
+	 */
+	stack = (unsigned long *)((unsigned long)stack & ~(sizeof(long)-1));
 
 	/*
 	 * Print function call entries within a stack. 'cond' is the
@@ -364,7 +377,8 @@
 	/*
 	 * This handles the process stack:
 	 */
-	HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0);
+	tinfo = current_thread_info();
+	HANDLE_STACK (valid_stack_ptr(tinfo, stack));
 #undef HANDLE_STACK
 }
 EXPORT_SYMBOL(dump_trace);
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index b9df2ab..d9534e7 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -17,6 +17,7 @@
 	text PT_LOAD FLAGS(5);	/* R_E */
 	data PT_LOAD FLAGS(7);	/* RWE */
 	user PT_LOAD FLAGS(7);	/* RWE */
+	data.init PT_LOAD FLAGS(7);	/* RWE */
 	note PT_NOTE FLAGS(4);	/* R__ */
 }
 SECTIONS
@@ -59,6 +60,7 @@
   }
 #endif
 
+  . = ALIGN(PAGE_SIZE);        /* Align data segment to page size boundary */
 				/* Data */
   .data : AT(ADDR(.data) - LOAD_OFFSET) {
 	*(.data)
@@ -131,7 +133,7 @@
   . = ALIGN(8192);		/* init_task */
   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
 	*(.data.init_task)
-  } :data
+  }:data.init
 
   . = ALIGN(4096);
   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
@@ -174,13 +176,7 @@
   __setup_end = .;
   __initcall_start = .;
   .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
   __con_initcall_start = .;
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index a98b460..92546c1 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -27,6 +27,9 @@
 #include <linux/jiffies.h>
 #include <linux/sysctl.h>
 #include <linux/getcpu.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/notifier.h>
 
 #include <asm/vsyscall.h>
 #include <asm/pgtable.h>
@@ -243,32 +246,17 @@
 
 #endif
 
-static void __cpuinit write_rdtscp_cb(void *info)
-{
-	write_rdtscp_aux((unsigned long)info);
-}
-
-void __cpuinit vsyscall_set_cpu(int cpu)
+/* Assume __initcall executes before all user space. Hopefully kmod
+   doesn't violate that. We'll find out if it does. */
+static void __cpuinit vsyscall_set_cpu(int cpu)
 {
 	unsigned long *d;
 	unsigned long node = 0;
 #ifdef CONFIG_NUMA
 	node = cpu_to_node[cpu];
 #endif
-	if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) {
-		void *info = (void *)((node << 12) | cpu);
-		/* Can happen on preemptive kernel */
-		if (get_cpu() == cpu)
-			write_rdtscp_cb(info);
-#ifdef CONFIG_SMP
-		else {
-			/* the notifier is unfortunately not executed on the
-			   target CPU */
-			smp_call_function_single(cpu,write_rdtscp_cb,info,0,1);
-		}
-#endif
-		put_cpu();
-	}
+	if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP))
+		write_rdtscp_aux((node << 12) | cpu);
 
 	/* Store cpu number in limit so that it can be loaded quickly
 	   in user space in vgetcpu.
@@ -280,6 +268,23 @@
 	*d |= (node >> 4) << 48;
 }
 
+static void __cpuinit cpu_vsyscall_init(void *arg)
+{
+	/* preemption should be already off */
+	vsyscall_set_cpu(raw_smp_processor_id());
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int __cpuinit
+cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg)
+{
+	long cpu = (long)arg;
+	if (action == CPU_ONLINE)
+		smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1);
+	return NOTIFY_DONE;
+}
+#endif
+
 static void __init map_vsyscall(void)
 {
 	extern char __vsyscall_0;
@@ -299,6 +304,8 @@
 #ifdef CONFIG_SYSCTL
 	register_sysctl_table(kernel_root_table2, 0);
 #endif
+	on_each_cpu(cpu_vsyscall_init, NULL, 0, 1);
+	hotcpu_notifier(cpu_vsyscall_notifier, 0);
 	return 0;
 }
 
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 971dc11..4c0c00e 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -496,7 +496,7 @@
 }
 EXPORT_SYMBOL_GPL(remove_memory);
 
-#ifndef CONFIG_ACPI_NUMA
+#if !defined(CONFIG_ACPI_NUMA) && defined(CONFIG_NUMA)
 int memory_add_physaddr_to_nid(u64 start)
 {
 	return 0;
@@ -504,13 +504,6 @@
 EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 #endif
 
-#ifndef CONFIG_ACPI_NUMA
-int memory_add_physaddr_to_nid(u64 start)
-{
-	return 0;
-}
-#endif
-
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
 #ifdef CONFIG_MEMORY_HOTPLUG_RESERVE
@@ -655,9 +648,22 @@
 
 void __init reserve_bootmem_generic(unsigned long phys, unsigned len) 
 { 
-	/* Should check here against the e820 map to avoid double free */ 
 #ifdef CONFIG_NUMA
 	int nid = phys_to_nid(phys);
+#endif
+	unsigned long pfn = phys >> PAGE_SHIFT;
+	if (pfn >= end_pfn) {
+		/* This can happen with kdump kernels when accessing firmware
+		   tables. */
+		if (pfn < end_pfn_map)
+			return;
+		printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n",
+				phys, len);
+		return;
+	}
+
+	/* Should check here against the e820 map to avoid double free */
+#ifdef CONFIG_NUMA
   	reserve_bootmem_node(NODE_DATA(nid), phys, len);
 #else       		
 	reserve_bootmem(phys, len);    
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 3cc0544..1087e15 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -207,7 +207,7 @@
 	return hotadd_percent > 0;
 }
 #else
-int update_end_of_memory(unsigned long end) {return 0;}
+int update_end_of_memory(unsigned long end) {return -1;}
 static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
 #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
 static inline int save_add_info(void) {return 1;}
@@ -337,7 +337,7 @@
 	push_node_boundaries(node, nd->start >> PAGE_SHIFT,
 						nd->end >> PAGE_SHIFT);
 
- 	if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) {
+ 	if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) {
 		/* Ignore hotadd region. Undo damage */
 		printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
 		*nd = oldnode;
diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile
index 1eb18f4..149aba0 100644
--- a/arch/x86_64/pci/Makefile
+++ b/arch/x86_64/pci/Makefile
@@ -3,7 +3,7 @@
 #
 # Reuse the i386 PCI subsystem
 #
-CFLAGS += -Iarch/i386/pci
+EXTRA_CFLAGS += -Iarch/i386/pci
 
 obj-y		:= i386.o
 obj-$(CONFIG_PCI_DIRECT)+= direct.o
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index 7732f42..f8b6b28 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -163,37 +163,6 @@
 	}
 }
 
-static __init void pci_mmcfg_insert_resources(void)
-{
-#define PCI_MMCFG_RESOURCE_NAME_LEN 19
-	int i;
-	struct resource *res;
-	char *names;
-	unsigned num_buses;
-
-	res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
-			pci_mmcfg_config_num, GFP_KERNEL);
-
-	if (!res) {
-		printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
-		return;
-	}
-
-	names = (void *)&res[pci_mmcfg_config_num];
-	for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
-		num_buses = pci_mmcfg_config[i].end_bus_number -
-		    pci_mmcfg_config[i].start_bus_number + 1;
-		res->name = names;
-		snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
-			pci_mmcfg_config[i].pci_segment_group_number);
-		res->start = pci_mmcfg_config[i].base_address;
-		res->end = res->start + (num_buses << 20) - 1;
-		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-		insert_resource(&iomem_resource, res);
-		names += PCI_MMCFG_RESOURCE_NAME_LEN;
-	}
-}
-
 void __init pci_mmcfg_init(int type)
 {
 	int i;
@@ -220,7 +189,7 @@
 
 	pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
 	if (pci_mmcfg_virt == NULL) {
-		printk("PCI: Can not allocate memory for mmconfig structures\n");
+		printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
 		return;
 	}
 	for (i = 0; i < pci_mmcfg_config_num; ++i) {
@@ -228,7 +197,8 @@
 		pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address,
 							 MMCONFIG_APER_MAX);
 		if (!pci_mmcfg_virt[i].virt) {
-			printk("PCI: Cannot map mmconfig aperture for segment %d\n",
+			printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
+					"segment %d\n",
 			       pci_mmcfg_config[i].pci_segment_group_number);
 			return;
 		}
@@ -236,7 +206,6 @@
 	}
 
 	unreachable_devices();
-	pci_mmcfg_insert_resources();
 
 	raw_pci_ops = &pci_mmcfg;
 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index ab6cdbd..cfe75f5 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -184,13 +184,7 @@
 
   __initcall_start = .;
   .initcall.init : {
-  	*(.initcall1.init)
-  	*(.initcall2.init)
-  	*(.initcall3.init)
-  	*(.initcall4.init)
-  	*(.initcall5.init)
-  	*(.initcall6.init)
-  	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
 
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index d3d7613..1d9c3c7 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -456,6 +456,9 @@
 	 */
 	while ((__alias = elv_rb_add(&cfqq->sort_list, rq)) != NULL)
 		cfq_dispatch_insert(cfqd->queue, __alias);
+
+	if (!cfq_cfqq_on_rr(cfqq))
+		cfq_add_cfqq_rr(cfqd, cfqq);
 }
 
 static inline void
@@ -1215,11 +1218,12 @@
 {
 	struct cfq_data *cfqd = cic->key;
 	struct cfq_queue *cfqq;
+	unsigned long flags;
 
 	if (unlikely(!cfqd))
 		return;
 
-	spin_lock(cfqd->queue->queue_lock);
+	spin_lock_irqsave(cfqd->queue->queue_lock, flags);
 
 	cfqq = cic->cfqq[ASYNC];
 	if (cfqq) {
@@ -1236,7 +1240,7 @@
 	if (cfqq)
 		cfq_mark_cfqq_prio_changed(cfqq);
 
-	spin_unlock(cfqd->queue->queue_lock);
+	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
 }
 
 static void cfq_ioc_set_ioprio(struct io_context *ioc)
@@ -1362,6 +1366,7 @@
 	struct rb_node **p;
 	struct rb_node *parent;
 	struct cfq_io_context *__cic;
+	unsigned long flags;
 	void *k;
 
 	cic->ioc = ioc;
@@ -1391,9 +1396,9 @@
 	rb_link_node(&cic->rb_node, parent, p);
 	rb_insert_color(&cic->rb_node, &ioc->cic_root);
 
-	spin_lock_irq(cfqd->queue->queue_lock);
+	spin_lock_irqsave(cfqd->queue->queue_lock, flags);
 	list_add(&cic->queue_list, &cfqd->cic_list);
-	spin_unlock_irq(cfqd->queue->queue_lock);
+	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
 }
 
 /*
@@ -1650,9 +1655,6 @@
 
 	cfq_add_rq_rb(rq);
 
-	if (!cfq_cfqq_on_rr(cfqq))
-		cfq_add_cfqq_rr(cfqd, cfqq);
-
 	list_add_tail(&rq->queuelist, &cfqq->fifo);
 
 	cfq_rq_enqueued(cfqd, cfqq, rq);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 1360665..9eaee66 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -2999,6 +2999,7 @@
 {
 	request_queue_t *q;
 	sector_t maxsector;
+	sector_t old_sector;
 	int ret, nr_sectors = bio_sectors(bio);
 	dev_t old_dev;
 
@@ -3027,7 +3028,7 @@
 	 * NOTE: we don't repeat the blk_size check for each new device.
 	 * Stacking drivers are expected to know what they are doing.
 	 */
-	maxsector = -1;
+	old_sector = -1;
 	old_dev = 0;
 	do {
 		char b[BDEVNAME_SIZE];
@@ -3061,15 +3062,31 @@
 		 */
 		blk_partition_remap(bio);
 
-		if (maxsector != -1)
+		if (old_sector != -1)
 			blk_add_trace_remap(q, bio, old_dev, bio->bi_sector, 
-					    maxsector);
+					    old_sector);
 
 		blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
 
-		maxsector = bio->bi_sector;
+		old_sector = bio->bi_sector;
 		old_dev = bio->bi_bdev->bd_dev;
 
+		maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
+		if (maxsector) {
+			sector_t sector = bio->bi_sector;
+
+			if (maxsector < nr_sectors ||
+					maxsector - nr_sectors < sector) {
+				/*
+				 * This may well happen - partitions are not
+				 * checked to make sure they are within the size
+				 * of the whole device.
+				 */
+				handle_bad_sector(bio);
+				goto end_io;
+			}
+		}
+
 		ret = q->make_request_fn(q, bio);
 	} while (ret);
 }
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 2dc3264..e55a756 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -246,10 +246,10 @@
 		switch (hdr->dxfer_direction) {
 		default:
 			return -EINVAL;
-		case SG_DXFER_TO_FROM_DEV:
 		case SG_DXFER_TO_DEV:
 			writing = 1;
 			break;
+		case SG_DXFER_TO_FROM_DEV:
 		case SG_DXFER_FROM_DEV:
 			break;
 		}
@@ -286,9 +286,8 @@
 	 * fill in request structure
 	 */
 	rq->cmd_len = hdr->cmd_len;
+	memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
 	memcpy(rq->cmd, cmd, hdr->cmd_len);
-	if (sizeof(rq->cmd) != hdr->cmd_len)
-		memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len);
 
 	memset(sense, 0, sizeof(sense));
 	rq->sense = sense;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index c84286c..068fe4f 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -73,7 +73,6 @@
 static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
 static struct workqueue_struct *kacpid_wq;
-static struct workqueue_struct *kacpi_notify_wq;
 
 acpi_status acpi_os_initialize(void)
 {
@@ -92,9 +91,8 @@
 		return AE_NULL_ENTRY;
 	}
 	kacpid_wq = create_singlethread_workqueue("kacpid");
-	kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
 	BUG_ON(!kacpid_wq);
-	BUG_ON(!kacpi_notify_wq);
+
 	return AE_OK;
 }
 
@@ -106,7 +104,6 @@
 	}
 
 	destroy_workqueue(kacpid_wq);
-	destroy_workqueue(kacpi_notify_wq);
 
 	return AE_OK;
 }
@@ -569,7 +566,10 @@
 
 static void acpi_os_execute_deferred(void *context)
 {
-	struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context;
+	struct acpi_os_dpc *dpc = NULL;
+
+
+	dpc = (struct acpi_os_dpc *)context;
 	if (!dpc) {
 		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
 		return;
@@ -604,12 +604,14 @@
 	struct acpi_os_dpc *dpc;
 	struct work_struct *task;
 
+	ACPI_FUNCTION_TRACE("os_queue_for_execution");
+
 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 			  "Scheduling function [%p(%p)] for deferred execution.\n",
 			  function, context));
 
 	if (!function)
-		return AE_BAD_PARAMETER;
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
 
 	/*
 	 * Allocate/initialize DPC structure.  Note that this memory will be
@@ -622,20 +624,26 @@
 	 * from the same memory.
 	 */
 
-	dpc = kmalloc(sizeof(struct acpi_os_dpc) +
-			sizeof(struct work_struct), GFP_ATOMIC);
+	dpc =
+	    kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct),
+		    GFP_ATOMIC);
 	if (!dpc)
-		return AE_NO_MEMORY;
+		return_ACPI_STATUS(AE_NO_MEMORY);
+
 	dpc->function = function;
 	dpc->context = context;
+
 	task = (void *)(dpc + 1);
 	INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc);
-	if (!queue_work((type == OSL_NOTIFY_HANDLER)?
-			kacpi_notify_wq : kacpid_wq, task)) {
-		status = AE_ERROR;
+
+	if (!queue_work(kacpid_wq, task)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Call to queue_work() failed.\n"));
 		kfree(dpc);
+		status = AE_ERROR;
 	}
-	return status;
+
+	return_ACPI_STATUS(status);
 }
 
 EXPORT_SYMBOL(acpi_os_execute);
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 7ba5e49..6fd174a 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -83,10 +83,8 @@
 		goto out;
 
 	ppc = (unsigned int)pr->performance_platform_limit;
-	if (!ppc)
-		goto out;
 
-	if (ppc > pr->performance->state_count)
+	if (ppc >= pr->performance->state_count)
 		goto out;
 
 	cpufreq_verify_within_limits(policy, 0,
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 3f4aa0c..03f6338 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -6,6 +6,7 @@
 
 config ATA
 	tristate "ATA device support"
+	depends on BLOCK
 	depends on !(M32R || M68K) || BROKEN
 	depends on !SUN4 || BROKEN
 	select SCSI
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 2592912..f510e11 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -314,6 +314,17 @@
 	{ PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
 	{ PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
 	{ PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
+	{ PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */
+	{ PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */
+	{ PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
+	{ PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
+	{ PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
+	{ PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
+	{ PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
+	{ PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
 
 	/* JMicron */
 	{ PCI_VDEVICE(JMICRON, 0x2360), board_ahci }, /* JMicron JMB360 */
@@ -334,6 +345,14 @@
 	{ PCI_VDEVICE(NVIDIA, 0x044d), board_ahci },		/* MCP65 */
 	{ PCI_VDEVICE(NVIDIA, 0x044e), board_ahci },		/* MCP65 */
 	{ PCI_VDEVICE(NVIDIA, 0x044f), board_ahci },		/* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0557), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0558), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci },		/* MCP67 */
 
 	/* SiS */
 	{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
@@ -736,8 +755,7 @@
 	}
 
 	/* check BUSY/DRQ, perform Command List Override if necessary */
-	ahci_tf_read(ap, &tf);
-	if (tf.command & (ATA_BUSY | ATA_DRQ)) {
+	if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) {
 		rc = ahci_clo(ap);
 
 		if (rc == -EOPNOTSUPP) {
@@ -1041,7 +1059,7 @@
 	/* hmmm... a spurious interupt */
 
 	/* some devices send D2H reg with I bit set during NCQ command phase */
-	if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS)
+	if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS))
 		return;
 
 	/* ignore interim PIO setup fis interrupts */
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 5719704..720174d 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -126,8 +126,7 @@
 	ich6_sata		= 7,
 	ich6_sata_ahci		= 8,
 	ich6m_sata_ahci		= 9,
-	ich7m_sata_ahci		= 10,
-	ich8_sata_ahci		= 11,
+	ich8_sata_ahci		= 10,
 
 	/* constants for mapping table */
 	P0			= 0,  /* port 0 */
@@ -227,7 +226,7 @@
 	/* 82801GB/GR/GH (ICH7, identical to ICH6) */
 	{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
 	/* 2801GBM/GHM (ICH7M, identical to ICH6M) */
-	{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7m_sata_ahci },
+	{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
 	/* Enterprise Southbridge 2 (where's the datasheet?) */
 	{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
 	/* SATA Controller 1 IDE (ICH8, no datasheet yet) */
@@ -399,23 +398,10 @@
 	.mask = 0x3,
 	.port_enable = 0x5,
 	.present_shift = 4,
-	.map = {
-		/* PM   PS   SM   SS       MAP */
-		{  P0,  P2,  RV,  RV }, /* 00b */
-		{  RV,  RV,  RV,  RV },
-		{  P0,  P2, IDE, IDE }, /* 10b */
-		{  RV,  RV,  RV,  RV },
-	},
-};
-
-static const struct piix_map_db ich7m_map_db = {
-	.mask = 0x3,
-	.port_enable = 0x5,
-	.present_shift = 4,
 
 	/* Map 01b isn't specified in the doc but some notebooks use
-	 * it anyway.  ATM, the only case spotted carries subsystem ID
-	 * 1025:0107.  This is the only difference from ich6m.
+	 * it anyway.  MAP 01b have been spotted on both ICH6M and
+	 * ICH7M.
 	 */
 	.map = {
 		/* PM   PS   SM   SS       MAP */
@@ -432,9 +418,9 @@
 	.present_shift = 8,
 	.map = {
 		/* PM   PS   SM   SS       MAP */
-		{  P0,  NA,  P1,  NA }, /* 00b (hardwired) */
+		{  P0,  P2,  P1,  P3 }, /* 00b (hardwired when in AHCI) */
 		{  RV,  RV,  RV,  RV },
-		{  RV,  RV,  RV,  RV }, /* 10b (never) */
+		{  IDE,  IDE,  NA,  NA }, /* 10b (IDE mode) */
 		{  RV,  RV,  RV,  RV },
 	},
 };
@@ -445,7 +431,6 @@
 	[ich6_sata]		= &ich6_map_db,
 	[ich6_sata_ahci]	= &ich6_map_db,
 	[ich6m_sata_ahci]	= &ich6m_map_db,
-	[ich7m_sata_ahci]	= &ich7m_map_db,
 	[ich8_sata_ahci]	= &ich8_map_db,
 };
 
@@ -556,19 +541,7 @@
 		.port_ops	= &piix_sata_ops,
 	},
 
-	/* ich7m_sata_ahci: 10 */
-	{
-		.sht		= &piix_sht,
-		.flags		= ATA_FLAG_SATA |
-				  PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
-				  PIIX_FLAG_AHCI,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
-		.udma_mask	= 0x7f,	/* udma0-6 */
-		.port_ops	= &piix_sata_ops,
-	},
-
-	/* ich8_sata_ahci: 11 */
+	/* ich8_sata_ahci: 10 */
 	{
 		.sht		= &piix_sht,
 		.flags		= ATA_FLAG_SATA |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 83728a9..915a55a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5957,7 +5957,7 @@
 	destroy_workqueue(ata_aux_wq);
 }
 
-module_init(ata_init);
+subsys_initcall(ata_init);
 module_exit(ata_exit);
 
 static unsigned long ratelimit_time;
@@ -6122,7 +6122,6 @@
 EXPORT_SYMBOL_GPL(ata_std_softreset);
 EXPORT_SYMBOL_GPL(sata_std_hardreset);
 EXPORT_SYMBOL_GPL(ata_std_postreset);
-EXPORT_SYMBOL_GPL(ata_dev_revalidate);
 EXPORT_SYMBOL_GPL(ata_dev_classify);
 EXPORT_SYMBOL_GPL(ata_dev_pair);
 EXPORT_SYMBOL_GPL(ata_port_disable);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 7af2a4b..47ea111 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1451,6 +1451,7 @@
 
 static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 {
+	struct ata_port *ap = qc->ap;
 	struct scsi_cmnd *cmd = qc->scsicmd;
 	u8 *cdb = cmd->cmnd;
  	int need_sense = (qc->err_mask != 0);
@@ -1459,11 +1460,12 @@
 	 * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
 	 * cache
 	 */
-	if (!need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) &&
+	if (ap->ops->error_handler &&
+	    !need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) &&
 	    ((qc->tf.feature == SETFEATURES_WC_ON) ||
 	     (qc->tf.feature == SETFEATURES_WC_OFF))) {
-		qc->ap->eh_info.action |= ATA_EH_REVALIDATE;
-		ata_port_schedule_eh(qc->ap);
+		ap->eh_info.action |= ATA_EH_REVALIDATE;
+		ata_port_schedule_eh(ap);
 	}
 
 	/* For ATA pass thru (SAT) commands, generate a sense block if
@@ -1490,8 +1492,8 @@
 		}
 	}
 
-	if (need_sense && !qc->ap->ops->error_handler)
-		ata_dump_status(qc->ap->id, &qc->result_tf);
+	if (need_sense && !ap->ops->error_handler)
+		ata_dump_status(ap->id, &qc->result_tf);
 
 	qc->scsidone(cmd);
 
@@ -1612,9 +1614,9 @@
 
 err_did:
 	ata_qc_free(qc);
-err_mem:
 	cmd->result = (DID_ERROR << 16);
 	done(cmd);
+err_mem:
 	DPRINTK("EXIT - internal\n");
 	return 0;
 
@@ -3345,20 +3347,23 @@
  *	@ap:	ATA port to which the command is being sent
  *
  *	RETURNS:
- *	Zero.
+ *	Return value from __ata_scsi_queuecmd() if @cmd can be queued,
+ *	0 otherwise.
  */
 
 int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
 		     struct ata_port *ap)
 {
+	int rc = 0;
+
 	ata_scsi_dump_cdb(ap, cmd);
 
 	if (likely(ata_scsi_dev_enabled(ap->device)))
-		__ata_scsi_queuecmd(cmd, done, ap->device);
+		rc = __ata_scsi_queuecmd(cmd, done, ap->device);
 	else {
 		cmd->result = (DID_BAD_TARGET << 16);
 		done(cmd);
 	}
-	return 0;
+	return rc;
 }
 EXPORT_SYMBOL_GPL(ata_sas_queuecmd);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 06daaa3..7645f2b 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -981,6 +981,15 @@
 		mask = (1 << 2) | (1 << 0);
 		if ((tmp8 & mask) != mask)
 			legacy_mode = (1 << 3);
+#if defined(CONFIG_NO_ATA_LEGACY)
+		/* Some platforms with PCI limits cannot address compat
+		   port space. In that case we punt if their firmware has
+		   left a device in compatibility mode */
+		if (legacy_mode) {
+			printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n");
+			return -EOPNOTSUPP;
+		}
+#endif
 	}
 
 	rc = pci_request_regions(pdev, DRV_NAME);
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index a5ecb71..0ed263b 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -53,6 +53,7 @@
 extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
 extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
 			   int post_reset, u16 *id);
+extern int ata_dev_revalidate(struct ata_device *dev, int post_reset);
 extern int ata_dev_configure(struct ata_device *dev, int print_info);
 extern int sata_down_spd_limit(struct ata_port *ap);
 extern int sata_set_spd_needed(struct ata_port *ap);
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 29234c8..5c47a9e 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -677,6 +677,8 @@
 	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE),	8 },
 	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE),	8 },
 	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE),	8 },
+	{ PCI_VDEVICE(NVIDIA,	PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE),	8 },
 	{ PCI_VDEVICE(AMD,	PCI_DEVICE_ID_AMD_CS5536_IDE),		9 },
 
 	{ },
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 690828e..96a0980 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -92,7 +92,7 @@
 		return -ENOENT;
 
 	pci_read_config_byte(pdev, 0x49, &tmp);
-	if (tmp & (1 >> ap->port_no))
+	if (tmp & (1 << ap->port_no))
 		ap->cbl = ATA_CBL_PATA40;
 	else
 		ap->cbl = ATA_CBL_PATA80;
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 7350443..fce3fcd 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -25,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt37x"
-#define DRV_VERSION	"0.5"
+#define DRV_VERSION	"0.5.1"
 
 struct hpt_clock {
 	u8	xfer_speed;
@@ -453,7 +453,13 @@
 {
 	u8 scr2, ata66;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
+	static const struct pci_bits hpt37x_enable_bits[] = {
+		{ 0x50, 1, 0x04, 0x04 },
+		{ 0x54, 1, 0x04, 0x04 }
+	};
+	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
+		return -ENOENT;
+		
 	pci_read_config_byte(pdev, 0x5B, &scr2);
 	pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
 	/* Cable register now active */
@@ -488,10 +494,17 @@
 
 static int hpt374_pre_reset(struct ata_port *ap)
 {
+	static const struct pci_bits hpt37x_enable_bits[] = {
+		{ 0x50, 1, 0x04, 0x04 },
+		{ 0x54, 1, 0x04, 0x04 }
+	};
 	u16 mcr3, mcr6;
 	u8 ata66;
-
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
+	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
+		return -ENOENT;
+		
 	/* Do the extra channel work */
 	pci_read_config_word(pdev, 0x52, &mcr3);
 	pci_read_config_word(pdev, 0x56, &mcr6);
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 323b607..d65ebfd 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -117,10 +117,14 @@
 	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
 	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
 	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
-	{ PCI_VDEVICE(NVIDIA, 0x045c), GENERIC },
-	{ PCI_VDEVICE(NVIDIA, 0x045d), GENERIC },
-	{ PCI_VDEVICE(NVIDIA, 0x045e), GENERIC },
-	{ PCI_VDEVICE(NVIDIA, 0x045f), GENERIC },
+	{ PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */
+	{ PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */
 	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
 		PCI_ANY_ID, PCI_ANY_ID,
 		PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 0738f52..9d1235b 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -240,7 +240,7 @@
 	struct ata_probe_ent *probe_ent = NULL;
 	int rc;
 	u32 genctl;
-	struct ata_port_info *ppi[2];
+	struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
 	int pci_dev_busy = 0;
 	u8 pmr;
 	u8 port2_start;
@@ -265,27 +265,20 @@
 	if (rc)
 		goto err_out_regions;
 
-	ppi[0] = ppi[1] = &sis_port_info;
-	probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
-	if (!probe_ent) {
-		rc = -ENOMEM;
-		goto err_out_regions;
-	}
-
 	/* check and see if the SCRs are in IO space or PCI cfg space */
 	pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
 	if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
-		probe_ent->port_flags |= SIS_FLAG_CFGSCR;
+		pi.flags |= SIS_FLAG_CFGSCR;
 
 	/* if hardware thinks SCRs are in IO space, but there are
 	 * no IO resources assigned, change to PCI cfg space.
 	 */
-	if ((!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) &&
+	if ((!(pi.flags & SIS_FLAG_CFGSCR)) &&
 	    ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) ||
 	     (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) {
 		genctl &= ~GENCTL_IOMAPPED_SCR;
 		pci_write_config_dword(pdev, SIS_GENCTL, genctl);
-		probe_ent->port_flags |= SIS_FLAG_CFGSCR;
+		pi.flags |= SIS_FLAG_CFGSCR;
 	}
 
 	pci_read_config_byte(pdev, SIS_PMR, &pmr);
@@ -306,6 +299,12 @@
 		port2_start = 0x20;
 	}
 
+	probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
+	if (!probe_ent) {
+		rc = -ENOMEM;
+		goto err_out_regions;
+	}
+
 	if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
 		probe_ent->port[0].scr_addr =
 			pci_resource_start(pdev, SIS_SCR_PCI_BAR);
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index f4455a1..1c7f19a 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -230,7 +230,7 @@
 	int online;
 
 	/* don't do any SCR stuff if we're not loading */
-	if (!ATA_PFLAG_LOADING)
+	if (!(ap->pflags & ATA_PFLAG_LOADING))
 		goto skip_scr;
 
 	/* Resume phy.  This is the old resume sequence from
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 323592d..9fffa7af 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -2452,8 +2452,8 @@
 static void __exit amb_module_exit (void)
 {
   PRINTD (DBG_FLOW|DBG_INIT, "cleanup_module");
-  
-  return pci_unregister_driver(&amb_driver);
+
+  pci_unregister_driver(&amb_driver);
 }
 
 module_init(amb_module_init);
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 40ab9b6..697ad82 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1002,6 +1002,10 @@
 					r = ROUND_UP;
 				}
 				error = make_rate (pcr, r, &tmc0, NULL);
+				if (error) {
+					kfree(tc);
+					return error;
+				}
 			}
 			fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr);
 		}
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index f593492..4dc1010 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -1789,7 +1789,7 @@
 	WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK);
 }
 
-static u16 __init read_bia (const hrz_dev * dev, u16 addr)
+static u16 __devinit read_bia (const hrz_dev * dev, u16 addr)
 {
   u32 ctrl = rd_regl (dev, CONTROL_0_REG);
   
@@ -2932,8 +2932,8 @@
 
 static void __exit hrz_module_exit (void) {
   PRINTD (DBG_FLOW, "cleanup_module");
-  
-  return pci_unregister_driver(&hrz_driver);
+
+  pci_unregister_driver(&hrz_driver);
 }
 
 module_init(hrz_module_init);
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 632ede5..bd09045 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -2759,7 +2759,7 @@
 {
    ns_dev *card;
    pool_levels pl;
-   int btype;
+   long btype;
    unsigned long flags;
 
    card = dev->dev_data;
@@ -2859,7 +2859,7 @@
       case NS_ADJBUFLEV:
          if (!capable(CAP_NET_ADMIN))
 	    return -EPERM;
-         btype = (int) arg;	/* an int is the same size as a pointer */
+         btype = (long) arg;	/* a long is the same size as a pointer or bigger */
          switch (btype)
 	 {
 	    case NS_BUFTYPE_SMALL:
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 0b4e224..1429f3a2 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -37,8 +37,8 @@
 
 	  If you are unsure about this, say N here.
 
-endmenu
-
 config SYS_HYPERVISOR
 	bool
 	default n
+
+endmenu
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 68ad11a..002fde4 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -591,8 +591,10 @@
 
 	if (parent)
 		klist_del(&dev->knode_parent);
-	if (dev->devt_attr)
+	if (dev->devt_attr) {
 		device_remove_file(dev, dev->devt_attr);
+		kfree(dev->devt_attr);
+	}
 	if (dev->class) {
 		sysfs_remove_link(&dev->kobj, "subsystem");
 		sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index db01b95..c5d6bb4 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -18,6 +18,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/kthread.h>
+#include <linux/wait.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -70,6 +71,8 @@
 };
 
 static atomic_t probe_count = ATOMIC_INIT(0);
+static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue);
+
 static int really_probe(void *void_data)
 {
 	struct stupid_thread_structure *data = void_data;
@@ -121,6 +124,7 @@
 done:
 	kfree(data);
 	atomic_dec(&probe_count);
+	wake_up(&probe_waitqueue);
 	return ret;
 }
 
@@ -337,6 +341,32 @@
 	}
 }
 
+#ifdef CONFIG_PCI_MULTITHREAD_PROBE
+static int __init wait_for_probes(void)
+{
+	DEFINE_WAIT(wait);
+
+	printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__,
+			atomic_read(&probe_count));
+	if (!atomic_read(&probe_count))
+		return 0;
+	while (atomic_read(&probe_count)) {
+		prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE);
+		if (atomic_read(&probe_count))
+			schedule();
+	}
+	finish_wait(&probe_waitqueue, &wait);
+	return 0;
+}
+
+core_initcall_sync(wait_for_probes);
+postcore_initcall_sync(wait_for_probes);
+arch_initcall_sync(wait_for_probes);
+subsys_initcall_sync(wait_for_probes);
+fs_initcall_sync(wait_for_probes);
+device_initcall_sync(wait_for_probes);
+late_initcall_sync(wait_for_probes);
+#endif
 
 EXPORT_SYMBOL_GPL(device_bind_driver);
 EXPORT_SYMBOL_GPL(device_release_driver);
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index d433f27..aa25f8b 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -68,6 +68,7 @@
 	&disk_attr_mac.attr,
 	&disk_attr_netif.attr,
 	&disk_attr_fwver.attr,
+	NULL
 };
 
 static const struct attribute_group attr_group = {
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index dcccaf2..4105c3b 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1300,6 +1300,12 @@
 
 	complete_buffers(rq->bio, rq->errors);
 
+	if (blk_fs_request(rq)) {
+		const int rw = rq_data_dir(rq);
+
+		disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
+	}
+
 #ifdef CCISS_DEBUG
 	printk("Done with %p\n", rq);
 #endif				/* CCISS_DEBUG */
@@ -1923,7 +1929,6 @@
 {
 	int return_code;
 	unsigned long t;
-	unsigned long rem;
 
 	memset(inq_buff, 0, sizeof(InquiryData_struct));
 	if (withirq)
@@ -1939,26 +1944,23 @@
 			printk(KERN_WARNING
 			       "cciss: reading geometry failed, volume "
 			       "does not support reading geometry\n");
-			drv->block_size = block_size;
-			drv->nr_blocks = total_size;
 			drv->heads = 255;
 			drv->sectors = 32;	// Sectors per track
-			t = drv->heads * drv->sectors;
-			drv->cylinders = total_size;
-			rem = do_div(drv->cylinders, t);
 		} else {
-			drv->block_size = block_size;
-			drv->nr_blocks = total_size;
 			drv->heads = inq_buff->data_byte[6];
 			drv->sectors = inq_buff->data_byte[7];
 			drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8;
 			drv->cylinders += inq_buff->data_byte[5];
 			drv->raid_level = inq_buff->data_byte[8];
-			t = drv->heads * drv->sectors;
-			if (t > 1) {
-				drv->cylinders = total_size;
-				rem = do_div(drv->cylinders, t);
-			}
+		}
+		drv->block_size = block_size;
+		drv->nr_blocks = total_size;
+		t = drv->heads * drv->sectors;
+		if (t > 1) {
+			unsigned rem = sector_div(total_size, t);
+			if (rem)
+				total_size++;
+			drv->cylinders = total_size;
 		}
 	} else {		/* Get geometry failed */
 		printk(KERN_WARNING "cciss: reading geometry failed\n");
@@ -1996,8 +1998,8 @@
 		*block_size = BLOCK_SIZE;
 	}
 	if (*total_size != (__u32) 0)
-		printk(KERN_INFO "      blocks= %lld block_size= %d\n",
-		*total_size, *block_size);
+		printk(KERN_INFO "      blocks= %llu block_size= %d\n",
+		(unsigned long long)*total_size, *block_size);
 	kfree(buf);
 	return;
 }
@@ -2031,8 +2033,8 @@
 		*total_size = 0;
 		*block_size = BLOCK_SIZE;
 	}
-	printk(KERN_INFO "      blocks= %lld block_size= %d\n",
-	       *total_size, *block_size);
+	printk(KERN_INFO "      blocks= %llu block_size= %d\n",
+	       (unsigned long long)*total_size, *block_size);
 	kfree(buf);
 	return;
 }
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 570d2f0..d5f519e 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -998,6 +998,7 @@
  */
 static inline void complete_command(cmdlist_t *cmd, int timeout)
 {
+	struct request *rq = cmd->rq;
 	int ok=1;
 	int i, ddir;
 
@@ -1029,12 +1030,18 @@
                 pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
 				cmd->req.sg[i].size, ddir);
 
-	complete_buffers(cmd->rq->bio, ok);
+	complete_buffers(rq->bio, ok);
 
-	add_disk_randomness(cmd->rq->rq_disk);
+	if (blk_fs_request(rq)) {
+		const int rw = rq_data_dir(rq);
 
-        DBGPX(printk("Done with %p\n", cmd->rq););
-	end_that_request_last(cmd->rq, ok ? 1 : -EIO);
+		disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
+	}
+
+	add_disk_randomness(rq->rq_disk);
+
+	DBGPX(printk("Done with %p\n", rq););
+	end_that_request_last(rq, ok ? 1 : -EIO);
 }
 
 /*
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 845b868..cbc0725 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -282,7 +282,7 @@
 		clear_bit(ready_bit, &(info->tx_state));
 
 		if (bt_cb(skb)->pkt_type & 0x80) {
-			DECLARE_WAIT_QUEUE_HEAD(wq);
+			DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
 			DEFINE_WAIT(wait);
 
 			unsigned char baud_reg;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 39a9f8c..2af12fc 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -409,14 +409,6 @@
          If you have an SGI Altix with an attached SABrick
          say Y or M here, otherwise say N.
 
-config MSPEC
-	tristate "Memory special operations driver"
-	depends on IA64
-	help
-	  If you have an ia64 and you want to enable memory special
-	  operations support (formerly known as fetchop), say Y here,
-	  otherwise say N.
-
 source "drivers/serial/Kconfig"
 
 config UNIX98_PTYS
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index c392001..5ff457b 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -1054,7 +1054,7 @@
 {
 	struct page * page;
 
-	page = alloc_page(GFP_KERNEL);
+	page = alloc_page(GFP_KERNEL | GFP_DMA32);
 	if (page == NULL)
 		return NULL;
 
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index d1ede7d..555b3a8 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -169,7 +169,7 @@
 {
 	struct page * page;
 
-	page = alloc_pages(GFP_KERNEL, 2);
+	page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2);
 	if (page == NULL)
 		return NULL;
 
@@ -387,11 +387,7 @@
 	/* We obtain the size of the GTT, which is also stored (for some
 	 * reason) at the top of stolen memory. Then we add 4KB to that
 	 * for the video BIOS popup, which is also stored in there. */
-
-	if (IS_I965)
-		size = 512 + 4;
-	else
-		size = agp_bridge->driver->fetch_size() + 4;
+	size = agp_bridge->driver->fetch_size() + 4;
 
 	if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
 	    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
@@ -805,6 +801,26 @@
 
 	return 0;
 }
+
+/*
+ * The i965 supports 36-bit physical addresses, but to keep
+ * the format of the GTT the same, the bits that don't fit
+ * in a 32-bit word are shifted down to bits 4..7.
+ *
+ * Gcc is smart enough to notice that "(addr >> 28) & 0xf0"
+ * is always zero on 32-bit architectures, so no need to make
+ * this conditional.
+ */
+static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
+	unsigned long addr, int type)
+{
+	/* Shift high bits down */
+	addr |= (addr >> 28) & 0xf0;
+
+	/* Type checking must be done elsewhere */
+	return addr | bridge->driver->masks[type].mask;
+}
+
 static int intel_i965_fetch_size(void)
 {
        struct aper_size_info_fixed *values;
@@ -832,7 +848,8 @@
 
        agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
 
-       return values[offset].size;
+	/* The i965 GTT is always sized as if it had a 512kB aperture size */
+	return 512;
 }
 
 /* The intel i965 automatically initializes the agp aperture during POST.
@@ -1584,7 +1601,7 @@
        .fetch_size             = intel_i965_fetch_size,
        .cleanup                = intel_i915_cleanup,
        .tlb_flush              = intel_i810_tlbflush,
-       .mask_memory            = intel_i810_mask_memory,
+       .mask_memory            = intel_i965_mask_memory,
        .masks                  = intel_i810_masks,
        .agp_enable             = intel_i810_agp_enable,
        .cache_flush            = global_cache_flush,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 91b71e7..dffc193 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -27,32 +27,42 @@
 static int uninorth_rev;
 static int is_u3;
 
+static char __devinitdata *aperture = NULL;
 
 static int uninorth_fetch_size(void)
 {
-	int i;
-	u32 temp;
-	struct aper_size_info_32 *values;
+	int i, size = 0;
+	struct aper_size_info_32 *values =
+	    A_SIZE_32(agp_bridge->driver->aperture_sizes);
 
-	pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
-	temp &= ~(0xfffff000);
-	values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
+	if (aperture) {
+		char *save = aperture;
 
-	for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
-		if (temp == values[i].size_value) {
-			agp_bridge->previous_size =
-			    agp_bridge->current_size = (void *) (values + i);
-			agp_bridge->aperture_size_idx = i;
-			return values[i].size;
+		size = memparse(aperture, &aperture) >> 20;
+		aperture = save;
+
+		for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+			if (size == values[i].size)
+				break;
+
+		if (i == agp_bridge->driver->num_aperture_sizes) {
+			printk(KERN_ERR PFX "Invalid aperture size, using"
+			       " default\n");
+			size = 0;
+			aperture = NULL;
 		}
 	}
 
-	agp_bridge->previous_size =
-	    agp_bridge->current_size = (void *) (values + 1);
-	agp_bridge->aperture_size_idx = 1;
-	return values[1].size;
+	if (!size) {
+		for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+			if (values[i].size == 32)
+				break;
+	}
 
-	return 0;
+	agp_bridge->previous_size =
+	    agp_bridge->current_size = (void *)(values + i);
+	agp_bridge->aperture_size_idx = i;
+	return values[i].size;
 }
 
 static void uninorth_tlbflush(struct agp_memory *mem)
@@ -683,5 +693,11 @@
 module_init(agp_uninorth_init);
 module_exit(agp_uninorth_cleanup);
 
+module_param(aperture, charp, 0);
+MODULE_PARM_DESC(aperture,
+		 "Aperture size, must be power of two between 4MB and an\n"
+		 "\t\tupper limit specific to the UniNorth revision.\n"
+		 "\t\tDefault: 32M");
+
 MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
 MODULE_LICENSE("GPL");
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 029baea..6eafff1 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -237,6 +237,8 @@
 
 	list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
 	if (!list) {
+		if (map->type == _DRM_REGISTERS)
+			drm_ioremapfree(map->handle, map->size, dev);
 		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
 		return -EINVAL;
 	}
@@ -252,6 +254,8 @@
 		map->offset;
 	ret = drm_map_handle(dev, &list->hash, user_token, 0);
 	if (ret) {
+		if (map->type == _DRM_REGISTERS)
+			drm_ioremapfree(map->handle, map->size, dev);
 		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
 		drm_free(list, sizeof(*list), DRM_MEM_MAPS);
 		mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index 51ad98c..ba4b8de 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -42,13 +42,24 @@
 struct class *drm_sysfs_create(struct module *owner, char *name)
 {
 	struct class *class;
+	int err;
 
 	class = class_create(owner, name);
-	if (!class)
-		return class;
+	if (!class) {
+		err = -ENOMEM;
+		goto err_out;
+	}
 
-	class_create_file(class, &class_attr_version);
+	err = class_create_file(class, &class_attr_version);
+	if (err)
+		goto err_out_class;
+
 	return class;
+
+err_out_class:
+	class_destroy(class);
+err_out:
+	return ERR_PTR(err);
 }
 
 /**
@@ -96,20 +107,36 @@
 struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head)
 {
 	struct class_device *class_dev;
-	int i;
+	int i, j, err;
 
 	class_dev = class_device_create(cs, NULL,
 					MKDEV(DRM_MAJOR, head->minor),
 					&(head->dev->pdev)->dev,
 					"card%d", head->minor);
-	if (!class_dev)
-		return NULL;
+	if (!class_dev) {
+		err = -ENOMEM;
+		goto err_out;
+	}
 
 	class_set_devdata(class_dev, head);
 
-	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-		class_device_create_file(class_dev, &class_device_attrs[i]);
+	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+		err = class_device_create_file(class_dev,
+					       &class_device_attrs[i]);
+		if (err)
+			goto err_out_files;
+	}
+
 	return class_dev;
+
+err_out_files:
+	if (i > 0)
+		for (j = 0; j < i; j++)
+			class_device_remove_file(class_dev,
+						 &class_device_attrs[i]);
+	class_device_unregister(class_dev);
+err_out:
+	return ERR_PTR(err);
 }
 
 /**
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index e30f556..be49dbb 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -47,6 +47,7 @@
 	    DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
 	    DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
 	    DRIVER_IRQ_VBL,
+	.dev_priv_size = sizeof(drm_mga_buf_priv_t),
 	.load = mga_driver_load,
 	.unload = mga_driver_unload,
 	.lastclose = mga_driver_lastclose,
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index 26bdf2c..d14477b 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -538,6 +538,36 @@
 	return 0;
 }
 
+static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
+					     drm_radeon_kcmd_buffer_t *cmdbuf)
+{
+	u32 *cmd = (u32 *) cmdbuf->buf;
+	int count, ret;
+	RING_LOCALS;
+
+	count=(cmd[0]>>16) & 0x3fff;
+
+	if ((cmd[1] & 0x8000ffff) != 0x80000810) {
+		DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
+		return DRM_ERR(EINVAL);
+	}
+	ret = r300_check_offset(dev_priv, cmd[2]);
+	if (ret) {
+		DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+		return DRM_ERR(EINVAL);
+	}
+
+	BEGIN_RING(count+2);
+	OUT_RING(cmd[0]);
+	OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
+	ADVANCE_RING();
+
+	cmdbuf->buf += (count+2)*4;
+	cmdbuf->bufsz -= (count+2)*4;
+
+	return 0;
+}
+
 static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
 					    drm_radeon_kcmd_buffer_t *cmdbuf)
 {
@@ -578,10 +608,11 @@
 	case RADEON_CNTL_BITBLT_MULTI:
 		return r300_emit_bitblt_multi(dev_priv, cmdbuf);
 
+	case RADEON_CP_INDX_BUFFER:	/* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
+		return r300_emit_indx_buffer(dev_priv, cmdbuf);
 	case RADEON_CP_3D_DRAW_IMMD_2:	/* triggers drawing using in-packet vertex data */
 	case RADEON_CP_3D_DRAW_VBUF_2:	/* triggers drawing of vertex buffers setup elsewhere */
 	case RADEON_CP_3D_DRAW_INDX_2:	/* triggers drawing using indices to vertex buffer */
-	case RADEON_CP_INDX_BUFFER:	/* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
 	case RADEON_WAIT_FOR_IDLE:
 	case RADEON_CP_NOP:
 		/* these packets are safe */
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index feac5f0..6e04fdd 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -275,6 +275,8 @@
 						     unsigned int *cmdsz)
 {
 	u32 *cmd = (u32 *) cmdbuf->buf;
+	u32 offset, narrays;
+	int count, i, k;
 
 	*cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
 
@@ -288,10 +290,106 @@
 		return DRM_ERR(EINVAL);
 	}
 
-	/* Check client state and fix it up if necessary */
-	if (cmd[0] & 0x8000) {	/* MSB of opcode: next DWORD GUI_CNTL */
-		u32 offset;
+	switch(cmd[0] & 0xff00) {
+	/* XXX Are there old drivers needing other packets? */
 
+	case RADEON_3D_DRAW_IMMD:
+	case RADEON_3D_DRAW_VBUF:
+	case RADEON_3D_DRAW_INDX:
+	case RADEON_WAIT_FOR_IDLE:
+	case RADEON_CP_NOP:
+	case RADEON_3D_CLEAR_ZMASK:
+/*	case RADEON_CP_NEXT_CHAR:
+	case RADEON_CP_PLY_NEXTSCAN:
+	case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */
+		/* these packets are safe */
+		break;
+
+	case RADEON_CP_3D_DRAW_IMMD_2:
+	case RADEON_CP_3D_DRAW_VBUF_2:
+	case RADEON_CP_3D_DRAW_INDX_2:
+	case RADEON_3D_CLEAR_HIZ:
+		/* safe but r200 only */
+		if (dev_priv->microcode_version != UCODE_R200) {
+			DRM_ERROR("Invalid 3d packet for r100-class chip\n");
+			return DRM_ERR(EINVAL);
+		}
+		break;
+
+	case RADEON_3D_LOAD_VBPNTR:
+		count = (cmd[0] >> 16) & 0x3fff;
+
+		if (count > 18) { /* 12 arrays max */
+			DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
+				  count);
+			return DRM_ERR(EINVAL);
+		}
+
+		/* carefully check packet contents */
+		narrays = cmd[1] & ~0xc000;
+		k = 0;
+		i = 2;
+		while ((k < narrays) && (i < (count + 2))) {
+			i++;		/* skip attribute field */
+			if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) {
+				DRM_ERROR
+				    ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
+				     k, i);
+				return DRM_ERR(EINVAL);
+			}
+			k++;
+			i++;
+			if (k == narrays)
+				break;
+			/* have one more to process, they come in pairs */
+			if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) {
+				DRM_ERROR
+				    ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
+				     k, i);
+				return DRM_ERR(EINVAL);
+			}
+			k++;
+			i++;
+		}
+		/* do the counts match what we expect ? */
+		if ((k != narrays) || (i != (count + 2))) {
+			DRM_ERROR
+			    ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
+			      k, i, narrays, count + 1);
+			return DRM_ERR(EINVAL);
+		}
+		break;
+
+	case RADEON_3D_RNDR_GEN_INDX_PRIM:
+		if (dev_priv->microcode_version != UCODE_R100) {
+			DRM_ERROR("Invalid 3d packet for r200-class chip\n");
+			return DRM_ERR(EINVAL);
+		}
+		if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[1])) {
+				DRM_ERROR("Invalid rndr_gen_indx offset\n");
+				return DRM_ERR(EINVAL);
+		}
+		break;
+
+	case RADEON_CP_INDX_BUFFER:
+		if (dev_priv->microcode_version != UCODE_R200) {
+			DRM_ERROR("Invalid 3d packet for r100-class chip\n");
+			return DRM_ERR(EINVAL);
+		}
+		if ((cmd[1] & 0x8000ffff) != 0x80000810) {
+			DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
+			return DRM_ERR(EINVAL);
+		}
+		if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[2])) {
+			DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+			return DRM_ERR(EINVAL);
+		}
+		break;
+
+	case RADEON_CNTL_HOSTDATA_BLT:
+	case RADEON_CNTL_PAINT_MULTI:
+	case RADEON_CNTL_BITBLT_MULTI:
+		/* MSB of opcode: next DWORD GUI_CNTL */
 		if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
 			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
 			offset = cmd[2] << 10;
@@ -313,6 +411,11 @@
 			}
 			cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
 		}
+		break;
+
+	default:
+		DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00);
+		return DRM_ERR(EINVAL);
 	}
 
 	return 0;
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
index 59c7520..a9a84f8 100644
--- a/drivers/char/drm/savage_bci.c
+++ b/drivers/char/drm/savage_bci.c
@@ -728,6 +728,7 @@
 		dev_priv->status = NULL;
 	}
 	if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) {
+		dev->agp_buffer_token = init->buffers_offset;
 		dev->agp_buffer_map = drm_core_findmap(dev,
 						       init->buffers_offset);
 		if (!dev->agp_buffer_map) {
diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c
index ef2581d..1ca1e9c 100644
--- a/drivers/char/drm/savage_state.c
+++ b/drivers/char/drm/savage_state.c
@@ -994,7 +994,7 @@
 	if (cmdbuf.size) {
 		kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER);
 		if (kcmd_addr == NULL)
-			return ENOMEM;
+			return DRM_ERR(ENOMEM);
 
 		if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr,
 				       cmdbuf.size * 8))
diff --git a/drivers/char/ftape/zftape/zftape-buffers.c b/drivers/char/ftape/zftape/zftape-buffers.c
index da06f13..7ebce2e 100644
--- a/drivers/char/ftape/zftape/zftape-buffers.c
+++ b/drivers/char/ftape/zftape/zftape-buffers.c
@@ -85,7 +85,7 @@
 		peak_memory = used_memory;
 	}
 	TRACE_ABORT(0, ft_t_noise,
-		    "allocated buffer @ %p, %d bytes", *(void **)new, size);
+		    "allocated buffer @ %p, %zd bytes", *(void **)new, size);
 }
 int zft_vmalloc_always(void *new, size_t size)
 {
@@ -101,7 +101,7 @@
 	if (*(void **)old) {
 		vfree(*(void **)old);
 		used_memory -= size;
-		TRACE(ft_t_noise, "released buffer @ %p, %d bytes",
+		TRACE(ft_t_noise, "released buffer @ %p, %zd bytes",
 		      *(void **)old, size);
 		*(void **)old = NULL;
 	}
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 34a4fd1..c47add8 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -376,13 +376,23 @@
 	}
 }
 
+static void free_smi_msg_list(struct list_head *q)
+{
+	struct ipmi_smi_msg *msg, *msg2;
+
+	list_for_each_entry_safe(msg, msg2, q, link) {
+		list_del(&msg->link);
+		ipmi_free_smi_msg(msg);
+	}
+}
+
 static void clean_up_interface_data(ipmi_smi_t intf)
 {
 	int              i;
 	struct cmd_rcvr  *rcvr, *rcvr2;
 	struct list_head list;
 
-	free_recv_msg_list(&intf->waiting_msgs);
+	free_smi_msg_list(&intf->waiting_msgs);
 	free_recv_msg_list(&intf->waiting_events);
 
 	/* Wholesale remove all the entries from the list in the
@@ -1844,7 +1854,7 @@
 	struct bmc_device *bmc = dev_get_drvdata(dev);
 
 	return snprintf(buf, 10, "%u\n",
-			bmc->id.device_revision && 0x80 >> 7);
+			(bmc->id.device_revision & 0x80) >> 7);
 }
 
 static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
@@ -1853,7 +1863,7 @@
 	struct bmc_device *bmc = dev_get_drvdata(dev);
 
 	return snprintf(buf, 20, "%u\n",
-			bmc->id.device_revision && 0x0F);
+			bmc->id.device_revision & 0x0F);
 }
 
 static ssize_t firmware_rev_show(struct device *dev,
@@ -2108,7 +2118,7 @@
 		dev_set_drvdata(&bmc->dev->dev, bmc);
 		kref_init(&bmc->refcount);
 
-		rv = platform_device_register(bmc->dev);
+		rv = platform_device_add(bmc->dev);
 		mutex_unlock(&ipmidriver_mutex);
 		if (rv) {
 			printk(KERN_ERR
@@ -3232,7 +3242,9 @@
                    report the error immediately. */
 		if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0)
 		    && (msg->rsp[2] != IPMI_NODE_BUSY_ERR)
-		    && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR))
+		    && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR)
+		    && (msg->rsp[2] != IPMI_BUS_ERR)
+		    && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR))
 		{
 			int chan = msg->rsp[3] & 0xf;
 
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index e5cfb1f..bb1fac1 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1211,7 +1211,7 @@
 static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset)
 {
 	return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift)
-		&& 0xff;
+		& 0xff;
 }
 
 static void intf_mem_outw(struct si_sm_io *io, unsigned int offset,
@@ -1223,7 +1223,7 @@
 static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset)
 {
 	return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift)
-		&& 0xff;
+		& 0xff;
 }
 
 static void intf_mem_outl(struct si_sm_io *io, unsigned int offset,
@@ -1236,7 +1236,7 @@
 static unsigned char mem_inq(struct si_sm_io *io, unsigned int offset)
 {
 	return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift)
-		&& 0xff;
+		& 0xff;
 }
 
 static void mem_outq(struct si_sm_io *io, unsigned int offset,
@@ -1867,7 +1867,7 @@
 
 static struct pci_device_id ipmi_pci_devices[] = {
 	{ PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
-	{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE) }
+	{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }
 };
 MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
 
@@ -2346,7 +2346,7 @@
 		new_smi->dev = &new_smi->pdev->dev;
 		new_smi->dev->driver = &ipmi_driver;
 
-		rv = platform_device_register(new_smi->pdev);
+		rv = platform_device_add(new_smi->pdev);
 		if (rv) {
 			printk(KERN_ERR
 			       "ipmi_si_intf:"
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index e9e9bf3..58c955e 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1062,11 +1062,12 @@
 static void isicom_close(struct tty_struct *tty, struct file *filp)
 {
 	struct isi_port *port = tty->driver_data;
-	struct isi_board *card = port->card;
+	struct isi_board *card;
 	unsigned long flags;
 
 	if (!port)
 		return;
+	card = port->card;
 	if (isicom_paranoia_check(port, tty->name, "isicom_close"))
 		return;
 
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index b401383..96cb1f0 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -130,6 +130,7 @@
 typedef struct _moxa_pci_devinfo {
 	ushort busNum;
 	ushort devNum;
+	struct pci_dev *pdev;
 } moxa_pci_devinfo;
 
 typedef struct _moxa_board_conf {
@@ -324,6 +325,9 @@
 	board->busType = MOXA_BUS_TYPE_PCI;
 	board->pciInfo.busNum = p->bus->number;
 	board->pciInfo.devNum = p->devfn >> 3;
+	board->pciInfo.pdev = p;
+	/* don't lose the reference in the next pci_get_device iteration */
+	pci_dev_get(p);
 
 	return (0);
 }
@@ -493,6 +497,11 @@
 	if (tty_unregister_driver(moxaDriver))
 		printk("Couldn't unregister MOXA Intellio family serial driver\n");
 	put_tty_driver(moxaDriver);
+
+	for (i = 0; i < MAX_BOARDS; i++)
+		if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
+			pci_dev_put(moxa_boards[i].pciInfo.pdev);
+
 	if (verbose)
 		printk("Done\n");
 }
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index 5c0dec3..235e892 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -72,7 +72,11 @@
 	MSPEC_UNCACHED
 };
 
+#ifdef CONFIG_SGI_SN
 static int is_sn2;
+#else
+#define is_sn2		0
+#endif
 
 /*
  * One of these structures is allocated when an mspec region is mmaped. The
@@ -211,7 +215,7 @@
 	if (vdata->type == MSPEC_FETCHOP)
 		paddr = TO_AMO(maddr);
 	else
-		paddr = __pa(TO_CAC(maddr));
+		paddr = maddr & ~__IA64_UNCACHED_OFFSET;
 
 	pfn = paddr >> PAGE_SHIFT;
 
@@ -335,6 +339,7 @@
 	 * The fetchop device only works on SN2 hardware, uncached and cached
 	 * memory drivers should both be valid on all ia64 hardware
 	 */
+#ifdef CONFIG_SGI_SN
 	if (ia64_platform_is("sn2")) {
 		is_sn2 = 1;
 		if (is_shub2()) {
@@ -363,6 +368,7 @@
 			goto free_scratch_pages;
 		}
 	}
+#endif
 	ret = misc_register(&cached_miscdev);
 	if (ret) {
 		printk(KERN_ERR "%s: failed to register device %i\n",
diff --git a/drivers/char/rio/host.h b/drivers/char/rio/host.h
index ee2ddea..23d0681 100644
--- a/drivers/char/rio/host.h
+++ b/drivers/char/rio/host.h
@@ -44,6 +44,7 @@
 **    the host.
 */
 struct Host {
+	struct pci_dev *pdev;
 	unsigned char Type;		/* RIO_EISA, RIO_MCA, ... */
 	unsigned char Ivec;		/* POLLED or ivec number */
 	unsigned char Mode;		/* Control stuff */
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index c382df0..7ac68cb 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -1017,6 +1017,10 @@
 			rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
 
 			fix_rio_pci(pdev);
+
+			p->RIOHosts[p->RIONumHosts].pdev = pdev;
+			pci_dev_get(pdev);
+
 			p->RIOLastPCISearch = 0;
 			p->RIONumHosts++;
 			found++;
@@ -1066,6 +1070,9 @@
 			    ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24);
 			rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
 
+			p->RIOHosts[p->RIONumHosts].pdev = pdev;
+			pci_dev_get(pdev);
+
 			p->RIOLastPCISearch = 0;
 			p->RIONumHosts++;
 			found++;
@@ -1181,6 +1188,8 @@
 		}
 		/* It is safe/allowed to del_timer a non-active timer */
 		del_timer(&hp->timer);
+		if (hp->Type == RIO_PCI)
+			pci_dev_put(hp->pdev);
 	}
 
 	if (misc_deregister(&rio_fw_device) < 0) {
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 2444a0e..244d30a 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -792,15 +792,14 @@
 	ret = misc_register(&tlclk_miscdev);
 	if (ret < 0) {
 		printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret);
-		ret = -EBUSY;
 		goto out3;
 	}
 
 	tlclk_device = platform_device_register_simple("telco_clock",
 				-1, NULL, 0);
-	if (!tlclk_device) {
+	if (IS_ERR(tlclk_device)) {
 		printk(KERN_ERR "tlclk: platform_device_register failed.\n");
-		ret = -EBUSY;
+		ret = PTR_ERR(tlclk_device);
 		goto out4;
 	}
 
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 89e46d6d..0187b11 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -13,7 +13,7 @@
 	  subsequently opening the file and then failing to write to it for
 	  longer than 1 minute will result in rebooting the machine. This
 	  could be useful for a networked machine that needs to come back
-	  online as fast as possible after a lock-up. There's both a watchdog
+	  on-line as fast as possible after a lock-up. There's both a watchdog
 	  implementation entirely in software (which can sometimes fail to
 	  reboot the machine) and a driver for hardware watchdog boards, which
 	  are more robust and can also keep track of the temperature inside
@@ -60,7 +60,7 @@
 
 # ARM Architecture
 
-config AT91_WATCHDOG
+config AT91RM9200_WATCHDOG
 	tristate "AT91RM9200 watchdog"
 	depends on WATCHDOG && ARCH_AT91RM9200
 	help
@@ -71,7 +71,7 @@
 	tristate "DC21285 watchdog"
 	depends on WATCHDOG && FOOTBRIDGE
 	help
-	  The Intel Footbridge chip contains a builtin watchdog circuit. Say Y
+	  The Intel Footbridge chip contains a built-in watchdog circuit. Say Y
 	  here if you wish to use this. Alternatively say M to compile the
 	  driver as a module, which will be called wdt285.
 
@@ -269,11 +269,11 @@
 	  Most people will say N.
 
 config IBMASR
-        tristate "IBM Automatic Server Restart"
-        depends on WATCHDOG && X86
-        help
+	tristate "IBM Automatic Server Restart"
+	depends on WATCHDOG && X86
+	help
 	  This is the driver for the IBM Automatic Server Restart watchdog
-	  timer builtin into some eServer xSeries machines.
+	  timer built-in into some eServer xSeries machines.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ibmasr.
@@ -316,13 +316,16 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called i8xx_tco.
 
+	  Note: This driver will be removed in the near future. Please
+	  use the Intel TCO Timer/Watchdog driver.
+
 config ITCO_WDT
-	tristate "Intel TCO Timer/Watchdog (EXPERIMENTAL)"
-	depends on WATCHDOG && (X86 || IA64) && PCI && EXPERIMENTAL
+	tristate "Intel TCO Timer/Watchdog"
+	depends on WATCHDOG && (X86 || IA64) && PCI
 	---help---
 	  Hardware driver for the intel TCO timer based watchdog devices.
 	  These drivers are included in the Intel 82801 I/O Controller
-	  Hub family 'from ICH0 up to ICH7) and in the Intel 6300ESB
+	  Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB
 	  controller hub.
 
 	  The TCO (Total Cost of Ownership) timer is a watchdog timer
@@ -395,6 +398,26 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called cpu5wdt.
 
+config SMSC37B787_WDT
+	tristate "Winbond SMsC37B787 Watchdog Timer"
+	depends on WATCHDOG && X86
+	---help---
+	  This is the driver for the hardware watchdog component on the
+	  Winbond SMsC37B787 chipset as used on the NetRunner Mainboard
+	  from Vision Systems and maybe others.
+
+	  This watchdog simply watches your kernel to make sure it doesn't
+	  freeze, and if it does, it reboots your computer after a certain
+	  amount of time.
+
+	  Usually a userspace daemon will notify the kernel WDT driver that
+	  userspace is still alive, at regular intervals.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called smsc37b787_wdt.
+
+	  Most people will say N.
+
 config W83627HF_WDT
 	tristate "W83627HF Watchdog Timer"
 	depends on WATCHDOG && X86
@@ -410,6 +433,21 @@
 
 	  Most people will say N.
 
+config W83697HF_WDT
+	tristate "W83697HF/W83697HG Watchdog Timer"
+	depends on WATCHDOG && X86
+	---help---
+	  This is the driver for the hardware watchdog on the W83697HF/HG
+	  chipset as used in Dedibox/VIA motherboards (and likely others).
+	  This watchdog simply watches your kernel to make sure it doesn't
+	  freeze, and if it does, it reboots your computer after a certain
+	  amount of time.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called w83697hf_wdt.
+
+	  Most people will say N.
+
 config W83877F_WDT
 	tristate "W83877F (EMACS) Watchdog Timer"
 	depends on WATCHDOG && X86
@@ -443,7 +481,7 @@
 	depends on WATCHDOG && X86
 	---help---
 	  If you are using a ZF Micro MachZ processor, say Y here, otherwise
-	  N.  This is the driver for the watchdog timer builtin on that
+	  N.  This is the driver for the watchdog timer built-in on that
 	  processor using ZF-Logic interface.  This watchdog simply watches
 	  your kernel to make sure it doesn't freeze, and if it does, it
 	  reboots your computer after a certain amount of time.
@@ -472,7 +510,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called sbc_epx_c3.
 
-
 # PowerPC Architecture
 
 config 8xx_WDT
@@ -502,7 +539,7 @@
 	help
 	  This driver adds watchdog support for the RTAS watchdog.
 
-          To compile this driver as a module, choose M here. The module
+	  To compile this driver as a module, choose M here. The module
 	  will be called wdrtas.
 
 # MIPS Architecture
@@ -556,7 +593,7 @@
 	help
 	  If you say Y here, user applications will be able to mmap the
 	  WDT/CPG registers.
-#
+
 # SPARC64 Architecture
 
 config WATCHDOG_CP1XXX
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 7f70aba..3644049 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -23,7 +23,7 @@
 obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
 
 # ARM Architecture
-obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o
+obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
 obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
 obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
 obj-$(CONFIG_977_WATCHDOG) += wdt977.o
@@ -53,7 +53,9 @@
 obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
 obj-$(CONFIG_SBC8360_WDT) += sbc8360.o
 obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
+obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o
 obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
+obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o
 obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
 obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
 obj-$(CONFIG_MACHZ_WDT) += machzwd.o
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91rm9200_wdt.c
similarity index 100%
rename from drivers/char/watchdog/at91_wdt.c
rename to drivers/char/watchdog/at91rm9200_wdt.c
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c
index aaac94db..b6f29cb 100644
--- a/drivers/char/watchdog/iTCO_wdt.c
+++ b/drivers/char/watchdog/iTCO_wdt.c
@@ -35,6 +35,10 @@
  *	82801GDH (ICH7DH)    : document number 307013-002, 307014-009,
  *	82801GBM (ICH7-M)    : document number 307013-002, 307014-009,
  *	82801GHM (ICH7-M DH) : document number 307013-002, 307014-009,
+ *	82801HB  (ICH8)      : document number 313056-002, 313057-004,
+ *	82801HR  (ICH8R)     : document number 313056-002, 313057-004,
+ *	82801HH  (ICH8DH)    : document number 313056-002, 313057-004,
+ *	82801HO  (ICH8DO)    : document number 313056-002, 313057-004,
  *	6300ESB  (6300ESB)   : document number 300641-003
  */
 
@@ -45,7 +49,7 @@
 /* Module and version information */
 #define DRV_NAME        "iTCO_wdt"
 #define DRV_VERSION     "1.00"
-#define DRV_RELDATE     "30-Jul-2006"
+#define DRV_RELDATE     "08-Oct-2006"
 #define PFX		DRV_NAME ": "
 
 /* Includes */
@@ -85,6 +89,9 @@
 	TCO_ICH7,	/* ICH7 & ICH7R */
 	TCO_ICH7M,	/* ICH7-M */
 	TCO_ICH7MDH,	/* ICH7-M DH */
+	TCO_ICH8,	/* ICH8 & ICH8R */
+	TCO_ICH8DH,	/* ICH8DH */
+	TCO_ICH8DO,	/* ICH8DO */
 };
 
 static struct {
@@ -108,6 +115,9 @@
 	{"ICH7 or ICH7R", 2},
 	{"ICH7-M", 2},
 	{"ICH7-M DH", 2},
+	{"ICH8 or ICH8R", 2},
+	{"ICH8DH", 2},
+	{"ICH8DO", 2},
 	{NULL,0}
 };
 
@@ -135,6 +145,9 @@
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7    },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7M   },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7MDH },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8    },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DH  },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DO  },
 	{ 0, },			/* End of list */
 };
 MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
@@ -355,7 +368,8 @@
 		spin_unlock(&iTCO_wdt_private.io_lock);
 
 		*time_left = (val8 * 6) / 10;
-	}
+	} else
+		return -EINVAL;
 	return 0;
 }
 
@@ -426,7 +440,6 @@
 {
 	int new_options, retval = -EINVAL;
 	int new_heartbeat;
-	int time_left;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
 	static struct watchdog_info ident = {
@@ -486,6 +499,8 @@
 
 		case WDIOC_GETTIMELEFT:
 		{
+			int time_left;
+
 			if (iTCO_wdt_get_timeleft(&time_left))
 				return -EINVAL;
 
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 68b1ca976..18cb050 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -380,18 +380,21 @@
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (res == NULL) {
 		printk(KERN_INFO PFX "failed to get irq resource\n");
+		iounmap(wdt_base);
 		return -ENOENT;
 	}
 
 	ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev);
 	if (ret != 0) {
 		printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
+		iounmap(wdt_base);
 		return ret;
 	}
 
 	wdt_clock = clk_get(&pdev->dev, "watchdog");
 	if (wdt_clock == NULL) {
 		printk(KERN_INFO PFX "failed to find watchdog clock source\n");
+		iounmap(wdt_base);
 		return -ENOENT;
 	}
 
@@ -415,6 +418,7 @@
 	if (ret) {
 		printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
 			WATCHDOG_MINOR, ret);
+		iounmap(wdt_base);
 		return ret;
 	}
 
@@ -451,6 +455,7 @@
 		wdt_clock = NULL;
 	}
 
+	iounmap(wdt_base);
 	misc_deregister(&s3c2410wdt_miscdev);
 	return 0;
 }
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
index d8d0f28..e323983 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -392,7 +392,7 @@
 	if (io == -1) {
 		printk(KERN_ERR PFX "io parameter must be specified\n");
 		ret = -EINVAL;
-		goto out_clean;
+		goto out_pnp;
 	}
 
 #if defined CONFIG_PNP
@@ -405,7 +405,7 @@
 	if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
 		printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
 		ret = -EBUSY;
-		goto out_clean;
+		goto out_pnp;
 	}
 
 	ret = sc1200wdt_probe();
@@ -435,6 +435,11 @@
 out_io:
 	release_region(io, io_len);
 
+out_pnp:
+#if defined CONFIG_PNP
+	if (isapnp)
+		pnp_unregister_driver(&scl200wdt_pnp_driver);
+#endif
 	goto out_clean;
 }
 
diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/char/watchdog/smsc37b787_wdt.c
new file mode 100644
index 0000000..9f56913
--- /dev/null
+++ b/drivers/char/watchdog/smsc37b787_wdt.c
@@ -0,0 +1,627 @@
+/*
+ *	SMsC 37B787 Watchdog Timer driver for Linux 2.6.x.x
+ *
+ *      Based on acquirewdt.c by Alan Cox <alan@redhat.com>
+ *       and some other existing drivers
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *	The authors do NOT admit liability nor provide warranty for
+ *	any of this software. This material is provided "AS-IS" in
+ *      the hope that it may be useful for others.
+ *
+ *	(C) Copyright 2003-2006  Sven Anders <anders@anduras.de>
+ *
+ *  History:
+ *	2003 - Created version 1.0 for Linux 2.4.x.
+ *	2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE
+ *             features. Released version 1.1
+ *
+ *  Theory of operation:
+ *
+ *      A Watchdog Timer (WDT) is a hardware circuit that can
+ *      reset the computer system in case of a software fault.
+ *      You probably knew that already.
+ *
+ *      Usually a userspace daemon will notify the kernel WDT driver
+ *      via the /dev/watchdog special device file that userspace is
+ *      still alive, at regular intervals.  When such a notification
+ *      occurs, the driver will usually tell the hardware watchdog
+ *      that everything is in order, and that the watchdog should wait
+ *      for yet another little while to reset the system.
+ *      If userspace fails (RAM error, kernel bug, whatever), the
+ *      notifications cease to occur, and the hardware watchdog will
+ *      reset the system (causing a reboot) after the timeout occurs.
+ *
+ * Create device with:
+ *  mknod /dev/watchdog c 10 130
+ *
+ * For an example userspace keep-alive daemon, see:
+ *   Documentation/watchdog/watchdog.txt
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+/* enable support for minutes as units? */
+/* (does not always work correctly, so disabled by default!) */
+#define SMSC_SUPPORT_MINUTES
+#undef SMSC_SUPPORT_MINUTES
+
+#define MAX_TIMEOUT     255
+
+#define UNIT_SECOND     0
+#define UNIT_MINUTE     1
+
+#define MODNAME		"smsc37b787_wdt: "
+#define VERSION         "1.1"
+
+#define IOPORT          0x3F0
+#define IOPORT_SIZE     2
+#define IODEV_NO        8
+
+static int unit = UNIT_SECOND;  /* timer's unit */
+static int timeout = 60;        /* timeout value: default is 60 "units" */
+static unsigned long timer_enabled = 0;   /* is the timer enabled? */
+
+static char expect_close;       /* is the close expected? */
+
+static spinlock_t io_lock;	/* to guard the watchdog from io races */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+/* -- Low level function ----------------------------------------*/
+
+/* unlock the IO chip */
+
+static inline void open_io_config(void)
+{
+        outb(0x55, IOPORT);
+	mdelay(1);
+        outb(0x55, IOPORT);
+}
+
+/* lock the IO chip */
+static inline void close_io_config(void)
+{
+        outb(0xAA, IOPORT);
+}
+
+/* select the IO device */
+static inline void select_io_device(unsigned char devno)
+{
+        outb(0x07, IOPORT);
+        outb(devno, IOPORT+1);
+}
+
+/* write to the control register */
+static inline void write_io_cr(unsigned char reg, unsigned char data)
+{
+        outb(reg, IOPORT);
+        outb(data, IOPORT+1);
+}
+
+/* read from the control register */
+static inline char read_io_cr(unsigned char reg)
+{
+        outb(reg, IOPORT);
+        return inb(IOPORT+1);
+}
+
+/* -- Medium level functions ------------------------------------*/
+
+static inline void gpio_bit12(unsigned char reg)
+{
+	// -- General Purpose I/O Bit 1.2 --
+	// Bit 0,   In/Out: 0 = Output, 1 = Input
+	// Bit 1,   Polarity: 0 = No Invert, 1 = Invert
+	// Bit 2,   Group Enable Intr.: 0 = Disable, 1 = Enable
+	// Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17,
+	//                           11 = Either Edge Triggered Intr. 2
+        // Bit 5/6  (Reserved)
+	// Bit 7,   Output Type: 0 = Push Pull Bit, 1 = Open Drain
+        write_io_cr(0xE2, reg);
+}
+
+static inline void gpio_bit13(unsigned char reg)
+{
+	// -- General Purpose I/O Bit 1.3 --
+	// Bit 0,  In/Out: 0 = Output, 1 = Input
+	// Bit 1,  Polarity: 0 = No Invert, 1 = Invert
+	// Bit 2,  Group Enable Intr.: 0 = Disable, 1 = Enable
+	// Bit 3,  Function select: 0 = GPI/O, 1 = LED
+        // Bit 4-6 (Reserved)
+	// Bit 7,  Output Type: 0 = Push Pull Bit, 1 = Open Drain
+        write_io_cr(0xE3, reg);
+}
+
+static inline void wdt_timer_units(unsigned char new_units)
+{
+	// -- Watchdog timer units --
+	// Bit 0-6 (Reserved)
+	// Bit 7,  WDT Time-out Value Units Select
+	//         (0 = Minutes, 1 = Seconds)
+        write_io_cr(0xF1, new_units);
+}
+
+static inline void wdt_timeout_value(unsigned char new_timeout)
+{
+	// -- Watchdog Timer Time-out Value --
+	// Bit 0-7 Binary coded units (0=Disabled, 1..255)
+        write_io_cr(0xF2, new_timeout);
+}
+
+static inline void wdt_timer_conf(unsigned char conf)
+{
+	// -- Watchdog timer configuration --
+	// Bit 0   Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O
+	// Bit 1   Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr.
+	// Bit 2   Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr.
+        // Bit 3   Reset the timer
+        //         (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled)
+	// Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled,
+	//            0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15)
+        write_io_cr(0xF3, conf);
+}
+
+static inline void wdt_timer_ctrl(unsigned char reg)
+{
+	// -- Watchdog timer control --
+	// Bit 0   Status Bit: 0 = Timer counting, 1 = Timeout occured
+	// Bit 1   Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz
+	// Bit 2   Force Timeout: 1 = Forces WD timeout event (self-cleaning)
+	// Bit 3   P20 Force Timeout enabled:
+	//          0 = P20 activity does not generate the WD timeout event
+	//          1 = P20 Allows rising edge of P20, from the keyboard
+	//              controller, to force the WD timeout event.
+	// Bit 4   (Reserved)
+	// -- Soft power management --
+	// Bit 5   Stop Counter: 1 = Stop software power down counter
+	//            set via register 0xB8, (self-cleaning)
+	//            (Upon read: 0 = Counter running, 1 = Counter stopped)
+	// Bit 6   Restart Counter: 1 = Restart software power down counter
+	//            set via register 0xB8, (self-cleaning)
+	// Bit 7   SPOFF: 1 = Force software power down (self-cleaning)
+
+        write_io_cr(0xF4, reg);
+}
+
+/* -- Higher level functions ------------------------------------*/
+
+/* initialize watchdog */
+
+static void wb_smsc_wdt_initialize(void)
+{
+        unsigned char old;
+
+	spin_lock(&io_lock);
+        open_io_config();
+        select_io_device(IODEV_NO);
+
+	// enable the watchdog
+	gpio_bit13(0x08);  // Select pin 80 = LED not GPIO
+	gpio_bit12(0x0A);  // Set pin 79 = WDT not GPIO/Output/Polarity=Invert
+
+	// disable the timeout
+        wdt_timeout_value(0);
+
+	// reset control register
+        wdt_timer_ctrl(0x00);
+
+	// reset configuration register
+	wdt_timer_conf(0x00);
+
+	// read old (timer units) register
+        old = read_io_cr(0xF1) & 0x7F;
+        if (unit == UNIT_SECOND) old |= 0x80; // set to seconds
+
+	// set the watchdog timer units
+        wdt_timer_units(old);
+
+        close_io_config();
+	spin_unlock(&io_lock);
+}
+
+/* shutdown the watchdog */
+
+static void wb_smsc_wdt_shutdown(void)
+{
+	spin_lock(&io_lock);
+        open_io_config();
+        select_io_device(IODEV_NO);
+
+	// disable the watchdog
+        gpio_bit13(0x09);
+        gpio_bit12(0x09);
+
+	// reset watchdog config register
+	wdt_timer_conf(0x00);
+
+	// reset watchdog control register
+        wdt_timer_ctrl(0x00);
+
+	// disable timeout
+        wdt_timeout_value(0x00);
+
+        close_io_config();
+	spin_unlock(&io_lock);
+}
+
+/* set timeout => enable watchdog */
+
+static void wb_smsc_wdt_set_timeout(unsigned char new_timeout)
+{
+	spin_lock(&io_lock);
+        open_io_config();
+        select_io_device(IODEV_NO);
+
+	// set Power LED to blink, if we enable the timeout
+        wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02);
+
+	// set timeout value
+        wdt_timeout_value(new_timeout);
+
+        close_io_config();
+	spin_unlock(&io_lock);
+}
+
+/* get timeout */
+
+static unsigned char wb_smsc_wdt_get_timeout(void)
+{
+        unsigned char set_timeout;
+
+	spin_lock(&io_lock);
+        open_io_config();
+        select_io_device(IODEV_NO);
+        set_timeout = read_io_cr(0xF2);
+        close_io_config();
+	spin_unlock(&io_lock);
+
+        return set_timeout;
+}
+
+/* disable watchdog */
+
+static void wb_smsc_wdt_disable(void)
+{
+        // set the timeout to 0 to disable the watchdog
+        wb_smsc_wdt_set_timeout(0);
+}
+
+/* enable watchdog by setting the current timeout */
+
+static void wb_smsc_wdt_enable(void)
+{
+        // set the current timeout...
+        wb_smsc_wdt_set_timeout(timeout);
+}
+
+/* reset the timer */
+
+static void wb_smsc_wdt_reset_timer(void)
+{
+	spin_lock(&io_lock);
+        open_io_config();
+        select_io_device(IODEV_NO);
+
+	// reset the timer
+	wdt_timeout_value(timeout);
+	wdt_timer_conf(0x08);
+
+        close_io_config();
+	spin_unlock(&io_lock);
+}
+
+/* return, if the watchdog is enabled (timeout is set...) */
+
+static int wb_smsc_wdt_status(void)
+{
+	return (wb_smsc_wdt_get_timeout() == 0) ? 0 : WDIOF_KEEPALIVEPING;
+}
+
+
+/* -- File operations -------------------------------------------*/
+
+/* open => enable watchdog and set initial timeout */
+
+static int wb_smsc_wdt_open(struct inode *inode, struct file *file)
+{
+	/* /dev/watchdog can only be opened once */
+
+	if (test_and_set_bit(0, &timer_enabled))
+		return -EBUSY;
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	/* Reload and activate timer */
+	wb_smsc_wdt_enable();
+
+	printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
+
+	return nonseekable_open(inode, file);
+}
+
+/* close => shut off the timer */
+
+static int wb_smsc_wdt_release(struct inode *inode, struct file *file)
+{
+	/* Shut off the timer. */
+
+	if (expect_close == 42) {
+	        wb_smsc_wdt_disable();
+		printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n");
+	} else {
+		printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n");
+		wb_smsc_wdt_reset_timer();
+	}
+
+	clear_bit(0, &timer_enabled);
+	expect_close = 0;
+	return 0;
+}
+
+/* write => update the timer to keep the machine alive */
+
+static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data,
+				 size_t len, loff_t *ppos)
+{
+	/* See if we got the magic character 'V' and reload the timer */
+	if (len) {
+		if (!nowayout) {
+			size_t i;
+
+			/* reset expect flag */
+			expect_close = 0;
+
+			/* scan to see whether or not we got the magic character */
+			for (i = 0; i != len; i++) {
+				char c;
+				if (get_user(c, data+i))
+					return -EFAULT;
+				if (c == 'V')
+					expect_close = 42;
+			}
+		}
+
+		/* someone wrote to us, we should reload the timer */
+		wb_smsc_wdt_reset_timer();
+	}
+	return len;
+}
+
+/* ioctl => control interface */
+
+static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file,
+			     unsigned int cmd, unsigned long arg)
+{
+	int new_timeout;
+
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	static struct watchdog_info ident = {
+		.options = 		WDIOF_KEEPALIVEPING |
+		                        WDIOF_SETTIMEOUT |
+					WDIOF_MAGICCLOSE,
+		.firmware_version =	0,
+		.identity = 		"SMsC 37B787 Watchdog"
+	};
+
+	uarg.i = (int __user *)arg;
+
+	switch (cmd) {
+		default:
+			return -ENOTTY;
+
+		case WDIOC_GETSUPPORT:
+			return copy_to_user(uarg.ident, &ident,
+				sizeof(ident)) ? -EFAULT : 0;
+
+		case WDIOC_GETSTATUS:
+			return put_user(wb_smsc_wdt_status(), uarg.i);
+
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0, uarg.i);
+
+		case WDIOC_KEEPALIVE:
+			wb_smsc_wdt_reset_timer();
+			return 0;
+
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_timeout, uarg.i))
+				return -EFAULT;
+
+			// the API states this is given in secs
+			if (unit == UNIT_MINUTE)
+			  new_timeout /= 60;
+
+			if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
+				return -EINVAL;
+
+			timeout = new_timeout;
+			wb_smsc_wdt_set_timeout(timeout);
+
+			// fall through and return the new timeout...
+
+		case WDIOC_GETTIMEOUT:
+
+		        new_timeout = timeout;
+
+			if (unit == UNIT_MINUTE)
+			  new_timeout *= 60;
+
+			return put_user(new_timeout, uarg.i);
+
+		case WDIOC_SETOPTIONS:
+		{
+			int options, retval = -EINVAL;
+
+			if (get_user(options, uarg.i))
+				return -EFAULT;
+
+			if (options & WDIOS_DISABLECARD) {
+				wb_smsc_wdt_disable();
+				retval = 0;
+			}
+
+			if (options & WDIOS_ENABLECARD) {
+				wb_smsc_wdt_enable();
+				retval = 0;
+			}
+
+			return retval;
+		}
+	}
+}
+
+/* -- Notifier funtions -----------------------------------------*/
+
+static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+	{
+                // set timeout to 0, to avoid possible race-condition
+	        timeout = 0;
+		wb_smsc_wdt_disable();
+	}
+	return NOTIFY_DONE;
+}
+
+/* -- Module's structures ---------------------------------------*/
+
+static struct file_operations wb_smsc_wdt_fops =
+{
+	.owner          = THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= wb_smsc_wdt_write,
+	.ioctl		= wb_smsc_wdt_ioctl,
+	.open		= wb_smsc_wdt_open,
+	.release	= wb_smsc_wdt_release,
+};
+
+static struct notifier_block wb_smsc_wdt_notifier =
+{
+	.notifier_call  = wb_smsc_wdt_notify_sys,
+};
+
+static struct miscdevice wb_smsc_wdt_miscdev =
+{
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &wb_smsc_wdt_fops,
+};
+
+/* -- Module init functions -------------------------------------*/
+
+/* module's "constructor" */
+
+static int __init wb_smsc_wdt_init(void)
+{
+	int ret;
+
+	spin_lock_init(&io_lock);
+
+	printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n");
+
+	if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) {
+		printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT);
+		ret = -EBUSY;
+		goto out_pnp;
+	}
+
+        // set new maximum, if it's too big
+        if (timeout > MAX_TIMEOUT)
+               timeout = MAX_TIMEOUT;
+
+        // init the watchdog timer
+        wb_smsc_wdt_initialize();
+
+	ret = register_reboot_notifier(&wb_smsc_wdt_notifier);
+	if (ret) {
+		printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret);
+		goto out_io;
+	}
+
+	ret = misc_register(&wb_smsc_wdt_miscdev);
+	if (ret) {
+		printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR);
+		goto out_rbt;
+	}
+
+	// output info
+	printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
+	printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout);
+
+	// ret = 0
+
+out_clean:
+	return ret;
+
+out_rbt:
+	unregister_reboot_notifier(&wb_smsc_wdt_notifier);
+
+out_io:
+	release_region(IOPORT, IOPORT_SIZE);
+
+out_pnp:
+	goto out_clean;
+}
+
+/* module's "destructor" */
+
+static void __exit wb_smsc_wdt_exit(void)
+{
+	/* Stop the timer before we leave */
+	if (!nowayout)
+	{
+		wb_smsc_wdt_shutdown();
+		printk(KERN_INFO MODNAME "Watchdog disabled.\n");
+	}
+
+	misc_deregister(&wb_smsc_wdt_miscdev);
+	unregister_reboot_notifier(&wb_smsc_wdt_notifier);
+	release_region(IOPORT, IOPORT_SIZE);
+
+	printk("SMsC 37B787 watchdog component driver removed.\n");
+}
+
+module_init(wb_smsc_wdt_init);
+module_exit(wb_smsc_wdt_exit);
+
+MODULE_AUTHOR("Sven Anders <anders@anduras.de>");
+MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")");
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
+#ifdef SMSC_SUPPORT_MINUTES
+module_param(unit, int, 0);
+MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0");
+#endif
+
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60");
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index b4adc52..07d4bff 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -33,6 +33,7 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
+#include <linux/spinlock.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -44,6 +45,7 @@
 
 static unsigned long wdt_is_open;
 static char expect_close;
+static spinlock_t io_lock;
 
 /* You must set this - there is no sane way to probe for this board. */
 static int wdt_io = 0x2E;
@@ -110,12 +112,16 @@
 static void
 wdt_ctrl(int timeout)
 {
+	spin_lock(&io_lock);
+	
 	w83627hf_select_wd_register();
 
 	outb_p(0xF6, WDT_EFER);    /* Select CRF6 */
 	outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF6 */
 
 	w83627hf_unselect_wd_register();
+
+	spin_unlock(&io_lock);
 }
 
 static int
@@ -303,6 +309,8 @@
 {
 	int ret;
 
+	spin_lock_init(&io_lock);
+
 	printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF Super I/O chip initialising.\n");
 
 	if (wdt_set_heartbeat(timeout)) {
diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c
new file mode 100644
index 0000000..7768b55
--- /dev/null
+++ b/drivers/char/watchdog/w83697hf_wdt.c
@@ -0,0 +1,450 @@
+/*
+ *	w83697hf/hg WDT driver
+ *
+ *	(c) Copyright 2006 Samuel Tardieu <sam@rfc1149.net>
+ *	(c) Copyright 2006 Marcus Junker <junker@anduras.de>
+ *
+ *	Based on w83627hf_wdt.c which is based on advantechwdt.c
+ *	which is based on wdt.c.
+ *	Original copyright messages:
+ *
+ *	(c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
+ *
+ *	(c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
+ *
+ *	(c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *				http://www.redhat.com
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *	Neither Marcus Junker nor ANDURAS AG admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#define WATCHDOG_NAME "w83697hf/hg WDT"
+#define PFX WATCHDOG_NAME ": "
+#define WATCHDOG_TIMEOUT 60		/* 60 sec default timeout */
+
+static unsigned long wdt_is_open;
+static char expect_close;
+static spinlock_t io_lock;
+
+/* You must set this - there is no sane way to probe for this board. */
+static int wdt_io = 0x2e;
+module_param(wdt_io, int, 0);
+MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)");
+
+static int timeout = WATCHDOG_TIMEOUT;	/* in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ *	Kernel methods.
+ */
+
+#define W83697HF_EFER (wdt_io+0)	/* Extended Function Enable Register */
+#define W83697HF_EFIR (wdt_io+0)	/* Extended Function Index Register (same as EFER) */
+#define W83697HF_EFDR (wdt_io+1)	/* Extended Function Data Register */
+
+static inline void
+w83697hf_unlock(void)
+{
+	outb_p(0x87, W83697HF_EFER);	/* Enter extended function mode */
+	outb_p(0x87, W83697HF_EFER);	/* Again according to manual */
+}
+
+static inline void
+w83697hf_lock(void)
+{
+	outb_p(0xAA, W83697HF_EFER);	/* Leave extended function mode */
+}
+
+/*
+ *	The three functions w83697hf_get_reg(), w83697hf_set_reg() and
+ *	w83697hf_write_timeout() must be called with the device unlocked.
+ */
+
+static unsigned char
+w83697hf_get_reg(unsigned char reg)
+{
+	outb_p(reg, W83697HF_EFIR);
+	return inb_p(W83697HF_EFDR);
+}
+
+static void
+w83697hf_set_reg(unsigned char reg, unsigned char data)
+{
+	outb_p(reg, W83697HF_EFIR);
+	outb_p(data, W83697HF_EFDR);
+}
+
+static void
+w83697hf_write_timeout(int timeout)
+{
+	w83697hf_set_reg(0xF4, timeout);	/* Write Timeout counter to CRF4 */
+}
+
+static void
+w83697hf_select_wdt(void)
+{
+	w83697hf_unlock();
+	w83697hf_set_reg(0x07, 0x08);	/* Switch to logic device 8 (GPIO2) */
+}
+
+static inline void
+w83697hf_deselect_wdt(void)
+{
+	w83697hf_lock();
+}
+
+static void
+w83697hf_init(void)
+{
+	unsigned char bbuf;
+
+	w83697hf_select_wdt();
+
+	bbuf = w83697hf_get_reg(0x29);
+	bbuf &= ~0x60;
+	bbuf |= 0x20;
+	w83697hf_set_reg(0x29, bbuf);	/* Set pin 119 to WDTO# mode (= CR29, WDT0) */
+
+	bbuf = w83697hf_get_reg(0xF3);
+	bbuf &= ~0x04;
+	w83697hf_set_reg(0xF3, bbuf);	/* Count mode is seconds */
+
+	w83697hf_deselect_wdt();
+}
+
+static int
+wdt_ping(void)
+{
+	spin_lock(&io_lock);
+	w83697hf_select_wdt();
+
+	w83697hf_write_timeout(timeout);
+
+	w83697hf_deselect_wdt();
+	spin_unlock(&io_lock);
+	return 0;
+}
+
+static int
+wdt_enable(void)
+{
+	spin_lock(&io_lock);
+	w83697hf_select_wdt();
+
+	w83697hf_write_timeout(timeout);
+	w83697hf_set_reg(0x30, 1);	/* Enable timer */
+
+	w83697hf_deselect_wdt();
+	spin_unlock(&io_lock);
+	return 0;
+}
+
+static int
+wdt_disable(void)
+{
+	spin_lock(&io_lock);
+	w83697hf_select_wdt();
+
+	w83697hf_set_reg(0x30, 0);	/* Disable timer */
+	w83697hf_write_timeout(0);
+
+	w83697hf_deselect_wdt();
+	spin_unlock(&io_lock);
+	return 0;
+}
+
+static int
+wdt_set_heartbeat(int t)
+{
+	if ((t < 1) || (t > 255))
+		return -EINVAL;
+
+	timeout = t;
+	return 0;
+}
+
+static ssize_t
+wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			expect_close = 0;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf+i))
+					return -EFAULT;
+				if (c == 'V')
+					expect_close = 42;
+			}
+		}
+		wdt_ping();
+	}
+	return count;
+}
+
+static int
+wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	  unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	int new_timeout;
+	static struct watchdog_info ident = {
+		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
+		.firmware_version = 1,
+		.identity = "W83697HF WDT",
+	};
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		if (copy_to_user(argp, &ident, sizeof(ident)))
+			return -EFAULT;
+		break;
+
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, p);
+
+	case WDIOC_KEEPALIVE:
+		wdt_ping();
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, p))
+			return -EFAULT;
+		if (wdt_set_heartbeat(new_timeout))
+			return -EINVAL;
+		wdt_ping();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(timeout, p);
+
+	case WDIOC_SETOPTIONS:
+	{
+		int options, retval = -EINVAL;
+
+		if (get_user(options, p))
+			return -EFAULT;
+
+		if (options & WDIOS_DISABLECARD) {
+			wdt_disable();
+			retval = 0;
+		}
+
+		if (options & WDIOS_ENABLECARD) {
+			wdt_enable();
+			retval = 0;
+		}
+
+		return retval;
+	}
+
+	default:
+		return -ENOTTY;
+	}
+	return 0;
+}
+
+static int
+wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(0, &wdt_is_open))
+		return -EBUSY;
+	/*
+	 *	Activate
+	 */
+
+	wdt_enable();
+	return nonseekable_open(inode, file);
+}
+
+static int
+wdt_close(struct inode *inode, struct file *file)
+{
+	if (expect_close == 42) {
+		wdt_disable();
+	} else {
+		printk (KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
+		wdt_ping();
+	}
+	expect_close = 0;
+	clear_bit(0, &wdt_is_open);
+	return 0;
+}
+
+/*
+ *	Notifier for system down
+ */
+
+static int
+wdt_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT) {
+		/* Turn the WDT off */
+		wdt_disable();
+	}
+	return NOTIFY_DONE;
+}
+
+/*
+ *	Kernel Interfaces
+ */
+
+static struct file_operations wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= wdt_write,
+	.ioctl		= wdt_ioctl,
+	.open		= wdt_open,
+	.release	= wdt_close,
+};
+
+static struct miscdevice wdt_miscdev = {
+	.minor = WATCHDOG_MINOR,
+	.name = "watchdog",
+	.fops = &wdt_fops,
+};
+
+/*
+ *	The WDT needs to learn about soft shutdowns in order to
+ *	turn the timebomb registers off.
+ */
+
+static struct notifier_block wdt_notifier = {
+	.notifier_call = wdt_notify_sys,
+};
+
+static int
+w83697hf_check_wdt(void)
+{
+	if (!request_region(wdt_io, 2, WATCHDOG_NAME)) {
+		printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io);
+		return -EIO;
+	}
+
+	printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io);
+	w83697hf_unlock();
+	if (w83697hf_get_reg(0x20) == 0x60) {
+		printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io);
+		w83697hf_lock();
+		return 0;
+	}
+	w83697hf_lock();	/* Reprotect in case it was a compatible device */
+
+	printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io);
+	release_region(wdt_io, 2);
+	return -EIO;
+}
+
+static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 };
+
+static int __init
+wdt_init(void)
+{
+	int ret, i, found = 0;
+
+	spin_lock_init(&io_lock);
+
+	printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n");
+
+	if (wdt_io == 0) {
+		/* we will autodetect the W83697HF/HG watchdog */
+		for (i = 0; ((!found) && (w83697hf_ioports[i] != 0)); i++) {
+			wdt_io = w83697hf_ioports[i];
+			if (!w83697hf_check_wdt())
+				found++;
+		}
+	} else {
+		if (!w83697hf_check_wdt())
+			found++;
+	}
+
+	if (!found) {
+		printk (KERN_ERR PFX "No W83697HF/HG could be found\n");
+		ret = -EIO;
+		goto out;
+	}
+
+	w83697hf_init();
+	wdt_disable();	/* Disable watchdog until first use */
+
+	if (wdt_set_heartbeat(timeout)) {
+		wdt_set_heartbeat(WATCHDOG_TIMEOUT);
+		printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n",
+			WATCHDOG_TIMEOUT);
+	}
+
+	ret = register_reboot_notifier(&wdt_notifier);
+	if (ret != 0) {
+		printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+			ret);
+		goto unreg_regions;
+	}
+
+	ret = misc_register(&wdt_miscdev);
+	if (ret != 0) {
+		printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+			WATCHDOG_MINOR, ret);
+		goto unreg_reboot;
+	}
+
+	printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
+		timeout, nowayout);
+
+out:
+	return ret;
+unreg_reboot:
+	unregister_reboot_notifier(&wdt_notifier);
+unreg_regions:
+	release_region(wdt_io, 2);
+	goto out;
+}
+
+static void __exit
+wdt_exit(void)
+{
+	misc_deregister(&wdt_miscdev);
+	unregister_reboot_notifier(&wdt_notifier);
+	release_region(wdt_io, 2);
+}
+
+module_init(wdt_init);
+module_exit(wdt_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marcus Junker <junker@anduras.de>, Samuel Tardieu <sam@rfc1149.net>");
+MODULE_DESCRIPTION("w83697hf/hg WDT driver");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 7ad3be8..7fcb77a 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -54,8 +54,8 @@
 		v1 = read_pmtmr();
 		v2 = read_pmtmr();
 		v3 = read_pmtmr();
-	} while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
-			|| (v3 > v1 && v3 < v2));
+	} while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+			  || (v3 > v1 && v3 < v2)));
 
 	return (cycle_t)v2;
 }
@@ -138,6 +138,8 @@
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
 			acpi_pm_check_graylist);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
+			acpi_pm_check_graylist);
 #endif
 
 
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 2cc71b6..491779a 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -107,6 +107,7 @@
 
 config CPU_FREQ_GOV_ONDEMAND
 	tristate "'ondemand' cpufreq policy governor"
+	select CPU_FREQ_TABLE
 	help
 	  'ondemand' - This driver adds a dynamic cpufreq policy governor.
 	  The governor does a periodic polling and 
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 86e69b7..dd0c262 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -59,7 +59,7 @@
 	srcu_init_notifier_head(&cpufreq_transition_notifier_list);
 	return 0;
 }
-core_initcall(init_cpufreq_transition_notifier_list);
+pure_initcall(init_cpufreq_transition_notifier_list);
 
 static LIST_HEAD(cpufreq_governor_list);
 static DEFINE_MUTEX (cpufreq_governor_mutex);
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 4bde30b..75e9e38 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -230,34 +230,43 @@
  */
 static int edac_sysfs_memctrl_setup(void)
 {
-	int err=0;
+	int err = 0;
 
 	debugf1("%s()\n", __func__);
 
 	/* create the /sys/devices/system/edac directory */
 	err = sysdev_class_register(&edac_class);
 
-	if (!err) {
-		/* Init the MC's kobject */
-		memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj));
-		edac_memctrl_kobj.parent = &edac_class.kset.kobj;
-		edac_memctrl_kobj.ktype = &ktype_memctrl;
-
-		/* generate sysfs "..../edac/mc"   */
-		err = kobject_set_name(&edac_memctrl_kobj,"mc");
-
-		if (!err) {
-			/* FIXME: maybe new sysdev_create_subdir() */
-			err = kobject_register(&edac_memctrl_kobj);
-
-			if (err)
-				debugf1("Failed to register '.../edac/mc'\n");
-			else
-				debugf1("Registered '.../edac/mc' kobject\n");
-		}
-	} else
+	if (err) {
 		debugf1("%s() error=%d\n", __func__, err);
+		return err;
+	}
 
+	/* Init the MC's kobject */
+	memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj));
+	edac_memctrl_kobj.parent = &edac_class.kset.kobj;
+	edac_memctrl_kobj.ktype = &ktype_memctrl;
+
+	/* generate sysfs "..../edac/mc"   */
+	err = kobject_set_name(&edac_memctrl_kobj,"mc");
+
+	if (err)
+		goto fail;
+
+	/* FIXME: maybe new sysdev_create_subdir() */
+	err = kobject_register(&edac_memctrl_kobj);
+
+	if (err) {
+		debugf1("Failed to register '.../edac/mc'\n");
+		goto fail;
+	}
+
+	debugf1("Registered '.../edac/mc' kobject\n");
+
+	return 0;
+
+fail:
+	sysdev_class_unregister(&edac_class);
 	return err;
 }
 
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index 22d1747..ca4e67a 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -70,9 +70,9 @@
 
 #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp))
 #define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0]))
-#define SC_FCMND(fcmnd) ((Scsi_Cmnd *)((long)fcmnd - (long)&(((Scsi_Cmnd *)0)->SCp)))
+#define SC_FCMND(fcmnd)	((struct scsi_cmnd *)((long)fcmnd - (long)&(((struct scsi_cmnd *)0)->SCp)))
 
-static int fcp_scsi_queue_it(fc_channel *, Scsi_Cmnd *, fcp_cmnd *, int);
+static int fcp_scsi_queue_it(fc_channel *, struct scsi_cmnd *, fcp_cmnd *, int);
 void fcp_queue_empty(fc_channel *);
 
 static void fcp_scsi_insert_queue (fc_channel *fc, fcp_cmnd *fcmd)
@@ -378,14 +378,14 @@
 		printk ("FC: %segistering unknown type %02x\n", unregister ? "Unr" : "R", type);
 }
 
-static void fcp_scsi_done(Scsi_Cmnd *SCpnt);
+static void fcp_scsi_done(struct scsi_cmnd *SCpnt);
 
 static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hdr *fch)
 {
 	fcp_cmnd *fcmd;
 	fcp_rsp  *rsp;
 	int host_status;
-	Scsi_Cmnd *SCpnt;
+	struct scsi_cmnd *SCpnt;
 	int sense_len;
 	int rsp_status;
 
@@ -757,13 +757,14 @@
 }
 
 
-static void fcp_scsi_done (Scsi_Cmnd *SCpnt)
+static void fcp_scsi_done(struct scsi_cmnd *SCpnt)
 {
 	if (FCP_CMND(SCpnt)->done)
 		FCP_CMND(SCpnt)->done(SCpnt);
 }
 
-static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare)
+static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt,
+			     fcp_cmnd *fcmd, int prepare)
 {
 	long i;
 	fcp_cmd *cmd;
@@ -837,7 +838,8 @@
 	return 0;
 }
 
-int fcp_scsi_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *))
+int fcp_scsi_queuecommand(struct scsi_cmnd *SCpnt,
+			  void (* done)(struct scsi_cmnd *))
 {
 	fcp_cmnd *fcmd = FCP_CMND(SCpnt);
 	fc_channel *fc = FC_SCMND(SCpnt);
@@ -873,7 +875,7 @@
 	}
 }
 
-int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
+int fcp_scsi_abort(struct scsi_cmnd *SCpnt)
 {
 	/* Internal bookkeeping only. Lose 1 cmd_slots slot. */
 	fcp_cmnd *fcmd = FCP_CMND(SCpnt);
@@ -910,7 +912,7 @@
 }
 
 #if 0
-void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt)
+void fcp_scsi_reset_done(struct scsi_cmnd *SCpnt)
 {
 	fc_channel *fc = FC_SCMND(SCpnt);
 
@@ -921,7 +923,7 @@
 
 #define FCP_RESET_TIMEOUT (2*HZ)
 
-int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
+int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt)
 {
 #if 0 /* broken junk, but if davem wants to compile this driver, let him.. */
 	unsigned long flags;
@@ -931,7 +933,7 @@
         DECLARE_MUTEX_LOCKED(sem);
 
 	if (!fc->rst_pkt) {
-		fc->rst_pkt = (Scsi_Cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL);
+		fc->rst_pkt = (struct scsi_cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL);
 		if (!fc->rst_pkt) return FAILED;
 		
 		fcmd = FCP_CMND(fc->rst_pkt);
@@ -999,7 +1001,7 @@
 	return SUCCESS;
 }
 
-static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
+static int __fcp_scsi_host_reset(struct scsi_cmnd *SCpnt)
 {
 	fc_channel *fc = FC_SCMND(SCpnt);
 	fcp_cmnd *fcmd = FCP_CMND(SCpnt);
@@ -1020,7 +1022,7 @@
 	else return FAILED;
 }
 
-int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
+int fcp_scsi_host_reset(struct scsi_cmnd *SCpnt)
 {
 	unsigned long flags;
 	int rc;
diff --git a/drivers/fc4/fcp_impl.h b/drivers/fc4/fcp_impl.h
index c397c84..1ac6133 100644
--- a/drivers/fc4/fcp_impl.h
+++ b/drivers/fc4/fcp_impl.h
@@ -39,7 +39,7 @@
 typedef struct fcp_cmnd {
 	struct fcp_cmnd		*next;
 	struct fcp_cmnd		*prev;
-	void			(*done)(Scsi_Cmnd *);
+	void			(*done)(struct scsi_cmnd *);
 	unsigned short		proto;
 	unsigned short		token;
 	unsigned int		did;
@@ -94,14 +94,14 @@
 	long			*scsi_bitmap;
 	long			scsi_bitmap_end;
 	int			scsi_free;
-	int			(*encode_addr)(Scsi_Cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *);
+	int			(*encode_addr)(struct scsi_cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *);
 	fcp_cmnd		*scsi_que;
 	char			scsi_name[4];
 	fcp_cmnd		**cmd_slots;
 	int			channels;
 	int			targets;
 	long			*ages;
-	Scsi_Cmnd		*rst_pkt;
+	struct scsi_cmnd	*rst_pkt;
 	fcp_posmap		*posmap;
 	/* LOGIN stuff */
 	fcp_cmnd		*login;
@@ -155,9 +155,10 @@
 	for_each_fc_channel(fc)				\
 		if (fc->state == FC_STATE_ONLINE)
 
-int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-int fcp_scsi_abort(Scsi_Cmnd *);
-int fcp_scsi_dev_reset(Scsi_Cmnd *);
-int fcp_scsi_host_reset(Scsi_Cmnd *);
+int fcp_scsi_queuecommand(struct scsi_cmnd *,
+			  void (* done) (struct scsi_cmnd *));
+int fcp_scsi_abort(struct scsi_cmnd *);
+int fcp_scsi_dev_reset(struct scsi_cmnd *);
+int fcp_scsi_host_reset(struct scsi_cmnd *);
 
 #endif /* !(_FCP_SCSI_H) */
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 08b1617..fc702e4 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -705,17 +705,16 @@
 
 static int __init dcdrbu_init(void)
 {
-	int rc = 0;
+	int rc;
 	spin_lock_init(&rbu_data.lock);
 
 	init_packet_head();
-	rbu_device =
-		platform_device_register_simple("dell_rbu", -1, NULL, 0);
-	if (!rbu_device) {
+	rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0);
+	if (IS_ERR(rbu_device)) {
 		printk(KERN_ERR
 			"dell_rbu:%s:platform_device_register_simple "
 			"failed\n", __FUNCTION__);
-		return -EIO;
+		return PTR_ERR(rbu_device);
 	}
 
 	rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index b8b596d..37deee6 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -326,6 +326,26 @@
 }
 EXPORT_SYMBOL(dmi_get_system_info);
 
+
+/**
+ *	dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
+ *	@str: 	Case sensitive Name
+ */
+int dmi_name_in_vendors(char *str)
+{
+	static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
+				DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
+				DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
+	int i;
+	for (i = 0; fields[i] != DMI_NONE; i++) {
+		int f = fields[i];
+		if (dmi_ident[f] && strstr(dmi_ident[f], str))
+			return 1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(dmi_name_in_vendors);
+
 /**
  *	dmi_find_device - find onboard device by type/name
  *	@type: device type or %DMI_DEV_TYPE_ANY to match all device types
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c
index 1ce01fb..68fe863 100644
--- a/drivers/i2c/busses/i2c-ixp4xx.c
+++ b/drivers/i2c/busses/i2c-ixp4xx.c
@@ -137,7 +137,8 @@
 	gpio_line_set(gpio->scl_pin, 0);
 	gpio_line_set(gpio->sda_pin, 0);
 
-	if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) {
+	err = i2c_bit_add_bus(&drv_data->adapter);
+	if (err) {
 		printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id);
 
 		kfree(drv_data);
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 81050d3..c95a6c1 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -272,7 +272,8 @@
 			dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
 				__func__, (long)jiffies, ISR, ICR, IBMR);
 
-		if ((ISR & (ISR_UB|ISR_IBB|ISR_SAD)) == ISR_SAD ||
+		if ((ISR & (ISR_UB|ISR_IBB)) == 0 ||
+		    (ISR & ISR_SAD) != 0 ||
 		    (ICR & ICR_SCLE) == 0) {
 			if (i2c_debug > 1)
 				dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
@@ -492,7 +493,10 @@
 	if (isr & ISR_BED) {
 		/* what should we do here? */
 	} else {
-		int ret = i2c->slave->read(i2c->slave->data);
+		int ret = 0;
+
+		if (i2c->slave != NULL)
+			ret = i2c->slave->read(i2c->slave->data);
 
 		IDBR = ret;
 		ICR |= ICR_TB;   /* allow next byte */
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 32aab0d..714bae7 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -494,11 +494,12 @@
 	iface->pdev = pdev;
 	iface->bar = bar;
 
-	pci_enable_device_bars(iface->pdev, 1 << iface->bar);
+	rc = pci_enable_device_bars(iface->pdev, 1 << iface->bar);
+	if (rc)
+		goto errout_free;
 
 	rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name);
-
-	if (rc != 0) {
+	if (rc) {
 		printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n",
 				iface->bar);
 		goto errout_free;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index bddfebd..8821494 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -724,7 +724,7 @@
 		 * if we have an error, pass back CHECK_CONDITION as the
 		 * scsi status byte
 		 */
-		if (!rq->errors)
+		if (blk_pc_request(rq) && !rq->errors)
 			rq->errors = SAM_STAT_CHECK_CONDITION;
 
 		/* Check for tray open. */
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index b1d5291..45ed035 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -459,7 +459,7 @@
 #ifdef DEBUG
 	printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n",
 		req->rq_disk->disk_name, req->sector, req->nr_sectors,
-		req->buffer+512));
+		req->buffer+512);
 #endif
 	if (req->current_nr_sectors <= 0)
 		end_request(req, 1);
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 2b0ea8b..753fe0e 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -75,6 +75,7 @@
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_AMD_CS5536_IDE,			0x40, AMD_UDMA_100 },
 	{ 0 }
 };
@@ -491,7 +492,8 @@
 	/* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
 	/* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"),
 	/* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"),
-	/* 19 */ DECLARE_AMD_DEV("AMD5536"),
+	/* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"),
+	/* 20 */ DECLARE_AMD_DEV("AMD5536"),
 };
 
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -530,7 +532,8 @@
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 },
-	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_CS5536_IDE,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_CS5536_IDE,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index 5b77a5b..9f30688 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -40,6 +40,19 @@
 
 static int ide_generic_all;		/* Set to claim all devices */
 
+/*
+ * the module_param_named() was added for the modular case
+ * the __setup() is left as compatibility for existing setups
+ */
+#ifndef MODULE
+static int __init ide_generic_all_on(char *unused)
+{
+	ide_generic_all = 1;
+	printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n");
+	return 1;
+}
+__setup("all-generic-ide", ide_generic_all_on);
+#endif
 module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
 MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
 
@@ -234,8 +247,10 @@
 	    (!(PCI_FUNC(dev->devfn) & 1)))
 		goto out;
 
-	if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1)
-		goto out;
+	if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
+		if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1)
+			goto out;
+	}
 
 	if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 244f7eb..cfad09a 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -768,14 +768,7 @@
 	return ioc4_register_submodule(&ioc4_ide_submodule);
 }
 
-static void __devexit
-ioc4_ide_exit(void)
-{
-	ioc4_unregister_submodule(&ioc4_ide_submodule);
-}
-
 late_initcall(ioc4_ide_init); /* Call only after IDE init is done */
-module_exit(ioc4_ide_exit);
 
 MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon");
 MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card");
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 8a7b8fa..31e5cc4 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -64,6 +64,7 @@
 #include <linux/ethtool.h>
 #include <asm/uaccess.h>
 #include <asm/delay.h>
+#include <asm/unaligned.h>
 #include <net/arp.h>
 
 #include "config_roms.h"
@@ -491,7 +492,7 @@
 	int i;
 	struct eth1394_priv *priv = netdev_priv(dev);
 	struct hpsb_host *host = priv->host;
-	u64 guid = *((u64*)&(host->csr.rom->bus_info_data[3]));
+	u64 guid = get_unaligned((u64*)&(host->csr.rom->bus_info_data[3]));
 	u16 maxpayload = 1 << (host->csr.max_rec + 1);
 	int max_speed = IEEE1394_SPEED_MAX;
 
@@ -514,8 +515,8 @@
 				      ETHER1394_GASP_OVERHEAD)));
 
 		/* Set our hardware address while we're at it */
-		*(u64*)dev->dev_addr = guid;
-		*(u64*)dev->broadcast = ~0x0ULL;
+		memcpy(dev->dev_addr, &guid, sizeof(u64));
+		memset(dev->broadcast, 0xff, sizeof(u64));
 	}
 
 	spin_unlock_irqrestore (&priv->lock, flags);
@@ -894,6 +895,7 @@
 		u16 maxpayload;
 		struct eth1394_node_ref *node;
 		struct eth1394_node_info *node_info;
+		__be64 guid;
 
 		/* Sanity check. MacOSX seems to be sending us 131 in this
 		 * field (atleast on my Panther G5). Not sure why. */
@@ -902,8 +904,9 @@
 
 		maxpayload = min(eth1394_speedto_maxpayload[sspd], (u16)(1 << (max_rec + 1)));
 
+		guid = get_unaligned(&arp1394->s_uniq_id);
 		node = eth1394_find_node_guid(&priv->ip_node_list,
-					      be64_to_cpu(arp1394->s_uniq_id));
+					      be64_to_cpu(guid));
 		if (!node) {
 			return 0;
 		}
@@ -931,10 +934,9 @@
 		arp_ptr += arp->ar_pln;		/* skip over sender IP addr */
 
 		if (arp->ar_op == htons(ARPOP_REQUEST))
-			/* just set ARP req target unique ID to 0 */
-			*((u64*)arp_ptr) = 0;
+			memset(arp_ptr, 0, sizeof(u64));
 		else
-			*((u64*)arp_ptr) = *((u64*)dev->dev_addr);
+			memcpy(arp_ptr, dev->dev_addr, sizeof(u64));
 	}
 
 	/* Now add the ethernet header. */
@@ -1675,8 +1677,10 @@
 		if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF])
 			priv->bc_dgl++;
 	} else {
+		__be64 guid = get_unaligned((u64 *)eth->h_dest);
+
 		node = eth1394_find_node_guid(&priv->ip_node_list,
-					      be64_to_cpu(*(u64*)eth->h_dest));
+					      be64_to_cpu(guid));
 		if (!node) {
 			ret = -EAGAIN;
 			goto fail;
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index dea1352..6e8ea91 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -3552,12 +3552,21 @@
 {
 	int err;
 
+	printk(KERN_INFO "%s does not fully support suspend and resume yet\n",
+	       OHCI1394_DRIVER_NAME);
+
 	err = pci_save_state(pdev);
-	if (err)
-		goto out;
+	if (err) {
+		printk(KERN_ERR "%s: pci_save_state failed with %d\n",
+		       OHCI1394_DRIVER_NAME, err);
+		return err;
+	}
 	err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#ifdef OHCI1394_DEBUG
 	if (err)
-		goto out;
+		printk(KERN_DEBUG "%s: pci_set_power_state failed with %d\n",
+		       OHCI1394_DRIVER_NAME, err);
+#endif /* OHCI1394_DEBUG */
 
 /* PowerMac suspend code comes last */
 #ifdef CONFIG_PPC_PMAC
@@ -3570,8 +3579,8 @@
 			pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
 	}
 #endif /* CONFIG_PPC_PMAC */
-out:
-	return err;
+
+	return 0;
 }
 #endif /* CONFIG_PM */
 
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 60d3fbd..e11187e 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -47,6 +47,7 @@
 	struct sockaddr src_addr;
 	struct sockaddr dst_addr;
 	struct rdma_dev_addr *addr;
+	struct rdma_addr_client *client;
 	void *context;
 	void (*callback)(int status, struct sockaddr *src_addr,
 			 struct rdma_dev_addr *addr, void *context);
@@ -61,6 +62,26 @@
 static DECLARE_WORK(work, process_req, NULL);
 static struct workqueue_struct *addr_wq;
 
+void rdma_addr_register_client(struct rdma_addr_client *client)
+{
+	atomic_set(&client->refcount, 1);
+	init_completion(&client->comp);
+}
+EXPORT_SYMBOL(rdma_addr_register_client);
+
+static inline void put_client(struct rdma_addr_client *client)
+{
+	if (atomic_dec_and_test(&client->refcount))
+		complete(&client->comp);
+}
+
+void rdma_addr_unregister_client(struct rdma_addr_client *client)
+{
+	put_client(client);
+	wait_for_completion(&client->comp);
+}
+EXPORT_SYMBOL(rdma_addr_unregister_client);
+
 int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
 		     const unsigned char *dst_dev_addr)
 {
@@ -229,6 +250,7 @@
 		list_del(&req->list);
 		req->callback(req->status, &req->src_addr, req->addr,
 			      req->context);
+		put_client(req->client);
 		kfree(req);
 	}
 }
@@ -264,7 +286,8 @@
 	return ret;
 }
 
-int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
+int rdma_resolve_ip(struct rdma_addr_client *client,
+		    struct sockaddr *src_addr, struct sockaddr *dst_addr,
 		    struct rdma_dev_addr *addr, int timeout_ms,
 		    void (*callback)(int status, struct sockaddr *src_addr,
 				     struct rdma_dev_addr *addr, void *context),
@@ -285,6 +308,8 @@
 	req->addr = addr;
 	req->callback = callback;
 	req->context = context;
+	req->client = client;
+	atomic_inc(&client->refcount);
 
 	src_in = (struct sockaddr_in *) &req->src_addr;
 	dst_in = (struct sockaddr_in *) &req->dst_addr;
@@ -305,6 +330,7 @@
 		break;
 	default:
 		ret = req->status;
+		atomic_dec(&client->refcount);
 		kfree(req);
 		break;
 	}
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 9ae4f3a..845090b 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -63,6 +63,7 @@
 };
 
 static struct ib_sa_client sa_client;
+static struct rdma_addr_client addr_client;
 static LIST_HEAD(dev_list);
 static LIST_HEAD(listen_any_list);
 static DEFINE_MUTEX(lock);
@@ -1625,8 +1626,8 @@
 	if (cma_any_addr(dst_addr))
 		ret = cma_resolve_loopback(id_priv);
 	else
-		ret = rdma_resolve_ip(&id->route.addr.src_addr, dst_addr,
-				      &id->route.addr.dev_addr,
+		ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr,
+				      dst_addr, &id->route.addr.dev_addr,
 				      timeout_ms, addr_handler, id_priv);
 	if (ret)
 		goto err;
@@ -1762,22 +1763,29 @@
 
 	if (!cma_any_addr(addr)) {
 		ret = rdma_translate_ip(addr, &id->route.addr.dev_addr);
-		if (!ret) {
-			mutex_lock(&lock);
-			ret = cma_acquire_dev(id_priv);
-			mutex_unlock(&lock);
-		}
 		if (ret)
-			goto err;
+			goto err1;
+
+		mutex_lock(&lock);
+		ret = cma_acquire_dev(id_priv);
+		mutex_unlock(&lock);
+		if (ret)
+			goto err1;
 	}
 
 	memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr));
 	ret = cma_get_port(id_priv);
 	if (ret)
-		goto err;
+		goto err2;
 
 	return 0;
-err:
+err2:
+	if (!cma_any_addr(addr)) {
+		mutex_lock(&lock);
+		cma_detach_from_dev(id_priv);
+		mutex_unlock(&lock);
+	}
+err1:
 	cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE);
 	return ret;
 }
@@ -2210,6 +2218,7 @@
 		return -ENOMEM;
 
 	ib_sa_register_client(&sa_client);
+	rdma_addr_register_client(&addr_client);
 
 	ret = ib_register_client(&cma_client);
 	if (ret)
@@ -2217,6 +2226,7 @@
 	return 0;
 
 err:
+	rdma_addr_unregister_client(&addr_client);
 	ib_sa_unregister_client(&sa_client);
 	destroy_workqueue(cma_wq);
 	return ret;
@@ -2225,6 +2235,7 @@
 static void cma_cleanup(void)
 {
 	ib_unregister_client(&cma_client);
+	rdma_addr_unregister_client(&addr_client);
 	ib_sa_unregister_client(&sa_client);
 	destroy_workqueue(cma_wq);
 	idr_destroy(&sdp_ps);
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 493f4c6..a72bcea 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1750,7 +1750,7 @@
 		     */
 		    (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) ||
 		     rcv_has_same_gid(mad_agent_priv, wr, wc)))
-			return wr;
+			return (wr->status == IB_WC_SUCCESS) ? wr : NULL;
 	}
 
 	/*
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index b72c7f6..743247e 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1214,7 +1214,7 @@
 	resp.qp_access_flags        = attr->qp_access_flags;
 	resp.pkey_index             = attr->pkey_index;
 	resp.alt_pkey_index         = attr->alt_pkey_index;
-	resp.en_sqd_async_notify    = attr->en_sqd_async_notify;
+	resp.sq_draining            = attr->sq_draining;
 	resp.max_rd_atomic          = attr->max_rd_atomic;
 	resp.max_dest_rd_atomic     = attr->max_dest_rd_atomic;
 	resp.min_rnr_timer          = attr->min_rnr_timer;
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c
index 9e7bd94..27fe242 100644
--- a/drivers/infiniband/hw/amso1100/c2.c
+++ b/drivers/infiniband/hw/amso1100/c2.c
@@ -1155,7 +1155,8 @@
 		goto bail10;
 	}
 
-	c2_register_device(c2dev);
+	if (c2_register_device(c2dev))
+		goto bail10;
 
 	return 0;
 
diff --git a/drivers/infiniband/hw/amso1100/c2_alloc.c b/drivers/infiniband/hw/amso1100/c2_alloc.c
index 028a60b..0315f99 100644
--- a/drivers/infiniband/hw/amso1100/c2_alloc.c
+++ b/drivers/infiniband/hw/amso1100/c2_alloc.c
@@ -42,13 +42,14 @@
 {
 	int i;
 	struct sp_chunk *new_head;
+	dma_addr_t dma_addr;
 
-	new_head = (struct sp_chunk *) __get_free_page(gfp_mask);
+	new_head = dma_alloc_coherent(&c2dev->pcidev->dev, PAGE_SIZE,
+				      &dma_addr, gfp_mask);
 	if (new_head == NULL)
 		return -ENOMEM;
 
-	new_head->dma_addr = dma_map_single(c2dev->ibdev.dma_device, new_head,
-					    PAGE_SIZE, DMA_FROM_DEVICE);
+	new_head->dma_addr = dma_addr;
 	pci_unmap_addr_set(new_head, mapping, new_head->dma_addr);
 
 	new_head->next = NULL;
@@ -80,10 +81,8 @@
 
 	while (root) {
 		next = root->next;
-		dma_unmap_single(c2dev->ibdev.dma_device,
-				 pci_unmap_addr(root, mapping), PAGE_SIZE,
-			         DMA_FROM_DEVICE);
-		__free_page((struct page *) root);
+		dma_free_coherent(&c2dev->pcidev->dev, PAGE_SIZE, root,
+				  pci_unmap_addr(root, mapping));
 		root = next;
 	}
 }
diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c b/drivers/infiniband/hw/amso1100/c2_cq.c
index 9d7bcc5..05c9154 100644
--- a/drivers/infiniband/hw/amso1100/c2_cq.c
+++ b/drivers/infiniband/hw/amso1100/c2_cq.c
@@ -246,20 +246,17 @@
 
 static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq)
 {
-
-	dma_unmap_single(c2dev->ibdev.dma_device, pci_unmap_addr(mq, mapping),
-			 mq->q_size * mq->msg_size, DMA_FROM_DEVICE);
-	free_pages((unsigned long) mq->msg_pool.host,
-		   get_order(mq->q_size * mq->msg_size));
+	dma_free_coherent(&c2dev->pcidev->dev, mq->q_size * mq->msg_size,
+			  mq->msg_pool.host, pci_unmap_addr(mq, mapping));
 }
 
 static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size,
 			   int msg_size)
 {
-	unsigned long pool_start;
+	u8 *pool_start;
 
-	pool_start = __get_free_pages(GFP_KERNEL,
-				      get_order(q_size * msg_size));
+	pool_start = dma_alloc_coherent(&c2dev->pcidev->dev, q_size * msg_size,
+					&mq->host_dma, GFP_KERNEL);
 	if (!pool_start)
 		return -ENOMEM;
 
@@ -267,13 +264,10 @@
 		       0,		/* index (currently unknown) */
 		       q_size,
 		       msg_size,
-		       (u8 *) pool_start,
+		       pool_start,
 		       NULL,	/* peer (currently unknown) */
 		       C2_MQ_HOST_TARGET);
 
-	mq->host_dma = dma_map_single(c2dev->ibdev.dma_device,
-				      (void *)pool_start,
-				      q_size * msg_size, DMA_FROM_DEVICE);
 	pci_unmap_addr_set(mq, mapping, mq->host_dma);
 
 	return 0;
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index da98d9f..fef9727 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -757,20 +757,17 @@
 
 int c2_register_device(struct c2_dev *dev)
 {
-	int ret;
+	int ret = -ENOMEM;
 	int i;
 
 	/* Register pseudo network device */
 	dev->pseudo_netdev = c2_pseudo_netdev_init(dev);
-	if (dev->pseudo_netdev) {
-		ret = register_netdev(dev->pseudo_netdev);
-		if (ret) {
-			printk(KERN_ERR PFX
-				"Unable to register netdev, ret = %d\n", ret);
-			free_netdev(dev->pseudo_netdev);
-			return ret;
-		}
-	}
+	if (!dev->pseudo_netdev)
+		goto out3;
+
+	ret = register_netdev(dev->pseudo_netdev);
+	if (ret)
+		goto out2;
 
 	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
 	strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX);
@@ -848,21 +845,25 @@
 
 	ret = ib_register_device(&dev->ibdev);
 	if (ret)
-		return ret;
+		goto out1;
 
 	for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) {
 		ret = class_device_create_file(&dev->ibdev.class_dev,
 					       c2_class_attributes[i]);
-		if (ret) {
-			unregister_netdev(dev->pseudo_netdev);
-			free_netdev(dev->pseudo_netdev);
-			ib_unregister_device(&dev->ibdev);
-			return ret;
-		}
+		if (ret)
+			goto out0;
 	}
+	goto out3;
 
-	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);
-	return 0;
+out0:
+	ib_unregister_device(&dev->ibdev);
+out1:
+	unregister_netdev(dev->pseudo_netdev);
+out2:
+	free_netdev(dev->pseudo_netdev);
+out3:
+	pr_debug("%s:%u ret=%d\n", __FUNCTION__, __LINE__, ret);
+	return ret;
 }
 
 void c2_unregister_device(struct c2_dev *dev)
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c
index 30409e1..623dc95 100644
--- a/drivers/infiniband/hw/amso1100/c2_rnic.c
+++ b/drivers/infiniband/hw/amso1100/c2_rnic.c
@@ -157,8 +157,8 @@
 
 	props->fw_ver =
 		((u64)be32_to_cpu(reply->fw_ver_major) << 32) |
-		((be32_to_cpu(reply->fw_ver_minor) && 0xFFFF) << 16) |
-		(be32_to_cpu(reply->fw_ver_patch) && 0xFFFF);
+		((be32_to_cpu(reply->fw_ver_minor) & 0xFFFF) << 16) |
+		(be32_to_cpu(reply->fw_ver_patch) & 0xFFFF);
 	memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6);
 	props->max_mr_size         = 0xFFFFFFFF;
 	props->page_size_cap       = ~(C2_MIN_PAGESIZE-1);
@@ -517,14 +517,12 @@
 	/* Initialize the Verbs Reply Queue */
 	qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_QSIZE));
 	msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_MSGSIZE));
-	q1_pages = kmalloc(qsize * msgsize, GFP_KERNEL);
+	q1_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize,
+				      &c2dev->rep_vq.host_dma, GFP_KERNEL);
 	if (!q1_pages) {
 		err = -ENOMEM;
 		goto bail1;
 	}
-	c2dev->rep_vq.host_dma = dma_map_single(c2dev->ibdev.dma_device,
-					        (void *)q1_pages, qsize * msgsize,
-				      		DMA_FROM_DEVICE);
 	pci_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma);
 	pr_debug("%s rep_vq va %p dma %llx\n", __FUNCTION__, q1_pages,
 		 (unsigned long long) c2dev->rep_vq.host_dma);
@@ -540,17 +538,15 @@
 	/* Initialize the Asynchronus Event Queue */
 	qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_QSIZE));
 	msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_MSGSIZE));
-	q2_pages = kmalloc(qsize * msgsize, GFP_KERNEL);
+	q2_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize,
+				      &c2dev->aeq.host_dma, GFP_KERNEL);
 	if (!q2_pages) {
 		err = -ENOMEM;
 		goto bail2;
 	}
-	c2dev->aeq.host_dma = dma_map_single(c2dev->ibdev.dma_device,
-					        (void *)q2_pages, qsize * msgsize,
-				      		DMA_FROM_DEVICE);
 	pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma);
-	pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q1_pages,
-		 (unsigned long long) c2dev->rep_vq.host_dma);
+	pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q2_pages,
+		 (unsigned long long) c2dev->aeq.host_dma);
 	c2_mq_rep_init(&c2dev->aeq,
 		       2,
 		       qsize,
@@ -597,17 +593,13 @@
       bail4:
 	vq_term(c2dev);
       bail3:
-	dma_unmap_single(c2dev->ibdev.dma_device,
-			 pci_unmap_addr(&c2dev->aeq, mapping),
-			 c2dev->aeq.q_size * c2dev->aeq.msg_size,
-		  	 DMA_FROM_DEVICE);
-	kfree(q2_pages);
+	dma_free_coherent(&c2dev->pcidev->dev,
+			  c2dev->aeq.q_size * c2dev->aeq.msg_size,
+			  q2_pages, pci_unmap_addr(&c2dev->aeq, mapping));
       bail2:
-	dma_unmap_single(c2dev->ibdev.dma_device,
-			 pci_unmap_addr(&c2dev->rep_vq, mapping),
-			 c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size,
-		  	 DMA_FROM_DEVICE);
-	kfree(q1_pages);
+	dma_free_coherent(&c2dev->pcidev->dev,
+			  c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size,
+			  q1_pages, pci_unmap_addr(&c2dev->rep_vq, mapping));
       bail1:
 	c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool);
       bail0:
@@ -640,19 +632,17 @@
 	/* Free the verbs request allocator */
 	vq_term(c2dev);
 
-	/* Unmap and free the asynchronus event queue */
-	dma_unmap_single(c2dev->ibdev.dma_device,
-			 pci_unmap_addr(&c2dev->aeq, mapping),
-			 c2dev->aeq.q_size * c2dev->aeq.msg_size,
-		  	 DMA_FROM_DEVICE);
-	kfree(c2dev->aeq.msg_pool.host);
+	/* Free the asynchronus event queue */
+	dma_free_coherent(&c2dev->pcidev->dev,
+			  c2dev->aeq.q_size * c2dev->aeq.msg_size,
+			  c2dev->aeq.msg_pool.host,
+			  pci_unmap_addr(&c2dev->aeq, mapping));
 
-	/* Unmap and free the verbs reply queue */
-	dma_unmap_single(c2dev->ibdev.dma_device,
-			 pci_unmap_addr(&c2dev->rep_vq, mapping),
-			 c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size,
-		  	 DMA_FROM_DEVICE);
-	kfree(c2dev->rep_vq.msg_pool.host);
+	/* Free the verbs reply queue */
+	dma_free_coherent(&c2dev->pcidev->dev,
+			  c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size,
+			  c2dev->rep_vq.msg_pool.host,
+			  pci_unmap_addr(&c2dev->rep_vq, mapping));
 
 	/* Free the MQ shared pointer pool */
 	c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool);
diff --git a/drivers/infiniband/hw/ehca/Kconfig b/drivers/infiniband/hw/ehca/Kconfig
index 922389b..727b10d 100644
--- a/drivers/infiniband/hw/ehca/Kconfig
+++ b/drivers/infiniband/hw/ehca/Kconfig
@@ -10,6 +10,7 @@
 config INFINIBAND_EHCA_SCALING
 	bool "Scaling support (EXPERIMENTAL)"
 	depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL
+	default y
 	---help---
 	eHCA scaling support schedules the CQ callbacks to different CPUs.
 
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c
index 3bac197..214e2fd 100644
--- a/drivers/infiniband/hw/ehca/ehca_av.c
+++ b/drivers/infiniband/hw/ehca/ehca_av.c
@@ -118,8 +118,7 @@
 		}
 		memcpy(&av->av.grh.word_1, &gid, sizeof(gid));
 	}
-	/* for the time being we use a hard coded PMTU of 2048 Bytes */
-	av->av.pmtu = 4;
+	av->av.pmtu = EHCA_MAX_MTU;
 
 	/* dgid comes in grh.word_3 */
 	memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid,
@@ -193,7 +192,7 @@
 		memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid));
 	}
 
-	new_ehca_av.pmtu = 4; /* see also comment in create_ah() */
+	new_ehca_av.pmtu = EHCA_MAX_MTU;
 
 	memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid,
 	       sizeof(ah_attr->grh.dgid));
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index 5eae6ac..e1b618c 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -40,6 +40,7 @@
  */
 
 #include "ehca_tools.h"
+#include "ehca_iverbs.h"
 #include "hcp_if.h"
 
 int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
@@ -49,7 +50,7 @@
 					      ib_device);
 	struct hipz_query_hca *rblock;
 
-	rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	rblock = ehca_alloc_fw_ctrlblock();
 	if (!rblock) {
 		ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
 		return -ENOMEM;
@@ -96,7 +97,7 @@
 		= min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX);
 
 query_device1:
-	kfree(rblock);
+	ehca_free_fw_ctrlblock(rblock);
 
 	return ret;
 }
@@ -109,7 +110,7 @@
 					      ib_device);
 	struct hipz_query_port *rblock;
 
-	rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	rblock = ehca_alloc_fw_ctrlblock();
 	if (!rblock) {
 		ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
 		return -ENOMEM;
@@ -162,7 +163,7 @@
 	props->active_speed    = 0x1;
 
 query_port1:
-	kfree(rblock);
+	ehca_free_fw_ctrlblock(rblock);
 
 	return ret;
 }
@@ -178,7 +179,7 @@
 		return -EINVAL;
 	}
 
-	rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	rblock = ehca_alloc_fw_ctrlblock();
 	if (!rblock) {
 		ehca_err(&shca->ib_device,  "Can't allocate rblock memory.");
 		return -ENOMEM;
@@ -193,7 +194,7 @@
 	memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16));
 
 query_pkey1:
-	kfree(rblock);
+	ehca_free_fw_ctrlblock(rblock);
 
 	return ret;
 }
@@ -211,7 +212,7 @@
 		return -EINVAL;
 	}
 
-	rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	rblock = ehca_alloc_fw_ctrlblock();
 	if (!rblock) {
 		ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
 		return -ENOMEM;
@@ -227,7 +228,7 @@
 	memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64));
 
 query_gid1:
-	kfree(rblock);
+	ehca_free_fw_ctrlblock(rblock);
 
 	return ret;
 }
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 048cc44..c3ea746 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -45,6 +45,7 @@
 #include "ehca_tools.h"
 #include "hcp_if.h"
 #include "hipz_fns.h"
+#include "ipz_pt_fn.h"
 
 #define EQE_COMPLETION_EVENT   EHCA_BMASK_IBM(1,1)
 #define EQE_CQ_QP_NUMBER       EHCA_BMASK_IBM(8,31)
@@ -137,38 +138,36 @@
 	u64 *rblock;
 	unsigned long block_count;
 
-	rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	rblock = ehca_alloc_fw_ctrlblock();
 	if (!rblock) {
 		ehca_err(&shca->ib_device, "Cannot allocate rblock memory.");
 		ret = -ENOMEM;
 		goto error_data1;
 	}
 
+	/* rblock must be 4K aligned and should be 4K large */
 	ret = hipz_h_error_data(shca->ipz_hca_handle,
 				resource,
 				rblock,
 				&block_count);
 
-	if (ret == H_R_STATE) {
+	if (ret == H_R_STATE)
 		ehca_err(&shca->ib_device,
 			 "No error data is available: %lx.", resource);
-	}
 	else if (ret == H_SUCCESS) {
 		int length;
 
 		length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]);
 
-		if (length > PAGE_SIZE)
-			length = PAGE_SIZE;
+		if (length > EHCA_PAGESIZE)
+			length = EHCA_PAGESIZE;
 
 		print_error_data(shca, data, rblock, length);
-	}
-	else {
+	} else
 		ehca_err(&shca->ib_device,
 			 "Error data could not be fetched: %lx", resource);
-	}
 
-	kfree(rblock);
+	ehca_free_fw_ctrlblock(rblock);
 
 error_data1:
 	return ret;
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index 319c39d..3720e30 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -179,4 +179,12 @@
 
 int ehca_munmap(unsigned long addr, size_t len);
 
+#ifdef CONFIG_PPC_64K_PAGES
+void *ehca_alloc_fw_ctrlblock(void);
+void ehca_free_fw_ctrlblock(void *ptr);
+#else
+#define ehca_alloc_fw_ctrlblock() ((void *) get_zeroed_page(GFP_KERNEL))
+#define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr))
+#endif
+
 #endif
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 024d511..01f5aa9 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -40,6 +40,9 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifdef CONFIG_PPC_64K_PAGES
+#include <linux/slab.h>
+#endif
 #include "ehca_classes.h"
 #include "ehca_iverbs.h"
 #include "ehca_mrmw.h"
@@ -49,7 +52,7 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
 MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0017");
+MODULE_VERSION("SVNEHCA_0018");
 
 int ehca_open_aqp1     = 0;
 int ehca_debug_level   = 0;
@@ -94,11 +97,31 @@
 DEFINE_IDR(ehca_qp_idr);
 DEFINE_IDR(ehca_cq_idr);
 
+
 static struct list_head shca_list; /* list of all registered ehcas */
 static spinlock_t shca_list_lock;
 
 static struct timer_list poll_eqs_timer;
 
+#ifdef CONFIG_PPC_64K_PAGES
+static struct kmem_cache *ctblk_cache = NULL;
+
+void *ehca_alloc_fw_ctrlblock(void)
+{
+	void *ret = kmem_cache_zalloc(ctblk_cache, SLAB_KERNEL);
+	if (!ret)
+		ehca_gen_err("Out of memory for ctblk");
+	return ret;
+}
+
+void ehca_free_fw_ctrlblock(void *ptr)
+{
+	if (ptr)
+		kmem_cache_free(ctblk_cache, ptr);
+
+}
+#endif
+
 static int ehca_create_slab_caches(void)
 {
 	int ret;
@@ -133,6 +156,17 @@
 		goto create_slab_caches5;
 	}
 
+#ifdef CONFIG_PPC_64K_PAGES
+	ctblk_cache = kmem_cache_create("ehca_cache_ctblk",
+					EHCA_PAGESIZE, H_CB_ALIGNMENT,
+					SLAB_HWCACHE_ALIGN,
+					NULL, NULL);
+	if (!ctblk_cache) {
+		ehca_gen_err("Cannot create ctblk SLAB cache.");
+		ehca_cleanup_mrmw_cache();
+		goto create_slab_caches5;
+	}
+#endif
 	return 0;
 
 create_slab_caches5:
@@ -157,6 +191,10 @@
 	ehca_cleanup_qp_cache();
 	ehca_cleanup_cq_cache();
 	ehca_cleanup_pd_cache();
+#ifdef CONFIG_PPC_64K_PAGES
+	if (ctblk_cache)
+		kmem_cache_destroy(ctblk_cache);
+#endif
 }
 
 #define EHCA_HCAAVER  EHCA_BMASK_IBM(32,39)
@@ -168,7 +206,7 @@
 	u64 h_ret;
 	struct hipz_query_hca *rblock;
 
-	rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	rblock = ehca_alloc_fw_ctrlblock();
 	if (!rblock) {
 		ehca_gen_err("Cannot allocate rblock memory.");
 		return -ENOMEM;
@@ -211,7 +249,7 @@
 	shca->sport[1].rate = IB_RATE_30_GBPS;
 
 num_ports1:
-	kfree(rblock);
+	ehca_free_fw_ctrlblock(rblock);
 	return ret;
 }
 
@@ -220,7 +258,7 @@
 	int ret = 0;
 	struct hipz_query_hca *rblock;
 
-	rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	rblock = ehca_alloc_fw_ctrlblock();
 	if (!rblock) {
 		ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
 		return -ENOMEM;
@@ -235,7 +273,7 @@
 	memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64));
 
 init_node_guid1:
-	kfree(rblock);
+	ehca_free_fw_ctrlblock(rblock);
 	return ret;
 }
 
@@ -431,7 +469,7 @@
 									   \
 	shca = dev->driver_data;					   \
 									   \
-	rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);			   \
+	rblock = ehca_alloc_fw_ctrlblock();				   \
 	if (!rblock) {						           \
 		dev_err(dev, "Can't allocate rblock memory.");		   \
 		return 0;						   \
@@ -439,12 +477,12 @@
 									   \
 	if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \
 		dev_err(dev, "Can't query device properties");	   	   \
-		kfree(rblock);					   	   \
+		ehca_free_fw_ctrlblock(rblock);			   	   \
 		return 0;					   	   \
 	}								   \
 									   \
 	data = rblock->name;                                               \
-	kfree(rblock);                                                     \
+	ehca_free_fw_ctrlblock(rblock);                                    \
 									   \
 	if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1))	   \
 		return snprintf(buf, 256, "1\n");			   \
@@ -752,7 +790,7 @@
 	int ret;
 
 	printk(KERN_INFO "eHCA Infiniband Device Driver "
-	                 "(Rel.: SVNEHCA_0017)\n");
+	                 "(Rel.: SVNEHCA_0018)\n");
 	idr_init(&ehca_qp_idr);
 	idr_init(&ehca_cq_idr);
 	spin_lock_init(&ehca_qp_idr_lock);
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 5ca6544..abce676 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -1013,7 +1013,7 @@
 	u32 i;
 	u64 *kpage;
 
-	kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	kpage = ehca_alloc_fw_ctrlblock();
 	if (!kpage) {
 		ehca_err(&shca->ib_device, "kpage alloc failed");
 		ret = -ENOMEM;
@@ -1092,7 +1092,7 @@
 
 
 ehca_reg_mr_rpages_exit1:
-	kfree(kpage);
+	ehca_free_fw_ctrlblock(kpage);
 ehca_reg_mr_rpages_exit0:
 	if (ret)
 		ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p "
@@ -1124,7 +1124,7 @@
 	ehca_mrmw_map_acl(acl, &hipz_acl);
 	ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
 
-	kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	kpage = ehca_alloc_fw_ctrlblock();
 	if (!kpage) {
 		ehca_err(&shca->ib_device, "kpage alloc failed");
 		ret = -ENOMEM;
@@ -1181,7 +1181,7 @@
 	}
 
 ehca_rereg_mr_rereg1_exit1:
-	kfree(kpage);
+	ehca_free_fw_ctrlblock(kpage);
 ehca_rereg_mr_rereg1_exit0:
 	if ( ret && (ret != -EAGAIN) )
 		ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x "
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 4394123..cf3e50e 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -811,8 +811,8 @@
 	unsigned long spl_flags = 0;
 
 	/* do query_qp to obtain current attr values */
-	mqpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
-	if (mqpcb == NULL) {
+	mqpcb = ehca_alloc_fw_ctrlblock();
+	if (!mqpcb) {
 		ehca_err(ibqp->device, "Could not get zeroed page for mqpcb "
 			 "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num);
 		return -ENOMEM;
@@ -1225,7 +1225,7 @@
 	}
 
 modify_qp_exit1:
-	kfree(mqpcb);
+	ehca_free_fw_ctrlblock(mqpcb);
 
 	return ret;
 }
@@ -1277,7 +1277,7 @@
 		return -EINVAL;
 	}
 
-	qpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL );
+	qpcb = ehca_alloc_fw_ctrlblock();
 	if (!qpcb) {
 		ehca_err(qp->device,"Out of memory for qpcb "
 			 "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num);
@@ -1401,7 +1401,7 @@
 		ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num);
 
 query_qp_exit1:
-	kfree(qpcb);
+	ehca_free_fw_ctrlblock(qpcb);
 
 	return ret;
 }
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
index 809da3e..973c4b5 100644
--- a/drivers/infiniband/hw/ehca/ehca_tools.h
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -63,6 +63,7 @@
 #include <asm/ibmebus.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
+#include <asm/hvcall.h>
 
 extern int ehca_debug_level;
 
diff --git a/drivers/infiniband/hw/ehca/hipz_hw.h b/drivers/infiniband/hw/ehca/hipz_hw.h
index 3fc92b0..fad9136 100644
--- a/drivers/infiniband/hw/ehca/hipz_hw.h
+++ b/drivers/infiniband/hw/ehca/hipz_hw.h
@@ -45,6 +45,8 @@
 
 #include "ehca_tools.h"
 
+#define EHCA_MAX_MTU 4
+
 /* QP Table Entry Memory Map */
 struct hipz_qptemm {
 	u64 qpx_hcr;
diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig
index 574a678..90c1454 100644
--- a/drivers/infiniband/hw/ipath/Kconfig
+++ b/drivers/infiniband/hw/ipath/Kconfig
@@ -1,6 +1,6 @@
 config INFINIBAND_IPATH
 	tristate "QLogic InfiniPath Driver"
-	depends on PCI_MSI && 64BIT && INFINIBAND
+	depends on (PCI_MSI || HT_IRQ) && 64BIT && INFINIBAND && NET
 	---help---
 	This is a driver for QLogic InfiniPath host channel adapters,
 	including InfiniBand verbs support.  This driver allows these
diff --git a/drivers/infiniband/hw/ipath/Makefile b/drivers/infiniband/hw/ipath/Makefile
index 5e29cb0..7dc1055 100644
--- a/drivers/infiniband/hw/ipath/Makefile
+++ b/drivers/infiniband/hw/ipath/Makefile
@@ -10,8 +10,6 @@
 	ipath_eeprom.o \
 	ipath_file_ops.o \
 	ipath_fs.o \
-	ipath_iba6110.o \
-	ipath_iba6120.o \
 	ipath_init_chip.o \
 	ipath_intr.o \
 	ipath_keys.o \
@@ -31,5 +29,8 @@
 	ipath_verbs_mcast.o \
 	ipath_verbs.o
 
+ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o
+ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o
+
 ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o
 ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index b4ffaa7..1aeddb4 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -304,7 +304,7 @@
 	}
 	addr = pci_resource_start(pdev, 0);
 	len = pci_resource_len(pdev, 0);
-	ipath_cdbg(VERBOSE, "regbase (0) %llx len %d irq %x, vend %x/%x "
+	ipath_cdbg(VERBOSE, "regbase (0) %llx len %d pdev->irq %d, vend %x/%x "
 		   "driver_data %lx\n", addr, len, pdev->irq, ent->vendor,
 		   ent->device, ent->driver_data);
 
@@ -390,12 +390,16 @@
 
 	/* setup the chip-specific functions, as early as possible. */
 	switch (ent->device) {
+#ifdef CONFIG_HT_IRQ
 	case PCI_DEVICE_ID_INFINIPATH_HT:
 		ipath_init_iba6110_funcs(dd);
 		break;
+#endif
+#ifdef CONFIG_PCI_MSI
 	case PCI_DEVICE_ID_INFINIPATH_PE800:
 		ipath_init_iba6120_funcs(dd);
 		break;
+#endif
 	default:
 		ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, "
 			      "failing\n", ent->device);
@@ -467,15 +471,15 @@
 	 * check 0 irq after we return from chip-specific bus setup, since
 	 * that can affect this due to setup
 	 */
-	if (!pdev->irq)
+	if (!dd->ipath_irq)
 		ipath_dev_err(dd, "irq is 0, BIOS error?  Interrupts won't "
 			      "work\n");
 	else {
-		ret = request_irq(pdev->irq, ipath_intr, IRQF_SHARED,
+		ret = request_irq(dd->ipath_irq, ipath_intr, IRQF_SHARED,
 				  IPATH_DRV_NAME, dd);
 		if (ret) {
 			ipath_dev_err(dd, "Couldn't setup irq handler, "
-				      "irq=%u: %d\n", pdev->irq, ret);
+				      "irq=%d: %d\n", dd->ipath_irq, ret);
 			goto bail_iounmap;
 		}
 	}
@@ -637,11 +641,10 @@
 	 * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs
 	 * for all versions of the driver, if they were allocated
 	 */
-	if (pdev->irq) {
-		ipath_cdbg(VERBOSE,
-			   "unit %u free_irq of irq %x\n",
-			   dd->ipath_unit, pdev->irq);
-		free_irq(pdev->irq, dd);
+	if (dd->ipath_irq) {
+		ipath_cdbg(VERBOSE, "unit %u free irq %d\n",
+			   dd->ipath_unit, dd->ipath_irq);
+		dd->ipath_f_free_irq(dd);
 	} else
 		ipath_dbg("irq is 0, not doing free_irq "
 			  "for unit %u\n", dd->ipath_unit);
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c
index 9e4e8d4..e57c7a3 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6110.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -38,6 +38,7 @@
 
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/htirq.h>
 
 #include "ipath_kernel.h"
 #include "ipath_registers.h"
@@ -913,49 +914,40 @@
 	}
 }
 
-static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev,
-			    int pos)
+static int ipath_ht_intconfig(struct ipath_devdata *dd)
 {
-	u32 int_handler_addr_lower;
-	u32 int_handler_addr_upper;
-	u64 ihandler;
-	u32 intvec;
+	int ret;
 
-	/* use indirection register to get the intr handler */
-	pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x10);
-	pci_read_config_dword(pdev, pos + 4, &int_handler_addr_lower);
-	pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x11);
-	pci_read_config_dword(pdev, pos + 4, &int_handler_addr_upper);
+	if (dd->ipath_intconfig) {
+		ipath_write_kreg(dd, dd->ipath_kregs->kr_interruptconfig,
+				 dd->ipath_intconfig);	/* interrupt address */
+		ret = 0;
+	} else {
+		ipath_dev_err(dd, "No interrupts enabled, couldn't setup "
+			      "interrupt address\n");
+		ret = -EINVAL;
+	}
 
-	ihandler = (u64) int_handler_addr_lower |
-		((u64) int_handler_addr_upper << 32);
+	return ret;
+}
+
+static void ipath_ht_irq_update(struct pci_dev *dev, int irq,
+				struct ht_irq_msg *msg)
+{
+	struct ipath_devdata *dd = pci_get_drvdata(dev);
+	u64 prev_intconfig = dd->ipath_intconfig;
+
+	dd->ipath_intconfig = msg->address_lo;
+	dd->ipath_intconfig |= ((u64) msg->address_hi) << 32;
 
 	/*
-	 * kernels with CONFIG_PCI_MSI set the vector in the irq field of
-	 * struct pci_device, so we use that to program the internal
-	 * interrupt register (not config space) with that value. The BIOS
-	 * must still have done the basic MSI setup.
+	 * If the previous value of dd->ipath_intconfig is zero, we're
+	 * getting configured for the first time, and must not program the
+	 * intconfig register here (it will be programmed later, when the
+	 * hardware is ready).  Otherwise, we should.
 	 */
-	intvec = pdev->irq;
-	/*
-	 * clear any vector bits there; normally not set but we'll overload
-	 * this for some debug purposes (setting the HTC debug register
-	 * value from software, rather than GPIOs), so it might be set on a
-	 * driver reload.
-	 */
-	ihandler &= ~0xff0000;
-	/* x86 vector goes in intrinfo[23:16] */
-	ihandler |= intvec << 16;
-	ipath_cdbg(VERBOSE, "ihandler lower %x, upper %x, intvec %x, "
-		   "interruptconfig %llx\n", int_handler_addr_lower,
-		   int_handler_addr_upper, intvec,
-		   (unsigned long long) ihandler);
-
-	/* can't program yet, so save for interrupt setup */
-	dd->ipath_intconfig = ihandler;
-	/* keep going, so we find link control stuff also */
-
-	return ihandler != 0;
+	if (prev_intconfig)
+		ipath_ht_intconfig(dd);
 }
 
 /**
@@ -971,12 +963,19 @@
 static int ipath_setup_ht_config(struct ipath_devdata *dd,
 				 struct pci_dev *pdev)
 {
-	int pos, ret = 0;
-	int ihandler = 0;
+	int pos, ret;
+
+	ret = __ht_create_irq(pdev, 0, ipath_ht_irq_update);
+	if (ret < 0) {
+		ipath_dev_err(dd, "Couldn't create interrupt handler: "
+			      "err %d\n", ret);
+		goto bail;
+	}
+	dd->ipath_irq = ret;
+	ret = 0;
 
 	/*
-	 * Read the capability info to find the interrupt info, and also
-	 * handle clearing CRC errors in linkctrl register if necessary.  We
+	 * Handle clearing CRC errors in linkctrl register if necessary.  We
 	 * do this early, before we ever enable errors or hardware errors,
 	 * mostly to avoid causing the chip to enter freeze mode.
 	 */
@@ -1000,17 +999,9 @@
 		}
 		if (!(cap_type & 0xE0))
 			slave_or_pri_blk(dd, pdev, pos, cap_type);
-		else if (cap_type == HT_INTR_DISC_CONFIG)
-			ihandler = set_int_handler(dd, pdev, pos);
 	} while ((pos = pci_find_next_capability(pdev, pos,
 						 PCI_CAP_ID_HT)));
 
-	if (!ihandler) {
-		ipath_dev_err(dd, "Couldn't find interrupt handler in "
-			      "config space\n");
-		ret = -ENODEV;
-	}
-
 bail:
 	return ret;
 }
@@ -1360,25 +1351,6 @@
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val);
 }
 
-static int ipath_ht_intconfig(struct ipath_devdata *dd)
-{
-	int ret;
-
-	if (!dd->ipath_intconfig) {
-		ipath_dev_err(dd, "No interrupts enabled, couldn't setup "
-			      "interrupt address\n");
-		ret = 1;
-		goto bail;
-	}
-
-	ipath_write_kreg(dd, dd->ipath_kregs->kr_interruptconfig,
-			 dd->ipath_intconfig);	/* interrupt address */
-	ret = 0;
-
-bail:
-	return ret;
-}
-
 /**
  * ipath_pe_put_tid - write a TID in chip
  * @dd: the infinipath device
@@ -1575,6 +1547,14 @@
 	return 0;
 }
 
+static void ipath_ht_free_irq(struct ipath_devdata *dd)
+{
+	free_irq(dd->ipath_irq, dd);
+	ht_destroy_irq(dd->ipath_irq);
+	dd->ipath_irq = 0;
+	dd->ipath_intconfig = 0;
+}
+
 /**
  * ipath_init_iba6110_funcs - set up the chip-specific function pointers
  * @dd: the infinipath device
@@ -1598,6 +1578,7 @@
 	dd->ipath_f_cleanup = ipath_setup_ht_cleanup;
 	dd->ipath_f_setextled = ipath_setup_ht_setextled;
 	dd->ipath_f_get_base_info = ipath_ht_get_base_info;
+	dd->ipath_f_free_irq = ipath_ht_free_irq;
 
 	/*
 	 * initialize chip-specific variables
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index a72ab9d..6af8968 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -851,6 +851,7 @@
 	int pos, ret;
 
 	dd->ipath_msi_lo = 0;	/* used as a flag during reset processing */
+	dd->ipath_irq = pdev->irq;
 	ret = pci_enable_msi(dd->pcidev);
 	if (ret)
 		ipath_dev_err(dd, "pci_enable_msi failed: %d, "
@@ -1323,6 +1324,12 @@
 	return 0;
 }
 
+static void ipath_pe_free_irq(struct ipath_devdata *dd)
+{
+	free_irq(dd->ipath_irq, dd);
+	dd->ipath_irq = 0;
+}
+
 /**
  * ipath_init_iba6120_funcs - set up the chip-specific function pointers
  * @dd: the infinipath device
@@ -1349,6 +1356,7 @@
 	dd->ipath_f_cleanup = ipath_setup_pe_cleanup;
 	dd->ipath_f_setextled = ipath_setup_pe_setextled;
 	dd->ipath_f_get_base_info = ipath_pe_get_base_info;
+	dd->ipath_f_free_irq = ipath_pe_free_irq;
 
 	/* initialize chip-specific variables */
 	dd->ipath_f_tidtemplate = ipath_pe_tidtemplate;
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index d9079ee..5652a55 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -710,14 +710,14 @@
 			 * linuxbios development work, and it may happen in
 			 * the future again.
 			 */
-			if (dd->pcidev && dd->pcidev->irq) {
+			if (dd->pcidev && dd->ipath_irq) {
 				ipath_dev_err(dd, "Now %u unexpected "
 					      "interrupts, unregistering "
 					      "interrupt handler\n",
 					      *unexpectp);
-				ipath_dbg("free_irq of irq %x\n",
-					  dd->pcidev->irq);
-				free_irq(dd->pcidev->irq, dd);
+				ipath_dbg("free_irq of irq %d\n",
+					  dd->ipath_irq);
+				dd->ipath_f_free_irq(dd);
 			}
 		}
 		if (ipath_read_kreg32(dd, dd->ipath_kregs->kr_intmask)) {
@@ -753,7 +753,7 @@
 		if (allbits == 2) {
 			ipath_dev_err(dd, "Still bad interrupt status, "
 				      "unregistering interrupt\n");
-			free_irq(dd->pcidev->irq, dd);
+			dd->ipath_f_free_irq(dd);
 		} else if (allbits > 2) {
 			if ((allbits % 10000) == 0)
 				printk(".");
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 06d5020..986b212 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -213,6 +213,8 @@
 	void (*ipath_f_setextled)(struct ipath_devdata *, u64, u64);
 	/* fill out chip-specific fields */
 	int (*ipath_f_get_base_info)(struct ipath_portdata *, void *);
+	/* free irq */
+	void (*ipath_f_free_irq)(struct ipath_devdata *);
 	struct ipath_ibdev *verbs_dev;
 	struct timer_list verbs_timer;
 	/* total dwords sent (summed from counter) */
@@ -328,6 +330,8 @@
 	/* so we can rewrite it after a chip reset */
 	u32 ipath_pcibar1;
 
+	/* interrupt number */
+	int ipath_irq;
 	/* HT/PCI Vendor ID (here for NodeInfo) */
 	u16 ipath_vendorid;
 	/* HT/PCI Device ID (here for NodeInfo) */
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 99a94d7..768df72 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1820,11 +1820,11 @@
 
 #define MAD_IFC_BOX_SIZE      0x400
 #define MAD_IFC_MY_QPN_OFFSET 0x100
-#define MAD_IFC_RQPN_OFFSET   0x104
-#define MAD_IFC_SL_OFFSET     0x108
-#define MAD_IFC_G_PATH_OFFSET 0x109
-#define MAD_IFC_RLID_OFFSET   0x10a
-#define MAD_IFC_PKEY_OFFSET   0x10e
+#define MAD_IFC_RQPN_OFFSET   0x108
+#define MAD_IFC_SL_OFFSET     0x10c
+#define MAD_IFC_G_PATH_OFFSET 0x10d
+#define MAD_IFC_RLID_OFFSET   0x10e
+#define MAD_IFC_PKEY_OFFSET   0x112
 #define MAD_IFC_GRH_OFFSET    0x140
 
 	inmailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
@@ -1862,7 +1862,7 @@
 
 		val = in_wc->dlid_path_bits |
 			(in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0);
-		MTHCA_PUT(inbox, val,               MAD_IFC_GRH_OFFSET);
+		MTHCA_PUT(inbox, val,               MAD_IFC_G_PATH_OFFSET);
 
 		MTHCA_PUT(inbox, in_wc->slid,       MAD_IFC_RLID_OFFSET);
 		MTHCA_PUT(inbox, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET);
@@ -1870,7 +1870,7 @@
 		if (in_grh)
 			memcpy(inbox + MAD_IFC_GRH_OFFSET, in_grh, 40);
 
-		op_modifier |= 0x10;
+		op_modifier |= 0x4;
 
 		in_modifier |= in_wc->slid << 16;
 	}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 1eaf00e..85522da 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -49,6 +49,8 @@
 
 #include <net/dst.h>
 
+#define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff)
+
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
 MODULE_LICENSE("Dual BSD/GPL");
@@ -520,8 +522,7 @@
 		memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,
 		       sizeof(union ib_gid));
 
-		ipoib_send(dev, skb, path->ah,
-			   be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
+		ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb->dst->neighbour->ha));
 	} else {
 		neigh->ah  = NULL;
 		__skb_queue_tail(&neigh->queue, skb);
@@ -599,8 +600,7 @@
 		ipoib_dbg(priv, "Send unicast ARP to %04x\n",
 			  be16_to_cpu(path->pathrec.dlid));
 
-		ipoib_send(dev, skb, path->ah,
-			   be32_to_cpup((__be32 *) phdr->hwaddr));
+		ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr));
 	} else if ((path->query || !path_rec_start(dev, path)) &&
 		   skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
 		/* put pseudoheader back on for next time */
@@ -661,8 +661,7 @@
 				goto out;
 			}
 
-			ipoib_send(dev, skb, neigh->ah,
-				   be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
+			ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha));
 			goto out;
 		}
 
@@ -694,7 +693,7 @@
 					   IPOIB_GID_FMT "\n",
 					   skb->dst ? "neigh" : "dst",
 					   be16_to_cpup((__be16 *) skb->data),
-					   be32_to_cpup((__be32 *) phdr->hwaddr),
+					   IPOIB_QPN(phdr->hwaddr),
 					   IPOIB_GID_RAW_ARG(phdr->hwaddr + 4));
 				dev_kfree_skb_any(skb);
 				++priv->stats.tx_dropped;
@@ -777,7 +776,7 @@
 
 	ipoib_dbg(priv,
 		  "neigh_destructor for %06x " IPOIB_GID_FMT "\n",
-		  be32_to_cpup((__be32 *) n->ha),
+		  IPOIB_QPN(n->ha),
 		  IPOIB_GID_RAW_ARG(n->ha + 4));
 
 	spin_lock_irqsave(&priv->lock, flags);
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index eb6f98d..9b2041e 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -363,11 +363,11 @@
 	struct iscsi_conn *conn = cls_conn->dd_data;
 	int err;
 
-	err = iscsi_conn_start(cls_conn);
+	err = iser_conn_set_full_featured_mode(conn);
 	if (err)
 		return err;
 
-	return iser_conn_set_full_featured_mode(conn);
+	return iscsi_conn_start(cls_conn);
 }
 
 static struct iscsi_transport iscsi_iser_transport;
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 708d5a1..979b93e 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -59,11 +59,6 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * email or by paper mail:
- * Jan-Benedict Glaw, Lilienstraße 16, 33790 Hörste (near Halle/Westf.),
- * Germany.
  */
 
 #include <linux/delay.h>
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index e31c6c5..58fca31 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -6,7 +6,7 @@
 #include <asm/io.h>
 #include <asm/delay.h>
 #include <asm/adc.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 
 #define MODNAME "hp680_ts_input"
 
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index aca165d..5800beee 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -616,7 +616,7 @@
 	} else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
 		skb_reserve(bcs->skb, HW_HDR_LEN);
 	else {
-		dev_warn(cs->dev, "could not allocate skb\n");
+		warn("could not allocate skb\n");
 		bcs->inputstate |= INS_skip_frame;
 	}
 
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index eb57a98..cfd2718 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -344,7 +344,7 @@
 
 config HISAX_ENTERNOW_PCI
 	bool "Formula-n enter:now PCI card"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
+	depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
 	help
 	  This enables HiSax support for the Formula-n enter:now PCI
 	  ISDN card.
diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c
index 1fadf01..1875877 100644
--- a/drivers/isdn/hysdn/hysdn_sched.c
+++ b/drivers/isdn/hysdn/hysdn_sched.c
@@ -155,21 +155,17 @@
 	if (card->debug_flags & LOG_SCHED_ASYN)
 		hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1);
 
-	spin_lock_irqsave(&card->hysdn_lock, flags);
 	while (card->async_busy) {
-		sti();
 
 		if (card->debug_flags & LOG_SCHED_ASYN)
 			hysdn_addlog(card, "async tx-cfg delayed");
 
 		msleep_interruptible(20);		/* Timeout 20ms */
-		if (!--cnt) {
-			spin_unlock_irqrestore(&card->hysdn_lock, flags);
+		if (!--cnt)
 			return (-ERR_ASYNC_TIME);	/* timed out */
-		}
-		cli();
 	}			/* wait for buffer to become free */
 
+	spin_lock_irqsave(&card->hysdn_lock, flags);
 	strcpy(card->async_data, line);
 	card->async_len = strlen(line) + 1;
 	card->async_channel = chan;
@@ -177,30 +173,23 @@
 
 	/* now queue the task */
 	schedule_work(&card->irq_queue);
-	sti();
+	spin_unlock_irqrestore(&card->hysdn_lock, flags);
 
 	if (card->debug_flags & LOG_SCHED_ASYN)
 		hysdn_addlog(card, "async tx-cfg data queued");
 
 	cnt++;			/* short delay */
-	cli();
 
 	while (card->async_busy) {
-		sti();
 
 		if (card->debug_flags & LOG_SCHED_ASYN)
 			hysdn_addlog(card, "async tx-cfg waiting for tx-ready");
 
 		msleep_interruptible(20);		/* Timeout 20ms */
-		if (!--cnt) {
-			spin_unlock_irqrestore(&card->hysdn_lock, flags);
+		if (!--cnt)
 			return (-ERR_ASYNC_TIME);	/* timed out */
-		}
-		cli();
 	}			/* wait for buffer to become free again */
 
-	spin_unlock_irqrestore(&card->hysdn_lock, flags);
-
 	if (card->debug_flags & LOG_SCHED_ASYN)
 		hysdn_addlog(card, "async tx-cfg data send");
 
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c
index fa4b13f..b3fbb45 100644
--- a/drivers/macintosh/windfarm_pm112.c
+++ b/drivers/macintosh/windfarm_pm112.c
@@ -685,6 +685,17 @@
 		++nr_cores;
 
 	printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n");
+
+#ifdef MODULE
+	request_module("windfarm_smu_controls");
+	request_module("windfarm_smu_sensors");
+	request_module("windfarm_smu_sat");
+	request_module("windfarm_lm75_sensor");
+	request_module("windfarm_max6690_sensor");
+	request_module("windfarm_cpufreq_clamp");
+
+#endif /* MODULE */
+
 	platform_driver_register(&wf_pm112_driver);
 	return 0;
 }
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
index 2a94485..f24fa73 100644
--- a/drivers/macintosh/windfarm_pm81.c
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -788,6 +788,7 @@
 		request_module("windfarm_smu_controls");
 		request_module("windfarm_smu_sensors");
 		request_module("windfarm_lm75_sensor");
+		request_module("windfarm_cpufreq_clamp");
 
 #endif /* MODULE */
 		platform_driver_register(&wf_smu_driver);
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c
index 9961a67..26eee69 100644
--- a/drivers/macintosh/windfarm_pm91.c
+++ b/drivers/macintosh/windfarm_pm91.c
@@ -719,6 +719,7 @@
 		request_module("windfarm_smu_controls");
 		request_module("windfarm_smu_sensors");
 		request_module("windfarm_lm75_sensor");
+		request_module("windfarm_cpufreq_clamp");
 
 #endif /* MODULE */
 		platform_driver_register(&wf_smu_driver);
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index d47d38a..d6f6147 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -536,7 +536,7 @@
 		printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) "
 			"-- forcing full recovery\n", bmname(bitmap), events,
 			(unsigned long long) bitmap->mddev->events);
-		sb->state |= BITMAP_STALE;
+		sb->state |= cpu_to_le32(BITMAP_STALE);
 	}
 success:
 	/* assign fields using values from superblock */
@@ -544,11 +544,11 @@
 	bitmap->daemon_sleep = daemon_sleep;
 	bitmap->daemon_lastrun = jiffies;
 	bitmap->max_write_behind = write_behind;
-	bitmap->flags |= sb->state;
+	bitmap->flags |= le32_to_cpu(sb->state);
 	if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
 		bitmap->flags |= BITMAP_HOSTENDIAN;
 	bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
-	if (sb->state & BITMAP_STALE)
+	if (sb->state & cpu_to_le32(BITMAP_STALE))
 		bitmap->events_cleared = bitmap->mddev->events;
 	err = 0;
 out:
@@ -578,9 +578,9 @@
 	spin_unlock_irqrestore(&bitmap->lock, flags);
 	sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
 	switch (op) {
-		case MASK_SET: sb->state |= bits;
+		case MASK_SET: sb->state |= cpu_to_le32(bits);
 				break;
-		case MASK_UNSET: sb->state &= ~bits;
+		case MASK_UNSET: sb->state &= cpu_to_le32(~bits);
 				break;
 		default: BUG();
 	}
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index a625576..08a40f4 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -915,8 +915,6 @@
 			char *result, unsigned int maxlen)
 {
 	struct crypt_config *cc = (struct crypt_config *) ti->private;
-	const char *cipher;
-	const char *chainmode = NULL;
 	unsigned int sz = 0;
 
 	switch (type) {
@@ -925,14 +923,11 @@
 		break;
 
 	case STATUSTYPE_TABLE:
-		cipher = crypto_blkcipher_name(cc->tfm);
-
-		chainmode = cc->chainmode;
-
 		if (cc->iv_mode)
-			DMEMIT("%s-%s-%s ", cipher, chainmode, cc->iv_mode);
+			DMEMIT("%s-%s-%s ", cc->cipher, cc->chainmode,
+			       cc->iv_mode);
 		else
-			DMEMIT("%s-%s ", cipher, chainmode);
+			DMEMIT("%s-%s ", cc->cipher, cc->chainmode);
 
 		if (cc->key_size > 0) {
 			if ((maxlen - sz) < ((cc->key_size << 1) + 1))
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index d13bb15..4510ad8 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -606,9 +606,14 @@
 		return __get_name_cell(param->name);
 
 	md = dm_get_md(huge_decode_dev(param->dev));
-	if (md)
-		mdptr = dm_get_mdptr(md);
+	if (!md)
+		goto out;
 
+	mdptr = dm_get_mdptr(md);
+	if (!mdptr)
+		dm_put(md);
+
+out:
 	return mdptr;
 }
 
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 659224c..48a653b 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -24,6 +24,7 @@
 
 static struct workqueue_struct *_kmirrord_wq;
 static struct work_struct _kmirrord_work;
+static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);
 
 static inline void wake(void)
 {
@@ -83,6 +84,7 @@
 	struct list_head *buckets;
 
 	spinlock_t region_lock;
+	atomic_t recovery_in_flight;
 	struct semaphore recovery_count;
 	struct list_head clean_regions;
 	struct list_head quiesced_regions;
@@ -191,6 +193,7 @@
 
 	spin_lock_init(&rh->region_lock);
 	sema_init(&rh->recovery_count, 0);
+	atomic_set(&rh->recovery_in_flight, 0);
 	INIT_LIST_HEAD(&rh->clean_regions);
 	INIT_LIST_HEAD(&rh->quiesced_regions);
 	INIT_LIST_HEAD(&rh->recovered_regions);
@@ -382,6 +385,8 @@
 		rh->log->type->clear_region(rh->log, reg->key);
 		rh->log->type->complete_resync_work(rh->log, reg->key, 1);
 		dispatch_bios(rh->ms, &reg->delayed_bios);
+		if (atomic_dec_and_test(&rh->recovery_in_flight))
+			wake_up_all(&_kmirrord_recovery_stopped);
 		up(&rh->recovery_count);
 		mempool_free(reg, rh->region_pool);
 	}
@@ -502,11 +507,21 @@
 
 static void rh_recovery_prepare(struct region_hash *rh)
 {
-	while (!down_trylock(&rh->recovery_count))
+	/* Extra reference to avoid race with rh_stop_recovery */
+	atomic_inc(&rh->recovery_in_flight);
+
+	while (!down_trylock(&rh->recovery_count)) {
+		atomic_inc(&rh->recovery_in_flight);
 		if (__rh_recovery_prepare(rh) <= 0) {
+			atomic_dec(&rh->recovery_in_flight);
 			up(&rh->recovery_count);
 			break;
 		}
+	}
+
+	/* Drop the extra reference */
+	if (atomic_dec_and_test(&rh->recovery_in_flight))
+		wake_up_all(&_kmirrord_recovery_stopped);
 }
 
 /*
@@ -1177,6 +1192,11 @@
 	struct dirty_log *log = ms->rh.log;
 
 	rh_stop_recovery(&ms->rh);
+
+	/* Wait for all I/O we generated to complete */
+	wait_event(_kmirrord_recovery_stopped,
+		   !atomic_read(&ms->rh.recovery_in_flight));
+
 	if (log->type->suspend && log->type->suspend(log))
 		/* FIXME: need better error handling */
 		DMWARN("log suspend failed");
diff --git a/drivers/md/dm-round-robin.c b/drivers/md/dm-round-robin.c
index c5a16c5..6f9fcd4 100644
--- a/drivers/md/dm-round-robin.c
+++ b/drivers/md/dm-round-robin.c
@@ -136,7 +136,7 @@
 
 	path->pscontext = pi;
 
-	list_add(&pi->list, &s->valid_paths);
+	list_add_tail(&pi->list, &s->valid_paths);
 
 	return 0;
 }
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index b5764a8..fc4f743 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1285,7 +1285,7 @@
 	down(&md->suspend_lock);
 
 	if (dm_suspended(md))
-		goto out;
+		goto out_unlock;
 
 	map = dm_get_table(md);
 
@@ -1361,6 +1361,8 @@
 	}
 
 	dm_table_put(map);
+
+out_unlock:
 	up(&md->suspend_lock);
 	return r;
 }
diff --git a/drivers/md/md.c b/drivers/md/md.c
index f7f1908..8cbf9c9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -974,12 +974,13 @@
  * version 1 superblock
  */
 
-static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
+static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb)
 {
-	unsigned int disk_csum, csum;
+	__le32 disk_csum;
+	u32 csum;
 	unsigned long long newcsum;
 	int size = 256 + le32_to_cpu(sb->max_dev)*2;
-	unsigned int *isuper = (unsigned int*)sb;
+	__le32 *isuper = (__le32*)sb;
 	int i;
 
 	disk_csum = sb->sb_csum;
@@ -989,7 +990,7 @@
 		newcsum += le32_to_cpu(*isuper++);
 
 	if (size == 2)
-		newcsum += le16_to_cpu(*(unsigned short*) isuper);
+		newcsum += le16_to_cpu(*(__le16*) isuper);
 
 	csum = (newcsum & 0xffffffff) + (newcsum >> 32);
 	sb->sb_csum = disk_csum;
@@ -1106,7 +1107,7 @@
 	if (le32_to_cpu(sb->chunksize))
 		rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
 
-	if (le32_to_cpu(sb->size) > rdev->size*2)
+	if (le64_to_cpu(sb->size) > rdev->size*2)
 		return -EINVAL;
 	return ret;
 }
@@ -1228,7 +1229,7 @@
 	else
 		sb->resync_offset = cpu_to_le64(0);
 
-	sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
+	sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
 
 	sb->raid_disks = cpu_to_le32(mddev->raid_disks);
 	sb->size = cpu_to_le64(mddev->size<<1);
@@ -2002,6 +2003,7 @@
 	kobject_init(&rdev->kobj);
 
 	rdev->desc_nr = -1;
+	rdev->saved_raid_disk = -1;
 	rdev->flags = 0;
 	rdev->data_offset = 0;
 	rdev->sb_events = 0;
@@ -3198,6 +3200,7 @@
 
 	mddev->changed = 1;
 	md_new_event(mddev);
+	kobject_uevent(&mddev->gendisk->kobj, KOBJ_CHANGE);
 	return 0;
 }
 
@@ -4043,11 +4046,8 @@
 		return -EBUSY;
 	ITERATE_RDEV(mddev,rdev,tmp) {
 		sector_t avail;
-		if (rdev->sb_offset > rdev->data_offset)
-			avail = (rdev->sb_offset*2) - rdev->data_offset;
-		else
-			avail = get_capacity(rdev->bdev->bd_disk)
-				- rdev->data_offset;
+		avail = rdev->size * 2;
+
 		if (fit && (size == 0 || size > avail/2))
 			size = avail/2;
 		if (avail < ((sector_t)size << 1))
@@ -4486,6 +4486,7 @@
 	 * many dirty RAID5 blocks.
 	 */
 
+	current->flags |= PF_NOFREEZE;
 	allow_signal(SIGKILL);
 	while (!kthread_should_stop()) {
 
@@ -4502,7 +4503,6 @@
 			 test_bit(THREAD_WAKEUP, &thread->flags)
 			 || kthread_should_stop(),
 			 thread->timeout);
-		try_to_freeze();
 
 		clear_bit(THREAD_WAKEUP, &thread->flags);
 
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 171ff41..14da37f 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -277,6 +277,7 @@
 			set_bit(Faulty, &rdev->flags);
 			set_bit(MD_CHANGE_DEVS, &mddev->flags);
 			conf->working_disks--;
+			mddev->degraded++;
 			printk(KERN_ALERT "multipath: IO failure on %s,"
 				" disabling IO path. \n	Operation continuing"
 				" on %d IO paths.\n",
@@ -336,6 +337,7 @@
 				blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
 			conf->working_disks++;
+			mddev->degraded--;
 			rdev->raid_disk = path;
 			set_bit(In_sync, &rdev->flags);
 			rcu_assign_pointer(p->rdev, rdev);
@@ -501,7 +503,7 @@
 			mdname(mddev));
 		goto out_free_conf;
 	}
-	mddev->degraded = conf->raid_disks = conf->working_disks;
+	mddev->degraded = conf->raid_disks - conf->working_disks;
 
 	conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS,
 						 sizeof(struct multipath_bh));
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index dc9d2de..656fae9 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1474,8 +1474,8 @@
 					       "raid1:%s: read error corrected "
 					       "(%d sectors at %llu on %s)\n",
 					       mdname(mddev), s,
-					       (unsigned long long)sect +
-					           rdev->data_offset,
+					       (unsigned long long)(sect +
+					           rdev->data_offset),
 					       bdevname(rdev->bdev, b));
 				}
 			}
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 1250f0e..7492d60 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1470,8 +1470,8 @@
 					       "raid10:%s: read error corrected"
 					       " (%d sectors at %llu on %s)\n",
 					       mdname(mddev), s,
-					       (unsigned long long)sect+
-					            rdev->data_offset,
+					       (unsigned long long)(sect+
+					            rdev->data_offset),
 					       bdevname(rdev->bdev, b));
 
 				rdev_dec_pending(rdev, mddev);
@@ -2079,7 +2079,7 @@
 		disk = conf->mirrors + i;
 
 		if (!disk->rdev ||
-		    !test_bit(In_sync, &rdev->flags)) {
+		    !test_bit(In_sync, &disk->rdev->flags)) {
 			disk->head_position = 0;
 			mddev->degraded++;
 		}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index e14f457..69c3e20 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3659,7 +3659,7 @@
 		bdev = bdget_disk(conf->mddev->gendisk, 0);
 		if (bdev) {
 			mutex_lock(&bdev->bd_inode->i_mutex);
-			i_size_write(bdev->bd_inode, conf->mddev->array_size << 10);
+			i_size_write(bdev->bd_inode, (loff_t)conf->mddev->array_size << 10);
 			mutex_unlock(&bdev->bd_inode->i_mutex);
 			bdput(bdev);
 		}
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index d9953f7..5297a36 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -217,11 +217,9 @@
 		}
 		/* wait until we get a transfer done or error */
 		timeout = jiffies + HZ/100 + 1; /* 10ms */
+		/* first read usually delivers bogus results... */
+		saa7146_i2c_status(dev);
 		while(1) {
-			/**
-			 *  first read usually delivers bogus results...
-			 */
-			saa7146_i2c_status(dev);
 			status = saa7146_i2c_status(dev);
 			if ((status & 0x3) != 1)
 				break;
@@ -232,10 +230,10 @@
 				DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
 				return -EIO;
 			}
-			if ((++trial < 20) && short_delay)
+			if (++trial < 50 && short_delay)
 				udelay(10);
 			else
-			msleep(1);
+				msleep(1);
 		}
 	}
 
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index 2853ea1..87fb75f 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -246,7 +246,7 @@
 	wIndex = (chipaddr << 8 ) | addr;
 
 	deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req,
-			((wValue && 0xff) << 8),wValue >> 8,((wIndex && 0xff) << 8),wIndex >> 8);
+		wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8);
 
 	len = usb_control_msg(fc_usb->udev,pipe,
 			req,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 53304e6..a2ab2ee 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -348,7 +348,7 @@
 
 static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
 {
-	fe_status_t s;
+	fe_status_t s = 0;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
 	/* if we've got no parameters, just keep idling */
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 2cc5caa..a263b3f 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -26,7 +26,7 @@
 	tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
 	depends on DVB_USB
 	select DVB_DIB3000MC
-	select DVB_TUNER_MT2060
+	select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
 
@@ -34,7 +34,7 @@
 	tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
 	depends on DVB_USB
 	select DVB_DIB3000MB
-	select DVB_TUNER_MT2060
+	select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
 	help
 	  Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
 	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
@@ -55,7 +55,7 @@
 	tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
 	depends on DVB_USB
 	select DVB_DIB3000MC
-	select DVB_TUNER_MT2060
+	select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
 	help
 	  Support for USB2.0 DVB-T receivers based on reference designs made by
 	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
@@ -70,7 +70,7 @@
 	tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
 	depends on DVB_USB
 	select DVB_DIB3000MC
-	select DVB_TUNER_MT2060
+	select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
 	help
 	  Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
 	  USB bridge is also present in devices having the DiB7700 DVB-T-USB
@@ -87,7 +87,7 @@
 	tristate "HanfTek UMT-010 DVB-T USB2.0 support"
 	depends on DVB_USB
 	select DVB_DIB3000MC
-	select DVB_TUNER_MT2060
+	select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
 
@@ -153,7 +153,7 @@
 	tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
 	depends on DVB_USB
 	select DVB_DIB3000MC
-	select DVB_TUNER_MT2060
+	select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
 
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 080fa25..aebb8d6f 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -276,6 +276,8 @@
 
 config DVB_TUNER_MT2060
 	tristate "Microtune MT2060 silicon IF tuner"
+	depends on I2C
+	default m if DVB_FE_CUSTOMISE
 	help
 	  A driver for the silicon IF tuner MT2060 from Microtune.
 
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h
index 6dfa839..7e4f95e 100644
--- a/drivers/media/dvb/frontends/bcm3510.h
+++ b/drivers/media/dvb/frontends/bcm3510.h
@@ -34,7 +34,7 @@
 	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
 };
 
-#if defined(CONFIG_DVB_BCM3510) || defined(CONFIG_DVB_BCM3510_MODULE)
+#if defined(CONFIG_DVB_BCM3510) || (defined(CONFIG_DVB_BCM3510_MODULE) && defined(MODULE))
 extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h
index 10286cc..7ac3369 100644
--- a/drivers/media/dvb/frontends/cx22700.h
+++ b/drivers/media/dvb/frontends/cx22700.h
@@ -31,7 +31,7 @@
 	u8 demod_address;
 };
 
-#if defined(CONFIG_DVB_CX22700) || defined(CONFIG_DVB_CX22700_MODULE)
+#if defined(CONFIG_DVB_CX22700) || (defined(CONFIG_DVB_CX22700_MODULE) && defined(MODULE))
 extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index bc217dd..9cd64da 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -41,7 +41,7 @@
 	u8 output_mode;
 };
 
-#if defined(CONFIG_DVB_CX22702) || defined(CONFIG_DVB_CX22702_MODULE)
+#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE))
 extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index c9d5ae2..0ca3af4 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -41,7 +41,7 @@
 	return r;
 }
 
-#if defined(CONFIG_DVB_CX24110) || defined(CONFIG_DVB_CX24110_MODULE)
+#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE))
 extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
index 57a1dae..84f9e4f 100644
--- a/drivers/media/dvb/frontends/cx24123.h
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -35,7 +35,7 @@
 	int lnb_polarity;
 };
 
-#if defined(CONFIG_DVB_CX24123) || defined(CONFIG_DVB_CX24123_MODULE)
+#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE))
 extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
index 0caac3f..a6d3854 100644
--- a/drivers/media/dvb/frontends/dib3000.h
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -41,7 +41,7 @@
 	int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
 };
 
-#if defined(CONFIG_DVB_DIB3000MB) || defined(CONFIG_DVB_DIB3000MB_MODULE)
+#if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE))
 extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
 					     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
 #else
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h
index 0d6fdef..72d4757 100644
--- a/drivers/media/dvb/frontends/dib3000mc.h
+++ b/drivers/media/dvb/frontends/dib3000mc.h
@@ -39,7 +39,7 @@
 #define DEFAULT_DIB3000MC_I2C_ADDRESS 16
 #define DEFAULT_DIB3000P_I2C_ADDRESS  24
 
-#if defined(CONFIG_DVB_DIB3000MC) || defined(CONFIG_DVB_DIB3000MC_MODULE)
+#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE))
 extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg);
 #else
 static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h
index 1916e3e..ea7f78a 100644
--- a/drivers/media/dvb/frontends/isl6421.h
+++ b/drivers/media/dvb/frontends/isl6421.h
@@ -39,7 +39,7 @@
 #define ISL6421_ISEL1	0x20
 #define ISL6421_DCL	0x40
 
-#if defined(CONFIG_DVB_ISL6421) || defined(CONFIG_DVB_ISL6421_MODULE)
+#if defined(CONFIG_DVB_ISL6421) || (defined(CONFIG_DVB_ISL6421_MODULE) && defined(MODULE))
 /* override_set and override_clear control which system register bits (above) to always set & clear */
 extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
 			  u8 override_set, u8 override_clear);
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
index 21ba4a2..cd15f76 100644
--- a/drivers/media/dvb/frontends/l64781.h
+++ b/drivers/media/dvb/frontends/l64781.h
@@ -31,7 +31,7 @@
 	u8 demod_address;
 };
 
-#if defined(CONFIG_DVB_L64781) || defined(CONFIG_DVB_L64781_MODULE)
+#if defined(CONFIG_DVB_L64781) || (defined(CONFIG_DVB_L64781_MODULE) && defined(MODULE))
 extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
 					  struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index 3f96b48..9950590 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -52,7 +52,7 @@
 	int clock_polarity_flip;
 };
 
-#if defined(CONFIG_DVB_LGDT330X) || defined(CONFIG_DVB_LGDT330X_MODULE)
+#if defined(CONFIG_DVB_LGDT330X) || (defined(CONFIG_DVB_LGDT330X_MODULE) && defined(MODULE))
 extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
 					    struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
index 1fe1dd1..68906ac 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -39,7 +39,7 @@
 
 #include <linux/dvb/frontend.h>
 
-#if defined(CONFIG_DVB_LNBP21) || defined(CONFIG_DVB_LNBP21_MODULE)
+#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE))
 /* override_set and override_clear control which system register bits (above) to always set & clear */
 extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear);
 #else
diff --git a/drivers/media/dvb/frontends/mt2060.h b/drivers/media/dvb/frontends/mt2060.h
index 34a37c2..0a86eab 100644
--- a/drivers/media/dvb/frontends/mt2060.h
+++ b/drivers/media/dvb/frontends/mt2060.h
@@ -30,6 +30,14 @@
 	u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
 };
 
+#if defined(CONFIG_DVB_TUNER_MT2060) || (defined(CONFIG_DVB_TUNER_MT2060_MODULE) && defined(MODULE))
 extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
+#else
+static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	return NULL;
+}
+#endif // CONFIG_DVB_TUNER_MT2060
 
 #endif
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
index 7112fb4..cf9a150 100644
--- a/drivers/media/dvb/frontends/mt312.h
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -34,7 +34,7 @@
 	u8 demod_address;
 };
 
-#if defined(CONFIG_DVB_MT312) || defined(CONFIG_DVB_MT312_MODULE)
+#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
 struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
 					struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
index 0035c2e..e996408 100644
--- a/drivers/media/dvb/frontends/mt352.h
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -51,7 +51,7 @@
 	int (*demod_init)(struct dvb_frontend* fe);
 };
 
-#if defined(CONFIG_DVB_MT352) || defined(CONFIG_DVB_MT352_MODULE)
+#if defined(CONFIG_DVB_MT352) || (defined(CONFIG_DVB_MT352_MODULE) && defined(MODULE))
 extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
 					 struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
index 2eb220e..28bc559 100644
--- a/drivers/media/dvb/frontends/nxt200x.h
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -45,7 +45,7 @@
 	int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
 };
 
-#if defined(CONFIG_DVB_NXT200X) || defined(CONFIG_DVB_NXT200X_MODULE)
+#if defined(CONFIG_DVB_NXT200X) || (defined(CONFIG_DVB_NXT200X_MODULE) && defined(MODULE))
 extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h
index 9397393..13d2251 100644
--- a/drivers/media/dvb/frontends/nxt6000.h
+++ b/drivers/media/dvb/frontends/nxt6000.h
@@ -33,7 +33,7 @@
 	u8 clock_inversion:1;
 };
 
-#if defined(CONFIG_DVB_NXT6000) || defined(CONFIG_DVB_NXT6000_MODULE)
+#if defined(CONFIG_DVB_NXT6000) || (defined(CONFIG_DVB_NXT6000_MODULE) && defined(MODULE))
 extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h
index 9718be4..add24f0 100644
--- a/drivers/media/dvb/frontends/or51132.h
+++ b/drivers/media/dvb/frontends/or51132.h
@@ -34,7 +34,7 @@
 	int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
 };
 
-#if defined(CONFIG_DVB_OR51132) || defined(CONFIG_DVB_OR51132_MODULE)
+#if defined(CONFIG_DVB_OR51132) || (defined(CONFIG_DVB_OR51132_MODULE) && defined(MODULE))
 extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h
index 10a5419..8aad840 100644
--- a/drivers/media/dvb/frontends/or51211.h
+++ b/drivers/media/dvb/frontends/or51211.h
@@ -37,7 +37,7 @@
 	void (*sleep)(struct dvb_frontend * fe);
 };
 
-#if defined(CONFIG_DVB_OR51211) || defined(CONFIG_DVB_OR51211_MODULE)
+#if defined(CONFIG_DVB_OR51211) || (defined(CONFIG_DVB_OR51211_MODULE) && defined(MODULE))
 extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index efc54d7..1555870 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -34,7 +34,7 @@
 	u8 invert:1;
 };
 
-#if defined(CONFIG_DVB_S5H1420) || defined(CONFIG_DVB_S5H1420_MODULE)
+#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE))
 extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
 	     struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h
index 4cf27d3..909cefe 100644
--- a/drivers/media/dvb/frontends/sp8870.h
+++ b/drivers/media/dvb/frontends/sp8870.h
@@ -35,7 +35,7 @@
 	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
 };
 
-#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE)
+#if defined(CONFIG_DVB_SP8870) || (defined(CONFIG_DVB_SP8870_MODULE) && defined(MODULE))
 extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
 					  struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h
index cab7ea6..7ee78d7 100644
--- a/drivers/media/dvb/frontends/sp887x.h
+++ b/drivers/media/dvb/frontends/sp887x.h
@@ -17,7 +17,7 @@
 	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
 };
 
-#if defined(CONFIG_DVB_SP887X) || defined(CONFIG_DVB_SP887X_MODULE)
+#if defined(CONFIG_DVB_SP887X) || (defined(CONFIG_DVB_SP887X_MODULE) && defined(MODULE))
 extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
 					  struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
index 760b80d..69f4515 100644
--- a/drivers/media/dvb/frontends/stv0297.h
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -42,7 +42,7 @@
 	u8 stop_during_read:1;
 };
 
-#if defined(CONFIG_DVB_STV0297) || defined(CONFIG_DVB_STV0297_MODULE)
+#if defined(CONFIG_DVB_STV0297) || (defined(CONFIG_DVB_STV0297_MODULE) && defined(MODULE))
 extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 7ef2520..33df949 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -89,7 +89,7 @@
 	int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
 };
 
-#if defined(CONFIG_DVB_STV0299) || defined(CONFIG_DVB_STV0299_MODULE)
+#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE))
 extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h
index d68ae20..e3da780 100644
--- a/drivers/media/dvb/frontends/tda10021.h
+++ b/drivers/media/dvb/frontends/tda10021.h
@@ -32,7 +32,7 @@
 	u8 demod_address;
 };
 
-#if defined(CONFIG_DVB_TDA10021) || defined(CONFIG_DVB_TDA10021_MODULE)
+#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
 extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
 					    struct i2c_adapter* i2c, u8 pwm);
 #else
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index e28fca0..605ad2d 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -71,7 +71,7 @@
 	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
 };
 
-#if defined(CONFIG_DVB_TDA1004X) || defined(CONFIG_DVB_TDA1004X_MODULE)
+#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE))
 extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
 					    struct i2c_adapter* i2c);
 
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
index 7456b0b..4c27a2d9 100644
--- a/drivers/media/dvb/frontends/tda10086.c
+++ b/drivers/media/dvb/frontends/tda10086.c
@@ -441,6 +441,10 @@
 
 	dprintk ("%s\n", __FUNCTION__);
 
+	// check for invalid symbol rate
+	if (fe_params->u.qpsk.symbol_rate < 500000)
+		return -EINVAL;
+
 	// calculate the updated frequency (note: we convert from Hz->kHz)
 	tmp64 = tda10086_read_byte(state, 0x52);
 	tmp64 |= (tda10086_read_byte(state, 0x51) << 8);
diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h
index 18457ad..ed584a8 100644
--- a/drivers/media/dvb/frontends/tda10086.h
+++ b/drivers/media/dvb/frontends/tda10086.h
@@ -35,7 +35,7 @@
 	u8 invert;
 };
 
-#if defined(CONFIG_DVB_TDA10086) || defined(CONFIG_DVB_TDA10086_MODULE)
+#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))
 extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
 					    struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h
index aae15bd..2d33079 100644
--- a/drivers/media/dvb/frontends/tda8083.h
+++ b/drivers/media/dvb/frontends/tda8083.h
@@ -35,7 +35,7 @@
 	u8 demod_address;
 };
 
-#if defined(CONFIG_DVB_TDA8083) || defined(CONFIG_DVB_TDA8083_MODULE)
+#if defined(CONFIG_DVB_TDA8083) || (defined(CONFIG_DVB_TDA8083_MODULE) && defined(MODULE))
 extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c
index eeab26b..34815b0 100644
--- a/drivers/media/dvb/frontends/tda826x.c
+++ b/drivers/media/dvb/frontends/tda826x.c
@@ -121,7 +121,7 @@
 	.info = {
 		.name = "Philips TDA826X",
 		.frequency_min = 950000,
-		.frequency_min = 2175000
+		.frequency_max = 2175000
 	},
 	.release = tda826x_release,
 	.sleep = tda826x_sleep,
diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb/frontends/tda826x.h
index 83998c0..ad99811 100644
--- a/drivers/media/dvb/frontends/tda826x.h
+++ b/drivers/media/dvb/frontends/tda826x.h
@@ -35,7 +35,7 @@
  * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector.
  * @return FE pointer on success, NULL on failure.
  */
-#if defined(CONFIG_DVB_TDA826X) || defined(CONFIG_DVB_TDA826X_MODULE)
+#if defined(CONFIG_DVB_TDA826X) || (defined(CONFIG_DVB_TDA826X_MODULE) && defined(MODULE))
 extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr,
 					   struct i2c_adapter *i2c,
 					   int has_loopthrough);
diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb/frontends/tua6100.h
index 8f98033..03a665e 100644
--- a/drivers/media/dvb/frontends/tua6100.h
+++ b/drivers/media/dvb/frontends/tua6100.h
@@ -34,7 +34,7 @@
 #include <linux/i2c.h>
 #include "dvb_frontend.h"
 
-#if defined(CONFIG_DVB_TUA6100) || defined(CONFIG_DVB_TUA6100_MODULE)
+#if defined(CONFIG_DVB_TUA6100) || (defined(CONFIG_DVB_TUA6100_MODULE) && defined(MODULE))
 extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c);
 #else
 static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h
index f0c9dde..e4a2a32 100644
--- a/drivers/media/dvb/frontends/ves1820.h
+++ b/drivers/media/dvb/frontends/ves1820.h
@@ -41,7 +41,7 @@
 	u8 selagc:1;
 };
 
-#if defined(CONFIG_DVB_VES1820) || defined(CONFIG_DVB_VES1820_MODULE)
+#if defined(CONFIG_DVB_VES1820) || (defined(CONFIG_DVB_VES1820_MODULE) && defined(MODULE))
 extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
 					   struct i2c_adapter* i2c, u8 pwm);
 #else
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h
index 395fed3..d507f89 100644
--- a/drivers/media/dvb/frontends/ves1x93.h
+++ b/drivers/media/dvb/frontends/ves1x93.h
@@ -40,7 +40,7 @@
 	u8 invert_pwm:1;
 };
 
-#if defined(CONFIG_DVB_VES1X93) || defined(CONFIG_DVB_VES1X93_MODULE)
+#if defined(CONFIG_DVB_VES1X93) || (defined(CONFIG_DVB_VES1X93_MODULE) && defined(MODULE))
 extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
 					   struct i2c_adapter* i2c);
 #else
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
index 79a9472..0bc0109 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -36,7 +36,7 @@
 	int parallel_ts;
 };
 
-#if defined(CONFIG_DVB_ZL10353) || defined(CONFIG_DVB_ZL10353_MODULE)
+#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
 extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
 					   struct i2c_adapter *i2c);
 #else
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 2a2e9b4..cd5ec48 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -46,7 +46,14 @@
 #include "bsbe1.h"
 #include "bsru6.h"
 
-#define DEBIADDR_IR		0x1234
+/*
+ * Regarding DEBIADDR_IR:
+ * Some CI modules hang if random addresses are read.
+ * Using address 0x4000 for the IR read means that we
+ * use the same address as for CI version, which should
+ * be a safe default.
+ */
+#define DEBIADDR_IR		0x4000
 #define DEBIADDR_CICONTROL	0x0000
 #define DEBIADDR_CIVERSION	0x4000
 #define DEBIADDR_IO		0x1000
@@ -1028,6 +1035,7 @@
 
 	case 0x1012:		// TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
 		budget_ci->tuner_pll_address = 0x60;
+		philips_tdm1316l_config.invert = 1;
 		budget_ci->budget.dvb_frontend =
 			dvb_attach(tda10046_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
 		if (budget_ci->budget.dvb_frontend) {
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index e58f039..56f1c80 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -46,6 +46,10 @@
 #include "lnbp21.h"
 #include "bsru6.h"
 
+static int diseqc_method;
+module_param(diseqc_method, int, 0444);
+MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)");
+
 static void Set22K (struct budget *budget, int state)
 {
 	struct saa7146_dev *dev=budget->dev;
@@ -382,6 +386,11 @@
 		if (budget->dvb_frontend) {
 			budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
 			budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
+			if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) {
+				budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
+				budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
+				budget->dvb_frontend->ops.set_tone = budget_set_tone;
+			}
 			break;
 		}
 		break;
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index fbe5b61..bf26755 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -186,7 +186,7 @@
 
 config VIDEO_SAA7110
 	tristate "Philips SAA7110 video decoder"
-	depends on VIDEO_V4L1
+	depends on VIDEO_V4L1 && I2C
 	---help---
 	  Support for the Philips SAA7110 video decoders.
 
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index a84903e..21ebe8f 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -4001,7 +4001,7 @@
  *      - sleep 1ms
  *      - write 0x0E
  *     read from GPIO_DATA into buf (uint_32)
- *      - if ( buf>>18 & 0x01 ) || ( buf>>19 && 0x01 != 0 )
+ *      - if ( buf>>18 & 0x01 ) || ( buf>>19 & 0x01 != 0 )
  *                error. ERROR_CPLD_Check_Failed.
  */
 /* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index ee48995..57e1c02 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -202,13 +202,19 @@
 		ir->sampling = 1;
 		break;
 	case CX88_BOARD_WINFAST_DTV2000H:
-	case CX88_BOARD_WINFAST2000XP_EXPERT:
 		ir_codes = ir_codes_winfast;
 		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0x8f8;
 		ir->mask_keyup = 0x100;
 		ir->polling = 50; /* ms */
 		break;
+	case CX88_BOARD_WINFAST2000XP_EXPERT:
+		ir_codes = ir_codes_winfast;
+		ir->gpio_addr = MO_GP0_IO;
+		ir->mask_keycode = 0x8f8;
+		ir->mask_keyup = 0x100;
+		ir->polling = 1; /* ms */
+		break;
 	case CX88_BOARD_IODATA_GVBCTV7E:
 		ir_codes = ir_codes_iodata_bctv7e;
 		ir->gpio_addr = MO_GP0_IO;
@@ -216,7 +222,7 @@
 		ir->mask_keydown = 0x02;
 		ir->polling = 5; /* ms */
 		break;
-       case CX88_BOARD_PROLINK_PLAYTVPVR:
+	case CX88_BOARD_PROLINK_PLAYTVPVR:
 	case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
 		ir_codes = ir_codes_pixelview;
 		ir->gpio_addr = MO_GP1_IO;
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index f786ab1..86e353b 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -1182,8 +1182,6 @@
 	video_set_drvdata(cam->v4ldev, NULL);
 	video_unregister_device(cam->v4ldev);
 
-	usb_put_dev(cam->usbdev);
-
 	mutex_unlock(&et61x251_sysfs_lock);
 
 	kfree(cam->control_buffer);
@@ -1275,6 +1273,7 @@
 
 	if (cam->state & DEV_DISCONNECTED) {
 		et61x251_release_resources(cam);
+		usb_put_dev(cam->usbdev);
 		mutex_unlock(&cam->dev_mutex);
 		kfree(cam);
 		return 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index df8feac..c80c26b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -221,7 +221,7 @@
 static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
 {
 	int ret;
-	ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0);
+	ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
 	pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
 }
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 97e974d..bb40e90 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -711,8 +711,8 @@
 	       dip->devbase.minor,pvr2_config_get_name(dip->config));
 
 	/* Paranoia */
-	dip->v4lp = 0;
-	dip->stream = 0;
+	dip->v4lp = NULL;
+	dip->stream = NULL;
 
 	/* Actual deallocation happens later when all internal references
 	   are gone. */
@@ -1076,7 +1076,7 @@
 	vp->vdev = kmalloc(sizeof(*vp->vdev),GFP_KERNEL);
 	if (!vp->vdev) {
 		kfree(vp);
-		return 0;
+		return NULL;
 	}
 	memset(vp->vdev,0,sizeof(*vp->vdev));
 	pvr2_channel_init(&vp->channel,mnp);
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index a81285c..7b9859c 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -212,8 +212,10 @@
 	if (rd_blocks > s->block_count)
 		rd_blocks = s->block_count;
 
-	if (!rd_blocks)
+	if (!rd_blocks) {
+		spin_unlock_irqrestore(&s->lock, flags);
 		return;
+	}
 
 	for (i = 0; i < rd_blocks; i++) {
 		if (block_to_user_buf(s, buf_ptr)) {
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index c5719f7..f28398d 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1464,8 +1464,6 @@
 	client->driver = &i2c_driver_saa711x;
 	snprintf(client->name, sizeof(client->name) - 1, "saa7115");
 
-	v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1);
-
 	for (i=0;i<0x0f;i++) {
 		saa711x_write(client, 0, i);
 		name[i] = (saa711x_read(client, 0) &0x0f) +'0';
@@ -1477,6 +1475,13 @@
 	saa711x_write(client, 0, 5);
 	chip_id = saa711x_read(client, 0) & 0x0f;
 
+	/* Check whether this chip is part of the saa711x series */
+	if (memcmp(name, "1f711", 5)) {
+		v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
+			address << 1, name);
+		return 0;
+	}
+
 	snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id);
 	v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name);
 
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index c9d8e3b..51f0cfd 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -2969,7 +2969,7 @@
 		/* Petr Baudis <pasky@ucw.cz> */
 		.name           = "AVerMedia TV Hybrid A16AR",
 		.audio_clock    = 0x187de7,
-		.tuner_type     = TUNER_PHILIPS_TDA8290, /* untested */
+		.tuner_type     = TUNER_PHILIPS_TD1316, /* untested */
 		.radio_type     = TUNER_TEA5767, /* untested */
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
@@ -3718,6 +3718,7 @@
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
 	case SAA7134_BOARD_AVERMEDIA_307:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
+	case SAA7134_BOARD_AVERMEDIA_777:
 /*      case SAA7134_BOARD_SABRENT_SBTTVFM:  */ /* not finished yet */
 	case SAA7134_BOARD_VIDEOMATE_TV_PVR:
 	case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
@@ -3734,6 +3735,7 @@
 	case SAA7134_BOARD_FLYDVBT_LR301:
 	case SAA7134_BOARD_FLYDVBTDUO:
 	case SAA7134_BOARD_PROTEUS_2309:
+	case SAA7134_BOARD_AVERMEDIA_A16AR:
 		dev->has_remote = SAA7134_REMOTE_GPIO;
 		break;
 	case SAA7134_BOARD_FLYDVBS_LR300:
@@ -3772,7 +3774,6 @@
 		saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
 		saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00);
 		break;
-	case SAA7134_BOARD_AVERMEDIA_A16AR:
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS:
 		/* power-up tuner chip */
 		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0xffffffff, 0xffffffff);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 1ba53b5..6b61d9b 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1147,6 +1147,8 @@
 					       &philips_europa_config,
 					       &dev->i2c_adap);
 		if (dev->dvb.frontend) {
+			dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
+			dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
 			dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
 			dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
 			dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index ff59911..dee8355 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -185,7 +185,6 @@
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
-	case SAA7134_BOARD_AVERMEDIA_A16AR:
 		ir_codes     = ir_codes_avermedia;
 		mask_keycode = 0x0007C8;
 		mask_keydown = 0x000010;
@@ -194,6 +193,16 @@
 		saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
 		saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
 		break;
+	case SAA7134_BOARD_AVERMEDIA_777:
+	case SAA7134_BOARD_AVERMEDIA_A16AR:
+		ir_codes     = ir_codes_avermedia;
+		mask_keycode = 0x02F200;
+		mask_keydown = 0x000400;
+		polling      = 50; // ms
+		/* Without this we won't receive key up events */
+		saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
+		saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
+		break;
 	case SAA7134_BOARD_KWORLD_TERMINATOR:
 		ir_codes     = ir_codes_pixelview;
 		mask_keycode = 0x00001f;
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index a4702d3..42fb60d 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -1462,8 +1462,6 @@
 	video_set_drvdata(cam->v4ldev, NULL);
 	video_unregister_device(cam->v4ldev);
 
-	usb_put_dev(cam->usbdev);
-
 	mutex_unlock(&sn9c102_sysfs_lock);
 
 	kfree(cam->control_buffer);
@@ -1555,6 +1553,7 @@
 
 	if (cam->state & DEV_DISCONNECTED) {
 		sn9c102_release_resources(cam);
+		usb_put_dev(cam->usbdev);
 		mutex_unlock(&cam->dev_mutex);
 		kfree(cam);
 		return 0;
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index e6baaee..6b9ef73 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -468,7 +468,7 @@
 				(eeprom_data[i+6] << 8) +
 				(eeprom_data[i+7] << 16);
 
-				if ( (eeprom_data[i + 8] && 0xf0) &&
+				if ( (eeprom_data[i + 8] & 0xf0) &&
 					(tvee->serial_number < 0xffffff) ) {
 					tvee->MAC_address[0] = 0x00;
 					tvee->MAC_address[1] = 0x0D;
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index c537d71..a4afad4 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -75,8 +75,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.04.01"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.01"
+#define MPT_LINUX_VERSION_COMMON	"3.04.02"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.02"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index e57bb03..1dd4917 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -96,6 +96,10 @@
 static void mptfc_target_destroy(struct scsi_target *starget);
 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
 static void __devexit mptfc_remove(struct pci_dev *pdev);
+static int mptfc_abort(struct scsi_cmnd *SCpnt);
+static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
+static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
+static int mptfc_host_reset(struct scsi_cmnd *SCpnt);
 
 static struct scsi_host_template mptfc_driver_template = {
 	.module				= THIS_MODULE,
@@ -110,10 +114,10 @@
 	.target_destroy			= mptfc_target_destroy,
 	.slave_destroy			= mptscsih_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
-	.eh_abort_handler		= mptscsih_abort,
-	.eh_device_reset_handler	= mptscsih_dev_reset,
-	.eh_bus_reset_handler		= mptscsih_bus_reset,
-	.eh_host_reset_handler		= mptscsih_host_reset,
+	.eh_abort_handler		= mptfc_abort,
+	.eh_device_reset_handler	= mptfc_dev_reset,
+	.eh_bus_reset_handler		= mptfc_bus_reset,
+	.eh_host_reset_handler		= mptfc_host_reset,
 	.bios_param			= mptscsih_bios_param,
 	.can_queue			= MPT_FC_CAN_QUEUE,
 	.this_id			= -1,
@@ -171,6 +175,77 @@
 	.show_host_symbolic_name = 1,
 };
 
+static int
+mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
+			  int (*func)(struct scsi_cmnd *SCpnt),
+			  const char *caller)
+{
+	struct scsi_device	*sdev = SCpnt->device;
+	struct Scsi_Host	*shost = sdev->host;
+	struct fc_rport		*rport = starget_to_rport(scsi_target(sdev));
+	unsigned long		flags;
+	int			ready;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) {
+		spin_unlock_irqrestore(shost->host_lock, flags);
+		dfcprintk ((MYIOC_s_INFO_FMT
+			"mptfc_block_error_handler.%d: %d:%d, port status is "
+			"DID_IMM_RETRY, deferring %s recovery.\n",
+			((MPT_SCSI_HOST *) shost->hostdata)->ioc->name,
+			((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no,
+			SCpnt->device->id,SCpnt->device->lun,caller));
+		msleep(1000);
+		spin_lock_irqsave(shost->host_lock, flags);
+	}
+	spin_unlock_irqrestore(shost->host_lock, flags);
+
+	if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) {
+		dfcprintk ((MYIOC_s_INFO_FMT
+			"%s.%d: %d:%d, failing recovery, "
+			"port state %d, vdev %p.\n", caller,
+			((MPT_SCSI_HOST *) shost->hostdata)->ioc->name,
+			((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no,
+			SCpnt->device->id,SCpnt->device->lun,ready,
+			SCpnt->device->hostdata));
+		return FAILED;
+	}
+	dfcprintk ((MYIOC_s_INFO_FMT
+		"%s.%d: %d:%d, executing recovery.\n", caller,
+		((MPT_SCSI_HOST *) shost->hostdata)->ioc->name,
+		((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no,
+		SCpnt->device->id,SCpnt->device->lun));
+	return (*func)(SCpnt);
+}
+
+static int
+mptfc_abort(struct scsi_cmnd *SCpnt)
+{
+	return
+	    mptfc_block_error_handler(SCpnt, mptscsih_abort, __FUNCTION__);
+}
+
+static int
+mptfc_dev_reset(struct scsi_cmnd *SCpnt)
+{
+	return
+	    mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __FUNCTION__);
+}
+
+static int
+mptfc_bus_reset(struct scsi_cmnd *SCpnt)
+{
+	return
+	    mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __FUNCTION__);
+}
+
+static int
+mptfc_host_reset(struct scsi_cmnd *SCpnt)
+{
+	return
+	    mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __FUNCTION__);
+}
+
 static void
 mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
 {
@@ -562,6 +637,12 @@
 		return 0;
 	}
 
+	if (!SCpnt->device->hostdata) {	/* vdev */
+		SCpnt->result = DID_NO_CONNECT << 16;
+		done(SCpnt);
+		return 0;
+	}
+
 	/* dd_data is null until finished adding target */
 	ri = *((struct mptfc_rport_info **)rport->dd_data);
 	if (unlikely(!ri)) {
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 91f95d1..a235064 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -124,10 +124,10 @@
 int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
 			  unsigned long timeout, struct i2o_dma *dma)
 {
-	DECLARE_WAIT_QUEUE_HEAD(wq);
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
 	struct i2o_exec_wait *wait;
 	static u32 tcntxt = 0x80000000;
-	long flags;
+	unsigned long flags;
 	int rc = 0;
 
 	wait = i2o_exec_wait_alloc();
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b6c045d..00db31c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -30,6 +30,7 @@
 
 config SGI_IOC4
 	tristate "SGI IOC4 Base IO support"
+	depends on PCI
 	---help---
 	  This option enables basic support for the IOC4 chip on certain
 	  SGI IO controller cards (IO9, IO10, and PCI-RT).  This option
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index 1c3c14a..b995a15 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -32,6 +32,7 @@
 #include <linux/ktime.h>
 #include <linux/mutex.h>
 #include <linux/time.h>
+#include <asm/io.h>
 
 /***************
  * Definitions *
@@ -209,8 +210,8 @@
 
 		do_div(ns, IOC4_EXTINT_COUNT_DIVISOR);
 		printk(KERN_DEBUG
-		       "IOC4 %s: PCI clock is %lld ns.\n",
-		       pci_name(idd->idd_pdev), ns);
+		       "IOC4 %s: PCI clock is %llu ns.\n",
+		       pci_name(idd->idd_pdev), (unsigned long long)ns);
 	}
 
 	/* Remember results.  We store the extint clock period rather
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index bbdba7b..db9d7df 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -44,12 +44,14 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/fs.h>
 #include <linux/module.h>
+#include <linux/buffer_head.h>
 #include <linux/kprobes.h>
-#include <linux/kallsyms.h>
+#include <linux/list.h>
 #include <linux/init.h>
-#include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/hrtimer.h>
 #include <scsi/scsi_cmnd.h>
 
 #ifdef CONFIG_IDE
@@ -116,16 +118,16 @@
 static int count = DEFAULT_COUNT;
 
 module_param(recur_count, int, 0644);
-MODULE_PARM_DESC(recur_count, "Recurcion level for the stack overflow test,\
-				 default is 10");
+MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\
+				 "default is 10");
 module_param(cpoint_name, charp, 0644);
-MODULE_PARM_DESC(cpoint_name, "Crash Point, where kernel is to be crashed");
-module_param(cpoint_type, charp, 06444);
-MODULE_PARM_DESC(cpoint_type, "Crash Point Type, action to be taken on\
-				hitting the crash point");
-module_param(cpoint_count, int, 06444);
-MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \
-				crash point is to be hit to trigger action");
+MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed");
+module_param(cpoint_type, charp, 0644);
+MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\
+				"hitting the crash point");
+module_param(cpoint_count, int, 0644);
+MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\
+				"crash point is to be hit to trigger action");
 
 unsigned int jp_do_irq(unsigned int irq)
 {
@@ -155,8 +157,8 @@
 
 struct scan_control;
 
-unsigned long jp_shrink_page_list(struct list_head *page_list,
-                                        struct scan_control *sc)
+unsigned long jp_shrink_inactive_list(unsigned long max_scan,
+				struct zone *zone, struct scan_control *sc)
 {
 	lkdtm_handler();
 	jprobe_return();
@@ -295,8 +297,8 @@
 		lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block;
 		break;
 	case MEM_SWAPOUT:
-		lkdtm.kp.symbol_name = "shrink_page_list";
-		lkdtm.entry = (kprobe_opcode_t*) jp_shrink_page_list;
+		lkdtm.kp.symbol_name = "shrink_inactive_list";
+		lkdtm.entry = (kprobe_opcode_t*) jp_shrink_inactive_list;
 		break;
 	case TIMERADD:
 		lkdtm.kp.symbol_name = "hrtimer_start";
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index ee8863c..766bc544 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -475,7 +475,7 @@
 	if (bit) {
 		bit -= 1;
 
-		ocr = 3 << bit;
+		ocr &= 3 << bit;
 
 		host->ios.vdd = bit;
 		mmc_set_ios(host);
@@ -1178,14 +1178,29 @@
 {
 	struct mmc_host *host = data;
 	struct list_head *l, *n;
+	unsigned char power_mode;
 
 	mmc_claim_host(host);
 
-	if (host->ios.power_mode == MMC_POWER_ON)
+	/*
+	 * Check for removed cards and newly inserted ones. We check for
+	 * removed cards first so we can intelligently re-select the VDD.
+	 */
+	power_mode = host->ios.power_mode;
+	if (power_mode == MMC_POWER_ON)
 		mmc_check_cards(host);
 
 	mmc_setup(host);
 
+	/*
+	 * Some broken cards process CMD1 even in stand-by state. There is
+	 * no reply, but an ILLEGAL_COMMAND error is cached and returned
+	 * after next command. We poll for card status here to clear any
+	 * possibly pending error.
+	 */
+	if (power_mode == MMC_POWER_ON)
+		mmc_check_cards(host);
+
 	if (!list_empty(&host->cards)) {
 		/*
 		 * (Re-)calculate the fastest clock rate which the
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index 2bacff6..0fdc55b 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -14,6 +14,7 @@
 #include <linux/mmc/protocol.h>
 #include <linux/mmc/host.h>
 #include <linux/highmem.h>
+#include <asm/io.h>
 
 #define DRIVER_NAME "tifm_sd"
 #define DRIVER_VERSION "0.6"
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 11de545..f69184a 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -1086,7 +1086,7 @@
 		}
 		spin_lock(chip->mutex);
 
-		if (chip->state != chip_state) {
+		while (chip->state != chip_state) {
 			/* Someone's suspended the operation: sleep */
 			DECLARE_WAITQUEUE(wait, current);
 			set_current_state(TASK_UNINTERRUPTIBLE);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index eed3271..dfe56e0 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1493,6 +1493,7 @@
  * @buf:	the data to write
  * @page:	page number to write
  * @cached:	cached programming
+ * @raw:	use _raw version of write_page
  */
 static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 			   const uint8_t *buf, int page, int cached, int raw)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ab92cc7..6e863aa 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -486,7 +486,7 @@
 
 config MIPS_SIM_NET
 	tristate "MIPS simulator Network device (EXPERIMENTAL)"
-	depends on NETDEVICES && MIPS_SIM && EXPERIMENTAL
+	depends on MIPS_SIM && EXPERIMENTAL
 	help
 	  The MIPSNET device is a simple Ethernet network device which is
 	  emulated by the MIPS Simulator.
@@ -2112,7 +2112,7 @@
 
 config SKY2
 	tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
-	depends on PCI && EXPERIMENTAL
+	depends on PCI
 	select CRC32
 	---help---
 	  This driver supports Gigabit Ethernet adapters based on the
@@ -2120,8 +2120,8 @@
 	  Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
 	  88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
 
-	  This driver does not support the original Yukon chipset: a seperate
-	  driver, skge, is provided for Yukon-based adapters.
+	  There is companion driver for the older Marvell Yukon and
+	  Genesis based adapters: skge.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called sky2.  This is recommended.
@@ -2288,7 +2288,7 @@
 
 config UGETH_HAS_GIGA
 	bool
-	depends on UCC_GETH && MPC836x
+	depends on UCC_GETH && PPC_MPC836x
 
 config MV643XX_ETH
 	tristate "MV-643XX Ethernet support"
@@ -2467,7 +2467,7 @@
 
 config RIONET
 	tristate "RapidIO Ethernet over messaging driver support"
-	depends on NETDEVICES && RAPIDIO
+	depends on RAPIDIO
 
 config RIONET_TX_SIZE
 	int "Number of outbound queue entries"
@@ -2717,6 +2717,7 @@
        select CRYPTO
        select CRYPTO_SHA1
        select CRYPTO_ARC4
+       select CRYPTO_ECB
        ---help---
          Support for the MPPE Encryption protocol, as employed by the
 	 Microsoft Point-to-Point Tunneling Protocol.
@@ -2832,7 +2833,7 @@
 	  "SCSI generic support".
 
 config SHAPER
-	tristate "Traffic Shaper (EXPERIMENTAL)"
+	tristate "Traffic Shaper (OBSOLETE)"
 	depends on EXPERIMENTAL
 	---help---
 	  The traffic shaper is a virtual network device that allows you to
@@ -2841,9 +2842,9 @@
 	  these virtual devices. See
 	  <file:Documentation/networking/shaper.txt> for more information.
 
-	  An alternative to this traffic shaper is the experimental
-	  Class-Based Queuing (CBQ) scheduling support which you get if you
-	  say Y to "QoS and/or fair queuing" above.
+	  An alternative to this traffic shaper are traffic schedulers which
+	  you'll get if you say Y to "QoS and/or fair queuing" in
+	  "Networking options".
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called shaper.  If unsure, say N.
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 0dc70c7..aa9dd8f 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -337,13 +337,16 @@
 	}
 }
 
-#ifdef MODULE
-
+#if defined(CONFIG_ARCNET_COM20020_PCI_MODULE) || \
+    defined(CONFIG_ARCNET_COM20020_ISA_MODULE)
 EXPORT_SYMBOL(com20020_check);
 EXPORT_SYMBOL(com20020_found);
+#endif
 
 MODULE_LICENSE("GPL");
 
+#ifdef MODULE
+
 int init_module(void)
 {
 	BUGLVL(D_NORMAL) printk(VERSION);
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 127561c..8ebd68e 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -193,12 +193,9 @@
 static int ep93xx_rx(struct net_device *dev, int *budget)
 {
 	struct ep93xx_priv *ep = netdev_priv(dev);
-	int tail_offset;
 	int rx_done;
 	int processed;
 
-	tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr;
-
 	rx_done = 0;
 	processed = 0;
 	while (*budget > 0) {
@@ -211,36 +208,28 @@
 
 		entry = ep->rx_pointer;
 		rstat = ep->descs->rstat + entry;
-		if ((void *)rstat - (void *)ep->descs == tail_offset) {
+
+		rstat0 = rstat->rstat0;
+		rstat1 = rstat->rstat1;
+		if (!(rstat0 & RSTAT0_RFP) || !(rstat1 & RSTAT1_RFP)) {
 			rx_done = 1;
 			break;
 		}
 
-		rstat0 = rstat->rstat0;
-		rstat1 = rstat->rstat1;
 		rstat->rstat0 = 0;
 		rstat->rstat1 = 0;
 
-		if (!(rstat0 & RSTAT0_RFP))
-			printk(KERN_CRIT "ep93xx_rx: buffer not done "
-					 " %.8x %.8x\n", rstat0, rstat1);
 		if (!(rstat0 & RSTAT0_EOF))
 			printk(KERN_CRIT "ep93xx_rx: not end-of-frame "
 					 " %.8x %.8x\n", rstat0, rstat1);
 		if (!(rstat0 & RSTAT0_EOB))
 			printk(KERN_CRIT "ep93xx_rx: not end-of-buffer "
 					 " %.8x %.8x\n", rstat0, rstat1);
-		if (!(rstat1 & RSTAT1_RFP))
-			printk(KERN_CRIT "ep93xx_rx: buffer1 not done "
-					 " %.8x %.8x\n", rstat0, rstat1);
 		if ((rstat1 & RSTAT1_BUFFER_INDEX) >> 16 != entry)
 			printk(KERN_CRIT "ep93xx_rx: entry mismatch "
 					 " %.8x %.8x\n", rstat0, rstat1);
 
 		if (!(rstat0 & RSTAT0_RWE)) {
-			printk(KERN_NOTICE "ep93xx_rx: receive error "
-					 " %.8x %.8x\n", rstat0, rstat1);
-
 			ep->stats.rx_errors++;
 			if (rstat0 & RSTAT0_OE)
 				ep->stats.rx_fifo_errors++;
@@ -301,13 +290,8 @@
 
 static int ep93xx_have_more_rx(struct ep93xx_priv *ep)
 {
-	struct ep93xx_rstat *rstat;
-	int tail_offset;
-
-	rstat = ep->descs->rstat + ep->rx_pointer;
-	tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr;
-
-	return !((void *)rstat - (void *)ep->descs == tail_offset);
+	struct ep93xx_rstat *rstat = ep->descs->rstat + ep->rx_pointer;
+	return !!((rstat->rstat0 & RSTAT0_RFP) && (rstat->rstat1 & RSTAT1_RFP));
 }
 
 static int ep93xx_poll(struct net_device *dev, int *budget)
@@ -347,7 +331,7 @@
 	struct ep93xx_priv *ep = netdev_priv(dev);
 	int entry;
 
-	if (unlikely(skb->len) > MAX_PKT_SIZE) {
+	if (unlikely(skb->len > MAX_PKT_SIZE)) {
 		ep->stats.tx_dropped++;
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
@@ -379,10 +363,8 @@
 static void ep93xx_tx_complete(struct net_device *dev)
 {
 	struct ep93xx_priv *ep = netdev_priv(dev);
-	int tail_offset;
 	int wake;
 
-	tail_offset = rdl(ep, REG_TXSTSQCURADD) - ep->descs_dma_addr;
 	wake = 0;
 
 	spin_lock(&ep->tx_pending_lock);
@@ -393,15 +375,13 @@
 
 		entry = ep->tx_clean_pointer;
 		tstat = ep->descs->tstat + entry;
-		if ((void *)tstat - (void *)ep->descs == tail_offset)
-			break;
 
 		tstat0 = tstat->tstat0;
+		if (!(tstat0 & TSTAT0_TXFP))
+			break;
+
 		tstat->tstat0 = 0;
 
-		if (!(tstat0 & TSTAT0_TXFP))
-			printk(KERN_CRIT "ep93xx_tx_complete: buffer not done "
-					 " %.8x\n", tstat0);
 		if (tstat0 & TSTAT0_FA)
 			printk(KERN_CRIT "ep93xx_tx_complete: frame aborted "
 					 " %.8x\n", tstat0);
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 4873dc6..7db3c8a 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -102,7 +102,7 @@
 // externs
 extern int get_ethernet_addr(char *ethernet_addr);
 extern void str2eaddr(unsigned char *ea, unsigned char *str);
-extern char * __init prom_getcmdline(void);
+extern char * prom_getcmdline(void);
 
 /*
  * Theory of operation
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 1ec2174..474a4e34 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -908,8 +908,9 @@
 	istat = br32(bp, B44_ISTAT);
 	imask = br32(bp, B44_IMASK);
 
-	/* ??? What the fuck is the purpose of the interrupt mask
-	 * ??? register if we have to mask it out by hand anyways?
+	/* The interrupt mask register controls which interrupt bits
+	 * will actually raise an interrupt to the CPU when set by hw/firmware,
+	 * but doesn't mask off the bits.
 	 */
 	istat &= imask;
 	if (istat) {
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c0bbdda..17a4611 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4692,6 +4692,8 @@
 	return 0;
 }
 
+static struct lock_class_key bonding_netdev_xmit_lock_key;
+
 /* Create a new bond based on the specified name and bonding parameters.
  * Caller must NOT hold rtnl_lock; we need to release it here before we
  * set up our sysfs entries.
@@ -4727,6 +4729,9 @@
 	if (res < 0) {
 		goto out_bond;
 	}
+
+	lockdep_set_class(&bond_dev->_xmit_lock, &bonding_netdev_xmit_lock_key);
+
 	if (newbond)
 		*newbond = bond_dev->priv;
 
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 966b563..a03d781 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -509,6 +509,8 @@
 		 * does not share cacheline with any other data (to avoid cache bug)
 		 */
 		RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES);
+		if (!RxDescList[i].skb)
+			return -ENOMEM;
 		RxDescList[i].descr.ctrl   = 0;
 		RxDescList[i].descr.sw_len = MAX_MEDIA_DATA_SIZE;
 		RxDescList[i].descr.next   = virt_to_phys(&RxDescList[i + 1]);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index a3a08a5d..19ab344 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2719,7 +2719,10 @@
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
 
-	netif_poll_disable(nic->netdev);
+#ifdef CONFIG_E100_NAPI
+	if (netif_running(netdev))
+		netif_poll_disable(nic->netdev);
+#endif
 	del_timer_sync(&nic->watchdog);
 	netif_carrier_off(nic->netdev);
 
@@ -2763,7 +2766,10 @@
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
 
-	netif_poll_disable(nic->netdev);
+#ifdef CONFIG_E100_NAPI
+	if (netif_running(netdev))
+		netif_poll_disable(nic->netdev);
+#endif
 	del_timer_sync(&nic->watchdog);
 	netif_carrier_off(nic->netdev);
 
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 773821e..c564adb 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -461,7 +461,8 @@
 	regs_buff[24] = (uint32_t)phy_data;  /* phy local receiver status */
 	regs_buff[25] = regs_buff[24];  /* phy remote receiver status */
 	if (hw->mac_type >= e1000_82540 &&
-	   hw->media_type == e1000_media_type_copper) {
+	    hw->mac_type < e1000_82571 &&
+	    hw->media_type == e1000_media_type_copper) {
 		regs_buff[26] = E1000_READ_REG(hw, MANC);
 	}
 }
@@ -1690,6 +1691,7 @@
 	int retval = 1; /* fail by default */
 
 	switch (hw->device_id) {
+	case E1000_DEV_ID_82542:
 	case E1000_DEV_ID_82543GC_FIBER:
 	case E1000_DEV_ID_82543GC_COPPER:
 	case E1000_DEV_ID_82544EI_FIBER:
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 112447f..449a603 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1961,9 +1961,9 @@
 #define E1000_RXDCTL_GRAN    0x01000000 /* RXDCTL Granularity */
 
 /* Transmit Descriptor Control */
-#define E1000_TXDCTL_PTHRESH 0x000000FF /* TXDCTL Prefetch Threshold */
-#define E1000_TXDCTL_HTHRESH 0x0000FF00 /* TXDCTL Host Threshold */
-#define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */
+#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
+#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */
+#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */
 #define E1000_TXDCTL_GRAN    0x01000000 /* TXDCTL Granularity */
 #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
 #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index ce0d35f..726ec5e 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -35,7 +35,7 @@
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION "7.2.9-k2"DRIVERNAPI
+#define DRV_VERSION "7.2.9-k4"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
 static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
 
@@ -699,7 +699,10 @@
 		                    phy_data);
 	}
 
-	if ((adapter->en_mng_pt) && (adapter->hw.mac_type < e1000_82571)) {
+	if ((adapter->en_mng_pt) &&
+	    (adapter->hw.mac_type >= e1000_82540) &&
+	    (adapter->hw.mac_type < e1000_82571) &&
+	    (adapter->hw.media_type == e1000_media_type_copper)) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
 		E1000_WRITE_REG(&adapter->hw, MANC, manc);
@@ -1076,8 +1079,9 @@
 
 	flush_scheduled_work();
 
-	if (adapter->hw.mac_type < e1000_82571 &&
-	   adapter->hw.media_type == e1000_media_type_copper) {
+	if (adapter->hw.mac_type >= e1000_82540 &&
+	    adapter->hw.mac_type < e1000_82571 &&
+	    adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		if (manc & E1000_MANC_SMBUS_EN) {
 			manc |= E1000_MANC_ARP_EN;
@@ -1804,9 +1808,11 @@
 	 * followed by the page buffers.  Therefore, skb->data is
 	 * sized to hold the largest protocol header.
 	 */
+	/* allocations using alloc_page take too long for regular MTU
+	 * so only enable packet split for jumbo frames */
 	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-	if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) &&
-	    PAGE_SIZE <= 16384)
+	if ((adapter->hw.mac_type >= e1000_82571) && (pages <= 3) &&
+	    PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE))
 		adapter->rx_ps_pages = pages;
 	else
 		adapter->rx_ps_pages = 0;
@@ -2986,6 +2992,11 @@
 		return NETDEV_TX_OK;
 	}
 
+	/* 82571 and newer doesn't need the workaround that limited descriptor
+	 * length to 4kB */
+	if (adapter->hw.mac_type >= e1000_82571)
+		max_per_txd = 8192;
+
 #ifdef NETIF_F_TSO
 	mss = skb_shinfo(skb)->gso_size;
 	/* The controller does a simple calculation to
@@ -3775,9 +3786,6 @@
 
 		length = le16_to_cpu(rx_desc->length);
 
-		/* adjust length to remove Ethernet CRC */
-		length -= 4;
-
 		if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
 			/* All receives must fit into a single buffer */
 			E1000_DBG("%s: Receive packet consumed multiple"
@@ -3805,6 +3813,10 @@
 			}
 		}
 
+		/* adjust length to remove Ethernet CRC, this must be
+		 * done after the TBI_ACCEPT workaround above */
+		length -= 4;
+
 		/* code added for copybreak, this should improve
 		 * performance for small packets with large amounts
 		 * of reassembly being done in the stack */
@@ -4773,8 +4785,9 @@
 		pci_enable_wake(pdev, PCI_D3cold, 0);
 	}
 
-	if (adapter->hw.mac_type < e1000_82571 &&
-	   adapter->hw.media_type == e1000_media_type_copper) {
+	if (adapter->hw.mac_type >= e1000_82540 &&
+	    adapter->hw.mac_type < e1000_82571 &&
+	    adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		if (manc & E1000_MANC_SMBUS_EN) {
 			manc |= E1000_MANC_ARP_EN;
@@ -4787,6 +4800,9 @@
 	if (adapter->hw.phy_type == e1000_phy_igp_3)
 		e1000_phy_powerdown_workaround(&adapter->hw);
 
+	if (netif_running(netdev))
+		e1000_free_irq(adapter);
+
 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
 	 * would have already happened in close and is redundant. */
 	e1000_release_hw_control(adapter);
@@ -4817,6 +4833,10 @@
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3cold, 0);
 
+	if (netif_running(netdev) && (err = e1000_request_irq(adapter)))
+		return err;
+
+	e1000_power_up_phy(adapter);
 	e1000_reset(adapter);
 	E1000_WRITE_REG(&adapter->hw, WUS, ~0);
 
@@ -4825,8 +4845,9 @@
 
 	netif_device_attach(netdev);
 
-	if (adapter->hw.mac_type < e1000_82571 &&
-	   adapter->hw.media_type == e1000_media_type_copper) {
+	if (adapter->hw.mac_type >= e1000_82540 &&
+	    adapter->hw.mac_type < e1000_82571 &&
+	    adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		manc &= ~(E1000_MANC_ARP_EN);
 		E1000_WRITE_REG(&adapter->hw, MANC, manc);
@@ -4914,10 +4935,6 @@
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3cold, 0);
 
-	/* Perform card reset only on one instance of the card */
-	if (PCI_FUNC (pdev->devfn) != 0)
-		return PCI_ERS_RESULT_RECOVERED;
-
 	e1000_reset(adapter);
 	E1000_WRITE_REG(&adapter->hw, WUS, ~0);
 
@@ -4948,6 +4965,7 @@
 	netif_device_attach(netdev);
 
 	if (adapter->hw.mac_type >= e1000_82540 &&
+	    adapter->hw.mac_type < e1000_82571 &&
 	    adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		manc &= ~(E1000_MANC_ARP_EN);
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index b40724f..39ad9f7 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_0034"
+#define DRV_VERSION	"EHEA_0043"
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
 	| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -105,9 +105,6 @@
 #define EHEA_BCMC_VLANID_ALL	0x01
 #define EHEA_BCMC_VLANID_SINGLE	0x00
 
-/* Use this define to kmallocate pHYP control blocks */
-#define H_CB_ALIGNMENT		4096
-
 #define EHEA_CACHE_LINE          128
 
 /* Memory Regions */
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
index 82eb2fb..9f57c2e 100644
--- a/drivers/net/ehea/ehea_ethtool.c
+++ b/drivers/net/ehea/ehea_ethtool.c
@@ -238,7 +238,7 @@
 	data[i++] = port->port_res[0].swqe_refill_th;
 	data[i++] = port->resets;
 
-	cb6 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb6 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb6) {
 		ehea_error("no mem for cb6");
 		return;
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index eb7d44d..6ad6961 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -92,7 +92,7 @@
 
 	memset(stats, 0, sizeof(*stats));
 
-	cb2 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb2 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb2) {
 		ehea_error("no mem for cb2");
 		goto out;
@@ -586,8 +586,8 @@
 	u64 hret;
 	struct hcp_ehea_port_cb0 *cb0;
 
-	cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
-	if (!cb0) {
+	cb0 = kzalloc(PAGE_SIZE, GFP_ATOMIC);   /* May be called via */
+	if (!cb0) {                             /* ehea_neq_tasklet() */
 		ehea_error("no mem for cb0");
 		ret = -ENOMEM;
 		goto out;
@@ -670,7 +670,7 @@
 	u64 hret;
 	int ret = 0;
 
-	cb4 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb4) {
 		ehea_error("no mem for cb4");
 		ret = -ENOMEM;
@@ -765,8 +765,7 @@
 
 		if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) {
 			if (!netif_carrier_ok(port->netdev)) {
-				ret = ehea_sense_port_attr(
-					port);
+				ret = ehea_sense_port_attr(port);
 				if (ret) {
 					ehea_error("failed resensing port "
 						   "attributes");
@@ -986,7 +985,7 @@
 	struct hcp_ehea_port_cb0 *cb0;
 
 	ret = -ENOMEM;
-	cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb0)
 		goto out;
 
@@ -1444,7 +1443,7 @@
 		goto out;
 	}
 
-	cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb0) {
 		ehea_error("no mem for cb0");
 		ret = -ENOMEM;
@@ -1502,7 +1501,7 @@
 	if ((enable && port->promisc) || (!enable && !port->promisc))
 		return;
 
-	cb7 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb7 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
 	if (!cb7) {
 		ehea_error("no mem for cb7");
 		goto out;
@@ -1606,7 +1605,7 @@
 	struct ehea_mc_list *ehea_mcl_entry;
 	u64 hret;
 
-	ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_KERNEL);
+	ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC);
 	if (!ehea_mcl_entry) {
 		ehea_error("no mem for mcl_entry");
 		return;
@@ -1871,7 +1870,7 @@
 
 	port->vgrp = grp;
 
-	cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb1) {
 		ehea_error("no mem for cb1");
 		goto out;
@@ -1900,7 +1899,7 @@
 	int index;
 	u64 hret;
 
-	cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb1) {
 		ehea_error("no mem for cb1");
 		goto out;
@@ -1936,7 +1935,7 @@
 	if (port->vgrp)
 		port->vgrp->vlan_devices[vid] = NULL;
 
-	cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb1) {
 		ehea_error("no mem for cb1");
 		goto out;
@@ -1969,7 +1968,7 @@
 	u64 dummy64 = 0;
 	struct hcp_modify_qp_cb0* cb0;
 
-	cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb0) {
 		ret = -ENOMEM;
 		goto out;
@@ -2270,7 +2269,7 @@
 	u64 hret;
 	int ret;
 
-	cb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb) {
 		ret = -ENOMEM;
 		goto out;
@@ -2341,7 +2340,7 @@
 		goto out;
 
 	/* Enable Jumbo frames */
-	cb4 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+	cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cb4) {
 		ehea_error("no mem for cb4");
 	} else {
diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c
index 0b51a8c..0cfc2bc 100644
--- a/drivers/net/ehea/ehea_phyp.c
+++ b/drivers/net/ehea/ehea_phyp.c
@@ -506,7 +506,7 @@
 			     const u8 pagesize, const u8 queue_type,
 			     const u64 log_pageaddr, const u64 count)
 {
-	if ((count > 1) && (log_pageaddr & 0xfff)) {
+	if ((count > 1) && (log_pageaddr & ~PAGE_MASK)) {
 		ehea_error("not on pageboundary");
 		return H_PARAMETER;
 	}
diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h
index fa51e3b..919f94b 100644
--- a/drivers/net/ehea/ehea_phyp.h
+++ b/drivers/net/ehea/ehea_phyp.h
@@ -81,14 +81,16 @@
 static inline void hcp_epas_ctor(struct h_epas *epas, u64 paddr_kernel,
 				 u64 paddr_user)
 {
-	epas->kernel.addr = ioremap(paddr_kernel, PAGE_SIZE);
+	/* To support 64k pages we must round to 64k page boundary */
+	epas->kernel.addr = ioremap((paddr_kernel & PAGE_MASK), PAGE_SIZE) +
+			    (paddr_kernel & ~PAGE_MASK);
 	epas->user.addr = paddr_user;
 }
 
 static inline void hcp_epas_dtor(struct h_epas *epas)
 {
 	if (epas->kernel.addr)
-		iounmap(epas->kernel.addr);
+		iounmap((void __iomem*)((u64)epas->kernel.addr & PAGE_MASK));
 
 	epas->user.addr = 0;
 	epas->kernel.addr = 0;
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 3e18623..72ef7bd 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -209,11 +209,11 @@
 {
 	u64 adapter_handle, hret;
 
-	adapter_handle = cq->adapter->handle;
-
 	if (!cq)
 		return 0;
 
+	adapter_handle = cq->adapter->handle;
+
 	/* deregister all previous registered pages */
 	hret = ehea_h_free_resource(adapter_handle, cq->fw_handle);
 	if (hret != H_SUCCESS) {
@@ -512,7 +512,7 @@
 
 	start = KERNELBASE;
 	end = (u64)high_memory;
-	nr_pages = (end - start) / PAGE_SIZE;
+	nr_pages = (end - start) / EHEA_PAGESIZE;
 
 	pt =  kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!pt) {
@@ -538,9 +538,9 @@
 		if (nr_pages > 1) {
 			u64 num_pages = min(nr_pages, (u64)512);
 			for (i = 0; i < num_pages; i++)
-				pt[i] = virt_to_abs((void*)(((u64)start)
-							     + ((k++) *
-								PAGE_SIZE)));
+				pt[i] = virt_to_abs((void*)(((u64)start) +
+							    ((k++) *
+							     EHEA_PAGESIZE)));
 
 			hret = ehea_h_register_rpage_mr(adapter->handle,
 							adapter->mr.handle, 0,
@@ -548,8 +548,9 @@
 							num_pages);
 			nr_pages -= num_pages;
 		} else {
-			u64 abs_adr = virt_to_abs((void*)(((u64)start)
-							   + (k * PAGE_SIZE)));
+			u64 abs_adr = virt_to_abs((void*)(((u64)start) +
+							  (k * EHEA_PAGESIZE)));
+
 			hret = ehea_h_register_rpage_mr(adapter->handle,
 							adapter->mr.handle, 0,
 							0, abs_adr,1);
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 86b3bb9..92420f0 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -914,7 +914,7 @@
 					printk(KERN_DEBUG "6pack: protocol violation\n");
 				else
 					sp->status = 0;
-				cmd &= !SIXP_RX_DCD_MASK;
+				cmd &= ~SIXP_RX_DCD_MASK;
 		}
 		sp->status = cmd & SIXP_PRIO_DATA_MASK;
 	} else { /* output watchdog char if idle */
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 2802db2..44c9f99 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -212,8 +212,8 @@
 			break;
 		}
 
-		free_index = pool->consumer_index++ % pool->size;
-		pool->consumer_index = free_index;
+		free_index = pool->consumer_index;
+		pool->consumer_index = (pool->consumer_index + 1) % pool->size;
 		index = pool->free_map[free_index];
 
 		ibmveth_assert(index != IBM_VETH_INVALID_MAP);
@@ -329,8 +329,10 @@
 			 adapter->rx_buff_pool[pool].buff_size,
 			 DMA_FROM_DEVICE);
 
-	free_index = adapter->rx_buff_pool[pool].producer_index++ % adapter->rx_buff_pool[pool].size;
-	adapter->rx_buff_pool[pool].producer_index = free_index;
+	free_index = adapter->rx_buff_pool[pool].producer_index;
+	adapter->rx_buff_pool[pool].producer_index
+		= (adapter->rx_buff_pool[pool].producer_index + 1)
+		% adapter->rx_buff_pool[pool].size;
 	adapter->rx_buff_pool[pool].free_map[free_index] = index;
 
 	mb();
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index e963dbf..f56b00e 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1017,7 +1017,7 @@
 	struct ioc3_private *ip = netdev_priv(dev);
 	struct ioc3 *ioc3 = ip->regs;
 
-	del_timer(&ip->ioc3_timer);		/* Kill if running	*/
+	del_timer_sync(&ip->ioc3_timer);	/* Kill if running	*/
 
 	ioc3_w_emcr(EMCR_RST);			/* Reset		*/
 	(void) ioc3_r_emcr();			/* Flush WB		*/
@@ -1081,7 +1081,7 @@
 {
 	struct ioc3_private *ip = netdev_priv(dev);
 
-	del_timer(&ip->ioc3_timer);
+	del_timer_sync(&ip->ioc3_timer);
 
 	netif_stop_queue(dev);
 
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index be8a66e..3b4c478 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -15,8 +15,7 @@
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
-*	the Free Software Foundation; either version 2 of the License, or
-*	(at your option) any later version.
+*	the Free Software Foundation; either version 2 of the License.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index fdbb0d7..806081b 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -2416,7 +2416,6 @@
  * firmware image, and set tx.boundary to 4KB.
  */
 
-#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE	0x0132
 #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
 #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
 
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index f1c7575..b977ed8 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -214,6 +214,7 @@
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, RTL_CFG_2 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), 0, 0, RTL_CFG_0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), 0, 0, RTL_CFG_0 },
+	{ PCI_DEVICE(0x1259,			0xc107), 0, 0, RTL_CFG_0 },
 	{ PCI_DEVICE(0x16ec,			0x0116), 0, 0, RTL_CFG_0 },
 	{ PCI_VENDOR_ID_LINKSYS,		0x1032,
 		PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
@@ -1396,41 +1397,6 @@
 }
 #endif
 
-static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr)
-{
-	unsigned int i, j;
-
-	RTL_W8(Cfg9346, Cfg9346_Unlock);
-	for (i = 0; i < 2; i++) {
-		__le32 l = 0;
-
-		for (j = 0; j < 4; j++) {
-			l <<= 8;
-			l |= dev->dev_addr[4*i + j];
-		}
-		RTL_W32(MAC0 + 4*i, cpu_to_be32(l));
-	}
-	RTL_W8(Cfg9346, Cfg9346_Lock);
-}
-
-static int rtl8169_set_mac_addr(struct net_device *dev, void *p)
-{
-	struct rtl8169_private *tp = netdev_priv(dev);
-	struct sockaddr *addr = p;
-
-	if (!is_valid_ether_addr(addr->sa_data))
-		return -EINVAL;
-
-	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-
-	if (netif_running(dev)) {
-		spin_lock_irq(&tp->lock);
-		__rtl8169_set_mac_addr(dev, tp->mmio_addr);
-		spin_unlock_irq(&tp->lock);
-	}
-	return 0;
-}
-
 static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
 				  void __iomem *ioaddr)
 {
@@ -1507,8 +1473,8 @@
 	struct rtl8169_private *tp;
 	struct net_device *dev;
 	void __iomem *ioaddr;
-	unsigned int i, pm_cap;
-	int rc;
+	unsigned int pm_cap;
+	int i, rc;
 
 	if (netif_msg_drv(&debug)) {
 		printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
@@ -1680,7 +1646,6 @@
 	dev->stop = rtl8169_close;
 	dev->tx_timeout = rtl8169_tx_timeout;
 	dev->set_multicast_list = rtl8169_set_rx_mode;
-	dev->set_mac_address = rtl8169_set_mac_addr;
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long) ioaddr;
@@ -1928,8 +1893,6 @@
 	/* Enable all known interrupts by setting the interrupt mask. */
 	RTL_W16(IntrMask, rtl8169_intr_mask);
 
-	__rtl8169_set_mac_addr(dev, ioaddr);
-
 	netif_start_queue(dev);
 }
 
@@ -2700,6 +2663,7 @@
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned int poll_locked = 0;
+	unsigned int intrmask;
 
 	rtl8169_delete_timer(dev);
 
@@ -2738,8 +2702,11 @@
 	 * 2) dev->change_mtu
 	 *    -> rtl8169_poll can not be issued again and re-enable the
 	 *       interruptions. Let's simply issue the IRQ down sequence again.
+	 *
+	 * No loop if hotpluged or major error (0xffff).
 	 */
-	if (RTL_R16(IntrMask))
+	intrmask = RTL_R16(IntrMask);
+	if (intrmask && (intrmask != 0xffff))
 		goto core_down;
 
 	rtl8169_tx_clear(tp);
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index a231ab7..33569ec 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -5985,6 +5985,11 @@
 			((RxD3_t*)rxdp)->Buffer1_ptr = *temp1;
 		} else {
 			*skb = dev_alloc_skb(size);
+			if (!(*skb)) {
+				DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n",
+					  dev->name);
+				return -ENOMEM;
+			}
 			((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 =
 				pci_map_single(sp->pdev, (*skb)->data,
 					       dev->mtu + 4,
@@ -6007,7 +6012,11 @@
 			((RxD3_t*)rxdp)->Buffer2_ptr = *temp2;
 		} else {
 			*skb = dev_alloc_skb(size);
-
+			if (!(*skb)) {
+				DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n",
+					  dev->name);
+				return -ENOMEM;
+			}
 			((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 =
 				pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
 					       PCI_DMA_FROMDEVICE);
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index db23249..1eae16b 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2903,7 +2903,7 @@
 
 		dev = alloc_etherdev(sizeof(struct sbmac_softc));
 		if (!dev)
-			return -ENOMEM;	/* return ENOMEM */
+			return -ENOMEM;
 
 		printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
 
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index e7e4149..b294903 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -11,8 +11,7 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation; either version 2 of the License.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 67ecd66..16616f5 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -10,8 +10,7 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation; either version 2 of the License.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -699,16 +698,10 @@
 
 }
 
-/* Assign Ram Buffer allocation.
- * start and end are in units of 4k bytes
- * ram registers are in units of 64bit words
- */
-static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
+/* Assign Ram Buffer allocation in units of 64bit (8 bytes) */
+static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end)
 {
-	u32 start, end;
-
-	start = startk * 4096/8;
-	end = (endk * 4096/8) - 1;
+	pr_debug(PFX "q %d %#x %#x\n", q, start, end);
 
 	sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
 	sky2_write32(hw, RB_ADDR(q, RB_START), start);
@@ -717,7 +710,7 @@
 	sky2_write32(hw, RB_ADDR(q, RB_RP), start);
 
 	if (q == Q_R1 || q == Q_R2) {
-		u32 space = (endk - startk) * 4096/8;
+		u32 space = end - start + 1;
 		u32 tp = space - space/4;
 
 		/* On receive queue's set the thresholds
@@ -1199,19 +1192,16 @@
 
 	sky2_mac_init(hw, port);
 
-	/* Determine available ram buffer space (in 4K blocks).
-	 * Note: not sure about the FE setting below yet
-	 */
-	if (hw->chip_id == CHIP_ID_YUKON_FE)
-		ramsize = 4;
+	/* Determine available ram buffer space in qwords.  */
+	ramsize = sky2_read8(hw, B2_E_0) * 4096/8;
+
+	if (ramsize > 6*1024/8)
+		rxspace = ramsize - (ramsize + 2) / 3;
 	else
-		ramsize = sky2_read8(hw, B2_E_0);
+		rxspace = ramsize / 2;
 
-	/* Give transmitter one third (rounded up) */
-	rxspace = ramsize - (ramsize + 2) / 3;
-
-	sky2_ramset(hw, rxqaddr[port], 0, rxspace);
-	sky2_ramset(hw, txqaddr[port], rxspace, ramsize);
+	sky2_ramset(hw, rxqaddr[port], 0, rxspace-1);
+	sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1);
 
 	/* Make sure SyncQ is disabled */
 	sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
@@ -3248,7 +3238,11 @@
 		dev->poll = sky2_poll;
 	dev->weight = NAPI_WEIGHT;
 #ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = sky2_netpoll;
+	/* Network console (only works on port 0)
+	 * because netpoll makes assumptions about NAPI
+	 */
+	if (port == 0)
+		dev->poll_controller = sky2_netpoll;
 #endif
 
 	sky2 = netdev_priv(dev);
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 0c9f1e7..a864016 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -416,6 +416,24 @@
 
 #define SMC_IRQ_FLAGS		(0)
 
+#elif	defined(CONFIG_ARCH_VERSATILE)
+
+#define SMC_CAN_USE_8BIT	1
+#define SMC_CAN_USE_16BIT	1
+#define SMC_CAN_USE_32BIT	1
+#define SMC_NOWAIT		1
+
+#define SMC_inb(a, r)		readb((a) + (r))
+#define SMC_inw(a, r)		readw((a) + (r))
+#define SMC_inl(a, r)		readl((a) + (r))
+#define SMC_outb(v, a, r)	writeb(v, (a) + (r))
+#define SMC_outw(v, a, r)	writew(v, (a) + (r))
+#define SMC_outl(v, a, r)	writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS		(0)
+
 #else
 
 #define SMC_CAN_USE_8BIT	1
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8e39849..c20bb99 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.67"
-#define DRV_MODULE_RELDATE	"October 18, 2006"
+#define DRV_MODULE_VERSION	"3.69"
+#define DRV_MODULE_RELDATE	"November 15, 2006"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -4728,10 +4728,11 @@
 	u32 val;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-		for (i = 0; i < 400; i++) {
+		/* Wait up to 20ms for init done. */
+		for (i = 0; i < 200; i++) {
 			if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE)
 				return 0;
-			udelay(10);
+			udelay(100);
 		}
 		return -ENODEV;
 	}
@@ -6014,7 +6015,7 @@
 		tg3_abort_hw(tp, 1);
 	}
 
-	if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && reset_phy)
+	if (reset_phy)
 		tg3_phy_reset(tp);
 
 	err = tg3_chip_reset(tp);
@@ -6574,7 +6575,7 @@
 		tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
 	}
 
-	err = tg3_setup_phy(tp, reset_phy);
+	err = tg3_setup_phy(tp, 0);
 	if (err)
 		return err;
 
@@ -6978,8 +6979,10 @@
 	tg3_full_lock(tp, 0);
 
 	err = tg3_set_power_state(tp, PCI_D0);
-	if (err)
+	if (err) {
+		tg3_full_unlock(tp);
 		return err;
+	}
 
 	tg3_disable_ints(tp);
 	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
@@ -10212,7 +10215,7 @@
 static void __devinit tg3_read_partno(struct tg3 *tp)
 {
 	unsigned char vpd_data[256];
-	int i;
+	unsigned int i;
 	u32 magic;
 
 	if (tg3_nvram_read_swab(tp, 0x0, &magic))
@@ -10258,9 +10261,9 @@
 	}
 
 	/* Now parse and find the part number. */
-	for (i = 0; i < 256; ) {
+	for (i = 0; i < 254; ) {
 		unsigned char val = vpd_data[i];
-		int block_end;
+		unsigned int block_end;
 
 		if (val == 0x82 || val == 0x91) {
 			i = (i + 3 +
@@ -10276,21 +10279,26 @@
 			     (vpd_data[i + 1] +
 			      (vpd_data[i + 2] << 8)));
 		i += 3;
-		while (i < block_end) {
+
+		if (block_end > 256)
+			goto out_not_found;
+
+		while (i < (block_end - 2)) {
 			if (vpd_data[i + 0] == 'P' &&
 			    vpd_data[i + 1] == 'N') {
 				int partno_len = vpd_data[i + 2];
 
-				if (partno_len > 24)
+				i += 3;
+				if (partno_len > 24 || (partno_len + i) > 256)
 					goto out_not_found;
 
 				memcpy(tp->board_part_number,
-				       &vpd_data[i + 3],
-				       partno_len);
+				       &vpd_data[i], partno_len);
 
 				/* Success. */
 				return;
 			}
+			i += 3 + vpd_data[i + 2];
 		}
 
 		/* Part number not found. */
@@ -10360,7 +10368,7 @@
 	u32 pci_state_reg, grc_misc_cfg;
 	u32 val;
 	u16 pci_cmd;
-	int err;
+	int err, pcie_cap;
 
 	/* Force memory write invalidate off.  If we leave it on,
 	 * then on 5700_BX chips we have to enable a workaround.
@@ -10535,8 +10543,19 @@
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
 		tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
 
-	if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0)
+	pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP);
+	if (pcie_cap != 0) {
 		tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+			u16 lnkctl;
+
+			pci_read_config_word(tp->pdev,
+					     pcie_cap + PCI_EXP_LNKCTL,
+					     &lnkctl);
+			if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN)
+				tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
+		}
+	}
 
 	/* If we have an AMD 762 or VIA K8T800 chipset, write
 	 * reordering to the mailbox registers done by the host
@@ -11803,6 +11822,7 @@
 	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
 	    tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
 	    (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
 		tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
 	} else {
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
index 4f75696..cb7dbb6 100644
--- a/drivers/net/tokenring/proteon.c
+++ b/drivers/net/tokenring/proteon.c
@@ -370,6 +370,10 @@
 		dev->dma = dma[i];
 		pdev = platform_device_register_simple("proteon",
 			i, NULL, 0);
+		if (IS_ERR(pdev)) {
+			free_netdev(dev);
+			continue;
+		}
 		err = setup_card(dev, &pdev->dev);
 		if (!err) {
 			proteon_dev[i] = pdev;
@@ -385,9 +389,10 @@
 	/* Probe for cards. */
 	if (num == 0) {
 		printk(KERN_NOTICE "proteon.c: No cards found.\n");
-		return (-ENODEV);
+		platform_driver_unregister(&proteon_driver);
+		return -ENODEV;
 	}
-	return (0);
+	return 0;
 }
 
 static void __exit proteon_cleanup(void)
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
index d6ba41c..33afea3 100644
--- a/drivers/net/tokenring/skisa.c
+++ b/drivers/net/tokenring/skisa.c
@@ -380,6 +380,10 @@
 		dev->dma = dma[i];
 		pdev = platform_device_register_simple("skisa",
 			i, NULL, 0);
+		if (IS_ERR(pdev)) {
+			free_netdev(dev);
+			continue;
+		}
 		err = setup_card(dev, &pdev->dev);
 		if (!err) {
 			sk_isa_dev[i] = pdev;
@@ -395,9 +399,10 @@
 	/* Probe for cards. */
 	if (num == 0) {
 		printk(KERN_NOTICE "skisa.c: No cards found.\n");
-		return (-ENODEV);
+		platform_driver_unregister(&sk_isa_driver);
+		return -ENODEV;
 	}
-	return (0);
+	return 0;
 }
 
 static void __exit sk_isa_cleanup(void)
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 12cd7b5..b378880 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -2,14 +2,11 @@
  * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
  *
  * Author: Shlomi Gridish <gridish@freescale.com>
+ *	   Li Yang <leoli@freescale.com>
  *
  * Description:
  * QE UCC Gigabit Ethernet Driver
  *
- * Changelog:
- * Jul 6, 2006 Li Yang <LeoLi@freescale.com>
- * - Rearrange code and style fixes
- *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
  * Free Software Foundation;  either version 2 of the  License, or (at your
@@ -31,9 +28,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/fsl_devices.h>
 #include <linux/ethtool.h>
-#include <linux/platform_device.h>
 #include <linux/mii.h>
 
+#include <asm/of_device.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -70,7 +67,7 @@
 
 static DEFINE_SPINLOCK(ugeth_lock);
 
-static ucc_geth_info_t ugeth_primary_info = {
+static struct ucc_geth_info ugeth_primary_info = {
 	.uf_info = {
 		    .bd_mem_part = MEM_PART_SYSTEM,
 		    .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
@@ -163,7 +160,7 @@
 	.riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
 };
 
-static ucc_geth_info_t ugeth_info[8];
+static struct ucc_geth_info ugeth_info[8];
 
 #ifdef DEBUG
 static void mem_disp(u8 *addr, int size)
@@ -219,8 +216,8 @@
 	}
 }
 
-static int get_interface_details(enet_interface_e enet_interface,
-				 enet_speed_e *speed,
+static int get_interface_details(enum enet_interface enet_interface,
+				 enum enet_speed *speed,
 				 int *r10m,
 				 int *rmm,
 				 int *rpm,
@@ -283,7 +280,7 @@
 	return 0;
 }
 
-static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd)
+static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd)
 {
 	struct sk_buff *skb = NULL;
 
@@ -303,21 +300,19 @@
 
 	skb->dev = ugeth->dev;
 
-	BD_BUFFER_SET(bd,
+	out_be32(&((struct qe_bd *)bd)->buf,
 		      dma_map_single(NULL,
 				     skb->data,
 				     ugeth->ug_info->uf_info.max_rx_buf_length +
 				     UCC_GETH_RX_DATA_BUF_ALIGNMENT,
 				     DMA_FROM_DEVICE));
 
-	BD_STATUS_AND_LENGTH_SET(bd,
-				 (R_E | R_I |
-				  (BD_STATUS_AND_LENGTH(bd) & R_W)));
+	out_be32((u32 *)bd, (R_E | R_I | (in_be32((u32 *)bd) & R_W)));
 
 	return skb;
 }
 
-static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ)
+static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ)
 {
 	u8 *bd;
 	u32 bd_status;
@@ -328,7 +323,7 @@
 	i = 0;
 
 	do {
-		bd_status = BD_STATUS_AND_LENGTH(bd);
+		bd_status = in_be32((u32*)bd);
 		skb = get_new_skb(ugeth, bd);
 
 		if (!skb)	/* If can not allocate data buffer,
@@ -338,19 +333,19 @@
 		ugeth->rx_skbuff[rxQ][i] = skb;
 
 		/* advance the BD pointer */
-		bd += UCC_GETH_SIZE_OF_BD;
+		bd += sizeof(struct qe_bd);
 		i++;
 	} while (!(bd_status & R_W));
 
 	return 0;
 }
 
-static int fill_init_enet_entries(ucc_geth_private_t *ugeth,
+static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
 				  volatile u32 *p_start,
 				  u8 num_entries,
 				  u32 thread_size,
 				  u32 thread_alignment,
-				  qe_risc_allocation_e risc,
+				  enum qe_risc_allocation risc,
 				  int skip_page_for_first_entry)
 {
 	u32 init_enet_offset;
@@ -383,10 +378,10 @@
 	return 0;
 }
 
-static int return_init_enet_entries(ucc_geth_private_t *ugeth,
+static int return_init_enet_entries(struct ucc_geth_private *ugeth,
 				    volatile u32 *p_start,
 				    u8 num_entries,
-				    qe_risc_allocation_e risc,
+				    enum qe_risc_allocation risc,
 				    int skip_page_for_first_entry)
 {
 	u32 init_enet_offset;
@@ -416,11 +411,11 @@
 }
 
 #ifdef DEBUG
-static int dump_init_enet_entries(ucc_geth_private_t *ugeth,
+static int dump_init_enet_entries(struct ucc_geth_private *ugeth,
 				  volatile u32 *p_start,
 				  u8 num_entries,
 				  u32 thread_size,
-				  qe_risc_allocation_e risc,
+				  enum qe_risc_allocation risc,
 				  int skip_page_for_first_entry)
 {
 	u32 init_enet_offset;
@@ -456,14 +451,14 @@
 #endif
 
 #ifdef CONFIG_UGETH_FILTERING
-static enet_addr_container_t *get_enet_addr_container(void)
+static struct enet_addr_container *get_enet_addr_container(void)
 {
-	enet_addr_container_t *enet_addr_cont;
+	struct enet_addr_container *enet_addr_cont;
 
 	/* allocate memory */
-	enet_addr_cont = kmalloc(sizeof(enet_addr_container_t), GFP_KERNEL);
+	enet_addr_cont = kmalloc(sizeof(struct enet_addr_container), GFP_KERNEL);
 	if (!enet_addr_cont) {
-		ugeth_err("%s: No memory for enet_addr_container_t object.",
+		ugeth_err("%s: No memory for enet_addr_container object.",
 			  __FUNCTION__);
 		return NULL;
 	}
@@ -472,45 +467,43 @@
 }
 #endif /* CONFIG_UGETH_FILTERING */
 
-static void put_enet_addr_container(enet_addr_container_t *enet_addr_cont)
+static void put_enet_addr_container(struct enet_addr_container *enet_addr_cont)
 {
 	kfree(enet_addr_cont);
 }
 
-#ifdef CONFIG_UGETH_FILTERING
-static int hw_add_addr_in_paddr(ucc_geth_private_t *ugeth,
-				enet_addr_t *p_enet_addr, u8 paddr_num)
+static int set_mac_addr(__be16 __iomem *reg, u8 *mac)
 {
-	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+	out_be16(&reg[0], ((u16)mac[5] << 8) | mac[4]);
+	out_be16(&reg[1], ((u16)mac[3] << 8) | mac[2]);
+	out_be16(&reg[2], ((u16)mac[1] << 8) | mac[0]);
+}
+
+#ifdef CONFIG_UGETH_FILTERING
+static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth,
+                                u8 *p_enet_addr, u8 paddr_num)
+{
+	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
 
 	if (!(paddr_num < NUM_OF_PADDRS)) {
-		ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
+		ugeth_warn("%s: Illegal paddr_num.", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	p_82xx_addr_filt =
-	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
 	    addressfiltering;
 
 	/* Ethernet frames are defined in Little Endian mode,    */
 	/* therefore to insert the address we reverse the bytes. */
-	out_be16(&p_82xx_addr_filt->paddr[paddr_num].h,
-		 (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) |
-			(u16) (*p_enet_addr)[4]));
-	out_be16(&p_82xx_addr_filt->paddr[paddr_num].m,
-		 (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) |
-			(u16) (*p_enet_addr)[2]));
-	out_be16(&p_82xx_addr_filt->paddr[paddr_num].l,
-		 (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) |
-			(u16) (*p_enet_addr)[0]));
-
+	set_mac_addr(&p_82xx_addr_filt->paddr[paddr_num].h, p_enet_addr);
 	return 0;
 }
 #endif /* CONFIG_UGETH_FILTERING */
 
-static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num)
+static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
 {
-	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
 
 	if (!(paddr_num < NUM_OF_PADDRS)) {
 		ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
@@ -518,7 +511,7 @@
 	}
 
 	p_82xx_addr_filt =
-	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
 	    addressfiltering;
 
 	/* Writing address ff.ff.ff.ff.ff.ff disables address
@@ -530,14 +523,14 @@
 	return 0;
 }
 
-static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth,
-				enet_addr_t *p_enet_addr)
+static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth,
+                                u8 *p_enet_addr)
 {
-	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
 	u32 cecr_subblock;
 
 	p_82xx_addr_filt =
-	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
 	    addressfiltering;
 
 	cecr_subblock =
@@ -546,25 +539,18 @@
 	/* Ethernet frames are defined in Little Endian mode,
 	therefor to insert */
 	/* the address to the hash (Big Endian mode), we reverse the bytes.*/
-	out_be16(&p_82xx_addr_filt->taddr.h,
-		 (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) |
-			(u16) (*p_enet_addr)[4]));
-	out_be16(&p_82xx_addr_filt->taddr.m,
-		 (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) |
-			(u16) (*p_enet_addr)[2]));
-	out_be16(&p_82xx_addr_filt->taddr.l,
-		 (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) |
-			(u16) (*p_enet_addr)[0]));
+
+	set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr);
 
 	qe_issue_cmd(QE_SET_GROUP_ADDRESS, cecr_subblock,
-		     (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+		     QE_CR_PROTOCOL_ETHERNET, 0);
 }
 
 #ifdef CONFIG_UGETH_MAGIC_PACKET
-static void magic_packet_detection_enable(ucc_geth_private_t *ugeth)
+static void magic_packet_detection_enable(struct ucc_geth_private *ugeth)
 {
-	ucc_fast_private_t *uccf;
-	ucc_geth_t *ug_regs;
+	struct ucc_fast_private *uccf;
+	struct ucc_geth *ug_regs;
 	u32 maccfg2, uccm;
 
 	uccf = ugeth->uccf;
@@ -581,10 +567,10 @@
 	out_be32(&ug_regs->maccfg2, maccfg2);
 }
 
-static void magic_packet_detection_disable(ucc_geth_private_t *ugeth)
+static void magic_packet_detection_disable(struct ucc_geth_private *ugeth)
 {
-	ucc_fast_private_t *uccf;
-	ucc_geth_t *ug_regs;
+	struct ucc_fast_private *uccf;
+	struct ucc_geth *ug_regs;
 	u32 maccfg2, uccm;
 
 	uccf = ugeth->uccf;
@@ -602,26 +588,26 @@
 }
 #endif /* MAGIC_PACKET */
 
-static inline int compare_addr(enet_addr_t *addr1, enet_addr_t *addr2)
+static inline int compare_addr(u8 **addr1, u8 **addr2)
 {
 	return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS);
 }
 
 #ifdef DEBUG
-static void get_statistics(ucc_geth_private_t *ugeth,
-			   ucc_geth_tx_firmware_statistics_t *
+static void get_statistics(struct ucc_geth_private *ugeth,
+			   struct ucc_geth_tx_firmware_statistics *
 			   tx_firmware_statistics,
-			   ucc_geth_rx_firmware_statistics_t *
+			   struct ucc_geth_rx_firmware_statistics *
 			   rx_firmware_statistics,
-			   ucc_geth_hardware_statistics_t *hardware_statistics)
+			   struct ucc_geth_hardware_statistics *hardware_statistics)
 {
-	ucc_fast_t *uf_regs;
-	ucc_geth_t *ug_regs;
-	ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram;
-	ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram;
+	struct ucc_fast *uf_regs;
+	struct ucc_geth *ug_regs;
+	struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram;
+	struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram;
 
 	ug_regs = ugeth->ug_regs;
-	uf_regs = (ucc_fast_t *) ug_regs;
+	uf_regs = (struct ucc_fast *) ug_regs;
 	p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram;
 	p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram;
 
@@ -727,7 +713,7 @@
 	}
 }
 
-static void dump_bds(ucc_geth_private_t *ugeth)
+static void dump_bds(struct ucc_geth_private *ugeth)
 {
 	int i;
 	int length;
@@ -736,7 +722,7 @@
 		if (ugeth->p_tx_bd_ring[i]) {
 			length =
 			    (ugeth->ug_info->bdRingLenTx[i] *
-			     UCC_GETH_SIZE_OF_BD);
+			     sizeof(struct qe_bd));
 			ugeth_info("TX BDs[%d]", i);
 			mem_disp(ugeth->p_tx_bd_ring[i], length);
 		}
@@ -745,14 +731,14 @@
 		if (ugeth->p_rx_bd_ring[i]) {
 			length =
 			    (ugeth->ug_info->bdRingLenRx[i] *
-			     UCC_GETH_SIZE_OF_BD);
+			     sizeof(struct qe_bd));
 			ugeth_info("RX BDs[%d]", i);
 			mem_disp(ugeth->p_rx_bd_ring[i], length);
 		}
 	}
 }
 
-static void dump_regs(ucc_geth_private_t *ugeth)
+static void dump_regs(struct ucc_geth_private *ugeth)
 {
 	int i;
 
@@ -893,7 +879,7 @@
 			ugeth_info("Base address: 0x%08x",
 				   (u32) & ugeth->p_thread_data_tx[i]);
 			mem_disp((u8 *) & ugeth->p_thread_data_tx[i],
-				 sizeof(ucc_geth_thread_data_tx_t));
+				 sizeof(struct ucc_geth_thread_data_tx));
 		}
 	}
 	if (ugeth->p_thread_data_rx) {
@@ -927,7 +913,7 @@
 			ugeth_info("Base address: 0x%08x",
 				   (u32) & ugeth->p_thread_data_rx[i]);
 			mem_disp((u8 *) & ugeth->p_thread_data_rx[i],
-				 sizeof(ucc_geth_thread_data_rx_t));
+				 sizeof(struct ucc_geth_thread_data_rx));
 		}
 	}
 	if (ugeth->p_exf_glbl_param) {
@@ -1105,7 +1091,7 @@
 			ugeth_info("Base address: 0x%08x",
 				   (u32) & ugeth->p_send_q_mem_reg->sqqd[i]);
 			mem_disp((u8 *) & ugeth->p_send_q_mem_reg->sqqd[i],
-				 sizeof(ucc_geth_send_queue_qd_t));
+				 sizeof(struct ucc_geth_send_queue_qd));
 		}
 	}
 	if (ugeth->p_scheduler) {
@@ -1187,7 +1173,7 @@
 				 qe_muram_addr(in_be32
 					       (&ugeth->p_rx_bd_qs_tbl[i].
 						bdbaseptr)),
-				 sizeof(ucc_geth_rx_prefetched_bds_t));
+				 sizeof(struct ucc_geth_rx_prefetched_bds));
 		}
 	}
 	if (ugeth->p_init_enet_param_shadow) {
@@ -1198,7 +1184,7 @@
 		mem_disp((u8 *) ugeth->p_init_enet_param_shadow,
 			 sizeof(*ugeth->p_init_enet_param_shadow));
 
-		size = sizeof(ucc_geth_thread_rx_pram_t);
+		size = sizeof(struct ucc_geth_thread_rx_pram);
 		if (ugeth->ug_info->rxExtendedFiltering) {
 			size +=
 			    THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
@@ -1216,7 +1202,7 @@
 				       &(ugeth->p_init_enet_param_shadow->
 					 txthread[0]),
 				       ENET_INIT_PARAM_MAX_ENTRIES_TX,
-				       sizeof(ucc_geth_thread_tx_pram_t),
+				       sizeof(struct ucc_geth_thread_tx_pram),
 				       ugeth->ug_info->riscTx, 0);
 		dump_init_enet_entries(ugeth,
 				       &(ugeth->p_init_enet_param_shadow->
@@ -1578,12 +1564,12 @@
 	return 0;
 }
 
-static int adjust_enet_interface(ucc_geth_private_t *ugeth)
+static int adjust_enet_interface(struct ucc_geth_private *ugeth)
 {
-	ucc_geth_info_t *ug_info;
-	ucc_geth_t *ug_regs;
-	ucc_fast_t *uf_regs;
-	enet_speed_e speed;
+	struct ucc_geth_info *ug_info;
+	struct ucc_geth *ug_regs;
+	struct ucc_fast *uf_regs;
+	enum enet_speed speed;
 	int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm =
 	    0, limited_to_full_duplex = 0;
 	u32 upsmr, maccfg2, utbipar, tbiBaseAddress;
@@ -1691,8 +1677,8 @@
  */
 static void adjust_link(struct net_device *dev)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
-	ucc_geth_t *ug_regs;
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
+	struct ucc_geth *ug_regs;
 	u32 tempval;
 	struct ugeth_mii_info *mii_info = ugeth->mii_info;
 
@@ -1722,7 +1708,7 @@
 		if (mii_info->speed != ugeth->oldspeed) {
 			switch (mii_info->speed) {
 			case 1000:
-#ifdef CONFIG_MPC836x
+#ifdef CONFIG_PPC_MPC836x
 /* FIXME: This code is for 100Mbs BUG fixing,
 remove this when it is fixed!!! */
 				if (ugeth->ug_info->enet_interface ==
@@ -1768,7 +1754,7 @@
 				break;
 			case 100:
 			case 10:
-#ifdef CONFIG_MPC836x
+#ifdef CONFIG_PPC_MPC836x
 /* FIXME: This code is for 100Mbs BUG fixing,
 remove this lines when it will be fixed!!! */
 				ugeth->ug_info->enet_interface = ENET_100_RGMII;
@@ -1827,9 +1813,9 @@
  */
 static int init_phy(struct net_device *dev)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 	struct phy_info *curphy;
-	ucc_mii_mng_t *mii_regs;
+	struct ucc_mii_mng *mii_regs;
 	struct ugeth_mii_info *mii_info;
 	int err;
 
@@ -1914,17 +1900,17 @@
 }
 
 #ifdef CONFIG_UGETH_TX_ON_DEMOND
-static int ugeth_transmit_on_demand(ucc_geth_private_t *ugeth)
+static int ugeth_transmit_on_demand(struct ucc_geth_private *ugeth)
 {
-	ucc_fast_transmit_on_demand(ugeth->uccf);
+	struct ucc_fastransmit_on_demand(ugeth->uccf);
 
 	return 0;
 }
 #endif
 
-static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth)
+static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
 {
-	ucc_fast_private_t *uccf;
+	struct ucc_fast_private *uccf;
 	u32 cecr_subblock;
 	u32 temp;
 
@@ -1940,7 +1926,7 @@
 	cecr_subblock =
 	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
 	qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock,
-		     (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+		     QE_CR_PROTOCOL_ETHERNET, 0);
 
 	/* Wait for command to complete */
 	do {
@@ -1952,9 +1938,9 @@
 	return 0;
 }
 
-static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth)
+static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
 {
-	ucc_fast_private_t *uccf;
+	struct ucc_fast_private *uccf;
 	u32 cecr_subblock;
 	u8 temp;
 
@@ -1973,7 +1959,7 @@
 		    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.
 						ucc_num);
 		qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
-			     (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+			     QE_CR_PROTOCOL_ETHERNET, 0);
 
 		temp = ugeth->p_rx_glbl_pram->rxgstpack;
 	} while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX));
@@ -1983,41 +1969,40 @@
 	return 0;
 }
 
-static int ugeth_restart_tx(ucc_geth_private_t *ugeth)
+static int ugeth_restart_tx(struct ucc_geth_private *ugeth)
 {
-	ucc_fast_private_t *uccf;
+	struct ucc_fast_private *uccf;
 	u32 cecr_subblock;
 
 	uccf = ugeth->uccf;
 
 	cecr_subblock =
 	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-	qe_issue_cmd(QE_RESTART_TX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
-		     0);
+	qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0);
 	uccf->stopped_tx = 0;
 
 	return 0;
 }
 
-static int ugeth_restart_rx(ucc_geth_private_t *ugeth)
+static int ugeth_restart_rx(struct ucc_geth_private *ugeth)
 {
-	ucc_fast_private_t *uccf;
+	struct ucc_fast_private *uccf;
 	u32 cecr_subblock;
 
 	uccf = ugeth->uccf;
 
 	cecr_subblock =
 	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-	qe_issue_cmd(QE_RESTART_RX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
+	qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET,
 		     0);
 	uccf->stopped_rx = 0;
 
 	return 0;
 }
 
-static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode)
+static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
 {
-	ucc_fast_private_t *uccf;
+	struct ucc_fast_private *uccf;
 	int enabled_tx, enabled_rx;
 
 	uccf = ugeth->uccf;
@@ -2044,9 +2029,9 @@
 
 }
 
-static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode)
+static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode)
 {
-	ucc_fast_private_t *uccf;
+	struct ucc_fast_private *uccf;
 
 	uccf = ugeth->uccf;
 
@@ -2069,7 +2054,7 @@
 	return 0;
 }
 
-static void ugeth_dump_regs(ucc_geth_private_t *ugeth)
+static void ugeth_dump_regs(struct ucc_geth_private *ugeth)
 {
 #ifdef DEBUG
 	ucc_fast_dump_regs(ugeth->uccf);
@@ -2079,9 +2064,9 @@
 }
 
 #ifdef CONFIG_UGETH_FILTERING
-static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t *
+static int ugeth_ext_filtering_serialize_tad(struct ucc_geth_tad_params *
 					     p_UccGethTadParams,
-					     qe_fltr_tad_t *qe_fltr_tad)
+					     struct qe_fltr_tad *qe_fltr_tad)
 {
 	u16 temp;
 
@@ -2119,11 +2104,11 @@
 	return 0;
 }
 
-static enet_addr_container_t
-    *ugeth_82xx_filtering_get_match_addr_in_hash(ucc_geth_private_t *ugeth,
-						 enet_addr_t *p_enet_addr)
+static struct enet_addr_container_t
+    *ugeth_82xx_filtering_get_match_addr_in_hash(struct ucc_geth_private *ugeth,
+						 struct enet_addr *p_enet_addr)
 {
-	enet_addr_container_t *enet_addr_cont;
+	struct enet_addr_container *enet_addr_cont;
 	struct list_head *p_lh;
 	u16 i, num;
 	int32_t j;
@@ -2144,7 +2129,7 @@
 
 	for (i = 0; i < num; i++) {
 		enet_addr_cont =
-		    (enet_addr_container_t *)
+		    (struct enet_addr_container *)
 		    ENET_ADDR_CONT_ENTRY(dequeue(p_lh));
 		for (j = ENET_NUM_OCTETS_PER_ADDRESS - 1; j >= 0; j--) {
 			if ((*p_enet_addr)[j] != (enet_addr_cont->address)[j])
@@ -2157,11 +2142,11 @@
 	return NULL;
 }
 
-static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth,
-						 enet_addr_t *p_enet_addr)
+static int ugeth_82xx_filtering_add_addr_in_hash(struct ucc_geth_private *ugeth,
+						 struct enet_addr *p_enet_addr)
 {
-	ucc_geth_enet_address_recognition_location_e location;
-	enet_addr_container_t *enet_addr_cont;
+	enum ucc_geth_enet_address_recognition_location location;
+	struct enet_addr_container *enet_addr_cont;
 	struct list_head *p_lh;
 	u8 i;
 	u32 limit;
@@ -2196,18 +2181,17 @@
 	enqueue(p_lh, &enet_addr_cont->node);	/* Put it back */
 	++(*p_counter);
 
-	hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address));
-
+	hw_add_addr_in_hash(ugeth, enet_addr_cont->address);
 	return 0;
 }
 
-static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth,
-						   enet_addr_t *p_enet_addr)
+static int ugeth_82xx_filtering_clear_addr_in_hash(struct ucc_geth_private *ugeth,
+						   struct enet_addr *p_enet_addr)
 {
-	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-	enet_addr_container_t *enet_addr_cont;
-	ucc_fast_private_t *uccf;
-	comm_dir_e comm_dir;
+	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct enet_addr_container *enet_addr_cont;
+	struct ucc_fast_private *uccf;
+	enum comm_dir comm_dir;
 	u16 i, num;
 	struct list_head *p_lh;
 	u32 *addr_h, *addr_l;
@@ -2216,7 +2200,7 @@
 	uccf = ugeth->uccf;
 
 	p_82xx_addr_filt =
-	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
 	    addressfiltering;
 
 	if (!
@@ -2256,9 +2240,9 @@
 	num = --(*p_counter);
 	for (i = 0; i < num; i++) {
 		enet_addr_cont =
-		    (enet_addr_container_t *)
+		    (struct enet_addr_container *)
 		    ENET_ADDR_CONT_ENTRY(dequeue(p_lh));
-		hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address));
+		hw_add_addr_in_hash(ugeth, enet_addr_cont->address);
 		enqueue(p_lh, &enet_addr_cont->node);	/* Put it back */
 	}
 
@@ -2269,14 +2253,14 @@
 }
 #endif /* CONFIG_UGETH_FILTERING */
 
-static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t *
+static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private *
 						       ugeth,
-						       enet_addr_type_e
+						       enum enet_addr_type
 						       enet_addr_type)
 {
-	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-	ucc_fast_private_t *uccf;
-	comm_dir_e comm_dir;
+	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_fast_private *uccf;
+	enum comm_dir comm_dir;
 	struct list_head *p_lh;
 	u16 i, num;
 	u32 *addr_h, *addr_l;
@@ -2285,7 +2269,7 @@
 	uccf = ugeth->uccf;
 
 	p_82xx_addr_filt =
-	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
 	    addressfiltering;
 
 	if (enet_addr_type == ENET_ADDR_TYPE_GROUP) {
@@ -2331,8 +2315,8 @@
 }
 
 #ifdef CONFIG_UGETH_FILTERING
-static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth,
-						  enet_addr_t *p_enet_addr,
+static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth,
+						  struct enet_addr *p_enet_addr,
 						  u8 paddr_num)
 {
 	int i;
@@ -2352,14 +2336,14 @@
 }
 #endif /* CONFIG_UGETH_FILTERING */
 
-static int ugeth_82xx_filtering_clear_addr_in_paddr(ucc_geth_private_t *ugeth,
+static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *ugeth,
 						    u8 paddr_num)
 {
 	ugeth->indAddrRegUsed[paddr_num] = 0; /* mark this paddr as not used */
 	return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */
 }
 
-static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
+static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
 {
 	u16 i, j;
 	u8 *bd;
@@ -2433,8 +2417,8 @@
 		for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
 			if (ugeth->tx_skbuff[i][j]) {
 				dma_unmap_single(NULL,
-						 BD_BUFFER_ARG(bd),
-						 (BD_STATUS_AND_LENGTH(bd) &
+						 ((qe_bd_t *)bd)->buf,
+						 (in_be32((u32 *)bd) &
 						  BD_LENGTH_MASK),
 						 DMA_TO_DEVICE);
 				dev_kfree_skb_any(ugeth->tx_skbuff[i][j]);
@@ -2460,18 +2444,17 @@
 			bd = ugeth->p_rx_bd_ring[i];
 			for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) {
 				if (ugeth->rx_skbuff[i][j]) {
-					dma_unmap_single(NULL, BD_BUFFER(bd),
-						 ugeth->ug_info->
-						 uf_info.
-						 max_rx_buf_length +
-						 UCC_GETH_RX_DATA_BUF_ALIGNMENT,
-						 DMA_FROM_DEVICE);
-
-					dev_kfree_skb_any(ugeth->
-							  rx_skbuff[i][j]);
+					dma_unmap_single(NULL,
+						((struct qe_bd *)bd)->buf,
+						ugeth->ug_info->
+						uf_info.max_rx_buf_length +
+						UCC_GETH_RX_DATA_BUF_ALIGNMENT,
+						DMA_FROM_DEVICE);
+					dev_kfree_skb_any(
+						ugeth->rx_skbuff[i][j]);
 					ugeth->rx_skbuff[i][j] = NULL;
 				}
-				bd += UCC_GETH_SIZE_OF_BD;
+				bd += sizeof(struct qe_bd);
 			}
 
 			kfree(ugeth->rx_skbuff[i]);
@@ -2496,11 +2479,11 @@
 
 static void ucc_geth_set_multi(struct net_device *dev)
 {
-	ucc_geth_private_t *ugeth;
+	struct ucc_geth_private *ugeth;
 	struct dev_mc_list *dmi;
-	ucc_fast_t *uf_regs;
-	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-	enet_addr_t tempaddr;
+	struct ucc_fast *uf_regs;
+	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	u8 tempaddr[6];
 	u8 *mcptr, *tdptr;
 	int i, j;
 
@@ -2517,7 +2500,7 @@
 		uf_regs->upsmr &= ~UPSMR_PRO;
 
 		p_82xx_addr_filt =
-		    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->
+		    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->
 		    p_rx_glbl_pram->addressfiltering;
 
 		if (dev->flags & IFF_ALLMULTI) {
@@ -2546,23 +2529,22 @@
 				 * copy bytes MSB first from dmi_addr.
 				 */
 				mcptr = (u8 *) dmi->dmi_addr + 5;
-				tdptr = (u8 *) & tempaddr;
+				tdptr = (u8 *) tempaddr;
 				for (j = 0; j < 6; j++)
 					*tdptr++ = *mcptr--;
 
 				/* Ask CPM to run CRC and set bit in
 				 * filter mask.
 				 */
-				hw_add_addr_in_hash(ugeth, &tempaddr);
-
+				hw_add_addr_in_hash(ugeth, tempaddr);
 			}
 		}
 	}
 }
 
-static void ucc_geth_stop(ucc_geth_private_t *ugeth)
+static void ucc_geth_stop(struct ucc_geth_private *ugeth)
 {
-	ucc_geth_t *ug_regs = ugeth->ug_regs;
+	struct ucc_geth *ug_regs = ugeth->ug_regs;
 	u32 tempval;
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -2605,15 +2587,15 @@
 	ucc_geth_memclean(ugeth);
 }
 
-static int ucc_geth_startup(ucc_geth_private_t *ugeth)
+static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 {
-	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-	ucc_geth_init_pram_t *p_init_enet_pram;
-	ucc_fast_private_t *uccf;
-	ucc_geth_info_t *ug_info;
-	ucc_fast_info_t *uf_info;
-	ucc_fast_t *uf_regs;
-	ucc_geth_t *ug_regs;
+	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_geth_init_pram *p_init_enet_pram;
+	struct ucc_fast_private *uccf;
+	struct ucc_geth_info *ug_info;
+	struct ucc_fast_info *uf_info;
+	struct ucc_fast *uf_regs;
+	struct ucc_geth *ug_regs;
 	int ret_val = -EINVAL;
 	u32 remoder = UCC_GETH_REMODER_INIT;
 	u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
@@ -2788,7 +2770,7 @@
 		UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP);
 
 	uf_regs = uccf->uf_regs;
-	ug_regs = (ucc_geth_t *) (uccf->uf_regs);
+	ug_regs = (struct ucc_geth *) (uccf->uf_regs);
 	ugeth->ug_regs = ug_regs;
 
 	init_default_reg_vals(&uf_regs->upsmr,
@@ -2869,10 +2851,10 @@
 		/* Allocate in multiple of
 		   UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT,
 		   according to spec */
-		length = ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD)
+		length = ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd))
 			  / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
 		    * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
-		if ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) %
+		if ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) %
 		    UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
 			length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
 		if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
@@ -2904,13 +2886,13 @@
 		}
 		/* Zero unused end of bd ring, according to spec */
 		memset(ugeth->p_tx_bd_ring[j] +
-		       ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD, 0,
-		       length - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD);
+		       ug_info->bdRingLenTx[j] * sizeof(struct qe_bd), 0,
+		       length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd));
 	}
 
 	/* Allocate Rx bds */
 	for (j = 0; j < ug_info->numQueuesRx; j++) {
-		length = ug_info->bdRingLenRx[j] * UCC_GETH_SIZE_OF_BD;
+		length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd);
 		if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
 			u32 align = 4;
 			if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4)
@@ -2960,12 +2942,15 @@
 		ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0;
 		bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j];
 		for (i = 0; i < ug_info->bdRingLenTx[j]; i++) {
-			BD_BUFFER_CLEAR(bd);
-			BD_STATUS_AND_LENGTH_SET(bd, 0);
-			bd += UCC_GETH_SIZE_OF_BD;
+			/* clear bd buffer */
+			out_be32(&((struct qe_bd *)bd)->buf, 0);
+			/* set bd status and length */
+			out_be32((u32 *)bd, 0);
+			bd += sizeof(struct qe_bd);
 		}
-		bd -= UCC_GETH_SIZE_OF_BD;
-		BD_STATUS_AND_LENGTH_SET(bd, T_W);/* for last BD set Wrap bit */
+		bd -= sizeof(struct qe_bd);
+		/* set bd status and length */
+		out_be32((u32 *)bd, T_W);	/* for last BD set Wrap bit */
 	}
 
 	/* Init Rx bds */
@@ -2989,12 +2974,15 @@
 		ugeth->skb_currx[j] = 0;
 		bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j];
 		for (i = 0; i < ug_info->bdRingLenRx[j]; i++) {
-			BD_STATUS_AND_LENGTH_SET(bd, R_I);
-			BD_BUFFER_CLEAR(bd);
-			bd += UCC_GETH_SIZE_OF_BD;
+			/* set bd status and length */
+			out_be32((u32 *)bd, R_I);
+			/* clear bd buffer */
+			out_be32(&((struct qe_bd *)bd)->buf, 0);
+			bd += sizeof(struct qe_bd);
 		}
-		bd -= UCC_GETH_SIZE_OF_BD;
-		BD_STATUS_AND_LENGTH_SET(bd, R_W);/* for last BD set Wrap bit */
+		bd -= sizeof(struct qe_bd);
+		/* set bd status and length */
+		out_be32((u32 *)bd, R_W); /* for last BD set Wrap bit */
 	}
 
 	/*
@@ -3003,7 +2991,7 @@
 	/* Tx global PRAM */
 	/* Allocate global tx parameter RAM page */
 	ugeth->tx_glbl_pram_offset =
-	    qe_muram_alloc(sizeof(ucc_geth_tx_global_pram_t),
+	    qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram),
 			   UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT);
 	if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) {
 		ugeth_err
@@ -3013,10 +3001,10 @@
 		return -ENOMEM;
 	}
 	ugeth->p_tx_glbl_pram =
-	    (ucc_geth_tx_global_pram_t *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_tx_global_pram *) qe_muram_addr(ugeth->
 							tx_glbl_pram_offset);
 	/* Zero out p_tx_glbl_pram */
-	memset(ugeth->p_tx_glbl_pram, 0, sizeof(ucc_geth_tx_global_pram_t));
+	memset(ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram));
 
 	/* Fill global PRAM */
 
@@ -3024,7 +3012,7 @@
 	/* Size varies with number of Tx threads */
 	ugeth->thread_dat_tx_offset =
 	    qe_muram_alloc(numThreadsTxNumerical *
-			   sizeof(ucc_geth_thread_data_tx_t) +
+			   sizeof(struct ucc_geth_thread_data_tx) +
 			   32 * (numThreadsTxNumerical == 1),
 			   UCC_GETH_THREAD_DATA_ALIGNMENT);
 	if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) {
@@ -3036,7 +3024,7 @@
 	}
 
 	ugeth->p_thread_data_tx =
-	    (ucc_geth_thread_data_tx_t *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_thread_data_tx *) qe_muram_addr(ugeth->
 							thread_dat_tx_offset);
 	out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset);
 
@@ -3053,7 +3041,7 @@
 	/* Size varies with number of Tx queues */
 	ugeth->send_q_mem_reg_offset =
 	    qe_muram_alloc(ug_info->numQueuesTx *
-			   sizeof(ucc_geth_send_queue_qd_t),
+			   sizeof(struct ucc_geth_send_queue_qd),
 			   UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT);
 	if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) {
 		ugeth_err
@@ -3064,7 +3052,7 @@
 	}
 
 	ugeth->p_send_q_mem_reg =
-	    (ucc_geth_send_queue_mem_region_t *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_send_queue_mem_region *) qe_muram_addr(ugeth->
 			send_q_mem_reg_offset);
 	out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset);
 
@@ -3073,7 +3061,7 @@
 	for (i = 0; i < ug_info->numQueuesTx; i++) {
 		endOfRing =
 		    ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] -
-					      1) * UCC_GETH_SIZE_OF_BD;
+					      1) * sizeof(struct qe_bd);
 		if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) {
 			out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
 				 (u32) virt_to_phys(ugeth->p_tx_bd_ring[i]));
@@ -3096,7 +3084,7 @@
 	if (ug_info->numQueuesTx > 1) {
 	/* scheduler exists only if more than 1 tx queue */
 		ugeth->scheduler_offset =
-		    qe_muram_alloc(sizeof(ucc_geth_scheduler_t),
+		    qe_muram_alloc(sizeof(struct ucc_geth_scheduler),
 				   UCC_GETH_SCHEDULER_ALIGNMENT);
 		if (IS_MURAM_ERR(ugeth->scheduler_offset)) {
 			ugeth_err
@@ -3107,12 +3095,12 @@
 		}
 
 		ugeth->p_scheduler =
-		    (ucc_geth_scheduler_t *) qe_muram_addr(ugeth->
+		    (struct ucc_geth_scheduler *) qe_muram_addr(ugeth->
 							   scheduler_offset);
 		out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer,
 			 ugeth->scheduler_offset);
 		/* Zero out p_scheduler */
-		memset(ugeth->p_scheduler, 0, sizeof(ucc_geth_scheduler_t));
+		memset(ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler));
 
 		/* Set values in scheduler */
 		out_be32(&ugeth->p_scheduler->mblinterval,
@@ -3144,7 +3132,7 @@
 	    statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
 		ugeth->tx_fw_statistics_pram_offset =
 		    qe_muram_alloc(sizeof
-				   (ucc_geth_tx_firmware_statistics_pram_t),
+				   (struct ucc_geth_tx_firmware_statistics_pram),
 				   UCC_GETH_TX_STATISTICS_ALIGNMENT);
 		if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) {
 			ugeth_err
@@ -3154,11 +3142,11 @@
 			return -ENOMEM;
 		}
 		ugeth->p_tx_fw_statistics_pram =
-		    (ucc_geth_tx_firmware_statistics_pram_t *)
+		    (struct ucc_geth_tx_firmware_statistics_pram *)
 		    qe_muram_addr(ugeth->tx_fw_statistics_pram_offset);
 		/* Zero out p_tx_fw_statistics_pram */
 		memset(ugeth->p_tx_fw_statistics_pram,
-		       0, sizeof(ucc_geth_tx_firmware_statistics_pram_t));
+		       0, sizeof(struct ucc_geth_tx_firmware_statistics_pram));
 	}
 
 	/* temoder */
@@ -3183,7 +3171,7 @@
 	/* Rx global PRAM */
 	/* Allocate global rx parameter RAM page */
 	ugeth->rx_glbl_pram_offset =
-	    qe_muram_alloc(sizeof(ucc_geth_rx_global_pram_t),
+	    qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram),
 			   UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT);
 	if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) {
 		ugeth_err
@@ -3193,10 +3181,10 @@
 		return -ENOMEM;
 	}
 	ugeth->p_rx_glbl_pram =
-	    (ucc_geth_rx_global_pram_t *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_rx_global_pram *) qe_muram_addr(ugeth->
 							rx_glbl_pram_offset);
 	/* Zero out p_rx_glbl_pram */
-	memset(ugeth->p_rx_glbl_pram, 0, sizeof(ucc_geth_rx_global_pram_t));
+	memset(ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram));
 
 	/* Fill global PRAM */
 
@@ -3204,7 +3192,7 @@
 	/* Size varies with number of Rx threads */
 	ugeth->thread_dat_rx_offset =
 	    qe_muram_alloc(numThreadsRxNumerical *
-			   sizeof(ucc_geth_thread_data_rx_t),
+			   sizeof(struct ucc_geth_thread_data_rx),
 			   UCC_GETH_THREAD_DATA_ALIGNMENT);
 	if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) {
 		ugeth_err
@@ -3215,7 +3203,7 @@
 	}
 
 	ugeth->p_thread_data_rx =
-	    (ucc_geth_thread_data_rx_t *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_thread_data_rx *) qe_muram_addr(ugeth->
 							thread_dat_rx_offset);
 	out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset);
 
@@ -3227,7 +3215,7 @@
 	    statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) {
 		ugeth->rx_fw_statistics_pram_offset =
 		    qe_muram_alloc(sizeof
-				   (ucc_geth_rx_firmware_statistics_pram_t),
+				   (struct ucc_geth_rx_firmware_statistics_pram),
 				   UCC_GETH_RX_STATISTICS_ALIGNMENT);
 		if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) {
 			ugeth_err
@@ -3237,11 +3225,11 @@
 			return -ENOMEM;
 		}
 		ugeth->p_rx_fw_statistics_pram =
-		    (ucc_geth_rx_firmware_statistics_pram_t *)
+		    (struct ucc_geth_rx_firmware_statistics_pram *)
 		    qe_muram_addr(ugeth->rx_fw_statistics_pram_offset);
 		/* Zero out p_rx_fw_statistics_pram */
 		memset(ugeth->p_rx_fw_statistics_pram, 0,
-		       sizeof(ucc_geth_rx_firmware_statistics_pram_t));
+		       sizeof(struct ucc_geth_rx_firmware_statistics_pram));
 	}
 
 	/* intCoalescingPtr */
@@ -3249,7 +3237,7 @@
 	/* Size varies with number of Rx queues */
 	ugeth->rx_irq_coalescing_tbl_offset =
 	    qe_muram_alloc(ug_info->numQueuesRx *
-			   sizeof(ucc_geth_rx_interrupt_coalescing_entry_t),
+			   sizeof(struct ucc_geth_rx_interrupt_coalescing_entry),
 			   UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
 	if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) {
 		ugeth_err
@@ -3260,7 +3248,7 @@
 	}
 
 	ugeth->p_rx_irq_coalescing_tbl =
-	    (ucc_geth_rx_interrupt_coalescing_table_t *)
+	    (struct ucc_geth_rx_interrupt_coalescing_table *)
 	    qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset);
 	out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr,
 		 ugeth->rx_irq_coalescing_tbl_offset);
@@ -3300,7 +3288,7 @@
 		l3qt = 0;
 		for (i = 0; i < 8; i++)
 			l3qt |= (ug_info->l3qt[j + i] << (28 - 4 * i));
-		out_be32(&ugeth->p_rx_glbl_pram->l3qt[j], l3qt);
+		out_be32(&ugeth->p_rx_glbl_pram->l3qt[j/8], l3qt);
 	}
 
 	/* vlantype */
@@ -3316,8 +3304,8 @@
 	/* Size varies with number of Rx queues */
 	ugeth->rx_bd_qs_tbl_offset =
 	    qe_muram_alloc(ug_info->numQueuesRx *
-			   (sizeof(ucc_geth_rx_bd_queues_entry_t) +
-			    sizeof(ucc_geth_rx_prefetched_bds_t)),
+			   (sizeof(struct ucc_geth_rx_bd_queues_entry) +
+			    sizeof(struct ucc_geth_rx_prefetched_bds)),
 			   UCC_GETH_RX_BD_QUEUES_ALIGNMENT);
 	if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) {
 		ugeth_err
@@ -3328,14 +3316,14 @@
 	}
 
 	ugeth->p_rx_bd_qs_tbl =
-	    (ucc_geth_rx_bd_queues_entry_t *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_rx_bd_queues_entry *) qe_muram_addr(ugeth->
 				    rx_bd_qs_tbl_offset);
 	out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset);
 	/* Zero out p_rx_bd_qs_tbl */
 	memset(ugeth->p_rx_bd_qs_tbl,
 	       0,
-	       ug_info->numQueuesRx * (sizeof(ucc_geth_rx_bd_queues_entry_t) +
-				       sizeof(ucc_geth_rx_prefetched_bds_t)));
+	       ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) +
+				       sizeof(struct ucc_geth_rx_prefetched_bds)));
 
 	/* Setup the table */
 	/* Assume BD rings are already established */
@@ -3406,7 +3394,7 @@
 		/* Allocate memory for extended filtering Mode Global
 		Parameters */
 		ugeth->exf_glbl_param_offset =
-		    qe_muram_alloc(sizeof(ucc_geth_exf_global_pram_t),
+		    qe_muram_alloc(sizeof(struct ucc_geth_exf_global_pram),
 		UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT);
 		if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) {
 			ugeth_err
@@ -3417,7 +3405,7 @@
 		}
 
 		ugeth->p_exf_glbl_param =
-		    (ucc_geth_exf_global_pram_t *) qe_muram_addr(ugeth->
+		    (struct ucc_geth_exf_global_pram *) qe_muram_addr(ugeth->
 				 exf_glbl_param_offset);
 		out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam,
 			 ugeth->exf_glbl_param_offset);
@@ -3439,7 +3427,7 @@
 			INIT_LIST_HEAD(&ugeth->ind_hash_q);
 		}
 		p_82xx_addr_filt =
-		    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->
+		    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->
 		    p_rx_glbl_pram->addressfiltering;
 
 		ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth,
@@ -3462,7 +3450,7 @@
 	 * allocated resources can be released when the channel is freed.
 	 */
 	if (!(ugeth->p_init_enet_param_shadow =
-	     (ucc_geth_init_pram_t *) kmalloc(sizeof(ucc_geth_init_pram_t),
+	     (struct ucc_geth_init_pram *) kmalloc(sizeof(struct ucc_geth_init_pram),
 					      GFP_KERNEL))) {
 		ugeth_err
 		    ("%s: Can not allocate memory for"
@@ -3472,7 +3460,7 @@
 	}
 	/* Zero out *p_init_enet_param_shadow */
 	memset((char *)ugeth->p_init_enet_param_shadow,
-	       0, sizeof(ucc_geth_init_pram_t));
+	       0, sizeof(struct ucc_geth_init_pram));
 
 	/* Fill shadow InitEnet command parameter structure */
 
@@ -3506,7 +3494,7 @@
 	}
 	ugeth->p_init_enet_param_shadow->largestexternallookupkeysize =
 	    ug_info->largestexternallookupkeysize;
-	size = sizeof(ucc_geth_thread_rx_pram_t);
+	size = sizeof(struct ucc_geth_thread_rx_pram);
 	if (ug_info->rxExtendedFiltering) {
 		size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
 		if (ug_info->largestexternallookupkeysize ==
@@ -3537,7 +3525,7 @@
 	     fill_init_enet_entries(ugeth,
 				    &(ugeth->p_init_enet_param_shadow->
 				      txthread[0]), numThreadsTxNumerical,
-				    sizeof(ucc_geth_thread_tx_pram_t),
+				    sizeof(struct ucc_geth_thread_tx_pram),
 				    UCC_GETH_THREAD_TX_PRAM_ALIGNMENT,
 				    ug_info->riscTx, 0)) != 0) {
 		ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
@@ -3557,7 +3545,7 @@
 	}
 
 	/* Allocate InitEnet command parameter structure */
-	init_enet_pram_offset = qe_muram_alloc(sizeof(ucc_geth_init_pram_t), 4);
+	init_enet_pram_offset = qe_muram_alloc(sizeof(struct ucc_geth_init_pram), 4);
 	if (IS_MURAM_ERR(init_enet_pram_offset)) {
 		ugeth_err
 		    ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
@@ -3566,7 +3554,7 @@
 		return -ENOMEM;
 	}
 	p_init_enet_pram =
-	    (ucc_geth_init_pram_t *) qe_muram_addr(init_enet_pram_offset);
+	    (struct ucc_geth_init_pram *) qe_muram_addr(init_enet_pram_offset);
 
 	/* Copy shadow InitEnet command parameter structure into PRAM */
 	p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1;
@@ -3591,7 +3579,7 @@
 	/* Issue QE command */
 	cecr_subblock =
 	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-	qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
+	qe_issue_cmd(command, cecr_subblock, QE_CR_PROTOCOL_ETHERNET,
 		     init_enet_pram_offset);
 
 	/* Free InitEnet command parameter */
@@ -3603,7 +3591,7 @@
 /* returns a net_device_stats structure pointer */
 static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 
 	return &(ugeth->stats);
 }
@@ -3614,7 +3602,7 @@
  * starting over will fix the problem. */
 static void ucc_geth_timeout(struct net_device *dev)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
 
@@ -3634,7 +3622,7 @@
 /* It is pointed to by the dev->hard_start_xmit function pointer */
 static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 	u8 *bd;			/* BD pointer */
 	u32 bd_status;
 	u8 txQ = 0;
@@ -3647,7 +3635,7 @@
 
 	/* Start from the next BD that should be filled */
 	bd = ugeth->txBd[txQ];
-	bd_status = BD_STATUS_AND_LENGTH(bd);
+	bd_status = in_be32((u32 *)bd);
 	/* Save the skb pointer so we can free it later */
 	ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb;
 
@@ -3657,20 +3645,21 @@
 	     1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
 
 	/* set up the buffer descriptor */
-	BD_BUFFER_SET(bd,
+	out_be32(&((struct qe_bd *)bd)->buf,
 		      dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE));
 
-	//printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data);
+	/* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */
 
 	bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len;
 
-	BD_STATUS_AND_LENGTH_SET(bd, bd_status);
+	/* set bd status and length */
+	out_be32((u32 *)bd, bd_status);
 
 	dev->trans_start = jiffies;
 
 	/* Move to next BD in the ring */
 	if (!(bd_status & T_W))
-		ugeth->txBd[txQ] = bd + UCC_GETH_SIZE_OF_BD;
+		ugeth->txBd[txQ] = bd + sizeof(struct qe_bd);
 	else
 		ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ];
 
@@ -3695,7 +3684,7 @@
 	return 0;
 }
 
-static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit)
+static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit)
 {
 	struct sk_buff *skb;
 	u8 *bd;
@@ -3709,11 +3698,11 @@
 	/* collect received buffers */
 	bd = ugeth->rxBd[rxQ];
 
-	bd_status = BD_STATUS_AND_LENGTH(bd);
+	bd_status = in_be32((u32 *)bd);
 
 	/* while there are received buffers and BD is full (~R_E) */
 	while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) {
-		bdBuffer = (u8 *) BD_BUFFER(bd);
+		bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf);
 		length = (u16) ((bd_status & BD_LENGTH_MASK) - 4);
 		skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]];
 
@@ -3768,9 +3757,9 @@
 		if (bd_status & R_W)
 			bd = ugeth->p_rx_bd_ring[rxQ];
 		else
-			bd += UCC_GETH_SIZE_OF_BD;
+			bd += sizeof(struct qe_bd);
 
-		bd_status = BD_STATUS_AND_LENGTH(bd);
+		bd_status = in_be32((u32 *)bd);
 	}
 
 	ugeth->rxBd[rxQ] = bd;
@@ -3781,12 +3770,12 @@
 static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 {
 	/* Start from the next BD that should be filled */
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 	u8 *bd;			/* BD pointer */
 	u32 bd_status;
 
 	bd = ugeth->confBd[txQ];
-	bd_status = BD_STATUS_AND_LENGTH(bd);
+	bd_status = in_be32((u32 *)bd);
 
 	/* Normal processing. */
 	while ((bd_status & T_R) == 0) {
@@ -3813,7 +3802,7 @@
 
 		/* Advance the confirmation BD pointer */
 		if (!(bd_status & T_W))
-			ugeth->confBd[txQ] += UCC_GETH_SIZE_OF_BD;
+			ugeth->confBd[txQ] += sizeof(struct qe_bd);
 		else
 			ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ];
 	}
@@ -3823,7 +3812,7 @@
 #ifdef CONFIG_UGETH_NAPI
 static int ucc_geth_poll(struct net_device *dev, int *budget)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 	int howmany;
 	int rx_work_limit = *budget;
 	u8 rxQ = 0;
@@ -3847,9 +3836,9 @@
 static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
 {
 	struct net_device *dev = (struct net_device *)info;
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
-	ucc_fast_private_t *uccf;
-	ucc_geth_info_t *ug_info;
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
+	struct ucc_fast_private *uccf;
+	struct ucc_geth_info *ug_info;
 	register u32 ucce = 0;
 	register u32 bit_mask = UCCE_RXBF_SINGLE_MASK;
 	register u32 tx_mask = UCCE_TXBF_SINGLE_MASK;
@@ -3912,7 +3901,7 @@
 static irqreturn_t phy_interrupt(int irq, void *dev_id)
 {
 	struct net_device *dev = (struct net_device *)dev_id;
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
 
@@ -3932,8 +3921,8 @@
 static void ugeth_phy_change(void *data)
 {
 	struct net_device *dev = (struct net_device *)data;
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
-	ucc_geth_t *ug_regs;
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
+	struct ucc_geth *ug_regs;
 	int result = 0;
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -3963,7 +3952,7 @@
 static void ugeth_phy_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 
 	schedule_work(&ugeth->tq);
 
@@ -3979,7 +3968,7 @@
 static void ugeth_phy_startup_timer(unsigned long data)
 {
 	struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data;
-	ucc_geth_private_t *ugeth = netdev_priv(mii_info->dev);
+	struct ucc_geth_private *ugeth = netdev_priv(mii_info->dev);
 	static int secondary = UGETH_AN_TIMEOUT;
 	int result;
 
@@ -4034,7 +4023,7 @@
 /* Returns 0 for success. */
 static int ucc_geth_open(struct net_device *dev)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 	int err;
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -4111,7 +4100,7 @@
 /* Stops the kernel queue, and halts the controller */
 static int ucc_geth_close(struct net_device *dev)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
 
@@ -4130,30 +4119,53 @@
 
 const struct ethtool_ops ucc_geth_ethtool_ops = { };
 
-static int ucc_geth_probe(struct device *device)
+static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match)
 {
-	struct platform_device *pdev = to_platform_device(device);
-	struct ucc_geth_platform_data *ugeth_pdata;
+	struct device *device = &ofdev->dev;
+	struct device_node *np = ofdev->node;
 	struct net_device *dev = NULL;
 	struct ucc_geth_private *ugeth = NULL;
 	struct ucc_geth_info *ug_info;
-	int err;
+	struct resource res;
+	struct device_node *phy;
+	int err, ucc_num, phy_interface;
 	static int mii_mng_configured = 0;
+	const phandle *ph;
+	const unsigned int *prop;
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
 
-	ugeth_pdata = (struct ucc_geth_platform_data *)pdev->dev.platform_data;
+	prop = get_property(np, "device-id", NULL);
+	ucc_num = *prop - 1;
+	if ((ucc_num < 0) || (ucc_num > 7))
+		return -ENODEV;
 
-	ug_info = &ugeth_info[pdev->id];
-	ug_info->uf_info.ucc_num = pdev->id;
-	ug_info->uf_info.rx_clock = ugeth_pdata->rx_clock;
-	ug_info->uf_info.tx_clock = ugeth_pdata->tx_clock;
-	ug_info->uf_info.regs = ugeth_pdata->phy_reg_addr;
-	ug_info->uf_info.irq = platform_get_irq(pdev, 0);
-	ug_info->phy_address = ugeth_pdata->phy_id;
-	ug_info->enet_interface = ugeth_pdata->phy_interface;
-	ug_info->board_flags = ugeth_pdata->board_flags;
-	ug_info->phy_interrupt = ugeth_pdata->phy_interrupt;
+	ug_info = &ugeth_info[ucc_num];
+	ug_info->uf_info.ucc_num = ucc_num;
+	prop = get_property(np, "rx-clock", NULL);
+	ug_info->uf_info.rx_clock = *prop;
+	prop = get_property(np, "tx-clock", NULL);
+	ug_info->uf_info.tx_clock = *prop;
+	err = of_address_to_resource(np, 0, &res);
+	if (err)
+		return -EINVAL;
+
+	ug_info->uf_info.regs = res.start;
+	ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
+
+	ph = get_property(np, "phy-handle", NULL);
+	phy = of_find_node_by_phandle(*ph);
+
+	if (phy == NULL)
+		return -ENODEV;
+
+	prop = get_property(phy, "reg", NULL);
+	ug_info->phy_address = *prop;
+	prop = get_property(phy, "interface", NULL);
+	ug_info->enet_interface = *prop;
+	ug_info->phy_interrupt = irq_of_parse_and_map(phy, 0);
+	ug_info->board_flags = (ug_info->phy_interrupt == NO_IRQ)?
+			0:FSL_UGETH_BRD_HAS_PHY_INTR;
 
 	printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
 		ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
@@ -4161,12 +4173,44 @@
 
 	if (ug_info == NULL) {
 		ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__,
-			  pdev->id);
+			  ucc_num);
 		return -ENODEV;
 	}
 
+	/* FIXME: Work around for early chip rev.               */
+	/* There's a bug in initial chip rev(s) in the RGMII ac */
+	/* timing.						*/
+	/* The following compensates by writing to the reserved */
+	/* QE Port Output Hold Registers (CPOH1?).              */
+	prop = get_property(phy, "interface", NULL);
+	phy_interface = *prop;
+	if ((phy_interface == ENET_1000_RGMII) ||
+			(phy_interface == ENET_100_RGMII) ||
+			(phy_interface == ENET_10_RGMII)) {
+		struct device_node *soc;
+		phys_addr_t immrbase = -1;
+		u32 *tmp_reg;
+		u32 tmp_val;
+
+		soc = of_find_node_by_type(NULL, "soc");
+		if (soc) {
+			unsigned int size;
+			const void *prop = get_property(soc, "reg", &size);
+			immrbase = of_translate_address(soc, prop);
+			of_node_put(soc);
+		};
+
+		tmp_reg = (u32 *) ioremap(immrbase + 0x14A8, 0x4);
+		tmp_val = in_be32(tmp_reg);
+		if (ucc_num == 1)
+			out_be32(tmp_reg, tmp_val | 0x00003000);
+		else if (ucc_num == 2)
+			out_be32(tmp_reg, tmp_val | 0x0c000000);
+		iounmap(tmp_reg);
+	}
+
 	if (!mii_mng_configured) {
-		ucc_set_qe_mux_mii_mng(ug_info->uf_info.ucc_num);
+		ucc_set_qe_mux_mii_mng(ucc_num);
 		mii_mng_configured = 1;
 	}
 
@@ -4213,13 +4257,14 @@
 
 	ugeth->ug_info = ug_info;
 	ugeth->dev = dev;
-	memcpy(dev->dev_addr, ugeth_pdata->mac_addr, 6);
+	memcpy(dev->dev_addr, get_property(np, "mac-address", NULL), 6);
 
 	return 0;
 }
 
-static int ucc_geth_remove(struct device *device)
+static int ucc_geth_remove(struct of_device* ofdev)
 {
+	struct device *device = &ofdev->dev;
 	struct net_device *dev = dev_get_drvdata(device);
 	struct ucc_geth_private *ugeth = netdev_priv(dev);
 
@@ -4230,28 +4275,38 @@
 	return 0;
 }
 
-/* Structure for a device driver */
-static struct device_driver ucc_geth_driver = {
-	.name = DRV_NAME,
-	.bus = &platform_bus_type,
-	.probe = ucc_geth_probe,
-	.remove = ucc_geth_remove,
+static struct of_device_id ucc_geth_match[] = {
+	{
+		.type = "network",
+		.compatible = "ucc_geth",
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, ucc_geth_match);
+
+static struct of_platform_driver ucc_geth_driver = {
+	.name		= DRV_NAME,
+	.match_table	= ucc_geth_match,
+	.probe		= ucc_geth_probe,
+	.remove		= ucc_geth_remove,
 };
 
 static int __init ucc_geth_init(void)
 {
 	int i;
+
 	printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
 	for (i = 0; i < 8; i++)
 		memcpy(&(ugeth_info[i]), &ugeth_primary_info,
 		       sizeof(ugeth_primary_info));
 
-	return driver_register(&ucc_geth_driver);
+	return of_register_driver(&ucc_geth_driver);
 }
 
 static void __exit ucc_geth_exit(void)
 {
-	driver_unregister(&ucc_geth_driver);
+	of_unregister_driver(&ucc_geth_driver);
 }
 
 module_init(ucc_geth_init);
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 005965f..a665612 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -36,24 +36,24 @@
 #define ENET_INIT_PARAM_MAX_ENTRIES_RX  9
 #define ENET_INIT_PARAM_MAX_ENTRIES_TX  8
 
-typedef struct ucc_mii_mng {
+struct ucc_mii_mng {
 	u32 miimcfg;		/* MII management configuration reg */
 	u32 miimcom;		/* MII management command reg */
 	u32 miimadd;		/* MII management address reg */
 	u32 miimcon;		/* MII management control reg */
 	u32 miimstat;		/* MII management status reg */
 	u32 miimind;		/* MII management indication reg */
-} __attribute__ ((packed)) ucc_mii_mng_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth {
-	ucc_fast_t uccf;
+struct ucc_geth {
+	struct ucc_fast uccf;
 
 	u32 maccfg1;		/* mac configuration reg. 1 */
 	u32 maccfg2;		/* mac configuration reg. 2 */
 	u32 ipgifg;		/* interframe gap reg.  */
 	u32 hafdup;		/* half-duplex reg.  */
 	u8 res1[0x10];
-	ucc_mii_mng_t miimng;	/* MII management structure */
+	struct ucc_mii_mng miimng;	/* MII management structure */
 	u32 ifctl;		/* interface control reg */
 	u32 ifstat;		/* interface statux reg */
 	u32 macstnaddr1;	/* mac station address part 1 reg */
@@ -111,7 +111,7 @@
 	u32 scar;		/* Statistics carry register */
 	u32 scam;		/* Statistics caryy mask register */
 	u8 res5[0x200 - 0x1c4];
-} __attribute__ ((packed)) ucc_geth_t;
+} __attribute__ ((packed));
 
 /* UCC GETH TEMODR Register */
 #define TEMODER_TX_RMON_STATISTICS_ENABLE       0x0100	/* enable Tx statistics
@@ -508,39 +508,39 @@
 /* UCC GETH UDSR (Data Synchronization Register) */
 #define UDSR_MAGIC                              0x067E
 
-typedef struct ucc_geth_thread_data_tx {
+struct ucc_geth_thread_data_tx {
 	u8 res0[104];
-} __attribute__ ((packed)) ucc_geth_thread_data_tx_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_thread_data_rx {
+struct ucc_geth_thread_data_rx {
 	u8 res0[40];
-} __attribute__ ((packed)) ucc_geth_thread_data_rx_t;
+} __attribute__ ((packed));
 
 /* Send Queue Queue-Descriptor */
-typedef struct ucc_geth_send_queue_qd {
+struct ucc_geth_send_queue_qd {
 	u32 bd_ring_base;	/* pointer to BD ring base address */
 	u8 res0[0x8];
 	u32 last_bd_completed_address;/* initialize to last entry in BD ring */
 	u8 res1[0x30];
-} __attribute__ ((packed)) ucc_geth_send_queue_qd_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_send_queue_mem_region {
-	ucc_geth_send_queue_qd_t sqqd[NUM_TX_QUEUES];
-} __attribute__ ((packed)) ucc_geth_send_queue_mem_region_t;
+struct ucc_geth_send_queue_mem_region {
+	struct ucc_geth_send_queue_qd sqqd[NUM_TX_QUEUES];
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_thread_tx_pram {
+struct ucc_geth_thread_tx_pram {
 	u8 res0[64];
-} __attribute__ ((packed)) ucc_geth_thread_tx_pram_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_thread_rx_pram {
+struct ucc_geth_thread_rx_pram {
 	u8 res0[128];
-} __attribute__ ((packed)) ucc_geth_thread_rx_pram_t;
+} __attribute__ ((packed));
 
 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING        64
 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8      64
 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16     96
 
-typedef struct ucc_geth_scheduler {
+struct ucc_geth_scheduler {
 	u16 cpucount0;		/* CPU packet counter */
 	u16 cpucount1;		/* CPU packet counter */
 	u16 cecount0;		/* QE packet counter */
@@ -574,9 +574,9 @@
 				      /**< weight factor for queues   */
 	u32 minw;		/* temporary variable handled by QE */
 	u8 res1[0x70 - 0x64];
-} __attribute__ ((packed)) ucc_geth_scheduler_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_tx_firmware_statistics_pram {
+struct ucc_geth_tx_firmware_statistics_pram {
 	u32 sicoltx;		/* single collision */
 	u32 mulcoltx;		/* multiple collision */
 	u32 latecoltxfr;	/* late collision */
@@ -596,9 +596,9 @@
 				   and 1518 octets */
 	u32 txpktsjumbo;	/* total packets (including bad) between 1024
 				   and MAXLength octets */
-} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_pram_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_firmware_statistics_pram {
+struct ucc_geth_rx_firmware_statistics_pram {
 	u32 frrxfcser;		/* frames with crc error */
 	u32 fraligner;		/* frames with alignment error */
 	u32 inrangelenrxer;	/* in range length error */
@@ -630,33 +630,33 @@
 				   replaced */
 	u32 insertvlan;		/* total frames that had their VLAN tag
 				   inserted */
-} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_pram_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_interrupt_coalescing_entry {
+struct ucc_geth_rx_interrupt_coalescing_entry {
 	u32 interruptcoalescingmaxvalue;	/* interrupt coalescing max
 						   value */
 	u32 interruptcoalescingcounter;	/* interrupt coalescing counter,
 					   initialize to
 					   interruptcoalescingmaxvalue */
-} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_entry_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_interrupt_coalescing_table {
-	ucc_geth_rx_interrupt_coalescing_entry_t coalescingentry[NUM_RX_QUEUES];
+struct ucc_geth_rx_interrupt_coalescing_table {
+	struct ucc_geth_rx_interrupt_coalescing_entry coalescingentry[NUM_RX_QUEUES];
 				       /**< interrupt coalescing entry */
-} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_table_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_prefetched_bds {
-	qe_bd_t bd[NUM_BDS_IN_PREFETCHED_BDS];	/* prefetched bd */
-} __attribute__ ((packed)) ucc_geth_rx_prefetched_bds_t;
+struct ucc_geth_rx_prefetched_bds {
+	struct qe_bd bd[NUM_BDS_IN_PREFETCHED_BDS];	/* prefetched bd */
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_bd_queues_entry {
+struct ucc_geth_rx_bd_queues_entry {
 	u32 bdbaseptr;		/* BD base pointer */
 	u32 bdptr;		/* BD pointer */
 	u32 externalbdbaseptr;	/* external BD base pointer */
 	u32 externalbdptr;	/* external BD pointer */
-} __attribute__ ((packed)) ucc_geth_rx_bd_queues_entry_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_tx_global_pram {
+struct ucc_geth_tx_global_pram {
 	u16 temoder;
 	u8 res0[0x38 - 0x02];
 	u32 sqptr;		/* a base pointer to send queue memory region */
@@ -670,15 +670,15 @@
 	u32 tqptr;		/* a base pointer to the Tx Queues Memory
 				   Region */
 	u8 res2[0x80 - 0x74];
-} __attribute__ ((packed)) ucc_geth_tx_global_pram_t;
+} __attribute__ ((packed));
 
 /* structure representing Extended Filtering Global Parameters in PRAM */
-typedef struct ucc_geth_exf_global_pram {
+struct ucc_geth_exf_global_pram {
 	u32 l2pcdptr;		/* individual address filter, high */
 	u8 res0[0x10 - 0x04];
-} __attribute__ ((packed)) ucc_geth_exf_global_pram_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_global_pram {
+struct ucc_geth_rx_global_pram {
 	u32 remoder;		/* ethernet mode reg. */
 	u32 rqptr;		/* base pointer to the Rx Queues Memory Region*/
 	u32 res0[0x1];
@@ -710,12 +710,12 @@
 	u32 exfGlobalParam;	/* base address for extended filtering global
 				   parameters */
 	u8 res6[0x100 - 0xC4];	/* Initialize to zero */
-} __attribute__ ((packed)) ucc_geth_rx_global_pram_t;
+} __attribute__ ((packed));
 
 #define GRACEFUL_STOP_ACKNOWLEDGE_RX            0x01
 
 /* structure representing InitEnet command */
-typedef struct ucc_geth_init_pram {
+struct ucc_geth_init_pram {
 	u8 resinit1;
 	u8 resinit2;
 	u8 resinit3;
@@ -729,7 +729,7 @@
 	u32 txglobal;		/* tx global */
 	u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX];	/* tx threads */
 	u8 res3[0x1];
-} __attribute__ ((packed)) ucc_geth_init_pram_t;
+} __attribute__ ((packed));
 
 #define ENET_INIT_PARAM_RGF_SHIFT               (32 - 4)
 #define ENET_INIT_PARAM_TGF_SHIFT               (32 - 8)
@@ -746,27 +746,27 @@
 #define ENET_INIT_PARAM_MAGIC_RES_INIT5         0x0400
 
 /* structure representing 82xx Address Filtering Enet Address in PRAM */
-typedef struct ucc_geth_82xx_enet_address {
+struct ucc_geth_82xx_enet_address {
 	u8 res1[0x2];
 	u16 h;			/* address (MSB) */
 	u16 m;			/* address */
 	u16 l;			/* address (LSB) */
-} __attribute__ ((packed)) ucc_geth_82xx_enet_address_t;
+} __attribute__ ((packed));
 
 /* structure representing 82xx Address Filtering PRAM */
-typedef struct ucc_geth_82xx_address_filtering_pram {
+struct ucc_geth_82xx_address_filtering_pram {
 	u32 iaddr_h;		/* individual address filter, high */
 	u32 iaddr_l;		/* individual address filter, low */
 	u32 gaddr_h;		/* group address filter, high */
 	u32 gaddr_l;		/* group address filter, low */
-	ucc_geth_82xx_enet_address_t taddr;
-	ucc_geth_82xx_enet_address_t paddr[NUM_OF_PADDRS];
+	struct ucc_geth_82xx_enet_address taddr;
+	struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS];
 	u8 res0[0x40 - 0x38];
-} __attribute__ ((packed)) ucc_geth_82xx_address_filtering_pram_t;
+} __attribute__ ((packed));
 
 /* GETH Tx firmware statistics structure, used when calling
    UCC_GETH_GetStatistics. */
-typedef struct ucc_geth_tx_firmware_statistics {
+struct ucc_geth_tx_firmware_statistics {
 	u32 sicoltx;		/* single collision */
 	u32 mulcoltx;		/* multiple collision */
 	u32 latecoltxfr;	/* late collision */
@@ -786,11 +786,11 @@
 				   and 1518 octets */
 	u32 txpktsjumbo;	/* total packets (including bad) between 1024
 				   and MAXLength octets */
-} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_t;
+} __attribute__ ((packed));
 
 /* GETH Rx firmware statistics structure, used when calling
    UCC_GETH_GetStatistics. */
-typedef struct ucc_geth_rx_firmware_statistics {
+struct ucc_geth_rx_firmware_statistics {
 	u32 frrxfcser;		/* frames with crc error */
 	u32 fraligner;		/* frames with alignment error */
 	u32 inrangelenrxer;	/* in range length error */
@@ -822,11 +822,11 @@
 				   replaced */
 	u32 insertvlan;		/* total frames that had their VLAN tag
 				   inserted */
-} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_t;
+} __attribute__ ((packed));
 
 /* GETH hardware statistics structure, used when calling
    UCC_GETH_GetStatistics. */
-typedef struct ucc_geth_hardware_statistics {
+struct ucc_geth_hardware_statistics {
 	u32 tx64;		/* Total number of frames (including bad
 				   frames) transmitted that were exactly of the
 				   minimal length (64 for un tagged, 68 for
@@ -871,7 +871,7 @@
 	u32 rbca;		/* Total number of frames received succesfully
 				   that had destination address equal to the
 				   broadcast address */
-} __attribute__ ((packed)) ucc_geth_hardware_statistics_t;
+} __attribute__ ((packed));
 
 /* UCC GETH Tx errors returned via TxConf callback */
 #define TX_ERRORS_DEF      0x0200
@@ -1013,21 +1013,21 @@
 				(MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112)
 
 /* Ethernet speed */
-typedef enum enet_speed {
+enum enet_speed {
 	ENET_SPEED_10BT,	/* 10 Base T */
 	ENET_SPEED_100BT,	/* 100 Base T */
 	ENET_SPEED_1000BT	/* 1000 Base T */
-} enet_speed_e;
+};
 
 /* Ethernet Address Type. */
-typedef enum enet_addr_type {
+enum enet_addr_type {
 	ENET_ADDR_TYPE_INDIVIDUAL,
 	ENET_ADDR_TYPE_GROUP,
 	ENET_ADDR_TYPE_BROADCAST
-} enet_addr_type_e;
+};
 
 /* TBI / MII Set Register */
-typedef enum enet_tbi_mii_reg {
+enum enet_tbi_mii_reg {
 	ENET_TBI_MII_CR = 0x00,	/* Control (CR ) */
 	ENET_TBI_MII_SR = 0x01,	/* Status (SR ) */
 	ENET_TBI_MII_ANA = 0x04,	/* AN advertisement (ANA ) */
@@ -1040,10 +1040,10 @@
 	ENET_TBI_MII_EXST = 0x0F,	/* Extended status (EXST ) */
 	ENET_TBI_MII_JD = 0x10,	/* Jitter diagnostics (JD ) */
 	ENET_TBI_MII_TBICON = 0x11	/* TBI control (TBICON ) */
-} enet_tbi_mii_reg_e;
+};
 
 /* UCC GETH 82xx Ethernet Address Recognition Location */
-typedef enum ucc_geth_enet_address_recognition_location {
+enum ucc_geth_enet_address_recognition_location {
 	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station
 								      address */
 	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST,	/* additional
@@ -1065,10 +1065,10 @@
 	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH,	/* group hash */
 	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual
 								      hash */
-} ucc_geth_enet_address_recognition_location_e;
+};
 
 /* UCC GETH vlan operation tagged */
-typedef enum ucc_geth_vlan_operation_tagged {
+enum ucc_geth_vlan_operation_tagged {
 	UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0,	/* Tagged - nop */
 	UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG
 		= 0x1,	/* Tagged - replace vid portion of q tag */
@@ -1076,18 +1076,18 @@
 		= 0x2,	/* Tagged - if vid0 replace vid with default value  */
 	UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME
 		= 0x3	/* Tagged - extract q tag from frame */
-} ucc_geth_vlan_operation_tagged_e;
+};
 
 /* UCC GETH vlan operation non-tagged */
-typedef enum ucc_geth_vlan_operation_non_tagged {
+enum ucc_geth_vlan_operation_non_tagged {
 	UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0,	/* Non tagged - nop */
 	UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1	/* Non tagged -
 								   q tag insert
 								 */
-} ucc_geth_vlan_operation_non_tagged_e;
+};
 
 /* UCC GETH Rx Quality of Service Mode */
-typedef enum ucc_geth_qos_mode {
+enum ucc_geth_qos_mode {
 	UCC_GETH_QOS_MODE_DEFAULT = 0x0,	/* default queue */
 	UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1,	/* queue
 								   determined
@@ -1097,11 +1097,11 @@
 								   determined
 								   by L3
 								   criteria */
-} ucc_geth_qos_mode_e;
+};
 
 /* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together
    for combined functionality */
-typedef enum ucc_geth_statistics_gathering_mode {
+enum ucc_geth_statistics_gathering_mode {
 	UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000,	/* No
 								   statistics
 								   gathering */
@@ -1122,10 +1122,10 @@
 								      statistics
 								      gathering
 								    */
-} ucc_geth_statistics_gathering_mode_e;
+};
 
 /* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */
-typedef enum ucc_geth_maccfg2_pad_and_crc_mode {
+enum ucc_geth_maccfg2_pad_and_crc_mode {
 	UCC_GETH_PAD_AND_CRC_MODE_NONE
 		= MACCFG2_PAD_AND_CRC_MODE_NONE,	/* Neither Padding
 							   short frames
@@ -1135,61 +1135,59 @@
 							   CRC only */
 	UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC =
 	    MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC
-} ucc_geth_maccfg2_pad_and_crc_mode_e;
+};
 
 /* UCC GETH upsmr Flow Control Mode */
-typedef enum ucc_geth_flow_control_mode {
+enum ucc_geth_flow_control_mode {
 	UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000,	/* No automatic
 								   flow control
 								 */
 	UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY
 		= 0x00004000	/* Send pause frame when RxFIFO reaches its
 				   emergency threshold */
-} ucc_geth_flow_control_mode_e;
+};
 
 /* UCC GETH number of threads */
-typedef enum ucc_geth_num_of_threads {
+enum ucc_geth_num_of_threads {
 	UCC_GETH_NUM_OF_THREADS_1 = 0x1,	/* 1 */
 	UCC_GETH_NUM_OF_THREADS_2 = 0x2,	/* 2 */
 	UCC_GETH_NUM_OF_THREADS_4 = 0x0,	/* 4 */
 	UCC_GETH_NUM_OF_THREADS_6 = 0x3,	/* 6 */
 	UCC_GETH_NUM_OF_THREADS_8 = 0x4	/* 8 */
-} ucc_geth_num_of_threads_e;
+};
 
 /* UCC GETH number of station addresses */
-typedef enum ucc_geth_num_of_station_addresses {
+enum ucc_geth_num_of_station_addresses {
 	UCC_GETH_NUM_OF_STATION_ADDRESSES_1,	/* 1 */
 	UCC_GETH_NUM_OF_STATION_ADDRESSES_5	/* 5 */
-} ucc_geth_num_of_station_addresses_e;
-
-typedef u8 enet_addr_t[ENET_NUM_OCTETS_PER_ADDRESS];
+};
 
 /* UCC GETH 82xx Ethernet Address Container */
-typedef struct enet_addr_container {
-	enet_addr_t address;	/* ethernet address */
-	ucc_geth_enet_address_recognition_location_e location;	/* location in
+struct enet_addr_container {
+	u8 address[ENET_NUM_OCTETS_PER_ADDRESS];	/* ethernet address */
+	enum ucc_geth_enet_address_recognition_location location;	/* location in
 								   82xx address
 								   recognition
 								   hardware */
 	struct list_head node;
-} enet_addr_container_t;
+};
 
-#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, enet_addr_container_t, node)
+#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, struct enet_addr_container, node)
 
 /* UCC GETH Termination Action Descriptor (TAD) structure. */
-typedef struct ucc_geth_tad_params {
+struct ucc_geth_tad_params {
 	int rx_non_dynamic_extended_features_mode;
 	int reject_frame;
-	ucc_geth_vlan_operation_tagged_e vtag_op;
-	ucc_geth_vlan_operation_non_tagged_e vnontag_op;
-	ucc_geth_qos_mode_e rqos;
+	enum ucc_geth_vlan_operation_tagged vtag_op;
+	enum ucc_geth_vlan_operation_non_tagged vnontag_op;
+	enum ucc_geth_qos_mode rqos;
 	u8 vpri;
 	u16 vid;
-} ucc_geth_tad_params_t;
+};
 
 /* GETH protocol initialization structure */
-typedef struct ucc_geth_info {
-	ucc_fast_info_t uf_info;
+struct ucc_geth_info {
+	struct ucc_fast_info uf_info;
 	u8 numQueuesTx;
 	u8 numQueuesRx;
 	int ipCheckSumCheck;
@@ -1251,51 +1249,51 @@
 	u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX];
 	u16 bdRingLenTx[NUM_TX_QUEUES];
 	u16 bdRingLenRx[NUM_RX_QUEUES];
-	enet_interface_e enet_interface;
-	ucc_geth_num_of_station_addresses_e numStationAddresses;
-	 qe_fltr_largest_external_tbl_lookup_key_size_e
+	enum enet_interface enet_interface;
+	enum ucc_geth_num_of_station_addresses numStationAddresses;
+	enum qe_fltr_largest_external_tbl_lookup_key_size
 	    largestexternallookupkeysize;
-	ucc_geth_statistics_gathering_mode_e statisticsMode;
-	ucc_geth_vlan_operation_tagged_e vlanOperationTagged;
-	ucc_geth_vlan_operation_non_tagged_e vlanOperationNonTagged;
-	ucc_geth_qos_mode_e rxQoSMode;
-	ucc_geth_flow_control_mode_e aufc;
-	ucc_geth_maccfg2_pad_and_crc_mode_e padAndCrc;
-	ucc_geth_num_of_threads_e numThreadsTx;
-	ucc_geth_num_of_threads_e numThreadsRx;
-	qe_risc_allocation_e riscTx;
-	qe_risc_allocation_e riscRx;
-} ucc_geth_info_t;
+	enum ucc_geth_statistics_gathering_mode statisticsMode;
+	enum ucc_geth_vlan_operation_tagged vlanOperationTagged;
+	enum ucc_geth_vlan_operation_non_tagged vlanOperationNonTagged;
+	enum ucc_geth_qos_mode rxQoSMode;
+	enum ucc_geth_flow_control_mode aufc;
+	enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc;
+	enum ucc_geth_num_of_threads numThreadsTx;
+	enum ucc_geth_num_of_threads numThreadsRx;
+	enum qe_risc_allocation riscTx;
+	enum qe_risc_allocation riscRx;
+};
 
 /* structure representing UCC GETH */
-typedef struct ucc_geth_private {
-	ucc_geth_info_t *ug_info;
-	ucc_fast_private_t *uccf;
+struct ucc_geth_private {
+	struct ucc_geth_info *ug_info;
+	struct ucc_fast_private *uccf;
 	struct net_device *dev;
 	struct net_device_stats stats;	/* linux network statistics */
-	ucc_geth_t *ug_regs;
-	ucc_geth_init_pram_t *p_init_enet_param_shadow;
-	ucc_geth_exf_global_pram_t *p_exf_glbl_param;
+	struct ucc_geth *ug_regs;
+	struct ucc_geth_init_pram *p_init_enet_param_shadow;
+	struct ucc_geth_exf_global_pram *p_exf_glbl_param;
 	u32 exf_glbl_param_offset;
-	ucc_geth_rx_global_pram_t *p_rx_glbl_pram;
+	struct ucc_geth_rx_global_pram *p_rx_glbl_pram;
 	u32 rx_glbl_pram_offset;
-	ucc_geth_tx_global_pram_t *p_tx_glbl_pram;
+	struct ucc_geth_tx_global_pram *p_tx_glbl_pram;
 	u32 tx_glbl_pram_offset;
-	ucc_geth_send_queue_mem_region_t *p_send_q_mem_reg;
+	struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg;
 	u32 send_q_mem_reg_offset;
-	ucc_geth_thread_data_tx_t *p_thread_data_tx;
+	struct ucc_geth_thread_data_tx *p_thread_data_tx;
 	u32 thread_dat_tx_offset;
-	ucc_geth_thread_data_rx_t *p_thread_data_rx;
+	struct ucc_geth_thread_data_rx *p_thread_data_rx;
 	u32 thread_dat_rx_offset;
-	ucc_geth_scheduler_t *p_scheduler;
+	struct ucc_geth_scheduler *p_scheduler;
 	u32 scheduler_offset;
-	ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram;
+	struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram;
 	u32 tx_fw_statistics_pram_offset;
-	ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram;
+	struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram;
 	u32 rx_fw_statistics_pram_offset;
-	ucc_geth_rx_interrupt_coalescing_table_t *p_rx_irq_coalescing_tbl;
+	struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl;
 	u32 rx_irq_coalescing_tbl_offset;
-	ucc_geth_rx_bd_queues_entry_t *p_rx_bd_qs_tbl;
+	struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl;
 	u32 rx_bd_qs_tbl_offset;
 	u8 *p_tx_bd_ring[NUM_TX_QUEUES];
 	u32 tx_bd_ring_offset[NUM_TX_QUEUES];
@@ -1308,7 +1306,7 @@
 	u16 cpucount[NUM_TX_QUEUES];
 	volatile u16 *p_cpucount[NUM_TX_QUEUES];
 	int indAddrRegUsed[NUM_OF_PADDRS];
-	enet_addr_t paddr[NUM_OF_PADDRS];
+	u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS];	/* ethernet address */
 	u8 numGroupAddrInHash;
 	u8 numIndAddrInHash;
 	u8 numIndAddrInReg;
@@ -1334,6 +1332,6 @@
 	int oldspeed;
 	int oldduplex;
 	int oldlink;
-} ucc_geth_private_t;
+};
 
 #endif				/* __UCC_GETH_H__ */
diff --git a/drivers/net/ucc_geth_phy.c b/drivers/net/ucc_geth_phy.c
index 67260eb..5360ec0 100644
--- a/drivers/net/ucc_geth_phy.c
+++ b/drivers/net/ucc_geth_phy.c
@@ -42,7 +42,6 @@
 
 #include "ucc_geth.h"
 #include "ucc_geth_phy.h"
-#include <platforms/83xx/mpc8360e_pb.h>
 
 #define ugphy_printk(level, format, arg...)  \
         printk(level format "\n", ## arg)
@@ -72,16 +71,14 @@
 u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum);
 void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val);
 
-static u8 *bcsr_regs = NULL;
-
 /* Write value to the PHY for this device to the register at regnum, */
 /* waiting until the write is done before it returns.  All PHY */
 /* configuration has to be done through the TSEC1 MIIM regs */
 void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
-	ucc_mii_mng_t *mii_regs;
-	enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
+	struct ucc_mii_mng *mii_regs;
+	enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum;
 	u32 tmp_reg;
 
 	ugphy_vdbg("%s: IN", __FUNCTION__);
@@ -116,9 +113,9 @@
 /* configuration has to be done through the TSEC1 MIIM regs */
 int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
 {
-	ucc_geth_private_t *ugeth = netdev_priv(dev);
-	ucc_mii_mng_t *mii_regs;
-	enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
+	struct ucc_mii_mng *mii_regs;
+	enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum;
 	u32 tmp_reg;
 	u16 value;
 
@@ -634,11 +631,6 @@
 
 static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info)
 {
-/* FIXME: This lines are for BUG fixing in the mpc8325.
-Remove this from here when it's fixed */
-	if (bcsr_regs == NULL)
-		bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
-	bcsr_regs[14] |= 0x40;
 	ugphy_vdbg("%s: IN", __FUNCTION__);
 
 	/* Clear the interrupts by reading the reg */
@@ -650,12 +642,6 @@
 
 static int dm9161_config_intr(struct ugeth_mii_info *mii_info)
 {
-/* FIXME: This lines are for BUG fixing in the mpc8325.
-Remove this from here when it's fixed */
-	if (bcsr_regs == NULL) {
-		bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
-		bcsr_regs[14] &= ~0x40;
-	}
 	ugphy_vdbg("%s: IN", __FUNCTION__);
 
 	if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
diff --git a/drivers/net/ucc_geth_phy.h b/drivers/net/ucc_geth_phy.h
index 2f98b8f..f574078 100644
--- a/drivers/net/ucc_geth_phy.h
+++ b/drivers/net/ucc_geth_phy.h
@@ -126,7 +126,7 @@
 	/* And management functions */
 	struct phy_info *phyinfo;
 
-	ucc_mii_mng_t *mii_regs;
+	struct ucc_mii_mng *mii_regs;
 
 	/* forced speed & duplex (no autoneg)
 	 * partner speed & duplex & pause (autoneg)
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 58b7efb..b5d0d7f 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -127,7 +127,7 @@
 # There is no way to detect a Sealevel board. Force it modular
 config SEALEVEL_4021
 	tristate "Sealevel Systems 4021 support"
-	depends on WAN && ISA && m && ISA_DMA_API
+	depends on WAN && ISA && m && ISA_DMA_API && INET
 	help
 	  This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
 
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index dcf46ad..5c322df 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -500,7 +500,7 @@
 #ifdef MODULE
 		printk(KERN_INFO "n2: no card initialized\n");
 #endif
-		return -ENOSYS;	/* no parameters specified, abort */
+		return -EINVAL;	/* no parameters specified, abort */
 	}
 
 	printk(KERN_INFO "%s\n", version);
@@ -538,11 +538,11 @@
 			n2_run(io, irq, ram, valid[0], valid[1]);
 
 		if (*hw == '\x0')
-			return first_card ? 0 : -ENOSYS;
+			return first_card ? 0 : -EINVAL;
 	}while(*hw++ == ':');
 
 	printk(KERN_ERR "n2: invalid hardware parameters\n");
-	return first_card ? 0 : -ENOSYS;
+	return first_card ? 0 : -EINVAL;
 }
 
 
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 5823e3b..36d1c3f 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -2867,7 +2867,6 @@
 	uclong clktype = chan->conf.phys_settings.clock_type;
 	ucshort encoding = chan->conf.proto_settings.encoding;
 	ucshort parity = chan->conf.proto_settings.parity;   
-	int tmc, br;
 	ucchar md0, md2;
     
 	/* Reset the channel */
@@ -2940,8 +2939,12 @@
 		case PC300_RSV:
 		case PC300_X21:
 			if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) {
+				int tmc, br;
+
 				/* Calculate the clkrate parameters */
 				tmc = clock_rate_calc(clkrate, card->hw.clock, &br);
+				if (tmc < 0)
+					return -EIO;
 				cpc_writeb(scabase + M_REG(TMCT, ch), tmc);
 				cpc_writeb(scabase + M_REG(TXS, ch),
 					   (TXS_DTRXC | TXS_IBRG | br));
@@ -3097,14 +3100,16 @@
 	return 0;
 }
 
-static void cpc_opench(pc300dev_t * d)
+static int cpc_opench(pc300dev_t * d)
 {
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
 	pc300_t *card = (pc300_t *) chan->card;
-	int ch = chan->channel;
+	int ch = chan->channel, rc;
 	void __iomem *scabase = card->hw.scabase;
 
-	ch_config(d);
+	rc = ch_config(d);
+	if (rc)
+		return rc;
 
 	rx_config(d);
 
@@ -3113,6 +3118,8 @@
 	/* Assert RTS and DTR */
 	cpc_writeb(scabase + M_REG(CTL, ch),
 		   cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
+
+	return 0;
 }
 
 static void cpc_closech(pc300dev_t * d)
@@ -3168,9 +3175,16 @@
 	}
 
 	sprintf(ifr.ifr_name, "%s", dev->name);
-	cpc_opench(d);
+	result = cpc_opench(d);
+	if (result)
+		goto err_out;
+
 	netif_start_queue(dev);
 	return 0;
+
+err_out:
+	hdlc_close(dev);
+	return result;
 }
 
 static int cpc_close(struct net_device *dev)
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 0a33c8a..efcdaf1 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2897,6 +2897,8 @@
 		goto err_out_map;
 	}
 	ai->wifidev = init_wifidev(ai, dev);
+	if (!ai->wifidev)
+		goto err_out_reg;
 
 	set_bit(FLAG_REGISTERED,&ai->flags);
 	airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x",
@@ -2908,11 +2910,18 @@
 		for( i = 0; i < MAX_FIDS; i++ )
 			ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
 
-	setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
+	if (setup_proc_entry(dev, dev->priv) < 0)
+		goto err_out_wifi;
+
 	netif_start_queue(dev);
 	SET_MODULE_OWNER(dev);
 	return dev;
 
+err_out_wifi:
+	unregister_netdev(ai->wifidev);
+	free_netdev(ai->wifidev);
+err_out_reg:
+	unregister_netdev(dev);
 err_out_map:
 	if (test_bit(FLAG_MPI,&ai->flags) && pci) {
 		pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
@@ -3089,7 +3098,8 @@
 						set_bit(JOB_AUTOWEP, &ai->jobs);
 						break;
 					}
-					if (!kthread_should_stop()) {
+					if (!kthread_should_stop() &&
+					    !freezing(current)) {
 						unsigned long wake_at;
 						if (!ai->expires || !ai->scan_timeout) {
 							wake_at = max(ai->expires,
@@ -3101,7 +3111,8 @@
 						schedule_timeout(wake_at - jiffies);
 						continue;
 					}
-				} else if (!kthread_should_stop()) {
+				} else if (!kthread_should_stop() &&
+					   !freezing(current)) {
 					schedule();
 					continue;
 				}
@@ -4495,91 +4506,128 @@
 	apriv->proc_entry = create_proc_entry(apriv->proc_name,
 					      S_IFDIR|airo_perm,
 					      airo_entry);
-        apriv->proc_entry->uid = proc_uid;
-        apriv->proc_entry->gid = proc_gid;
-        apriv->proc_entry->owner = THIS_MODULE;
+	if (!apriv->proc_entry)
+		goto fail;
+	apriv->proc_entry->uid = proc_uid;
+	apriv->proc_entry->gid = proc_gid;
+	apriv->proc_entry->owner = THIS_MODULE;
 
 	/* Setup the StatsDelta */
 	entry = create_proc_entry("StatsDelta",
 				  S_IFREG | (S_IRUGO&proc_perm),
 				  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+	if (!entry)
+		goto fail_stats_delta;
+	entry->uid = proc_uid;
+	entry->gid = proc_gid;
 	entry->data = dev;
-        entry->owner = THIS_MODULE;
+	entry->owner = THIS_MODULE;
 	SETPROC_OPS(entry, proc_statsdelta_ops);
 
 	/* Setup the Stats */
 	entry = create_proc_entry("Stats",
 				  S_IFREG | (S_IRUGO&proc_perm),
 				  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+	if (!entry)
+		goto fail_stats;
+	entry->uid = proc_uid;
+	entry->gid = proc_gid;
 	entry->data = dev;
-        entry->owner = THIS_MODULE;
+	entry->owner = THIS_MODULE;
 	SETPROC_OPS(entry, proc_stats_ops);
 
 	/* Setup the Status */
 	entry = create_proc_entry("Status",
 				  S_IFREG | (S_IRUGO&proc_perm),
 				  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+	if (!entry)
+		goto fail_status;
+	entry->uid = proc_uid;
+	entry->gid = proc_gid;
 	entry->data = dev;
-        entry->owner = THIS_MODULE;
+	entry->owner = THIS_MODULE;
 	SETPROC_OPS(entry, proc_status_ops);
 
 	/* Setup the Config */
 	entry = create_proc_entry("Config",
 				  S_IFREG | proc_perm,
 				  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+	if (!entry)
+		goto fail_config;
+	entry->uid = proc_uid;
+	entry->gid = proc_gid;
 	entry->data = dev;
-        entry->owner = THIS_MODULE;
+	entry->owner = THIS_MODULE;
 	SETPROC_OPS(entry, proc_config_ops);
 
 	/* Setup the SSID */
 	entry = create_proc_entry("SSID",
 				  S_IFREG | proc_perm,
 				  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+	if (!entry)
+		goto fail_ssid;
+	entry->uid = proc_uid;
+	entry->gid = proc_gid;
 	entry->data = dev;
-        entry->owner = THIS_MODULE;
+	entry->owner = THIS_MODULE;
 	SETPROC_OPS(entry, proc_SSID_ops);
 
 	/* Setup the APList */
 	entry = create_proc_entry("APList",
 				  S_IFREG | proc_perm,
 				  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+	if (!entry)
+		goto fail_aplist;
+	entry->uid = proc_uid;
+	entry->gid = proc_gid;
 	entry->data = dev;
-        entry->owner = THIS_MODULE;
+	entry->owner = THIS_MODULE;
 	SETPROC_OPS(entry, proc_APList_ops);
 
 	/* Setup the BSSList */
 	entry = create_proc_entry("BSSList",
 				  S_IFREG | proc_perm,
 				  apriv->proc_entry);
+	if (!entry)
+		goto fail_bsslist;
 	entry->uid = proc_uid;
 	entry->gid = proc_gid;
 	entry->data = dev;
-        entry->owner = THIS_MODULE;
+	entry->owner = THIS_MODULE;
 	SETPROC_OPS(entry, proc_BSSList_ops);
 
 	/* Setup the WepKey */
 	entry = create_proc_entry("WepKey",
 				  S_IFREG | proc_perm,
 				  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+	if (!entry)
+		goto fail_wepkey;
+	entry->uid = proc_uid;
+	entry->gid = proc_gid;
 	entry->data = dev;
-        entry->owner = THIS_MODULE;
+	entry->owner = THIS_MODULE;
 	SETPROC_OPS(entry, proc_wepkey_ops);
 
 	return 0;
+
+fail_wepkey:
+	remove_proc_entry("BSSList", apriv->proc_entry);
+fail_bsslist:
+	remove_proc_entry("APList", apriv->proc_entry);
+fail_aplist:
+	remove_proc_entry("SSID", apriv->proc_entry);
+fail_ssid:
+	remove_proc_entry("Config", apriv->proc_entry);
+fail_config:
+	remove_proc_entry("Status", apriv->proc_entry);
+fail_status:
+	remove_proc_entry("Stats", apriv->proc_entry);
+fail_stats:
+	remove_proc_entry("StatsDelta", apriv->proc_entry);
+fail_stats_delta:
+	remove_proc_entry(apriv->proc_name, airo_entry);
+fail:
+	return -ENOMEM;
 }
 
 static int takedown_proc_entry( struct net_device *dev,
@@ -5924,7 +5972,6 @@
 
 	/* Get the current SSID */
 	memcpy(extra, status_rid.SSID, status_rid.SSIDlen);
-	extra[status_rid.SSIDlen] = '\0';
 	/* If none, we may want to get the one that was set */
 
 	/* Push it out ! */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 31eed85..0c07b8b 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1678,11 +1678,9 @@
 	/* Get the current SSID */
 	if (priv->new_SSID_size != 0) {
 		memcpy(extra, priv->new_SSID, priv->new_SSID_size);
-		extra[priv->new_SSID_size] = '\0';
 		dwrq->length = priv->new_SSID_size;
 	} else {
 		memcpy(extra, priv->SSID, priv->SSID_size);
-		extra[priv->SSID_size] = '\0';
 		dwrq->length = priv->SSID_size;
 	}
 
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
index 76e3aed..978ed09 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
@@ -705,11 +705,30 @@
 	struct bcm43xx_dmaring *ring;
 	int err = -ENOMEM;
 	int dma64 = 0;
-	u32 sbtmstatehi;
+	u64 mask = bcm43xx_get_supported_dma_mask(bcm);
+	int nobits;
 
-	sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
-	if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT)
+	if (mask == DMA_64BIT_MASK) {
 		dma64 = 1;
+		nobits = 64;
+	} else if (mask == DMA_32BIT_MASK)
+		nobits = 32;
+	else
+		nobits = 30;
+	err = pci_set_dma_mask(bcm->pci_dev, mask);
+	err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask);
+	if (err) {
+#ifdef CONFIG_BCM43XX_PIO
+		printk(KERN_WARNING PFX "DMA not supported on this device."
+					" Falling back to PIO.\n");
+		bcm->__using_pio = 1;
+		return -ENOSYS;
+#else
+		printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
+				    "Please recompile the driver with PIO support.\n");
+		return -ENODEV;
+#endif /* CONFIG_BCM43XX_PIO */
+	}
 
 	/* setup TX DMA channels. */
 	ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
@@ -755,8 +774,7 @@
 		dma->rx_ring3 = ring;
 	}
 
-	dprintk(KERN_INFO PFX "%s DMA initialized\n",
-			dma64 ? "64-bit" : "32-bit");
+	dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits);
 	err = 0;
 out:
 	return err;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
index e04bcad..d1105e5 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
@@ -4,6 +4,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
+#include <linux/dma-mapping.h>
 #include <linux/linkage.h>
 #include <asm/atomic.h>
 
@@ -314,6 +315,23 @@
 		   struct ieee80211_txb *txb);
 void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
 
+/* Helper function that returns the dma mask for this device. */
+static inline
+u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm)
+{
+	int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) &
+				   BCM43xx_SBTMSTATEHIGH_DMA64BIT;
+	u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0);
+	u32 mask = BCM43xx_DMA32_TXADDREXT_MASK;
+
+	if (dma64)
+		return DMA_64BIT_MASK;
+	bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask);
+	if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask)
+		return DMA_32BIT_MASK;
+	return DMA_30BIT_MASK;
+}
+
 #else /* CONFIG_BCM43XX_DMA */
 
 
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
index c3f90c8..7d383a2 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -189,20 +189,24 @@
 		case BCM43xx_LED_INACTIVE:
 			continue;
 		case BCM43xx_LED_OFF:
+		case BCM43xx_LED_BCM4303_3:
 			break;
 		case BCM43xx_LED_ON:
 			turn_on = 1;
 			break;
 		case BCM43xx_LED_ACTIVITY:
+		case BCM43xx_LED_BCM4303_0:
 			turn_on = activity;
 			break;
 		case BCM43xx_LED_RADIO_ALL:
 			turn_on = radio->enabled;
 			break;
 		case BCM43xx_LED_RADIO_A:
+		case BCM43xx_LED_BCM4303_2:
 			turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A);
 			break;
 		case BCM43xx_LED_RADIO_B:
+		case BCM43xx_LED_BCM4303_1:
 			turn_on = (radio->enabled &&
 				   (phy->type == BCM43xx_PHYTYPE_B ||
 				    phy->type == BCM43xx_PHYTYPE_G));
@@ -242,7 +246,7 @@
 			//TODO
 			break;
 		case BCM43xx_LED_ASSOC:
-			if (bcm->softmac->associated)
+			if (bcm->softmac->associnfo.associated)
 				turn_on = 1;
 			break;
 #ifdef CONFIG_BCM43XX_DEBUG
@@ -257,7 +261,8 @@
 			continue;
 #endif /* CONFIG_BCM43XX_DEBUG */
 		default:
-			assert(0);
+			dprintkl(KERN_INFO PFX "Bad value in leds_update,"
+				" led->behaviour: 0x%x\n", led->behaviour);
 		};
 
 		if (led->activelow)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
index d3716cf..811e14a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
@@ -46,6 +46,12 @@
 	BCM43xx_LED_TEST_BLINKSLOW,
 	BCM43xx_LED_TEST_BLINKMEDIUM,
 	BCM43xx_LED_TEST_BLINKFAST,
+
+	/* Misc values for BCM4303 */
+	BCM43xx_LED_BCM4303_0 = 0x2B,
+	BCM43xx_LED_BCM4303_1 = 0x78,
+	BCM43xx_LED_BCM4303_2 = 0x2E,
+	BCM43xx_LED_BCM4303_3 = 0x19,
 };
 
 int bcm43xx_leds_init(struct bcm43xx_private *bcm);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index bad3452..a1b7838 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -746,7 +746,7 @@
 	if (err)
 		goto err_ctlreg;
 	spromctl |= 0x10; /* SPROM WRITE enable. */
-	bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
+	err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
 	if (err)
 		goto err_ctlreg;
 	/* We must burn lots of CPU cycles here, but that does not
@@ -768,7 +768,7 @@
 		mdelay(20);
 	}
 	spromctl &= ~0x10; /* SPROM WRITE enable. */
-	bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
+	err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
 	if (err)
 		goto err_ctlreg;
 	mdelay(500);
@@ -1463,6 +1463,23 @@
 	}
 }
 
+static void drain_txstatus_queue(struct bcm43xx_private *bcm)
+{
+	u32 dummy;
+
+	if (bcm->current_core->rev < 5)
+		return;
+	/* Read all entries from the microcode TXstatus FIFO
+	 * and throw them away.
+	 */
+	while (1) {
+		dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
+		if (!dummy)
+			break;
+		dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
+	}
+}
+
 static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm)
 {
 	bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F);
@@ -2925,10 +2942,13 @@
 		bcm43xx_write16(bcm, 0x043C, 0x000C);
 
 	if (active_wlcore) {
-		if (bcm43xx_using_pio(bcm))
+		if (bcm43xx_using_pio(bcm)) {
 			err = bcm43xx_pio_init(bcm);
-		else
+		} else {
 			err = bcm43xx_dma_init(bcm);
+			if (err == -ENOSYS)
+				err = bcm43xx_pio_init(bcm);
+		}
 		if (err)
 			goto err_chip_cleanup;
 	}
@@ -3160,17 +3180,30 @@
 static void bcm43xx_periodic_work_handler(void *d)
 {
 	struct bcm43xx_private *bcm = d;
+	struct net_device *net_dev = bcm->net_dev;
 	unsigned long flags;
 	u32 savedirqs = 0;
 	int badness;
+	unsigned long orig_trans_start = 0;
 
+	mutex_lock(&bcm->mutex);
 	badness = estimate_periodic_work_badness(bcm->periodic_state);
 	if (badness > BADNESS_LIMIT) {
 		/* Periodic work will take a long time, so we want it to
 		 * be preemtible.
 		 */
-		mutex_lock(&bcm->mutex);
-		netif_tx_disable(bcm->net_dev);
+
+		netif_tx_lock_bh(net_dev);
+		/* We must fake a started transmission here, as we are going to
+		 * disable TX. If we wouldn't fake a TX, it would be possible to
+		 * trigger the netdev watchdog, if the last real TX is already
+		 * some time on the past (slightly less than 5secs)
+		 */
+		orig_trans_start = net_dev->trans_start;
+		net_dev->trans_start = jiffies;
+		netif_stop_queue(net_dev);
+		netif_tx_unlock_bh(net_dev);
+
 		spin_lock_irqsave(&bcm->irq_lock, flags);
 		bcm43xx_mac_suspend(bcm);
 		if (bcm43xx_using_pio(bcm))
@@ -3182,7 +3215,6 @@
 		/* Periodic work should take short time, so we want low
 		 * locking overhead.
 		 */
-		mutex_lock(&bcm->mutex);
 		spin_lock_irqsave(&bcm->irq_lock, flags);
 	}
 
@@ -3196,6 +3228,7 @@
 			bcm43xx_pio_thaw_txqueues(bcm);
 		bcm43xx_mac_enable(bcm);
 		netif_wake_queue(bcm->net_dev);
+		net_dev->trans_start = orig_trans_start;
 	}
 	mmiowb();
 	spin_unlock_irqrestore(&bcm->irq_lock, flags);
@@ -3516,6 +3549,7 @@
 	bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
 	bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
 	bcm43xx_security_init(bcm);
+	drain_txstatus_queue(bcm);
 	ieee80211softmac_start(bcm->net_dev);
 
 	/* Let's go! Be careful after enabling the IRQs.
@@ -3993,8 +4027,6 @@
 				struct net_device *net_dev,
 				struct pci_dev *pci_dev)
 {
-	int err;
-
 	bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
 	bcm->ieee = netdev_priv(net_dev);
 	bcm->softmac = ieee80211_priv(net_dev);
@@ -4012,22 +4044,8 @@
 		     (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
 		     (unsigned long)bcm);
 	tasklet_disable_nosync(&bcm->isr_tasklet);
-	if (modparam_pio) {
+	if (modparam_pio)
 		bcm->__using_pio = 1;
-	} else {
-		err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK);
-		err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK);
-		if (err) {
-#ifdef CONFIG_BCM43XX_PIO
-			printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
-			bcm->__using_pio = 1;
-#else
-			printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
-					    "Recompile the driver with PIO support, please.\n");
-			return -ENODEV;
-#endif /* CONFIG_BCM43XX_PIO */
-		}
-	}
 	bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
 
 	/* default to sw encryption for now */
@@ -4208,7 +4226,11 @@
 	dprintk(KERN_INFO PFX "Resuming...\n");
 
 	pci_set_power_state(pdev, 0);
-	pci_enable_device(pdev);
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR PFX "Failure with pci_enable_device!\n");
+		return err;
+	}
 	pci_restore_state(pdev);
 
 	bcm43xx_chipset_attach(bcm);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index 9b7b15c..d27016f 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -847,7 +847,7 @@
 	unsigned long flags;
 
 	wstats = &bcm->stats.wstats;
-	if (!mac->associated) {
+	if (!mac->associnfo.associated) {
 		wstats->miss.beacon = 0;
 //		bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here?
 		wstats->discard.retries = 0;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 686d895..f63909e 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -887,6 +887,13 @@
 	PCMCIA_DEVICE_PROD_ID123(
 		"U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02",
 		0xc7b8df9d, 0x1700d087, 0x4b74baa0),
+	PCMCIA_DEVICE_PROD_ID123(
+		"Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio",
+		"Ver. 1.00",
+		0x5cd01705, 0x4271660f, 0x9d08ee12),
+	PCMCIA_DEVICE_PROD_ID123(
+		"corega", "WL PCCL-11", "ISL37300P",
+		0xa21501a, 0x59868926, 0xc9049a39),
 	PCMCIA_DEVICE_NULL
 };
 MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 6dfa041..bc81b13 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -364,7 +364,7 @@
 
 	pos = 0;
 	while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) {
-		if (pos + cis[pos + 1] >= CIS_MAX_LEN)
+		if (pos + 2 + cis[pos + 1] > CIS_MAX_LEN)
 			goto cis_error;
 
 		switch (cis[pos]) {
@@ -391,7 +391,7 @@
 			break;
 
 		case CISTPL_MANFID:
-			if (cis[pos + 1] < 5)
+			if (cis[pos + 1] < 4)
 				goto cis_error;
 			manfid1 = cis[pos + 2] + (cis[pos + 3] << 8);
 			manfid2 = cis[pos + 4] + (cis[pos + 5] << 8);
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index b779c7d..336caba 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -2457,6 +2457,7 @@
 /* Wireless extensions                                              */
 /********************************************************************/
 
+/* Return : < 0 -> error code ; >= 0 -> length */
 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
 				char buf[IW_ESSID_MAX_SIZE+1])
 {
@@ -2501,9 +2502,9 @@
 	len = le16_to_cpu(essidbuf.len);
 	BUG_ON(len > IW_ESSID_MAX_SIZE);
 
-	memset(buf, 0, IW_ESSID_MAX_SIZE+1);
+	memset(buf, 0, IW_ESSID_MAX_SIZE);
 	memcpy(buf, p, len);
-	buf[len] = '\0';
+	err = len;
 
  fail_unlock:
 	orinoco_unlock(priv, &flags);
@@ -3027,17 +3028,18 @@
 
 	if (netif_running(dev)) {
 		err = orinoco_hw_get_essid(priv, &active, essidbuf);
-		if (err)
+		if (err < 0)
 			return err;
+		erq->length = err;
 	} else {
 		if (orinoco_lock(priv, &flags) != 0)
 			return -EBUSY;
-		memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1);
+		memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
+		erq->length = strlen(priv->desired_essid);
 		orinoco_unlock(priv, &flags);
 	}
 
 	erq->flags = 1;
-	erq->length = strlen(essidbuf);
 
 	return 0;
 }
@@ -3075,10 +3077,10 @@
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
-	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
+	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
 	orinoco_unlock(priv, &flags);
 
-	nrq->length = strlen(nickbuf);
+	nrq->length = strlen(priv->nick);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 0b381d7..7fbfc9e 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1198,7 +1198,6 @@
 
 	/* Get the essid that was set */
 	memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
-	extra[IW_ESSID_MAX_SIZE] = '\0';
 
 	/* Push it out ! */
 	dwrq->length = strlen(extra);
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 30057a3..36b29ff 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -193,10 +193,8 @@
 	struct sk_buff *skb;
 	unsigned char type;
 
-	if (!zd) {
-		free = 1;
-		goto exit;
-	}
+	if (!zd)
+		return;
 
 	switch(urb->status) {
 		case -EILSEQ:
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 2d12837..a7d29bd 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -1099,7 +1099,7 @@
 	int r;
 
 	spin_lock_irq(&mac->lock);
-	is_associated = sm->associated != 0;
+	is_associated = sm->associnfo.associated != 0;
 	spin_unlock_irq(&mac->lock);
 
 	r = zd_chip_control_leds(chip,
diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c
index e3e1927..ec44efd 100644
--- a/drivers/parport/parport_ip32.c
+++ b/drivers/parport/parport_ip32.c
@@ -780,7 +780,7 @@
 	enum parport_ip32_irq_mode irq_mode = priv->irq_mode;
 	switch (irq_mode) {
 	case PARPORT_IP32_IRQ_FWD:
-		parport_generic_irq(irq, p, regs);
+		parport_generic_irq(irq, p);
 		break;
 	case PARPORT_IP32_IRQ_HERE:
 		parport_ip32_wakeup(p);
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index ecc50db..5f1b9f5 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -19,7 +19,7 @@
 
 config PCI_MULTITHREAD_PROBE
 	bool "PCI Multi-threaded probe (EXPERIMENTAL)"
-	depends on PCI && EXPERIMENTAL
+	depends on PCI && EXPERIMENTAL && BROKEN
 	help
 	  Say Y here if you want the PCI core to spawn a new thread for
 	  every PCI device that is probed.  This can cause a huge
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index c44311a..16167b0 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1807,8 +1807,8 @@
 
 
 /*
- * latch closed:  1
- * latch   open:  0
+ * latch   open:  1
+ * latch closed:  0
  */
 u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)
 {
@@ -1816,7 +1816,7 @@
 
 	sta = get_slot_status(slot);
 
-	return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0;
+	return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1;
 }
 
 
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index 0e27f24..0a8d1cc 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -25,97 +25,72 @@
 
 struct ht_irq_cfg {
 	struct pci_dev *dev;
+	 /* Update callback used to cope with buggy hardware */
+	ht_irq_update_t *update;
 	unsigned pos;
 	unsigned idx;
+	struct ht_irq_msg msg;
 };
 
-void write_ht_irq_low(unsigned int irq, u32 data)
+
+void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
 {
 	struct ht_irq_cfg *cfg = get_irq_data(irq);
 	unsigned long flags;
 	spin_lock_irqsave(&ht_irq_lock, flags);
-	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
-	pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
+	if (cfg->msg.address_lo != msg->address_lo) {
+		pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
+		pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_lo);
+	}
+	if (cfg->msg.address_hi != msg->address_hi) {
+		pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);
+		pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_hi);
+	}
+	if (cfg->update)
+		cfg->update(cfg->dev, irq, msg);
 	spin_unlock_irqrestore(&ht_irq_lock, flags);
+	cfg->msg = *msg;
 }
 
-void write_ht_irq_high(unsigned int irq, u32 data)
+void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
 {
 	struct ht_irq_cfg *cfg = get_irq_data(irq);
-	unsigned long flags;
-	spin_lock_irqsave(&ht_irq_lock, flags);
-	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);
-	pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
-	spin_unlock_irqrestore(&ht_irq_lock, flags);
-}
-
-u32 read_ht_irq_low(unsigned int irq)
-{
-	struct ht_irq_cfg *cfg = get_irq_data(irq);
-	unsigned long flags;
-	u32 data;
-	spin_lock_irqsave(&ht_irq_lock, flags);
-	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
-	pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
-	spin_unlock_irqrestore(&ht_irq_lock, flags);
-	return data;
-}
-
-u32 read_ht_irq_high(unsigned int irq)
-{
-	struct ht_irq_cfg *cfg = get_irq_data(irq);
-	unsigned long flags;
-	u32 data;
-	spin_lock_irqsave(&ht_irq_lock, flags);
-	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);
-	pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
-	spin_unlock_irqrestore(&ht_irq_lock, flags);
-	return data;
+	*msg = cfg->msg;
 }
 
 void mask_ht_irq(unsigned int irq)
 {
 	struct ht_irq_cfg *cfg;
-	unsigned long flags;
-	u32 data;
+	struct ht_irq_msg msg;
 
 	cfg = get_irq_data(irq);
 
-	spin_lock_irqsave(&ht_irq_lock, flags);
-	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
-	pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
-	data |= 1;
-	pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
-	spin_unlock_irqrestore(&ht_irq_lock, flags);
+	msg = cfg->msg;
+	msg.address_lo |= 1;
+	write_ht_irq_msg(irq, &msg);
 }
 
 void unmask_ht_irq(unsigned int irq)
 {
 	struct ht_irq_cfg *cfg;
-	unsigned long flags;
-	u32 data;
+	struct ht_irq_msg msg;
 
 	cfg = get_irq_data(irq);
 
-	spin_lock_irqsave(&ht_irq_lock, flags);
-	pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
-	pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
-	data &= ~1;
-	pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
-	spin_unlock_irqrestore(&ht_irq_lock, flags);
+	msg = cfg->msg;
+	msg.address_lo &= ~1;
+	write_ht_irq_msg(irq, &msg);
 }
 
 /**
- * ht_create_irq - create an irq and attach it to a device.
+ * __ht_create_irq - create an irq and attach it to a device.
  * @dev: The hypertransport device to find the irq capability on.
  * @idx: Which of the possible irqs to attach to.
- *
- * ht_create_irq is needs to be called for all hypertransport devices
- * that generate irqs.
+ * @update: Function to be called when changing the htirq message
  *
  * The irq number of the new irq or a negative error value is returned.
  */
-int ht_create_irq(struct pci_dev *dev, int idx)
+int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
 {
 	struct ht_irq_cfg *cfg;
 	unsigned long flags;
@@ -150,8 +125,12 @@
 		return -ENOMEM;
 
 	cfg->dev = dev;
+	cfg->update = update;
 	cfg->pos = pos;
 	cfg->idx = 0x10 + (idx * 2);
+	/* Initialize msg to a value that will never match the first write. */
+	cfg->msg.address_lo = 0xffffffff;
+	cfg->msg.address_hi = 0xffffffff;
 
 	irq = create_irq();
 	if (irq < 0) {
@@ -169,6 +148,21 @@
 }
 
 /**
+ * ht_create_irq - create an irq and attach it to a device.
+ * @dev: The hypertransport device to find the irq capability on.
+ * @idx: Which of the possible irqs to attach to.
+ *
+ * ht_create_irq needs to be called for all hypertransport devices
+ * that generate irqs.
+ *
+ * The irq number of the new irq or a negative error value is returned.
+ */
+int ht_create_irq(struct pci_dev *dev, int idx)
+{
+	return __ht_create_irq(dev, idx, NULL);
+}
+
+/**
  * ht_destroy_irq - destroy an irq created with ht_create_irq
  *
  * This reverses ht_create_irq removing the specified irq from
@@ -186,5 +180,6 @@
 	kfree(cfg);
 }
 
+EXPORT_SYMBOL(__ht_create_irq);
 EXPORT_SYMBOL(ht_create_irq);
 EXPORT_SYMBOL(ht_destroy_irq);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index b1c0c70..194f1d2 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -265,6 +265,13 @@
 	}
 
 	/*
+	 * If the device is still on, set the power state as "unknown",
+	 * since it might change by the next time we load the driver.
+	 */
+	if (pci_dev->current_state == PCI_D0)
+		pci_dev->current_state = PCI_UNKNOWN;
+
+	/*
 	 * We would love to complain here if pci_dev->is_enabled is set, that
 	 * the driver should have called pci_disable_device(), but the
 	 * unfortunate fact is there are too many odd BIOS and bridge setups
@@ -288,6 +295,12 @@
 		suspend_report_result(drv->suspend, i);
 	} else {
 		pci_save_state(pci_dev);
+		/*
+		 * mark its power state as "unknown", since we don't know if
+		 * e.g. the BIOS will change its device state when we suspend.
+		 */
+		if (pci_dev->current_state == PCI_D0)
+			pci_dev->current_state = PCI_UNKNOWN;
 	}
 	return i;
 }
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index a1d2e97..f952bfe 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -642,6 +642,9 @@
  */
 void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
 {
+	if (!sysfs_initialized)
+		return;
+
 	if (pdev->cfg_size < 4096)
 		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
 	else
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e8a7f1b..5b44838 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -714,33 +714,6 @@
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C597_0,	quirk_vt82c598_id );
 
-#ifdef CONFIG_ACPI_SLEEP
-
-/*
- * Some VIA systems boot with the abnormal status flag set. This can cause
- * the BIOS to re-POST the system on resume rather than passing control
- * back to the OS.  Clear the flag on boot
- */
-static void __devinit quirk_via_abnormal_poweroff(struct pci_dev *dev)
-{
-	u32 reg;
-
-	acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
-				&reg);
-
-	if (reg & 0x800) {
-		printk("Clearing abnormal poweroff flag\n");
-		acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-					ACPI_REGISTER_PM1_STATUS,
-					(u16)0x800);
-	}
-}
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_abnormal_poweroff);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_abnormal_poweroff);
-
-#endif
-
 /*
  * CardBus controllers have a legacy base address that enables them
  * to respond as i82365 pcmcia controllers.  We don't want them to
@@ -1487,33 +1460,6 @@
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	0x260a, quirk_intel_pcie_pm);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	0x260b, quirk_intel_pcie_pm);
 
-/*
- * Fixup the cardbus bridges on the IBM Dock II docking station
- */
-static void __devinit quirk_ibm_dock2_cardbus(struct pci_dev *dev)
-{
-	u32 val;
-
-	/*
-	 * tie the 2 interrupt pins to INTA, and configure the
-	 * multifunction routing register to handle this.
-	 */
-	if ((dev->subsystem_vendor == PCI_VENDOR_ID_IBM) &&
-		(dev->subsystem_device == 0x0148)) {
-		printk(KERN_INFO "PCI: Found IBM Dock II Cardbus Bridge "
-			"applying quirk\n");
-		pci_read_config_dword(dev, 0x8c, &val);
-		val = ((val & 0xffffff00) | 0x1002);
-		pci_write_config_dword(dev, 0x8c, val);
-		pci_read_config_dword(dev, 0x80, &val);
-		val = ((val & 0x00ffff00) | 0x2864c077);
-		pci_write_config_dword(dev, 0x80, val);
-	}
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420,
-				quirk_ibm_dock2_cardbus);
-
 static void __devinit quirk_netmos(struct pci_dev *dev)
 {
 	unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4;
@@ -1619,52 +1565,6 @@
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
 
-/*
- * Fixup to mark boot BIOS video selected by BIOS before it changes
- *
- * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
- *
- * The standard boot ROM sequence for an x86 machine uses the BIOS
- * to select an initial video card for boot display. This boot video
- * card will have it's BIOS copied to C0000 in system RAM.
- * IORESOURCE_ROM_SHADOW is used to associate the boot video
- * card with this copy. On laptops this copy has to be used since
- * the main ROM may be compressed or combined with another image.
- * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
- * is marked here since the boot video device will be the only enabled
- * video device at this point.
- */
-
-static void __devinit fixup_video(struct pci_dev *pdev)
-{
-	struct pci_dev *bridge;
-	struct pci_bus *bus;
-	u16 config;
-
-	if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
-		return;
-
-	/* Is VGA routed to us? */
-	bus = pdev->bus;
-	while (bus) {
-		bridge = bus->self;
-		if (bridge) {
-			pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
-						&config);
-			if (!(config & PCI_BRIDGE_CTL_VGA))
-				return;
-		}
-		bus = bus->parent;
-	}
-	pci_read_config_word(pdev, PCI_COMMAND, &config);
-	if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
-		pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
-		printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
-	}
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_video);
-
-
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
 {
 	while (f < end) {
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 43e4a49..e1dcefc 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -72,8 +72,9 @@
 	int last_image;
 
 	/*
-	 * IORESOURCE_ROM_SHADOW set if the VGA enable bit of the Bridge Control
-	 * register is set for embedded VGA.
+	 * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
+	 * memory map if the VGA enable bit of the Bridge Control register is
+	 * set for embedded VGA.
 	 */
 	if (res->flags & IORESOURCE_ROM_SHADOW) {
 		/* primary video rom always starts here */
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 7f5df9a..3bcb7dc 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -241,12 +241,6 @@
 	csa = at91_sys_read(AT91_EBI_CSA);
 	at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
 
-	/* force poweron defaults for these pins ... */
-	(void) at91_set_A_periph(AT91_PIN_PC9, 0);	/* A25/CFRNW */
-	(void) at91_set_A_periph(AT91_PIN_PC10, 0);	/* NCS4/CFCS */
-	(void) at91_set_A_periph(AT91_PIN_PC11, 0);	/* NCS5/CFCE1 */
-	(void) at91_set_A_periph(AT91_PIN_PC12, 0);	/* NCS6/CFCE2 */
-
 	/* nWAIT is _not_ a default setting */
 	(void) at91_set_A_periph(AT91_PIN_PC6, 1);	/*  nWAIT */
 
@@ -316,12 +310,14 @@
 	return 0;
 
 fail2:
-	iounmap((void __iomem *) cf->socket.io_offset);
 	release_mem_region(io->start, io->end + 1 - io->start);
 fail1:
+	if (cf->socket.io_offset)
+		iounmap((void __iomem *) cf->socket.io_offset);
 	if (board->irq_pin)
 		free_irq(board->irq_pin, cf);
 fail0a:
+	device_init_wakeup(&pdev->dev, 0);
 	free_irq(board->det_pin, cf);
 	device_init_wakeup(&pdev->dev, 0);
 fail0:
@@ -360,26 +356,20 @@
 	struct at91_cf_data	*board = cf->board;
 
 	pcmcia_socket_dev_suspend(&pdev->dev, mesg);
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(&pdev->dev)) {
 		enable_irq_wake(board->det_pin);
-	else {
+		if (board->irq_pin)
+			enable_irq_wake(board->irq_pin);
+	} else {
 		disable_irq_wake(board->det_pin);
-		disable_irq(board->det_pin);
+		if (board->irq_pin)
+			disable_irq_wake(board->irq_pin);
 	}
-	if (board->irq_pin)
-		disable_irq(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 (board->irq_pin)
-		enable_irq(board->irq_pin);
-	if (!device_may_wakeup(&pdev->dev))
-		enable_irq(board->det_pin);
 	pcmcia_socket_dev_resume(&pdev->dev);
 	return 0;
 }
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index d5dd0ce..551bde5 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -351,6 +351,7 @@
 int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
 {
 	struct skt_dev_info *sinfo;
+	struct au1000_pcmcia_socket *skt;
 	int ret, i;
 
 	sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
@@ -365,7 +366,7 @@
 	 * Initialise the per-socket structure.
 	 */
 	for (i = 0; i < nr; i++) {
-		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+		skt = PCMCIA_SOCKET(i);
 		memset(skt, 0, sizeof(*skt));
 
 		skt->socket.resource_ops = &pccard_static_ops;
@@ -438,17 +439,29 @@
 	dev_set_drvdata(dev, sinfo);
 	return 0;
 
-	do {
-		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+
+out_err:
+	flush_scheduled_work();
+	ops->hw_shutdown(skt);
+	while (i-- > 0) {
+		skt = PCMCIA_SOCKET(i);
 
 		del_timer_sync(&skt->poll_timer);
 		pcmcia_unregister_socket(&skt->socket);
-out_err:
 		flush_scheduled_work();
+		if (i == 0) {
+			iounmap(skt->virt_io + (u32)mips_io_port_base);
+			skt->virt_io = NULL;
+		}
+#ifndef CONFIG_MIPS_XXS1500
+		else {
+			iounmap(skt->virt_io + (u32)mips_io_port_base);
+			skt->virt_io = NULL;
+		}
+#endif
 		ops->hw_shutdown(skt);
 
-		i--;
-	} while (i > 0);
+	}
 	kfree(sinfo);
 out:
 	return ret;
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 74b3124..21d83a8 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -717,6 +717,7 @@
 static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
 {
 	int no_devices=0;
+	int ret = 0;
 	unsigned long flags;
 
 	/* must be called with skt_mutex held */
@@ -729,7 +730,7 @@
 	 * missing resource information or other trouble, we need to
 	 * do this now. */
 	if (no_devices) {
-		int ret = pcmcia_card_add(skt);
+		ret = pcmcia_card_add(skt);
 		if (ret)
 			return;
 	}
@@ -741,7 +742,9 @@
 
 	/* we re-scan all devices, not just the ones connected to this
 	 * socket. This does not matter, though. */
-	bus_rescan_devices(&pcmcia_bus_type);
+	ret = bus_rescan_devices(&pcmcia_bus_type);
+	if (ret)
+		printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n");
 }
 
 static inline int pcmcia_devmatch(struct pcmcia_device *dev,
@@ -1001,6 +1004,7 @@
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	int ret;
 
 	if (!count)
 		return -EINVAL;
@@ -1009,7 +1013,10 @@
 	p_dev->allow_func_id_match = 1;
 	mutex_unlock(&p_dev->socket->skt_mutex);
 
-	bus_rescan_devices(&pcmcia_bus_type);
+	ret = bus_rescan_devices(&pcmcia_bus_type);
+	if (ret)
+		printk(KERN_INFO "pcmcia: bus_rescan_devices failed after "
+		       "allowing func_id matches\n");
 
 	return count;
 }
@@ -1264,6 +1271,11 @@
 	socket->pcmcia_state.dead = 1;
 	pccard_register_pcmcia(socket, NULL);
 
+	/* unregister any unbound devices */
+	mutex_lock(&socket->skt_mutex);
+	pcmcia_card_remove(socket, NULL);
+	mutex_unlock(&socket->skt_mutex);
+
 	pcmcia_put_socket(socket);
 
 	return;
@@ -1292,10 +1304,22 @@
 
 static int __init init_pcmcia_bus(void)
 {
+	int ret;
+
 	spin_lock_init(&pcmcia_dev_list_lock);
 
-	bus_register(&pcmcia_bus_type);
-	class_interface_register(&pcmcia_bus_interface);
+	ret = bus_register(&pcmcia_bus_type);
+	if (ret < 0) {
+		printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret);
+		return ret;
+	}
+	ret = class_interface_register(&pcmcia_bus_interface);
+	if (ret < 0) {
+		printk(KERN_WARNING
+			"pcmcia: class_interface_register error: %d\n", ret);
+		bus_unregister(&pcmcia_bus_type);
+		return ret;
+	}
 
 	pcmcia_setup_ioctl();
 
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index 82715f4..c2ea07a 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -41,6 +41,7 @@
 };
 MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
 
+#ifdef CONFIG_PM
 static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state)
 {
 	return pcmcia_socket_dev_suspend(&dev->dev, state);
@@ -50,14 +51,17 @@
 {
 	return pcmcia_socket_dev_resume(&dev->dev);
 }
+#endif
 
 static struct pci_driver i82092aa_pci_drv = {
 	.name           = "i82092aa",
 	.id_table       = i82092aa_pci_ids,
 	.probe          = i82092aa_pci_probe,
 	.remove         = __devexit_p(i82092aa_pci_remove),
+#ifdef CONFIG_PM
 	.suspend        = i82092aa_socket_suspend,
 	.resume         = i82092aa_socket_resume,
+#endif
 };
 
 
@@ -705,10 +709,7 @@
 
 static int i82092aa_module_init(void)
 {
-	enter("i82092aa_module_init");
-	pci_register_driver(&i82092aa_pci_drv);
-	leave("i82092aa_module_init");
-	return 0;
+	return pci_register_driver(&i82092aa_pci_drv);
 }
 
 static void i82092aa_module_exit(void)
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index e070a28..3b72be8 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -427,7 +427,7 @@
 			reg |= BCSR1_PCCVCC1;
 			break;
 		default:
-			return 1;
+			goto out_unmap;
 	}
 
 	switch(vpp) {
@@ -438,15 +438,15 @@
 			if(vcc == vpp)
 				reg |= BCSR1_PCCVPP1;
 			else
-				return 1;
+				goto out_unmap;
 			break;
 		case 120:
 			if ((vcc == 33) || (vcc == 50))
 				reg |= BCSR1_PCCVPP0;
 			else
-				return 1;
+				goto out_unmap;
 		default:
-			return 1;
+			goto out_unmap;
 	}
 
 	/* first, turn off all power */
@@ -457,6 +457,10 @@
 
 	iounmap(bcsr_io);
 	return 0;
+
+out_unmap:
+	iounmap(bcsr_io);
+	return 1;
 }
 
 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index c8e838c..06bf7f4 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -309,9 +309,10 @@
 	return 0;
 
 fail2:
-	iounmap((void __iomem *) cf->socket.io_offset);
 	release_mem_region(cf->phys_cf, SZ_8K);
 fail1:
+	if (cf->socket.io_offset)
+		iounmap((void __iomem *) cf->socket.io_offset);
 	free_irq(irq, cf);
 fail0:
 	kfree(cf);
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 9ad18e6..310ede5 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -128,9 +128,12 @@
 			     int count, int *eof, void *data)
 {
 	char *p = buf;
+	int rc;
 
-	bus_for_each_drv(&pcmcia_bus_type, NULL,
-			 (void *) &p, proc_read_drivers_callback);
+	rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
+			      (void *) &p, proc_read_drivers_callback);
+	if (rc < 0)
+		return rc;
 
 	return (p - buf);
 }
@@ -269,8 +272,10 @@
 	 * Prevent this racing with a card insertion.
 	 */
 	mutex_lock(&s->skt_mutex);
-	bus_rescan_devices(&pcmcia_bus_type);
+	ret = bus_rescan_devices(&pcmcia_bus_type);
 	mutex_unlock(&s->skt_mutex);
+	if (ret)
+		goto err_put_module;
 
 	/* check whether the driver indeed matched. I don't care if this
 	 * is racy or not, because it can only happen on cardmgr access
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 74cebd4..b9201c2 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -95,7 +95,7 @@
 	 * potential conflicts, just the most obvious ones.
 	 */
 	for (i = 0; i < MAX_IO_WIN; i++)
-		if ((s->io[i].res) &&
+		if ((s->io[i].res) && *base &&
 		    ((s->io[i].res->start & (align-1)) == *base))
 			return 1;
 	for (i = 0; i < MAX_IO_WIN; i++) {
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index c83a0a6..a70f97f 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -755,6 +755,7 @@
 	kfree(socket);
 }
 
+#ifdef CONFIG_PM
 static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state)
 {
 	return pcmcia_socket_dev_suspend(&dev->dev, state);
@@ -764,6 +765,7 @@
 {
 	return pcmcia_socket_dev_resume(&dev->dev);
 }
+#endif
 
 static struct pci_device_id pd6729_pci_ids[] = {
 	{
@@ -781,8 +783,10 @@
 	.id_table	= pd6729_pci_ids,
 	.probe		= pd6729_pci_probe,
 	.remove		= __devexit_p(pd6729_pci_remove),
+#ifdef CONFIG_PM
 	.suspend	= pd6729_socket_suspend,
 	.resume		= pd6729_socket_resume,
+#endif
 };
 
 static int pd6729_module_init(void)
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index b351813..dca9f85 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -166,7 +166,7 @@
 }
 #endif
 
-int pxa2xx_drv_pcmcia_probe(struct device *dev)
+int __pxa2xx_drv_pcmcia_probe(struct device *dev)
 {
 	int ret;
 	struct pcmcia_low_level *ops;
@@ -203,35 +203,52 @@
 
 	return ret;
 }
-EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe);
+EXPORT_SYMBOL(__pxa2xx_drv_pcmcia_probe);
 
-static int pxa2xx_drv_pcmcia_resume(struct device *dev)
+
+static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
 {
-	struct pcmcia_low_level *ops = dev->platform_data;
+	return __pxa2xx_drv_pcmcia_probe(&dev->dev);
+}
+
+static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
+{
+	return soc_common_drv_pcmcia_remove(&dev->dev);
+}
+
+static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
+{
+	struct pcmcia_low_level *ops = dev->dev.platform_data;
 	int nr = ops ? ops->nr : 0;
 
 	MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
 
-	return pcmcia_socket_dev_resume(dev);
+	return pcmcia_socket_dev_resume(&dev->dev);
 }
 
-static struct device_driver pxa2xx_pcmcia_driver = {
+static struct platform_driver pxa2xx_pcmcia_driver = {
 	.probe		= pxa2xx_drv_pcmcia_probe,
-	.remove		= soc_common_drv_pcmcia_remove,
-	.suspend 	= pcmcia_socket_dev_suspend,
+	.remove		= pxa2xx_drv_pcmcia_remove,
+	.suspend 	= pxa2xx_drv_pcmcia_suspend,
 	.resume 	= pxa2xx_drv_pcmcia_resume,
-	.name		= "pxa2xx-pcmcia",
-	.bus		= &platform_bus_type,
+	.driver		= {
+		.name	= "pxa2xx-pcmcia",
+	},
 };
 
 static int __init pxa2xx_pcmcia_init(void)
 {
-	return driver_register(&pxa2xx_pcmcia_driver);
+	return platform_driver_register(&pxa2xx_pcmcia_driver);
 }
 
 static void __exit pxa2xx_pcmcia_exit(void)
 {
-	driver_unregister(&pxa2xx_pcmcia_driver);
+	platform_driver_unregister(&pxa2xx_pcmcia_driver);
 }
 
 fs_initcall(pxa2xx_pcmcia_init);
diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h
index e46cff3..235d681 100644
--- a/drivers/pcmcia/pxa2xx_base.h
+++ b/drivers/pcmcia/pxa2xx_base.h
@@ -1,3 +1,3 @@
 /* temporary measure */
-extern int pxa2xx_drv_pcmcia_probe(struct device *);
+extern int __pxa2xx_drv_pcmcia_probe(struct device *);
 
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
index fd1f691..a92f111 100644
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ b/drivers/pcmcia/pxa2xx_lubbock.c
@@ -260,7 +260,7 @@
 		lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
 
 		sadev->dev.platform_data = &lubbock_pcmcia_ops;
-		ret = pxa2xx_drv_pcmcia_probe(&sadev->dev);
+		ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev);
 	}
 
 	return ret;
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 3627e52..e433704 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -824,3 +824,4 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(soc_common_drv_pcmcia_remove);
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 26229d9..da471bd 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -1197,8 +1197,12 @@
 	ret = pcmcia_register_socket(&socket->socket);
 	if (ret == 0) {
 		/* Add the yenta register attributes */
-		device_create_file(&dev->dev, &dev_attr_yenta_registers);
-		goto out;
+		ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
+		if (ret == 0)
+			goto out;
+
+		/* error path... */
+		pcmcia_unregister_socket(&socket->socket);
 	}
 
  unmap:
@@ -1213,7 +1217,7 @@
 	return ret;
 }
 
-
+#ifdef CONFIG_PM
 static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state)
 {
 	struct yenta_socket *socket = pci_get_drvdata(dev);
@@ -1248,12 +1252,18 @@
 	struct yenta_socket *socket = pci_get_drvdata(dev);
 
 	if (socket) {
+		int rc;
+
 		pci_set_power_state(dev, 0);
 		/* FIXME: pci_restore_state needs to have a better interface */
 		pci_restore_state(dev);
 		pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
 		pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
-		pci_enable_device(dev);
+
+		rc = pci_enable_device(dev);
+		if (rc)
+			return rc;
+
 		pci_set_master(dev);
 
 		if (socket->type && socket->type->restore_state)
@@ -1262,7 +1272,7 @@
 
 	return pcmcia_socket_dev_resume(&dev->dev);
 }
-
+#endif
 
 #define CB_ID(vend,dev,type)				\
 	{						\
@@ -1359,8 +1369,10 @@
 	.id_table	= yenta_table,
 	.probe		= yenta_probe,
 	.remove		= __devexit_p(yenta_close),
+#ifdef CONFIG_PM
 	.suspend	= yenta_dev_suspend,
 	.resume		= yenta_dev_resume,
+#endif
 };
 
 
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 579cd66..6f11f6d 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -145,6 +145,13 @@
 }
 EXPORT_SYMBOL_GPL(rtc_set_alarm);
 
+/**
+ * rtc_update_irq - report RTC periodic, alarm, and/or update irqs
+ * @class_dev: the rtc's class device
+ * @num: how many irqs are being reported (usually one)
+ * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF
+ * Context: in_interrupt(), irqs blocked
+ */
 void rtc_update_irq(struct class_device *class_dev,
 		unsigned long num, unsigned long events)
 {
@@ -201,12 +208,12 @@
 	if (task == NULL || task->func == NULL)
 		return -EINVAL;
 
-	spin_lock(&rtc->irq_task_lock);
+	spin_lock_irq(&rtc->irq_task_lock);
 	if (rtc->irq_task == NULL) {
 		rtc->irq_task = task;
 		retval = 0;
 	}
-	spin_unlock(&rtc->irq_task_lock);
+	spin_unlock_irq(&rtc->irq_task_lock);
 
 	return retval;
 }
@@ -216,10 +223,10 @@
 {
 	struct rtc_device *rtc = to_rtc_device(class_dev);
 
-	spin_lock(&rtc->irq_task_lock);
+	spin_lock_irq(&rtc->irq_task_lock);
 	if (rtc->irq_task == task)
 		rtc->irq_task = NULL;
-	spin_unlock(&rtc->irq_task_lock);
+	spin_unlock_irq(&rtc->irq_task_lock);
 }
 EXPORT_SYMBOL_GPL(rtc_irq_unregister);
 
@@ -265,3 +272,4 @@
 	}
 	return err;
 }
+EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
diff --git a/drivers/rtc/rtc-at91.c b/drivers/rtc/rtc-at91.c
index bd61e99..5c8addc 100644
--- a/drivers/rtc/rtc-at91.c
+++ b/drivers/rtc/rtc-at91.c
@@ -292,7 +292,8 @@
 					AT91_RTC_CALEV);
 
 	ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
-				IRQF_SHARED, "at91_rtc", pdev);
+				IRQF_DISABLED | IRQF_SHARED,
+				"at91_rtc", pdev);
 	if (ret) {
 		printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n",
 				AT91_ID_SYS);
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 583789c..814b9e1 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -61,7 +61,9 @@
 	int err;
 
 	err = rtc_read_time(&rtc->class_dev, &tm);
-	spin_lock_irq(&rtc->irq_lock);
+
+	local_irq_disable();
+	spin_lock(&rtc->irq_lock);
 	if (rtc->stop_uie_polling || err) {
 		rtc->uie_task_active = 0;
 	} else if (rtc->oldsecs != tm.tm_sec) {
@@ -74,11 +76,11 @@
 	} else if (schedule_work(&rtc->uie_task) == 0) {
 		rtc->uie_task_active = 0;
 	}
-	spin_unlock_irq(&rtc->irq_lock);
+	spin_unlock(&rtc->irq_lock);
 	if (num)
 		rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF);
+	local_irq_enable();
 }
-
 static void rtc_uie_timer(unsigned long data)
 {
 	struct rtc_device *rtc = (struct rtc_device *)data;
@@ -214,7 +216,7 @@
 	struct rtc_wkalrm alarm;
 	void __user *uarg = (void __user *) arg;
 
-	/* check that the calles has appropriate permissions
+	/* check that the calling task has appropriate permissions
 	 * for certain ioctls. doing this check here is useful
 	 * to avoid duplicate code in each driver.
 	 */
@@ -238,10 +240,10 @@
 
 	/* avoid conflicting IRQ users */
 	if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
-		spin_lock(&rtc->irq_task_lock);
+		spin_lock_irq(&rtc->irq_task_lock);
 		if (rtc->irq_task)
 			err = -EBUSY;
-		spin_unlock(&rtc->irq_task_lock);
+		spin_unlock_irq(&rtc->irq_task_lock);
 
 		if (err < 0)
 			return err;
@@ -299,6 +301,17 @@
 
 		err = rtc_set_time(class_dev, &tm);
 		break;
+
+	case RTC_IRQP_READ:
+		if (ops->irq_set_freq)
+			err = put_user(rtc->irq_freq, (unsigned long *) arg);
+		break;
+
+	case RTC_IRQP_SET:
+		if (ops->irq_set_freq)
+			err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg);
+		break;
+
 #if 0
 	case RTC_EPOCH_SET:
 #ifndef rtc_epoch
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 78552e6..001eb11 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -340,7 +340,8 @@
 
 	if (pdata->irq >= 0) {
 		writeb(0, ioaddr + RTC_INTERRUPTS);
-		if (request_irq(pdata->irq, ds1553_rtc_interrupt, IRQF_SHARED,
+		if (request_irq(pdata->irq, ds1553_rtc_interrupt,
+				IRQF_DISABLED | IRQF_SHARED,
 				pdev->name, pdev) < 0) {
 			dev_warn(&pdev->dev, "interrupt not available.\n");
 			pdata->irq = -1;
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 2a86632..a44fe4e 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -126,13 +126,13 @@
 		return -EIO;
 	}
 
-	dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim);
-
 	if (osc)
 		*osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768;
 
-	if (trim)
+	if (trim) {
 		*trim = buf & RS5C372_TRIM_MASK;
+		dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim);
+	}
 
 	return 0;
 }
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index bc4bd24..6ef9c62 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -99,6 +99,7 @@
 	struct rtc_device *rtc = platform_get_drvdata(plat_dev);
 
 	retval = count;
+	local_irq_disable();
 	if (strncmp(buf, "tick", 4) == 0)
 		rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF);
 	else if (strncmp(buf, "alarm", 5) == 0)
@@ -107,6 +108,7 @@
 		rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF);
 	else
 		retval = -EINVAL;
+	local_irq_enable();
 
 	return retval;
 }
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index a2dee5b..ad7f7e1 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -271,10 +271,6 @@
 		/* Reset intparm to zeroes. */
 		sch->schib.pmcw.intparm = 0;
 		cio_modify(sch);
-
-		/* Probe if necessary. */
-		if (action == UNREGISTER_PROBE)
-			ret = css_probe_device(sch->schid);
 		break;
 	case REPROBE:
 		device_trigger_reprobe(sch);
@@ -283,6 +279,9 @@
 		break;
 	}
 	spin_unlock_irqrestore(&sch->lock, flags);
+	/* Probe if necessary. */
+	if (action == UNREGISTER_PROBE)
+		ret = css_probe_device(sch->schid);
 
 	return ret;
 }
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 94bdd4d..39c98f9 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -532,8 +532,7 @@
 
 /* this is a simple abstraction for device_register that sets the
  * correct bus type and adds the bus specific files */
-int
-ccw_device_register(struct ccw_device *cdev)
+static int ccw_device_register(struct ccw_device *cdev)
 {
 	struct device *dev = &cdev->dev;
 	int ret;
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index c6140cc..9233b5c 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -78,7 +78,6 @@
 
 int ccw_device_cancel_halt_clear(struct ccw_device *);
 
-int ccw_device_register(struct ccw_device *);
 void ccw_device_do_unreg_rereg(void *);
 void ccw_device_call_sch_unregister(void *);
 
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index c5ccd20..79d89c3 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -739,11 +739,16 @@
 		dev = bus_find_device(&ap_bus_type, NULL,
 				      (void *)(unsigned long)qid,
 				      __ap_scan_bus);
+		rc = ap_query_queue(qid, &queue_depth, &device_type);
+		if (dev && rc) {
+			put_device(dev);
+			device_unregister(dev);
+			continue;
+		}
 		if (dev) {
 			put_device(dev);
 			continue;
 		}
-		rc = ap_query_queue(qid, &queue_depth, &device_type);
 		if (rc)
 			continue;
 		rc = ap_init_queue(qid);
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 8f88269..74c0eac 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -107,6 +107,10 @@
 	(ZFCP_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2)
         /* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */
 
+#define ZFCP_MAX_SECTORS (ZFCP_MAX_SBALES_PER_REQ * 8)
+        /* max. number of (data buffer) SBALEs in largest SBAL chain
+           multiplied with number of sectors per 4k block */
+
 /* FIXME(tune): free space should be one max. SBAL chain plus what? */
 #define ZFCP_QDIO_PCI_INTERVAL		(QDIO_MAX_BUFFERS_PER_Q \
                                          - (ZFCP_MAX_SBALS_PER_REQ + 4))
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 4d2bc79..452d96f 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -58,6 +58,7 @@
 		.cmd_per_lun		= 1,
 		.use_clustering		= 1,
 		.sdev_attrs		= zfcp_sysfs_sdev_attrs,
+		.max_sectors		= ZFCP_MAX_SECTORS,
 	},
 	.driver_version = ZFCP_VERSION,
 };
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
index 935952e..98fcbb3 100644
--- a/drivers/sbus/sbus.c
+++ b/drivers/sbus/sbus.c
@@ -61,11 +61,11 @@
 	else
 		sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev;
 	sdev->ofdev.dev.bus = &sbus_bus_type;
-	strcpy(sdev->ofdev.dev.bus_id, dp->path_component_name);
+	sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node);
 
 	if (of_device_register(&sdev->ofdev) != 0)
 		printk(KERN_DEBUG "sbus: device registration error for %s!\n",
-		       sdev->ofdev.dev.bus_id);
+		       dp->path_component_name);
 }
 
 static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus)
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 5f8c26c..b091a0f 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -66,6 +66,9 @@
    2.26.02.006 - Fix 9550SX pchip reset timeout.
                  Add big endian support.
    2.26.02.007 - Disable local interrupts during kmap/unmap_atomic().
+   2.26.02.008 - Free irq handler in __twa_shutdown().
+                 Serialize reset code.
+                 Add support for 9650SE controllers.
 */
 
 #include <linux/module.h>
@@ -89,7 +92,7 @@
 #include "3w-9xxx.h"
 
 /* Globals */
-#define TW_DRIVER_VERSION "2.26.02.007"
+#define TW_DRIVER_VERSION "2.26.02.008"
 static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
 static unsigned int twa_device_extension_count;
 static int twa_major = -1;
@@ -566,9 +569,9 @@
 		goto out;
 	}
 
-	tw_dev->working_srl = fw_on_ctlr_srl;
-	tw_dev->working_branch = fw_on_ctlr_branch;
-	tw_dev->working_build = fw_on_ctlr_build;
+	tw_dev->tw_compat_info.working_srl = fw_on_ctlr_srl;
+	tw_dev->tw_compat_info.working_branch = fw_on_ctlr_branch;
+	tw_dev->tw_compat_info.working_build = fw_on_ctlr_build;
 
 	/* Try base mode compatibility */
 	if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
@@ -590,10 +593,23 @@
 			}
 			goto out;
 		}
-		tw_dev->working_srl = TW_BASE_FW_SRL;
-		tw_dev->working_branch = TW_BASE_FW_BRANCH;
-		tw_dev->working_build = TW_BASE_FW_BUILD;
+		tw_dev->tw_compat_info.working_srl = TW_BASE_FW_SRL;
+		tw_dev->tw_compat_info.working_branch = TW_BASE_FW_BRANCH;
+		tw_dev->tw_compat_info.working_build = TW_BASE_FW_BUILD;
 	}
+
+	/* Load rest of compatibility struct */
+	strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
+	tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
+	tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
+	tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
+	tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
+	tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
+	tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
+	tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
+	tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
+	tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
+
 	retval = 0;
 out:
 	return retval;
@@ -631,7 +647,7 @@
 		goto out2;
 
 	/* Check data buffer size */
-	if (driver_command.buffer_length > TW_MAX_SECTORS * 512) {
+	if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
 		retval = TW_IOCTL_ERROR_OS_EINVAL;
 		goto out2;
 	}
@@ -680,13 +696,6 @@
 		/* Now wait for command to complete */
 		timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
 
-		/* See if we reset while waiting for the ioctl to complete */
-		if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
-			clear_bit(TW_IN_RESET, &tw_dev->flags);
-			retval = TW_IOCTL_ERROR_OS_ERESTARTSYS;
-			goto out3;
-		}
-
 		/* We timed out, and didn't get an interrupt */
 		if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
 			/* Now we need to reset the board */
@@ -694,11 +703,6 @@
 			       tw_dev->host->host_no, TW_DRIVER, 0xc,
 			       cmd);
 			retval = TW_IOCTL_ERROR_OS_EIO;
-			spin_lock_irqsave(tw_dev->host->host_lock, flags);
-			tw_dev->state[request_id] = TW_S_COMPLETED;
-			twa_free_request_id(tw_dev, request_id);
-			tw_dev->posted_request_count--;
-			spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 			twa_reset_device_extension(tw_dev, 1);
 			goto out3;
 		}
@@ -717,16 +721,7 @@
 		tw_ioctl->driver_command.status = 0;
 		/* Copy compatiblity struct into ioctl data buffer */
 		tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
-		strncpy(tw_compat_info->driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
-		tw_compat_info->working_srl = tw_dev->working_srl;
-		tw_compat_info->working_branch = tw_dev->working_branch;
-		tw_compat_info->working_build = tw_dev->working_build;
-		tw_compat_info->driver_srl_high = TW_CURRENT_DRIVER_SRL;
-		tw_compat_info->driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
-		tw_compat_info->driver_build_high = TW_CURRENT_DRIVER_BUILD;
-		tw_compat_info->driver_srl_low = TW_BASE_FW_SRL;
-		tw_compat_info->driver_branch_low = TW_BASE_FW_BRANCH;
-		tw_compat_info->driver_build_low = TW_BASE_FW_BUILD;
+		memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
 		break;
 	case TW_IOCTL_GET_LAST_EVENT:
 		if (tw_dev->event_queue_wrapped) {
@@ -895,7 +890,8 @@
 	}
 
 	if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
-		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
+		if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags)))
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
 		writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
 	}
 
@@ -939,10 +935,12 @@
 	unsigned long before;
 	int retval = 1;
 
-	if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) {
+	if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) ||
+	    (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) {
 		before = jiffies;
 		while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) {
 			response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
+			msleep(1);
 			if (time_after(jiffies, before + HZ * 30))
 				goto out;
 		}
@@ -1214,6 +1212,10 @@
 
 	handled = 1;
 
+	/* If we are resetting, bail */
+	if (test_bit(TW_IN_RESET, &tw_dev->flags))
+		goto twa_interrupt_bail;
+
 	/* Check controller for errors */
 	if (twa_check_bits(status_reg_value)) {
 		if (twa_decode_bits(tw_dev, status_reg_value)) {
@@ -1355,8 +1357,8 @@
 
 	if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
 		newcommand = &full_command_packet->command.newcommand;
-		newcommand->request_id__lunl = 
-			TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id);
+		newcommand->request_id__lunl =
+			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
 		newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
 		newcommand->sg_list[0].length = cpu_to_le32(length);
 		newcommand->sgl_entries__lunh =
@@ -1531,6 +1533,13 @@
 	int retval = 1;
 
 	command_que_value = tw_dev->command_packet_phys[request_id];
+
+	/* For 9650SE write low 4 bytes first */
+	if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) {
+		command_que_value += TW_COMMAND_OFFSET;
+		writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev));
+	}
+
 	status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
 
 	if (twa_check_bits(status_reg_value))
@@ -1557,13 +1566,17 @@
 		TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
 		goto out;
 	} else {
-		/* We successfully posted the command packet */
-		if (sizeof(dma_addr_t) > 4) {
-			command_que_value += TW_COMMAND_OFFSET;
-			writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
-			writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4);
+		if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) {
+			/* Now write upper 4 bytes */
+			writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4);
 		} else {
-			writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
+			if (sizeof(dma_addr_t) > 4) {
+				command_que_value += TW_COMMAND_OFFSET;
+				writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
+				writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4);
+			} else {
+				writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
+			}
 		}
 		tw_dev->state[request_id] = TW_S_POSTED;
 		tw_dev->posted_request_count++;
@@ -1620,14 +1633,9 @@
 		goto out;
 
 	TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+	clear_bit(TW_IN_RESET, &tw_dev->flags);
+	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
 
-	/* Wake up any ioctl that was pending before the reset */
-	if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)) {
-		clear_bit(TW_IN_RESET, &tw_dev->flags);
-	} else {
-		tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
-		wake_up(&tw_dev->ioctl_wqueue);
-	}
 	retval = 0;
 out:
 	return retval;
@@ -1736,6 +1744,9 @@
 		"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
 		TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
 
+	/* Make sure we are not issuing an ioctl or resetting from ioctl */
+	mutex_lock(&tw_dev->ioctl_lock);
+
 	/* Now reset the card and some of the device extension data */
 	if (twa_reset_device_extension(tw_dev, 0)) {
 		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
@@ -1744,6 +1755,7 @@
 
 	retval = SUCCESS;
 out:
+	mutex_unlock(&tw_dev->ioctl_lock);
 	return retval;
 } /* End twa_scsi_eh_reset() */
 
@@ -1753,8 +1765,14 @@
 	int request_id, retval;
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
 
+	/* If we are resetting due to timed out ioctl, report as busy */
+	if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
+		retval = SCSI_MLQUEUE_HOST_BUSY;
+		goto out;
+	}
+
 	/* Check if this FW supports luns */
-	if ((SCpnt->device->lun != 0) && (tw_dev->working_srl < TW_FW_SRL_LUNS_SUPPORTED)) {
+	if ((SCpnt->device->lun != 0) && (tw_dev->tw_compat_info.working_srl < TW_FW_SRL_LUNS_SUPPORTED)) {
 		SCpnt->result = (DID_BAD_TARGET << 16);
 		done(SCpnt);
 		retval = 0;
@@ -1960,6 +1978,9 @@
 	/* Disable interrupts */
 	TW_DISABLE_INTERRUPTS(tw_dev);
 
+	/* Free up the IRQ */
+	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
 	printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no);
 
 	/* Tell the card we are shutting down */
@@ -2091,21 +2112,25 @@
 
 	/* Initialize the card */
 	if (twa_reset_sequence(tw_dev, 0))
-		goto out_release_mem_region;
+		goto out_iounmap;
 
 	/* Set host specific parameters */
-	host->max_id = TW_MAX_UNITS;
+	if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE)
+		host->max_id = TW_MAX_UNITS_9650SE;
+	else
+		host->max_id = TW_MAX_UNITS;
+
 	host->max_cmd_len = TW_MAX_CDB_LEN;
 
 	/* Channels aren't supported by adapter */
-	host->max_lun = TW_MAX_LUNS(tw_dev->working_srl);
+	host->max_lun = TW_MAX_LUNS(tw_dev->tw_compat_info.working_srl);
 	host->max_channel = 0;
 
 	/* Register the card with the kernel SCSI layer */
 	retval = scsi_add_host(host, &pdev->dev);
 	if (retval) {
 		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed");
-		goto out_release_mem_region;
+		goto out_iounmap;
 	}
 
 	pci_set_drvdata(pdev, host);
@@ -2145,6 +2170,8 @@
 
 out_remove_host:
 	scsi_remove_host(host);
+out_iounmap:
+	iounmap(tw_dev->base_addr);
 out_release_mem_region:
 	pci_release_regions(pdev);
 out_free_device_extension:
@@ -2170,12 +2197,12 @@
 		twa_major = -1;
 	}
 
-	/* Free up the IRQ */
-	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
-
 	/* Shutdown the card */
 	__twa_shutdown(tw_dev);
 
+	/* Free IO remapping */
+	iounmap(tw_dev->base_addr);
+
 	/* Free up the mem region */
 	pci_release_regions(pdev);
 
@@ -2193,6 +2220,8 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h
index e5685be..7901517 100644
--- a/drivers/scsi/3w-9xxx.h
+++ b/drivers/scsi/3w-9xxx.h
@@ -289,7 +289,6 @@
 #define TW_STATUS_VALID_INTERRUPT              0x00DF0000
 
 /* PCI related defines */
-#define TW_NUMDEVICES 1
 #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
 #define TW_PCI_CLEAR_PCI_ABORT     0x2000
 
@@ -335,6 +334,7 @@
 #define TW_ALIGNMENT_9000                     4  /* 4 bytes */
 #define TW_ALIGNMENT_9000_SGL                 0x3
 #define TW_MAX_UNITS			      16
+#define TW_MAX_UNITS_9650SE		      32
 #define TW_INIT_MESSAGE_CREDITS		      0x100
 #define TW_INIT_COMMAND_PACKET_SIZE	      0x3
 #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED  0x6
@@ -354,7 +354,6 @@
 #define TW_MAX_RESPONSE_DRAIN		      256
 #define TW_MAX_AEN_DRAIN		      40
 #define TW_IN_RESET                           2
-#define TW_IN_CHRDEV_IOCTL                    3
 #define TW_IN_ATTENTION_LOOP		      4
 #define TW_MAX_SECTORS                        256
 #define TW_AEN_WAIT_TIME                      1000
@@ -417,6 +416,9 @@
 #ifndef PCI_DEVICE_ID_3WARE_9550SX
 #define PCI_DEVICE_ID_3WARE_9550SX 0x1003
 #endif
+#ifndef PCI_DEVICE_ID_3WARE_9650SE
+#define PCI_DEVICE_ID_3WARE_9650SE 0x1004
+#endif
 
 /* Bitmask macros to eliminate bitfields */
 
@@ -442,6 +444,7 @@
 #define TW_CONTROL_REG_ADDR(x) (x->base_addr)
 #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
 #define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
+#define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x20)
 #define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC)
 #define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30)
 #define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
@@ -626,6 +629,9 @@
 	unsigned short driver_srl_low;
 	unsigned short driver_branch_low;
 	unsigned short driver_build_low;
+	unsigned short fw_on_ctlr_srl;
+	unsigned short fw_on_ctlr_branch;
+	unsigned short fw_on_ctlr_build;
 } TW_Compatibility_Info;
 
 #pragma pack()
@@ -668,9 +674,7 @@
 	wait_queue_head_t	ioctl_wqueue;
 	struct mutex		ioctl_lock;
 	char			aen_clobber;
-	unsigned short		working_srl;
-	unsigned short		working_branch;
-	unsigned short		working_build;
+	TW_Compatibility_Info	tw_compat_info;
 } TW_Device_Extension;
 
 #endif /* _3W_9XXX_H */
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h
index df3346b..170a434 100644
--- a/drivers/scsi/aic7xxx/aic79xx.h
+++ b/drivers/scsi/aic7xxx/aic79xx.h
@@ -53,14 +53,6 @@
 struct scb_platform_data;
 
 /****************************** Useful Macros *********************************/
-#ifndef MAX
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef MIN
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
 #ifndef TRUE
 #define TRUE 1
 #endif
@@ -972,8 +964,6 @@
 
 int		ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
 				  u_int start_addr, u_int count);
-int		ahd_wait_seeprom(struct ahd_softc *ahd);
-int		ahd_verify_vpd_cksum(struct vpd_config *vpd);
 int		ahd_verify_cksum(struct seeprom_config *sc);
 int		ahd_acquire_seeprom(struct ahd_softc *ahd);
 void		ahd_release_seeprom(struct ahd_softc *ahd);
@@ -1320,8 +1310,6 @@
 	char			*name;
 	ahd_device_setup_t	*setup;
 };
-extern struct ahd_pci_identity ahd_pci_ident_table [];
-extern const u_int ahd_num_pci_devs;
 
 /***************************** VL/EISA Declarations ***************************/
 struct aic7770_identity {
@@ -1339,15 +1327,6 @@
 /*************************** Function Declarations ****************************/
 /******************************************************************************/
 void			ahd_reset_cmds_pending(struct ahd_softc *ahd);
-u_int			ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl);
-void			ahd_busy_tcl(struct ahd_softc *ahd,
-				     u_int tcl, u_int busyid);
-static __inline void	ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl);
-static __inline void
-ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
-{
-	ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
-}
 
 /***************************** PCI Front End *********************************/
 struct	ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t);
@@ -1356,7 +1335,6 @@
 int	ahd_pci_test_register_access(struct ahd_softc *);
 
 /************************** SCB and SCB queue management **********************/
-int		ahd_probe_scbs(struct ahd_softc *);
 void		ahd_qinfifo_requeue_tail(struct ahd_softc *ahd,
 					 struct scb *scb);
 int		ahd_match_scb(struct ahd_softc *ahd, struct scb *scb,
@@ -1374,33 +1352,20 @@
 int			 ahd_parse_cfgdata(struct ahd_softc *ahd,
 					   struct seeprom_config *sc);
 void			 ahd_intr_enable(struct ahd_softc *ahd, int enable);
-void			 ahd_update_coalescing_values(struct ahd_softc *ahd,
-						      u_int timer,
-						      u_int maxcmds,
-						      u_int mincmds);
-void			 ahd_enable_coalescing(struct ahd_softc *ahd,
-					       int enable);
 void			 ahd_pause_and_flushwork(struct ahd_softc *ahd);
 int			 ahd_suspend(struct ahd_softc *ahd); 
-int			 ahd_resume(struct ahd_softc *ahd);
 void			 ahd_set_unit(struct ahd_softc *, int);
 void			 ahd_set_name(struct ahd_softc *, char *);
 struct scb		*ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
 void			 ahd_free_scb(struct ahd_softc *ahd, struct scb *scb);
-void			 ahd_alloc_scbs(struct ahd_softc *ahd);
 void			 ahd_free(struct ahd_softc *ahd);
 int			 ahd_reset(struct ahd_softc *ahd, int reinit);
-void			 ahd_shutdown(void *arg);
 int			 ahd_write_flexport(struct ahd_softc *ahd,
 					    u_int addr, u_int value);
 int			 ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
 					   uint8_t *value);
-int			 ahd_wait_flexport(struct ahd_softc *ahd);
 
 /*************************** Interrupt Services *******************************/
-void			ahd_pci_intr(struct ahd_softc *ahd);
-void			ahd_clear_intstat(struct ahd_softc *ahd);
-void			ahd_flush_qoutfifo(struct ahd_softc *ahd);
 void			ahd_run_qoutfifo(struct ahd_softc *ahd);
 #ifdef AHD_TARGET_MODE
 void			ahd_run_tqinfifo(struct ahd_softc *ahd, int paused);
@@ -1409,7 +1374,6 @@
 void			ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat);
 void			ahd_handle_scsiint(struct ahd_softc *ahd,
 					   u_int intstat);
-void			ahd_clear_critical_section(struct ahd_softc *ahd);
 
 /***************************** Error Recovery *********************************/
 typedef enum {
@@ -1426,23 +1390,9 @@
 					     char channel, int lun, u_int tag,
 					     int stop_on_first, int remove,
 					     int save_state);
-void			ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
 int			ahd_reset_channel(struct ahd_softc *ahd, char channel,
 					  int initiate_reset);
-int			ahd_abort_scbs(struct ahd_softc *ahd, int target,
-				       char channel, int lun, u_int tag,
-				       role_t role, uint32_t status);
-void			ahd_restart(struct ahd_softc *ahd);
-void			ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo);
-void			ahd_handle_scb_status(struct ahd_softc *ahd,
-					      struct scb *scb);
-void			ahd_handle_scsi_status(struct ahd_softc *ahd,
-					       struct scb *scb);
-void			ahd_calc_residual(struct ahd_softc *ahd,
-					  struct scb *scb);
 /*************************** Utility Functions ********************************/
-struct ahd_phase_table_entry*
-			ahd_lookup_phase_entry(int phase);
 void			ahd_compile_devinfo(struct ahd_devinfo *devinfo,
 					    u_int our_id, u_int target,
 					    u_int lun, char channel,
@@ -1450,14 +1400,6 @@
 /************************** Transfer Negotiation ******************************/
 void			ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
 					  u_int *ppr_options, u_int maxsync);
-void			ahd_validate_offset(struct ahd_softc *ahd,
-					    struct ahd_initiator_tinfo *tinfo,
-					    u_int period, u_int *offset,
-					    int wide, role_t role);
-void			ahd_validate_width(struct ahd_softc *ahd,
-					   struct ahd_initiator_tinfo *tinfo,
-					   u_int *bus_width,
-					   role_t role);
 /*
  * Negotiation types.  These are used to qualify if we should renegotiate
  * even if our goal and current transport parameters are identical.
@@ -1486,11 +1428,6 @@
 	AHD_QUEUE_TAGGED
 } ahd_queue_alg;
 
-void			ahd_set_tags(struct ahd_softc *ahd,
-				     struct scsi_cmnd *cmd,
-				     struct ahd_devinfo *devinfo,
-				     ahd_queue_alg alg);
-
 /**************************** Target Mode *************************************/
 #ifdef AHD_TARGET_MODE
 void		ahd_send_lstate_events(struct ahd_softc *,
@@ -1528,10 +1465,8 @@
 #define AHD_SHOW_INT_COALESCING	0x10000
 #define AHD_DEBUG_SEQUENCER	0x20000
 #endif
-void			ahd_print_scb(struct scb *scb);
 void			ahd_print_devinfo(struct ahd_softc *ahd,
 					  struct ahd_devinfo *devinfo);
-void			ahd_dump_sglist(struct scb *scb);
 void			ahd_dump_card_state(struct ahd_softc *ahd);
 int			ahd_print_register(ahd_reg_parse_entry_t *table,
 					   u_int num_entries,
@@ -1540,5 +1475,4 @@
 					   u_int value,
 					   u_int *cur_column,
 					   u_int wrap_point);
-void			ahd_dump_scbs(struct ahd_softc *ahd);
 #endif /* _AIC79XX_H_ */
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 653818d..07a86a3 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -52,7 +52,7 @@
 
 
 /***************************** Lookup Tables **********************************/
-char *ahd_chip_names[] =
+static char *ahd_chip_names[] =
 {
 	"NONE",
 	"aic7901",
@@ -237,10 +237,33 @@
 					      struct target_cmd *cmd);
 #endif
 
+static int		ahd_abort_scbs(struct ahd_softc *ahd, int target,
+				       char channel, int lun, u_int tag,
+				       role_t role, uint32_t status);
+static void		ahd_alloc_scbs(struct ahd_softc *ahd);
+static void		ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl,
+				     u_int scbid);
+static void		ahd_calc_residual(struct ahd_softc *ahd,
+					  struct scb *scb);
+static void		ahd_clear_critical_section(struct ahd_softc *ahd);
+static void		ahd_clear_intstat(struct ahd_softc *ahd);
+static void		ahd_enable_coalescing(struct ahd_softc *ahd,
+					      int enable);
+static u_int		ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl);
+static void		ahd_freeze_devq(struct ahd_softc *ahd,
+					struct scb *scb);
+static void		ahd_handle_scb_status(struct ahd_softc *ahd,
+					      struct scb *scb);
+static struct ahd_phase_table_entry* ahd_lookup_phase_entry(int phase);
+static void		ahd_shutdown(void *arg);
+static void		ahd_update_coalescing_values(struct ahd_softc *ahd,
+						     u_int timer,
+						     u_int maxcmds,
+						     u_int mincmds);
+static int		ahd_verify_vpd_cksum(struct vpd_config *vpd);
+static int		ahd_wait_seeprom(struct ahd_softc *ahd);
+
 /******************************** Private Inlines *****************************/
-static __inline void	ahd_assert_atn(struct ahd_softc *ahd);
-static __inline int	ahd_currently_packetized(struct ahd_softc *ahd);
-static __inline int	ahd_set_active_fifo(struct ahd_softc *ahd);
 
 static __inline void
 ahd_assert_atn(struct ahd_softc *ahd)
@@ -294,11 +317,44 @@
 	}
 }
 
+static __inline void
+ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
+{
+	ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
+}
+
+/*
+ * Determine whether the sequencer reported a residual
+ * for this SCB/transaction.
+ */
+static __inline void
+ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
+{
+	uint32_t sgptr;
+
+	sgptr = ahd_le32toh(scb->hscb->sgptr);
+	if ((sgptr & SG_STATUS_VALID) != 0)
+		ahd_calc_residual(ahd, scb);
+}
+
+static __inline void
+ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb)
+{
+	uint32_t sgptr;
+
+	sgptr = ahd_le32toh(scb->hscb->sgptr);
+	if ((sgptr & SG_STATUS_VALID) != 0)
+		ahd_handle_scb_status(ahd, scb);
+	else
+		ahd_done(ahd, scb);
+}
+
+
 /************************* Sequencer Execution Control ************************/
 /*
  * Restart the sequencer program from address zero
  */
-void
+static void
 ahd_restart(struct ahd_softc *ahd)
 {
 
@@ -342,7 +398,7 @@
 	ahd_unpause(ahd);
 }
 
-void
+static void
 ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo)
 {
 	ahd_mode_state	 saved_modes;
@@ -366,7 +422,7 @@
  * Flush and completed commands that are sitting in the command
  * complete queues down on the chip but have yet to be dma'ed back up.
  */
-void
+static void
 ahd_flush_qoutfifo(struct ahd_softc *ahd)
 {
 	struct		scb *scb;
@@ -905,6 +961,51 @@
 	ahd_free(ahd);
 }
 
+#ifdef AHD_DEBUG
+static void
+ahd_dump_sglist(struct scb *scb)
+{
+	int i;
+
+	if (scb->sg_count > 0) {
+		if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) {
+			struct ahd_dma64_seg *sg_list;
+
+			sg_list = (struct ahd_dma64_seg*)scb->sg_list;
+			for (i = 0; i < scb->sg_count; i++) {
+				uint64_t addr;
+				uint32_t len;
+
+				addr = ahd_le64toh(sg_list[i].addr);
+				len = ahd_le32toh(sg_list[i].len);
+				printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
+				       i,
+				       (uint32_t)((addr >> 32) & 0xFFFFFFFF),
+				       (uint32_t)(addr & 0xFFFFFFFF),
+				       sg_list[i].len & AHD_SG_LEN_MASK,
+				       (sg_list[i].len & AHD_DMA_LAST_SEG)
+				     ? " Last" : "");
+			}
+		} else {
+			struct ahd_dma_seg *sg_list;
+
+			sg_list = (struct ahd_dma_seg*)scb->sg_list;
+			for (i = 0; i < scb->sg_count; i++) {
+				uint32_t len;
+
+				len = ahd_le32toh(sg_list[i].len);
+				printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
+				       i,
+				       (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
+				       ahd_le32toh(sg_list[i].addr),
+				       len & AHD_SG_LEN_MASK,
+				       len & AHD_DMA_LAST_SEG ? " Last" : "");
+			}
+		}
+	}
+}
+#endif  /*  AHD_DEBUG  */
+
 void
 ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
 {
@@ -1053,10 +1154,12 @@
 			 * If a target takes us into the command phase
 			 * assume that it has been externally reset and
 			 * has thus lost our previous packetized negotiation
-			 * agreement.
-			 * Revert to async/narrow transfers until we
-			 * can renegotiate with the device and notify
-			 * the OSM about the reset.
+			 * agreement.  Since we have not sent an identify
+			 * message and may not have fully qualified the
+			 * connection, we change our command to TUR, assert
+			 * ATN and ABORT the task when we go to message in
+			 * phase.  The OSM will see the REQUEUE_REQUEST
+			 * status and retry the command.
 			 */
 			scbid = ahd_get_scbptr(ahd);
 			scb = ahd_lookup_scb(ahd, scbid);
@@ -1083,7 +1186,28 @@
 			ahd_set_syncrate(ahd, &devinfo, /*period*/0,
 					 /*offset*/0, /*ppr_options*/0,
 					 AHD_TRANS_ACTIVE, /*paused*/TRUE);
-			scb->flags |= SCB_EXTERNAL_RESET;
+			/* Hand-craft TUR command */
+			ahd_outb(ahd, SCB_CDB_STORE, 0);
+			ahd_outb(ahd, SCB_CDB_STORE+1, 0);
+			ahd_outb(ahd, SCB_CDB_STORE+2, 0);
+			ahd_outb(ahd, SCB_CDB_STORE+3, 0);
+			ahd_outb(ahd, SCB_CDB_STORE+4, 0);
+			ahd_outb(ahd, SCB_CDB_STORE+5, 0);
+			ahd_outb(ahd, SCB_CDB_LEN, 6);
+			scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE);
+			scb->hscb->control |= MK_MESSAGE;
+			ahd_outb(ahd, SCB_CONTROL, scb->hscb->control);
+			ahd_outb(ahd, MSG_OUT, HOST_MSG);
+			ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
+			/*
+			 * The lun is 0, regardless of the SCB's lun
+			 * as we have not sent an identify message.
+			 */
+			ahd_outb(ahd, SAVED_LUN, 0);
+			ahd_outb(ahd, SEQ_FLAGS, 0);
+			ahd_assert_atn(ahd);
+			scb->flags &= ~SCB_PACKETIZED;
+			scb->flags |= SCB_ABORT|SCB_EXTERNAL_RESET;
 			ahd_freeze_devq(ahd, scb);
 			ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
 			ahd_freeze_scb(scb);
@@ -1519,8 +1643,10 @@
 	/*
 	 * Ignore external resets after a bus reset.
 	 */
-	if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE))
+	if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE)) {
+		ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
 		return;
+	}
 
 	/*
 	 * Clear bus reset flag
@@ -2200,6 +2326,22 @@
 			if (sent_msg == MSG_ABORT_TAG)
 				tag = SCB_GET_TAG(scb);
 
+			if ((scb->flags & SCB_EXTERNAL_RESET) != 0) {
+				/*
+				 * This abort is in response to an
+				 * unexpected switch to command phase
+				 * for a packetized connection.  Since
+				 * the identify message was never sent,
+				 * "saved lun" is 0.  We really want to
+				 * abort only the SCB that encountered
+				 * this error, which could have a different
+				 * lun.  The SCB will be retried so the OS
+				 * will see the UA after renegotiating to
+				 * packetized.
+				 */
+				tag = SCB_GET_TAG(scb);
+				saved_lun = scb->hscb->lun;
+			}
 			found = ahd_abort_scbs(ahd, target, 'A', saved_lun,
 					       tag, ROLE_INITIATOR,
 					       CAM_REQ_ABORTED);
@@ -2523,7 +2665,7 @@
 }
 
 #define AHD_MAX_STEPS 2000
-void
+static void
 ahd_clear_critical_section(struct ahd_softc *ahd)
 {
 	ahd_mode_state	saved_modes;
@@ -2646,7 +2788,7 @@
 /*
  * Clear any pending interrupt status.
  */
-void
+static void
 ahd_clear_intstat(struct ahd_softc *ahd)
 {
 	AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
@@ -2677,6 +2819,8 @@
 #ifdef AHD_DEBUG
 uint32_t ahd_debug = AHD_DEBUG_OPTS;
 #endif
+
+#if 0
 void
 ahd_print_scb(struct scb *scb)
 {
@@ -2701,49 +2845,7 @@
 	       SCB_GET_TAG(scb));
 	ahd_dump_sglist(scb);
 }
-
-void
-ahd_dump_sglist(struct scb *scb)
-{
-	int i;
-
-	if (scb->sg_count > 0) {
-		if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) {
-			struct ahd_dma64_seg *sg_list;
-
-			sg_list = (struct ahd_dma64_seg*)scb->sg_list;
-			for (i = 0; i < scb->sg_count; i++) {
-				uint64_t addr;
-				uint32_t len;
-
-				addr = ahd_le64toh(sg_list[i].addr);
-				len = ahd_le32toh(sg_list[i].len);
-				printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
-				       i,
-				       (uint32_t)((addr >> 32) & 0xFFFFFFFF),
-				       (uint32_t)(addr & 0xFFFFFFFF),
-				       sg_list[i].len & AHD_SG_LEN_MASK,
-				       (sg_list[i].len & AHD_DMA_LAST_SEG)
-				     ? " Last" : "");
-			}
-		} else {
-			struct ahd_dma_seg *sg_list;
-
-			sg_list = (struct ahd_dma_seg*)scb->sg_list;
-			for (i = 0; i < scb->sg_count; i++) {
-				uint32_t len;
-
-				len = ahd_le32toh(sg_list[i].len);
-				printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
-				       i,
-				       (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
-				       ahd_le32toh(sg_list[i].addr),
-				       len & AHD_SG_LEN_MASK,
-				       len & AHD_DMA_LAST_SEG ? " Last" : "");
-			}
-		}
-	}
-}
+#endif  /*  0  */
 
 /************************* Transfer Negotiation *******************************/
 /*
@@ -2850,14 +2952,14 @@
 		transinfo = &tinfo->goal;
 	*ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN);
 	if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
-		maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2);
+		maxsync = max(maxsync, (u_int)AHD_SYNCRATE_ULTRA2);
 		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
 	}
 	if (transinfo->period == 0) {
 		*period = 0;
 		*ppr_options = 0;
 	} else {
-		*period = MAX(*period, transinfo->period);
+		*period = max(*period, (u_int)transinfo->period);
 		ahd_find_syncrate(ahd, period, ppr_options, maxsync);
 	}
 }
@@ -2906,7 +3008,7 @@
  * Truncate the given synchronous offset to a value the
  * current adapter type and syncrate are capable of.
  */
-void
+static void
 ahd_validate_offset(struct ahd_softc *ahd,
 		    struct ahd_initiator_tinfo *tinfo,
 		    u_int period, u_int *offset, int wide,
@@ -2924,12 +3026,12 @@
 			maxoffset = MAX_OFFSET_PACED;
 	} else
 		maxoffset = MAX_OFFSET_NON_PACED;
-	*offset = MIN(*offset, maxoffset);
+	*offset = min(*offset, maxoffset);
 	if (tinfo != NULL) {
 		if (role == ROLE_TARGET)
-			*offset = MIN(*offset, tinfo->user.offset);
+			*offset = min(*offset, (u_int)tinfo->user.offset);
 		else
-			*offset = MIN(*offset, tinfo->goal.offset);
+			*offset = min(*offset, (u_int)tinfo->goal.offset);
 	}
 }
 
@@ -2937,7 +3039,7 @@
  * Truncate the given transfer width parameter to a value the
  * current adapter type is capable of.
  */
-void
+static void
 ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo,
 		   u_int *bus_width, role_t role)
 {
@@ -2955,9 +3057,9 @@
 	}
 	if (tinfo != NULL) {
 		if (role == ROLE_TARGET)
-			*bus_width = MIN(tinfo->user.width, *bus_width);
+			*bus_width = min((u_int)tinfo->user.width, *bus_width);
 		else
-			*bus_width = MIN(tinfo->goal.width, *bus_width);
+			*bus_width = min((u_int)tinfo->goal.width, *bus_width);
 	}
 }
 
@@ -3210,7 +3312,7 @@
 /*
  * Update the current state of tagged queuing for a given target.
  */
-void
+static void
 ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
 	     struct ahd_devinfo *devinfo, ahd_queue_alg alg)
 {
@@ -3466,7 +3568,7 @@
 	       devinfo->target, devinfo->lun);
 }
 
-struct ahd_phase_table_entry*
+static struct ahd_phase_table_entry*
 ahd_lookup_phase_entry(int phase)
 {
 	struct ahd_phase_table_entry *entry;
@@ -5351,7 +5453,7 @@
 	return;
 }
 
-void
+static void
 ahd_shutdown(void *arg)
 {
 	struct	ahd_softc *ahd;
@@ -5480,7 +5582,7 @@
 /*
  * Determine the number of SCBs available on the controller
  */
-int
+static int
 ahd_probe_scbs(struct ahd_softc *ahd) {
 	int i;
 
@@ -5929,7 +6031,7 @@
 	ahd_platform_scb_free(ahd, scb);
 }
 
-void
+static void
 ahd_alloc_scbs(struct ahd_softc *ahd)
 {
 	struct scb_data *scb_data;
@@ -6057,9 +6159,9 @@
 #endif
 	}
 
-	newcount = MIN(scb_data->sense_left, scb_data->scbs_left);
-	newcount = MIN(newcount, scb_data->sgs_left);
-	newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));
+	newcount = min(scb_data->sense_left, scb_data->scbs_left);
+	newcount = min(newcount, scb_data->sgs_left);
+	newcount = min(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));
 	for (i = 0; i < newcount; i++) {
 		struct scb_platform_data *pdata;
 		u_int col_tag;
@@ -6982,7 +7084,7 @@
 	ahd_outb(ahd, HCNTRL, hcntrl);
 }
 
-void
+static void
 ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
 			     u_int mincmds)
 {
@@ -7000,7 +7102,7 @@
 	ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds);
 }
 
-void
+static void
 ahd_enable_coalescing(struct ahd_softc *ahd, int enable)
 {
 
@@ -7070,6 +7172,7 @@
 	ahd->flags &= ~AHD_ALL_INTERRUPTS;
 }
 
+#if 0
 int
 ahd_suspend(struct ahd_softc *ahd)
 {
@@ -7083,7 +7186,9 @@
 	ahd_shutdown(ahd);
 	return (0);
 }
+#endif  /*  0  */
 
+#if 0
 int
 ahd_resume(struct ahd_softc *ahd)
 {
@@ -7093,6 +7198,7 @@
 	ahd_restart(ahd);
 	return (0);
 }
+#endif  /*  0  */
 
 /************************** Busy Target Table *********************************/
 /*
@@ -7125,7 +7231,7 @@
 /*
  * Return the untagged transaction id for a given target/channel lun.
  */
-u_int
+static u_int
 ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
 {
 	u_int scbid;
@@ -7138,7 +7244,7 @@
 	return (scbid);
 }
 
-void
+static void
 ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid)
 {
 	u_int scb_offset;
@@ -7186,7 +7292,7 @@
 	return match;
 }
 
-void
+static void
 ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
 {
 	int	target;
@@ -7690,7 +7796,7 @@
  * been modified from CAM_REQ_INPROG.  This routine assumes that the sequencer
  * is paused before it is called.
  */
-int
+static int
 ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
 	       int lun, u_int tag, role_t role, uint32_t status)
 {
@@ -7920,6 +8026,11 @@
 	ahd_clear_fifo(ahd, 1);
 
 	/*
+	 * Clear SCSI interrupt status
+	 */
+	ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
+
+	/*
 	 * Reenable selections
 	 */
 	ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST);
@@ -7952,10 +8063,6 @@
 		}
 	}
 #endif
-	/* Notify the XPT that a bus reset occurred */
-	ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
-		       CAM_LUN_WILDCARD, AC_BUS_RESET);
-
 	/*
 	 * Revert to async/narrow transfers until we renegotiate.
 	 */
@@ -7977,6 +8084,10 @@
 		}
 	}
 
+	/* Notify the XPT that a bus reset occurred */
+	ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
+		       CAM_LUN_WILDCARD, AC_BUS_RESET);
+
 	ahd_restart(ahd);
 
 	return (found);
@@ -8019,18 +8130,8 @@
 }
 
 /****************************** Status Processing *****************************/
-void
-ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb)
-{
-	if (scb->hscb->shared_data.istatus.scsi_status != 0) {
-		ahd_handle_scsi_status(ahd, scb);
-	} else {
-		ahd_calc_residual(ahd, scb);
-		ahd_done(ahd, scb);
-	}
-}
 
-void
+static void
 ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
 {
 	struct	hardware_scb *hscb;
@@ -8238,10 +8339,21 @@
 	}
 }
 
+static void
+ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb)
+{
+	if (scb->hscb->shared_data.istatus.scsi_status != 0) {
+		ahd_handle_scsi_status(ahd, scb);
+	} else {
+		ahd_calc_residual(ahd, scb);
+		ahd_done(ahd, scb);
+	}
+}
+
 /*
  * Calculate the residual for a just completed SCB.
  */
-void
+static void
 ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
 {
 	struct hardware_scb *hscb;
@@ -8668,7 +8780,7 @@
 		if (skip_addr > i) {
 			int end_addr;
 
-			end_addr = MIN(address, skip_addr);
+			end_addr = min(address, skip_addr);
 			address_offset += end_addr - i;
 			i = skip_addr;
 		} else {
@@ -9092,6 +9204,7 @@
 		ahd_unpause(ahd);
 }
 
+#if 0
 void
 ahd_dump_scbs(struct ahd_softc *ahd)
 {
@@ -9117,6 +9230,7 @@
 	ahd_set_scbptr(ahd, saved_scb_index);
 	ahd_restore_modes(ahd, saved_modes);
 }
+#endif  /*  0  */
 
 /**************************** Flexport Logic **********************************/
 /*
@@ -9219,7 +9333,7 @@
 /*
  * Wait ~100us for the serial eeprom to satisfy our request.
  */
-int
+static int
 ahd_wait_seeprom(struct ahd_softc *ahd)
 {
 	int cnt;
@@ -9237,7 +9351,7 @@
  * Validate the two checksums in the per_channel
  * vital product data struct.
  */
-int
+static int
 ahd_verify_vpd_cksum(struct vpd_config *vpd)
 {
 	int i;
@@ -9316,6 +9430,24 @@
 	/* Currently a no-op */
 }
 
+/*
+ * Wait at most 2 seconds for flexport arbitration to succeed.
+ */
+static int
+ahd_wait_flexport(struct ahd_softc *ahd)
+{
+	int cnt;
+
+	AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
+	cnt = 1000000 * 2 / 5;
+	while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
+		ahd_delay(5);
+
+	if (cnt == 0)
+		return (ETIMEDOUT);
+	return (0);
+}
+
 int
 ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value)
 {
@@ -9357,24 +9489,6 @@
 	return (0);
 }
 
-/*
- * Wait at most 2 seconds for flexport arbitration to succeed.
- */
-int
-ahd_wait_flexport(struct ahd_softc *ahd)
-{
-	int cnt;
-
-	AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
-	cnt = 1000000 * 2 / 5;
-	while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
-		ahd_delay(5);
-
-	if (cnt == 0)
-		return (ETIMEDOUT);
-	return (0);
-}
-
 /************************* Target Mode ****************************************/
 #ifdef AHD_TARGET_MODE
 cam_status
diff --git a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h
index a3266e0..2ceb67f 100644
--- a/drivers/scsi/aic7xxx/aic79xx_inline.h
+++ b/drivers/scsi/aic7xxx/aic79xx_inline.h
@@ -418,10 +418,6 @@
 }
 
 /*********************** Miscelaneous Support Functions ***********************/
-static __inline void	ahd_complete_scb(struct ahd_softc *ahd,
-					 struct scb *scb);
-static __inline void	ahd_update_residual(struct ahd_softc *ahd,
-					    struct scb *scb);
 static __inline struct ahd_initiator_tinfo *
 			ahd_fetch_transinfo(struct ahd_softc *ahd,
 					    char channel, u_int our_id,
@@ -467,32 +463,6 @@
 			ahd_get_sense_bufaddr(struct ahd_softc *ahd,
 					      struct scb *scb);
 
-static __inline void
-ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb)
-{
-	uint32_t sgptr;
-
-	sgptr = ahd_le32toh(scb->hscb->sgptr);
-	if ((sgptr & SG_STATUS_VALID) != 0)
-		ahd_handle_scb_status(ahd, scb);
-	else
-		ahd_done(ahd, scb);
-}
-
-/*
- * Determine whether the sequencer reported a residual
- * for this SCB/transaction.
- */
-static __inline void
-ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
-{
-	uint32_t sgptr;
-
-	sgptr = ahd_le32toh(scb->hscb->sgptr);
-	if ((sgptr & SG_STATUS_VALID) != 0)
-		ahd_calc_residual(ahd, scb);
-}
-
 /*
  * Return pointers to the transfer negotiation information
  * for the specified our_id/remote_id pair.
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index f8e6048..9bfcca5 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -293,7 +293,7 @@
  * force all outstanding transactions to be serviced prior to a new
  * transaction.
  */
-uint32_t aic79xx_periodic_otag;
+static uint32_t aic79xx_periodic_otag;
 
 /* Some storage boxes are using an LSI chip which has a bug making it
  * impossible to use aic79xx Rev B chip in 320 speeds.  The following
@@ -773,6 +773,7 @@
 #endif
 	.can_queue		= AHD_MAX_QUEUE,
 	.this_id		= -1,
+	.max_sectors		= 8192,
 	.cmd_per_lun		= 2,
 	.use_clustering		= ENABLE_CLUSTERING,
 	.slave_alloc		= ahd_linux_slave_alloc,
@@ -1813,9 +1814,9 @@
 			u_int sense_offset;
 
 			if (scb->flags & SCB_SENSE) {
-				sense_size = MIN(sizeof(struct scsi_sense_data)
+				sense_size = min(sizeof(struct scsi_sense_data)
 					       - ahd_get_sense_residual(scb),
-						 sizeof(cmd->sense_buffer));
+						 (u_long)sizeof(cmd->sense_buffer));
 				sense_offset = 0;
 			} else {
 				/*
@@ -1824,7 +1825,8 @@
 				 */
 				siu = (struct scsi_status_iu_header *)
 				    scb->sense_data;
-				sense_size = MIN(scsi_4btoul(siu->sense_length),
+				sense_size = min_t(size_t,
+						scsi_4btoul(siu->sense_length),
 						sizeof(cmd->sense_buffer));
 				sense_offset = SIU_SENSE_OFFSET(siu);
 			}
@@ -2634,8 +2636,22 @@
 		       pcomp ? "Enable" : "Disable");
 #endif
 
-	if (pcomp)
+	if (pcomp) {
+		uint8_t precomp;
+
+		if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
+			struct ahd_linux_iocell_opts *iocell_opts;
+
+			iocell_opts = &aic79xx_iocell_info[ahd->unit];
+			precomp = iocell_opts->precomp;
+		} else {
+			precomp = AIC79XX_DEFAULT_PRECOMP;
+		}
 		ppr_options |= MSG_EXT_PPR_PCOMP_EN;
+		AHD_SET_PRECOMP(ahd, precomp);
+	} else {
+		AHD_SET_PRECOMP(ahd, 0);
+	}
 
 	ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
 			    starget->channel + 'A', ROLE_INITIATOR);
@@ -2678,7 +2694,25 @@
 	ahd_unlock(ahd, &flags);
 }
 
+static void ahd_linux_get_signalling(struct Scsi_Host *shost)
+{
+	struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata;
+	unsigned long flags;
+	u8 mode;
 
+	ahd_lock(ahd, &flags);
+	ahd_pause(ahd);
+	mode = ahd_inb(ahd, SBLKCTL);
+	ahd_unpause(ahd);
+	ahd_unlock(ahd, &flags);
+
+	if (mode & ENAB40)
+		spi_signalling(shost) = SPI_SIGNAL_LVD;
+	else if (mode & ENAB20)
+		spi_signalling(shost) = SPI_SIGNAL_SE;
+	else
+		spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
+}
 
 static struct spi_function_template ahd_linux_transport_functions = {
 	.set_offset	= ahd_linux_set_offset,
@@ -2703,6 +2737,7 @@
 	.show_pcomp_en	= 1,
 	.set_hold_mcs	= ahd_linux_set_hold_mcs,
 	.show_hold_mcs	= 1,
+	.get_signalling = ahd_linux_get_signalling,
 };
 
 static int __init
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index fb3d4dd..3a67fc5 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -506,9 +506,6 @@
 	int pos;
 };
 
-void	ahd_format_transinfo(struct info_str *info,
-			     struct ahd_transinfo *tinfo);
-
 /******************************** Locking *************************************/
 static __inline void
 ahd_lockinit(struct ahd_softc *ahd)
@@ -582,8 +579,6 @@
 #define PCIXM_STATUS_MAXCRDS	0x1C00	/* Maximum Cumulative Read Size */
 #define PCIXM_STATUS_RCVDSCEM	0x2000	/* Received a Split Comp w/Error msg */
 
-extern struct pci_driver aic79xx_pci_driver;
-
 typedef enum
 {
 	AHD_POWER_STATE_D0,
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 4b53542..2001fe8 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -82,7 +82,7 @@
 
 MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table);
 
-struct pci_driver aic79xx_pci_driver = {
+static struct pci_driver aic79xx_pci_driver = {
 	.name		= "aic79xx",
 	.probe		= ahd_linux_pci_dev_probe,
 	.remove		= ahd_linux_pci_dev_remove,
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
index 14850f3..c077358 100644
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -97,7 +97,7 @@
 static ahd_device_setup_t ahd_aic7902_setup;
 static ahd_device_setup_t ahd_aic790X_setup;
 
-struct ahd_pci_identity ahd_pci_ident_table [] =
+static struct ahd_pci_identity ahd_pci_ident_table [] =
 {
 	/* aic7901 based controllers */
 	{
@@ -201,7 +201,7 @@
 	}
 };
 
-const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table);
+static const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table);
 		
 #define	DEVCONFIG		0x40
 #define		PCIXINITPAT	0x0000E000ul
@@ -245,6 +245,7 @@
 static void	ahd_configure_termination(struct ahd_softc *ahd,
 					  u_int adapter_control);
 static void	ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
+static void	ahd_pci_intr(struct ahd_softc *ahd);
 
 struct ahd_pci_identity *
 ahd_find_pci_device(ahd_dev_softc_t pci)
@@ -757,7 +758,7 @@
 	"%s: Address or Write Phase Parity Error Detected in %s.\n"
 };
 
-void
+static void
 ahd_pci_intr(struct ahd_softc *ahd)
 {
 	uint8_t		pci_status[8];
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c
index c5f0ee5..6b28beb 100644
--- a/drivers/scsi/aic7xxx/aic79xx_proc.c
+++ b/drivers/scsi/aic7xxx/aic79xx_proc.c
@@ -136,7 +136,7 @@
 	return (len);
 }
 
-void
+static void
 ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
 {
 	u_int speed;
diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h
index 62ff8c3..954c7c2 100644
--- a/drivers/scsi/aic7xxx/aic7xxx.h
+++ b/drivers/scsi/aic7xxx/aic7xxx.h
@@ -54,14 +54,6 @@
 struct seeprom_descriptor;
 
 /****************************** Useful Macros *********************************/
-#ifndef MAX
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef MIN
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
 #ifndef TRUE
 #define TRUE 1
 #endif
@@ -1135,8 +1127,6 @@
 	char			*name;
 	ahc_device_setup_t	*setup;
 };
-extern struct ahc_pci_identity ahc_pci_ident_table[];
-extern const u_int ahc_num_pci_devs;
 
 /***************************** VL/EISA Declarations ***************************/
 struct aic7770_identity {
@@ -1289,6 +1279,7 @@
 } ahc_queue_alg;
 
 void			ahc_set_tags(struct ahc_softc *ahc,
+				     struct scsi_cmnd *cmd,
 				     struct ahc_devinfo *devinfo,
 				     ahc_queue_alg alg);
 
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index 93e4e409..50ef785 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -1671,7 +1671,7 @@
 		transinfo = &tinfo->goal;
 	*ppr_options &= transinfo->ppr_options;
 	if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
-		maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2);
+		maxsync = max(maxsync, (u_int)AHC_SYNCRATE_ULTRA2);
 		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
 	}
 	if (transinfo->period == 0) {
@@ -1679,7 +1679,7 @@
 		*ppr_options = 0;
 		return (NULL);
 	}
-	*period = MAX(*period, transinfo->period);
+	*period = max(*period, (u_int)transinfo->period);
 	return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));
 }
 
@@ -1804,12 +1804,12 @@
 		else
 			maxoffset = MAX_OFFSET_8BIT;
 	}
-	*offset = MIN(*offset, maxoffset);
+	*offset = min(*offset, maxoffset);
 	if (tinfo != NULL) {
 		if (role == ROLE_TARGET)
-			*offset = MIN(*offset, tinfo->user.offset);
+			*offset = min(*offset, (u_int)tinfo->user.offset);
 		else
-			*offset = MIN(*offset, tinfo->goal.offset);
+			*offset = min(*offset, (u_int)tinfo->goal.offset);
 	}
 }
 
@@ -1835,9 +1835,9 @@
 	}
 	if (tinfo != NULL) {
 		if (role == ROLE_TARGET)
-			*bus_width = MIN(tinfo->user.width, *bus_width);
+			*bus_width = min((u_int)tinfo->user.width, *bus_width);
 		else
-			*bus_width = MIN(tinfo->goal.width, *bus_width);
+			*bus_width = min((u_int)tinfo->goal.width, *bus_width);
 	}
 }
 
@@ -1986,7 +1986,7 @@
 		tinfo->curr.ppr_options = ppr_options;
 
 		ahc_send_async(ahc, devinfo->channel, devinfo->target,
-			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
+			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
 		if (bootverbose) {
 			if (offset != 0) {
 				printf("%s: target %d synchronous at %sMHz%s, "
@@ -2056,7 +2056,7 @@
 		tinfo->curr.width = width;
 
 		ahc_send_async(ahc, devinfo->channel, devinfo->target,
-			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
+			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
 		if (bootverbose) {
 			printf("%s: target %d using %dbit transfers\n",
 			       ahc_name(ahc), devinfo->target,
@@ -2074,12 +2074,14 @@
  * Update the current state of tagged queuing for a given target.
  */
 void
-ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-	     ahc_queue_alg alg)
+ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
+	     struct ahc_devinfo *devinfo, ahc_queue_alg alg)
 {
- 	ahc_platform_set_tags(ahc, devinfo, alg);
+	struct scsi_device *sdev = cmd->device;
+
+ 	ahc_platform_set_tags(ahc, sdev, devinfo, alg);
  	ahc_send_async(ahc, devinfo->channel, devinfo->target,
- 		       devinfo->lun, AC_TRANSFER_NEG, &alg);
+ 		       devinfo->lun, AC_TRANSFER_NEG);
 }
 
 /*
@@ -3489,7 +3491,7 @@
 			printf("(%s:%c:%d:%d): refuses tagged commands.  "
 			       "Performing non-tagged I/O\n", ahc_name(ahc),
 			       devinfo->channel, devinfo->target, devinfo->lun);
-			ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE);
+			ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_NONE);
 			mask = ~0x23;
 		} else {
 			printf("(%s:%c:%d:%d): refuses %s tagged commands.  "
@@ -3497,7 +3499,7 @@
 			       ahc_name(ahc), devinfo->channel, devinfo->target,
 			       devinfo->lun, tag_type == MSG_ORDERED_TASK
 			       ? "ordered" : "head of queue");
-			ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC);
+			ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC);
 			mask = ~0x03;
 		}
 
@@ -3763,7 +3765,7 @@
 	
 	if (status != CAM_SEL_TIMEOUT)
 		ahc_send_async(ahc, devinfo->channel, devinfo->target,
-			       CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
+			       CAM_LUN_WILDCARD, AC_SENT_BDR);
 
 	if (message != NULL
 	 && (verbose_level <= bootverbose))
@@ -4406,7 +4408,7 @@
 	physaddr = sg_map->sg_physaddr;
 
 	newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
-	newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
+	newcount = min(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
 	for (i = 0; i < newcount; i++) {
 		struct scb_platform_data *pdata;
 #ifndef __linux__
@@ -6018,7 +6020,7 @@
 #endif
 	/* Notify the XPT that a bus reset occurred */
 	ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,
-		       CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
+		       CAM_LUN_WILDCARD, AC_BUS_RESET);
 
 	/*
 	 * Revert to async/narrow transfers until we renegotiate.
@@ -6442,7 +6444,7 @@
 			if (skip_addr > i) {
 				int end_addr;
 
-				end_addr = MIN(address, skip_addr);
+				end_addr = min(address, skip_addr);
 				address_offset += end_addr - i;
 				i = skip_addr;
 			} else {
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 43ab753..660f26e 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -328,7 +328,7 @@
  * force all outstanding transactions to be serviced prior to a new
  * transaction.
  */
-uint32_t aic7xxx_periodic_otag;
+static uint32_t aic7xxx_periodic_otag;
 
 /*
  * Module information and settable options.
@@ -512,7 +512,6 @@
 	struct seeprom_config *sc = ahc->seep_config;
 	unsigned long flags;
 	struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget);
-	struct ahc_linux_target *targ = scsi_transport_target_data(starget);
 	unsigned short scsirate;
 	struct ahc_devinfo devinfo;
 	struct ahc_initiator_tinfo *tinfo;
@@ -533,7 +532,6 @@
 	BUG_ON(*ahc_targp != NULL);
 
 	*ahc_targp = starget;
-	memset(targ, 0, sizeof(*targ));
 
 	if (sc) {
 		int maxsync = AHC_SYNCRATE_DT;
@@ -594,14 +592,11 @@
 	struct	ahc_softc *ahc =
 		*((struct ahc_softc **)sdev->host->hostdata);
 	struct scsi_target *starget = sdev->sdev_target;
-	struct ahc_linux_target *targ = scsi_transport_target_data(starget);
 	struct ahc_linux_device *dev;
 
 	if (bootverbose)
 		printf("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id);
 
-	BUG_ON(targ->sdev[sdev->lun] != NULL);
-
 	dev = scsi_transport_device_data(sdev);
 	memset(dev, 0, sizeof(*dev));
 
@@ -618,8 +613,6 @@
 	 */
 	dev->maxtags = 0;
 	
-	targ->sdev[sdev->lun] = sdev;
-
 	spi_period(starget) = 0;
 
 	return 0;
@@ -644,22 +637,6 @@
 	return 0;
 }
 
-static void
-ahc_linux_slave_destroy(struct scsi_device *sdev)
-{
-	struct	ahc_softc *ahc;
-	struct	ahc_linux_device *dev = scsi_transport_device_data(sdev);
-	struct	ahc_linux_target *targ = scsi_transport_target_data(sdev->sdev_target);
-
-	ahc = *((struct ahc_softc **)sdev->host->hostdata);
-	if (bootverbose)
-		printf("%s: Slave Destroy %d\n", ahc_name(ahc), sdev->id);
-
-	BUG_ON(dev->active);
-
-	targ->sdev[sdev->lun] = NULL;
-}
-
 #if defined(__i386__)
 /*
  * Return the disk geometry for the given SCSI device.
@@ -777,11 +754,11 @@
 #endif
 	.can_queue		= AHC_MAX_QUEUE,
 	.this_id		= -1,
+	.max_sectors		= 8192,
 	.cmd_per_lun		= 2,
 	.use_clustering		= ENABLE_CLUSTERING,
 	.slave_alloc		= ahc_linux_slave_alloc,
 	.slave_configure	= ahc_linux_slave_configure,
-	.slave_destroy		= ahc_linux_slave_destroy,
 	.target_alloc		= ahc_linux_target_alloc,
 	.target_destroy		= ahc_linux_target_destroy,
 };
@@ -1203,21 +1180,13 @@
 ahc_platform_free(struct ahc_softc *ahc)
 {
 	struct scsi_target *starget;
-	int i, j;
+	int i;
 
 	if (ahc->platform_data != NULL) {
 		/* destroy all of the device and target objects */
 		for (i = 0; i < AHC_NUM_TARGETS; i++) {
 			starget = ahc->platform_data->starget[i];
 			if (starget != NULL) {
-				for (j = 0; j < AHC_NUM_LUNS; j++) {
-					struct ahc_linux_target *targ =
-						scsi_transport_target_data(starget);
-
-					if (targ->sdev[j] == NULL)
-						continue;
-					targ->sdev[j] = NULL;
-				}
 				ahc->platform_data->starget[i] = NULL;
  			}
  		}
@@ -1251,24 +1220,13 @@
 }
 
 void
-ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
-		      ahc_queue_alg alg)
+ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
+		      struct ahc_devinfo *devinfo, ahc_queue_alg alg)
 {
-	struct scsi_target *starget;
-	struct ahc_linux_target *targ;
 	struct ahc_linux_device *dev;
-	struct scsi_device *sdev;
-	u_int target_offset;
 	int was_queuing;
 	int now_queuing;
 
-	target_offset = devinfo->target;
-	if (devinfo->channel != 'A')
-		target_offset += 8;
-	starget = ahc->platform_data->starget[target_offset];
-	targ = scsi_transport_target_data(starget);
-	BUG_ON(targ == NULL);
-	sdev = targ->sdev[devinfo->lun];
 	if (sdev == NULL)
 		return;
 	dev = scsi_transport_device_data(sdev);
@@ -1401,11 +1359,15 @@
 	tags = ahc_linux_user_tagdepth(ahc, &devinfo);
 	if (tags != 0 && sdev->tagged_supported != 0) {
 
-		ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED);
+		ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_TAGGED);
+		ahc_send_async(ahc, devinfo.channel, devinfo.target,
+			       devinfo.lun, AC_TRANSFER_NEG);
 		ahc_print_devinfo(ahc, &devinfo);
 		printf("Tagged Queuing enabled.  Depth %d\n", tags);
 	} else {
-		ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE);
+		ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_NONE);
+		ahc_send_async(ahc, devinfo.channel, devinfo.target,
+			       devinfo.lun, AC_TRANSFER_NEG);
 	}
 }
 
@@ -1629,7 +1591,7 @@
 
 void
 ahc_send_async(struct ahc_softc *ahc, char channel,
-	       u_int target, u_int lun, ac_code code, void *arg)
+	       u_int target, u_int lun, ac_code code)
 {
 	switch (code) {
 	case AC_TRANSFER_NEG:
@@ -1875,9 +1837,9 @@
 		if (scb->flags & SCB_SENSE) {
 			u_int sense_size;
 
-			sense_size = MIN(sizeof(struct scsi_sense_data)
+			sense_size = min(sizeof(struct scsi_sense_data)
 				       - ahc_get_sense_residual(scb),
-					 sizeof(cmd->sense_buffer));
+					 (u_long)sizeof(cmd->sense_buffer));
 			memcpy(cmd->sense_buffer,
 			       ahc_get_sense_buf(ahc, scb), sense_size);
 			if (sense_size < sizeof(cmd->sense_buffer))
@@ -1946,7 +1908,7 @@
 			}
 			ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
 			ahc_set_scsi_status(scb, SCSI_STATUS_OK);
-			ahc_platform_set_tags(ahc, &devinfo,
+			ahc_platform_set_tags(ahc, sdev, &devinfo,
 				     (dev->flags & AHC_DEV_Q_BASIC)
 				   ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
 			break;
@@ -1957,7 +1919,7 @@
 		 */
 		dev->openings = 1;
 		ahc_set_scsi_status(scb, SCSI_STATUS_BUSY);
-		ahc_platform_set_tags(ahc, &devinfo,
+		ahc_platform_set_tags(ahc, sdev, &devinfo,
 			     (dev->flags & AHC_DEV_Q_BASIC)
 			   ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
 		break;
@@ -2599,8 +2561,6 @@
 	if (!ahc_linux_transport_template)
 		return -ENODEV;
 
-	scsi_transport_reserve_target(ahc_linux_transport_template,
-				      sizeof(struct ahc_linux_target));
 	scsi_transport_reserve_device(ahc_linux_transport_template,
 				      sizeof(struct ahc_linux_device));
 
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index a87a4ce..85ae5d8 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -256,7 +256,6 @@
 	AHC_DEV_PERIODIC_OTAG	 = 0x40, /* Send OTAG to prevent starvation */
 } ahc_linux_dev_flags;
 
-struct ahc_linux_target;
 struct ahc_linux_device {
 	/*
 	 * The number of transactions currently
@@ -329,12 +328,6 @@
 #define AHC_OTAG_THRESH	500
 };
 
-struct ahc_linux_target {
-	struct scsi_device	 *sdev[AHC_NUM_LUNS];
-	struct ahc_transinfo	  last_tinfo;
-	struct ahc_softc	 *ahc;
-};
-
 /********************* Definitions Required by the Core ***********************/
 /*
  * Number of SG segments we require.  So long as the S/G segments for
@@ -533,8 +526,6 @@
 #define PCIR_SUBVEND_0	0x2c
 #define PCIR_SUBDEV_0	0x2e
 
-extern struct pci_driver aic7xxx_pci_driver;
-
 typedef enum
 {
 	AHC_POWER_STATE_D0,
@@ -824,7 +815,7 @@
         }
 }
 
-void	ahc_platform_set_tags(struct ahc_softc *ahc,
+void	ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
 			      struct ahc_devinfo *devinfo, ahc_queue_alg);
 int	ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
 				char channel, int lun, u_int tag,
@@ -834,7 +825,7 @@
 void	ahc_platform_flushwork(struct ahc_softc *ahc);
 void	ahc_done(struct ahc_softc*, struct scb*);
 void	ahc_send_async(struct ahc_softc *, char channel,
-		       u_int target, u_int lun, ac_code, void *);
+		       u_int target, u_int lun, ac_code);
 void	ahc_print_path(struct ahc_softc *, struct scb *);
 void	ahc_platform_dump_card_state(struct ahc_softc *ahc);
 
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index d20ca51..ea5687d 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -130,7 +130,7 @@
 
 MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table);
 
-struct pci_driver aic7xxx_pci_driver = {
+static struct pci_driver aic7xxx_pci_driver = {
 	.name		= "aic7xxx",
 	.probe		= ahc_linux_pci_dev_probe,
 	.remove		= ahc_linux_pci_dev_remove,
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
index 63cab2d..09c8172 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c
@@ -168,7 +168,7 @@
 static ahc_device_setup_t ahc_aha494XX_setup;
 static ahc_device_setup_t ahc_aha398XX_setup;
 
-struct ahc_pci_identity ahc_pci_ident_table [] =
+static struct ahc_pci_identity ahc_pci_ident_table [] =
 {
 	/* aic7850 based controllers */
 	{
@@ -559,7 +559,7 @@
 	}
 };
 
-const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table);
+static const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table);
 		
 #define AHC_394X_SLOT_CHANNEL_A	4
 #define AHC_394X_SLOT_CHANNEL_B	5
diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c
index 5914b4a..99e5443 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_proc.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c
@@ -182,7 +182,6 @@
 		      u_int our_id, char channel, u_int target_id,
 		      u_int target_offset)
 {
-	struct	ahc_linux_target *targ;
 	struct	scsi_target *starget;
 	struct	ahc_initiator_tinfo *tinfo;
 	struct	ahc_tmode_tstate *tstate;
@@ -198,7 +197,6 @@
 	starget = ahc->platform_data->starget[target_offset];
 	if (!starget)
 		return;
-	targ = scsi_transport_target_data(starget);
 
 	copy_info(info, "\tGoal: ");
 	ahc_format_transinfo(info, &tinfo->goal);
@@ -208,7 +206,7 @@
 	for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
 		struct scsi_device *sdev;
 
-		sdev = targ->sdev[lun];
+		sdev = scsi_device_lookup_by_target(starget, lun);
 
 		if (sdev == NULL)
 			continue;
@@ -383,11 +381,11 @@
 	}
 	copy_info(&info, "\n");
 
-	max_targ = 15;
+	max_targ = 16;
 	if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
-		max_targ = 7;
+		max_targ = 8;
 
-	for (i = 0; i <= max_targ; i++) {
+	for (i = 0; i < max_targ; i++) {
 		u_int our_id;
 		u_int target_id;
 		char channel;
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index bcd7fff..46eed10 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -2646,7 +2646,7 @@
 
 	while (p->completeq.head != NULL) {
 		cmd = p->completeq.head;
-		p->completeq.head = (struct scsi_Cmnd *) cmd->host_scribble;
+		p->completeq.head = (struct scsi_cmnd *) cmd->host_scribble;
 		cmd->host_scribble = NULL;
 		cmd->scsi_done(cmd);
 	}
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
index 3c2d7a3..af7e011 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.c
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -112,6 +112,21 @@
 	return 0;
 }
 
+static void asd_init_ports(struct asd_ha_struct *asd_ha)
+{
+	int i;
+
+	spin_lock_init(&asd_ha->asd_ports_lock);
+	for (i = 0; i < ASD_MAX_PHYS; i++) {
+		struct asd_port *asd_port = &asd_ha->asd_ports[i];
+
+		memset(asd_port->sas_addr, 0, SAS_ADDR_SIZE);
+		memset(asd_port->attached_sas_addr, 0, SAS_ADDR_SIZE);
+		asd_port->phy_mask = 0;
+		asd_port->num_phys = 0;
+	}
+}
+
 static int asd_init_phys(struct asd_ha_struct *asd_ha)
 {
 	u8 i;
@@ -121,6 +136,7 @@
 		struct asd_phy *phy = &asd_ha->phys[i];
 
 		phy->phy_desc = &asd_ha->hw_prof.phy_desc[i];
+		phy->asd_port = NULL;
 
 		phy->sas_phy.enabled = 0;
 		phy->sas_phy.id = i;
@@ -658,6 +674,8 @@
 		goto Out;
 	}
 
+	asd_init_ports(asd_ha);
+
 	err = asd_init_scbs(asd_ha);
 	if (err) {
 		asd_printk("couldn't initialize scbs for %s\n",
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h
index 14319d1..c6c3d18 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.h
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.h
@@ -46,6 +46,7 @@
 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410
 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412
 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E
+#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1F 0x41F
 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430
 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432
 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E
@@ -192,6 +193,16 @@
 	struct asd_ascb **escb_arr; /* array of pointers to escbs */
 };
 
+/* This is an internal port structure. These are used to get accurate
+ * phy_mask for updating DDB 0.
+ */
+struct asd_port {
+	u8  sas_addr[SAS_ADDR_SIZE];
+	u8  attached_sas_addr[SAS_ADDR_SIZE];
+	u32 phy_mask;
+	int num_phys;
+};
+
 /* This is the Host Adapter structure.  It describes the hardware
  * SAS adapter.
  */
@@ -210,6 +221,8 @@
 	struct hw_profile hw_prof;
 
 	struct asd_phy    phys[ASD_MAX_PHYS];
+	spinlock_t        asd_ports_lock;
+	struct asd_port   asd_ports[ASD_MAX_PHYS];
 	struct asd_sas_port   ports[ASD_MAX_PHYS];
 
 	struct dma_pool  *scb_pool;
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 99743ca..57c5ba4 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -786,8 +786,6 @@
 }
 
 static struct sas_domain_function_template aic94xx_transport_functions = {
-	.lldd_port_formed	= asd_update_port_links,
-
 	.lldd_dev_found		= asd_dev_found,
 	.lldd_dev_gone		= asd_dev_gone,
 
@@ -814,6 +812,8 @@
 	 0, 0, 1},
 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E),
 	 0, 0, 1},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1F),
+	 0, 0, 1},
 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30),
 	 0, 0, 2},
 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32),
diff --git a/drivers/scsi/aic94xx/aic94xx_sas.h b/drivers/scsi/aic94xx/aic94xx_sas.h
index 64d2317..9050e93 100644
--- a/drivers/scsi/aic94xx/aic94xx_sas.h
+++ b/drivers/scsi/aic94xx/aic94xx_sas.h
@@ -733,6 +733,7 @@
 
 	struct sas_identify_frame *identify_frame;
 	struct asd_dma_tok  *id_frm_tok;
+	struct asd_port     *asd_port;
 
 	u8         frame_rcvd[ASD_EDB_SIZE];
 };
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c
index 7ee49b5..b15caf1 100644
--- a/drivers/scsi/aic94xx/aic94xx_scb.c
+++ b/drivers/scsi/aic94xx/aic94xx_scb.c
@@ -168,6 +168,70 @@
 	}
 }
 
+static void asd_form_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
+{
+	int i;
+	struct asd_port *free_port = NULL;
+	struct asd_port *port;
+	struct asd_sas_phy *sas_phy = &phy->sas_phy;
+	unsigned long flags;
+
+	spin_lock_irqsave(&asd_ha->asd_ports_lock, flags);
+	if (!phy->asd_port) {
+		for (i = 0; i < ASD_MAX_PHYS; i++) {
+			port = &asd_ha->asd_ports[i];
+
+			/* Check for wide port */
+			if (port->num_phys > 0 &&
+			    memcmp(port->sas_addr, sas_phy->sas_addr,
+				   SAS_ADDR_SIZE) == 0 &&
+			    memcmp(port->attached_sas_addr,
+				   sas_phy->attached_sas_addr,
+				   SAS_ADDR_SIZE) == 0) {
+				break;
+			}
+
+			/* Find a free port */
+			if (port->num_phys == 0 && free_port == NULL) {
+				free_port = port;
+			}
+		}
+
+		/* Use a free port if this doesn't form a wide port */
+		if (i >= ASD_MAX_PHYS) {
+			port = free_port;
+			BUG_ON(!port);
+			memcpy(port->sas_addr, sas_phy->sas_addr,
+			       SAS_ADDR_SIZE);
+			memcpy(port->attached_sas_addr,
+			       sas_phy->attached_sas_addr,
+			       SAS_ADDR_SIZE);
+		}
+		port->num_phys++;
+		port->phy_mask |= (1U << sas_phy->id);
+		phy->asd_port = port;
+	}
+	ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n",
+		    __FUNCTION__, phy->asd_port->phy_mask, sas_phy->id);
+	asd_update_port_links(asd_ha, phy);
+	spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
+}
+
+static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
+{
+	struct asd_port *port = phy->asd_port;
+	struct asd_sas_phy *sas_phy = &phy->sas_phy;
+	unsigned long flags;
+
+	spin_lock_irqsave(&asd_ha->asd_ports_lock, flags);
+	if (port) {
+		port->num_phys--;
+		port->phy_mask &= ~(1U << sas_phy->id);
+		phy->asd_port = NULL;
+	}
+	spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
+}
+
 static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
 					   struct done_list_struct *dl,
 					   int edb_id, int phy_id)
@@ -187,6 +251,7 @@
 	asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
 	spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
 	asd_dump_frame_rcvd(phy, dl);
+	asd_form_port(ascb->ha, phy);
 	sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
 }
 
@@ -197,6 +262,7 @@
 	struct asd_ha_struct *asd_ha = ascb->ha;
 	struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
 	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
+	struct asd_phy *phy = &asd_ha->phys[phy_id];
 	u8 lr_error = dl->status_block[1];
 	u8 retries_left = dl->status_block[2];
 
@@ -221,6 +287,7 @@
 
 	asd_turn_led(asd_ha, phy_id, 0);
 	sas_phy_disconnected(sas_phy);
+	asd_deform_port(asd_ha, phy);
 	sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
 
 	if (retries_left == 0) {
@@ -248,6 +315,8 @@
 	unsigned long flags;
 	struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
 	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
+	struct asd_ha_struct *asd_ha = ascb->ha;
+	struct asd_phy *phy = &asd_ha->phys[phy_id];
 	u8  reg  = dl->status_block[1];
 	u32 cont = dl->status_block[2] << ((reg & 3)*8);
 
@@ -284,6 +353,7 @@
 				    phy_id);
 			/* The sequencer disables all phys on that port.
 			 * We have to re-enable the phys ourselves. */
+			asd_deform_port(asd_ha, phy);
 			sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
 			break;
 
@@ -351,6 +421,7 @@
 	u8  sb_opcode = dl->status_block[0];
 	int phy_id = sb_opcode & DL_PHY_MASK;
 	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
+	struct asd_phy *phy = &asd_ha->phys[phy_id];
 
 	if (edb > 6 || edb < 0) {
 		ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
@@ -395,6 +466,7 @@
 		asd_turn_led(asd_ha, phy_id, 0);
 		/* the device is gone */
 		sas_phy_disconnected(sas_phy);
+		asd_deform_port(asd_ha, phy);
 		sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
 		break;
 	case REQ_TASK_ABORT:
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
index 83574b5..de7c04d 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.c
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -630,10 +630,6 @@
 
 	reg = asd_read_reg_dword(asd_ha, EXSICNFGR);
 
-	if (!(reg & FLASHEX)) {
-		ASD_DPRINTK("flash doesn't exist\n");
-		return -ENOENT;
-	}
 	if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR,
 				  &asd_ha->hw_prof.flash.bar)) {
 		asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n",
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c
index 56e4b3b..8451125 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.c
+++ b/drivers/scsi/aic94xx/aic94xx_seq.c
@@ -1369,10 +1369,9 @@
  * port_map_by_links is also used as the conn_mask byte in the
  * initiator/target port DDB.
  */
-void asd_update_port_links(struct asd_sas_phy *sas_phy)
+void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
 {
-	struct asd_ha_struct *asd_ha = sas_phy->ha->lldd_ha;
-	const u8 phy_mask = (u8) sas_phy->port->phy_mask;
+	const u8 phy_mask = (u8) phy->asd_port->phy_mask;
 	u8  phy_is_up;
 	u8  mask;
 	int i, err;
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.h b/drivers/scsi/aic94xx/aic94xx_seq.h
index 42281c3..9e715e5 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.h
+++ b/drivers/scsi/aic94xx/aic94xx_seq.h
@@ -64,7 +64,7 @@
 int asd_init_seqs(struct asd_ha_struct *asd_ha);
 int asd_start_seqs(struct asd_ha_struct *asd_ha);
 
-void asd_update_port_links(struct asd_sas_phy *phy);
+void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy);
 #endif
 
 #endif
diff --git a/drivers/scsi/dpt/dpti_i2o.h b/drivers/scsi/dpt/dpti_i2o.h
index b3fa7ed..5a49216 100644
--- a/drivers/scsi/dpt/dpti_i2o.h
+++ b/drivers/scsi/dpt/dpti_i2o.h
@@ -49,7 +49,7 @@
 
 #include <linux/wait.h>
 typedef wait_queue_head_t adpt_wait_queue_head_t;
-#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait)
+#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait)
 typedef wait_queue_t adpt_wait_queue_t;
 
 /*
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 65e6e7b..5d4ea6f 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -387,6 +387,7 @@
 static int               bios_major;
 static int               bios_minor;
 static int               PCI_bus;
+static struct pci_dev	*PCI_dev;
 static int               Quantum;	/* Quantum board variant */
 static int               interrupt_level;
 static volatile int      in_command;
@@ -812,9 +813,10 @@
 	   PCI_DEVICE_ID_FD_36C70 );
 #endif 
 
-   if ((pdev = pci_find_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL)
+   if ((pdev = pci_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL)
 		return 0;
-   if (pci_enable_device(pdev)) return 0;
+   if (pci_enable_device(pdev))
+   	goto fail;
        
 #if DEBUG_DETECT
    printk( "scsi: <fdomain> TMC-3260 detect:"
@@ -831,7 +833,7 @@
    pci_irq = pdev->irq;
 
    if (!request_region( pci_base, 0x10, "fdomain" ))
-	return 0;
+   	goto fail;
 
    /* Now we have the I/O base address and interrupt from the PCI
       configuration registers. */
@@ -848,17 +850,22 @@
    if (!fdomain_is_valid_port(pci_base)) {
       printk(KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" );
       release_region(pci_base, 0x10);
-      return 0;
+      goto fail;
    }
 
 				/* Fill in a few global variables.  Ugh. */
    bios_major = bios_minor = -1;
    PCI_bus    = 1;
+   PCI_dev    = pdev;
    Quantum    = 0;
    bios_base  = 0;
    
    return 1;
+fail:
+   pci_dev_put(pdev);
+   return 0;
 }
+
 #endif
 
 struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt )
@@ -909,8 +916,7 @@
       if (setup_called) {
 	 printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n");
       }
-      release_region(port_base, 0x10);
-      return NULL;
+      goto fail;
    }
 
    if (this_id) {
@@ -942,8 +948,7 @@
    /* Log IRQ with kernel */   
    if (!interrupt_level) {
       printk(KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" );
-      release_region(port_base, 0x10);
-      return NULL;
+      goto fail;
    } else {
       /* Register the IRQ with the kernel */
 
@@ -964,11 +969,14 @@
 	    printk(KERN_ERR "                Send mail to faith@acm.org\n" );
 	 }
 	 printk(KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" );
-         release_region(port_base, 0x10);
-	 return NULL;
+	 goto fail;
       }
    }
    return shpnt;
+fail:
+   pci_dev_put(pdev);
+   release_region(port_base, 0x10);
+   return NULL;
 }
 
 static int fdomain_16x0_detect(struct scsi_host_template *tpnt)
@@ -1714,6 +1722,8 @@
 		free_irq(shpnt->irq, shpnt);
 	if (shpnt->io_port && shpnt->n_io_port)
 		release_region(shpnt->io_port, shpnt->n_io_port);
+	if (PCI_bus)
+		pci_dev_put(PCI_dev);
 	return 0;
 }
 
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 4bc14ad..4c698a7 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -3531,7 +3531,7 @@
                 IStatus &= ~0x80;
 #ifdef INT_COAL
                 if (coalesced)
-                    ha->status = pcs->ext_status && 0xffff;
+                    ha->status = pcs->ext_status & 0xffff;
                 else 
 #endif
                     ha->status = gdth_readw(&dp6m_ptr->i960r.status);
@@ -3543,7 +3543,7 @@
             if (coalesced) {    
                 ha->info = pcs->info0;
                 ha->info2 = pcs->info1;
-                ha->service = (pcs->ext_status >> 16) && 0xffff;
+                ha->service = (pcs->ext_status >> 16) & 0xffff;
             } else
 #endif
             {
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 669ea4f..fbc1d5c 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1213,7 +1213,7 @@
 			       "ibmvscsi: Re-enabling adapter!\n");
 			purge_requests(hostdata, DID_REQUEUE);
 			if ((ibmvscsi_reenable_crq_queue(&hostdata->queue,
-							hostdata) == 0) ||
+							hostdata)) ||
 			    (ibmvscsi_send_crq(hostdata,
 					       0xC001000000000000LL, 0))) {
 					atomic_set(&hostdata->request_limit,
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 2d95ac9..e31f612 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -1153,7 +1153,7 @@
 {
 	struct Scsi_Host *host;
 	imm_struct *dev;
-	DECLARE_WAIT_QUEUE_HEAD(waiting);
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
 	DEFINE_WAIT(wait);
 	int ports;
 	int modes, ppb;
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 0a9dbc5..d0b139c 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -415,8 +415,8 @@
 	iscsi_solicit_data_init(conn, ctask, r2t);
 
 	tcp_ctask->exp_r2tsn = r2tsn + 1;
-	tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
 	__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
+	tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
 	list_move_tail(&ctask->running, &conn->xmitqueue);
 
 	scsi_queue_work(session->host, &conn->xmitwork);
@@ -1627,9 +1627,12 @@
 	if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
 		tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
 		tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
-		if (!tcp_ctask->r2t)
+		if (!tcp_ctask->r2t) {
+			spin_lock_bh(&session->lock);
 			__kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
 				    sizeof(void*));
+			spin_unlock_bh(&session->lock);
+		}
 send_hdr:
 		r2t = tcp_ctask->r2t;
 		dtask = &r2t->dtask;
@@ -1816,21 +1819,14 @@
 {
 	struct iscsi_conn *conn = cls_conn->dd_data;
 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
-	int digest = 0;
-
-	if (conn->hdrdgst_en || conn->datadgst_en)
-		digest = 1;
 
 	iscsi_tcp_release_conn(conn);
 	iscsi_conn_teardown(cls_conn);
 
-	/* now free tcp_conn */
-	if (digest) {
-		if (tcp_conn->tx_hash.tfm)
-			crypto_free_hash(tcp_conn->tx_hash.tfm);
-		if (tcp_conn->rx_hash.tfm)
-			crypto_free_hash(tcp_conn->rx_hash.tfm);
-	}
+	if (tcp_conn->tx_hash.tfm)
+		crypto_free_hash(tcp_conn->tx_hash.tfm);
+	if (tcp_conn->rx_hash.tfm)
+		crypto_free_hash(tcp_conn->rx_hash.tfm);
 
 	kfree(tcp_conn);
 }
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index c542d0e..5d88621 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -481,8 +481,8 @@
 			break;
 		case ISCSI_OP_ASYNC_EVENT:
 			conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
-			/* we need sth like iscsi_async_event_rsp() */
-			rc = ISCSI_ERR_BAD_OPCODE;
+			if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
+				rc = ISCSI_ERR_CONN_FAILED;
 			break;
 		default:
 			rc = ISCSI_ERR_BAD_OPCODE;
@@ -578,6 +578,27 @@
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_failure);
 
+static int iscsi_xmit_imm_task(struct iscsi_conn *conn)
+{
+	struct iscsi_hdr *hdr = conn->mtask->hdr;
+	int rc, was_logout = 0;
+
+	if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) {
+		conn->session->state = ISCSI_STATE_IN_RECOVERY;
+		iscsi_block_session(session_to_cls(conn->session));
+		was_logout = 1;
+	}
+	rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask);
+	if (rc)
+		return rc;
+
+	if (was_logout) {
+		set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+		return -ENODATA;
+	}
+	return 0;
+}
+
 /**
  * iscsi_data_xmit - xmit any command into the scheduled connection
  * @conn: iscsi connection
@@ -623,7 +644,7 @@
 		conn->ctask = NULL;
 	}
 	if (conn->mtask) {
-		rc = tt->xmit_mgmt_task(conn, conn->mtask);
+		rc = iscsi_xmit_imm_task(conn);
 	        if (rc)
 		        goto again;
 		/* done with this in-progress mtask */
@@ -638,7 +659,7 @@
 			list_add_tail(&conn->mtask->running,
 				      &conn->mgmt_run_list);
 			spin_unlock_bh(&conn->session->lock);
-			rc = tt->xmit_mgmt_task(conn, conn->mtask);
+			rc = iscsi_xmit_imm_task(conn);
 		        if (rc)
 			        goto again;
 	        }
@@ -661,8 +682,6 @@
 		spin_unlock_bh(&conn->session->lock);
 
 		rc = tt->xmit_cmd_task(conn, conn->ctask);
-		if (rc)
-			goto again;
 
 		spin_lock_bh(&conn->session->lock);
 		__iscsi_put_ctask(conn->ctask);
@@ -778,6 +797,10 @@
 	}
 
 	conn = session->leadconn;
+	if (!conn) {
+		reason = FAILURE_SESSION_FREED;
+		goto fault;
+	}
 
 	if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask,
 			 sizeof(void*))) {
@@ -952,13 +975,13 @@
 	if (session->state == ISCSI_STATE_TERMINATE) {
 failed:
 		debug_scsi("failing host reset: session terminated "
-			   "[CID %d age %d]", conn->id, session->age);
+			   "[CID %d age %d]\n", conn->id, session->age);
 		spin_unlock_bh(&session->lock);
 		return FAILED;
 	}
 
 	if (sc->SCp.phase == session->age) {
-		debug_scsi("failing connection CID %d due to SCSI host reset",
+		debug_scsi("failing connection CID %d due to SCSI host reset\n",
 			   conn->id);
 		fail_session = 1;
 	}
@@ -1031,7 +1054,8 @@
 				     NULL, 0);
 	if (rc) {
 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-		debug_scsi("abort sent failure [itt 0x%x] %d", ctask->itt, rc);
+		debug_scsi("abort sent failure [itt 0x%x] %d\n", ctask->itt,
+		           rc);
 		return rc;
 	}
 
@@ -1048,7 +1072,7 @@
 		conn->tmabort_timer.function = iscsi_tmabort_timedout;
 		conn->tmabort_timer.data = (unsigned long)ctask;
 		add_timer(&conn->tmabort_timer);
-		debug_scsi("abort set timeout [itt 0x%x]", ctask->itt);
+		debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt);
 	}
 	spin_unlock_bh(&session->lock);
 	mutex_unlock(&conn->xmitmutex);
@@ -1377,7 +1401,6 @@
 	}
 
 	spin_lock_init(&session->lock);
-	INIT_LIST_HEAD(&session->connections);
 
 	/* initialize immediate command pool */
 	if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max,
@@ -1580,16 +1603,11 @@
 	kfree(conn->persistent_address);
 	__kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
 		    sizeof(void*));
-	list_del(&conn->item);
-	if (list_empty(&session->connections))
+	if (session->leadconn == conn) {
 		session->leadconn = NULL;
-	if (session->leadconn && session->leadconn == conn)
-		session->leadconn = container_of(session->connections.next,
-			struct iscsi_conn, item);
-
-	if (session->leadconn == NULL)
 		/* no connections exits.. reset sequencing */
 		session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
+	}
 	spin_unlock_bh(&session->lock);
 
 	kfifo_free(conn->immqueue);
@@ -1777,32 +1795,12 @@
 		    struct iscsi_cls_conn *cls_conn, int is_leading)
 {
 	struct iscsi_session *session = class_to_transport_session(cls_session);
-	struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data;
+	struct iscsi_conn *conn = cls_conn->dd_data;
 
-	/* lookup for existing connection */
 	spin_lock_bh(&session->lock);
-	list_for_each_entry(tmp, &session->connections, item) {
-		if (tmp == conn) {
-			if (conn->c_stage != ISCSI_CONN_STOPPED ||
-			    conn->stop_stage == STOP_CONN_TERM) {
-				printk(KERN_ERR "iscsi: can't bind "
-				       "non-stopped connection (%d:%d)\n",
-				       conn->c_stage, conn->stop_stage);
-				spin_unlock_bh(&session->lock);
-				return -EIO;
-			}
-			break;
-		}
-	}
-	if (tmp != conn) {
-		/* bind new iSCSI connection to session */
-		conn->session = session;
-		list_add(&conn->item, &session->connections);
-	}
-	spin_unlock_bh(&session->lock);
-
 	if (is_leading)
 		session->leadconn = conn;
+	spin_unlock_bh(&session->lock);
 
 	/*
 	 * Unblock xmitworker(), Login Phase will pass through.
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 30b8014..e34a934 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -71,55 +71,65 @@
 static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
 			    void *resp, int resp_size)
 {
-	int res;
-	struct sas_task *task = sas_alloc_task(GFP_KERNEL);
+	int res, retry;
+	struct sas_task *task = NULL;
 	struct sas_internal *i =
 		to_sas_internal(dev->port->ha->core.shost->transportt);
 
-	if (!task)
-		return -ENOMEM;
+	for (retry = 0; retry < 3; retry++) {
+		task = sas_alloc_task(GFP_KERNEL);
+		if (!task)
+			return -ENOMEM;
 
-	task->dev = dev;
-	task->task_proto = dev->tproto;
-	sg_init_one(&task->smp_task.smp_req, req, req_size);
-	sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
+		task->dev = dev;
+		task->task_proto = dev->tproto;
+		sg_init_one(&task->smp_task.smp_req, req, req_size);
+		sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
 
-	task->task_done = smp_task_done;
+		task->task_done = smp_task_done;
 
-	task->timer.data = (unsigned long) task;
-	task->timer.function = smp_task_timedout;
-	task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
-	add_timer(&task->timer);
+		task->timer.data = (unsigned long) task;
+		task->timer.function = smp_task_timedout;
+		task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
+		add_timer(&task->timer);
 
-	res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
+		res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
 
-	if (res) {
-		del_timer(&task->timer);
-		SAS_DPRINTK("executing SMP task failed:%d\n", res);
-		goto ex_err;
-	}
-
-	wait_for_completion(&task->completion);
-	res = -ETASK;
-	if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
-		SAS_DPRINTK("smp task timed out or aborted\n");
-		i->dft->lldd_abort_task(task);
-		if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
-			SAS_DPRINTK("SMP task aborted and not done\n");
+		if (res) {
+			del_timer(&task->timer);
+			SAS_DPRINTK("executing SMP task failed:%d\n", res);
 			goto ex_err;
 		}
+
+		wait_for_completion(&task->completion);
+		res = -ETASK;
+		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+			SAS_DPRINTK("smp task timed out or aborted\n");
+			i->dft->lldd_abort_task(task);
+			if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
+				SAS_DPRINTK("SMP task aborted and not done\n");
+				goto ex_err;
+			}
+		}
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+		    task->task_status.stat == SAM_GOOD) {
+			res = 0;
+			break;
+		} else {
+			SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
+				    "status 0x%x\n", __FUNCTION__,
+				    SAS_ADDR(dev->sas_addr),
+				    task->task_status.resp,
+				    task->task_status.stat);
+			sas_free_task(task);
+			task = NULL;
+		}
 	}
-	if (task->task_status.resp == SAS_TASK_COMPLETE &&
-	    task->task_status.stat == SAM_GOOD)
-		res = 0;
-	else
-		SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
-			    "status 0x%x\n", __FUNCTION__,
-			    SAS_ADDR(dev->sas_addr),
-			    task->task_status.resp,
-			    task->task_status.stat);
 ex_err:
-	sas_free_task(task);
+	BUG_ON(retry == 3 && task != NULL);
+	if (task != NULL) {
+		sas_free_task(task);
+	}
 	return res;
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 9496e87..2a4e02e 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -594,7 +594,8 @@
 {
 	struct Scsi_Host *host = class_to_shost(cdev);
 	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
-	return snprintf(buf, PAGE_SIZE, "0x%llx\n", phba->cfg_soft_wwpn);
+	return snprintf(buf, PAGE_SIZE, "0x%llx\n",
+			(unsigned long long)phba->cfg_soft_wwpn);
 }
 
 
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 1b53afb..3add7c2 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -188,7 +188,8 @@
 
 		if (!mp->virt) {
 			kfree(mp);
-			lpfc_free_ct_rsp(phba, mlist);
+			if (mlist)
+				lpfc_free_ct_rsp(phba, mlist);
 			return NULL;
 		}
 
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index d586c3d..19c79a0 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -305,7 +305,7 @@
 {
 	struct lpfc_hba *phba = p;
 	int rc;
-	DECLARE_WAIT_QUEUE_HEAD(work_waitq);
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(work_waitq);
 
 	set_user_nice(current, -20);
 	phba->work_wait = &work_waitq;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 24a1779..582f5ea 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2983,7 +2983,7 @@
 			 struct lpfc_iocbq * prspiocbq,
 			 uint32_t timeout)
 {
-	DECLARE_WAIT_QUEUE_HEAD(done_q);
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
 	long timeleft, timeout_req = 0;
 	int retval = IOCB_SUCCESS;
 	uint32_t creg_val;
@@ -3061,7 +3061,7 @@
 lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
 			 uint32_t timeout)
 {
-	DECLARE_WAIT_QUEUE_HEAD(done_q);
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
 	DECLARE_WAITQUEUE(wq_entry, current);
 	uint32_t timeleft = 0;
 	int retval;
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index b1d3460..f2d79c3 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -183,7 +183,7 @@
  * Clenaup parameters and call done() functions.
  * You must be set SCpnt->result before call this function.
  */
-static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
+static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
 {
 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 
@@ -192,7 +192,8 @@
 	SCpnt->scsi_done(SCpnt);
 }
 
-static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
+			    void (*done)(struct scsi_cmnd *))
 {
 #ifdef NSP_DEBUG
 	/*unsigned int host_id = SCpnt->device->host->this_id;*/
@@ -365,7 +366,7 @@
 /*
  * Start selection phase
  */
-static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
+static int nsphw_start_selection(struct scsi_cmnd *SCpnt)
 {
 	unsigned int  host_id	 = SCpnt->device->host->this_id;
 	unsigned int  base	 = SCpnt->device->host->io_port;
@@ -446,7 +447,7 @@
 /*
  * setup synchronous data transfer mode
  */
-static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
+static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
 {
 	unsigned char	       target = scmd_id(SCpnt);
 //	unsigned char	       lun    = SCpnt->device->lun;
@@ -504,7 +505,7 @@
 /*
  * start ninja hardware timer
  */
-static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
+static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
 {
 	unsigned int base = SCpnt->device->host->io_port;
 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
@@ -517,7 +518,8 @@
 /*
  * wait for bus phase change
  */
-static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
+static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
+			     char *str)
 {
 	unsigned int  base = SCpnt->device->host->io_port;
 	unsigned char reg;
@@ -544,9 +546,9 @@
 /*
  * expect Ninja Irq
  */
-static int nsp_expect_signal(Scsi_Cmnd	   *SCpnt,
-			     unsigned char  current_phase,
-			     unsigned char  mask)
+static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
+			     unsigned char current_phase,
+			     unsigned char mask)
 {
 	unsigned int  base	 = SCpnt->device->host->io_port;
 	int	      time_out;
@@ -579,7 +581,7 @@
 /*
  * transfer SCSI message
  */
-static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
+static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase)
 {
 	unsigned int  base = SCpnt->device->host->io_port;
 	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
@@ -619,7 +621,7 @@
 /*
  * get extra SCSI data from fifo
  */
-static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
+static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt)
 {
 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 	unsigned int count;
@@ -651,7 +653,7 @@
 /*
  * accept reselection
  */
-static int nsp_reselected(Scsi_Cmnd *SCpnt)
+static int nsp_reselected(struct scsi_cmnd *SCpnt)
 {
 	unsigned int  base    = SCpnt->device->host->io_port;
 	unsigned int  host_id = SCpnt->device->host->this_id;
@@ -690,7 +692,7 @@
 /*
  * count how many data transferd
  */
-static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
+static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
 {
 	unsigned int base = SCpnt->device->host->io_port;
 	unsigned int count;
@@ -717,7 +719,7 @@
 /*
  * read data in DATA IN phase
  */
-static void nsp_pio_read(Scsi_Cmnd *SCpnt)
+static void nsp_pio_read(struct scsi_cmnd *SCpnt)
 {
 	unsigned int  base      = SCpnt->device->host->io_port;
 	unsigned long mmio_base = SCpnt->device->host->base;
@@ -812,7 +814,7 @@
 /*
  * write data in DATA OUT phase
  */
-static void nsp_pio_write(Scsi_Cmnd *SCpnt)
+static void nsp_pio_write(struct scsi_cmnd *SCpnt)
 {
 	unsigned int  base      = SCpnt->device->host->io_port;
 	unsigned long mmio_base = SCpnt->device->host->base;
@@ -905,7 +907,7 @@
 /*
  * setup synchronous/asynchronous data transfer mode
  */
-static int nsp_nexus(Scsi_Cmnd *SCpnt)
+static int nsp_nexus(struct scsi_cmnd *SCpnt)
 {
 	unsigned int   base   = SCpnt->device->host->io_port;
 	unsigned char  target = scmd_id(SCpnt);
@@ -952,7 +954,7 @@
 {
 	unsigned int   base;
 	unsigned char  irq_status, irq_phase, phase;
-	Scsi_Cmnd     *tmpSC;
+	struct scsi_cmnd *tmpSC;
 	unsigned char  target, lun;
 	unsigned int  *sync_neg;
 	int            i, tmp;
@@ -1530,7 +1532,7 @@
 /*---------------------------------------------------------------*/
 
 /*
-static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
+static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
 {
 	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
 
@@ -1558,7 +1560,7 @@
 	return SUCCESS;
 }
 
-static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
+static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
 {
 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 
@@ -1567,7 +1569,7 @@
 	return nsp_bus_reset(data);
 }
 
-static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
+static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
 {
 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index a88714f..625ca97 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -266,7 +266,7 @@
 
 	int           TimerCount;
 	int           SelectionTimeOut;
-	Scsi_Cmnd    *CurrentSC;
+	struct scsi_cmnd *CurrentSC;
 	//int           CurrnetTarget;
 
 	int           FifoCount;
@@ -319,30 +319,34 @@
 					 int     hostno,
 #endif
 					 int     inout);
-static        int        nsp_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *SCpnt));
+static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
+			    void (* done)(struct scsi_cmnd *SCpnt));
 
 /* Error handler */
-/*static int nsp_eh_abort       (Scsi_Cmnd *SCpnt);*/
-/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/
-static int nsp_eh_bus_reset    (Scsi_Cmnd *SCpnt);
-static int nsp_eh_host_reset   (Scsi_Cmnd *SCpnt);
+/*static int nsp_eh_abort       (struct scsi_cmnd *SCpnt);*/
+/*static int nsp_eh_device_reset(struct scsi_cmnd *SCpnt);*/
+static int nsp_eh_bus_reset    (struct scsi_cmnd *SCpnt);
+static int nsp_eh_host_reset   (struct scsi_cmnd *SCpnt);
 static int nsp_bus_reset       (nsp_hw_data *data);
 
 /* */
 static int  nsphw_init           (nsp_hw_data *data);
-static int  nsphw_start_selection(Scsi_Cmnd *SCpnt);
-static void nsp_start_timer      (Scsi_Cmnd *SCpnt, int time);
-static int  nsp_fifo_count       (Scsi_Cmnd *SCpnt);
-static void nsp_pio_read         (Scsi_Cmnd *SCpnt);
-static void nsp_pio_write        (Scsi_Cmnd *SCpnt);
-static int  nsp_nexus            (Scsi_Cmnd *SCpnt);
-static void nsp_scsi_done        (Scsi_Cmnd *SCpnt);
-static int  nsp_analyze_sdtr     (Scsi_Cmnd *SCpnt);
-static int  nsp_negate_signal    (Scsi_Cmnd *SCpnt, unsigned char mask, char *str);
-static int  nsp_expect_signal    (Scsi_Cmnd *SCpnt, unsigned char current_phase, unsigned char  mask);
-static int  nsp_xfer             (Scsi_Cmnd *SCpnt, int phase);
-static int  nsp_dataphase_bypass (Scsi_Cmnd *SCpnt);
-static int  nsp_reselected       (Scsi_Cmnd *SCpnt);
+static int  nsphw_start_selection(struct scsi_cmnd *SCpnt);
+static void nsp_start_timer      (struct scsi_cmnd *SCpnt, int time);
+static int  nsp_fifo_count       (struct scsi_cmnd *SCpnt);
+static void nsp_pio_read         (struct scsi_cmnd *SCpnt);
+static void nsp_pio_write        (struct scsi_cmnd *SCpnt);
+static int  nsp_nexus            (struct scsi_cmnd *SCpnt);
+static void nsp_scsi_done        (struct scsi_cmnd *SCpnt);
+static int  nsp_analyze_sdtr     (struct scsi_cmnd *SCpnt);
+static int  nsp_negate_signal    (struct scsi_cmnd *SCpnt,
+				  unsigned char mask, char *str);
+static int  nsp_expect_signal    (struct scsi_cmnd *SCpnt,
+				  unsigned char current_phase,
+				  unsigned char  mask);
+static int  nsp_xfer             (struct scsi_cmnd *SCpnt, int phase);
+static int  nsp_dataphase_bypass (struct scsi_cmnd *SCpnt);
+static int  nsp_reselected       (struct scsi_cmnd *SCpnt);
 static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht);
 
 /* Interrupt handler */
@@ -355,8 +359,8 @@
 
 /* Debug */
 #ifdef NSP_DEBUG
-static void show_command (Scsi_Cmnd *SCpnt);
-static void show_phase   (Scsi_Cmnd *SCpnt);
+static void show_command (struct scsi_cmnd *SCpnt);
+static void show_phase   (struct scsi_cmnd *SCpnt);
 static void show_busphase(unsigned char stat);
 static void show_message (nsp_hw_data *data);
 #else
diff --git a/drivers/scsi/pcmcia/nsp_debug.c b/drivers/scsi/pcmcia/nsp_debug.c
index 62e5c60..2f75fe6 100644
--- a/drivers/scsi/pcmcia/nsp_debug.c
+++ b/drivers/scsi/pcmcia/nsp_debug.c
@@ -138,12 +138,12 @@
 	printk("\n");
 }
 
-static void show_command(Scsi_Cmnd *SCpnt)
+static void show_command(struct scsi_cmnd *SCpnt)
 {
 	print_commandk(SCpnt->cmnd);
 }
 
-static void show_phase(Scsi_Cmnd *SCpnt)
+static void show_phase(struct scsi_cmnd *SCpnt)
 {
 	int i = SCpnt->SCp.phase;
 
diff --git a/drivers/scsi/pcmcia/nsp_message.c b/drivers/scsi/pcmcia/nsp_message.c
index d705773..ef593b7 100644
--- a/drivers/scsi/pcmcia/nsp_message.c
+++ b/drivers/scsi/pcmcia/nsp_message.c
@@ -8,7 +8,7 @@
 
 /* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */
 
-static void nsp_message_in(Scsi_Cmnd *SCpnt)
+static void nsp_message_in(struct scsi_cmnd *SCpnt)
 {
 	unsigned int  base = SCpnt->device->host->io_port;
 	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
@@ -50,7 +50,7 @@
 
 }
 
-static void nsp_message_out(Scsi_Cmnd *SCpnt)
+static void nsp_message_out(struct scsi_cmnd *SCpnt)
 {
 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 	int ret = 1;
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index b0eba39..89a2a9f 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -1012,7 +1012,7 @@
 static int __ppa_attach(struct parport *pb)
 {
 	struct Scsi_Host *host;
-	DECLARE_WAIT_QUEUE_HEAD(waiting);
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
 	DEFINE_WAIT(wait);
 	ppa_struct *dev;
 	int ports;
diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c
index a720c92..899e89d 100644
--- a/drivers/scsi/psi240i.c
+++ b/drivers/scsi/psi240i.c
@@ -87,11 +87,11 @@
 	{
 	USHORT		 ports[13];
 	OUR_DEVICE	 device[8];
-	Scsi_Cmnd	*pSCmnd;
+	struct scsi_cmnd *pSCmnd;
 	IDE_STRUCT	 ide;
 	ULONG		 startSector;
 	USHORT		 sectorCount;
-	Scsi_Cmnd	*SCpnt;
+	struct scsi_cmnd *SCpnt;
 	VOID		*buffer;
 	USHORT		 expectingIRQ;
 	}	ADAPTER240I, *PADAPTER240I;
@@ -253,12 +253,12 @@
  ****************************************************************/
 static void Irq_Handler (int irq, void *dev_id)
 	{
-	struct Scsi_Host   *shost;			// Pointer to host data block
-	PADAPTER240I		padapter;		// Pointer to adapter control structure
-	USHORT		 	   *pports;			// I/O port array
-	Scsi_Cmnd		   *SCpnt;
-	UCHAR				status;
-	int					z;
+	struct Scsi_Host *shost;	// Pointer to host data block
+	PADAPTER240I padapter;		// Pointer to adapter control structure
+	USHORT *pports;			// I/O port array
+	struct scsi_cmnd *SCpnt;
+	UCHAR status;
+	int z;
 
 	DEB(printk ("\npsi240i received interrupt\n"));
 
@@ -328,7 +328,7 @@
 				pinquiryData->AdditionalLength = 35 - 4;
 
 				// Fill in vendor identification fields.
-				for ( z = 0;  z < 20;  z += 2 )
+				for ( z = 0;  z < 8;  z += 2 )
 					{
 					pinquiryData->VendorId[z]	  = ((UCHAR *)identifyData.ModelNumber)[z + 1];
 					pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z];
@@ -389,12 +389,17 @@
  *	Returns:		Status code.
  *
  ****************************************************************/
-static int Psi240i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int Psi240i_QueueCommand(struct scsi_cmnd *SCpnt,
+				void (*done)(struct scsi_cmnd *))
 	{
-	UCHAR		   *cdb = (UCHAR *)SCpnt->cmnd;					// Pointer to SCSI CDB
-	PADAPTER240I	padapter = HOSTDATA (SCpnt->device->host); 			// Pointer to adapter control structure
-	POUR_DEVICE 		pdev	 = &padapter->device [SCpnt->device->id];// Pointer to device information
-	UCHAR			rc;											// command return code
+	UCHAR *cdb = (UCHAR *)SCpnt->cmnd;
+	// Pointer to SCSI CDB
+	PADAPTER240I padapter = HOSTDATA (SCpnt->device->host);
+	// Pointer to adapter control structure
+	POUR_DEVICE pdev = &padapter->device [SCpnt->device->id];
+	// Pointer to device information
+	UCHAR rc;
+	// command return code
 
 	SCpnt->scsi_done = done;
 	padapter->ide.ide.ides.spigot = pdev->spigot;
diff --git a/drivers/scsi/psi240i.h b/drivers/scsi/psi240i.h
index 6a59876..21ebb92 100644
--- a/drivers/scsi/psi240i.h
+++ b/drivers/scsi/psi240i.h
@@ -309,7 +309,7 @@
 #endif	// PSI_EIDE_SCSIOP
 
 // function prototypes
-int Psi240i_Command			(Scsi_Cmnd *SCpnt);
-int Psi240i_Abort			(Scsi_Cmnd *SCpnt);
-int Psi240i_Reset			(Scsi_Cmnd *SCpnt, unsigned int flags);
+int Psi240i_Command(struct scsi_cmnd *SCpnt);
+int Psi240i_Abort(struct scsi_cmnd *SCpnt);
+int Psi240i_Reset(struct scsi_cmnd *SCpnt, unsigned int flags);
 #endif
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 2521d54..16af5b7 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -931,11 +931,10 @@
 
 	case BUS_RESET:
 		if (qla1280_verbose)
-			printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS "
-			       "DEVICE RESET\n", ha->host_no, bus);
-		if (qla1280_bus_reset(ha, bus == 0))
+			printk(KERN_INFO "qla1280(%ld:%d): Issued bus "
+			       "reset.\n", ha->host_no, bus);
+		if (qla1280_bus_reset(ha, bus) == 0)
 			result = SUCCESS;
-
 		break;
 
 	case ADAPTER_RESET:
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index ee75a71..285c8e8 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -379,21 +379,37 @@
 	.read = qla2x00_sysfs_read_sfp,
 };
 
+static struct sysfs_entry {
+	char *name;
+	struct bin_attribute *attr;
+	int is4GBp_only;
+} bin_file_entries[] = {
+	{ "fw_dump", &sysfs_fw_dump_attr, },
+	{ "nvram", &sysfs_nvram_attr, },
+	{ "optrom", &sysfs_optrom_attr, },
+	{ "optrom_ctl", &sysfs_optrom_ctl_attr, },
+	{ "vpd", &sysfs_vpd_attr, 1 },
+	{ "sfp", &sysfs_sfp_attr, 1 },
+	{ 0 },
+};
+
 void
 qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
 {
 	struct Scsi_Host *host = ha->host;
+	struct sysfs_entry *iter;
+	int ret;
 
-	sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr);
-	sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
-	sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
-	sysfs_create_bin_file(&host->shost_gendev.kobj,
-	    &sysfs_optrom_ctl_attr);
-	if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
-		sysfs_create_bin_file(&host->shost_gendev.kobj,
-		    &sysfs_vpd_attr);
-		sysfs_create_bin_file(&host->shost_gendev.kobj,
-		    &sysfs_sfp_attr);
+	for (iter = bin_file_entries; iter->name; iter++) {
+		if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)))
+			continue;
+
+		ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
+		    iter->attr);
+		if (ret)
+			qla_printk(KERN_INFO, ha,
+			    "Unable to create sysfs %s binary attribute "
+			    "(%d).\n", iter->name, ret);
 	}
 }
 
@@ -401,17 +417,14 @@
 qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
 {
 	struct Scsi_Host *host = ha->host;
+	struct sysfs_entry *iter;
 
-	sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr);
-	sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
-	sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
-	sysfs_remove_bin_file(&host->shost_gendev.kobj,
-	    &sysfs_optrom_ctl_attr);
-	if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+	for (iter = bin_file_entries; iter->name; iter++) {
+		if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)))
+			continue;
+
 		sysfs_remove_bin_file(&host->shost_gendev.kobj,
-		    &sysfs_vpd_attr);
-		sysfs_remove_bin_file(&host->shost_gendev.kobj,
-		    &sysfs_sfp_attr);
+		    iter->attr);
 	}
 
 	if (ha->beacon_blink_led == 1)
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index 90dad7e..5b12278 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -38,7 +38,7 @@
 * Macros use for debugging the driver.
 */
 
-#define DEBUG(x)	do { if (qla2_extended_error_logging) { x; } } while (0)
+#define DEBUG(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
 
 #if defined(QL_DEBUG_LEVEL_1)
 #define DEBUG1(x)	do {x;} while (0)
@@ -46,12 +46,12 @@
 #define DEBUG1(x)	do {} while (0)
 #endif
 
-#define DEBUG2(x)	do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_3(x)	do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_3_11(x)	do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_9_10(x)	do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_11(x)	do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_13(x)	do { if (qla2_extended_error_logging) { x; } } while (0)
+#define DEBUG2(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_3(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_3_11(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_9_10(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_11(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_13(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
 
 #if defined(QL_DEBUG_LEVEL_3)
 #define DEBUG3(x)	do {x;} while (0)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index bab33f6..c4fc40f 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1545,6 +1545,9 @@
 	spinlock_t rport_lock;
 	struct fc_rport *rport, *drport;
 	u32 supported_classes;
+
+	unsigned long last_queue_full;
+	unsigned long last_ramp_up;
 } fc_port_t;
 
 /*
@@ -2255,6 +2258,7 @@
 	uint16_t	mgmt_svr_loop_id;
 
         uint32_t	login_retry_count;
+	int		max_q_depth;
 
 	/* Fibre Channel Device List. */
 	struct list_head	fcports;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 7da6983..32ebeec 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -48,6 +48,7 @@
 extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
 
 extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
+extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
 
 /*
  * Global Data in qla_os.c source file.
@@ -60,7 +61,8 @@
 extern int ql2xloginretrycount;
 extern int ql2xfdmienable;
 extern int ql2xallocfwdump;
-extern int qla2_extended_error_logging;
+extern int ql2xextended_error_logging;
+extern int ql2xqfullrampup;
 
 extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
 
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 833b930..08cb5e3 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1644,7 +1644,7 @@
 	 * Set host adapter parameters.
 	 */
 	if (nv->host_p[0] & BIT_7)
-		qla2_extended_error_logging = 1;
+		ql2xextended_error_logging = 1;
 	ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0);
 	/* Always load RISC code on non ISP2[12]00 chips. */
 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
@@ -3948,3 +3948,24 @@
 fail_fw_integrity:
 	return QLA_FUNCTION_FAILED;
 }
+
+void
+qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha)
+{
+	int ret, retries;
+
+	if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+		return;
+
+	ret = qla2x00_stop_firmware(ha);
+	for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) {
+		qla2x00_reset_chip(ha);
+		if (qla2x00_chip_diag(ha) != QLA_SUCCESS)
+			continue;
+		if (qla2x00_setup_chip(ha) != QLA_SUCCESS)
+			continue;
+		qla_printk(KERN_INFO, ha,
+		    "Attempting retry of stop-firmware command...\n");
+		ret = qla2x00_stop_firmware(ha);
+	}
+}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 626c717..d3b6df4 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -6,6 +6,8 @@
  */
 #include "qla_def.h"
 
+#include <scsi/scsi_tcq.h>
+
 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
 static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
 static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
@@ -593,6 +595,67 @@
 	}
 }
 
+static void
+qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data)
+{
+	fc_port_t *fcport = data;
+
+	if (fcport->ha->max_q_depth <= sdev->queue_depth)
+		return;
+
+	if (sdev->ordered_tags)
+		scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
+		    sdev->queue_depth + 1);
+	else
+		scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG,
+		    sdev->queue_depth + 1);
+
+	fcport->last_ramp_up = jiffies;
+
+	DEBUG2(qla_printk(KERN_INFO, fcport->ha,
+	    "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n",
+	    fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
+	    sdev->queue_depth));
+}
+
+static void
+qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data)
+{
+	fc_port_t *fcport = data;
+
+	if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1))
+		return;
+
+	DEBUG2(qla_printk(KERN_INFO, fcport->ha,
+	    "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
+	    fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
+	    sdev->queue_depth));
+}
+
+static inline void
+qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp)
+{
+	fc_port_t *fcport;
+	struct scsi_device *sdev;
+
+	sdev = sp->cmd->device;
+	if (sdev->queue_depth >= ha->max_q_depth)
+		return;
+
+	fcport = sp->fcport;
+	if (time_before(jiffies,
+	    fcport->last_ramp_up + ql2xqfullrampup * HZ))
+		return;
+	if (time_before(jiffies,
+	    fcport->last_queue_full + ql2xqfullrampup * HZ))
+		return;
+
+	spin_unlock_irq(&ha->hardware_lock);
+	starget_for_each_device(sdev->sdev_target, fcport,
+	    qla2x00_adjust_sdev_qdepth_up);
+	spin_lock_irq(&ha->hardware_lock);
+}
+
 /**
  * qla2x00_process_completed_request() - Process a Fast Post response.
  * @ha: SCSI driver HA context
@@ -624,6 +687,8 @@
 
 		/* Save ISP completion status */
 		sp->cmd->result = DID_OK << 16;
+
+		qla2x00_ramp_up_queue_depth(ha, sp);
 		qla2x00_sp_compl(ha, sp);
 	} else {
 		DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
@@ -823,6 +888,7 @@
 	 */
 	switch (comp_status) {
 	case CS_COMPLETE:
+	case CS_QUEUE_FULL:
 		if (scsi_status == 0) {
 			cp->result = DID_OK << 16;
 			break;
@@ -849,6 +915,20 @@
 		}
 		cp->result = DID_OK << 16 | lscsi_status;
 
+		if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
+			DEBUG2(printk(KERN_INFO
+			    "scsi(%ld): QUEUE FULL status detected "
+			    "0x%x-0x%x.\n", ha->host_no, comp_status,
+			    scsi_status));
+
+			/* Adjust queue depth for all luns on the port. */
+			fcport->last_queue_full = jiffies;
+			spin_unlock_irq(&ha->hardware_lock);
+			starget_for_each_device(cp->device->sdev_target,
+			    fcport, qla2x00_adjust_sdev_qdepth_down);
+			spin_lock_irq(&ha->hardware_lock);
+			break;
+		}
 		if (lscsi_status != SS_CHECK_CONDITION)
 			break;
 
@@ -1066,17 +1146,6 @@
 			qla2x00_mark_device_lost(ha, fcport, 1, 1);
 		break;
 
-	case CS_QUEUE_FULL:
-		DEBUG2(printk(KERN_INFO
-		    "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n",
-		    ha->host_no, comp_status, scsi_status));
-
-		/* SCSI Mid-Layer handles device queue full */
-
-		cp->result = DID_OK << 16 | lscsi_status;
-
-		break;
-
 	default:
 		DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
 		    "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3f20d76..208607b 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -61,9 +61,9 @@
 		"during HBA initialization.  Memory allocation requirements "
 		"vary by ISP type.  Default is 1 - allocate memory.");
 
-int qla2_extended_error_logging;
-module_param(qla2_extended_error_logging, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(qla2_extended_error_logging,
+int ql2xextended_error_logging;
+module_param(ql2xextended_error_logging, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xextended_error_logging,
 		"Option to enable extended error logging, "
 		"Default is 0 - no logging. 1 - log errors.");
 
@@ -77,6 +77,19 @@
 		"Enables FDMI registratons "
 		"Default is 0 - no FDMI. 1 - perfom FDMI.");
 
+#define MAX_Q_DEPTH    32
+static int ql2xmaxqdepth = MAX_Q_DEPTH;
+module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ql2xmaxqdepth,
+		"Maximum queue depth to report for target devices.");
+
+int ql2xqfullrampup = 120;
+module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ql2xqfullrampup,
+		"Number of seconds to wait to begin to ramp-up the queue "
+		"depth for a device after a queue-full condition has been "
+		"detected.  Default is 120 seconds.");
+
 /*
  * SCSI host template entry points
  */
@@ -1104,9 +1117,9 @@
 	struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
 
 	if (sdev->tagged_supported)
-		scsi_activate_tcq(sdev, 32);
+		scsi_activate_tcq(sdev, ha->max_q_depth);
 	else
-		scsi_deactivate_tcq(sdev, 32);
+		scsi_deactivate_tcq(sdev, ha->max_q_depth);
 
 	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
 
@@ -1413,6 +1426,10 @@
 	ha->link_data_rate = PORT_SPEED_UNKNOWN;
 	ha->optrom_size = OPTROM_SIZE_2300;
 
+	ha->max_q_depth = MAX_Q_DEPTH;
+	if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU)
+		ha->max_q_depth = ql2xmaxqdepth;
+
 	/* Assign ISP specific operations. */
 	ha->isp_ops.pci_config		= qla2100_pci_config;
 	ha->isp_ops.reset_chip		= qla2x00_reset_chip;
@@ -1712,8 +1729,10 @@
 	if (ha->eft)
 		qla2x00_trace_control(ha, TC_DISABLE, 0, 0);
 
+	ha->flags.online = 0;
+
 	/* Stop currently executing firmware. */
-	qla2x00_stop_firmware(ha);
+	qla2x00_try_to_stop_firmware(ha);
 
 	/* turn-off interrupts on the card */
 	if (ha->interrupts_on)
@@ -1721,8 +1740,6 @@
 
 	qla2x00_mem_free(ha);
 
-	ha->flags.online = 0;
-
 	/* Detach interrupts */
 	if (ha->host->irq)
 		free_irq(ha->host->irq, ha);
@@ -2697,7 +2714,7 @@
 
 	/* Derive version string. */
 	strcpy(qla2x00_version_str, QLA2XXX_VERSION);
-	if (qla2_extended_error_logging)
+	if (ql2xextended_error_logging)
 		strcat(qla2x00_version_str, "-debug");
 
 	qla2xxx_transport_template =
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index e57bf45..1fa0bce 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.01.07-k2"
+#define QLA2XXX_VERSION      "8.01.07-k3"
 
 #define QLA_DRIVER_MAJOR_VER	8
 #define QLA_DRIVER_MINOR_VER	1
diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig
index 08a07f0..69cbff3 100644
--- a/drivers/scsi/qla4xxx/Kconfig
+++ b/drivers/scsi/qla4xxx/Kconfig
@@ -1,6 +1,6 @@
 config SCSI_QLA_ISCSI
 	tristate "QLogic ISP4XXX host adapter family support"
-	depends on PCI && SCSI
+	depends on PCI && SCSI && NET
 	select SCSI_ISCSI_ATTRS
 	---help---
 	This driver supports the QLogic 40xx (ISP4XXX) iSCSI host
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.h b/drivers/scsi/qla4xxx/ql4_dbg.h
index 3e99dcf..d861c3b 100644
--- a/drivers/scsi/qla4xxx/ql4_dbg.h
+++ b/drivers/scsi/qla4xxx/ql4_dbg.h
@@ -22,14 +22,14 @@
 #endif
 
 #if defined(QL_DEBUG_LEVEL_2)
-#define DEBUG2(x)      do {if(qla4_extended_error_logging == 2) x;} while (0);
+#define DEBUG2(x)      do {if(ql4xextended_error_logging == 2) x;} while (0);
 #define DEBUG2_3(x)   do {x;} while (0);
 #else				/*  */
 #define DEBUG2(x)	do {} while (0);
 #endif				/*  */
 
 #if defined(QL_DEBUG_LEVEL_3)
-#define DEBUG3(x)      do {if(qla4_extended_error_logging == 3) x;} while (0);
+#define DEBUG3(x)      do {if(ql4xextended_error_logging == 3) x;} while (0);
 #else				/*  */
 #define DEBUG3(x)	do {} while (0);
 #if !defined(QL_DEBUG_LEVEL_2)
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 2c803ed..1b221ff 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -72,7 +72,7 @@
 int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha,
 				uint32_t fw_ddb_index, uint32_t state);
 
-extern int qla4_extended_error_logging;
+extern int ql4xextended_error_logging;
 extern int ql4xdiscoverywait;
 extern int ql4xdontresethba;
 #endif				/* _QLA4x_GBL_H */
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index ef82399..b721dc5 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -701,7 +701,7 @@
 	DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
 		      ha->host_no, num_valid_entries));
 
-	if (qla4_extended_error_logging == 3) {
+	if (ql4xextended_error_logging == 3) {
 		if (oldest_entry == 0) {
 			/* Circular Buffer has not wrapped around */
 			for (i=0; i < num_valid_entries; i++) {
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 178fcdd..5b8db61 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -34,9 +34,9 @@
 		 " default it will reset hba :0"
 		 " set to 1 to avoid resetting HBA");
 
-int qla4_extended_error_logging = 0; /* 0 = off, 1 = log errors */
-module_param(qla4_extended_error_logging, int, S_IRUGO | S_IRUSR);
-MODULE_PARM_DESC(qla4_extended_error_logging,
+int ql4xextended_error_logging = 0; /* 0 = off, 1 = log errors */
+module_param(ql4xextended_error_logging, int, S_IRUGO | S_IRUSR);
+MODULE_PARM_DESC(ql4xextended_error_logging,
 		 "Option to enable extended error logging, "
 		 "Default is 0 - no logging, 1 - debug logging");
 
@@ -1714,7 +1714,7 @@
 
 	/* Derive version string. */
 	strcpy(qla4xxx_version_str, QLA4XXX_DRIVER_VERSION);
-	if (qla4_extended_error_logging)
+	if (ql4xextended_error_logging)
 		strcat(qla4xxx_version_str, "-debug");
 
 	qla4xxx_scsi_transport =
@@ -1724,13 +1724,13 @@
 		goto release_srb_cache;
 	}
 
-	printk(KERN_INFO "QLogic iSCSI HBA Driver\n");
 	ret = pci_register_driver(&qla4xxx_pci_driver);
 	if (ret)
 		goto unregister_transport;
 
 	printk(KERN_INFO "QLogic iSCSI HBA Driver\n");
 	return 0;
+
 unregister_transport:
 	iscsi_unregister_transport(&qla4xxx_iscsi_transport);
 release_srb_cache:
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index e072535..2e7db18 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -209,7 +209,7 @@
  *	caller must hold host lock
  */
 
-static void ql_icmd(Scsi_Cmnd * cmd)
+static void ql_icmd(struct scsi_cmnd *cmd)
 {
 	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
 	int 	qbase = priv->qbase;
@@ -256,7 +256,7 @@
  *	Process scsi command - usually after interrupt 
  */
 
-static unsigned int ql_pcmd(Scsi_Cmnd * cmd)
+static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
 {
 	unsigned int i, j;
 	unsigned long k;
@@ -407,7 +407,7 @@
 
 static void ql_ihandl(void *dev_id)
 {
-	Scsi_Cmnd *icmd;
+	struct scsi_cmnd *icmd;
 	struct Scsi_Host *host = dev_id;
 	struct qlogicfas408_priv *priv = get_priv_by_host(host);
 	int qbase = priv->qbase;
@@ -447,7 +447,8 @@
  *	Queued command
  */
 
-int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
+			      void (*done) (struct scsi_cmnd *))
 {
 	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
 	if (scmd_id(cmd) == priv->qinitid) {
@@ -470,9 +471,8 @@
  *	Return bios parameters 
  */
 
-int qlogicfas408_biosparam(struct scsi_device * disk,
-		        struct block_device *dev,
-			sector_t capacity, int ip[])
+int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev,
+			   sector_t capacity, int ip[])
 {
 /* This should mimic the DOS Qlogic driver's behavior exactly */
 	ip[0] = 0x40;
@@ -494,7 +494,7 @@
  *	Abort a command in progress
  */
  
-int qlogicfas408_abort(Scsi_Cmnd * cmd)
+int qlogicfas408_abort(struct scsi_cmnd *cmd)
 {
 	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
 	priv->qabort = 1;
@@ -508,7 +508,7 @@
  *	the PCMCIA qlogic_stub code. This wants fixing
  */
 
-int qlogicfas408_bus_reset(Scsi_Cmnd * cmd)
+int qlogicfas408_bus_reset(struct scsi_cmnd *cmd)
 {
 	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
 	unsigned long flags;
diff --git a/drivers/scsi/qlogicfas408.h b/drivers/scsi/qlogicfas408.h
index 8fd5555..2606264 100644
--- a/drivers/scsi/qlogicfas408.h
+++ b/drivers/scsi/qlogicfas408.h
@@ -75,15 +75,15 @@
 /*----------------------------------------------------------------*/
 
 struct qlogicfas408_priv {
-	 int		qbase;		/* Port */
-	 int		qinitid;	/* initiator ID */
-	 int		qabort;		/* Flag to cause an abort */
-	 int		qlirq;		/* IRQ being used */
-	 int		int_type;	/* type of irq, 2 for ISA board, 0 for PCMCIA */
-	 char		qinfo[80];	/* description */
-	 Scsi_Cmnd 	*qlcmd;		/* current command being processed */
-	 struct Scsi_Host *shost;	/* pointer back to host */
-	 struct qlogicfas408_priv *next; /* next private struct */
+	int qbase;		/* Port */
+	int qinitid;		/* initiator ID */
+	int qabort;		/* Flag to cause an abort */
+	int qlirq;		/* IRQ being used */
+	int int_type;		/* type of irq, 2 for ISA board, 0 for PCMCIA */
+	char qinfo[80];		/* description */
+	struct scsi_cmnd *qlcmd;	/* current command being processed */
+	struct Scsi_Host *shost;	/* pointer back to host */
+	struct qlogicfas408_priv *next; /* next private struct */
 };
 
 /* The qlogic card uses two register maps - These macros select which one */
@@ -103,12 +103,13 @@
 #define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0])
 
 irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id);
-int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
+int qlogicfas408_queuecommand(struct scsi_cmnd * cmd,
+			      void (*done) (struct scsi_cmnd *));
 int qlogicfas408_biosparam(struct scsi_device * disk,
-		        struct block_device *dev,
-			sector_t capacity, int ip[]);
-int qlogicfas408_abort(Scsi_Cmnd * cmd);
-int qlogicfas408_bus_reset(Scsi_Cmnd * cmd);
+			   struct block_device *dev,
+			   sector_t capacity, int ip[]);
+int qlogicfas408_abort(struct scsi_cmnd * cmd);
+int qlogicfas408_bus_reset(struct scsi_cmnd * cmd);
 const char *qlogicfas408_info(struct Scsi_Host *host);
 int qlogicfas408_get_chip_type(int qbase, int int_type);
 void qlogicfas408_setup(int qbase, int id, int int_type);
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 9c0f358..30ee3d7 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -52,7 +52,7 @@
 #include "scsi_debug.h"
 
 #define SCSI_DEBUG_VERSION "1.80"
-static const char * scsi_debug_version_date = "20060914";
+static const char * scsi_debug_version_date = "20061018";
 
 /* Additional Sense Code (ASC) used */
 #define NO_ADDITIONAL_SENSE 0x0
@@ -254,6 +254,8 @@
 			 struct sdebug_dev_info * devip);
 static int resp_start_stop(struct scsi_cmnd * scp,
 			   struct sdebug_dev_info * devip);
+static int resp_report_tgtpgs(struct scsi_cmnd * scp,
+			      struct sdebug_dev_info * devip);
 static int resp_readcap(struct scsi_cmnd * SCpnt,
 			struct sdebug_dev_info * devip);
 static int resp_readcap16(struct scsi_cmnd * SCpnt,
@@ -287,9 +289,9 @@
 static void __init init_all_queued(void);
 static void stop_all_queued(void);
 static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
-static int inquiry_evpd_83(unsigned char * arr, int target_dev_id,
-			   int dev_id_num, const char * dev_id_str,
-			   int dev_id_str_len);
+static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
+			   int target_dev_id, int dev_id_num,
+			   const char * dev_id_str, int dev_id_str_len);
 static int inquiry_evpd_88(unsigned char * arr, int target_dev_id);
 static int do_create_driverfs_files(void);
 static void do_remove_driverfs_files(void);
@@ -422,6 +424,15 @@
 		}
 		errsts = resp_readcap16(SCpnt, devip);
 		break;
+	case MAINTENANCE_IN:
+		if (MI_REPORT_TARGET_PGS != cmd[1]) {
+			mk_sense_buffer(devip, ILLEGAL_REQUEST,
+					INVALID_OPCODE, 0);
+			errsts = check_condition_result;
+			break;
+		}
+		errsts = resp_report_tgtpgs(SCpnt, devip);
+		break;
 	case READ_16:
 	case READ_12:
 	case READ_10:
@@ -665,8 +676,9 @@
 static const char * inq_product_id = "scsi_debug      ";
 static const char * inq_product_rev = "0004";
 
-static int inquiry_evpd_83(unsigned char * arr, int target_dev_id,
-			   int dev_id_num, const char * dev_id_str,
+static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
+			   int target_dev_id, int dev_id_num,
+			   const char * dev_id_str,
 			   int dev_id_str_len)
 {
 	int num, port_a;
@@ -720,6 +732,15 @@
 	arr[num++] = (port_a >> 16) & 0xff;
 	arr[num++] = (port_a >> 8) & 0xff;
 	arr[num++] = port_a & 0xff;
+	/* NAA-5, Target port group identifier */
+	arr[num++] = 0x61;	/* proto=sas, binary */
+	arr[num++] = 0x95;	/* piv=1, target port group id */
+	arr[num++] = 0x0;
+	arr[num++] = 0x4;
+	arr[num++] = 0;
+	arr[num++] = 0;
+	arr[num++] = (port_group_id >> 8) & 0xff;
+	arr[num++] = port_group_id & 0xff;
 	/* NAA-5, Target device identifier */
 	arr[num++] = 0x61;	/* proto=sas, binary */
 	arr[num++] = 0xa3;	/* piv=1, target device, naa */
@@ -928,12 +949,12 @@
 			struct sdebug_dev_info * devip)
 {
 	unsigned char pq_pdt;
-	unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ];
+	unsigned char * arr;
 	unsigned char *cmd = (unsigned char *)scp->cmnd;
-	int alloc_len, n;
+	int alloc_len, n, ret;
 
 	alloc_len = (cmd[3] << 8) + cmd[4];
-	memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ);
+	arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL);
 	if (devip->wlun)
 		pq_pdt = 0x1e;	/* present, wlun */
 	else if (scsi_debug_no_lun_0 && (0 == devip->lun))
@@ -944,12 +965,15 @@
 	if (0x2 & cmd[1]) {  /* CMDDT bit set */
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
 			       	0);
+		kfree(arr);
 		return check_condition_result;
 	} else if (0x1 & cmd[1]) {  /* EVPD bit set */
-		int lu_id_num, target_dev_id, len;
+		int lu_id_num, port_group_id, target_dev_id, len;
 		char lu_id_str[6];
 		int host_no = devip->sdbg_host->shost->host_no;
 		
+		port_group_id = (((host_no + 1) & 0x7f) << 8) +
+		    (devip->channel & 0x7f);
 		if (0 == scsi_debug_vpd_use_hostno)
 			host_no = 0;
 		lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) +
@@ -977,8 +1001,9 @@
 			memcpy(&arr[4], lu_id_str, len);
 		} else if (0x83 == cmd[2]) { /* device identification */
 			arr[1] = cmd[2];	/*sanity */
-			arr[3] = inquiry_evpd_83(&arr[4], target_dev_id,
-						 lu_id_num, lu_id_str, len);
+			arr[3] = inquiry_evpd_83(&arr[4], port_group_id,
+						 target_dev_id, lu_id_num,
+						 lu_id_str, len);
 		} else if (0x84 == cmd[2]) { /* Software interface ident. */
 			arr[1] = cmd[2];	/*sanity */
 			arr[3] = inquiry_evpd_84(&arr[4]);
@@ -1012,17 +1037,22 @@
 			/* Illegal request, invalid field in cdb */
 			mk_sense_buffer(devip, ILLEGAL_REQUEST,
 					INVALID_FIELD_IN_CDB, 0);
+			kfree(arr);
 			return check_condition_result;
 		}
 		len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len);
-		return fill_from_dev_buffer(scp, arr,
+		ret = fill_from_dev_buffer(scp, arr,
 			    min(len, SDEBUG_MAX_INQ_ARR_SZ));
+		kfree(arr);
+		return ret;
 	}
 	/* drops through here for a standard inquiry */
 	arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0;	/* Removable disk */
 	arr[2] = scsi_debug_scsi_level;
 	arr[3] = 2;    /* response_data_format==2 */
 	arr[4] = SDEBUG_LONG_INQ_SZ - 5;
+	if (0 == scsi_debug_vpd_use_hostno)
+		arr[5] = 0x10; /* claim: implicit TGPS */
 	arr[6] = 0x10; /* claim: MultiP */
 	/* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */
 	arr[7] = 0xa; /* claim: LINKED + CMDQUE */
@@ -1039,8 +1069,10 @@
 		arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */
 	}
 	arr[n++] = 0xc; arr[n++] = 0xf;  /* SAS-1.1 rev 10 */
-	return fill_from_dev_buffer(scp, arr,
+	ret = fill_from_dev_buffer(scp, arr,
 			    min(alloc_len, SDEBUG_LONG_INQ_SZ));
+	kfree(arr);
+	return ret;
 }
 
 static int resp_requests(struct scsi_cmnd * scp,
@@ -1171,6 +1203,87 @@
 				    min(alloc_len, SDEBUG_READCAP16_ARR_SZ));
 }
 
+#define SDEBUG_MAX_TGTPGS_ARR_SZ 1412
+
+static int resp_report_tgtpgs(struct scsi_cmnd * scp,
+			      struct sdebug_dev_info * devip)
+{
+	unsigned char *cmd = (unsigned char *)scp->cmnd;
+	unsigned char * arr;
+	int host_no = devip->sdbg_host->shost->host_no;
+	int n, ret, alen, rlen;
+	int port_group_a, port_group_b, port_a, port_b;
+
+	alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8)
+		+ cmd[9]);
+
+	arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL);
+	/*
+	 * EVPD page 0x88 states we have two ports, one
+	 * real and a fake port with no device connected.
+	 * So we create two port groups with one port each
+	 * and set the group with port B to unavailable.
+	 */
+	port_a = 0x1; /* relative port A */
+	port_b = 0x2; /* relative port B */
+	port_group_a = (((host_no + 1) & 0x7f) << 8) +
+	    (devip->channel & 0x7f);
+	port_group_b = (((host_no + 1) & 0x7f) << 8) +
+	    (devip->channel & 0x7f) + 0x80;
+
+	/*
+	 * The asymmetric access state is cycled according to the host_id.
+	 */
+	n = 4;
+	if (0 == scsi_debug_vpd_use_hostno) {
+	    arr[n++] = host_no % 3; /* Asymm access state */
+	    arr[n++] = 0x0F; /* claim: all states are supported */
+	} else {
+	    arr[n++] = 0x0; /* Active/Optimized path */
+	    arr[n++] = 0x01; /* claim: only support active/optimized paths */
+	}
+	arr[n++] = (port_group_a >> 8) & 0xff;
+	arr[n++] = port_group_a & 0xff;
+	arr[n++] = 0;    /* Reserved */
+	arr[n++] = 0;    /* Status code */
+	arr[n++] = 0;    /* Vendor unique */
+	arr[n++] = 0x1;  /* One port per group */
+	arr[n++] = 0;    /* Reserved */
+	arr[n++] = 0;    /* Reserved */
+	arr[n++] = (port_a >> 8) & 0xff;
+	arr[n++] = port_a & 0xff;
+	arr[n++] = 3;    /* Port unavailable */
+	arr[n++] = 0x08; /* claim: only unavailalbe paths are supported */
+	arr[n++] = (port_group_b >> 8) & 0xff;
+	arr[n++] = port_group_b & 0xff;
+	arr[n++] = 0;    /* Reserved */
+	arr[n++] = 0;    /* Status code */
+	arr[n++] = 0;    /* Vendor unique */
+	arr[n++] = 0x1;  /* One port per group */
+	arr[n++] = 0;    /* Reserved */
+	arr[n++] = 0;    /* Reserved */
+	arr[n++] = (port_b >> 8) & 0xff;
+	arr[n++] = port_b & 0xff;
+
+	rlen = n - 4;
+	arr[0] = (rlen >> 24) & 0xff;
+	arr[1] = (rlen >> 16) & 0xff;
+	arr[2] = (rlen >> 8) & 0xff;
+	arr[3] = rlen & 0xff;
+
+	/*
+	 * Return the smallest value of either
+	 * - The allocated length
+	 * - The constructed command length
+	 * - The maximum array size
+	 */
+	rlen = min(alen,n);
+	ret = fill_from_dev_buffer(scp, arr,
+				   min(rlen, SDEBUG_MAX_TGTPGS_ARR_SZ));
+	kfree(arr);
+	return ret;
+}
+
 /* <<Following mode page info copied from ST318451LW>> */
 
 static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 743f67e..3ac4890 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -410,6 +410,7 @@
 		goto free_req;
 
 	req->cmd_len = cmd_len;
+	memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
 	memcpy(req->cmd, cmd, req->cmd_len);
 	req->sense = sioc->sense;
 	req->sense_len = 0;
@@ -1084,7 +1085,7 @@
 {
 	struct request *req = cmd->request;
 
-	BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
+	BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
 	memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
 	cmd->cmd_len = req->cmd_len;
 	if (!req->data_len)
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index fd9e281..94a2746 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -631,12 +631,22 @@
 	 * scanning run at their own risk, or supply a user level program
 	 * that can correctly scan.
 	 */
-	sdev->inquiry = kmalloc(sdev->inquiry_len, GFP_ATOMIC);
-	if (sdev->inquiry == NULL) {
-		return SCSI_SCAN_NO_RESPONSE;
-	}
 
-	memcpy(sdev->inquiry, inq_result, sdev->inquiry_len);
+	/*
+	 * Copy at least 36 bytes of INQUIRY data, so that we don't
+	 * dereference unallocated memory when accessing the Vendor,
+	 * Product, and Revision strings.  Badly behaved devices may set
+	 * the INQUIRY Additional Length byte to a small value, indicating
+	 * these strings are invalid, but often they contain plausible data
+	 * nonetheless.  It doesn't matter if the device sent < 36 bytes
+	 * total, since scsi_probe_lun() initializes inq_result with 0s.
+	 */
+	sdev->inquiry = kmemdup(inq_result,
+				max_t(size_t, sdev->inquiry_len, 36),
+				GFP_ATOMIC);
+	if (sdev->inquiry == NULL)
+		return SCSI_SCAN_NO_RESPONSE;
+
 	sdev->vendor = (char *) (sdev->inquiry + 8);
 	sdev->model = (char *) (sdev->inquiry + 16);
 	sdev->rev = (char *) (sdev->inquiry + 32);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index e7fe565..e1a9166 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -192,6 +192,7 @@
 shost_rd_attr(unique_id, "%u\n");
 shost_rd_attr(host_busy, "%hu\n");
 shost_rd_attr(cmd_per_lun, "%hd\n");
+shost_rd_attr(can_queue, "%hd\n");
 shost_rd_attr(sg_tablesize, "%hu\n");
 shost_rd_attr(unchecked_isa_dma, "%d\n");
 shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");
@@ -200,6 +201,7 @@
 	&class_device_attr_unique_id,
 	&class_device_attr_host_busy,
 	&class_device_attr_cmd_per_lun,
+	&class_device_attr_can_queue,
 	&class_device_attr_sg_tablesize,
 	&class_device_attr_unchecked_isa_dma,
 	&class_device_attr_proc_name,
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 7b0019c..9b25124 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -21,7 +21,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 #include <linux/module.h>
-#include <linux/mempool.h>
 #include <linux/mutex.h>
 #include <net/tcp.h>
 #include <scsi/scsi.h>
@@ -34,7 +33,7 @@
 #define ISCSI_SESSION_ATTRS 11
 #define ISCSI_CONN_ATTRS 11
 #define ISCSI_HOST_ATTRS 0
-#define ISCSI_TRANSPORT_VERSION "2.0-685"
+#define ISCSI_TRANSPORT_VERSION "2.0-724"
 
 struct iscsi_internal {
 	int daemon_pid;
@@ -149,30 +148,6 @@
 static struct sock *nls;
 static DEFINE_MUTEX(rx_queue_mutex);
 
-struct mempool_zone {
-	mempool_t *pool;
-	atomic_t allocated;
-	int size;
-	int hiwat;
-	struct list_head freequeue;
-	spinlock_t freelock;
-};
-
-static struct mempool_zone *z_reply;
-
-/*
- * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time
- * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM
- *             so daemon will notice OOM on NETLINK tranposrt level and will
- *             be able to predict or change operational behavior
- */
-#define Z_MAX_REPLY	8
-#define Z_HIWAT_REPLY	6
-#define Z_MAX_PDU	8
-#define Z_HIWAT_PDU	6
-#define Z_MAX_ERROR	16
-#define Z_HIWAT_ERROR	12
-
 static LIST_HEAD(sesslist);
 static DEFINE_SPINLOCK(sesslock);
 static LIST_HEAD(connlist);
@@ -414,59 +389,11 @@
 }
 EXPORT_SYMBOL_GPL(iscsi_destroy_session);
 
-static void mempool_zone_destroy(struct mempool_zone *zp)
-{
-	mempool_destroy(zp->pool);
-	kfree(zp);
-}
-
-static void*
-mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
-{
-	struct mempool_zone *zone = pool_data;
-
-	return alloc_skb(zone->size, gfp_mask);
-}
-
-static void
-mempool_zone_free_skb(void *element, void *pool_data)
-{
-	kfree_skb(element);
-}
-
-static struct mempool_zone *
-mempool_zone_init(unsigned max, unsigned size, unsigned hiwat)
-{
-	struct mempool_zone *zp;
-
-	zp = kzalloc(sizeof(*zp), GFP_KERNEL);
-	if (!zp)
-		return NULL;
-
-	zp->size = size;
-	zp->hiwat = hiwat;
-	INIT_LIST_HEAD(&zp->freequeue);
-	spin_lock_init(&zp->freelock);
-	atomic_set(&zp->allocated, 0);
-
-	zp->pool = mempool_create(max, mempool_zone_alloc_skb,
-				  mempool_zone_free_skb, zp);
-	if (!zp->pool) {
-		kfree(zp);
-		return NULL;
-	}
-
-	return zp;
-}
-
 static void iscsi_conn_release(struct device *dev)
 {
 	struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);
 	struct device *parent = conn->dev.parent;
 
-	mempool_zone_destroy(conn->z_pdu);
-	mempool_zone_destroy(conn->z_error);
-
 	kfree(conn);
 	put_device(parent);
 }
@@ -476,31 +403,6 @@
 	return dev->release == iscsi_conn_release;
 }
 
-static int iscsi_create_event_pools(struct iscsi_cls_conn *conn)
-{
-	conn->z_pdu = mempool_zone_init(Z_MAX_PDU,
-			NLMSG_SPACE(sizeof(struct iscsi_uevent) +
-				    sizeof(struct iscsi_hdr) +
-				    DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
-			Z_HIWAT_PDU);
-	if (!conn->z_pdu) {
-		dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
-			   "pdu zone for new conn\n");
-		return -ENOMEM;
-	}
-
-	conn->z_error = mempool_zone_init(Z_MAX_ERROR,
-			NLMSG_SPACE(sizeof(struct iscsi_uevent)),
-			Z_HIWAT_ERROR);
-	if (!conn->z_error) {
-		dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
-			   "error zone for new conn\n");
-		mempool_zone_destroy(conn->z_pdu);
-		return -ENOMEM;
-	}
-	return 0;
-}
-
 /**
  * iscsi_create_conn - create iscsi class connection
  * @session: iscsi cls session
@@ -533,12 +435,9 @@
 	conn->transport = transport;
 	conn->cid = cid;
 
-	if (iscsi_create_event_pools(conn))
-		goto free_conn;
-
 	/* this is released in the dev's release function */
 	if (!get_device(&session->dev))
-		goto free_conn_pools;
+		goto free_conn;
 
 	snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
 		 session->sid, cid);
@@ -555,8 +454,6 @@
 
 release_parent_ref:
 	put_device(&session->dev);
-free_conn_pools:
-
 free_conn:
 	kfree(conn);
 	return NULL;
@@ -599,81 +496,31 @@
 	return NULL;
 }
 
-static inline struct list_head *skb_to_lh(struct sk_buff *skb)
-{
-	return (struct list_head *)&skb->cb;
-}
-
-static void
-mempool_zone_complete(struct mempool_zone *zone)
-{
-	unsigned long flags;
-	struct list_head *lh, *n;
-
-	spin_lock_irqsave(&zone->freelock, flags);
-	list_for_each_safe(lh, n, &zone->freequeue) {
-		struct sk_buff *skb = (struct sk_buff *)((char *)lh -
-				offsetof(struct sk_buff, cb));
-		if (!skb_shared(skb)) {
-			list_del(skb_to_lh(skb));
-			mempool_free(skb, zone->pool);
-			atomic_dec(&zone->allocated);
-		}
-	}
-	spin_unlock_irqrestore(&zone->freelock, flags);
-}
-
-static struct sk_buff*
-mempool_zone_get_skb(struct mempool_zone *zone)
-{
-	struct sk_buff *skb;
-
-	skb = mempool_alloc(zone->pool, GFP_ATOMIC);
-	if (skb)
-		atomic_inc(&zone->allocated);
-	return skb;
-}
-
 static int
-iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb, gfp_t gfp)
+iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp)
 {
-	unsigned long flags;
 	int rc;
 
-	skb_get(skb);
 	rc = netlink_broadcast(nls, skb, 0, 1, gfp);
 	if (rc < 0) {
-		mempool_free(skb, zone->pool);
 		printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc);
 		return rc;
 	}
 
-	spin_lock_irqsave(&zone->freelock, flags);
-	INIT_LIST_HEAD(skb_to_lh(skb));
-	list_add(skb_to_lh(skb), &zone->freequeue);
-	spin_unlock_irqrestore(&zone->freelock, flags);
 	return 0;
 }
 
 static int
-iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid)
+iscsi_unicast_skb(struct sk_buff *skb, int pid)
 {
-	unsigned long flags;
 	int rc;
 
-	skb_get(skb);
 	rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
 	if (rc < 0) {
-		mempool_free(skb, zone->pool);
 		printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
 		return rc;
 	}
 
-	spin_lock_irqsave(&zone->freelock, flags);
-	INIT_LIST_HEAD(skb_to_lh(skb));
-	list_add(skb_to_lh(skb), &zone->freequeue);
-	spin_unlock_irqrestore(&zone->freelock, flags);
-
 	return 0;
 }
 
@@ -692,9 +539,7 @@
 	if (!priv)
 		return -EINVAL;
 
-	mempool_zone_complete(conn->z_pdu);
-
-	skb = mempool_zone_get_skb(conn->z_pdu);
+	skb = alloc_skb(len, GFP_ATOMIC);
 	if (!skb) {
 		iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED);
 		dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver "
@@ -707,15 +552,13 @@
 	memset(ev, 0, sizeof(*ev));
 	ev->transport_handle = iscsi_handle(conn->transport);
 	ev->type = ISCSI_KEVENT_RECV_PDU;
-	if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
-		ev->iferror = -ENOMEM;
 	ev->r.recv_req.cid = conn->cid;
 	ev->r.recv_req.sid = iscsi_conn_get_sid(conn);
 	pdu = (char*)ev + sizeof(*ev);
 	memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
 	memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
 
-	return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid);
+	return iscsi_unicast_skb(skb, priv->daemon_pid);
 }
 EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
 
@@ -731,9 +574,7 @@
 	if (!priv)
 		return;
 
-	mempool_zone_complete(conn->z_error);
-
-	skb = mempool_zone_get_skb(conn->z_error);
+	skb = alloc_skb(len, GFP_ATOMIC);
 	if (!skb) {
 		dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored "
 			  "conn error (%d)\n", error);
@@ -744,13 +585,11 @@
 	ev = NLMSG_DATA(nlh);
 	ev->transport_handle = iscsi_handle(conn->transport);
 	ev->type = ISCSI_KEVENT_CONN_ERROR;
-	if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat)
-		ev->iferror = -ENOMEM;
 	ev->r.connerror.error = error;
 	ev->r.connerror.cid = conn->cid;
 	ev->r.connerror.sid = iscsi_conn_get_sid(conn);
 
-	iscsi_broadcast_skb(conn->z_error, skb, GFP_ATOMIC);
+	iscsi_broadcast_skb(skb, GFP_ATOMIC);
 
 	dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
 		   error);
@@ -767,9 +606,7 @@
 	int flags = multi ? NLM_F_MULTI : 0;
 	int t = done ? NLMSG_DONE : type;
 
-	mempool_zone_complete(z_reply);
-
-	skb = mempool_zone_get_skb(z_reply);
+	skb = alloc_skb(len, GFP_ATOMIC);
 	/*
 	 * FIXME:
 	 * user is supposed to react on iferror == -ENOMEM;
@@ -780,7 +617,7 @@
 	nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
 	nlh->nlmsg_flags = flags;
 	memcpy(NLMSG_DATA(nlh), payload, size);
-	return iscsi_unicast_skb(z_reply, skb, pid);
+	return iscsi_unicast_skb(skb, pid);
 }
 
 static int
@@ -810,9 +647,7 @@
 	do {
 		int actual_size;
 
-		mempool_zone_complete(conn->z_pdu);
-
-		skbstat = mempool_zone_get_skb(conn->z_pdu);
+		skbstat = alloc_skb(len, GFP_ATOMIC);
 		if (!skbstat) {
 			dev_printk(KERN_ERR, &conn->dev, "iscsi: can not "
 				   "deliver stats: OOM\n");
@@ -825,8 +660,6 @@
 		memset(evstat, 0, sizeof(*evstat));
 		evstat->transport_handle = iscsi_handle(conn->transport);
 		evstat->type = nlh->nlmsg_type;
-		if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
-			evstat->iferror = -ENOMEM;
 		evstat->u.get_stats.cid =
 			ev->u.get_stats.cid;
 		evstat->u.get_stats.sid =
@@ -845,7 +678,7 @@
 		skb_trim(skbstat, NLMSG_ALIGN(actual_size));
 		nlhstat->nlmsg_len = actual_size;
 
-		err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid);
+		err = iscsi_unicast_skb(skbstat, priv->daemon_pid);
 	} while (err < 0 && err != -ECONNREFUSED);
 
 	return err;
@@ -876,9 +709,7 @@
 	session = iscsi_dev_to_session(conn->dev.parent);
 	shost = iscsi_session_to_shost(session);
 
-	mempool_zone_complete(conn->z_pdu);
-
-	skb = mempool_zone_get_skb(conn->z_pdu);
+	skb = alloc_skb(len, GFP_KERNEL);
 	if (!skb) {
 		dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
 			  "session creation event\n");
@@ -896,7 +727,7 @@
 	 * this will occur if the daemon is not up, so we just warn
 	 * the user and when the daemon is restarted it will handle it
 	 */
-	rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL);
+	rc = iscsi_broadcast_skb(skb, GFP_KERNEL);
 	if (rc < 0)
 		dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
 			  "session destruction event. Check iscsi daemon\n");
@@ -939,9 +770,7 @@
 	session = iscsi_dev_to_session(conn->dev.parent);
 	shost = iscsi_session_to_shost(session);
 
-	mempool_zone_complete(conn->z_pdu);
-
-	skb = mempool_zone_get_skb(conn->z_pdu);
+	skb = alloc_skb(len, GFP_KERNEL);
 	if (!skb) {
 		dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
 			  "session creation event\n");
@@ -959,7 +788,7 @@
 	 * this will occur if the daemon is not up, so we just warn
 	 * the user and when the daemon is restarted it will handle it
 	 */
-	rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL);
+	rc = iscsi_broadcast_skb(skb, GFP_KERNEL);
 	if (rc < 0)
 		dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
 			  "session creation event. Check iscsi daemon\n");
@@ -1278,9 +1107,6 @@
 				err = iscsi_if_send_reply(
 					NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
 					nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
-				if (atomic_read(&z_reply->allocated) >=
-						z_reply->hiwat)
-					ev->iferror = -ENOMEM;
 			} while (err < 0 && err != -ECONNREFUSED);
 			skb_pull(skb, rlen);
 		}
@@ -1584,32 +1410,6 @@
 }
 EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
 
-static int
-iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-	struct netlink_notify *n = ptr;
-
-	if (event == NETLINK_URELEASE &&
-	    n->protocol == NETLINK_ISCSI && n->pid) {
-		struct iscsi_cls_conn *conn;
-		unsigned long flags;
-
-		mempool_zone_complete(z_reply);
-		spin_lock_irqsave(&connlock, flags);
-		list_for_each_entry(conn, &connlist, conn_list) {
-			mempool_zone_complete(conn->z_error);
-			mempool_zone_complete(conn->z_pdu);
-		}
-		spin_unlock_irqrestore(&connlock, flags);
-	}
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block iscsi_nl_notifier = {
-	.notifier_call	= iscsi_rcv_nl_event,
-};
-
 static __init int iscsi_transport_init(void)
 {
 	int err;
@@ -1633,25 +1433,15 @@
 	if (err)
 		goto unregister_conn_class;
 
-	err = netlink_register_notifier(&iscsi_nl_notifier);
-	if (err)
-		goto unregister_session_class;
-
 	nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx,
 			THIS_MODULE);
 	if (!nls) {
 		err = -ENOBUFS;
-		goto unregister_notifier;
+		goto unregister_session_class;
 	}
 
-	z_reply = mempool_zone_init(Z_MAX_REPLY,
-		NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY);
-	if (z_reply)
-		return 0;
+	return 0;
 
-	sock_release(nls->sk_socket);
-unregister_notifier:
-	netlink_unregister_notifier(&iscsi_nl_notifier);
 unregister_session_class:
 	transport_class_unregister(&iscsi_session_class);
 unregister_conn_class:
@@ -1665,9 +1455,7 @@
 
 static void __exit iscsi_transport_exit(void)
 {
-	mempool_zone_destroy(z_reply);
 	sock_release(nls->sk_socket);
-	netlink_unregister_notifier(&iscsi_nl_notifier);
 	transport_class_unregister(&iscsi_connection_class);
 	transport_class_unregister(&iscsi_session_class);
 	transport_class_unregister(&iscsi_host_class);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 3f8b931..81e3bc7 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -60,7 +60,7 @@
 
 #ifdef CONFIG_SCSI_PROC_FS
 #include <linux/proc_fs.h>
-static char *sg_version_date = "20060920";
+static char *sg_version_date = "20061027";
 
 static int sg_proc_init(void);
 static void sg_proc_cleanup(void);
@@ -710,12 +710,12 @@
 			  (int) cmnd[0], (int) hp->cmd_len));
 
 	if ((k = sg_start_req(srp))) {
-		SCSI_LOG_TIMEOUT(1, printk("sg_write: start_req err=%d\n", k));
+		SCSI_LOG_TIMEOUT(1, printk("sg_common_write: start_req err=%d\n", k));
 		sg_finish_rem_req(srp);
 		return k;	/* probably out of space --> ENOMEM */
 	}
 	if ((k = sg_write_xfer(srp))) {
-		SCSI_LOG_TIMEOUT(1, printk("sg_write: write_xfer, bad address\n"));
+		SCSI_LOG_TIMEOUT(1, printk("sg_common_write: write_xfer, bad address\n"));
 		sg_finish_rem_req(srp);
 		return k;
 	}
@@ -746,7 +746,7 @@
 				hp->dxfer_len, srp->data.k_use_sg, timeout,
 				SG_DEFAULT_RETRIES, srp, sg_cmd_done,
 				GFP_ATOMIC)) {
-		SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n"));
+		SCSI_LOG_TIMEOUT(1, printk("sg_common_write: scsi_execute_async failed\n"));
 		/*
 		 * most likely out of mem, but could also be a bad map
 		 */
@@ -1283,7 +1283,7 @@
 		sg_finish_rem_req(srp);
 		srp = NULL;
 		if (NULL == sfp->headrp) {
-			SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n"));
+			SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n"));
 			if (0 == sg_remove_sfp(sdp, sfp)) {	/* device still present */
 				scsi_device_put(sdp->device);
 			}
@@ -1512,12 +1512,12 @@
 						    POLL_HUP);
 				}
 			}
-			SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k));
+			SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k));
 			if (NULL == sdp->headfp) {
 				sg_dev_arr[k] = NULL;
 			}
 		} else {	/* nothing active, simple case */
-			SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k));
+			SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k));
 			sg_dev_arr[k] = NULL;
 		}
 		sg_nr_dev--;
@@ -1876,14 +1876,15 @@
 			}
 		}
 		sg->page = p;
-		sg->length = ret_sz;
+		sg->length = (ret_sz > num) ? num : ret_sz;
 
-		SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
-				  k, p, ret_sz));
+		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
+				 "ret_sz=%d\n", k, num, ret_sz));
 	}		/* end of for loop */
 
 	schp->k_use_sg = k;
-	SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz));
+	SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, "
+			 "rem_sz=%d\n", k, rem_sz));
 
 	schp->bufflen = blk_size;
 	if (rem_sz > 0)	/* must have failed */
@@ -2014,7 +2015,7 @@
 			for (k = 0; (k < schp->k_use_sg) && sg->page;
 			     ++k, ++sg) {
 				SCSI_LOG_TIMEOUT(5, printk(
-				    "sg_remove_scat: k=%d, a=0x%p, len=%d\n",
+				    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
 				    k, sg->page, sg->length));
 				sg_page_free(sg->page, sg->length);
 			}
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 3babdc7..e1a52c5 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -1177,7 +1177,10 @@
 		goto err_out;
 	if ((filp->f_flags & O_NONBLOCK) == 0 &&
 	    retval != CHKRES_READY) {
-		retval = (-EIO);
+		if (STp->ready == NO_TAPE)
+			retval = (-ENOMEDIUM);
+		else
+			retval = (-EIO);
 		goto err_out;
 	}
 	return 0;
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 5ec5af8..3b3f305 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -266,8 +266,8 @@
 	(struct NCR5380_hostdata *)(in)->hostdata
 #define	HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
 
-#define	NEXT(cmd)	((Scsi_Cmnd *)((cmd)->host_scribble))
-#define	NEXTADDR(cmd)	((Scsi_Cmnd **)&((cmd)->host_scribble))
+#define	NEXT(cmd)	((struct scsi_cmnd *)((cmd)->host_scribble))
+#define	NEXTADDR(cmd)	((struct scsi_cmnd **)&((cmd)->host_scribble))
 
 #define	HOSTNO		instance->host_no
 #define	H_NO(cmd)	(cmd)->device->host->host_no
@@ -360,7 +360,7 @@
  * conditions.
  */ 
 
-static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged )
+static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
 {
     SETUP_HOSTDATA(cmd->device->host);
 
@@ -384,7 +384,7 @@
  * untagged.
  */
 
-static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged )
+static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
 {
     SETUP_HOSTDATA(cmd->device->host);
 
@@ -416,7 +416,7 @@
  * unlock the LUN.
  */
 
-static void cmd_free_tag( Scsi_Cmnd *cmd )
+static void cmd_free_tag(struct scsi_cmnd *cmd)
 {
     SETUP_HOSTDATA(cmd->device->host);
 
@@ -460,18 +460,18 @@
 
 
 /*
- * Function: void merge_contiguous_buffers( Scsi_Cmnd *cmd )
+ * Function: void merge_contiguous_buffers(struct scsi_cmnd *cmd)
  *
  * Purpose: Try to merge several scatter-gather requests into one DMA
  *    transfer. This is possible if the scatter buffers lie on
  *    physical contiguous addresses.
  *
- * Parameters: Scsi_Cmnd *cmd
+ * Parameters: struct scsi_cmnd *cmd
  *    The command to work on. The first scatter buffer's data are
  *    assumed to be already transfered into ptr/this_residual.
  */
 
-static void merge_contiguous_buffers( Scsi_Cmnd *cmd )
+static void merge_contiguous_buffers(struct scsi_cmnd *cmd)
 {
     unsigned long endaddr;
 #if (NDEBUG & NDEBUG_MERGING)
@@ -501,15 +501,15 @@
 }
 
 /*
- * Function : void initialize_SCp(Scsi_Cmnd *cmd)
+ * Function : void initialize_SCp(struct scsi_cmnd *cmd)
  *
  * Purpose : initialize the saved data pointers for cmd to point to the 
  *	start of the buffer.
  *
- * Inputs : cmd - Scsi_Cmnd structure to have pointers reset.
+ * Inputs : cmd - struct scsi_cmnd structure to have pointers reset.
  */
 
-static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
+static __inline__ void initialize_SCp(struct scsi_cmnd *cmd)
 {
     /* 
      * Initialize the Scsi Pointer field so that all of the commands in the 
@@ -753,14 +753,15 @@
   do { if (pos + strlen(fmt) + 20 /* slop */ < buffer + length) \
 	 pos += sprintf(pos, fmt , ## args); } while(0)
 static
-char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length);
+char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer,
+		       int length);
 
-static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **start,
-		       off_t offset, int length, int inout)
+static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer,
+			     char **start, off_t offset, int length, int inout)
 {
     char *pos = buffer;
     struct NCR5380_hostdata *hostdata;
-    Scsi_Cmnd *ptr;
+    struct scsi_cmnd *ptr;
     unsigned long flags;
     off_t begin = 0;
 #define check_offset()				\
@@ -784,18 +785,19 @@
     if (!hostdata->connected)
 	SPRINTF("scsi%d: no currently connected command\n", HOSTNO);
     else
-	pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected,
+	pos = lprint_Scsi_Cmnd ((struct scsi_cmnd *) hostdata->connected,
 				pos, buffer, length);
     SPRINTF("scsi%d: issue_queue\n", HOSTNO);
     check_offset();
-    for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) {
+    for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr))
+    {
 	pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length);
 	check_offset();
     }
 
     SPRINTF("scsi%d: disconnected_queue\n", HOSTNO);
     check_offset();
-    for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
+    for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
 	 ptr = NEXT(ptr)) {
 	pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length);
 	check_offset();
@@ -810,8 +812,8 @@
     return length;
 }
 
-static char *
-lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length)
+static char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer,
+			      int length)
 {
     int i, s;
     unsigned char *command;
@@ -888,8 +890,8 @@
 }
 
 /* 
- * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, 
- *	void (*done)(Scsi_Cmnd *)) 
+ * Function : int NCR5380_queue_command (struct scsi_cmnd *cmd,
+ *	void (*done)(struct scsi_cmnd *))
  *
  * Purpose :  enqueues a SCSI command
  *
@@ -906,10 +908,11 @@
  */
 
 /* Only make static if a wrapper function is used */
-static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int NCR5380_queue_command(struct scsi_cmnd *cmd,
+				 void (*done)(struct scsi_cmnd *))
 {
     SETUP_HOSTDATA(cmd->device->host);
-    Scsi_Cmnd *tmp;
+    struct scsi_cmnd *tmp;
     unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
@@ -990,7 +993,7 @@
 	NEXT(cmd) = hostdata->issue_queue;
 	hostdata->issue_queue = cmd;
     } else {
-	for (tmp = (Scsi_Cmnd *)hostdata->issue_queue;
+	for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
 	     NEXT(tmp); tmp = NEXT(tmp))
 	    ;
 	LIST(cmd, tmp);
@@ -1030,7 +1033,7 @@
     
 static void NCR5380_main (void *bl)
 {
-    Scsi_Cmnd *tmp, *prev;
+    struct scsi_cmnd *tmp, *prev;
     struct Scsi_Host *instance = first_instance;
     struct NCR5380_hostdata *hostdata = HOSTDATA(instance);
     int done;
@@ -1073,12 +1076,12 @@
 	     * for a target that's not busy.
 	     */
 #if (NDEBUG & NDEBUG_LISTS)
-	    for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL;
+	    for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL;
 		 tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp))
 		;
 	    if ((tmp == prev) && tmp) printk(" LOOP\n");/* else printk("\n");*/
 #endif
-	    for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, 
+	    for (tmp = (struct scsi_cmnd *) hostdata->issue_queue,
 		 prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) {
 
 #if (NDEBUG & NDEBUG_LISTS)
@@ -1339,7 +1342,8 @@
 }
 
 #ifdef NCR5380_STATS
-static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd)
+static void collect_stats(struct NCR5380_hostdata *hostdata,
+			  struct scsi_cmnd *cmd)
 {
 # ifdef NCR5380_STAT_LIMIT
     if (cmd->request_bufflen > NCR5380_STAT_LIMIT)
@@ -1365,8 +1369,8 @@
 #endif
 
 /* 
- * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, 
- *	int tag);
+ * Function : int NCR5380_select(struct Scsi_Host *instance,
+ * 				 struct scsi_cmnd *cmd,	int tag);
  *
  * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command,
  *	including ARBITRATION, SELECTION, and initial message out for 
@@ -1395,7 +1399,8 @@
  *		cmd->result host byte set to DID_BAD_TARGET.
  */
 
-static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
+static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd,
+			  int tag)
 {
     SETUP_HOSTDATA(instance);
     unsigned char tmp[3], phase;
@@ -1985,7 +1990,7 @@
 #endif
     unsigned char *data;
     unsigned char phase, tmp, extended_msg[10], old_phase=0xff;
-    Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
+    struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
 
 #ifdef SUN3_SCSI_VME
     dregs->csr |= CSR_INTR;
@@ -2272,7 +2277,7 @@
 			local_irq_save(flags);
 			LIST(cmd,hostdata->issue_queue);
 			NEXT(cmd) = hostdata->issue_queue;
-		        hostdata->issue_queue = (Scsi_Cmnd *) cmd;
+		        hostdata->issue_queue = (struct scsi_cmnd *) cmd;
 		        local_irq_restore(flags);
 			QU_PRINTK("scsi%d: REQUEST SENSE added to head of "
 				  "issue queue\n", H_NO(cmd));
@@ -2502,7 +2507,7 @@
  * Function : void NCR5380_reselect (struct Scsi_Host *instance)
  *
  * Purpose : does reselection, initializing the instance->connected 
- *	field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q 
+ *	field to point to the struct scsi_cmnd for which the I_T_L or I_T_L_Q
  *	nexus has been reestablished,
  *	
  * Inputs : instance - this instance of the NCR5380.
@@ -2521,7 +2526,7 @@
     unsigned char tag;
 #endif
     unsigned char msg[3];
-    Scsi_Cmnd *tmp = NULL, *prev;
+    struct scsi_cmnd *tmp = NULL, *prev;
 /*    unsigned long flags; */
 
     /*
@@ -2577,7 +2582,7 @@
      * just reestablished, and remove it from the disconnected queue.
      */
 
-    for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; 
+    for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
 	 tmp; prev = tmp, tmp = NEXT(tmp) ) {
 	if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
 #ifdef SUPPORT_TAGS
@@ -2668,11 +2673,11 @@
 
 
 /*
- * Function : int NCR5380_abort (Scsi_Cmnd *cmd)
+ * Function : int NCR5380_abort(struct scsi_cmnd *cmd)
  *
  * Purpose : abort a command
  *
- * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the 
+ * Inputs : cmd - the struct scsi_cmnd to abort, code - code to set the
  * 	host byte of the result field to, if zero DID_ABORTED is 
  *	used.
  *
@@ -2684,11 +2689,11 @@
  * 	 called where the loop started in NCR5380_main().
  */
 
-static int NCR5380_abort (Scsi_Cmnd *cmd)
+static int NCR5380_abort(struct scsi_cmnd *cmd)
 {
     struct Scsi_Host *instance = cmd->device->host;
     SETUP_HOSTDATA(instance);
-    Scsi_Cmnd *tmp, **prev;
+    struct scsi_cmnd *tmp, **prev;
     unsigned long flags;
 
     printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO);
@@ -2753,9 +2758,9 @@
  * Case 2 : If the command hasn't been issued yet, we simply remove it 
  * 	    from the issue queue.
  */
-    for (prev = (Scsi_Cmnd **) &(hostdata->issue_queue), 
-	tmp = (Scsi_Cmnd *) hostdata->issue_queue;
-	tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) )
+    for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue),
+	tmp = (struct scsi_cmnd *) hostdata->issue_queue;
+	tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp))
 	if (cmd == tmp) {
 	    REMOVE(5, *prev, tmp, NEXT(tmp));
 	    (*prev) = NEXT(tmp);
@@ -2812,7 +2817,7 @@
  * it from the disconnected queue.
  */
 
-    for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp;
+    for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
 	 tmp = NEXT(tmp)) 
         if (cmd == tmp) {
             local_irq_restore(flags);
@@ -2826,8 +2831,8 @@
 	    do_abort (instance);
 
 	    local_irq_save(flags);
-	    for (prev = (Scsi_Cmnd **) &(hostdata->disconnected_queue), 
-		tmp = (Scsi_Cmnd *) hostdata->disconnected_queue;
+	    for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue),
+		tmp = (struct scsi_cmnd *) hostdata->disconnected_queue;
 		tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) )
 		    if (cmd == tmp) {
 		    REMOVE(5, *prev, tmp, NEXT(tmp));
@@ -2868,7 +2873,7 @@
 
 
 /* 
- * Function : int NCR5380_bus_reset (Scsi_Cmnd *cmd)
+ * Function : int NCR5380_bus_reset(struct scsi_cmnd *cmd)
  * 
  * Purpose : reset the SCSI bus.
  *
@@ -2876,13 +2881,13 @@
  *
  */ 
 
-static int NCR5380_bus_reset( Scsi_Cmnd *cmd)
+static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
 {
     SETUP_HOSTDATA(cmd->device->host);
     int           i;
     unsigned long flags;
 #if 1
-    Scsi_Cmnd *connected, *disconnected_queue;
+    struct scsi_cmnd *connected, *disconnected_queue;
 #endif
 
 
@@ -2914,9 +2919,9 @@
      * remembered in local variables first.
      */
     local_irq_save(flags);
-    connected = (Scsi_Cmnd *)hostdata->connected;
+    connected = (struct scsi_cmnd *)hostdata->connected;
     hostdata->connected = NULL;
-    disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue;
+    disconnected_queue = (struct scsi_cmnd *)hostdata->disconnected_queue;
     hostdata->disconnected_queue = NULL;
 #ifdef SUPPORT_TAGS
     free_all_tags();
diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
index e625b4c..d56d85d 100644
--- a/drivers/scsi/sun3_scsi.c
+++ b/drivers/scsi/sun3_scsi.c
@@ -119,7 +119,7 @@
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 
-static Scsi_Cmnd *sun3_dma_setup_done = NULL;
+static struct scsi_cmnd *sun3_dma_setup_done = NULL;
 
 #define	AFTER_RESET_DELAY	(HZ/2)
 
@@ -521,8 +521,9 @@
 	return last_residual;
 }
 
-static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd,
-				    int write_flag)
+static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted,
+						  struct scsi_cmnd *cmd,
+						  int write_flag)
 {
 	if(blk_fs_request(cmd->request))
  		return wanted;
diff --git a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h
index 834dab4..a1103b3 100644
--- a/drivers/scsi/sun3_scsi.h
+++ b/drivers/scsi/sun3_scsi.h
@@ -47,11 +47,12 @@
 
 #define IOBASE_SUN3_VMESCSI 0xff200000
 
-static int sun3scsi_abort (Scsi_Cmnd *);
+static int sun3scsi_abort(struct scsi_cmnd *);
 static int sun3scsi_detect (struct scsi_host_template *);
 static const char *sun3scsi_info (struct Scsi_Host *);
-static int sun3scsi_bus_reset(Scsi_Cmnd *);
-static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int sun3scsi_bus_reset(struct scsi_cmnd *);
+static int sun3scsi_queue_command(struct scsi_cmnd *,
+				  void (*done)(struct scsi_cmnd *));
 static int sun3scsi_release (struct Scsi_Host *);
 
 #ifndef CMD_PER_LUN
diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c
index e8faab1..92def31 100644
--- a/drivers/scsi/sun3_scsi_vme.c
+++ b/drivers/scsi/sun3_scsi_vme.c
@@ -84,7 +84,7 @@
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 
-static Scsi_Cmnd *sun3_dma_setup_done = NULL;
+static struct scsi_cmnd *sun3_dma_setup_done = NULL;
 
 #define	AFTER_RESET_DELAY	(HZ/2)
 
@@ -455,8 +455,9 @@
 	return last_residual;
 }
 
-static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd,
-				    int write_flag)
+static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted,
+						  struct scsi_cmnd *cmd,
+						  int write_flag)
 {
 	if(blk_fs_request(cmd->request))
  		return wanted;
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index d03aa6c..fa5382e 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -2304,6 +2304,7 @@
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 1,
 	.use_clustering		= ENABLE_CLUSTERING,
+	.max_sectors		= 0x4000, /* 8MiB = 16 * 1024 * 512 */
 };
 
 /***********************************************************************
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index a8f894c..69715e5 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -88,7 +88,7 @@
 
 /* these are located in their respective files */
 void cpm_line_cr_cmd(int line, int cmd);
-int cpm_uart_init_portdesc(void);
+int __init cpm_uart_init_portdesc(void);
 int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con);
 void cpm_uart_freebuf(struct uart_cpm_port *pinfo);
 
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 0abb544..7a3b97f 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -195,10 +195,8 @@
 	if (cpm_uart_tx_pump(port) != 0) {
 		if (IS_SMC(pinfo)) {
 			smcp->smc_smcm |= SMCM_TX;
-			smcp->smc_smcmr |= SMCMR_TEN;
 		} else {
 			sccp->scc_sccm |= UART_SCCM_TX;
-			pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT;
 		}
 	}
 }
@@ -421,9 +419,10 @@
 	/* Startup rx-int */
 	if (IS_SMC(pinfo)) {
 		pinfo->smcp->smc_smcm |= SMCM_RX;
-		pinfo->smcp->smc_smcmr |= SMCMR_REN;
+		pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
 	} else {
 		pinfo->sccp->scc_sccm |= UART_SCCM_RX;
+		pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
 	}
 
 	if (!(pinfo->flags & FLAG_CONSOLE))
@@ -1350,11 +1349,10 @@
 		pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n");
 		pr_info(
 		"cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n");
-#ifndef CONFIG_SERIAL_CPM_CONSOLE
-		ret = cpm_uart_init_portdesc();
-		if (ret)
-			return ret;
-#endif
+
+		/* Don't run this again, if the console driver did it already */
+		if (cpm_uart_nr == 0)
+			cpm_uart_init_portdesc();
 
 		cpm_reg.nr = cpm_uart_nr;
 		ret = uart_register_driver(&cpm_reg);
@@ -1366,6 +1364,8 @@
 			int con = cpm_uart_port_map[i];
 			cpm_uart_ports[con].port.line = i;
 			cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
+			if (cpm_uart_ports[con].set_lineif)
+				cpm_uart_ports[con].set_lineif(&cpm_uart_ports[con]);
 			uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
 		}
 
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 95afc37..08e55fd 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -184,7 +184,7 @@
 }
 
 /* Setup any dynamic params in the uart desc */
-int cpm_uart_init_portdesc(void)
+int __init cpm_uart_init_portdesc(void)
 {
 	pr_debug("CPM uart[-]:init portdesc\n");
 
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index ff4fa25..711bd15 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -921,7 +921,7 @@
 {
 	struct ioc4_port *port = (struct ioc4_port *)arg;
 	struct hooks *hooks = port->ip_hooks;
-	unsigned int flags;
+	unsigned long flags;
 
 	spin_lock_irqsave(&port->ip_lock, flags);
 
@@ -1834,7 +1834,7 @@
 	struct ioc4_port *port = (struct ioc4_port *)arg;
 	struct hooks *hooks = port->ip_hooks;
 	unsigned int rx_high_rd_aborted = 0;
-	unsigned int flags;
+	unsigned long flags;
 	struct uart_port *the_port;
 	int loop_counter;
 
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 146298a..c3c0626 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -281,7 +281,6 @@
 	up(&board_lock);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(spi_register_board_info);
 
 /* FIXME someone should add support for a __setup("spi", ...) that
  * creates board info from kernel command lines
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index fbea454..8d69bcd 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -1295,7 +1295,7 @@
 	Proc_Info_Type Info_write;
 	unsigned short frame_count;
 	unsigned int filter_hist[4];
-	unsigned char filter_en[4];
+	unsigned char filter_en[6];
 	unsigned short proc_load;
 	unsigned long framesread;
 	unsigned long frameswritten;
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 809d465..6303970 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -722,6 +722,7 @@
 		usblp->wcomplete = 0;
 		err = usb_submit_urb(usblp->writeurb, GFP_KERNEL);
 		if (err) {
+			usblp->wcomplete = 1;
 			if (err != -ENOMEM)
 				count = -EIO;
 			else
@@ -1202,8 +1203,6 @@
 	down (&usblp->sem);
 	/* we take no more IO */
 	usblp->sleeping = 1;
-	/* we wait for anything printing */
-	wait_event (usblp->wait, usblp->wcomplete || !usblp->present);
 	usblp_unlink_urbs(usblp);
 	up (&usblp->sem);
 	mutex_unlock (&usblp_mutex);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 66bff18..ba165af 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1188,6 +1188,7 @@
 
 #ifdef	CONFIG_USB_OTG
 #include "otg_whitelist.h"
+static int __usb_port_suspend(struct usb_device *, int port1);
 #endif
 
 /**
@@ -1289,8 +1290,6 @@
 		 * (Includes HNP test device.)
 		 */
 		if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
-			static int __usb_port_suspend(struct usb_device *,
-						int port1);
 			err = __usb_port_suspend(udev, udev->bus->otg_port);
 			if (err < 0)
 				dev_dbg(&udev->dev, "HNP fail, %d\n", err);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index fccd195..7729c07 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -828,10 +828,7 @@
  * Context: !in_interrupt ()
  *
  * Updates the copy of the device descriptor stored in the device structure,
- * which dedicates space for this purpose.  Note that several fields are
- * converted to the host CPU's byte order:  the USB version (bcdUSB), and
- * vendors product and version fields (idVendor, idProduct, and bcdDevice).
- * That lets device drivers compare against non-byteswapped constants.
+ * which dedicates space for this purpose.
  *
  * Not exported, only for use by the core.  If drivers really want to read
  * the device descriptor directly, they can call usb_get_descriptor() with
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 9be6b30..ea4714e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -715,13 +715,6 @@
 		return IRQ_NOTMINE;
 	}
 
-	if (ints & OHCI_INTR_RHSC) {
-		ohci_vdbg (ohci, "rhsc\n");
-		ohci->next_statechange = jiffies + STATECHANGE_DELAY;
-		ohci_writel (ohci, OHCI_INTR_RHSC, &regs->intrstatus);
-		usb_hcd_poll_rh_status(hcd);
-	}
-
 	if (ints & OHCI_INTR_UE) {
 		disable (ohci);
 		ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
@@ -731,9 +724,21 @@
 		ohci_usb_reset (ohci);
 	}
 
-	if (ints & OHCI_INTR_RD) {
-		ohci_vdbg (ohci, "resume detect\n");
-		ohci_writel (ohci, OHCI_INTR_RD, &regs->intrstatus);
+	if (ints & OHCI_INTR_RHSC) {
+		ohci_vdbg(ohci, "rhsc\n");
+		ohci->next_statechange = jiffies + STATECHANGE_DELAY;
+		ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC,
+				&regs->intrstatus);
+		usb_hcd_poll_rh_status(hcd);
+	}
+
+	/* For connect and disconnect events, we expect the controller
+	 * to turn on RHSC along with RD.  But for remote wakeup events
+	 * this might not happen.
+	 */
+	else if (ints & OHCI_INTR_RD) {
+		ohci_vdbg(ohci, "resume detect\n");
+		ohci_writel(ohci, OHCI_INTR_RD, &regs->intrstatus);
 		hcd->poll_rh = 1;
 		if (ohci->autostop) {
 			spin_lock (&ohci->lock);
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 6f11359..6995ea3 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -169,7 +169,8 @@
 		break;
 	case OHCI_USB_RESUME:
 		/* HCFS changes sometime after INTR_RD */
-		ohci_info (ohci, "wakeup\n");
+		ohci_info(ohci, "%swakeup\n",
+				autostopped ? "auto-" : "");
 		break;
 	case OHCI_USB_OPER:
 		/* this can happen after resuming a swsusp snapshot */
@@ -422,7 +423,8 @@
 				ohci->autostop = 0;
 				ohci->next_statechange = jiffies +
 						STATECHANGE_DELAY;
-			} else if (time_after_eq (jiffies,
+			} else if (device_may_wakeup(&hcd->self.root_hub->dev)
+					&& time_after_eq(jiffies,
 						ohci->next_statechange)
 					&& !ohci->ed_rm_list
 					&& !(ohci->hc_control &
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index f659f30..787b847 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -636,13 +636,11 @@
 	if (ati_remote->out_urb)
 		usb_free_urb(ati_remote->out_urb);
 
-	if (ati_remote->inbuf)
-		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
-				ati_remote->inbuf, ati_remote->inbuf_dma);
+	usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+		ati_remote->inbuf, ati_remote->inbuf_dma);
 
-	if (ati_remote->outbuf)
-		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
-				ati_remote->inbuf, ati_remote->outbuf_dma);
+	usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+		ati_remote->outbuf, ati_remote->outbuf_dma);
 }
 
 static void ati_remote_input_init(struct ati_remote *ati_remote)
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 45f44fe..6d08a3b 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -270,7 +270,7 @@
  * Read data value from item.
  */
 
-static __inline__ __u32 item_udata(struct hid_item *item)
+static u32 item_udata(struct hid_item *item)
 {
 	switch (item->size) {
 		case 1: return item->data.u8;
@@ -280,7 +280,7 @@
 	return 0;
 }
 
-static __inline__ __s32 item_sdata(struct hid_item *item)
+static s32 item_sdata(struct hid_item *item)
 {
 	switch (item->size) {
 		case 1: return item->data.s8;
@@ -727,7 +727,7 @@
  * done by hand.
  */
 
-static __inline__ __s32 snto32(__u32 value, unsigned n)
+static s32 snto32(__u32 value, unsigned n)
 {
 	switch (n) {
 		case 8:  return ((__s8)value);
@@ -741,9 +741,9 @@
  * Convert a signed 32-bit integer to a signed n-bit integer.
  */
 
-static __inline__ __u32 s32ton(__s32 value, unsigned n)
+static u32 s32ton(__s32 value, unsigned n)
 {
-	__s32 a = value >> (n - 1);
+	s32 a = value >> (n - 1);
 	if (a && a != -1)
 		return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
 	return value & ((1 << n) - 1);
@@ -751,30 +751,55 @@
 
 /*
  * Extract/implement a data field from/to a little endian report (bit array).
+ *
+ * Code sort-of follows HID spec:
+ *     http://www.usb.org/developers/devclass_docs/HID1_11.pdf
+ *
+ * While the USB HID spec allows unlimited length bit fields in "report
+ * descriptors", most devices never use more than 16 bits.
+ * One model of UPS is claimed to report "LINEV" as a 32-bit field.
+ * Search linux-kernel and linux-usb-devel archives for "hid-core extract".
  */
 
 static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
 {
-	u32 x;
+	u64 x;
+
+	WARN_ON(n > 32);
 
 	report += offset >> 3;  /* adjust byte index */
-	offset &= 8 - 1;
-	x = get_unaligned((u32 *) report);
-	x = le32_to_cpu(x);
-	x = (x >> offset) & ((1 << n) - 1);
-	return x;
+	offset &= 7;		/* now only need bit offset into one byte */
+	x = get_unaligned((u64 *) report);
+	x = le64_to_cpu(x);
+	x = (x >> offset) & ((1ULL << n) - 1);	/* extract bit field */
+	return (u32) x;
 }
 
+/*
+ * "implement" : set bits in a little endian bit stream.
+ * Same concepts as "extract" (see comments above).
+ * The data mangled in the bit stream remains in little endian
+ * order the whole time. It make more sense to talk about
+ * endianness of register values by considering a register
+ * a "cached" copy of the little endiad bit stream.
+ */
 static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
 {
-	u32 x;
+	u64 x;
+	u64 m = (1ULL << n) - 1;
+
+	WARN_ON(n > 32);
+
+	WARN_ON(value > m);
+	value &= m;
 
 	report += offset >> 3;
-	offset &= 8 - 1;
-	x = get_unaligned((u32 *)report);
-	x &= cpu_to_le32(~((((__u32) 1 << n) - 1) << offset));
-	x |= cpu_to_le32(value << offset);
-	put_unaligned(x,(u32 *)report);
+	offset &= 7;
+
+	x = get_unaligned((u64 *)report);
+	x &= cpu_to_le64(~(m << offset));
+	x |= cpu_to_le64(((u64) value) << offset);
+	put_unaligned(x, (u64 *) report);
 }
 
 /*
@@ -1615,6 +1640,9 @@
 #define USB_VENDOR_ID_SUN		0x0430
 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE	0xcdab
 
+#define USB_VENDOR_ID_AIRCABLE		0x16CA
+#define USB_DEVICE_ID_AIRCABLE1		0x1502
+
 /*
  * Alphabetically sorted blacklist by quirk type.
  */
@@ -1632,6 +1660,7 @@
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE },
@@ -1768,11 +1797,12 @@
 	{ USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN },
 	{ USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN },
 	{ USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
-	{ USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN },
+	{ USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
 	{ USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
 	{ USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN },
-	{ USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN },
+	{ USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
 	{ USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN },
+	{ USB_VENDOR_ID_APPLE, 0x021B, HID_QUIRK_POWERBOOK_HAS_FN },
 	{ USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
 	{ USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
 
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 9a808a3..68e7ebb 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -121,6 +121,12 @@
 	{ }
 };
 
+static struct hidinput_key_translation powerbook_iso_keyboard[] = {
+	{ KEY_GRAVE,    KEY_102ND },
+	{ KEY_102ND,    KEY_GRAVE },
+	{ }
+};
+
 static int usbhid_pb_fnmode = 1;
 module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
 MODULE_PARM_DESC(pb_fnmode,
@@ -195,6 +201,14 @@
 		}
 	}
 
+	if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) {
+		trans = find_translation(powerbook_iso_keyboard, usage->code);
+		if (trans) {
+			input_event(input, usage->type, trans->to, value);
+			return 1;
+		}
+	}
+
 	return 0;
 }
 
@@ -210,6 +224,9 @@
 
 	for (trans = powerbook_numlock_keys; trans->from; trans++)
 		set_bit(trans->to, input->keybit);
+
+	for (trans = powerbook_iso_keyboard; trans->from; trans++)
+		set_bit(trans->to, input->keybit);
 }
 #else
 static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index 9b50eff..0e76e6d 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -260,6 +260,7 @@
 #define HID_QUIRK_POWERBOOK_HAS_FN		0x00001000
 #define HID_QUIRK_POWERBOOK_FN_ON		0x00002000
 #define HID_QUIRK_INVERT_HWHEEL			0x00004000
+#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD	0x00008000
 
 /*
  * This is the global environment of the parser. This information is
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c
index 2902742..933cedd 100644
--- a/drivers/usb/input/usbtouchscreen.c
+++ b/drivers/usb/input/usbtouchscreen.c
@@ -640,7 +640,7 @@
 		                     type->max_press, 0, 0);
 
 	usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
-			 usb_rcvintpipe(usbtouch->udev, 0x81),
+			 usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress),
 			 usbtouch->data, type->rept_size,
 			 usbtouch_irq, usbtouch, endpoint->bInterval);
 
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index 6a12a94..df97e5c 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -2,6 +2,10 @@
  * X-Box gamepad - v0.0.6
  *
  * Copyright (c) 2002 Marko Friedemann <mfr@bmx-chemnitz.de>
+ *               2004 Oliver Schwartz <Oliver.Schwartz@gmx.de>,
+ *                    Steven Toth <steve@toth.demon.co.uk>,
+ *                    Franz Lehner <franz@caos.at>,
+ *                    Ivan Hawkes <blackhawk@ivanhawkes.com>
  *               2005 Dominic Cerquetti <binary1230@yahoo.com>
  *               2006 Adam Buchbinder <adam.buchbinder@gmail.com>
  *
@@ -29,6 +33,7 @@
  *  - ITO Takayuki for providing essential xpad information on his website
  *  - Vojtech Pavlik     - iforce driver / input subsystem
  *  - Greg Kroah-Hartman - usb-skeleton driver
+ *  - XBOX Linux project - extra USB id's
  *
  * TODO:
  *  - fine tune axes (especially trigger axes)
@@ -54,6 +59,13 @@
  *  - fixed d-pad to axes mapping
  *
  * 2002-07-17 - 0.0.5 : simplified d-pad handling
+ *
+ * 2004-10-02 - 0.0.6 : DDR pad support
+ *  - borrowed from the XBOX linux kernel
+ *  - USB id's for commonly used dance pads are present
+ *  - dance pads will map D-PAD to buttons, not axes
+ *  - pass the module paramater 'dpad_to_buttons' to force
+ *    the D-PAD to map to buttons if your pad is not detected
  */
 
 #include <linux/kernel.h>
@@ -90,8 +102,35 @@
 	{ 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES },
 	{ 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES },
 	{ 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES },
-	{ 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES },
+	{ 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES },
 	{ 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS },
+	{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES },
+	{ 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES },
+	{ 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES },
+	{ 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES },
+	{ 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES },
+	{ 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES },
+	{ 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES },
+	{ 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES },
+	{ 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES },
+	{ 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS },
+	{ 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES },
+	{ 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS },
+	{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES },
+	{ 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES },
+	{ 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES },
+	{ 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES },
+	{ 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES},
+	{ 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES },
+	{ 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES },
+	{ 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES },
+	{ 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES },
+	{ 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES },
+	{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES },
+	{ 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES },
+	{ 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS },
+	{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS },
+	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES },
 	{ 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN }
 };
 
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 0be9d62..e4971d6 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -780,7 +780,7 @@
 
 bl_fail:/* not enough memory. Free allocated elements */
         dbg ("auerbuf_setup: no more memory");
-	kfree(bep);
+	auerbuf_free(bep);
         auerbuf_free_buffers (bcp);
         return -ENOMEM;
 }
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
index 454a186..e081836 100644
--- a/drivers/usb/net/Kconfig
+++ b/drivers/usb/net/Kconfig
@@ -92,8 +92,13 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called rtl8150.
 
+config USB_USBNET_MII
+	tristate
+	default n
+
 config USB_USBNET
 	tristate "Multi-purpose USB Networking Framework"
+	select MII if USBNET_MII != n
 	---help---
 	  This driver supports several kinds of network links over USB,
 	  with "minidrivers" built around a common network driver core
@@ -129,7 +134,7 @@
 	tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
 	depends on USB_USBNET && NET_ETHERNET
 	select CRC32
-	select MII
+	select USB_USBNET_MII
 	default y
 	help
 	  This option adds support for ASIX AX88xxx based USB 2.0
@@ -210,6 +215,7 @@
 config USB_NET_MCS7830
 	tristate "MosChip MCS7830 based Ethernet adapters"
 	depends on USB_USBNET
+	select USB_USBNET_MII
 	help
 	  Choose this option if you're using a 10/100 Ethernet USB2
 	  adapter based on the MosChip 7830 controller. This includes
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index cf3d20e..760b532 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -554,7 +554,7 @@
 {
 	struct usbnet		*dev = netdev_priv(net);
 	int			temp;
-	DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); 
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup);
 	DECLARE_WAITQUEUE (wait, current);
 
 	netif_stop_queue (net);
@@ -669,6 +669,9 @@
  * they'll probably want to use this base set.
  */
 
+#if defined(CONFIG_MII) || defined(CONFIG_MII_MODULE)
+#define HAVE_MII
+
 int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd)
 {
 	struct usbnet *dev = netdev_priv(net);
@@ -699,20 +702,6 @@
 }
 EXPORT_SYMBOL_GPL(usbnet_set_settings);
 
-
-void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
-{
-	struct usbnet *dev = netdev_priv(net);
-
-	/* REVISIT don't always return "usbnet" */
-	strncpy (info->driver, driver_name, sizeof info->driver);
-	strncpy (info->version, DRIVER_VERSION, sizeof info->version);
-	strncpy (info->fw_version, dev->driver_info->description,
-		sizeof info->fw_version);
-	usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
-}
-EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
-
 u32 usbnet_get_link (struct net_device *net)
 {
 	struct usbnet *dev = netdev_priv(net);
@@ -730,6 +719,32 @@
 }
 EXPORT_SYMBOL_GPL(usbnet_get_link);
 
+int usbnet_nway_reset(struct net_device *net)
+{
+	struct usbnet *dev = netdev_priv(net);
+
+	if (!dev->mii.mdio_write)
+		return -EOPNOTSUPP;
+
+	return mii_nway_restart(&dev->mii);
+}
+EXPORT_SYMBOL_GPL(usbnet_nway_reset);
+
+#endif	/* HAVE_MII */
+
+void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
+{
+	struct usbnet *dev = netdev_priv(net);
+
+	/* REVISIT don't always return "usbnet" */
+	strncpy (info->driver, driver_name, sizeof info->driver);
+	strncpy (info->version, DRIVER_VERSION, sizeof info->version);
+	strncpy (info->fw_version, dev->driver_info->description,
+		sizeof info->fw_version);
+	usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
+}
+EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
+
 u32 usbnet_get_msglevel (struct net_device *net)
 {
 	struct usbnet *dev = netdev_priv(net);
@@ -746,24 +761,15 @@
 }
 EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
 
-int usbnet_nway_reset(struct net_device *net)
-{
-	struct usbnet *dev = netdev_priv(net);
-
-	if (!dev->mii.mdio_write)
-		return -EOPNOTSUPP;
-
-	return mii_nway_restart(&dev->mii);
-}
-EXPORT_SYMBOL_GPL(usbnet_nway_reset);
-
 /* drivers may override default ethtool_ops in their bind() routine */
 static struct ethtool_ops usbnet_ethtool_ops = {
+#ifdef	HAVE_MII
 	.get_settings		= usbnet_get_settings,
 	.set_settings		= usbnet_set_settings,
-	.get_drvinfo		= usbnet_get_drvinfo,
 	.get_link		= usbnet_get_link,
 	.nway_reset		= usbnet_nway_reset,
+#endif
+	.get_drvinfo		= usbnet_get_drvinfo,
 	.get_msglevel		= usbnet_get_msglevel,
 	.set_msglevel		= usbnet_set_msglevel,
 };
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 9a6ec1b..2a8dd4c 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -54,10 +54,10 @@
 	  properly.
 
 config USB_SERIAL_AIRCABLE
-	tristate "AIRcable USB Bluetooth Dongle Driver (EXPERIMENTAL)"
+	tristate "USB AIRcable Bluetooth Dongle Driver (EXPERIMENTAL)"
 	depends on USB_SERIAL && EXPERIMENTAL
 	help
-	    Say Y here if you want to use AIRcable USB Bluetoot Dongle.
+	    Say Y here if you want to use USB AIRcable Bluetooth Dongle.
 
 	    To compile this driver as a module, choose M here: the module
 	    will be called aircable.
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index bbf6532..f95d42c 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -64,6 +64,9 @@
 	{ USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
 	{ USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
 	{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
+	{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
+	{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
+	{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
 	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index bd76b4c..c186b4e 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -311,6 +311,7 @@
 	{ USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) },
 	{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
@@ -511,6 +512,7 @@
 	{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
+	{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index f0edb87..bae117d 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -55,6 +55,9 @@
 /* iPlus device */
 #define FTDI_IPLUS_PID 0xD070 /* Product Id */
 
+/* DMX4ALL DMX Interfaces */
+#define FTDI_DMX4ALL 0xC850
+
 /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */
 /* they use the ftdi chipset for the USB interface and the vendor id is the same */
 #define FTDI_XF_632_PID 0xFC08	/* 632: 16x2 Character Display */
@@ -175,9 +178,15 @@
 #define FTDI_ASK_RDR400_PID	0xC991	/* ASK RDR 400 series card reader */
 
 /*
+ * FTDI USB UART chips used in construction projects from the
+ * Elektor Electronics magazine (http://elektor-electronics.co.uk)
+ */
+#define ELEKTOR_VID		0x0C7D
+#define ELEKTOR_FT323R_PID	0x0005	/* RFID-Reader, issue 09-2006 */
+
+/*
  * DSS-20 Sync Station for Sony Ericsson P800
  */
- 
 #define FTDI_DSS20_PID          0xFC82  
 
 /*
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 6238aff..d72cf8b 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -320,6 +320,7 @@
 	{ USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */
 	{ USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */
 	{ USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */
+	{ USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC USB Modem */
 	{ USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */
 	{ USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */
 	{ USB_DEVICE(0x0BB4, 0x0A03) }, /* PocketPC USB Sync */
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index ea16572..4b5097f 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -35,6 +35,7 @@
 	{ USB_DEVICE(0x1199, 0x0020) },	/* Sierra Wireless MC5725 */
 	{ USB_DEVICE(0x1199, 0x0017) },	/* Sierra Wireless EM5625 */
 	{ USB_DEVICE(0x1199, 0x0019) },	/* Sierra Wireless AirCard 595 */
+	{ USB_DEVICE(0x1199, 0x0218) },	/* Sierra Wireless MC5720 */
 	{ USB_DEVICE(0x1199, 0x6802) },	/* Sierra Wireless MC8755 */
 	{ USB_DEVICE(0x1199, 0x6803) },	/* Sierra Wireless MC8765 */
 	{ USB_DEVICE(0x1199, 0x6804) },	/* Sierra Wireless MC8755 for Europe */
@@ -58,8 +59,10 @@
 	{ USB_DEVICE(0x1199, 0x0020) },	/* Sierra Wireless MC5725 */
 	{ USB_DEVICE(0x1199, 0x0017) },	/* Sierra Wireless EM5625 */
 	{ USB_DEVICE(0x1199, 0x0019) },	/* Sierra Wireless AirCard 595 */
+	{ USB_DEVICE(0x1199, 0x0218) },	/* Sierra Wireless MC5720 */
 	{ USB_DEVICE(0x1199, 0x6802) },	/* Sierra Wireless MC8755 */
 	{ USB_DEVICE(0x1199, 0x6803) },	/* Sierra Wireless MC8765 */
+	{ USB_DEVICE(0x1199, 0x6804) },	/* Sierra Wireless MC8755 for Europe */
 	{ USB_DEVICE(0x1199, 0x6812) },	/* Sierra Wireless MC8775 */
 	{ USB_DEVICE(0x1199, 0x6820) },	/* Sierra Wireless AirCard 875 */
 	{ }
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 37ed8e0..efb047f 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1236,7 +1236,7 @@
 		"Cowon Systems",
 		"iAUDIO M5",
 		US_SC_DEVICE, US_PR_BULK, NULL,
-		0 ),
+		US_FL_NEED_OVERRIDE ),
 
 /* Submitted by Antoine Mairesse <antoine.mairesse@free.fr> */
 UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300,
@@ -1306,18 +1306,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
-/* Reported by Jan Mate <mate@fiit.stuba.sk> */
-UNUSUAL_DEV(  0x0fce, 0xe030, 0x0000, 0x0000,
-		"Sony Ericsson",
-		"P990i",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
 /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
  * Tested on hardware version 1.10.
  * Entry is needed only for the initializer function override.
+ * Devices with bcd > 110 seem to not need it while those
+ * with bcd < 110 appear to need it.
  */
-UNUSUAL_DEV(  0x1019, 0x0c55, 0x0110, 0x0110,
+UNUSUAL_DEV(  0x1019, 0x0c55, 0x0000, 0x0110,
 		"Desknote",
 		"UCR-61S2B",
 		US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index b77b309..e815b35 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -406,7 +406,7 @@
 	{ PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO },
 	{ PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
 	{ PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
-	{ PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
+	{ PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 },
 	{ PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
 
 	{ PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 6767545..869725a 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -139,7 +139,13 @@
 int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
 			       u8 **out_edid)
 {
-	u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
+	u32 reg = rinfo->i2c[conn-1].ddc_reg;
+	u8 *edid;
+
+	OUTREG(reg, INREG(reg) &
+			~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
+
+	edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
 
 	if (out_edid)
 		*out_edid = edid;
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index 2ebbfd9..d07ecb5 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -111,7 +111,7 @@
 	.update_status  = corgibl_set_intensity,
 };
 
-static int __init corgibl_probe(struct platform_device *pdev)
+static int corgibl_probe(struct platform_device *pdev)
 {
 	struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
 
@@ -166,4 +166,4 @@
 
 MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
 MODULE_DESCRIPTION("Corgi Backlight Driver");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index fe14883..e399321 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -19,7 +19,7 @@
 #include <linux/backlight.h>
 
 #include <asm/cpu/dac.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 #include <asm/hd64461.h>
 
 #define HP680_MAX_INTENSITY 255
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c
index 3aa6ebf..f836137 100644
--- a/drivers/video/fb_ddc.c
+++ b/drivers/video/fb_ddc.c
@@ -20,26 +20,26 @@
 static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter)
 {
 	unsigned char start = 0x0;
+	unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
 	struct i2c_msg msgs[] = {
 		{
 			.addr	= DDC_ADDR,
+			.flags	= 0,
 			.len	= 1,
 			.buf	= &start,
 		}, {
 			.addr	= DDC_ADDR,
 			.flags	= I2C_M_RD,
 			.len	= EDID_LENGTH,
+			.buf	= buf,
 		}
 	};
-	unsigned char *buf;
 
-	buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
 	if (!buf) {
 		dev_warn(&adapter->dev, "unable to allocate memory for EDID "
 			 "block.\n");
 		return NULL;
 	}
-	msgs[1].buf = buf;
 
 	if (i2c_transfer(adapter, msgs, 2) == 2)
 		return buf;
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index 3afb472..3dc4942 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -29,7 +29,6 @@
 #include <asm/io.h>
 #include <asm/hd64461.h>
 #include <asm/cpu/dac.h>
-#include <asm/hp6xx/hp6xx.h>
 
 #define	WIDTH 640
 
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index eeeeff9..a958368 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -161,7 +161,7 @@
 		return 1;
 
 	/* Find the bridge device.  It is always 0:0.0 */
-	if (!(bridge_dev = pci_find_slot(0, PCI_DEVFN(0, 0)))) {
+	if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) {
 		ERR_MSG("cannot find bridge device\n");
 		return 1;
 	}
@@ -169,6 +169,8 @@
 	/* Get the fb aperture size and "stolen" memory amount. */
 	tmp = 0;
 	pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
+	pci_dev_put(bridge_dev);
+
 	switch (pdev->device) {
 	case PCI_DEVICE_ID_INTEL_915G:
 	case PCI_DEVICE_ID_INTEL_915GM:
@@ -662,7 +664,7 @@
 	int index = dinfo->pll_index;
 	DBG_MSG("intelfbhw_print_hw_state\n");
 
-	if (!hw || !dinfo)
+	if (!hw)
 		return;
 	/* Read in as much of the HW state as possible. */
 	printk("hw state dump start\n");
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index 9ed640d..ea42611 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -145,12 +145,18 @@
 
 	if (par->Architecture >= NV_ARCH_40) {
 		pll = NV_RD32(par->PMC, 0x4020);
-		P = (pll >> 16) & 0x03;
+		P = (pll >> 16) & 0x07;
 		pll = NV_RD32(par->PMC, 0x4024);
 		M = pll & 0xFF;
 		N = (pll >> 8) & 0xFF;
-		MB = (pll >> 16) & 0xFF;
-		NB = (pll >> 24) & 0xFF;
+		if (((par->Chipset & 0xfff0) == 0x0290) ||
+				((par->Chipset & 0xfff0) == 0x0390)) {
+			MB = 1;
+			NB = 1;
+		} else {
+			MB = (pll >> 16) & 0xFF;
+			NB = (pll >> 24) & 0xFF;
+		}
 		*MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
 
 		pll = NV_RD32(par->PMC, 0x4000);
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index a18a9ae..eab3e28 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -262,7 +262,7 @@
 #endif
 
 	dev = pci_find_slot(0, 1);
-	if ((par->Chipset && 0xffff) == 0x01a0) {
+	if ((par->Chipset & 0xffff) == 0x01a0) {
 		int amt = 0;
 
 		pci_read_config_dword(dev, 0x7c, &amt);
@@ -359,6 +359,7 @@
 	case 0x0186:
 	case 0x0187:
 	case 0x018D:
+	case 0x0228:
 	case 0x0286:
 	case 0x028C:
 	case 0x0316:
@@ -382,6 +383,10 @@
 	case 0x034C:
 	case 0x0160:
 	case 0x0166:
+	case 0x0169:
+	case 0x016B:
+	case 0x016C:
+	case 0x016D:
 	case 0x00C8:
 	case 0x00CC:
 	case 0x0144:
@@ -639,12 +644,23 @@
 		par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1;
 		par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033;
 
-		printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight);
+		printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, par->fpHeight);
 	}
 
 	if (monA)
 		info->monspecs = *monA;
 
+	if (!par->FlatPanel || !par->twoHeads)
+		par->FPDither = 0;
+
+	par->LVDS = 0;
+	if (par->FlatPanel && par->twoHeads) {
+		NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004);
+		if (par->PRAMDAC0[0x08b4] & 1)
+			par->LVDS = 1;
+		printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS");
+	}
+
 	kfree(edidA);
 	kfree(edidB);
 done:
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index acdc266..86e65de 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -129,6 +129,7 @@
 	int fpHeight;
 	int PanelTweak;
 	int paneltweak;
+	int LVDS;
 	int pm_state;
 	u32 crtcSync_read;
 	u32 fpSyncs;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index eb24107..538e947 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1160,20 +1160,20 @@
 	case 0x0340:		/* GeForceFX 5700 */
 		arch = NV_ARCH_30;
 		break;
-	case 0x0040:
-	case 0x00C0:
-	case 0x0120:
+	case 0x0040:		/* GeForce 6800 */
+	case 0x00C0:		/* GeForce 6800 */
+	case 0x0120:		/* GeForce 6800 */
 	case 0x0130:
-	case 0x0140:
-	case 0x0160:
-	case 0x01D0:
-	case 0x0090:
-	case 0x0210:
-	case 0x0220:
+	case 0x0140:		/* GeForce 6600 */
+	case 0x0160:		/* GeForce 6200 */
+	case 0x01D0:		/* GeForce 7200, 7300, 7400 */
+	case 0x0090:		/* GeForce 7800 */
+	case 0x0210:		/* GeForce 6800 */
+	case 0x0220:		/* GeForce 6200 */
 	case 0x0230:
-	case 0x0240:
-	case 0x0290:
-	case 0x0390:
+	case 0x0240:		/* GeForce 6100 */
+	case 0x0290:		/* GeForce 7900 */
+	case 0x0390:		/* GeForce 7600 */
 		arch = NV_ARCH_40;
 		break;
 	case 0x0020:		/* TNT, TNT2 */
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index bad0e98..9a40bbe 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -157,7 +157,7 @@
 		out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
 		break;
 	case cmap_gxt2000:
-		out_le32((unsigned __iomem *) par->cmap_adr + regno,
+		out_le32(((unsigned __iomem *) par->cmap_adr) + regno,
 			 (red << 16 | green << 8 | blue));
 		break;
 	}
@@ -213,7 +213,7 @@
 				out_le32(par->cmap_adr + 0xb4, 0);
 				break;
 			case cmap_gxt2000:
-				out_le32((unsigned __iomem *) par->cmap_adr + i,
+				out_le32(((unsigned __iomem *) par->cmap_adr) + i,
 					 0);
 				break;
 			}
@@ -226,13 +226,23 @@
 static void __iomem *offb_map_reg(struct device_node *np, int index,
 				  unsigned long offset, unsigned long size)
 {
-	struct resource r;
+	const u32 *addrp;
+	u64 asize, taddr;
+	unsigned int flags;
 
-	if (of_address_to_resource(np, index, &r))
-		return 0;
-	if ((r.start + offset + size) > r.end)
-		return 0;
-	return ioremap(r.start + offset, size);
+	addrp = of_get_pci_address(np, index, &asize, &flags);
+	if (addrp == NULL)
+		addrp = of_get_address(np, index, &asize, &flags);
+	if (addrp == NULL)
+		return NULL;
+	if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+		return NULL;
+	if ((offset + size) > asize)
+		return NULL;
+	taddr = of_translate_address(np, addrp);
+	if (taddr == OF_BAD_ADDR)
+		return NULL;
+	return ioremap(taddr + offset, size);
 }
 
 static void __init offb_init_fb(const char *name, const char *full_name,
@@ -289,7 +299,6 @@
 
 	par->cmap_type = cmap_unknown;
 	if (depth == 8) {
-		/* Palette hacks disabled for now */
 		if (dp && !strncmp(name, "ATY,Rage128", 11)) {
 			par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
 			if (par->cmap_adr)
@@ -313,7 +322,8 @@
 			    ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
 			par->cmap_data = par->cmap_adr + 1;
 			par->cmap_type = cmap_m64;
-		} else if (dp && device_is_compatible(dp, "pci1014,b7")) {
+		} else if (dp && (device_is_compatible(dp, "pci1014,b7") ||
+				  device_is_compatible(dp, "pci1014,21c"))) {
 			par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
 			if (par->cmap_adr)
 				par->cmap_type = cmap_gxt2000;
@@ -433,7 +443,7 @@
 	pp = get_property(dp, "linux,bootx-linebytes", &len);
 	if (pp == NULL)
 		pp = get_property(dp, "linebytes", &len);
-	if (pp && len == sizeof(u32))
+	if (pp && len == sizeof(u32) && (*pp != 0xffffffffu))
 		pitch = *pp;
 	else
 		pitch = width * ((depth + 7) / 8);
@@ -496,7 +506,7 @@
 		offb_init_fb(no_real_node ? "bootx" : dp->name,
 			     no_real_node ? "display" : dp->full_name,
 			     width, height, depth, pitch, address,
-			     no_real_node ? dp : NULL);
+			     no_real_node ? NULL : dp);
 	}
 }
 
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
index 7d9453c..f29e66e 100644
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -154,7 +154,8 @@
 			goto err1;
 	}
 
-	if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor"))
+	if (!fb_get_options("pnxrgbfb", &option) && option &&
+			!strcmp(option, "nocursor"))
 		rgbfb_ops.fb_cursor = no_cursor;
 
 	info->node = -1;
@@ -191,7 +192,7 @@
 
 static struct platform_driver rgbfb_driver = {
 	.driver = {
-		.name = "rgbfb",
+		.name = "pnx4008-rgbfb",
 	},
 	.probe = rgbfb_probe,
 	.remove = rgbfb_remove,
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
index 51f0ecc..d23bf0d 100644
--- a/drivers/video/pnx4008/sdum.c
+++ b/drivers/video/pnx4008/sdum.c
@@ -848,7 +848,7 @@
 
 static struct platform_driver sdum_driver = {
 	.driver = {
-		.name = "sdum",
+		.name = "pnx4008-sdum",
 	},
 	.probe = sdum_probe,
 	.remove = sdum_remove,
diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c
index 2788b8c..6f9d880 100644
--- a/drivers/w1/masters/matrox_w1.c
+++ b/drivers/w1/masters/matrox_w1.c
@@ -215,6 +215,8 @@
 	return 0;
 
 err_out_free_device:
+	if (dev->virt_addr)
+		iounmap(dev->virt_addr);
 	kfree(dev);
 
 	return err;
diff --git a/fs/Kconfig b/fs/Kconfig
index fee318e..7b1511d 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1777,6 +1777,7 @@
 	select CRYPTO
 	select CRYPTO_MD5
 	select CRYPTO_DES
+	select CRYPTO_CBC
 	help
 	  Provides for secure RPC calls by means of a gss-api
 	  mechanism based on Kerberos V5. This is required for
@@ -1795,6 +1796,7 @@
 	select CRYPTO_MD5
 	select CRYPTO_DES
 	select CRYPTO_CAST5
+	select CRYPTO_CBC
 	help
 	  Provides for secure RPC calls by means of a gss-api
 	  mechanism based on the SPKM3 public-key mechanism.
@@ -2058,8 +2060,7 @@
 	  For most cases you probably want to say N.
 
 config AFS_FS
-# for fs/nls/Config.in
-	tristate "Andrew File System support (AFS) (Experimental)"
+	tristate "Andrew File System support (AFS) (EXPERIMENTAL)"
 	depends on INET && EXPERIMENTAL
 	select RXRPC
 	help
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index 54c518c..38ede5c 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -25,6 +25,14 @@
 	struct autofs_sb_info *sbi = autofs_sbi(sb);
 	unsigned int n;
 
+	/*
+	 * In the event of a failure in get_sb_nodev the superblock
+	 * info is not present so nothing else has been setup, so
+	 * just exit when we are called from deactivate_super.
+	 */
+	if (!sbi)
+		return;
+
 	if ( !sbi->catatonic )
 		autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
 
@@ -136,7 +144,8 @@
 
 	s->s_fs_info = sbi;
 	sbi->magic = AUTOFS_SBI_MAGIC;
-	sbi->catatonic = 0;
+	sbi->pipe = NULL;
+	sbi->catatonic = 1;
 	sbi->exp_timeout = 0;
 	sbi->oz_pgrp = process_group(current);
 	autofs_initialize_hash(&sbi->dirhash);
@@ -180,6 +189,7 @@
 	if ( !pipe->f_op || !pipe->f_op->write )
 		goto fail_fput;
 	sbi->pipe = pipe;
+	sbi->catatonic = 0;
 
 	/*
 	 * Success! Install the root dentry now to indicate completion.
@@ -198,6 +208,8 @@
 	iput(root_inode);
 fail_free:
 	kfree(sbi);
+	s->s_fs_info = NULL;
+	kill_anon_super(s);
 fail_unlock:
 	return -EINVAL;
 }
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
index 633f628..19a9caf 100644
--- a/fs/autofs/waitq.c
+++ b/fs/autofs/waitq.c
@@ -41,6 +41,7 @@
 		wq = nwq;
 	}
 	fput(sbi->pipe);	/* Close the pipe */
+	sbi->pipe = NULL;
 	autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */
 }
 
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 51fd859..ce7c0f1 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -99,6 +99,9 @@
 	struct dentry *this_parent = sbi->sb->s_root;
 	struct list_head *next;
 
+	if (!sbi->sb->s_root)
+		return;
+
 	spin_lock(&dcache_lock);
 repeat:
 	next = this_parent->d_subdirs.next;
@@ -146,6 +149,14 @@
 {
 	struct autofs_sb_info *sbi = autofs4_sbi(sb);
 
+	/*
+	 * In the event of a failure in get_sb_nodev the superblock
+	 * info is not present so nothing else has been setup, so
+	 * just exit when we are called from deactivate_super.
+	 */
+	if (!sbi)
+		return;
+
 	sb->s_fs_info = NULL;
 
 	if ( !sbi->catatonic )
@@ -310,7 +321,8 @@
 	s->s_fs_info = sbi;
 	sbi->magic = AUTOFS_SBI_MAGIC;
 	sbi->pipefd = -1;
-	sbi->catatonic = 0;
+	sbi->pipe = NULL;
+	sbi->catatonic = 1;
 	sbi->exp_timeout = 0;
 	sbi->oz_pgrp = process_group(current);
 	sbi->sb = s;
@@ -388,6 +400,7 @@
 		goto fail_fput;
 	sbi->pipe = pipe;
 	sbi->pipefd = pipefd;
+	sbi->catatonic = 0;
 
 	/*
 	 * Success! Install the root dentry now to indicate completion.
@@ -412,6 +425,8 @@
 	kfree(ino);
 fail_free:
 	kfree(sbi);
+	s->s_fs_info = NULL;
+	kill_anon_super(s);
 fail_unlock:
 	return -EINVAL;
 }
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index c0a6c8d..1e4a539 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -41,10 +41,8 @@
 		wake_up_interruptible(&wq->queue);
 		wq = nwq;
 	}
-	if (sbi->pipe) {
-		fput(sbi->pipe);	/* Close the pipe */
-		sbi->pipe = NULL;
-	}
+	fput(sbi->pipe);	/* Close the pipe */
+	sbi->pipe = NULL;
 }
 
 static int autofs4_write(struct file *file, const void *addr, int bytes)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index bc8f27c..36c0e7a 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -642,34 +642,47 @@
 }
 
 /**
+ * find_bd_holder - find matching struct bd_holder from the block device
+ *
+ * @bdev:	struct block device to be searched
+ * @bo:		target struct bd_holder
+ *
+ * Returns matching entry with @bo in @bdev->bd_holder_list.
+ * If found, increment the reference count and return the pointer.
+ * If not found, returns NULL.
+ */
+static struct bd_holder *find_bd_holder(struct block_device *bdev,
+					struct bd_holder *bo)
+{
+	struct bd_holder *tmp;
+
+	list_for_each_entry(tmp, &bdev->bd_holder_list, list)
+		if (tmp->sdir == bo->sdir) {
+			tmp->count++;
+			return tmp;
+		}
+
+	return NULL;
+}
+
+/**
  * add_bd_holder - create sysfs symlinks for bd_claim() relationship
  *
  * @bdev:	block device to be bd_claimed
  * @bo:		preallocated and initialized by alloc_bd_holder()
  *
- * If there is no matching entry with @bo in @bdev->bd_holder_list,
- * add @bo to the list, create symlinks.
+ * Add @bo to @bdev->bd_holder_list, create symlinks.
  *
- * Returns 0 if symlinks are created or already there.
- * Returns -ve if something fails and @bo can be freed.
+ * Returns 0 if symlinks are created.
+ * Returns -ve if something fails.
  */
 static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo)
 {
-	struct bd_holder *tmp;
 	int ret;
 
 	if (!bo)
 		return -EINVAL;
 
-	list_for_each_entry(tmp, &bdev->bd_holder_list, list) {
-		if (tmp->sdir == bo->sdir) {
-			tmp->count++;
-			/* We've already done what we need to do here. */
-			free_bd_holder(bo);
-			return 0;
-		}
-	}
-
 	if (!bd_holder_grab_dirs(bdev, bo))
 		return -EBUSY;
 
@@ -740,7 +753,7 @@
 				struct kobject *kobj)
 {
 	int res;
-	struct bd_holder *bo;
+	struct bd_holder *bo, *found;
 
 	if (!kobj)
 		return -EINVAL;
@@ -751,9 +764,16 @@
 
 	mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION);
 	res = bd_claim(bdev, holder);
-	if (res == 0)
-		res = add_bd_holder(bdev, bo);
-	if (res)
+	if (res == 0) {
+		found = find_bd_holder(bdev, bo);
+		if (found == NULL) {
+			res = add_bd_holder(bdev, bo);
+			if (res)
+				bd_release(bdev);
+		}
+	}
+
+	if (res || found)
 		free_bd_holder(bo);
 	mutex_unlock(&bdev->bd_mutex);
 
@@ -1131,6 +1151,8 @@
 	filp->f_flags |= O_LARGEFILE;
 
 	bdev = bd_acquire(inode);
+	if (bdev == NULL)
+		return -ENOMEM;
 
 	res = do_open(bdev, filp, BD_MUTEX_NORMAL);
 	if (res)
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 1eb9a2e..0b3c37e 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,6 +1,11 @@
 Version 1.46
 ------------
 Support deep tree mounts.  Better support OS/2, Win9x (DOS) time stamps.
+Allow null user to be specified on mount ("username="). Do not return
+EINVAL on readdir when filldir fails due to overwritten blocksize
+(fixes FC problem).  Return error in rename 2nd attempt retry (ie report
+if rename by handle also fails, after rename by path fails, we were
+not reporting whether the retry worked or not).
 
 Version 1.45
 ------------
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4093d53..71f7791 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -822,10 +822,13 @@
 		} else if (strnicmp(data, "nouser_xattr",12) == 0) {
 			vol->no_xattr = 1;
 		} else if (strnicmp(data, "user", 4) == 0) {
-			if (!value || !*value) {
+			if (!value) {
 				printk(KERN_WARNING
 				       "CIFS: invalid or missing username\n");
 				return 1;	/* needs_arg; */
+			} else if(!*value) {
+				/* null user, ie anonymous, authentication */
+				vol->nullauth = 1;
 			}
 			if (strnlen(value, 200) < 200) {
 				vol->username = value;
@@ -1642,6 +1645,8 @@
 		/* BB fixme parse for domain name here */
 		cFYI(1, ("Username: %s ", volume_info.username));
 
+	} else if (volume_info.nullauth) {
+		cFYI(1,("null user"));
 	} else {
 		cifserror("No username specified");
         /* In userspace mount helper we can get user name from alternate
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 976a691..2436ed8 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -492,10 +492,14 @@
 					the struct would be in each open file,
 					but this should give enough time to 
 					clear the socket */
-					cERROR(1,("close with pending writes"));
+#ifdef CONFIG_CIFS_DEBUG2
+					cFYI(1,("close delay, write pending"));
+#endif /* DEBUG2 */
 					msleep(timeout);
 					timeout *= 4;
-				} 
+				}
+				if(atomic_read(&pSMBFile->wrtPending))
+					cERROR(1,("close with pending writes"));
 				rc = CIFSSMBClose(xid, pTcon,
 						  pSMBFile->netfid);
 			}
@@ -1806,13 +1810,6 @@
 		}
 		if ((rc < 0) || (smb_read_data == NULL)) {
 			cFYI(1, ("Read error in readpages: %d", rc));
-			/* clean up remaing pages off list */
-			while (!list_empty(page_list) && (i < num_pages)) {
-				page = list_entry(page_list->prev, struct page,
-						  lru);
-				list_del(&page->lru);
-				page_cache_release(page);
-			}
 			break;
 		} else if (bytes_read > 0) {
 			pSMBr = (struct smb_com_read_rsp *)smb_read_data;
@@ -1831,13 +1828,7 @@
 				   this case is ok - if we are at server EOF 
 				   we will hit it on next read */
 
-			/* while (!list_empty(page_list) && (i < num_pages)) {
-					page = list_entry(page_list->prev, 
-							  struct page, list);
-					list_del(&page->list);
-					page_cache_release(page);
-				}
-				break; */
+				/* break; */
 			}
 		} else {
 			cFYI(1, ("No bytes read (%d) at offset %lld . "
@@ -1845,14 +1836,6 @@
 				 bytes_read, offset));
 			/* BB turn off caching and do new lookup on 
 			   file size at server? */
-			while (!list_empty(page_list) && (i < num_pages)) {
-				page = list_entry(page_list->prev, struct page,
-						  lru);
-				list_del(&page->lru);
-
-				/* BB removeme - replace with zero of page? */
-				page_cache_release(page);
-			}
 			break;
 		}
 		if (smb_read_data) {
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 35d54bb..1ad8c9f 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -885,10 +885,14 @@
 			kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
 		if (info_buf_source != NULL) {
 			info_buf_target = info_buf_source + 1;
-			rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
-				info_buf_source, cifs_sb_source->local_nls, 
-				cifs_sb_source->mnt_cifs_flags &
-					CIFS_MOUNT_MAP_SPECIAL_CHR);
+			if (pTcon->ses->capabilities & CAP_UNIX)
+				rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
+					info_buf_source, 
+					cifs_sb_source->local_nls,
+					cifs_sb_source->mnt_cifs_flags &
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
+			/* else rc is still EEXIST so will fall through to
+			   unlink the target and retry rename */
 			if (rc == 0) {
 				rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName,
 						info_buf_target,
@@ -937,7 +941,7 @@
 				 cifs_sb_source->mnt_cifs_flags & 
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		if (rc==0) {
-			CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
+			rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
 					      cifs_sb_source->local_nls, 
 					      cifs_sb_source->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -1085,8 +1089,10 @@
 	struct kstat *stat)
 {
 	int err = cifs_revalidate(dentry);
-	if (!err)
+	if (!err) {
 		generic_fillattr(dentry->d_inode, stat);
+		stat->blksize = CIFS_MAX_MSGSIZE;
+	}
 	return err;
 }
 
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index b5b0a2a..ed18c39 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -896,6 +896,10 @@
 		     tmp_inode->i_ino,obj_type);
 	if(rc) {
 		cFYI(1,("filldir rc = %d",rc));
+		/* we can not return filldir errors to the caller
+		since they are "normal" when the stat blocksize
+		is too small - we return remapped error instead */
+		rc = -EOVERFLOW;
 	}
 
 	dput(tmp_dentry);
@@ -1074,6 +1078,11 @@
 			we want to check for that here? */
 			rc = cifs_filldir(current_entry, file,
 					filldir, direntry, tmp_buf, max_len);
+			if(rc == -EOVERFLOW) {
+				rc = 0;
+				break;
+			}
+
 			file->f_pos++;
 			if(file->f_pos == 
 				cifsFile->srch_inf.index_of_last_entry) {
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index a8a0835..bbdda99 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -90,7 +90,9 @@
 	} */
 	/* copy user */
 	if(ses->userName == NULL) {
-		/* BB what about null user mounts - check that we do this BB */
+		/* null user mount */
+		*bcc_ptr = 0;
+		*(bcc_ptr+1) = 0;
 	} else { /* 300 should be long enough for any conceivable user name */
 		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
 					  300, nls_cp);
@@ -98,10 +100,13 @@
 	bcc_ptr += 2 * bytes_ret;
 	bcc_ptr += 2; /* account for null termination */
 	/* copy domain */
-	if(ses->domainName == NULL)
-		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr,
-					  "CIFS_LINUX_DOM", 32, nls_cp);
-	else
+	if(ses->domainName == NULL) {
+		/* Sending null domain better than using a bogus domain name (as
+		we did briefly in 2.6.18) since server will use its default */
+		*bcc_ptr = 0;
+		*(bcc_ptr+1) = 0;
+		bytes_ret = 0;
+	} else
 		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 
 					  256, nls_cp);
 	bcc_ptr += 2 * bytes_ret;
@@ -144,13 +149,11 @@
 
         /* copy domain */
 	
-        if(ses->domainName == NULL) {
-                strcpy(bcc_ptr, "CIFS_LINUX_DOM");
-		bcc_ptr += 14;  /* strlen(CIFS_LINUX_DOM) */
- 	} else {
+        if(ses->domainName != NULL) {
                 strncpy(bcc_ptr, ses->domainName, 256); 
 		bcc_ptr += strnlen(ses->domainName, 256);
-	}
+	} /* else we will send a null domain name 
+	     so the server will default to its own domain */
 	*bcc_ptr = 0;
 	bcc_ptr++;
 
diff --git a/fs/compat.c b/fs/compat.c
index 50624d4..8d0a001 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1835,9 +1835,12 @@
 
 	} while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec));
 
-	if (ret == 0 && tsp && !(current->personality & STICKY_TIMEOUTS)) {
+	if (tsp) {
 		struct compat_timespec rts;
 
+		if (current->personality & STICKY_TIMEOUTS)
+			goto sticky;
+
 		rts.tv_sec = timeout / HZ;
 		rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ);
 		if (rts.tv_nsec >= NSEC_PER_SEC) {
@@ -1846,8 +1849,19 @@
 		}
 		if (compat_timespec_compare(&rts, &ts) >= 0)
 			rts = ts;
-		if (copy_to_user(tsp, &rts, sizeof(rts)))
-			ret = -EFAULT;
+		if (copy_to_user(tsp, &rts, sizeof(rts))) {
+sticky:
+			/*
+			 * If an application puts its timeval in read-only
+			 * memory, we don't want the Linux-specific update to
+			 * the timeval to cause a fault after the select has
+			 * completed successfully. However, because we're not
+			 * updating the timeval, we can't restart the system
+			 * call.
+			 */
+			if (ret == -ERESTARTNOHAND)
+				ret = -EINTR;
+		}
 	}
 
 	if (ret == -ERESTARTNOHAND) {
diff --git a/fs/dcache.c b/fs/dcache.c
index 2bac4ba..fd4a428 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -478,11 +478,12 @@
 			up_read(s_umount);
 		}
 		spin_unlock(&dentry->d_lock);
-		/* Cannot remove the first dentry, and it isn't appropriate
-		 * to move it to the head of the list, so give up, and try
-		 * later
+		/*
+		 * Insert dentry at the head of the list as inserting at the
+		 * tail leads to a cycle.
 		 */
-		break;
+ 		list_add(&dentry->d_lru, &dentry_unused);
+		dentry_stat.nr_unused++;
 	}
 	spin_unlock(&dcache_lock);
 }
@@ -556,6 +557,7 @@
 static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
 {
 	struct dentry *parent;
+	unsigned detached = 0;
 
 	BUG_ON(!IS_ROOT(dentry));
 
@@ -620,7 +622,7 @@
 				atomic_dec(&parent->d_count);
 
 			list_del(&dentry->d_u.d_child);
-			dentry_stat.nr_dentry--;	/* For d_free, below */
+			detached++;
 
 			inode = dentry->d_inode;
 			if (inode) {
@@ -638,7 +640,7 @@
 			 * otherwise we ascend to the parent and move to the
 			 * next sibling if there is one */
 			if (!parent)
-				return;
+				goto out;
 
 			dentry = parent;
 
@@ -647,6 +649,11 @@
 		dentry = list_entry(dentry->d_subdirs.next,
 				    struct dentry, d_u.d_child);
 	}
+out:
+	/* several dentries were freed, need to correct nr_dentry */
+	spin_lock(&dcache_lock);
+	dentry_stat.nr_dentry -= detached;
+	spin_unlock(&dcache_lock);
 }
 
 /*
@@ -1469,23 +1476,21 @@
  * deleted it.
  */
  
-/**
- * d_move - move a dentry
+/*
+ * d_move_locked - move a dentry
  * @dentry: entry to move
  * @target: new dentry
  *
  * Update the dcache to reflect the move of a file name. Negative
  * dcache entries should not be moved in this way.
  */
-
-void d_move(struct dentry * dentry, struct dentry * target)
+static void d_move_locked(struct dentry * dentry, struct dentry * target)
 {
 	struct hlist_head *list;
 
 	if (!dentry->d_inode)
 		printk(KERN_WARNING "VFS: moving negative dcache entry\n");
 
-	spin_lock(&dcache_lock);
 	write_seqlock(&rename_lock);
 	/*
 	 * XXXX: do we really need to take target->d_lock?
@@ -1536,10 +1541,84 @@
 	fsnotify_d_move(dentry);
 	spin_unlock(&dentry->d_lock);
 	write_sequnlock(&rename_lock);
+}
+
+/**
+ * d_move - move a dentry
+ * @dentry: entry to move
+ * @target: new dentry
+ *
+ * Update the dcache to reflect the move of a file name. Negative
+ * dcache entries should not be moved in this way.
+ */
+
+void d_move(struct dentry * dentry, struct dentry * target)
+{
+	spin_lock(&dcache_lock);
+	d_move_locked(dentry, target);
 	spin_unlock(&dcache_lock);
 }
 
 /*
+ * Helper that returns 1 if p1 is a parent of p2, else 0
+ */
+static int d_isparent(struct dentry *p1, struct dentry *p2)
+{
+	struct dentry *p;
+
+	for (p = p2; p->d_parent != p; p = p->d_parent) {
+		if (p->d_parent == p1)
+			return 1;
+	}
+	return 0;
+}
+
+/*
+ * This helper attempts to cope with remotely renamed directories
+ *
+ * It assumes that the caller is already holding
+ * dentry->d_parent->d_inode->i_mutex and the dcache_lock
+ *
+ * Note: If ever the locking in lock_rename() changes, then please
+ * remember to update this too...
+ *
+ * On return, dcache_lock will have been unlocked.
+ */
+static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
+{
+	struct mutex *m1 = NULL, *m2 = NULL;
+	struct dentry *ret;
+
+	/* If alias and dentry share a parent, then no extra locks required */
+	if (alias->d_parent == dentry->d_parent)
+		goto out_unalias;
+
+	/* Check for loops */
+	ret = ERR_PTR(-ELOOP);
+	if (d_isparent(alias, dentry))
+		goto out_err;
+
+	/* See lock_rename() */
+	ret = ERR_PTR(-EBUSY);
+	if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))
+		goto out_err;
+	m1 = &dentry->d_sb->s_vfs_rename_mutex;
+	if (!mutex_trylock(&alias->d_parent->d_inode->i_mutex))
+		goto out_err;
+	m2 = &alias->d_parent->d_inode->i_mutex;
+out_unalias:
+	d_move_locked(alias, dentry);
+	ret = alias;
+out_err:
+	spin_unlock(&dcache_lock);
+	if (m2)
+		mutex_unlock(m2);
+	if (m1)
+		mutex_unlock(m1);
+	return ret;
+}
+
+/*
  * Prepare an anonymous dentry for life in the superblock's dentry tree as a
  * named dentry in place of the dentry to be replaced.
  */
@@ -1581,7 +1660,7 @@
  */
 struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
 {
-	struct dentry *alias, *actual;
+	struct dentry *actual;
 
 	BUG_ON(!d_unhashed(dentry));
 
@@ -1593,26 +1672,27 @@
 		goto found_lock;
 	}
 
-	/* See if a disconnected directory already exists as an anonymous root
-	 * that we should splice into the tree instead */
-	if (S_ISDIR(inode->i_mode) && (alias = __d_find_alias(inode, 1))) {
-		spin_lock(&alias->d_lock);
+	if (S_ISDIR(inode->i_mode)) {
+		struct dentry *alias;
 
-		/* Is this a mountpoint that we could splice into our tree? */
-		if (IS_ROOT(alias))
-			goto connect_mountpoint;
-
-		if (alias->d_name.len == dentry->d_name.len &&
-		    alias->d_parent == dentry->d_parent &&
-		    memcmp(alias->d_name.name,
-			   dentry->d_name.name,
-			   dentry->d_name.len) == 0)
-			goto replace_with_alias;
-
-		spin_unlock(&alias->d_lock);
-
-		/* Doh! Seem to be aliasing directories for some reason... */
-		dput(alias);
+		/* Does an aliased dentry already exist? */
+		alias = __d_find_alias(inode, 0);
+		if (alias) {
+			actual = alias;
+			/* Is this an anonymous mountpoint that we could splice
+			 * into our tree? */
+			if (IS_ROOT(alias)) {
+				spin_lock(&alias->d_lock);
+				__d_materialise_dentry(dentry, alias);
+				__d_drop(alias);
+				goto found;
+			}
+			/* Nope, but we must(!) avoid directory aliasing */
+			actual = __d_unalias(dentry, alias);
+			if (IS_ERR(actual))
+				dput(alias);
+			goto out_nolock;
+		}
 	}
 
 	/* Add a unique reference */
@@ -1628,7 +1708,7 @@
 	_d_rehash(actual);
 	spin_unlock(&actual->d_lock);
 	spin_unlock(&dcache_lock);
-
+out_nolock:
 	if (actual == dentry) {
 		security_d_instantiate(dentry, inode);
 		return NULL;
@@ -1637,16 +1717,6 @@
 	iput(inode);
 	return actual;
 
-	/* Convert the anonymous/root alias into an ordinary dentry */
-connect_mountpoint:
-	__d_materialise_dentry(dentry, alias);
-
-	/* Replace the candidate dentry with the alias in the tree */
-replace_with_alias:
-	__d_drop(alias);
-	actual = alias;
-	goto found;
-
 shouldnt_be_hashed:
 	spin_unlock(&dcache_lock);
 	BUG();
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index e77676d..137d76c 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -21,6 +21,7 @@
 #include <linux/mount.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <linux/kobject.h>
 #include <linux/namei.h>
 #include <linux/debugfs.h>
 
@@ -147,13 +148,13 @@
 	*dentry = NULL;
 	mutex_lock(&parent->d_inode->i_mutex);
 	*dentry = lookup_one_len(name, parent, strlen(name));
-	if (!IS_ERR(dentry)) {
+	if (!IS_ERR(*dentry)) {
 		if ((mode & S_IFMT) == S_IFDIR)
 			error = debugfs_mkdir(parent->d_inode, *dentry, mode);
 		else 
 			error = debugfs_create(parent->d_inode, *dentry, mode);
 	} else
-		error = PTR_ERR(dentry);
+		error = PTR_ERR(*dentry);
 	mutex_unlock(&parent->d_inode->i_mutex);
 
 	return error;
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 109333c..f8842ca 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -43,6 +43,10 @@
 	ssize_t ret = len;
 	int n = simple_strtol(buf, NULL, 0);
 
+	ls = dlm_find_lockspace_local(ls->ls_local_handle);
+	if (!ls)
+		return -EINVAL;
+
 	switch (n) {
 	case 0:
 		dlm_ls_stop(ls);
@@ -53,6 +57,7 @@
 	default:
 		ret = -EINVAL;
 	}
+	dlm_put_lockspace(ls);
 	return ret;
 }
 
@@ -143,6 +148,12 @@
 	return a->store ? a->store(ls, buf, len) : len;
 }
 
+static void lockspace_kobj_release(struct kobject *k)
+{
+	struct dlm_ls *ls  = container_of(k, struct dlm_ls, ls_kobj);
+	kfree(ls);
+}
+
 static struct sysfs_ops dlm_attr_ops = {
 	.show  = dlm_attr_show,
 	.store = dlm_attr_store,
@@ -151,6 +162,7 @@
 static struct kobj_type dlm_ktype = {
 	.default_attrs = dlm_attrs,
 	.sysfs_ops     = &dlm_attr_ops,
+	.release       = lockspace_kobj_release,
 };
 
 static struct kset dlm_kset = {
@@ -678,7 +690,7 @@
 	dlm_clear_members_gone(ls);
 	kfree(ls->ls_node_array);
 	kobject_unregister(&ls->ls_kobj);
-	kfree(ls);
+        /* The ls structure will be freed when the kobject is done with */
 
 	mutex_lock(&ls_lock);
 	ls_count--;
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index ed35a9712..f63a775 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -94,25 +94,53 @@
 				  struct ecryptfs_crypt_stat *crypt_stat,
 				  char *src, int len)
 {
-	int rc = 0;
 	struct scatterlist sg;
+	struct hash_desc desc = {
+		.tfm = crypt_stat->hash_tfm,
+		.flags = CRYPTO_TFM_REQ_MAY_SLEEP
+	};
+	int rc = 0;
 
-	mutex_lock(&crypt_stat->cs_md5_tfm_mutex);
+	mutex_lock(&crypt_stat->cs_hash_tfm_mutex);
 	sg_init_one(&sg, (u8 *)src, len);
-	if (!crypt_stat->md5_tfm) {
-		crypt_stat->md5_tfm =
-			crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP);
-		if (!crypt_stat->md5_tfm) {
-			rc = -ENOMEM;
+	if (!desc.tfm) {
+		desc.tfm = crypto_alloc_hash(ECRYPTFS_DEFAULT_HASH, 0,
+					     CRYPTO_ALG_ASYNC);
+		if (IS_ERR(desc.tfm)) {
+			rc = PTR_ERR(desc.tfm);
 			ecryptfs_printk(KERN_ERR, "Error attempting to "
-					"allocate crypto context\n");
+					"allocate crypto context; rc = [%d]\n",
+					rc);
 			goto out;
 		}
+		crypt_stat->hash_tfm = desc.tfm;
 	}
-	crypto_digest_init(crypt_stat->md5_tfm);
-	crypto_digest_update(crypt_stat->md5_tfm, &sg, 1);
-	crypto_digest_final(crypt_stat->md5_tfm, dst);
-	mutex_unlock(&crypt_stat->cs_md5_tfm_mutex);
+	crypto_hash_init(&desc);
+	crypto_hash_update(&desc, &sg, len);
+	crypto_hash_final(&desc, dst);
+	mutex_unlock(&crypt_stat->cs_hash_tfm_mutex);
+out:
+	return rc;
+}
+
+int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
+					   char *cipher_name,
+					   char *chaining_modifier)
+{
+	int cipher_name_len = strlen(cipher_name);
+	int chaining_modifier_len = strlen(chaining_modifier);
+	int algified_name_len;
+	int rc;
+
+	algified_name_len = (chaining_modifier_len + cipher_name_len + 3);
+	(*algified_name) = kmalloc(algified_name_len, GFP_KERNEL);
+	if (!(*algified_name)) {
+		rc = -ENOMEM;
+		goto out;
+	}
+	snprintf((*algified_name), algified_name_len, "%s(%s)",
+		 chaining_modifier, cipher_name);
+	rc = 0;
 out:
 	return rc;
 }
@@ -178,7 +206,7 @@
 	memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
 	mutex_init(&crypt_stat->cs_mutex);
 	mutex_init(&crypt_stat->cs_tfm_mutex);
-	mutex_init(&crypt_stat->cs_md5_tfm_mutex);
+	mutex_init(&crypt_stat->cs_hash_tfm_mutex);
 	ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED);
 }
 
@@ -191,9 +219,9 @@
 void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
 {
 	if (crypt_stat->tfm)
-		crypto_free_tfm(crypt_stat->tfm);
-	if (crypt_stat->md5_tfm)
-		crypto_free_tfm(crypt_stat->md5_tfm);
+		crypto_free_blkcipher(crypt_stat->tfm);
+	if (crypt_stat->hash_tfm)
+		crypto_free_hash(crypt_stat->hash_tfm);
 	memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
 }
 
@@ -203,7 +231,7 @@
 	if (mount_crypt_stat->global_auth_tok_key)
 		key_put(mount_crypt_stat->global_auth_tok_key);
 	if (mount_crypt_stat->global_key_tfm)
-		crypto_free_tfm(mount_crypt_stat->global_key_tfm);
+		crypto_free_blkcipher(mount_crypt_stat->global_key_tfm);
 	memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
 }
 
@@ -269,6 +297,11 @@
 			       struct scatterlist *src_sg, int size,
 			       unsigned char *iv)
 {
+	struct blkcipher_desc desc = {
+		.tfm = crypt_stat->tfm,
+		.info = iv,
+		.flags = CRYPTO_TFM_REQ_MAY_SLEEP
+	};
 	int rc = 0;
 
 	BUG_ON(!crypt_stat || !crypt_stat->tfm
@@ -282,8 +315,8 @@
 	}
 	/* Consider doing this once, when the file is opened */
 	mutex_lock(&crypt_stat->cs_tfm_mutex);
-	rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
-				  crypt_stat->key_size);
+	rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
+				     crypt_stat->key_size);
 	if (rc) {
 		ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
 				rc);
@@ -292,7 +325,7 @@
 		goto out;
 	}
 	ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size);
-	crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv);
+	crypto_blkcipher_encrypt_iv(&desc, dest_sg, src_sg, size);
 	mutex_unlock(&crypt_stat->cs_tfm_mutex);
 out:
 	return rc;
@@ -675,12 +708,17 @@
 			       struct scatterlist *src_sg, int size,
 			       unsigned char *iv)
 {
+	struct blkcipher_desc desc = {
+		.tfm = crypt_stat->tfm,
+		.info = iv,
+		.flags = CRYPTO_TFM_REQ_MAY_SLEEP
+	};
 	int rc = 0;
 
 	/* Consider doing this once, when the file is opened */
 	mutex_lock(&crypt_stat->cs_tfm_mutex);
-	rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
-				  crypt_stat->key_size);
+	rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
+				     crypt_stat->key_size);
 	if (rc) {
 		ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
 				rc);
@@ -689,8 +727,7 @@
 		goto out;
 	}
 	ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
-	rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size,
-				      iv);
+	rc = crypto_blkcipher_decrypt_iv(&desc, dest_sg, src_sg, size);
 	mutex_unlock(&crypt_stat->cs_tfm_mutex);
 	if (rc) {
 		ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n",
@@ -759,6 +796,7 @@
  */
 int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
 {
+	char *full_alg_name;
 	int rc = -EINVAL;
 
 	if (!crypt_stat->cipher) {
@@ -775,16 +813,25 @@
 		goto out;
 	}
 	mutex_lock(&crypt_stat->cs_tfm_mutex);
-	crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher,
-					   ECRYPTFS_DEFAULT_CHAINING_MODE
-					   | CRYPTO_TFM_REQ_WEAK_KEY);
-	mutex_unlock(&crypt_stat->cs_tfm_mutex);
-	if (!crypt_stat->tfm) {
+	rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
+						    crypt_stat->cipher, "cbc");
+	if (rc)
+		goto out;
+	crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0,
+						 CRYPTO_ALG_ASYNC);
+	kfree(full_alg_name);
+	if (IS_ERR(crypt_stat->tfm)) {
+		rc = PTR_ERR(crypt_stat->tfm);
 		ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
 				"Error initializing cipher [%s]\n",
 				crypt_stat->cipher);
+		mutex_unlock(&crypt_stat->cs_tfm_mutex);
 		goto out;
 	}
+	crypto_blkcipher_set_flags(crypt_stat->tfm,
+				   (ECRYPTFS_DEFAULT_CHAINING_MODE
+				    | CRYPTO_TFM_REQ_WEAK_KEY));
+	mutex_unlock(&crypt_stat->cs_tfm_mutex);
 	rc = 0;
 out:
 	return rc;
@@ -1145,28 +1192,28 @@
 int ecryptfs_read_header_region(char *data, struct dentry *dentry,
 				struct vfsmount *mnt)
 {
-	struct file *file;
+	struct file *lower_file;
 	mm_segment_t oldfs;
 	int rc;
 
-	mnt = mntget(mnt);
-	file = dentry_open(dentry, mnt, O_RDONLY);
-	if (IS_ERR(file)) {
-		ecryptfs_printk(KERN_DEBUG, "Error opening file to "
-				"read header region\n");
-		mntput(mnt);
-		rc = PTR_ERR(file);
+	if ((rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt,
+					   O_RDONLY))) {
+		printk(KERN_ERR
+		       "Error opening lower_file to read header region\n");
 		goto out;
 	}
-	file->f_pos = 0;
+	lower_file->f_pos = 0;
 	oldfs = get_fs();
 	set_fs(get_ds());
 	/* For releases 0.1 and 0.2, all of the header information
 	 * fits in the first data extent-sized region. */
-	rc = file->f_op->read(file, (char __user *)data,
-			      ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos);
+	rc = lower_file->f_op->read(lower_file, (char __user *)data,
+			      ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos);
 	set_fs(oldfs);
-	fput(file);
+	if ((rc = ecryptfs_close_lower_file(lower_file))) {
+		printk(KERN_ERR "Error closing lower_file\n");
+		goto out;
+	}
 	rc = 0;
 out:
 	return rc;
@@ -1573,84 +1620,52 @@
 
 /**
  * ecryptfs_process_cipher - Perform cipher initialization.
- * @tfm: Crypto context set by this function
  * @key_tfm: Crypto context for key material, set by this function
- * @cipher_name: Name of the cipher.
- * @key_size: Size of the key in bytes.
+ * @cipher_name: Name of the cipher
+ * @key_size: Size of the key in bytes
  *
  * Returns zero on success. Any crypto_tfm structs allocated here
  * should be released by other functions, such as on a superblock put
  * event, regardless of whether this function succeeds for fails.
  */
 int
-ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
-			char *cipher_name, size_t key_size)
+ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
+			size_t *key_size)
 {
 	char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
+	char *full_alg_name;
 	int rc;
 
-	*tfm = *key_tfm = NULL;
-	if (key_size > ECRYPTFS_MAX_KEY_BYTES) {
+	*key_tfm = NULL;
+	if (*key_size > ECRYPTFS_MAX_KEY_BYTES) {
 		rc = -EINVAL;
 		printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum "
-		       "allowable is [%d]\n", key_size, ECRYPTFS_MAX_KEY_BYTES);
+		      "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES);
 		goto out;
 	}
-	*tfm = crypto_alloc_tfm(cipher_name, (ECRYPTFS_DEFAULT_CHAINING_MODE
-					      | CRYPTO_TFM_REQ_WEAK_KEY));
-	if (!(*tfm)) {
-		rc = -EINVAL;
+	rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, cipher_name,
+						    "ecb");
+	if (rc)
+		goto out;
+	*key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC);
+	kfree(full_alg_name);
+	if (IS_ERR(*key_tfm)) {
+		rc = PTR_ERR(*key_tfm);
 		printk(KERN_ERR "Unable to allocate crypto cipher with name "
-		       "[%s]\n", cipher_name);
+		       "[%s]; rc = [%d]\n", cipher_name, rc);
 		goto out;
 	}
-	*key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY);
-	if (!(*key_tfm)) {
-		rc = -EINVAL;
-		printk(KERN_ERR "Unable to allocate crypto cipher with name "
-		       "[%s]\n", cipher_name);
-		goto out;
+	crypto_blkcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+	if (*key_size == 0) {
+		struct blkcipher_alg *alg = crypto_blkcipher_alg(*key_tfm);
+
+		*key_size = alg->max_keysize;
 	}
-	if (key_size < crypto_tfm_alg_min_keysize(*tfm)) {
-		rc = -EINVAL;
-		printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
-		       "supported by cipher [%s] is [%d]\n", key_size,
-		       cipher_name, crypto_tfm_alg_min_keysize(*tfm));
-		goto out;
-	}
-	if (key_size < crypto_tfm_alg_min_keysize(*key_tfm)) {
-		rc = -EINVAL;
-		printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
-		       "supported by cipher [%s] is [%d]\n", key_size,
-		       cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
-		goto out;
-	}
-	if (key_size > crypto_tfm_alg_max_keysize(*tfm)) {
-		rc = -EINVAL;
-		printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
-		       "supported by cipher [%s] is [%d]\n", key_size,
-		       cipher_name, crypto_tfm_alg_min_keysize(*tfm));
-		goto out;
-	}
-	if (key_size > crypto_tfm_alg_max_keysize(*key_tfm)) {
-		rc = -EINVAL;
-		printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
-		       "supported by cipher [%s] is [%d]\n", key_size,
-		       cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
-		goto out;
-	}
-	get_random_bytes(dummy_key, key_size);
-	rc = crypto_cipher_setkey(*tfm, dummy_key, key_size);
+	get_random_bytes(dummy_key, *key_size);
+	rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size);
 	if (rc) {
 		printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
-		       "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
-		rc = -EINVAL;
-		goto out;
-	}
-	rc = crypto_cipher_setkey(*key_tfm, dummy_key, key_size);
-	if (rc) {
-		printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
-		       "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
+		       "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc);
 		rc = -EINVAL;
 		goto out;
 	}
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
index f0d2a43..52d1e36 100644
--- a/fs/ecryptfs/dentry.c
+++ b/fs/ecryptfs/dentry.c
@@ -24,6 +24,7 @@
 
 #include <linux/dcache.h>
 #include <linux/namei.h>
+#include <linux/mount.h>
 #include "ecryptfs_kernel.h"
 
 /**
@@ -56,6 +57,12 @@
 	rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
 	nd->dentry = dentry_save;
 	nd->mnt = vfsmount_save;
+	if (dentry->d_inode) {
+		struct inode *lower_inode =
+			ecryptfs_inode_to_lower(dentry->d_inode);
+
+		ecryptfs_copy_attr_all(dentry->d_inode, lower_inode);
+	}
 out:
 	return rc;
 }
@@ -76,8 +83,13 @@
 	if (ecryptfs_dentry_to_private(dentry))
 		kmem_cache_free(ecryptfs_dentry_info_cache,
 				ecryptfs_dentry_to_private(dentry));
-	if (lower_dentry)
+	if (lower_dentry) {
+		struct vfsmount *lower_mnt =
+			ecryptfs_dentry_to_lower_mnt(dentry);
+
+		mntput(lower_mnt);
 		dput(lower_dentry);
+	}
 	return;
 }
 
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 872c995..f992533 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -175,6 +175,7 @@
 #define ECRYPTFS_DEFAULT_CIPHER "aes"
 #define ECRYPTFS_DEFAULT_KEY_BYTES 16
 #define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC
+#define ECRYPTFS_DEFAULT_HASH "md5"
 #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C
 #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED
 #define MD5_DIGEST_SIZE 16
@@ -204,15 +205,15 @@
 	size_t extent_shift;
 	unsigned int extent_mask;
 	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
-	struct crypto_tfm *tfm;
-	struct crypto_tfm *md5_tfm; /* Crypto context for generating
-				     * the initialization vectors */
+	struct crypto_blkcipher *tfm;
+	struct crypto_hash *hash_tfm; /* Crypto context for generating
+				       * the initialization vectors */
 	unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];
 	unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
 	unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
 	unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX];
 	struct mutex cs_tfm_mutex;
-	struct mutex cs_md5_tfm_mutex;
+	struct mutex cs_hash_tfm_mutex;
 	struct mutex cs_mutex;
 };
 
@@ -244,7 +245,7 @@
 	struct ecryptfs_auth_tok *global_auth_tok;
 	struct key *global_auth_tok_key;
 	size_t global_default_cipher_key_size;
-	struct crypto_tfm *global_key_tfm;
+	struct crypto_blkcipher *global_key_tfm;
 	struct mutex global_key_tfm_mutex;
 	unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
 						 + 1];
@@ -425,6 +426,9 @@
 void ecryptfs_destruct_mount_crypt_stat(
 	struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
 int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
+int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
+					   char *cipher_name,
+					   char *chaining_modifier);
 int ecryptfs_write_inode_size_to_header(struct file *lower_file,
 					struct inode *lower_inode,
 					struct inode *inode);
@@ -473,10 +477,14 @@
 			  unsigned char *src, struct dentry *ecryptfs_dentry);
 int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
 int
-ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
-			char *cipher_name, size_t key_size);
+ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
+			size_t *key_size);
 int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
 int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
 void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode);
+int ecryptfs_open_lower_file(struct file **lower_file,
+			     struct dentry *lower_dentry,
+			     struct vfsmount *lower_mnt, int flags);
+int ecryptfs_close_lower_file(struct file *lower_file);
 
 #endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index c8550c9..a92ef05 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -198,6 +198,33 @@
 
 struct kmem_cache *ecryptfs_file_info_cache;
 
+int ecryptfs_open_lower_file(struct file **lower_file,
+			     struct dentry *lower_dentry,
+			     struct vfsmount *lower_mnt, int flags)
+{
+	int rc = 0;
+
+	dget(lower_dentry);
+	mntget(lower_mnt);
+	*lower_file = dentry_open(lower_dentry, lower_mnt, flags);
+	if (IS_ERR(*lower_file)) {
+		printk(KERN_ERR "Error opening lower file for lower_dentry "
+		       "[0x%p], lower_mnt [0x%p], and flags [0x%x]\n",
+		       lower_dentry, lower_mnt, flags);
+		rc = PTR_ERR(*lower_file);
+		*lower_file = NULL;
+		goto out;
+	}
+out:
+	return rc;
+}
+
+int ecryptfs_close_lower_file(struct file *lower_file)
+{
+	fput(lower_file);
+	return 0;
+}
+
 /**
  * ecryptfs_open
  * @inode: inode speciying file to open
@@ -244,19 +271,15 @@
 		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
 	}
 	mutex_unlock(&crypt_stat->cs_mutex);
-	/* This mntget & dget is undone via fput when the file is released */
-	dget(lower_dentry);
 	lower_flags = file->f_flags;
 	if ((lower_flags & O_ACCMODE) == O_WRONLY)
 		lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
 	if (file->f_flags & O_APPEND)
 		lower_flags &= ~O_APPEND;
 	lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
-	mntget(lower_mnt);
 	/* Corresponding fput() in ecryptfs_release() */
-	lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags);
-	if (IS_ERR(lower_file)) {
-		rc = PTR_ERR(lower_file);
+	if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
+					   lower_flags))) {
 		ecryptfs_printk(KERN_ERR, "Error opening lower file\n");
 		goto out_puts;
 	}
@@ -341,11 +364,16 @@
 	struct file *lower_file = ecryptfs_file_to_lower(file);
 	struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file);
 	struct inode *lower_inode = ecryptfs_inode_to_lower(inode);
+	int rc;
 
-	fput(lower_file);
+	if ((rc = ecryptfs_close_lower_file(lower_file))) {
+		printk(KERN_ERR "Error closing lower_file\n");
+		goto out;
+	}
 	inode->i_blocks = lower_inode->i_blocks;
 	kmem_cache_free(ecryptfs_file_info_cache, file_info);
-	return 0;
+out:
+	return rc;
 }
 
 static int
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index efdd2b7..dfcc684 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -231,7 +231,6 @@
 	int lower_flags;
 	struct ecryptfs_crypt_stat *crypt_stat;
 	struct dentry *lower_dentry;
-	struct dentry *tlower_dentry = NULL;
 	struct file *lower_file;
 	struct inode *inode, *lower_inode;
 	struct vfsmount *lower_mnt;
@@ -241,30 +240,19 @@
 			lower_dentry->d_name.name);
 	inode = ecryptfs_dentry->d_inode;
 	crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
-	tlower_dentry = dget(lower_dentry);
-	if (!tlower_dentry) {
-		rc = -ENOMEM;
-		ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n");
-		goto out;
-	}
 	lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR;
 #if BITS_PER_LONG != 32
 	lower_flags |= O_LARGEFILE;
 #endif
 	lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
-	mntget(lower_mnt);
 	/* Corresponding fput() at end of this function */
-	lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags);
-	if (IS_ERR(lower_file)) {
-		rc = PTR_ERR(lower_file);
+	if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
+					   lower_flags))) {
 		ecryptfs_printk(KERN_ERR,
 				"Error opening dentry; rc = [%i]\n", rc);
 		goto out;
 	}
-	/* fput(lower_file) should handle the puts if we do this */
-	lower_file->f_dentry = tlower_dentry;
-	lower_file->f_vfsmnt = lower_mnt;
-	lower_inode = tlower_dentry->d_inode;
+	lower_inode = lower_dentry->d_inode;
 	if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
 		ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
 		ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
@@ -285,7 +273,8 @@
 	}
 	rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode);
 out_fput:
-	fput(lower_file);
+	if ((rc = ecryptfs_close_lower_file(lower_file)))
+		printk(KERN_ERR "Error closing lower_file\n");
 out:
 	return rc;
 }
@@ -336,7 +325,6 @@
 	struct dentry *lower_dir_dentry;
 	struct dentry *lower_dentry;
 	struct vfsmount *lower_mnt;
-	struct dentry *tlower_dentry = NULL;
 	char *encoded_name;
 	unsigned int encoded_namelen;
 	struct ecryptfs_crypt_stat *crypt_stat = NULL;
@@ -347,27 +335,32 @@
 	lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
 	dentry->d_op = &ecryptfs_dops;
 	if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, "."))
-	    || (dentry->d_name.len == 2 && !strcmp(dentry->d_name.name, "..")))
-		goto out_drop;
+	    || (dentry->d_name.len == 2
+		&& !strcmp(dentry->d_name.name, ".."))) {
+		d_drop(dentry);
+		goto out;
+	}
 	encoded_namelen = ecryptfs_encode_filename(crypt_stat,
 						   dentry->d_name.name,
 						   dentry->d_name.len,
 						   &encoded_name);
 	if (encoded_namelen < 0) {
 		rc = encoded_namelen;
-		goto out_drop;
+		d_drop(dentry);
+		goto out;
 	}
 	ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen "
 			"= [%d]\n", encoded_name, encoded_namelen);
 	lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry,
 				      encoded_namelen - 1);
 	kfree(encoded_name);
-	lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
 	if (IS_ERR(lower_dentry)) {
 		ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n");
 		rc = PTR_ERR(lower_dentry);
-		goto out_drop;
+		d_drop(dentry);
+		goto out;
 	}
+	lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
 	ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->"
        		"d_name.name = [%s]\n", lower_dentry,
 		lower_dentry->d_name.name);
@@ -408,12 +401,6 @@
 				"as we *think* we are about to unlink\n");
 		goto out;
 	}
-	tlower_dentry = dget(lower_dentry);
-	if (!tlower_dentry || IS_ERR(tlower_dentry)) {
-		rc = -ENOMEM;
-		ecryptfs_printk(KERN_ERR, "Cannot dget lower_dentry\n");
-		goto out_dput;
-	}
 	/* Released in this function */
 	page_virt =
 	    (char *)kmem_cache_alloc(ecryptfs_header_cache_2,
@@ -425,7 +412,7 @@
 		goto out_dput;
 	}
 	memset(page_virt, 0, PAGE_CACHE_SIZE);
-	rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt);
+	rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt);
 	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
 	if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED))
 		ecryptfs_set_default_sizes(crypt_stat);
@@ -448,9 +435,6 @@
 
 out_dput:
 	dput(lower_dentry);
-	if (tlower_dentry)
-		dput(tlower_dentry);
-out_drop:
 	d_drop(dentry);
 out:
 	return ERR_PTR(rc);
@@ -486,8 +470,9 @@
 	unlock_dir(lower_dir_dentry);
 	dput(lower_new_dentry);
 	dput(lower_old_dentry);
-	if (!new_dentry->d_inode)
-		d_drop(new_dentry);
+	d_drop(lower_old_dentry);
+	d_drop(new_dentry);
+	d_drop(old_dentry);
 	return rc;
 }
 
@@ -500,7 +485,7 @@
 	lock_parent(lower_dentry);
 	rc = vfs_unlink(lower_dir_inode, lower_dentry);
 	if (rc) {
-		ecryptfs_printk(KERN_ERR, "Error in vfs_unlink\n");
+		printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
 		goto out_unlock;
 	}
 	ecryptfs_copy_attr_times(dir, lower_dir_inode);
@@ -576,41 +561,24 @@
 
 static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
 {
-	int rc = 0;
-	struct dentry *tdentry = NULL;
 	struct dentry *lower_dentry;
-	struct dentry *tlower_dentry = NULL;
 	struct dentry *lower_dir_dentry;
+	int rc;
 
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
-	if (!(tdentry = dget(dentry))) {
-		rc = -EINVAL;
-		ecryptfs_printk(KERN_ERR, "Error dget'ing dentry [%p]\n",
-				dentry);
-		goto out;
-	}
+	dget(dentry);
 	lower_dir_dentry = lock_parent(lower_dentry);
-	if (!(tlower_dentry = dget(lower_dentry))) {
-		rc = -EINVAL;
-		ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry "
-				"[%p]\n", lower_dentry);
-		goto out;
-	}
+	dget(lower_dentry);
 	rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
-	if (!rc) {
-		d_delete(tlower_dentry);
-		tlower_dentry = NULL;
-	}
+	dput(lower_dentry);
+	if (!rc)
+		d_delete(lower_dentry);
 	ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode);
 	dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
 	unlock_dir(lower_dir_dentry);
 	if (!rc)
 		d_drop(dentry);
-out:
-	if (tdentry)
-		dput(tdentry);
-	if (tlower_dentry)
-		dput(tlower_dentry);
+	dput(dentry);
 	return rc;
 }
 
@@ -663,6 +631,8 @@
 		ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
 out_lock:
 	unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+	dput(lower_new_dentry->d_parent);
+	dput(lower_old_dentry->d_parent);
 	dput(lower_new_dentry);
 	dput(lower_old_dentry);
 	return rc;
@@ -832,12 +802,11 @@
 	}
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	/* This dget & mntget is released through fput at out_fput: */
-	dget(lower_dentry);
 	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
-	mntget(lower_mnt);
-	lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR);
-	if (unlikely(IS_ERR(lower_file))) {
-		rc = PTR_ERR(lower_file);
+	if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
+					   O_RDWR))) {
+		ecryptfs_printk(KERN_ERR,
+				"Error opening dentry; rc = [%i]\n", rc);
 		goto out_free;
 	}
 	ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file);
@@ -879,7 +848,8 @@
 		= CURRENT_TIME;
 	mark_inode_dirty_sync(inode);
 out_fput:
-	fput(lower_file);
+	if ((rc = ecryptfs_close_lower_file(lower_file)))
+		printk(KERN_ERR "Error closing lower_file\n");
 out_free:
 	if (ecryptfs_file_to_private(&fake_ecryptfs_file))
 		kmem_cache_free(ecryptfs_file_info_cache,
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index ba45478..c3746f5 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -458,14 +458,16 @@
 static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
 			       struct ecryptfs_crypt_stat *crypt_stat)
 {
-	int rc = 0;
 	struct ecryptfs_password *password_s_ptr;
-	struct crypto_tfm *tfm = NULL;
 	struct scatterlist src_sg[2], dst_sg[2];
 	struct mutex *tfm_mutex = NULL;
 	/* TODO: Use virt_to_scatterlist for these */
 	char *encrypted_session_key;
 	char *session_key;
+	struct blkcipher_desc desc = {
+		.flags = CRYPTO_TFM_REQ_MAY_SLEEP
+	};
+	int rc = 0;
 
 	password_s_ptr = &auth_tok->token.password;
 	if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags,
@@ -482,30 +484,37 @@
 	if (!strcmp(crypt_stat->cipher,
 		    crypt_stat->mount_crypt_stat->global_default_cipher_name)
 	    && crypt_stat->mount_crypt_stat->global_key_tfm) {
-		tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+		desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
 		tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
 	} else {
-		tfm = crypto_alloc_tfm(crypt_stat->cipher,
-				       CRYPTO_TFM_REQ_WEAK_KEY);
-		if (!tfm) {
-			printk(KERN_ERR "Error allocating crypto context\n");
-			rc = -ENOMEM;
+		char *full_alg_name;
+
+		rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
+							    crypt_stat->cipher,
+							    "ecb");
+		if (rc)
+			goto out;
+		desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
+						  CRYPTO_ALG_ASYNC);
+		kfree(full_alg_name);
+		if (IS_ERR(desc.tfm)) {
+			rc = PTR_ERR(desc.tfm);
+			printk(KERN_ERR "Error allocating crypto context; "
+			       "rc = [%d]\n", rc);
 			goto out;
 		}
-	}
-	if (password_s_ptr->session_key_encryption_key_bytes
-	    < crypto_tfm_alg_min_keysize(tfm)) {
-		printk(KERN_WARNING "Session key encryption key is [%d] bytes; "
-		       "minimum keysize for selected cipher is [%d] bytes.\n",
-		       password_s_ptr->session_key_encryption_key_bytes,
-		       crypto_tfm_alg_min_keysize(tfm));
-		rc = -EINVAL;
-		goto out;
+		crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
 	}
 	if (tfm_mutex)
 		mutex_lock(tfm_mutex);
-	crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key,
-			     crypt_stat->key_size);
+	rc = crypto_blkcipher_setkey(desc.tfm,
+				     password_s_ptr->session_key_encryption_key,
+				     crypt_stat->key_size);
+	if (rc < 0) {
+		printk(KERN_ERR "Error setting key for crypto context\n");
+		rc = -EINVAL;
+		goto out_free_tfm;
+	}
 	/* TODO: virt_to_scatterlist */
 	encrypted_session_key = (char *)__get_free_page(GFP_KERNEL);
 	if (!encrypted_session_key) {
@@ -531,9 +540,12 @@
 	auth_tok->session_key.decrypted_key_size =
 	    auth_tok->session_key.encrypted_key_size;
 	dst_sg[0].length = auth_tok->session_key.encrypted_key_size;
-	/* TODO: Handle error condition */
-	crypto_cipher_decrypt(tfm, dst_sg, src_sg,
-			      auth_tok->session_key.encrypted_key_size);
+	rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg,
+				      auth_tok->session_key.encrypted_key_size);
+	if (rc) {
+		printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc);
+		goto out_free_memory;
+	}
 	auth_tok->session_key.decrypted_key_size =
 	    auth_tok->session_key.encrypted_key_size;
 	memcpy(auth_tok->session_key.decrypted_key, session_key,
@@ -546,6 +558,7 @@
 	if (ecryptfs_verbosity > 0)
 		ecryptfs_dump_hex(crypt_stat->key,
 				  crypt_stat->key_size);
+out_free_memory:
 	memset(encrypted_session_key, 0, PAGE_CACHE_SIZE);
 	free_page((unsigned long)encrypted_session_key);
 	memset(session_key, 0, PAGE_CACHE_SIZE);
@@ -554,7 +567,7 @@
 	if (tfm_mutex)
 		mutex_unlock(tfm_mutex);
 	else
-		crypto_free_tfm(tfm);
+		crypto_free_blkcipher(desc.tfm);
 out:
 	return rc;
 }
@@ -803,19 +816,21 @@
 		   struct ecryptfs_crypt_stat *crypt_stat,
 		   struct ecryptfs_key_record *key_rec, size_t *packet_size)
 {
-	int rc = 0;
-
 	size_t i;
 	size_t signature_is_valid = 0;
 	size_t encrypted_session_key_valid = 0;
 	char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
 	struct scatterlist dest_sg[2];
 	struct scatterlist src_sg[2];
-	struct crypto_tfm *tfm = NULL;
 	struct mutex *tfm_mutex = NULL;
 	size_t key_rec_size;
 	size_t packet_size_length;
 	size_t cipher_code;
+	struct blkcipher_desc desc = {
+		.tfm = NULL,
+		.flags = CRYPTO_TFM_REQ_MAY_SLEEP
+	};
+	int rc = 0;
 
 	(*packet_size) = 0;
 	/* Check for a valid signature on the auth_tok */
@@ -882,33 +897,48 @@
 	if (!strcmp(crypt_stat->cipher,
 		    crypt_stat->mount_crypt_stat->global_default_cipher_name)
 	    && crypt_stat->mount_crypt_stat->global_key_tfm) {
-		tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+		desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
 		tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
-	} else
-		tfm = crypto_alloc_tfm(crypt_stat->cipher, 0);
-	if (!tfm) {
-		ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
-				"context for cipher [%s]\n",
-				crypt_stat->cipher);
-		rc = -EINVAL;
-		goto out;
+	} else {
+		char *full_alg_name;
+
+		rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
+							    crypt_stat->cipher,
+							    "ecb");
+		if (rc)
+			goto out;
+		desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
+						  CRYPTO_ALG_ASYNC);
+		kfree(full_alg_name);
+		if (IS_ERR(desc.tfm)) {
+			rc = PTR_ERR(desc.tfm);
+			ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
+					"context for cipher [%s]; rc = [%d]\n",
+					crypt_stat->cipher, rc);
+			goto out;
+		}
+		crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
 	}
 	if (tfm_mutex)
 		mutex_lock(tfm_mutex);
-	rc = crypto_cipher_setkey(tfm, session_key_encryption_key,
-				  crypt_stat->key_size);
+	rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key,
+				     crypt_stat->key_size);
 	if (rc < 0) {
 		if (tfm_mutex)
 			mutex_unlock(tfm_mutex);
 		ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
-				"context\n");
+				"context; rc = [%d]\n", rc);
 		goto out;
 	}
 	rc = 0;
 	ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
 			crypt_stat->key_size);
-	crypto_cipher_encrypt(tfm, dest_sg, src_sg,
-			      (*key_rec).enc_key_size);
+	rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg,
+				      (*key_rec).enc_key_size);
+	if (rc) {
+		printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc);
+		goto out;
+	}
 	if (tfm_mutex)
 		mutex_unlock(tfm_mutex);
 	ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
@@ -971,8 +1001,8 @@
 	       (*key_rec).enc_key_size);
 	(*packet_size) += (*key_rec).enc_key_size;
 out:
-	if (tfm && !tfm_mutex)
-		crypto_free_tfm(tfm);
+	if (desc.tfm && !tfm_mutex)
+		crypto_free_blkcipher(desc.tfm);
 	if (rc)
 		(*packet_size) = 0;
 	return rc;
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 5938a23..a78d87d 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -208,7 +208,6 @@
 	char *cipher_name_dst;
 	char *cipher_name_src;
 	char *cipher_key_bytes_src;
-	struct crypto_tfm *tmp_tfm;
 	int cipher_name_len;
 
 	if (!options) {
@@ -305,25 +304,19 @@
 		    = '\0';
 	}
 	if (!cipher_key_bytes_set) {
-		mount_crypt_stat->global_default_cipher_key_size =
-			ECRYPTFS_DEFAULT_KEY_BYTES;
-		ecryptfs_printk(KERN_DEBUG, "Cipher key size was not "
-				"specified.  Defaulting to [%d]\n",
-				mount_crypt_stat->
-				global_default_cipher_key_size);
+		mount_crypt_stat->global_default_cipher_key_size = 0;
 	}
 	rc = ecryptfs_process_cipher(
-		&tmp_tfm,
 		&mount_crypt_stat->global_key_tfm,
 		mount_crypt_stat->global_default_cipher_name,
-		mount_crypt_stat->global_default_cipher_key_size);
-	if (tmp_tfm)
-		crypto_free_tfm(tmp_tfm);
+		&mount_crypt_stat->global_default_cipher_key_size);
 	if (rc) {
 		printk(KERN_ERR "Error attempting to initialize cipher [%s] "
 		       "with key size [%Zd] bytes; rc = [%d]\n",
 		       mount_crypt_stat->global_default_cipher_name,
 		       mount_crypt_stat->global_default_cipher_key_size, rc);
+		mount_crypt_stat->global_key_tfm = NULL;
+		mount_crypt_stat->global_auth_tok_key = NULL;
 		rc = -EINVAL;
 		goto out;
 	}
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index c337c04..825757a 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -138,23 +138,6 @@
 }
 
 /**
- * ecryptfs_umount_begin
- *
- * Called in do_umount().
- */
-static void ecryptfs_umount_begin(struct vfsmount *vfsmnt, int flags)
-{
-	struct vfsmount *lower_mnt =
-		ecryptfs_dentry_to_lower_mnt(vfsmnt->mnt_sb->s_root);
-	struct super_block *lower_sb;
-
-	mntput(lower_mnt);
-	lower_sb = lower_mnt->mnt_sb;
-	if (lower_sb->s_op->umount_begin)
-		lower_sb->s_op->umount_begin(lower_mnt, flags);
-}
-
-/**
  * ecryptfs_show_options
  *
  * Prints the directory we are currently mounted over.
@@ -193,6 +176,5 @@
 	.statfs = ecryptfs_statfs,
 	.remount_fs = NULL,
 	.clear_inode = ecryptfs_clear_inode,
-	.umount_begin = ecryptfs_umount_begin,
 	.show_options = ecryptfs_show_options
 };
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 1e95780..4fe49c3 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -69,44 +69,49 @@
 	else if (outside(input->block_bitmap, start, end))
 		ext4_warning(sb, __FUNCTION__,
 			     "Block bitmap not in group (block %llu)",
-			     input->block_bitmap);
+			     (unsigned long long)input->block_bitmap);
 	else if (outside(input->inode_bitmap, start, end))
 		ext4_warning(sb, __FUNCTION__,
 			     "Inode bitmap not in group (block %llu)",
-			     input->inode_bitmap);
+			     (unsigned long long)input->inode_bitmap);
 	else if (outside(input->inode_table, start, end) ||
 	         outside(itend - 1, start, end))
 		ext4_warning(sb, __FUNCTION__,
 			     "Inode table not in group (blocks %llu-%llu)",
-			     input->inode_table, itend - 1);
+			     (unsigned long long)input->inode_table, itend - 1);
 	else if (input->inode_bitmap == input->block_bitmap)
 		ext4_warning(sb, __FUNCTION__,
 			     "Block bitmap same as inode bitmap (%llu)",
-			     input->block_bitmap);
+			     (unsigned long long)input->block_bitmap);
 	else if (inside(input->block_bitmap, input->inode_table, itend))
 		ext4_warning(sb, __FUNCTION__,
 			     "Block bitmap (%llu) in inode table (%llu-%llu)",
-			     input->block_bitmap, input->inode_table, itend-1);
+			     (unsigned long long)input->block_bitmap,
+			     (unsigned long long)input->inode_table, itend - 1);
 	else if (inside(input->inode_bitmap, input->inode_table, itend))
 		ext4_warning(sb, __FUNCTION__,
 			     "Inode bitmap (%llu) in inode table (%llu-%llu)",
-			     input->inode_bitmap, input->inode_table, itend-1);
+			     (unsigned long long)input->inode_bitmap,
+			     (unsigned long long)input->inode_table, itend - 1);
 	else if (inside(input->block_bitmap, start, metaend))
 		ext4_warning(sb, __FUNCTION__,
 			     "Block bitmap (%llu) in GDT table"
 			     " (%llu-%llu)",
-			     input->block_bitmap, start, metaend - 1);
+			     (unsigned long long)input->block_bitmap,
+			     start, metaend - 1);
 	else if (inside(input->inode_bitmap, start, metaend))
 		ext4_warning(sb, __FUNCTION__,
 			     "Inode bitmap (%llu) in GDT table"
 			     " (%llu-%llu)",
-			     input->inode_bitmap, start, metaend - 1);
+			     (unsigned long long)input->inode_bitmap,
+			     start, metaend - 1);
 	else if (inside(input->inode_table, start, metaend) ||
 	         inside(itend - 1, start, metaend))
 		ext4_warning(sb, __FUNCTION__,
 			     "Inode table (%llu-%llu) overlaps"
 			     "GDT table (%llu-%llu)",
-			     input->inode_table, itend - 1, start, metaend - 1);
+			     (unsigned long long)input->inode_table,
+			     itend - 1, start, metaend - 1);
 	else
 		err = 0;
 	brelse(bh);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 8337451..0aa813d 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -303,7 +303,17 @@
 	fat_flush_inodes(inode->i_sb, inode, NULL);
 }
 
+int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+	struct inode *inode = dentry->d_inode;
+	generic_fillattr(inode, stat);
+	stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fat_getattr);
+
 struct inode_operations fat_file_inode_operations = {
 	.truncate	= fat_truncate,
 	.setattr	= fat_notify_change,
+	.getattr	= fat_getattr,
 };
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index cfc8f81..c71a6c0 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -138,6 +138,7 @@
 		struct fuse_entry_out outarg;
 		struct fuse_conn *fc;
 		struct fuse_req *req;
+		struct fuse_req *forget_req;
 		struct dentry *parent;
 
 		/* Doesn't hurt to "reset" the validity timeout */
@@ -152,25 +153,33 @@
 		if (IS_ERR(req))
 			return 0;
 
+		forget_req = fuse_get_req(fc);
+		if (IS_ERR(forget_req)) {
+			fuse_put_request(fc, req);
+			return 0;
+		}
+
 		parent = dget_parent(entry);
 		fuse_lookup_init(req, parent->d_inode, entry, &outarg);
 		request_send(fc, req);
 		dput(parent);
 		err = req->out.h.error;
+		fuse_put_request(fc, req);
 		/* Zero nodeid is same as -ENOENT */
 		if (!err && !outarg.nodeid)
 			err = -ENOENT;
 		if (!err) {
 			struct fuse_inode *fi = get_fuse_inode(inode);
 			if (outarg.nodeid != get_node_id(inode)) {
-				fuse_send_forget(fc, req, outarg.nodeid, 1);
+				fuse_send_forget(fc, forget_req,
+						 outarg.nodeid, 1);
 				return 0;
 			}
 			spin_lock(&fc->lock);
 			fi->nlookup ++;
 			spin_unlock(&fc->lock);
 		}
-		fuse_put_request(fc, req);
+		fuse_put_request(fc, forget_req);
 		if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
 			return 0;
 
@@ -221,6 +230,7 @@
 	struct inode *inode = NULL;
 	struct fuse_conn *fc = get_fuse_conn(dir);
 	struct fuse_req *req;
+	struct fuse_req *forget_req;
 
 	if (entry->d_name.len > FUSE_NAME_MAX)
 		return ERR_PTR(-ENAMETOOLONG);
@@ -229,9 +239,16 @@
 	if (IS_ERR(req))
 		return ERR_PTR(PTR_ERR(req));
 
+	forget_req = fuse_get_req(fc);
+	if (IS_ERR(forget_req)) {
+		fuse_put_request(fc, req);
+		return ERR_PTR(PTR_ERR(forget_req));
+	}
+
 	fuse_lookup_init(req, dir, entry, &outarg);
 	request_send(fc, req);
 	err = req->out.h.error;
+	fuse_put_request(fc, req);
 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
 	if (!err && outarg.nodeid &&
 	    (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode)))
@@ -240,11 +257,11 @@
 		inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
 				  &outarg.attr);
 		if (!inode) {
-			fuse_send_forget(fc, req, outarg.nodeid, 1);
+			fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
 			return ERR_PTR(-ENOMEM);
 		}
 	}
-	fuse_put_request(fc, req);
+	fuse_put_request(fc, forget_req);
 	if (err && err != -ENOENT)
 		return ERR_PTR(err);
 
@@ -388,6 +405,13 @@
 	struct fuse_entry_out outarg;
 	struct inode *inode;
 	int err;
+	struct fuse_req *forget_req;
+
+	forget_req = fuse_get_req(fc);
+	if (IS_ERR(forget_req)) {
+		fuse_put_request(fc, req);
+		return PTR_ERR(forget_req);
+	}
 
 	req->in.h.nodeid = get_node_id(dir);
 	req->out.numargs = 1;
@@ -395,24 +419,24 @@
 	req->out.args[0].value = &outarg;
 	request_send(fc, req);
 	err = req->out.h.error;
-	if (err) {
-		fuse_put_request(fc, req);
-		return err;
-	}
+	fuse_put_request(fc, req);
+	if (err)
+		goto out_put_forget_req;
+
 	err = -EIO;
 	if (invalid_nodeid(outarg.nodeid))
-		goto out_put_request;
+		goto out_put_forget_req;
 
 	if ((outarg.attr.mode ^ mode) & S_IFMT)
-		goto out_put_request;
+		goto out_put_forget_req;
 
 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
 			  &outarg.attr);
 	if (!inode) {
-		fuse_send_forget(fc, req, outarg.nodeid, 1);
+		fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
 		return -ENOMEM;
 	}
-	fuse_put_request(fc, req);
+	fuse_put_request(fc, forget_req);
 
 	if (S_ISDIR(inode->i_mode)) {
 		struct dentry *alias;
@@ -434,8 +458,8 @@
 	fuse_invalidate_attr(dir);
 	return 0;
 
- out_put_request:
-	fuse_put_request(fc, req);
+ out_put_forget_req:
+	fuse_put_request(fc, forget_req);
 	return err;
 }
 
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 2bb5ace..763a50d 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -397,14 +397,14 @@
 
 	err = -EIO;
 	if (is_bad_inode(inode))
-		goto clean_pages_up;
+		goto out;
 
 	data.file = file;
 	data.inode = inode;
 	data.req = fuse_get_req(fc);
 	err = PTR_ERR(data.req);
 	if (IS_ERR(data.req))
-		goto clean_pages_up;
+		goto out;
 
 	err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
 	if (!err) {
@@ -413,10 +413,7 @@
 		else
 			fuse_put_request(fc, data.req);
 	}
-	return err;
-
-clean_pages_up:
-	put_pages_list(pages);
+out:
 	return err;
 }
 
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 57c43ac..d470e52 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -157,6 +157,9 @@
 	struct gfs2_glock *io_gl;
 	int error;
 
+	if (!inode)
+		return ERR_PTR(-ENOBUFS);
+
 	if (inode->i_state & I_NEW) {
 		struct gfs2_sbd *sdp = GFS2_SB(inode);
 		umode_t mode = DT2IF(type);
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 21508a1..9889c1e 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -84,8 +84,8 @@
 
 	gfs2_inode_cachep = kmem_cache_create("gfs2_inode",
 					      sizeof(struct gfs2_inode),
-					      0, (SLAB_RECLAIM_ACCOUNT|
-					      SLAB_PANIC|SLAB_MEM_SPREAD),
+					      0,  SLAB_RECLAIM_ACCOUNT|
+					          SLAB_MEM_SPREAD,
 					      gfs2_init_inode_once, NULL);
 	if (!gfs2_inode_cachep)
 		goto fail;
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 8d5963c..015640b 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -337,13 +337,6 @@
 out_noerror:
 	ret = 0;
 out_unlock:
-	/* unlock all pages, we can't do any I/O right now */
-	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
-		struct page *page = list_entry(pages->prev, struct page, lru);
-		list_del(&page->lru);
-		unlock_page(page);
-		page_cache_release(page);
-	}
 	if (do_unlock)
 		gfs2_holder_uninit(&gh);
 	goto out;
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 06f06f7..b47d959 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -138,16 +138,27 @@
 }
 
 /**
- * gfs2_write_super - disk commit all incore transactions
- * @sb: the filesystem
+ * gfs2_write_super
+ * @sb: the superblock
  *
- * This function is called every time sync(2) is called.
- * After this exits, all dirty buffers are synced.
  */
 
 static void gfs2_write_super(struct super_block *sb)
 {
+	sb->s_dirt = 0;
+}
+
+/**
+ * gfs2_sync_fs - sync the filesystem
+ * @sb: the superblock
+ *
+ * Flushes the log to disk.
+ */
+static int gfs2_sync_fs(struct super_block *sb, int wait)
+{
+	sb->s_dirt = 0;
 	gfs2_log_flush(sb->s_fs_info, NULL);
+	return 0;
 }
 
 /**
@@ -452,17 +463,18 @@
 }
 
 struct super_operations gfs2_super_ops = {
-	.alloc_inode = gfs2_alloc_inode,
-	.destroy_inode = gfs2_destroy_inode,
-	.write_inode = gfs2_write_inode,
-	.delete_inode = gfs2_delete_inode,
-	.put_super = gfs2_put_super,
-	.write_super = gfs2_write_super,
-	.write_super_lockfs = gfs2_write_super_lockfs,
-	.unlockfs = gfs2_unlockfs,
-	.statfs = gfs2_statfs,
-	.remount_fs = gfs2_remount_fs,
-	.clear_inode = gfs2_clear_inode,
-	.show_options = gfs2_show_options,
+	.alloc_inode		= gfs2_alloc_inode,
+	.destroy_inode		= gfs2_destroy_inode,
+	.write_inode		= gfs2_write_inode,
+	.delete_inode		= gfs2_delete_inode,
+	.put_super		= gfs2_put_super,
+	.write_super		= gfs2_write_super,
+	.sync_fs		= gfs2_sync_fs,
+	.write_super_lockfs 	= gfs2_write_super_lockfs,
+	.unlockfs		= gfs2_unlockfs,
+	.statfs			= gfs2_statfs,
+	.remount_fs		= gfs2_remount_fs,
+	.clear_inode		= gfs2_clear_inode,
+	.show_options		= gfs2_show_options,
 };
 
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index d43b4fc..85b17b3 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -390,11 +390,13 @@
 		hfs_find_exit(&fd);
 		goto bail_no_root;
 	}
+	res = -EINVAL;
 	root_inode = hfs_iget(sb, &fd.search_key->cat, &rec);
 	hfs_find_exit(&fd);
 	if (!root_inode)
 		goto bail_no_root;
 
+	res = -ENOMEM;
 	sb->s_root = d_alloc_root(root_inode);
 	if (!sb->s_root)
 		goto bail_iput;
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 4ee3f00..7f47569 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -62,24 +62,19 @@
 	loff_t len, vma_len;
 	int ret;
 
-	if (vma->vm_pgoff & (HPAGE_SIZE / PAGE_SIZE - 1))
-		return -EINVAL;
-
-	if (vma->vm_start & ~HPAGE_MASK)
-		return -EINVAL;
-
-	if (vma->vm_end & ~HPAGE_MASK)
-		return -EINVAL;
-
-	if (vma->vm_end - vma->vm_start < HPAGE_SIZE)
-		return -EINVAL;
+	/*
+	 * vma alignment has already been checked by prepare_hugepage_range.
+	 * If you add any error returns here, do so after setting VM_HUGETLB,
+	 * so is_vm_hugetlb_page tests below unmap_region go the right way
+	 * when do_mmap_pgoff unwinds (may be important on powerpc and ia64).
+	 */
+	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
+	vma->vm_ops = &hugetlb_vm_ops;
 
 	vma_len = (loff_t)(vma->vm_end - vma->vm_start);
 
 	mutex_lock(&inode->i_mutex);
 	file_accessed(file);
-	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
-	vma->vm_ops = &hugetlb_vm_ops;
 
 	ret = -ENOMEM;
 	len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
@@ -271,26 +266,24 @@
 		hugetlbfs_forget_inode(inode);
 }
 
-/*
- * h_pgoff is in HPAGE_SIZE units.
- * vma->vm_pgoff is in PAGE_SIZE units.
- */
 static inline void
-hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
+hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff)
 {
 	struct vm_area_struct *vma;
 	struct prio_tree_iter iter;
 
-	vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) {
-		unsigned long h_vm_pgoff;
+	vma_prio_tree_foreach(vma, &iter, root, pgoff, ULONG_MAX) {
 		unsigned long v_offset;
 
-		h_vm_pgoff = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT);
-		v_offset = (h_pgoff - h_vm_pgoff) << HPAGE_SHIFT;
 		/*
-		 * Is this VMA fully outside the truncation point?
+		 * Can the expression below overflow on 32-bit arches?
+		 * No, because the prio_tree returns us only those vmas
+		 * which overlap the truncated area starting at pgoff,
+		 * and no vma on a 32-bit arch can span beyond the 4GB.
 		 */
-		if (h_vm_pgoff >= h_pgoff)
+		if (vma->vm_pgoff < pgoff)
+			v_offset = (pgoff - vma->vm_pgoff) << PAGE_SHIFT;
+		else
 			v_offset = 0;
 
 		__unmap_hugepage_range(vma,
@@ -303,14 +296,14 @@
  */
 static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
 {
-	unsigned long pgoff;
+	pgoff_t pgoff;
 	struct address_space *mapping = inode->i_mapping;
 
 	if (offset > inode->i_size)
 		return -EINVAL;
 
 	BUG_ON(offset & ~HPAGE_MASK);
-	pgoff = offset >> HPAGE_SHIFT;
+	pgoff = offset >> PAGE_SHIFT;
 
 	inode->i_size = offset;
 	spin_lock(&mapping->i_mmap_lock);
@@ -624,7 +617,6 @@
 				do_div(size, 100);
 				rest++;
 			}
-			size &= HPAGE_MASK;
 			pconfig->nr_blocks = (size >> HPAGE_SHIFT);
 			value = rest;
 		} else if (!strcmp(opt,"nr_inodes")) {
diff --git a/fs/inode.c b/fs/inode.c
index d9a21d1..26cdb11 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1306,6 +1306,42 @@
 	wake_up_bit(&inode->i_state, __I_LOCK);
 }
 
+/*
+ * We rarely want to lock two inodes that do not have a parent/child
+ * relationship (such as directory, child inode) simultaneously. The
+ * vast majority of file systems should be able to get along fine
+ * without this. Do not use these functions except as a last resort.
+ */
+void inode_double_lock(struct inode *inode1, struct inode *inode2)
+{
+	if (inode1 == NULL || inode2 == NULL || inode1 == inode2) {
+		if (inode1)
+			mutex_lock(&inode1->i_mutex);
+		else if (inode2)
+			mutex_lock(&inode2->i_mutex);
+		return;
+	}
+
+	if (inode1 < inode2) {
+		mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT);
+		mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD);
+	} else {
+		mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
+		mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
+	}
+}
+EXPORT_SYMBOL(inode_double_lock);
+
+void inode_double_unlock(struct inode *inode1, struct inode *inode2)
+{
+	if (inode1)
+		mutex_unlock(&inode1->i_mutex);
+
+	if (inode2 && inode2 != inode1)
+		mutex_unlock(&inode2->i_mutex);
+}
+EXPORT_SYMBOL(inode_double_unlock);
+
 static __initdata unsigned long ihash_entries;
 static int __init set_ihash_entries(char *str)
 {
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index d5c6304..4f82bcd6 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -967,6 +967,13 @@
 	 */
 	jbd_lock_bh_state(bh);
 	spin_lock(&journal->j_list_lock);
+
+	/* Now that we have bh_state locked, are we really still mapped? */
+	if (!buffer_mapped(bh)) {
+		JBUFFER_TRACE(jh, "unmapped buffer, bailing out");
+		goto no_journal;
+	}
+
 	if (jh->b_transaction) {
 		JBUFFER_TRACE(jh, "has transaction");
 		if (jh->b_transaction != handle->h_transaction) {
@@ -1028,6 +1035,11 @@
 				sync_dirty_buffer(bh);
 				jbd_lock_bh_state(bh);
 				spin_lock(&journal->j_list_lock);
+				/* Since we dropped the lock... */
+				if (!buffer_mapped(bh)) {
+					JBUFFER_TRACE(jh, "buffer got unmapped");
+					goto no_journal;
+				}
 				/* The buffer may become locked again at any
 				   time if it is redirtied */
 			}
@@ -1824,6 +1836,7 @@
 			}
 		}
 	} else if (transaction == journal->j_committing_transaction) {
+		JBUFFER_TRACE(jh, "on committing transaction");
 		if (jh->b_jlist == BJ_Locked) {
 			/*
 			 * The buffer is on the committing transaction's locked
@@ -1838,7 +1851,6 @@
 		 * can remove it's next_transaction pointer from the
 		 * running transaction if that is set, but nothing
 		 * else. */
-		JBUFFER_TRACE(jh, "on committing transaction");
 		set_buffer_freed(bh);
 		if (jh->b_next_transaction) {
 			J_ASSERT(jh->b_next_transaction ==
@@ -1858,6 +1870,7 @@
 		 * i_size already for this truncate so recovery will not
 		 * expose the disk blocks we are discarding here.) */
 		J_ASSERT_JH(jh, transaction == journal->j_running_transaction);
+		JBUFFER_TRACE(jh, "on running transaction");
 		may_free = __dispose_buffer(jh, transaction);
 	}
 
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index b6cf2be..c051a94 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -967,6 +967,13 @@
 	 */
 	jbd_lock_bh_state(bh);
 	spin_lock(&journal->j_list_lock);
+
+	/* Now that we have bh_state locked, are we really still mapped? */
+	if (!buffer_mapped(bh)) {
+		JBUFFER_TRACE(jh, "unmapped buffer, bailing out");
+		goto no_journal;
+	}
+
 	if (jh->b_transaction) {
 		JBUFFER_TRACE(jh, "has transaction");
 		if (jh->b_transaction != handle->h_transaction) {
@@ -1028,6 +1035,11 @@
 				sync_dirty_buffer(bh);
 				jbd_lock_bh_state(bh);
 				spin_lock(&journal->j_list_lock);
+				/* Since we dropped the lock... */
+				if (!buffer_mapped(bh)) {
+					JBUFFER_TRACE(jh, "buffer got unmapped");
+					goto no_journal;
+				}
 				/* The buffer may become locked again at any
 				   time if it is redirtied */
 			}
@@ -1824,6 +1836,7 @@
 			}
 		}
 	} else if (transaction == journal->j_committing_transaction) {
+		JBUFFER_TRACE(jh, "on committing transaction");
 		if (jh->b_jlist == BJ_Locked) {
 			/*
 			 * The buffer is on the committing transaction's locked
@@ -1838,7 +1851,6 @@
 		 * can remove it's next_transaction pointer from the
 		 * running transaction if that is set, but nothing
 		 * else. */
-		JBUFFER_TRACE(jh, "on committing transaction");
 		set_buffer_freed(bh);
 		if (jh->b_next_transaction) {
 			J_ASSERT(jh->b_next_transaction ==
@@ -1858,6 +1870,7 @@
 		 * i_size already for this truncate so recovery will not
 		 * expose the disk blocks we are discarding here.) */
 		J_ASSERT_JH(jh, transaction == journal->j_running_transaction);
+		JBUFFER_TRACE(jh, "on running transaction");
 		may_free = __dispose_buffer(jh, transaction);
 	}
 
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 34181b8..aa9132d 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -109,6 +109,8 @@
 	.aio_write	= generic_file_aio_write,
 	.mmap		= generic_file_mmap,
 	.sendfile	= generic_file_sendfile,
+	.splice_read	= generic_file_splice_read,
+	.splice_write	= generic_file_splice_write,
 	.fsync		= jfs_fsync,
 	.release	= jfs_release,
 	.ioctl		= jfs_ioctl,
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 489a3d6..ee9b473 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -318,7 +318,7 @@
 	struct inomap *imap;
 	int block_offset;
 	int inodes_left;
-	uint pageno;
+	unsigned long pageno;
 	int rel_inode;
 
 	jfs_info("diRead: ino = %ld", ip->i_ino);
@@ -606,7 +606,7 @@
 	int block_offset;
 	int inodes_left;
 	struct metapage *mp;
-	uint pageno;
+	unsigned long pageno;
 	int rel_inode;
 	int dioffset;
 	struct inode *ipimap;
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 4c7985e..b753ba2 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -756,6 +756,11 @@
 	return -EOPNOTSUPP;
 }
 
+/*
+ * Most of the permission checking is done by xattr_permission in the vfs.
+ * The local file system is responsible for handling the system.* namespace.
+ * We also need to verify that this is a namespace that we recognize.
+ */
 static int can_set_xattr(struct inode *inode, const char *name,
 			 const void *value, size_t value_len)
 {
@@ -771,10 +776,6 @@
 	    strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))
 		return -EOPNOTSUPP;
 
-	if (!S_ISREG(inode->i_mode) &&
-	    (!S_ISDIR(inode->i_mode) || inode->i_mode &S_ISVTX))
-		return -EPERM;
-
 	return 0;
 }
 
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 6341392..8ca1808 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -353,9 +353,6 @@
  * Sysctl parameters (same as module parameters, different interface).
  */
 
-/* Something that isn't CTL_ANY, CTL_NONE or a value that may clash. */
-#define CTL_UNNUMBERED		-2
-
 static ctl_table nlm_sysctls[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index b0f01b3..4524619 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -654,6 +654,7 @@
 	.rmdir		= msdos_rmdir,
 	.rename		= msdos_rename,
 	.setattr	= fat_notify_change,
+	.getattr	= fat_getattr,
 };
 
 static int msdos_fill_super(struct super_block *sb, void *data, int silent)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 4133ef5..b34cd16 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -935,8 +935,17 @@
 
 no_entry:
 	res = d_materialise_unique(dentry, inode);
-	if (res != NULL)
+	if (res != NULL) {
+		struct dentry *parent;
+		if (IS_ERR(res))
+			goto out_unlock;
+		/* Was a directory renamed! */
+		parent = dget_parent(res);
+		if (!IS_ROOT(parent))
+			nfs_mark_for_revalidate(parent->d_inode);
+		dput(parent);
 		dentry = res;
+	}
 	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 out_unlock:
@@ -1132,6 +1141,8 @@
 	alias = d_materialise_unique(dentry, inode);
 	if (alias != NULL) {
 		dput(dentry);
+		if (IS_ERR(alias))
+			return NULL;
 		dentry = alias;
 	}
 
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
index 2fe3403..3ea50ac 100644
--- a/fs/nfs/sysctl.c
+++ b/fs/nfs/sysctl.c
@@ -18,11 +18,6 @@
 static const int nfs_set_port_min = 0;
 static const int nfs_set_port_max = 65535;
 static struct ctl_table_header *nfs_callback_sysctl_table;
-/*
- * Something that isn't CTL_ANY, CTL_NONE or a value that may clash.
- * Use the same values as fs/lockd/svc.c
- */
-#define CTL_UNNUMBERED -2
 
 static ctl_table nfs_cb_sysctls[] = {
 #ifdef CONFIG_NFS_V4
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 64db601..7f5bad0 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -258,7 +258,7 @@
 	/* Now create the file and set attributes */
 	nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len,
 				attr, newfhp,
-				argp->createmode, argp->verf, NULL);
+				argp->createmode, argp->verf, NULL, NULL);
 
 	RETURN_STATUS(nfserr);
 }
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 0a7bbdc..50bc942 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -93,6 +93,7 @@
 {
 	struct svc_fh resfh;
 	__be32 status;
+	int created = 0;
 
 	fh_init(&resfh, NFS4_FHSIZE);
 	open->op_truncate = 0;
@@ -105,28 +106,27 @@
 		status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data,
 					open->op_fname.len, &open->op_iattr,
 					&resfh, open->op_createmode,
-					(u32 *)open->op_verf.data, &open->op_truncate);
-	}
-	else {
+					(u32 *)open->op_verf.data, &open->op_truncate, &created);
+	} else {
 		status = nfsd_lookup(rqstp, current_fh,
 				     open->op_fname.data, open->op_fname.len, &resfh);
 		fh_unlock(current_fh);
 	}
+	if (status)
+		goto out;
 
-	if (!status) {
-		set_change_info(&open->op_cinfo, current_fh);
+	set_change_info(&open->op_cinfo, current_fh);
 
-		/* set reply cache */
-		fh_dup2(current_fh, &resfh);
-		open->op_stateowner->so_replay.rp_openfh_len =
-			resfh.fh_handle.fh_size;
-		memcpy(open->op_stateowner->so_replay.rp_openfh,
-				&resfh.fh_handle.fh_base,
-				resfh.fh_handle.fh_size);
+	/* set reply cache */
+	fh_dup2(current_fh, &resfh);
+	open->op_stateowner->so_replay.rp_openfh_len = resfh.fh_handle.fh_size;
+	memcpy(open->op_stateowner->so_replay.rp_openfh,
+			&resfh.fh_handle.fh_base, resfh.fh_handle.fh_size);
 
+	if (!created)
 		status = do_open_permission(rqstp, current_fh, open, MAY_NOP);
-	}
 
+out:
 	fh_put(&resfh);
 	return status;
 }
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index e9d0770..81b8565 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -274,7 +274,7 @@
 	 * any regular files anyway, just in case the directory was created by
 	 * a kernel from the future.... */
 	nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
-	mutex_lock(&dir->d_inode->i_mutex);
+	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
 	status = vfs_rmdir(dir->d_inode, dentry);
 	mutex_unlock(&dir->d_inode->i_mutex);
 	return status;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index f21e917..bb4d926 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1177,7 +1177,7 @@
 	/*
 	 * Get the dir op function pointer.
 	 */
-	err = nfserr_perm;
+	err = 0;
 	switch (type) {
 	case S_IFREG:
 		host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
@@ -1237,7 +1237,7 @@
 nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
 		char *fname, int flen, struct iattr *iap,
 		struct svc_fh *resfhp, int createmode, u32 *verifier,
-	        int *truncp)
+	        int *truncp, int *created)
 {
 	struct dentry	*dentry, *dchild = NULL;
 	struct inode	*dirp;
@@ -1331,6 +1331,8 @@
 	host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
 	if (host_err < 0)
 		goto out_nfserr;
+	if (created)
+		*created = 1;
 
 	if (EX_ISSYNC(fhp->fh_export)) {
 		err = nfserrno(nfsd_sync_dir(dentry));
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 8df27401..795319c 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -442,7 +442,8 @@
 
 		if (task) {
 			task_lock(task);
-			namespace = task->nsproxy->namespace;
+			if (task->nsproxy)
+				namespace = task->nsproxy->namespace;
 			if (namespace)
 				get_namespace(namespace);
 			task_unlock(task);
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index b67ce935..ac14318 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -74,7 +74,8 @@
 			igrab(inode);
 			reiserfs_warning(inode->i_sb,
 					 "pinning inode %lu because the "
-					 "preallocation can't be freed");
+					 "preallocation can't be freed",
+					 inode->i_ino);
 			goto out;
 		}
 	}
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 9041802..1724999 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1619,6 +1619,7 @@
 		      "jmacd-8: reiserfs_fill_super: unable to read bitmap");
 		goto error;
 	}
+	errval = -EINVAL;
 #ifdef CONFIG_REISERFS_CHECK
 	SWARN(silent, s, "CONFIG_REISERFS_CHECK is set ON");
 	SWARN(silent, s, "- it is slow mode for debugging.");
diff --git a/fs/splice.c b/fs/splice.c
index a567010..da74583 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -74,7 +74,7 @@
 		wait_on_page_writeback(page);
 
 		if (PagePrivate(page))
-			try_to_release_page(page, mapping_gfp_mask(mapping));
+			try_to_release_page(page, GFP_KERNEL);
 
 		/*
 		 * If we succeeded in removing the mapping, set LRU flag
@@ -333,7 +333,7 @@
 				break;
 
 			error = add_to_page_cache_lru(page, mapping, index,
-					      mapping_gfp_mask(mapping));
+					      GFP_KERNEL);
 			if (unlikely(error)) {
 				page_cache_release(page);
 				if (error == -EEXIST)
@@ -557,7 +557,6 @@
 {
 	struct file *file = sd->file;
 	struct address_space *mapping = file->f_mapping;
-	gfp_t gfp_mask = mapping_gfp_mask(mapping);
 	unsigned int offset, this_len;
 	struct page *page;
 	pgoff_t index;
@@ -591,7 +590,7 @@
 			goto find_page;
 
 		page = buf->page;
-		if (add_to_page_cache(page, mapping, index, gfp_mask)) {
+		if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) {
 			unlock_page(page);
 			goto find_page;
 		}
@@ -613,7 +612,7 @@
 			 * This will also lock the page
 			 */
 			ret = add_to_page_cache_lru(page, mapping, index,
-						    gfp_mask);
+						    GFP_KERNEL);
 			if (unlikely(ret))
 				goto out;
 		}
@@ -707,9 +706,9 @@
  * key here is the 'actor' worker passed in that actually moves the data
  * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
  */
-ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
-			 loff_t *ppos, size_t len, unsigned int flags,
-			 splice_actor *actor)
+static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
+				  struct file *out, loff_t *ppos, size_t len,
+				  unsigned int flags, splice_actor *actor)
 {
 	int ret, do_wakeup, err;
 	struct splice_desc sd;
@@ -722,9 +721,6 @@
 	sd.file = out;
 	sd.pos = *ppos;
 
-	if (pipe->inode)
-		mutex_lock(&pipe->inode->i_mutex);
-
 	for (;;) {
 		if (pipe->nrbufs) {
 			struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
@@ -797,9 +793,6 @@
 		pipe_wait(pipe);
 	}
 
-	if (pipe->inode)
-		mutex_unlock(&pipe->inode->i_mutex);
-
 	if (do_wakeup) {
 		smp_mb();
 		if (waitqueue_active(&pipe->wait))
@@ -810,6 +803,73 @@
 	return ret;
 }
 
+ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
+			 loff_t *ppos, size_t len, unsigned int flags,
+			 splice_actor *actor)
+{
+	ssize_t ret;
+	struct inode *inode = out->f_mapping->host;
+
+	/*
+	 * The actor worker might be calling ->prepare_write and
+	 * ->commit_write. Most of the time, these expect i_mutex to
+	 * be held. Since this may result in an ABBA deadlock with
+	 * pipe->inode, we have to order lock acquiry here.
+	 */
+	inode_double_lock(inode, pipe->inode);
+	ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor);
+	inode_double_unlock(inode, pipe->inode);
+
+	return ret;
+}
+
+/**
+ * generic_file_splice_write_nolock - generic_file_splice_write without mutexes
+ * @pipe:	pipe info
+ * @out:	file to write to
+ * @len:	number of bytes to splice
+ * @flags:	splice modifier flags
+ *
+ * Will either move or copy pages (determined by @flags options) from
+ * the given pipe inode to the given file. The caller is responsible
+ * for acquiring i_mutex on both inodes.
+ *
+ */
+ssize_t
+generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
+				 loff_t *ppos, size_t len, unsigned int flags)
+{
+	struct address_space *mapping = out->f_mapping;
+	struct inode *inode = mapping->host;
+	ssize_t ret;
+	int err;
+
+	err = remove_suid(out->f_dentry);
+	if (unlikely(err))
+		return err;
+
+	ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
+	if (ret > 0) {
+		*ppos += ret;
+
+		/*
+		 * If file or inode is SYNC and we actually wrote some data,
+		 * sync it.
+		 */
+		if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
+			err = generic_osync_inode(inode, mapping,
+						  OSYNC_METADATA|OSYNC_DATA);
+
+			if (err)
+				ret = err;
+		}
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(generic_file_splice_write_nolock);
+
 /**
  * generic_file_splice_write - splice data from a pipe to a file
  * @pipe:	pipe info
@@ -826,12 +886,21 @@
 			  loff_t *ppos, size_t len, unsigned int flags)
 {
 	struct address_space *mapping = out->f_mapping;
+	struct inode *inode = mapping->host;
 	ssize_t ret;
+	int err;
+
+	err = should_remove_suid(out->f_dentry);
+	if (unlikely(err)) {
+		mutex_lock(&inode->i_mutex);
+		err = __remove_suid(out->f_dentry, err);
+		mutex_unlock(&inode->i_mutex);
+		if (err)
+			return err;
+	}
 
 	ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
 	if (ret > 0) {
-		struct inode *inode = mapping->host;
-
 		*ppos += ret;
 
 		/*
@@ -839,8 +908,6 @@
 		 * sync it.
 		 */
 		if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
-			int err;
-
 			mutex_lock(&inode->i_mutex);
 			err = generic_osync_inode(inode, mapping,
 						  OSYNC_METADATA|OSYNC_DATA);
@@ -1042,6 +1109,19 @@
 EXPORT_SYMBOL(do_splice_direct);
 
 /*
+ * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
+ * location, so checking ->i_pipe is not enough to verify that this is a
+ * pipe.
+ */
+static inline struct pipe_inode_info *pipe_info(struct inode *inode)
+{
+	if (S_ISFIFO(inode->i_mode))
+		return inode->i_pipe;
+
+	return NULL;
+}
+
+/*
  * Determine where to splice to/from.
  */
 static long do_splice(struct file *in, loff_t __user *off_in,
@@ -1052,7 +1132,7 @@
 	loff_t offset, *off;
 	long ret;
 
-	pipe = in->f_dentry->d_inode->i_pipe;
+	pipe = pipe_info(in->f_dentry->d_inode);
 	if (pipe) {
 		if (off_in)
 			return -ESPIPE;
@@ -1073,7 +1153,7 @@
 		return ret;
 	}
 
-	pipe = out->f_dentry->d_inode->i_pipe;
+	pipe = pipe_info(out->f_dentry->d_inode);
 	if (pipe) {
 		if (off_out)
 			return -ESPIPE;
@@ -1231,7 +1311,7 @@
 static long do_vmsplice(struct file *file, const struct iovec __user *iov,
 			unsigned long nr_segs, unsigned int flags)
 {
-	struct pipe_inode_info *pipe = file->f_dentry->d_inode->i_pipe;
+	struct pipe_inode_info *pipe;
 	struct page *pages[PIPE_BUFFERS];
 	struct partial_page partial[PIPE_BUFFERS];
 	struct splice_pipe_desc spd = {
@@ -1241,7 +1321,8 @@
 		.ops = &user_page_pipe_buf_ops,
 	};
 
-	if (unlikely(!pipe))
+	pipe = pipe_info(file->f_dentry->d_inode);
+	if (!pipe)
 		return -EBADF;
 	if (unlikely(nr_segs > UIO_MAXIOV))
 		return -EINVAL;
@@ -1400,13 +1481,7 @@
 	 * grabbing by inode address. Otherwise two different processes
 	 * could deadlock (one doing tee from A -> B, the other from B -> A).
 	 */
-	if (ipipe->inode < opipe->inode) {
-		mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_PARENT);
-		mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_CHILD);
-	} else {
-		mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_PARENT);
-		mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_CHILD);
-	}
+	inode_double_lock(ipipe->inode, opipe->inode);
 
 	do {
 		if (!opipe->readers) {
@@ -1450,8 +1525,7 @@
 		i++;
 	} while (len);
 
-	mutex_unlock(&ipipe->inode->i_mutex);
-	mutex_unlock(&opipe->inode->i_mutex);
+	inode_double_unlock(ipipe->inode, opipe->inode);
 
 	/*
 	 * If we put data in the output pipe, wakeup any potential readers.
@@ -1475,8 +1549,8 @@
 static long do_tee(struct file *in, struct file *out, size_t len,
 		   unsigned int flags)
 {
-	struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe;
-	struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe;
+	struct pipe_inode_info *ipipe = pipe_info(in->f_dentry->d_inode);
+	struct pipe_inode_info *opipe = pipe_info(out->f_dentry->d_inode);
 	int ret = -EINVAL;
 
 	/*
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index edb711f..0afd745 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -1004,6 +1004,7 @@
 	.rmdir		= vfat_rmdir,
 	.rename		= vfat_rename,
 	.setattr	= fat_notify_change,
+	.getattr	= fat_getattr,
 };
 
 static int vfat_fill_super(struct super_block *sb, void *data, int silent)
diff --git a/fs/xattr.c b/fs/xattr.c
index 3956351..0901bdc 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -48,14 +48,21 @@
 		return 0;
 
 	/*
-	 * The trusted.* namespace can only accessed by a privilegued user.
+	 * The trusted.* namespace can only be accessed by a privileged user.
 	 */
 	if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
 		return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
 
+	/* In user.* namespace, only regular files and directories can have
+	 * extended attributes. For sticky directories, only the owner and
+	 * privileged user can write attributes.
+	 */
 	if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
-		if (!S_ISREG(inode->i_mode) &&
-		    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
+		if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
+			return -EPERM;
+		if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
+		    (mask & MAY_WRITE) && (current->fsuid != inode->i_uid) &&
+		    !capable(CAP_FOWNER))
 			return -EPERM;
 	}
 
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index 291948d..b49989b 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -21,22 +21,7 @@
 XFS_LINUX := linux-2.6
 
 ifeq ($(CONFIG_XFS_DEBUG),y)
-	EXTRA_CFLAGS += -g -DSTATIC="" -DDEBUG
-	EXTRA_CFLAGS += -DXFS_BUF_LOCK_TRACKING
-endif
-ifeq ($(CONFIG_XFS_TRACE),y)
-	EXTRA_CFLAGS += -DXFS_ALLOC_TRACE
-	EXTRA_CFLAGS += -DXFS_ATTR_TRACE
-	EXTRA_CFLAGS += -DXFS_BLI_TRACE
-	EXTRA_CFLAGS += -DXFS_BMAP_TRACE
-	EXTRA_CFLAGS += -DXFS_BMBT_TRACE
-	EXTRA_CFLAGS += -DXFS_DIR2_TRACE
-	EXTRA_CFLAGS += -DXFS_DQUOT_TRACE
-	EXTRA_CFLAGS += -DXFS_ILOCK_TRACE
-	EXTRA_CFLAGS += -DXFS_LOG_TRACE
-	EXTRA_CFLAGS += -DXFS_RW_TRACE
-	EXTRA_CFLAGS += -DXFS_BUF_TRACE
-	EXTRA_CFLAGS += -DXFS_VNODE_TRACE
+	EXTRA_CFLAGS += -g
 endif
 
 obj-$(CONFIG_XFS_FS)		+= xfs.o
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index db5f5a3..d338284 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -15,6 +15,7 @@
  * along with this program; if not, write the Free Software Foundation,
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
+#include "xfs.h"
 #include <linux/stddef.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
@@ -31,7 +32,6 @@
 #include <linux/kthread.h>
 #include <linux/migrate.h>
 #include <linux/backing-dev.h>
-#include "xfs_linux.h"
 
 STATIC kmem_zone_t *xfs_buf_zone;
 STATIC kmem_shaker_t xfs_buf_shake;
@@ -1406,7 +1406,7 @@
 	btp->bt_hashshift = external ? 3 : 8;	/* 8 or 256 buckets */
 	btp->bt_hashmask = (1 << btp->bt_hashshift) - 1;
 	btp->bt_hash = kmem_zalloc((1 << btp->bt_hashshift) *
-					sizeof(xfs_bufhash_t), KM_SLEEP);
+					sizeof(xfs_bufhash_t), KM_SLEEP | KM_LARGE);
 	for (i = 0; i < (1 << btp->bt_hashshift); i++) {
 		spin_lock_init(&btp->bt_hash[i].bh_lock);
 		INIT_LIST_HEAD(&btp->bt_hash[i].bh_list);
diff --git a/fs/xfs/linux-2.6/xfs_dmapi_priv.h b/fs/xfs/linux-2.6/xfs_dmapi_priv.h
new file mode 100644
index 0000000..a8b0b16
--- /dev/null
+++ b/fs/xfs/linux-2.6/xfs_dmapi_priv.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef __XFS_DMAPI_PRIV_H__
+#define __XFS_DMAPI_PRIV_H__
+
+/*
+ *	Based on IO_ISDIRECT, decide which i_ flag is set.
+ */
+#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
+			      DM_FLAGS_IMUX : 0)
+#define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
+
+#endif /*__XFS_DMAPI_PRIV_H__*/
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index a74f854..74d09482 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -341,8 +341,11 @@
 		put_unused_fd(new_fd);
 		return -XFS_ERROR(-PTR_ERR(filp));
 	}
-	if (inode->i_mode & S_IFREG)
+	if (inode->i_mode & S_IFREG) {
+		/* invisible operation should not change atime */
+		filp->f_flags |= O_NOATIME;
 		filp->f_op = &xfs_invis_file_operations;
+	}
 
 	fd_install(new_fd, filp);
 	return new_fd;
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 38c4d12..de05abb 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -227,9 +227,7 @@
 		xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
 		xfs_set_inodeops(inode);
 
-		spin_lock(&ip->i_flags_lock);
-		ip->i_flags &= ~XFS_INEW;
-		spin_unlock(&ip->i_flags_lock);
+		xfs_iflags_clear(ip, XFS_INEW);
 		barrier();
 
 		unlock_new_inode(inode);
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index c75f683..4363512 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -15,11 +15,9 @@
  * along with this program; if not, write the Free Software Foundation,
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
+#include <xfs.h>
 #include "debug.h"
 #include "spin.h"
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
 
 static char		message[256];	/* keep it off the stack */
 static DEFINE_SPINLOCK(xfs_err_lock);
diff --git a/fs/xfs/support/move.c b/fs/xfs/support/move.c
index caefa17..ac8617c 100644
--- a/fs/xfs/support/move.c
+++ b/fs/xfs/support/move.c
@@ -22,7 +22,7 @@
  * as we go.
  */
 int
-uio_read(caddr_t src, size_t len, struct uio *uio)
+xfs_uio_read(caddr_t src, size_t len, struct uio *uio)
 {
 	size_t	count;
 
diff --git a/fs/xfs/support/move.h b/fs/xfs/support/move.h
index 97a2498..977879c 100644
--- a/fs/xfs/support/move.h
+++ b/fs/xfs/support/move.h
@@ -65,6 +65,6 @@
 typedef struct uio uio_t;
 typedef struct iovec iovec_t;
 
-extern int	uio_read (caddr_t, size_t, uio_t *);
+extern int	xfs_uio_read (caddr_t, size_t, uio_t *);
 
 #endif  /* __XFS_SUPPORT_MOVE_H__ */
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h
index 1a48dbb..bf0a120 100644
--- a/fs/xfs/xfs.h
+++ b/fs/xfs/xfs.h
@@ -17,5 +17,28 @@
  */
 #ifndef __XFS_H__
 #define __XFS_H__
+
+#ifdef CONFIG_XFS_DEBUG
+#define STATIC
+#define DEBUG 1
+#define XFS_BUF_LOCK_TRACKING 1
+/* #define QUOTADEBUG 1 */
+#endif
+
+#ifdef CONFIG_XFS_TRACE
+#define XFS_ALLOC_TRACE 1
+#define XFS_ATTR_TRACE 1
+#define XFS_BLI_TRACE 1
+#define XFS_BMAP_TRACE 1
+#define XFS_BMBT_TRACE 1
+#define XFS_DIR2_TRACE 1
+#define XFS_DQUOT_TRACE 1
+#define XFS_ILOCK_TRACE 1
+#define XFS_LOG_TRACE 1
+#define XFS_RW_TRACE 1
+#define XFS_BUF_TRACE 1
+#define XFS_VNODE_TRACE 1
+#endif
+
 #include <linux-2.6/xfs_linux.h>
 #endif	/* __XFS_H__ */
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 5b050c0..498ad50d 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1171,6 +1171,8 @@
 		xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK);
 		xfs_bmbt_set_blockcount(ep, temp);
 		r[0] = *new;
+		r[1].br_state = PREV.br_state;
+		r[1].br_startblock = 0;
 		r[1].br_startoff = new_endoff;
 		temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
 		r[1].br_blockcount = temp2;
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 8edbe1a..8e8e527 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -678,7 +678,7 @@
 	idbp->d_off = pa->cook;
 	idbp->d_name[namelen] = '\0';
 	memcpy(idbp->d_name, pa->name, namelen);
-	rval = uio_read((caddr_t)idbp, reclen, uio);
+	rval = xfs_uio_read((caddr_t)idbp, reclen, uio);
 	pa->done = (rval == 0);
 	return rval;
 }
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 4e7865a..adc3d25 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -157,27 +157,9 @@
 #define DM_FLAGS_IALLOCSEM_WR	0x020	/* thread holds i_alloc_sem wr */
 
 /*
- *	Based on IO_ISDIRECT, decide which i_ flag is set.
+ *	Pull in platform specific event flags defines
  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
-#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
-			      DM_FLAGS_IMUX : 0)
-#define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \
-    (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22))
-#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
-			      DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_IMUX)
-#define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
-#endif
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21)
-#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
-			      0 : DM_FLAGS_IMUX)
-#define DM_SEM_FLAG_WR	(DM_FLAGS_IMUX)
-#endif
-
+#include "xfs_dmapi_priv.h"
 
 /*
  *	Macros to turn caller specified delay/block flags into
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index b73d216..c1c89da 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -215,7 +215,7 @@
 			 * If INEW is set this inode is being set up
 			 * we need to pause and try again.
 			 */
-			if (ip->i_flags & XFS_INEW) {
+			if (xfs_iflags_test(ip, XFS_INEW)) {
 				read_unlock(&ih->ih_lock);
 				delay(1);
 				XFS_STATS_INC(xs_ig_frecycle);
@@ -230,22 +230,50 @@
 				 * on its way out of the system,
 				 * we need to pause and try again.
 				 */
-				if (ip->i_flags & XFS_IRECLAIM) {
+				if (xfs_iflags_test(ip, XFS_IRECLAIM)) {
 					read_unlock(&ih->ih_lock);
 					delay(1);
 					XFS_STATS_INC(xs_ig_frecycle);
 
 					goto again;
 				}
+				ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE));
+
+				/*
+				 * If lookup is racing with unlink, then we
+				 * should return an error immediately so we
+				 * don't remove it from the reclaim list and
+				 * potentially leak the inode.
+				 */
+				if ((ip->i_d.di_mode == 0) &&
+				    !(flags & XFS_IGET_CREATE)) {
+					read_unlock(&ih->ih_lock);
+					return ENOENT;
+				}
+
+				/*
+				 * There may be transactions sitting in the
+				 * incore log buffers or being flushed to disk
+				 * at this time.  We can't clear the
+				 * XFS_IRECLAIMABLE flag until these
+				 * transactions have hit the disk, otherwise we
+				 * will void the guarantee the flag provides
+				 * xfs_iunpin()
+				 */
+				if (xfs_ipincount(ip)) {
+					read_unlock(&ih->ih_lock);
+					xfs_log_force(mp, 0,
+						XFS_LOG_FORCE|XFS_LOG_SYNC);
+					XFS_STATS_INC(xs_ig_frecycle);
+					goto again;
+				}
 
 				vn_trace_exit(vp, "xfs_iget.alloc",
 					(inst_t *)__return_address);
 
 				XFS_STATS_INC(xs_ig_found);
 
-				spin_lock(&ip->i_flags_lock);
-				ip->i_flags &= ~XFS_IRECLAIMABLE;
-				spin_unlock(&ip->i_flags_lock);
+				xfs_iflags_clear(ip, XFS_IRECLAIMABLE);
 				version = ih->ih_version;
 				read_unlock(&ih->ih_lock);
 				xfs_ihash_promote(ih, ip, version);
@@ -299,10 +327,7 @@
 			if (lock_flags != 0)
 				xfs_ilock(ip, lock_flags);
 
-			spin_lock(&ip->i_flags_lock);
-			ip->i_flags &= ~XFS_ISTALE;
-			spin_unlock(&ip->i_flags_lock);
-
+			xfs_iflags_clear(ip, XFS_ISTALE);
 			vn_trace_exit(vp, "xfs_iget.found",
 						(inst_t *)__return_address);
 			goto return_ip;
@@ -371,10 +396,7 @@
 	ih->ih_next = ip;
 	ip->i_udquot = ip->i_gdquot = NULL;
 	ih->ih_version++;
-	spin_lock(&ip->i_flags_lock);
-	ip->i_flags |= XFS_INEW;
-	spin_unlock(&ip->i_flags_lock);
-
+	xfs_iflags_set(ip, XFS_INEW);
 	write_unlock(&ih->ih_lock);
 
 	/*
@@ -625,7 +647,7 @@
 	vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
 
 	if ((ip->i_d.di_mode == 0)) {
-		ASSERT(!(ip->i_flags & XFS_IRECLAIMABLE));
+		ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
 		vn_mark_bad(vp);
 	}
 	if (inode->i_state & I_NEW)
@@ -683,6 +705,7 @@
 	/*
 	 * Free all memory associated with the inode.
 	 */
+	xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
 	xfs_idestroy(ip);
 }
 
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index c27d7d49..44dfac5 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2193,7 +2193,7 @@
 			/* Inode not in memory or we found it already,
 			 * nothing to do
 			 */
-			if (!ip || (ip->i_flags & XFS_ISTALE)) {
+			if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) {
 				read_unlock(&ih->ih_lock);
 				continue;
 			}
@@ -2215,10 +2215,7 @@
 
 			if (ip == free_ip) {
 				if (xfs_iflock_nowait(ip)) {
-					spin_lock(&ip->i_flags_lock);
-					ip->i_flags |= XFS_ISTALE;
-					spin_unlock(&ip->i_flags_lock);
-
+					xfs_iflags_set(ip, XFS_ISTALE);
 					if (xfs_inode_clean(ip)) {
 						xfs_ifunlock(ip);
 					} else {
@@ -2231,9 +2228,7 @@
 
 			if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
 				if (xfs_iflock_nowait(ip)) {
-					spin_lock(&ip->i_flags_lock);
-					ip->i_flags |= XFS_ISTALE;
-					spin_unlock(&ip->i_flags_lock);
+					xfs_iflags_set(ip, XFS_ISTALE);
 
 					if (xfs_inode_clean(ip)) {
 						xfs_ifunlock(ip);
@@ -2263,9 +2258,7 @@
 				AIL_LOCK(mp,s);
 				iip->ili_flush_lsn = iip->ili_item.li_lsn;
 				AIL_UNLOCK(mp, s);
-				spin_lock(&iip->ili_inode->i_flags_lock);
-				iip->ili_inode->i_flags |= XFS_ISTALE;
-				spin_unlock(&iip->ili_inode->i_flags_lock);
+				xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
 				pre_flushed++;
 			}
 			lip = lip->li_bio_list;
@@ -2748,42 +2741,39 @@
 {
 	ASSERT(atomic_read(&ip->i_pincount) > 0);
 
-	if (atomic_dec_and_test(&ip->i_pincount)) {
-		/*
-		 * If the inode is currently being reclaimed, the
-		 * linux inode _and_ the xfs vnode may have been
-		 * freed so we cannot reference either of them safely.
-		 * Hence we should not try to do anything to them
-		 * if the xfs inode is currently in the reclaim
-		 * path.
-		 *
-		 * However, we still need to issue the unpin wakeup
-		 * call as the inode reclaim may be blocked waiting for
-		 * the inode to become unpinned.
-		 */
-		struct inode *inode = NULL;
+	if (atomic_dec_and_lock(&ip->i_pincount, &ip->i_flags_lock)) {
 
-		spin_lock(&ip->i_flags_lock);
-		if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
+		/*
+		 * If the inode is currently being reclaimed, the link between
+		 * the bhv_vnode and the xfs_inode will be broken after the
+		 * XFS_IRECLAIM* flag is set. Hence, if these flags are not
+		 * set, then we can move forward and mark the linux inode dirty
+		 * knowing that it is still valid as it won't freed until after
+		 * the bhv_vnode<->xfs_inode link is broken in xfs_reclaim. The
+		 * i_flags_lock is used to synchronise the setting of the
+		 * XFS_IRECLAIM* flags and the breaking of the link, and so we
+		 * can execute atomically w.r.t to reclaim by holding this lock
+		 * here.
+		 *
+		 * However, we still need to issue the unpin wakeup call as the
+		 * inode reclaim may be blocked waiting for the inode to become
+		 * unpinned.
+		 */
+
+		if (!__xfs_iflags_test(ip, XFS_IRECLAIM|XFS_IRECLAIMABLE)) {
 			bhv_vnode_t	*vp = XFS_ITOV_NULL(ip);
+			struct inode *inode = NULL;
+
+			BUG_ON(vp == NULL);
+			inode = vn_to_inode(vp);
+			BUG_ON(inode->i_state & I_CLEAR);
 
 			/* make sync come back and flush this inode */
-			if (vp) {
-				inode = vn_to_inode(vp);
-
-				if (!(inode->i_state &
-						(I_NEW|I_FREEING|I_CLEAR))) {
-					inode = igrab(inode);
-					if (inode)
-						mark_inode_dirty_sync(inode);
-				} else
-					inode = NULL;
-			}
+			if (!(inode->i_state & (I_NEW|I_FREEING)))
+				mark_inode_dirty_sync(inode);
 		}
 		spin_unlock(&ip->i_flags_lock);
 		wake_up(&ip->i_ipin_wait);
-		if (inode)
-			iput(inode);
 	}
 }
 
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index e96eb08..bc82372 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -305,6 +305,47 @@
 #endif
 } xfs_inode_t;
 
+
+/*
+ * i_flags helper functions
+ */
+static inline void
+__xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
+{
+	ip->i_flags |= flags;
+}
+
+static inline void
+xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
+{
+	spin_lock(&ip->i_flags_lock);
+	__xfs_iflags_set(ip, flags);
+	spin_unlock(&ip->i_flags_lock);
+}
+
+static inline void
+xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags)
+{
+	spin_lock(&ip->i_flags_lock);
+	ip->i_flags &= ~flags;
+	spin_unlock(&ip->i_flags_lock);
+}
+
+static inline int
+__xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
+{
+	return (ip->i_flags & flags);
+}
+
+static inline int
+xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
+{
+	int ret;
+	spin_lock(&ip->i_flags_lock);
+	ret = __xfs_iflags_test(ip, flags);
+	spin_unlock(&ip->i_flags_lock);
+	return ret;
+}
 #endif	/* __KERNEL__ */
 
 
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 061e2ff..bda774a 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1013,7 +1013,7 @@
 	pathlen = (int)ip->i_d.di_size;
 
 	if (ip->i_df.if_flags & XFS_IFINLINE) {
-		error = uio_read(ip->i_df.if_u1.if_data, pathlen, uiop);
+		error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop);
 	}
 	else {
 		/*
@@ -1044,7 +1044,7 @@
 				byte_cnt = pathlen;
 			pathlen -= byte_cnt;
 
-			error = uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop);
+			error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop);
 			xfs_buf_relse (bp);
 		}
 
@@ -3827,11 +3827,16 @@
 	 */
 	xfs_synchronize_atime(ip);
 
-	/* If we have nothing to flush with this inode then complete the
-	 * teardown now, otherwise break the link between the xfs inode
-	 * and the linux inode and clean up the xfs inode later. This
-	 * avoids flushing the inode to disk during the delete operation
-	 * itself.
+	/*
+	 * If we have nothing to flush with this inode then complete the
+	 * teardown now, otherwise break the link between the xfs inode and the
+	 * linux inode and clean up the xfs inode later. This avoids flushing
+	 * the inode to disk during the delete operation itself.
+	 *
+	 * When breaking the link, we need to set the XFS_IRECLAIMABLE flag
+	 * first to ensure that xfs_iunpin() will never see an xfs inode
+	 * that has a linux inode being reclaimed. Synchronisation is provided
+	 * by the i_flags_lock.
 	 */
 	if (!ip->i_update_core && (ip->i_itemp == NULL)) {
 		xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -3840,13 +3845,13 @@
 	} else {
 		xfs_mount_t	*mp = ip->i_mount;
 
-		/* Protect sync from us */
+		/* Protect sync and unpin from us */
 		XFS_MOUNT_ILOCK(mp);
-		vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
-		list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
 		spin_lock(&ip->i_flags_lock);
-		ip->i_flags |= XFS_IRECLAIMABLE;
+		__xfs_iflags_set(ip, XFS_IRECLAIMABLE);
+		vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
 		spin_unlock(&ip->i_flags_lock);
+		list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
 		XFS_MOUNT_IUNLOCK(mp);
 	}
 	return 0;
@@ -3872,8 +3877,8 @@
 	 */
 	write_lock(&ih->ih_lock);
 	spin_lock(&ip->i_flags_lock);
-	if ((ip->i_flags & XFS_IRECLAIM) ||
-	    (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) {
+	if (__xfs_iflags_test(ip, XFS_IRECLAIM) ||
+	    (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) {
 		spin_unlock(&ip->i_flags_lock);
 		write_unlock(&ih->ih_lock);
 		if (locked) {
@@ -3882,7 +3887,7 @@
 		}
 		return 1;
 	}
-	ip->i_flags |= XFS_IRECLAIM;
+	__xfs_iflags_set(ip, XFS_IRECLAIM);
 	spin_unlock(&ip->i_flags_lock);
 	write_unlock(&ih->ih_lock);
 
diff --git a/include/asm-arm/arch-ebsa110/io.h b/include/asm-arm/arch-ebsa110/io.h
index ae04844..722c5e0 100644
--- a/include/asm-arm/arch-ebsa110/io.h
+++ b/include/asm-arm/arch-ebsa110/io.h
@@ -27,9 +27,9 @@
 u32 __inl(unsigned int port);
 void __outl(u32 val, unsigned int port);
 
-u8  __readb(void __iomem *addr);
-u16 __readw(void __iomem *addr);
-u32 __readl(void __iomem *addr);
+u8  __readb(const volatile void __iomem *addr);
+u16 __readw(const volatile void __iomem *addr);
+u32 __readl(const volatile void __iomem *addr);
 
 void __writeb(u8  val, void __iomem *addr);
 void __writew(u16 val, void __iomem *addr);
@@ -64,8 +64,14 @@
 #define writew(v,b)		__writew(v,b)
 #define writel(v,b)		__writel(v,b)
 
-#define __arch_ioremap(cookie,sz,c)	((void __iomem *)(cookie))
-#define __arch_iounmap(cookie)		do { } while (0)
+static inline void __iomem *__arch_ioremap(unsigned long cookie, size_t size,
+					   unsigned int flags)
+{
+	return (void __iomem *)cookie;
+}
+
+#define __arch_ioremap		__arch_ioremap
+#define __arch_iounmap(cookie)	do { } while (0)
 
 extern void insb(unsigned int port, void *buf, int sz);
 extern void insw(unsigned int port, void *buf, int sz);
diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h
index f3bc70e..67ed436 100644
--- a/include/asm-arm/arch-pxa/irqs.h
+++ b/include/asm-arm/arch-pxa/irqs.h
@@ -73,7 +73,7 @@
 #define IRQ_TO_GPIO(i)	(((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i))
 
 #if defined(CONFIG_PXA25x)
-#define PXA_LAST_GPIO	80
+#define PXA_LAST_GPIO	84
 #elif defined(CONFIG_PXA27x)
 #define PXA_LAST_GPIO	127
 #endif
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 68731e0..cff752f 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -2242,7 +2242,7 @@
 
 #define CICR1_TBIT	(1 << 31)	/* Transparency bit */
 #define CICR1_RGBT_CONV	(0x3 << 30)	/* RGBT conversion mask */
-#define CICR1_PPL	(0x3f << 15)	/* Pixels per line mask */
+#define CICR1_PPL	(0x7ff << 15)	/* Pixels per line mask */
 #define CICR1_RGB_CONV	(0x7 << 12)	/* RGB conversion mask */
 #define CICR1_RGB_F	(1 << 11)	/* RGB format */
 #define CICR1_YCBCR_F	(1 << 10)	/* YCbCr format */
@@ -2268,7 +2268,7 @@
 #define CICR3_VSW	(0x3f << 10)	/* Vertical sync pulse width mask */
 #define CICR3_BFPW	(0x3f << 3)	/* Beginning-of-frame pixel clock
 					   wait count mask */
-#define CICR3_LPF	(0x3ff << 0)	/* Lines per frame mask */
+#define CICR3_LPF	(0x7ff << 0)	/* Lines per frame mask */
 
 #define CICR4_MCLK_DLY	(0x3 << 24)	/* MCLK Data Capture Delay mask */
 #define CICR4_PCLK_EN	(1 << 23)	/* Pixel clock enable */
@@ -2289,8 +2289,8 @@
 #define CISR_EOL	(1 << 8)	/* End of line */
 #define CISR_PAR_ERR	(1 << 7)	/* Parity error */
 #define CISR_CQD	(1 << 6)	/* Camera interface quick disable */
-#define CISR_SOF	(1 << 5)	/* Start of frame */
-#define CISR_CDD	(1 << 4)	/* Camera interface disable done */
+#define CISR_CDD	(1 << 5)	/* Camera interface disable done */
+#define CISR_SOF	(1 << 4)	/* Start of frame */
 #define CISR_EOF	(1 << 3)	/* End of frame */
 #define CISR_IFO_2	(1 << 2)	/* FIFO overrun for Channel 2 */
 #define CISR_IFO_1	(1 << 1)	/* FIFO overrun for Channel 1 */
diff --git a/include/asm-arm/arch-pxa/udc.h b/include/asm-arm/arch-pxa/udc.h
index 121cd24..646480d 100644
--- a/include/asm-arm/arch-pxa/udc.h
+++ b/include/asm-arm/arch-pxa/udc.h
@@ -4,23 +4,8 @@
  * This supports machine-specific differences in how the PXA2xx
  * USB Device Controller (UDC) is wired.
  *
- * It is set in linux/arch/arm/mach-pxa/<machine>.c and used in
- * the probe routine of linux/drivers/usb/gadget/pxa2xx_udc.c
  */
-struct pxa2xx_udc_mach_info {
-        int  (*udc_is_connected)(void);		/* do we see host? */
-        void (*udc_command)(int cmd);
-#define	PXA2XX_UDC_CMD_CONNECT		0	/* let host see us */
-#define	PXA2XX_UDC_CMD_DISCONNECT	1	/* so host won't see us */
-
-	/* Boards following the design guidelines in the developer's manual,
-	 * with on-chip GPIOs not Lubbock's wierd hardware, can have a sane
-	 * VBUS IRQ and omit the methods above.  Store the GPIO number
-	 * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits.
-	 */
-	u16	gpio_vbus;			/* high == vbus present */
-	u16	gpio_pullup;			/* high == pullup activated */
-};
+#include <asm/mach/udc_pxa2xx.h>
 
 extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
 
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index 55eb4dc..6666177 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -12,6 +12,10 @@
  * uncached, unwrite-buffered mapped memory space for use with DMA
  * devices.  This is the "generic" version.  The PCI specific version
  * is in pci.h
+ *
+ * Note: Drivers should NOT use this function directly, as it will break
+ * platforms with CONFIG_DMABOUNCE.
+ * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
 extern void consistent_sync(void *kaddr, size_t size, int rw);
 
diff --git a/include/asm-arm/mach/udc_pxa2xx.h b/include/asm-arm/mach/udc_pxa2xx.h
new file mode 100644
index 0000000..ff0a957
--- /dev/null
+++ b/include/asm-arm/mach/udc_pxa2xx.h
@@ -0,0 +1,26 @@
+/*
+ * linux/include/asm-arm/mach/udc_pxa2xx.h
+ *
+ * This supports machine-specific differences in how the PXA2xx
+ * USB Device Controller (UDC) is wired.
+ *
+ * It is set in linux/arch/arm/mach-pxa/<machine>.c or in
+ * linux/arch/mach-ixp4xx/<machine>.c and used in
+ * the probe routine of linux/drivers/usb/gadget/pxa2xx_udc.c
+ */
+
+struct pxa2xx_udc_mach_info {
+        int  (*udc_is_connected)(void);		/* do we see host? */
+        void (*udc_command)(int cmd);
+#define	PXA2XX_UDC_CMD_CONNECT		0	/* let host see us */
+#define	PXA2XX_UDC_CMD_DISCONNECT	1	/* so host won't see us */
+
+	/* Boards following the design guidelines in the developer's manual,
+	 * with on-chip GPIOs not Lubbock's wierd hardware, can have a sane
+	 * VBUS IRQ and omit the methods above.  Store the GPIO number
+	 * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits.
+	 */
+	u16	gpio_vbus;			/* high == vbus present */
+	u16	gpio_pullup;			/* high == pullup activated */
+};
+
diff --git a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h
index 09ad0ca..5f420a0 100644
--- a/include/asm-arm/uaccess.h
+++ b/include/asm-arm/uaccess.h
@@ -383,19 +383,19 @@
 
 
 #ifdef CONFIG_MMU
-extern unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n);
-extern unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n);
-extern unsigned long __clear_user(void __user *addr, unsigned long n);
+extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
+extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
+extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
 #else
 #define __copy_from_user(to,from,n)	(memcpy(to, (void __force *)from, n), 0)
 #define __copy_to_user(to,from,n)	(memcpy((void __force *)to, from, n), 0)
 #define __clear_user(addr,n)		(memset((void __force *)addr, 0, n), 0)
 #endif
 
-extern unsigned long __strncpy_from_user(char *to, const char __user *from, unsigned long count);
-extern unsigned long __strnlen_user(const char __user *s, long n);
+extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count);
+extern unsigned long __must_check __strnlen_user(const char __user *s, long n);
 
-static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
+static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
 {
 	if (access_ok(VERIFY_READ, from, n))
 		n = __copy_from_user(to, from, n);
@@ -404,7 +404,7 @@
 	return n;
 }
 
-static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
+static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	if (access_ok(VERIFY_WRITE, to, n))
 		n = __copy_to_user(to, from, n);
@@ -414,14 +414,14 @@
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
-static inline unsigned long clear_user(void __user *to, unsigned long n)
+static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
 {
 	if (access_ok(VERIFY_WRITE, to, n))
 		n = __clear_user(to, n);
 	return n;
 }
 
-static inline long strncpy_from_user(char *dst, const char __user *src, long count)
+static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count)
 {
 	long res = -EFAULT;
 	if (access_ok(VERIFY_READ, src, 1))
@@ -431,7 +431,7 @@
 
 #define strlen_user(s)	strnlen_user(s, ~0UL >> 1)
 
-static inline long strnlen_user(const char __user *s, long n)
+static inline long __must_check strnlen_user(const char __user *s, long n)
 {
 	unsigned long res = 0;
 
diff --git a/include/asm-avr32/atomic.h b/include/asm-avr32/atomic.h
index e0b9c44..c40b603 100644
--- a/include/asm-avr32/atomic.h
+++ b/include/asm-avr32/atomic.h
@@ -41,7 +41,7 @@
 		"	stcond	%1, %0\n"
 		"	brne	1b"
 		: "=&r"(result), "=o"(v->counter)
-		: "m"(v->counter), "ir"(i)
+		: "m"(v->counter), "rKs21"(i)
 		: "cc");
 
 	return result;
@@ -58,7 +58,7 @@
 {
 	int result;
 
-	if (__builtin_constant_p(i))
+	if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576))
 		result = atomic_sub_return(-i, v);
 	else
 		asm volatile(
@@ -101,7 +101,7 @@
 		"	mov	%1, 1\n"
 		"1:"
 		: "=&r"(tmp), "=&r"(result), "=o"(v->counter)
-		: "m"(v->counter), "ir"(a), "ir"(u)
+		: "m"(v->counter), "rKs21"(a), "rKs21"(u)
 		: "cc", "memory");
 
 	return result;
@@ -121,7 +121,7 @@
 {
 	int tmp, result;
 
-	if (__builtin_constant_p(a))
+	if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576))
 		result = atomic_sub_unless(v, -a, u);
 	else {
 		result = 0;
diff --git a/include/asm-avr32/io.h b/include/asm-avr32/io.h
index 2fc8f11..eec4750 100644
--- a/include/asm-avr32/io.h
+++ b/include/asm-avr32/io.h
@@ -76,6 +76,39 @@
 #define readsw(p, d, l)		__raw_readsw((unsigned int)p, d, l)
 #define readsl(p, d, l)		__raw_readsl((unsigned int)p, d, l)
 
+
+/*
+ * io{read,write}{8,16,32} macros in both le (for PCI style consumers) and native be
+ */
+#ifndef ioread8
+
+#define ioread8(p)	({ unsigned int __v = __raw_readb(p); __v; })
+
+#define ioread16(p)	({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; })
+#define ioread16be(p)	({ unsigned int __v = be16_to_cpu(__raw_readw(p)); __v; })
+
+#define ioread32(p)	({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; })
+#define ioread32be(p)	({ unsigned int __v = be32_to_cpu(__raw_readl(p)); __v; })
+
+#define iowrite8(v,p)	__raw_writeb(v, p)
+
+#define iowrite16(v,p)	__raw_writew(cpu_to_le16(v), p)
+#define iowrite16be(v,p)	__raw_writew(cpu_to_be16(v), p)
+
+#define iowrite32(v,p)	__raw_writel(cpu_to_le32(v), p)
+#define iowrite32be(v,p)	__raw_writel(cpu_to_be32(v), p)
+
+#define ioread8_rep(p,d,c)	__raw_readsb(p,d,c)
+#define ioread16_rep(p,d,c)	__raw_readsw(p,d,c)
+#define ioread32_rep(p,d,c)	__raw_readsl(p,d,c)
+
+#define iowrite8_rep(p,s,c)	__raw_writesb(p,s,c)
+#define iowrite16_rep(p,s,c)	__raw_writesw(p,s,c)
+#define iowrite32_rep(p,s,c)	__raw_writesl(p,s,c)
+
+#endif
+
+
 /*
  * These two are only here because ALSA _thinks_ it needs them...
  */
diff --git a/include/asm-avr32/unistd.h b/include/asm-avr32/unistd.h
index a50e500..56ed1f9 100644
--- a/include/asm-avr32/unistd.h
+++ b/include/asm-avr32/unistd.h
@@ -280,9 +280,10 @@
 #define __NR_sync_file_range	262
 #define __NR_tee		263
 #define __NR_vmsplice		264
+#define __NR_epoll_pwait	265
 
 #ifdef __KERNEL__
-#define NR_syscalls		265
+#define NR_syscalls		266
 
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 69240b5..e60d6f2 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -125,6 +125,10 @@
 		*(__param)						\
 		VMLINUX_SYMBOL(__stop___param) = .;			\
 	}								\
+									\
+	/* Unwind data binary search table */				\
+	EH_FRAME_HDR							\
+									\
 	__end_rodata = .;						\
 	. = ALIGN(4096);
 
@@ -157,6 +161,18 @@
 		*(.kprobes.text)					\
 		VMLINUX_SYMBOL(__kprobes_text_end) = .;
 
+#ifdef CONFIG_STACK_UNWIND
+		/* Unwind data binary search table */
+#define EH_FRAME_HDR							\
+        	.eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) {	\
+			VMLINUX_SYMBOL(__start_unwind_hdr) = .;		\
+			*(.eh_frame_hdr)				\
+			VMLINUX_SYMBOL(__end_unwind_hdr) = .;		\
+		}
+#else
+#define EH_FRAME_HDR
+#endif
+
 		/* DWARF debug sections.
 		Symbols in the DWARF debugging sections are relative to
 		the beginning of the section so we begin them at 0.  */
@@ -197,3 +213,22 @@
 
 #define NOTES								\
 		.notes : { *(.note.*) } :note
+
+#define INITCALLS							\
+  	*(.initcall0.init)						\
+  	*(.initcall0s.init)						\
+  	*(.initcall1.init)						\
+  	*(.initcall1s.init)						\
+  	*(.initcall2.init)						\
+  	*(.initcall2s.init)						\
+  	*(.initcall3.init)						\
+  	*(.initcall3s.init)						\
+  	*(.initcall4.init)						\
+  	*(.initcall4s.init)						\
+  	*(.initcall5.init)						\
+  	*(.initcall5s.init)						\
+  	*(.initcall6.init)						\
+  	*(.initcall6s.init)						\
+  	*(.initcall7.init)						\
+  	*(.initcall7s.init)
+
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index 6016632..c80b3a9 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -132,6 +132,7 @@
 
 #ifdef CONFIG_X86_IO_APIC
 extern int acpi_skip_timer_override;
+extern int acpi_use_timer_override;
 #endif
 
 static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
diff --git a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h
index 276ea7e..059a9ff 100644
--- a/include/asm-i386/io_apic.h
+++ b/include/asm-i386/io_apic.h
@@ -12,10 +12,6 @@
 
 #ifdef CONFIG_X86_IO_APIC
 
-#define IO_APIC_BASE(idx) \
-		((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
-		+ (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
-
 /*
  * The structure of the IO-APIC:
  */
@@ -119,31 +115,8 @@
 /* non-0 if default (table-less) MP configuration */
 extern int mpc_default_type;
 
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
-	*IO_APIC_BASE(apic) = reg;
-	return *(IO_APIC_BASE(apic)+4);
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
-	*IO_APIC_BASE(apic) = reg;
-	*(IO_APIC_BASE(apic)+4) = value;
-}
-
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- *
- * Older SiS APIC requires we rewrite the index regiser
- */
+/* Older SiS APIC requires we rewrite the index register */
 extern int sis_apic_bug;
-static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
-{
-	if (sis_apic_bug)
-		*IO_APIC_BASE(apic) = reg;
-	*(IO_APIC_BASE(apic)+4) = value;
-}
 
 /* 1 if "noapic" boot option passed */
 extern int skip_ioapic_setup;
diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
index ef0671e..43e5bd8 100644
--- a/include/asm-i386/mach-summit/mach_apic.h
+++ b/include/asm-i386/mach-summit/mach_apic.h
@@ -88,7 +88,11 @@
 
 static inline int apicid_to_node(int logical_apicid)
 {
+#ifdef CONFIG_SMP
 	return apicid_2_node[hard_smp_processor_id()];
+#else
+	return 0;
+#endif
 }
 
 /* Mapping from cpu number to logical apicid */
diff --git a/include/asm-i386/mach-visws/do_timer.h b/include/asm-i386/mach-visws/do_timer.h
deleted file mode 100644
index 21cd696..0000000
--- a/include/asm-i386/mach-visws/do_timer.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* defines for inline arch setup functions */
-
-#include <asm/fixmap.h>
-#include <asm/i8259.h>
-#include "cobalt.h"
-
-static inline void do_timer_interrupt_hook(void)
-{
-	/* Clear the interrupt */
-	co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
-
-	do_timer(1);
-#ifndef CONFIG_SMP
-	update_process_times(user_mode_vm(irq_regs));
-#endif
-/*
- * In the SMP case we use the local APIC timer interrupt to do the
- * profiling, except when we simulate SMP mode on a uniprocessor
- * system, in that case we have to call the local interrupt handler.
- */
-#ifndef CONFIG_X86_LOCAL_APIC
-	profile_tick(CPU_PROFILING);
-#else
-	if (!using_apic_timer)
-		smp_local_timer_interrupt();
-#endif
-}
-
-static inline int do_timer_overflow(int count)
-{
-	int i;
-
-	spin_lock(&i8259A_lock);
-	/*
-	 * This is tricky when I/O APICs are used;
-	 * see do_timer_interrupt().
-	 */
-	i = inb(0x20);
-	spin_unlock(&i8259A_lock);
-	
-	/* assumption about timer being IRQ0 */
-	if (i & 0x01) {
-		/*
-		 * We cannot detect lost timer interrupts ... 
-		 * well, that's why we call them lost, don't we? :)
-		 * [hmm, on the Pentium and Alpha we can ... sort of]
-		 */
-		count -= LATCH;
-	} else {
-		printk("do_slow_gettimeoffset(): hardware timer problem?\n");
-	}
-	return count;
-}
diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h
index de438c71..18afe6b 100644
--- a/include/asm-i386/mach-visws/mach_apic.h
+++ b/include/asm-i386/mach-visws/mach_apic.h
@@ -51,6 +51,11 @@
 {
 }
 
+static inline int apicid_to_node(int logical_apicid)
+{
+	return 0;
+}
+
 /* Mapping from cpu number to logical apicid */
 static inline int cpu_to_logical_apicid(int cpu)
 {
diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h
index 0b210ab..d000689 100644
--- a/include/asm-ia64/sal.h
+++ b/include/asm-ia64/sal.h
@@ -659,6 +659,7 @@
 }
 
 extern s64 ia64_sal_cache_flush (u64 cache_type);
+extern void __init check_sal_cache_flush (void);
 
 /* Initialize all the processor and platform level instruction and data caches */
 static inline s64
diff --git a/include/asm-ia64/sn/addrs.h b/include/asm-ia64/sn/addrs.h
index 1d9efe5..e715c79 100644
--- a/include/asm-ia64/sn/addrs.h
+++ b/include/asm-ia64/sn/addrs.h
@@ -136,9 +136,13 @@
  */
 #define TO_PHYS(x)		(TO_PHYS_MASK & (x))
 #define TO_CAC(x)		(CAC_BASE     | TO_PHYS(x))
+#ifdef CONFIG_SGI_SN
 #define TO_AMO(x)		(AMO_BASE     | TO_PHYS(x))
 #define TO_GET(x)		(GET_BASE     | TO_PHYS(x))
-
+#else
+#define TO_AMO(x)		({ BUG(); x; })
+#define TO_GET(x)		({ BUG(); x; })
+#endif
 
 /*
  * Covert from processor physical address to II/TIO physical address:
diff --git a/include/asm-ia64/uaccess.h b/include/asm-ia64/uaccess.h
index 9adb512..449c8c0 100644
--- a/include/asm-ia64/uaccess.h
+++ b/include/asm-ia64/uaccess.h
@@ -389,7 +389,7 @@
 	struct page *page;
 	char * ptr;
 
-	page = virt_to_page((unsigned long)p >> PAGE_SHIFT);
+	page = virt_to_page((unsigned long)p);
 	if (PageUncached(page))
 		ptr = (char *)__pa(p) + __IA64_UNCACHED_OFFSET;
 	else
diff --git a/include/asm-m68knommu/irq_regs.h b/include/asm-m68knommu/irq_regs.h
new file mode 100644
index 0000000..3dd9c0b
--- /dev/null
+++ b/include/asm-m68knommu/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-m68knommu/irqnode.h b/include/asm-m68knommu/irqnode.h
index a2503df..6132a98 100644
--- a/include/asm-m68knommu/irqnode.h
+++ b/include/asm-m68knommu/irqnode.h
@@ -8,7 +8,7 @@
  * interrupt source (if it supports chaining).
  */
 typedef struct irq_node {
-	irqreturn_t	(*handler)(int, void *, struct pt_regs *);
+	irq_handler_t	handler;
 	unsigned long	flags;
 	void		*dev_id;
 	const char	*devname;
@@ -18,12 +18,12 @@
 /*
  * This structure has only 4 elements for speed reasons
  */
-typedef struct irq_handler {
-	irqreturn_t	(*handler)(int, void *, struct pt_regs *);
+struct irq_entry {
+	irq_handler_t	handler;
 	unsigned long	flags;
 	void		*dev_id;
 	const char	*devname;
-} irq_handler_t;
+};
 
 /* count of spurious interrupts */
 extern volatile unsigned int num_spurious;
diff --git a/include/asm-m68knommu/machdep.h b/include/asm-m68knommu/machdep.h
index 27c90af..6ce28f8 100644
--- a/include/asm-m68knommu/machdep.h
+++ b/include/asm-m68knommu/machdep.h
@@ -18,7 +18,7 @@
 extern void (*mach_kbd_leds) (unsigned int);
 /* machine dependent irq functions */
 extern void (*mach_init_IRQ) (void);
-extern irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
+extern irq_handler_t mach_default_handler;
 extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
                                 unsigned long flags, const char *devname, void *dev_id);
 extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h
index e3038a4..838eb31 100644
--- a/include/asm-mips/asm.h
+++ b/include/asm-mips/asm.h
@@ -344,6 +344,7 @@
 #define PTR_L		lw
 #define PTR_S		sw
 #define PTR_LA		la
+#define PTR_LI		li
 #define PTR_SLL		sll
 #define PTR_SLLV	sllv
 #define PTR_SRL		srl
@@ -368,6 +369,7 @@
 #define PTR_L		ld
 #define PTR_S		sd
 #define PTR_LA		dla
+#define PTR_LI		dli
 #define PTR_SLL		dsll
 #define PTR_SLLV	dsllv
 #define PTR_SRL		dsrl
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index 9ab59e2..e3c9925 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -55,24 +55,13 @@
 #define flush_cache_vmap(start, end)		flush_cache_all()
 #define flush_cache_vunmap(start, end)		flush_cache_all()
 
-static inline void copy_to_user_page(struct vm_area_struct *vma,
+extern void copy_to_user_page(struct vm_area_struct *vma,
 	struct page *page, unsigned long vaddr, void *dst, const void *src,
-	unsigned long len)
-{
-	if (cpu_has_dc_aliases)
-		flush_cache_page(vma, vaddr, page_to_pfn(page));
-	memcpy(dst, src, len);
-	__flush_icache_page(vma, page);
-}
+	unsigned long len);
 
-static inline void copy_from_user_page(struct vm_area_struct *vma,
+extern void copy_from_user_page(struct vm_area_struct *vma,
 	struct page *page, unsigned long vaddr, void *dst, const void *src,
-	unsigned long len)
-{
-	if (cpu_has_dc_aliases)
-		flush_cache_page(vma, vaddr, page_to_pfn(page));
-	memcpy(dst, src, len);
-}
+	unsigned long len);
 
 extern void (*flush_cache_sigtramp)(unsigned long addr);
 extern void (*flush_icache_all)(void);
diff --git a/include/asm-mips/div64.h b/include/asm-mips/div64.h
index 5f7dcf5..d107832 100644
--- a/include/asm-mips/div64.h
+++ b/include/asm-mips/div64.h
@@ -83,27 +83,6 @@
 #if (_MIPS_SZLONG == 64)
 
 /*
- * Don't use this one in new code
- */
-#define do_div64_32(res, high, low, base) ({ \
-	unsigned int __quot, __mod; \
-	unsigned long __div; \
-	unsigned int __low, __high, __base; \
-	\
-	__high = (high); \
-	__low = (low); \
-	__div = __high; \
-	__div = __div << 32 | __low; \
-	__base = (base); \
-	\
-	__mod = __div % __base; \
-	__div = __div / __base; \
-	\
-	__quot = __div; \
-	(res) = __quot; \
-	__mod; })
-
-/*
  * Hey, we're already 64-bit, no
  * need to play games..
  */
diff --git a/include/asm-mips/fixmap.h b/include/asm-mips/fixmap.h
index 6959bdb..02c8a13 100644
--- a/include/asm-mips/fixmap.h
+++ b/include/asm-mips/fixmap.h
@@ -45,8 +45,16 @@
  * fix-mapped?
  */
 enum fixed_addresses {
+#define FIX_N_COLOURS 8
+	FIX_CMAP_BEGIN,
+#ifdef CONFIG_MIPS_MT_SMTC
+	FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS),
+#else
+	FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
+#endif
 #ifdef CONFIG_HIGHMEM
-	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
+	/* reserved pte's for temporary kernel mappings */
+	FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
 #endif
 	__end_of_fixed_addresses
@@ -70,9 +78,9 @@
  * at the top of mem..
  */
 #if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX)
-#define FIXADDR_TOP	(0xff000000UL - 0x2000)
+#define FIXADDR_TOP	((unsigned long)(long)(int)(0xff000000 - 0x20000))
 #else
-#define FIXADDR_TOP	(0xffffe000UL)
+#define FIXADDR_TOP	((unsigned long)(long)(int)0xfffe0000)
 #endif
 #define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
index 0ce2a80..35a05ca 100644
--- a/include/asm-mips/irq.h
+++ b/include/asm-mips/irq.h
@@ -74,4 +74,8 @@
                           unsigned long hwmask);
 #endif /* CONFIG_MIPS_MT_SMTC */
 
+extern int allocate_irqno(void);
+extern void alloc_legacy_irqno(void);
+extern void free_irqno(unsigned int irq);
+
 #endif /* _ASM_IRQ_H */
diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
index 301e713..e9fa252 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_ide.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
@@ -170,10 +170,8 @@
         static int auide_dma_host_on(ide_drive_t *drive);
         static int auide_dma_lostirq(ide_drive_t *drive);
         static int auide_dma_on(ide_drive_t *drive);
-        static void auide_ddma_tx_callback(int irq, void *param,
-                                           struct pt_regs *regs);
-        static void auide_ddma_rx_callback(int irq, void *param,
-                                           struct pt_regs *regs);
+        static void auide_ddma_tx_callback(int irq, void *param);
+        static void auide_ddma_rx_callback(int irq, void *param);
         static int auide_dma_off_quietly(ide_drive_t *drive);
 #endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
 
diff --git a/include/asm-mips/mipsmtregs.h b/include/asm-mips/mipsmtregs.h
index f637ce7..3e9468f 100644
--- a/include/asm-mips/mipsmtregs.h
+++ b/include/asm-mips/mipsmtregs.h
@@ -352,6 +352,8 @@
 #define write_vpe_c0_vpecontrol(val)	mttc0(1, 1, val)
 #define read_vpe_c0_vpeconf0()		mftc0(1, 2)
 #define write_vpe_c0_vpeconf0(val)	mttc0(1, 2, val)
+#define read_vpe_c0_count()		mftc0(9, 0)
+#define write_vpe_c0_count(val)		mttc0(9, 0, val)
 #define read_vpe_c0_status()		mftc0(12, 0)
 #define write_vpe_c0_status(val)	mttc0(12, 0, val)
 #define read_vpe_c0_cause()		mftc0(13, 0)
diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h
index 582c1fe..af121c6 100644
--- a/include/asm-mips/pgalloc.h
+++ b/include/asm-mips/pgalloc.h
@@ -48,7 +48,7 @@
 
 	ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
 	if (ret) {
-		init = pgd_offset(&init_mm, 0);
+		init = pgd_offset(&init_mm, 0UL);
 		pgd_init((unsigned long)ret);
 		memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
 		       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h
index d05fb6f..7e73203 100644
--- a/include/asm-mips/pgtable-64.h
+++ b/include/asm-mips/pgtable-64.h
@@ -174,7 +174,7 @@
 #define __pmd_offset(address)	pmd_index(address)
 
 /* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, 0)
+#define pgd_offset_k(address) pgd_offset(&init_mm, 0UL)
 
 #define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 #define pmd_index(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
index b09e16c..2ba6988 100644
--- a/include/asm-mips/sibyte/sb1250.h
+++ b/include/asm-mips/sibyte/sb1250.h
@@ -51,8 +51,8 @@
 extern void sb1250_unmask_irq(int cpu, int irq);
 extern void sb1250_smp_finish(void);
 
+extern void bcm1480_hpt_setup(void);
 extern void bcm1480_time_init(void);
-extern unsigned long bcm1480_gettimeoffset(void);
 extern void bcm1480_mask_irq(int cpu, int irq);
 extern void bcm1480_unmask_irq(int cpu, int irq);
 extern void bcm1480_smp_finish(void);
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index dcb4701..3056fee 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -392,7 +392,7 @@
 {
 	__u64 retval;
 
-	if (cpu_has_llsc) {
+	if (cpu_has_llsc && R10000_LLSC_WAR) {
 		__asm__ __volatile__(
 		"	.set	push					\n"
 		"	.set	noat					\n"
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index 28512ba..625acd3 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -48,7 +48,8 @@
  * If mips_hpt_read is NULL, an R4k-compatible timer setup is attempted.
  */
 extern unsigned int (*mips_hpt_read)(void);
-extern void (*mips_hpt_init)(unsigned int);
+extern void (*mips_hpt_init)(void);
+extern unsigned int mips_hpt_mask;
 
 /*
  * to_tm() converts system time back to (year, mon, day, hour, min, sec).
@@ -58,13 +59,6 @@
 extern void to_tm(unsigned long tim, struct rtc_time *tm);
 
 /*
- * do_gettimeoffset(). By default, this func pointer points to
- * do_null_gettimeoffset(), which leads to the same resolution as HZ.
- * Higher resolution versions are available, which give ~1us resolution.
- */
-extern unsigned long (*do_gettimeoffset)(void);
-
-/*
  * high-level timer interrupt routines.
  */
 extern irqreturn_t timer_interrupt(int irq, void *dev_id);
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index 30240a4..ec56aa5 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -332,16 +332,18 @@
 #define __NR_set_robust_list		(__NR_Linux + 309)
 #define __NR_get_robust_list		(__NR_Linux + 310)
 #define __NR_kexec_load			(__NR_Linux + 311)
+#define __NR_getcpu			(__NR_Linux + 312)
+#define __NR_epoll_pwait		(__NR_Linux + 313)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls		311
+#define __NR_Linux_syscalls		313
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux			4000
-#define __NR_O32_Linux_syscalls		311
+#define __NR_O32_Linux_syscalls		313
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
@@ -620,16 +622,18 @@
 #define __NR_set_robust_list		(__NR_Linux + 268)
 #define __NR_get_robust_list		(__NR_Linux + 269)
 #define __NR_kexec_load			(__NR_Linux + 270)
+#define __NR_getcpu			(__NR_Linux + 271)
+#define __NR_epoll_pwait		(__NR_Linux + 272)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls		270
+#define __NR_Linux_syscalls		272
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux			5000
-#define __NR_64_Linux_syscalls		270
+#define __NR_64_Linux_syscalls		272
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
@@ -912,16 +916,18 @@
 #define __NR_set_robust_list		(__NR_Linux + 272)
 #define __NR_get_robust_list		(__NR_Linux + 273)
 #define __NR_kexec_load			(__NR_Linux + 274)
+#define __NR_getcpu			(__NR_Linux + 275)
+#define __NR_epoll_pwait		(__NR_Linux + 276)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls		274
+#define __NR_Linux_syscalls		276
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux			6000
-#define __NR_N32_Linux_syscalls		274
+#define __NR_N32_Linux_syscalls		276
 
 #ifdef __KERNEL__
 
@@ -1189,6 +1195,7 @@
 #endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
 
 
+#define __ARCH_OMIT_COMPAT_SYS_GETDENTS64
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h
index c9ee41c..d45827a 100644
--- a/include/asm-parisc/semaphore.h
+++ b/include/asm-parisc/semaphore.h
@@ -115,7 +115,8 @@
  */
 extern __inline__ int down_trylock(struct semaphore * sem)
 {
-	int flags, count;
+	unsigned long flags;
+	int count;
 
 	spin_lock_irqsave(&sem->sentry, flags);
 	count = sem->count - 1;
@@ -131,7 +132,8 @@
  */
 extern __inline__ void up(struct semaphore * sem)
 {
-	int flags;
+	unsigned long flags;
+
 	spin_lock_irqsave(&sem->sentry, flags);
 	if (sem->count < 0) {
 		__up(sem);
diff --git a/include/asm-powerpc/asm-compat.h b/include/asm-powerpc/asm-compat.h
index 8e64be0..c89bd58 100644
--- a/include/asm-powerpc/asm-compat.h
+++ b/include/asm-powerpc/asm-compat.h
@@ -14,6 +14,58 @@
 #  define ASM_CONST(x)		__ASM_CONST(x)
 #endif
 
+
+/*
+ * Feature section common macros
+ *
+ * Note that the entries now contain offsets between the table entry
+ * and the code rather than absolute code pointers in order to be
+ * useable with the vdso shared library. There is also an assumption
+ * that values will be negative, that is, the fixup table has to be
+ * located after the code it fixes up.
+ */
+#ifdef CONFIG_PPC64
+#ifdef __powerpc64__
+/* 64 bits kernel, 64 bits code */
+#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect)	\
+99:							\
+	.section sect,"a";				\
+	.align 3;					\
+98:						       	\
+	.llong msk;					\
+	.llong val;					\
+	.llong label##b-98b;				\
+	.llong 99b-98b;		 			\
+	.previous
+#else /* __powerpc64__ */
+/* 64 bits kernel, 32 bits code (ie. vdso32) */
+#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect)	\
+99:							\
+	.section sect,"a";				\
+	.align 3;					\
+98:						       	\
+	.llong msk;					\
+	.llong val;					\
+	.long 0xffffffff;      				\
+	.long label##b-98b;				\
+	.long 0xffffffff;	       			\
+	.long 99b-98b;		 			\
+	.previous
+#endif /* !__powerpc64__ */
+#else /* CONFIG_PPC64 */
+/* 32 bits kernel, 32 bits code */
+#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect)	\
+99:						       	\
+	.section sect,"a";			       	\
+	.align 2;				       	\
+98:						       	\
+	.long msk;				       	\
+	.long val;				       	\
+	.long label##b-98b;			       	\
+	.long 99b-98b;				       	\
+	.previous
+#endif /* !CONFIG_PPC64 */
+
 #ifdef __powerpc64__
 
 /* operations for longs and pointers */
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 12707ab..a9a4014 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -89,8 +89,11 @@
 
 extern struct cpu_spec		*cur_cpu_spec;
 
-extern void identify_cpu(unsigned long offset, unsigned long cpu);
-extern void do_cpu_ftr_fixups(unsigned long offset);
+extern unsigned int __start___ftr_fixup, __stop___ftr_fixup;
+
+extern struct cpu_spec *identify_cpu(unsigned long offset);
+extern void do_feature_fixups(unsigned long value, void *fixup_start,
+			      void *fixup_end);
 
 #endif /* __ASSEMBLY__ */
 
@@ -144,6 +147,7 @@
 #define CPU_FTR_CI_LARGE_PAGE		LONG_ASM_CONST(0x0000100000000000)
 #define CPU_FTR_PAUSE_ZERO		LONG_ASM_CONST(0x0000200000000000)
 #define CPU_FTR_PURR			LONG_ASM_CONST(0x0000400000000000)
+#define CPU_FTR_CELL_TB_BUG		LONG_ASM_CONST(0x0000800000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -332,7 +336,7 @@
 #define CPU_FTRS_CELL	(CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
-	    CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE)
+	    CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG)
 #define CPU_FTRS_PA6T (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
@@ -431,29 +435,12 @@
 
 #ifdef __ASSEMBLY__
 
-#define BEGIN_FTR_SECTION		98:
-
-#ifndef __powerpc64__
+#define BEGIN_FTR_SECTION_NESTED(label)	label:
+#define BEGIN_FTR_SECTION		BEGIN_FTR_SECTION_NESTED(97)
+#define END_FTR_SECTION_NESTED(msk, val, label) \
+	MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup)
 #define END_FTR_SECTION(msk, val)		\
-99:						\
-	.section __ftr_fixup,"a";		\
-	.align 2;				\
-	.long msk;				\
-	.long val;				\
-	.long 98b;				\
-	.long 99b;				\
-	.previous
-#else /* __powerpc64__ */
-#define END_FTR_SECTION(msk, val)		\
-99:						\
-	.section __ftr_fixup,"a";		\
-	.align 3;				\
-	.llong msk;				\
-	.llong val;				\
-	.llong 98b;				\
-	.llong 99b;	 			\
-	.previous
-#endif /* __powerpc64__ */
+	END_FTR_SECTION_NESTED(msk, val, 97)
 
 #define END_FTR_SECTION_IFSET(msk)	END_FTR_SECTION((msk), (msk))
 #define END_FTR_SECTION_IFCLR(msk)	END_FTR_SECTION((msk), 0)
diff --git a/include/asm-powerpc/current.h b/include/asm-powerpc/current.h
index 1938d6ab..b8708ae 100644
--- a/include/asm-powerpc/current.h
+++ b/include/asm-powerpc/current.h
@@ -14,7 +14,17 @@
 #ifdef __powerpc64__
 #include <asm/paca.h>
 
-#define current		(get_paca()->__current)
+static inline struct task_struct *get_current(void)
+{
+	struct task_struct *task;
+
+	__asm__ __volatile__("ld %0,%1(13)"
+	: "=r" (task)
+	: "i" (offsetof(struct paca_struct, __current)));
+
+	return task;
+}
+#define current	get_current()
 
 #else
 
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index 1022737..fdf9aff 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -96,19 +96,16 @@
 /* This is true if we are using the firmware NMI handler (typically LPAR) */
 extern int fwnmi_active;
 
+extern unsigned int __start___fw_ftr_fixup, __stop___fw_ftr_fixup;
+
 #else /* __ASSEMBLY__ */
 
-#define BEGIN_FW_FTR_SECTION		96:
-
+#define BEGIN_FW_FTR_SECTION_NESTED(label)	label:
+#define BEGIN_FW_FTR_SECTION			BEGIN_FW_FTR_SECTION_NESTED(97)
+#define END_FW_FTR_SECTION_NESTED(msk, val, label) \
+	MAKE_FTR_SECTION_ENTRY(msk, val, label, __fw_ftr_fixup)
 #define END_FW_FTR_SECTION(msk, val)		\
-97:						\
-	.section __fw_ftr_fixup,"a";		\
-	.align 3;				\
-	.llong msk;				\
-	.llong val;				\
-	.llong 96b;				\
-	.llong 97b;				\
-	.previous
+	END_FW_FTR_SECTION_NESTED(msk, val, 97)
 
 #define END_FW_FTR_SECTION_IFSET(msk)	END_FW_FTR_SECTION((msk), (msk))
 #define END_FW_FTR_SECTION_IFCLR(msk)	END_FW_FTR_SECTION((msk), 0)
diff --git a/include/asm-powerpc/i8259.h b/include/asm-powerpc/i8259.h
index 78489fb..db1362f 100644
--- a/include/asm-powerpc/i8259.h
+++ b/include/asm-powerpc/i8259.h
@@ -7,6 +7,7 @@
 #ifdef CONFIG_PPC_MERGE
 extern void i8259_init(struct device_node *node, unsigned long intack_addr);
 extern unsigned int i8259_irq(void);
+extern struct irq_host *i8259_get_host(void);
 #else
 extern void i8259_init(unsigned long intack_addr, int offset);
 extern int i8259_irq(void);
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 3baff8b..c2c5f14 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -163,8 +163,11 @@
 
 static inline void mmiowb(void)
 {
-	__asm__ __volatile__ ("sync" : : : "memory");
-	get_paca()->io_sync = 0;
+	unsigned long tmp;
+
+	__asm__ __volatile__("sync; li %0,0; stb %0,%1(13)"
+	: "=&r" (tmp) : "i" (offsetof(struct paca_struct, io_sync))
+	: "memory");
 }
 
 /*
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index a5e9864..39fad68 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -22,17 +22,35 @@
 #define _ASM_IOMMU_H
 #ifdef __KERNEL__
 
-#include <asm/types.h>
+#include <linux/compiler.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <asm/types.h>
+#include <asm/bitops.h>
+
+#define IOMMU_PAGE_SHIFT      12
+#define IOMMU_PAGE_SIZE       (ASM_CONST(1) << IOMMU_PAGE_SHIFT)
+#define IOMMU_PAGE_MASK       (~((1 << IOMMU_PAGE_SHIFT) - 1))
+#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE)
+
+#ifndef __ASSEMBLY__
+
+/* Pure 2^n version of get_order */
+static __inline__ __attribute_const__ int get_iommu_order(unsigned long size)
+{
+	return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT) + 1;
+}
+
+#endif   /* __ASSEMBLY__ */
+
 
 /*
  * IOMAP_MAX_ORDER defines the largest contiguous block
  * of dma space we can get.  IOMAP_MAX_ORDER = 13
  * allows up to 2**12 pages (4096 * 4096) = 16 MB
  */
-#define IOMAP_MAX_ORDER 13
+#define IOMAP_MAX_ORDER		13
 
 struct iommu_table {
 	unsigned long  it_busno;     /* Bus number this table belongs to */
diff --git a/include/asm-powerpc/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h
index 5b33994..07a10e5 100644
--- a/include/asm-powerpc/oprofile_impl.h
+++ b/include/asm-powerpc/oprofile_impl.h
@@ -42,7 +42,7 @@
 	void (*reg_setup) (struct op_counter_config *,
 			   struct op_system_config *,
 			   int num_counters);
-	void (*cpu_setup) (void *);
+	void (*cpu_setup) (struct op_counter_config *);
 	void (*start) (struct op_counter_config *);
 	void (*stop) (void);
 	void (*handle_interrupt) (struct pt_regs *,
@@ -121,7 +121,90 @@
 		break;
 	}
 }
-#endif /* !CONFIG_FSL_BOOKE */
+#else /* CONFIG_FSL_BOOKE */
+static inline u32 get_pmlca(int ctr)
+{
+	u32 pmlca;
+
+	switch (ctr) {
+		case 0:
+			pmlca = mfpmr(PMRN_PMLCA0);
+			break;
+		case 1:
+			pmlca = mfpmr(PMRN_PMLCA1);
+			break;
+		case 2:
+			pmlca = mfpmr(PMRN_PMLCA2);
+			break;
+		case 3:
+			pmlca = mfpmr(PMRN_PMLCA3);
+			break;
+		default:
+			panic("Bad ctr number\n");
+	}
+
+	return pmlca;
+}
+
+static inline void set_pmlca(int ctr, u32 pmlca)
+{
+	switch (ctr) {
+		case 0:
+			mtpmr(PMRN_PMLCA0, pmlca);
+			break;
+		case 1:
+			mtpmr(PMRN_PMLCA1, pmlca);
+			break;
+		case 2:
+			mtpmr(PMRN_PMLCA2, pmlca);
+			break;
+		case 3:
+			mtpmr(PMRN_PMLCA3, pmlca);
+			break;
+		default:
+			panic("Bad ctr number\n");
+	}
+}
+
+static inline unsigned int ctr_read(unsigned int i)
+{
+	switch(i) {
+		case 0:
+			return mfpmr(PMRN_PMC0);
+		case 1:
+			return mfpmr(PMRN_PMC1);
+		case 2:
+			return mfpmr(PMRN_PMC2);
+		case 3:
+			return mfpmr(PMRN_PMC3);
+		default:
+			return 0;
+	}
+}
+
+static inline void ctr_write(unsigned int i, unsigned int val)
+{
+	switch(i) {
+		case 0:
+			mtpmr(PMRN_PMC0, val);
+			break;
+		case 1:
+			mtpmr(PMRN_PMC1, val);
+			break;
+		case 2:
+			mtpmr(PMRN_PMC2, val);
+			break;
+		case 3:
+			mtpmr(PMRN_PMC3, val);
+			break;
+		default:
+			break;
+	}
+}
+
+
+#endif /* CONFIG_FSL_BOOKE */
+
 
 extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth);
 
diff --git a/include/asm-powerpc/pmc.h b/include/asm-powerpc/pmc.h
index 07d6a42..8588be6 100644
--- a/include/asm-powerpc/pmc.h
+++ b/include/asm-powerpc/pmc.h
@@ -32,18 +32,5 @@
 void power4_enable_pmcs(void);
 #endif
 
-#ifdef CONFIG_FSL_BOOKE
-void init_pmc_stop(int ctr);
-void set_pmc_event(int ctr, int event);
-void set_pmc_user_kernel(int ctr, int user, int kernel);
-void set_pmc_marked(int ctr, int mark0, int mark1);
-void pmc_start_ctr(int ctr, int enable);
-void pmc_start_ctrs(int enable);
-void pmc_stop_ctrs(void);
-void dump_pmcs(void);
-
-extern struct op_powerpc_model op_model_fsl_booke;
-#endif
-
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PMC_H */
diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h
index a940cfe..fa083d8 100644
--- a/include/asm-powerpc/ppc_asm.h
+++ b/include/asm-powerpc/ppc_asm.h
@@ -30,9 +30,9 @@
 	mfspr	ra,SPRN_PURR;		/* get processor util. reg */	\
 END_FTR_SECTION_IFSET(CPU_FTR_PURR);					\
 BEGIN_FTR_SECTION;							\
-	mftb	ra;			/* or get TB if no PURR */	\
+	MFTB(ra);			/* or get TB if no PURR */	\
 END_FTR_SECTION_IFCLR(CPU_FTR_PURR);					\
-	ld	rb,PACA_STARTPURR(r13);				\
+	ld	rb,PACA_STARTPURR(r13);					\
 	std	ra,PACA_STARTPURR(r13);					\
 	subf	rb,rb,ra;		/* subtract start value */	\
 	ld	ra,PACA_USER_TIME(r13);					\
@@ -45,9 +45,9 @@
 	mfspr	ra,SPRN_PURR;		/* get processor util. reg */	\
 END_FTR_SECTION_IFSET(CPU_FTR_PURR);					\
 BEGIN_FTR_SECTION;							\
-	mftb	ra;			/* or get TB if no PURR */	\
+	MFTB(ra);			/* or get TB if no PURR */	\
 END_FTR_SECTION_IFCLR(CPU_FTR_PURR);					\
-	ld	rb,PACA_STARTPURR(r13);				\
+	ld	rb,PACA_STARTPURR(r13);					\
 	std	ra,PACA_STARTPURR(r13);					\
 	subf	rb,rb,ra;		/* subtract start value */	\
 	ld	ra,PACA_SYSTEM_TIME(r13);				\
@@ -274,6 +274,16 @@
 #define ISYNC_601
 #endif
 
+#ifdef CONFIG_PPC_CELL
+#define MFTB(dest)			\
+90:	mftb  dest;			\
+BEGIN_FTR_SECTION_NESTED(96);		\
+	cmpwi dest,0;			\
+	beq-  90b;			\
+END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
+#else
+#define MFTB(dest)			mftb dest
+#endif
 
 #ifndef CONFIG_SMP
 #define TLBSYNC
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 5246297..ec11d44 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -134,7 +134,7 @@
 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);
-extern struct property *of_find_property(struct device_node *np,
+extern struct property *of_find_property(const struct device_node *np,
 					 const char *name,
 					 int *lenp);
 extern struct device_node *of_node_get(struct device_node *node);
@@ -158,10 +158,12 @@
 extern void finish_device_tree(void);
 extern void unflatten_device_tree(void);
 extern void early_init_devtree(void *);
-extern int device_is_compatible(struct device_node *device, const char *);
+extern int device_is_compatible(const struct device_node *device,
+				const char *);
 extern int machine_is_compatible(const char *compat);
-extern const void *get_property(struct device_node *node, const char *name,
-		int *lenp);
+extern const void *get_property(const struct device_node *node,
+				const char *name,
+				int *lenp);
 extern void print_properties(struct device_node *node);
 extern int prom_n_addr_cells(struct device_node* np);
 extern int prom_n_size_cells(struct device_node* np);
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 8fb9681..6faae7b 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -591,6 +591,7 @@
 #define PV_630		0x0040
 #define PV_630p	0x0041
 #define PV_970MP	0x0044
+#define PV_970GX	0x0045
 #define PV_BE		0x0070
 #define PV_PA6T		0x0090
 
@@ -618,10 +619,35 @@
 				: "=r" (rval)); rval;})
 #define mtspr(rn, v)	asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
 
+#ifdef __powerpc64__
+#ifdef CONFIG_PPC_CELL
+#define mftb()		({unsigned long rval;				\
+			asm volatile(					\
+				"90:	mftb %0;\n"			\
+				"97:	cmpwi %0,0;\n"			\
+				"	beq- 90b;\n"			\
+				"99:\n"					\
+				".section __ftr_fixup,\"a\"\n"		\
+				".align 3\n"				\
+				"98:\n"					\
+				"	.llong %1\n"			\
+				"	.llong %1\n"			\
+				"	.llong 97b-98b\n"		\
+				"	.llong 99b-98b\n"		\
+				".previous"				\
+			: "=r" (rval) : "i" (CPU_FTR_CELL_TB_BUG)); rval;})
+#else
 #define mftb()		({unsigned long rval;	\
 			asm volatile("mftb %0" : "=r" (rval)); rval;})
+#endif /* !CONFIG_PPC_CELL */
+
+#else /* __powerpc64__ */
+
 #define mftbl()		({unsigned long rval;	\
 			asm volatile("mftbl %0" : "=r" (rval)); rval;})
+#define mftbu()		({unsigned long rval;	\
+			asm volatile("mftbu %0" : "=r" (rval)); rval;})
+#endif /* !__powerpc64__ */
 
 #define mttbl(v)	asm volatile("mttbl %0":: "r"(v))
 #define mttbu(v)	asm volatile("mttbu %0":: "r"(v))
diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h
index eac85ce..97b4354 100644
--- a/include/asm-powerpc/systbl.h
+++ b/include/asm-powerpc/systbl.h
@@ -261,7 +261,7 @@
 PPC_SYS_SPU(rtas)
 OLDSYS(debug_setcontext)
 SYSCALL(ni_syscall)
-SYSCALL(ni_syscall)
+COMPAT_SYS(migrate_pages)
 COMPAT_SYS(mbind)
 COMPAT_SYS(get_mempolicy)
 COMPAT_SYS(set_mempolicy)
@@ -304,3 +304,4 @@
 SYSCALL_SPU(faccessat)
 COMPAT_SYS_SPU(get_robust_list)
 COMPAT_SYS_SPU(set_robust_list)
+COMPAT_SYS(move_pages)
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 4362759..f7b1227 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -25,8 +25,8 @@
  *
  * We have to use the sync instructions for mb(), since lwsync doesn't
  * order loads with respect to previous stores.  Lwsync is fine for
- * rmb(), though.  Note that lwsync is interpreted as sync by
- * 32-bit and older 64-bit CPUs.
+ * rmb(), though. Note that rmb() actually uses a sync on 32-bit
+ * architectures.
  *
  * For wmb(), we use sync since wmb is used in drivers to order
  * stores to system memory with respect to writes to the device.
@@ -34,7 +34,7 @@
  * SMP since it is only used to order updates to system memory.
  */
 #define mb()   __asm__ __volatile__ ("sync" : : : "memory")
-#define rmb()  __asm__ __volatile__ ("lwsync" : : : "memory")
+#define rmb()  __asm__ __volatile__ (__stringify(LWSYNC) : : : "memory")
 #define wmb()  __asm__ __volatile__ ("sync" : : : "memory")
 #define read_barrier_depends()  do { } while(0)
 
diff --git a/include/asm-powerpc/tce.h b/include/asm-powerpc/tce.h
index c9483ad..f663634 100644
--- a/include/asm-powerpc/tce.h
+++ b/include/asm-powerpc/tce.h
@@ -22,6 +22,8 @@
 #define _ASM_POWERPC_TCE_H
 #ifdef __KERNEL__
 
+#include <asm/iommu.h>
+
 /*
  * Tces come in two formats, one for the virtual bus and a different
  * format for PCI
@@ -33,7 +35,6 @@
 
 #define TCE_SHIFT	12
 #define TCE_PAGE_SIZE	(1 << TCE_SHIFT)
-#define TCE_PAGE_FACTOR	(PAGE_SHIFT - TCE_SHIFT)
 
 #define TCE_ENTRY_SIZE		8		/* each TCE is 64 bits */
 
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
index b051d4c..4cff977 100644
--- a/include/asm-powerpc/time.h
+++ b/include/asm-powerpc/time.h
@@ -39,10 +39,6 @@
 extern void wakeup_decrementer(void);
 extern void snapshot_timebase(void);
 
-#ifdef CONFIG_RTC_CLASS
-extern int __init rtc_class_hookup(void);
-#endif
-
 /* Some sane defaults: 125 MHz timebase, 1GHz processor */
 extern unsigned long ppc_proc_freq;
 #define DEFAULT_PROC_FREQ	(DEFAULT_TB_FREQ * 8)
@@ -82,30 +78,35 @@
 #define __USE_RTC()	0
 #endif
 
-/* On ppc64 this gets us the whole timebase; on ppc32 just the lower half */
+#ifdef CONFIG_PPC64
+
+/* For compatibility, get_tbl() is defined as get_tb() on ppc64 */
+#define get_tbl		get_tb
+
+#else
+
 static inline unsigned long get_tbl(void)
 {
-	unsigned long tbl;
-
 #if defined(CONFIG_403GCX)
+	unsigned long tbl;
 	asm volatile("mfspr %0, 0x3dd" : "=r" (tbl));
-#else
-	asm volatile("mftb %0" : "=r" (tbl));
-#endif
 	return tbl;
+#else
+	return mftbl();
+#endif
 }
 
 static inline unsigned int get_tbu(void)
 {
+#ifdef CONFIG_403GCX
 	unsigned int tbu;
-
-#if defined(CONFIG_403GCX)
 	asm volatile("mfspr %0, 0x3dc" : "=r" (tbu));
-#else
-	asm volatile("mftbu %0" : "=r" (tbu));
-#endif
 	return tbu;
+#else
+	return mftbu();
+#endif
 }
+#endif /* !CONFIG_PPC64 */
 
 static inline unsigned int get_rtcl(void)
 {
@@ -131,7 +132,7 @@
 {
 	return mftb();
 }
-#else
+#else /* CONFIG_PPC64 */
 static inline u64 get_tb(void)
 {
 	unsigned int tbhi, tblo, tbhi2;
@@ -144,7 +145,7 @@
 
 	return ((u64)tbhi << 32) | tblo;
 }
-#endif
+#endif /* !CONFIG_PPC64 */
 
 static inline void set_tb(unsigned int upper, unsigned int lower)
 {
diff --git a/include/asm-powerpc/timex.h b/include/asm-powerpc/timex.h
index 3b9a8e7..92dedde 100644
--- a/include/asm-powerpc/timex.h
+++ b/include/asm-powerpc/timex.h
@@ -8,6 +8,7 @@
  */
 
 #include <asm/cputable.h>
+#include <asm/reg.h>
 
 #define CLOCK_TICK_RATE	1024000 /* Underlying HZ */
 
@@ -15,13 +16,11 @@
 
 static inline cycles_t get_cycles(void)
 {
+#ifdef __powerpc64__
+	return mftb();
+#else
 	cycles_t ret;
 
-#ifdef __powerpc64__
-
-	__asm__ __volatile__("mftb %0" : "=r" (ret) : );
-
-#else
 	/*
 	 * For the "cycle" counter we use the timebase lower half.
 	 * Currently only used on SMP.
@@ -30,18 +29,19 @@
 	ret = 0;
 
 	__asm__ __volatile__(
-		"98:	mftb %0\n"
+		"97:	mftb %0\n"
 		"99:\n"
 		".section __ftr_fixup,\"a\"\n"
+		".align 2\n"
+		"98:\n"
 		"	.long %1\n"
 		"	.long 0\n"
-		"	.long 98b\n"
-		"	.long 99b\n"
+		"	.long 97b-98b\n"
+		"	.long 99b-98b\n"
 		".previous"
 		: "=r" (ret) : "i" (CPU_FTR_601));
-#endif
-
 	return ret;
+#endif
 }
 
 #endif	/* __KERNEL__ */
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index 8f7ee16..9fe7894 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -96,7 +96,13 @@
 
 #ifdef CONFIG_SMP
 #include <asm/cputable.h>
-#define smt_capable() 		(cpu_has_feature(CPU_FTR_SMT))
+#define smt_capable()		(cpu_has_feature(CPU_FTR_SMT))
+
+#ifdef CONFIG_PPC64
+#include <asm/smp.h>
+
+#define topology_thread_siblings(cpu)	(cpu_sibling_map[cpu])
+#endif
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index 464a48c..0e4ea37 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -276,7 +276,7 @@
 #define __NR_rtas		255
 #define __NR_sys_debug_setcontext 256
 /* Number 257 is reserved for vserver */
-/* 258 currently unused */
+#define __NR_migrate_pages	258
 #define __NR_mbind		259
 #define __NR_get_mempolicy	260
 #define __NR_set_mempolicy	261
@@ -323,10 +323,11 @@
 #define __NR_faccessat		298
 #define __NR_get_robust_list	299
 #define __NR_set_robust_list	300
+#define __NR_move_pages		301
 
 #ifdef __KERNEL__
 
-#define __NR_syscalls		301
+#define __NR_syscalls		302
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
diff --git a/include/asm-sh/edosk7705/io.h b/include/asm-sh/edosk7705.h
similarity index 100%
rename from include/asm-sh/edosk7705/io.h
rename to include/asm-sh/edosk7705.h
diff --git a/include/asm-sh/hp6xx/hp6xx.h b/include/asm-sh/hp6xx.h
similarity index 100%
rename from include/asm-sh/hp6xx/hp6xx.h
rename to include/asm-sh/hp6xx.h
diff --git a/include/asm-sh/hp6xx/ide.h b/include/asm-sh/hp6xx/ide.h
deleted file mode 100644
index 570395a..0000000
--- a/include/asm-sh/hp6xx/ide.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __ASM_SH_HP6XX_IDE_H
-#define __ASM_SH_HP6XX_IDE_H
-
-#define IRQ_CFCARD	93
-#define IRQ_PCMCIA	94
-
-#endif /* __ASM_SH_HP6XX_IDE_H */
-
diff --git a/include/asm-sh/hp6xx/io.h b/include/asm-sh/hp6xx/io.h
deleted file mode 100644
index 2044476..0000000
--- a/include/asm-sh/hp6xx/io.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __ASM_SH_HP6XX_IO_H
-#define __ASM_SH_HP6XX_IO_H
-
-/*
- * Nothing special here.. just use the generic cchip io routines.
- */
-#include <asm/hd64461.h>
-
-#endif /* __ASM_SH_HP6XX_IO_H */
-
diff --git a/include/asm-sh/hs7751rvoip/hs7751rvoip.h b/include/asm-sh/hs7751rvoip.h
similarity index 100%
rename from include/asm-sh/hs7751rvoip/hs7751rvoip.h
rename to include/asm-sh/hs7751rvoip.h
diff --git a/include/asm-sh/hs7751rvoip/ide.h b/include/asm-sh/hs7751rvoip/ide.h
deleted file mode 100644
index 65ad1d0..0000000
--- a/include/asm-sh/hs7751rvoip/ide.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __ASM_SH_HS7751RVOIP_IDE_H
-#define __ASM_SH_HS7751RVOIP_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/hs7751rvoip/hs7751rvoip.h>
-
-#endif /* __ASM_SH_HS7751RVOIP_IDE_H */
-
diff --git a/include/asm-sh/irq-sh7780.h b/include/asm-sh/irq-sh7780.h
index 895c578..19912ae 100644
--- a/include/asm-sh/irq-sh7780.h
+++ b/include/asm-sh/irq-sh7780.h
@@ -6,16 +6,6 @@
  *
  * Copyright (C) 2004 Takashi SHUDO <shudo@hitachi-ul.co.jp>
  */
-
-#ifdef CONFIG_IDE
-# ifndef IRQ_CFCARD
-#  define IRQ_CFCARD	14
-# endif
-# ifndef IRQ_PCMCIA
-#  define IRQ_PCMCIA	15
-# endif
-#endif
-
 #define INTC_BASE	0xffd00000
 #define INTC_ICR0	(INTC_BASE+0x0)
 #define INTC_ICR1	(INTC_BASE+0x1c)
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index 28996f9..6cd3e9e 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -14,16 +14,6 @@
 #include <asm/machvec.h>
 #include <asm/ptrace.h>		/* for pt_regs */
 
-#if defined(CONFIG_SH_HP6XX) || \
-    defined(CONFIG_SH_RTS7751R2D) || \
-    defined(CONFIG_SH_HS7751RVOIP) || \
-    defined(CONFIG_SH_HS7751RVOIP) || \
-    defined(CONFIG_SH_SH03) || \
-    defined(CONFIG_SH_R7780RP) || \
-    defined(CONFIG_SH_LANDISK)
-#include <asm/mach/ide.h>
-#endif
-
 #ifndef CONFIG_CPU_SUBTYPE_SH7780
 
 #define INTC_DMAC0_MSK	0
@@ -38,15 +28,6 @@
 #define INTC_IPRD	0xffd00010UL
 #endif
 
-#ifdef CONFIG_IDE
-# ifndef IRQ_CFCARD
-#  define IRQ_CFCARD	14
-# endif
-# ifndef IRQ_PCMCIA
-#  define IRQ_PCMCIA	15
-# endif
-#endif
-
 #define TIMER_IRQ	16
 #define TIMER_IPR_ADDR	INTC_IPRA
 #define TIMER_IPR_POS	 3
@@ -346,11 +327,17 @@
  */
 void init_IRQ_pint(void);
 
+struct ipr_data {
+	unsigned int irq;
+	unsigned int addr;	/* Address of Interrupt Priority Register */
+	int shift;		/* Shifts of the 16-bit data */
+	int priority;		/* The priority */
+};
+
 /*
  * Function for "on chip support modules".
  */
-extern void make_ipr_irq(unsigned int irq, unsigned int addr,
-			 int pos,  int priority);
+extern void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs);
 extern void make_imask_irq(unsigned int irq);
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
@@ -704,7 +691,7 @@
 	unsigned char priority;
 };
 
-void make_intc2_irq(struct intc2_data *);
+void make_intc2_irq(struct intc2_data *, unsigned int nr_irqs);
 void init_IRQ_intc2(void);
 #endif
 
diff --git a/include/asm-sh/landisk/ide.h b/include/asm-sh/landisk/ide.h
deleted file mode 100644
index 6490e28..0000000
--- a/include/asm-sh/landisk/ide.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * modifed by kogiidena
- * 2005.03.03
- */
-
-#ifndef __ASM_SH_LANDISK_IDE_H
-#define __ASM_SH_LANDISK_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/landisk/iodata_landisk.h>
-#define IRQ_CFCARD	IRQ_FATA	/* CF Card IRQ */
-#define IRQ_PCMCIA	IRQ_ATA		/* PCMCIA IRQ */
-
-#endif /* __ASM_SH_LANDISK_IDE_H  */
diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h
index 4747738..45bb74e 100644
--- a/include/asm-sh/processor.h
+++ b/include/asm-sh/processor.h
@@ -255,6 +255,8 @@
  */
 #define thread_saved_pc(tsk)	(tsk->thread.pc)
 
+void show_trace(struct task_struct *tsk, unsigned long *sp,
+		struct pt_regs *regs);
 extern unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)  ((tsk)->thread.pc)
diff --git a/include/asm-sh/r7780rp/r7780rp.h b/include/asm-sh/r7780rp.h
similarity index 96%
rename from include/asm-sh/r7780rp/r7780rp.h
rename to include/asm-sh/r7780rp.h
index f95d9db..c18f648 100644
--- a/include/asm-sh/r7780rp/r7780rp.h
+++ b/include/asm-sh/r7780rp.h
@@ -72,8 +72,6 @@
 
 #define PA_AX88796L     0xa4100400      /* AX88796L Area */
 #define PA_SC1602BSLB   0xa6000000      /* SC1602BSLB Area */
-#define PA_AREA5_IO     0xb4000000      /* Area 5 IO Memory */
-#define PA_AREA6_IO     0xb8000000      /* Area 6 IO Memory */
 #define PA_IDE_OFFSET   0x1f0           /* CF IDE Offset */
 #define AX88796L_IO_BASE        0x1000  /* AX88796L IO Base Address */
 
@@ -83,7 +81,6 @@
 #define IRQ_PCISLOT2    66              /* PCI Slot #2 IRQ */
 #define IRQ_PCISLOT3    67              /* PCI Slot #3 IRQ */
 #define IRQ_PCISLOT4    68              /* PCI Slot #4 IRQ */
-#define IRQ_CFCARD      1               /* CF Card IRQ */
 // #define IRQ_CFINST   0               /* CF Card Insert IRQ */
 #define IRQ_TP          2               /* Touch Panel IRQ */
 #define IRQ_SCI1        3               /* SCI1 IRQ */
@@ -146,8 +143,6 @@
 
 #define PA_AX88796L	0xa5800400	/* AX88796L Area */
 #define PA_SC1602BSLB	0xa6000000	/* SC1602BSLB Area */
-#define PA_AREA5_IO	0xb4000000	/* Area 5 IO Memory */
-#define PA_AREA6_IO	0xb8000000	/* Area 6 IO Memory */
 #define PA_IDE_OFFSET	0x1f0		/* CF IDE Offset */
 #define AX88796L_IO_BASE	0x1000	/* AX88796L IO Base Address */
 
@@ -157,7 +152,6 @@
 #define IRQ_PCISLOT2	1		/* PCI Slot #2 IRQ */
 #define IRQ_PCISLOT3	2		/* PCI Slot #3 IRQ */
 #define IRQ_PCISLOT4	3		/* PCI Slot #4 IRQ */
-#define IRQ_CFCARD	4		/* CF Card IRQ */
 #define IRQ_CFINST	5		/* CF Card Insert IRQ */
 #define IRQ_M66596	6		/* M66596 IRQ */
 #define IRQ_SDCARD	7		/* SD Card IRQ */
diff --git a/include/asm-sh/r7780rp/ide.h b/include/asm-sh/r7780rp/ide.h
deleted file mode 100644
index a1ed78e..0000000
--- a/include/asm-sh/r7780rp/ide.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __ASM_SH_R7780RP_IDE_H
-#define __ASM_SH_R7780RP_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/mach/r7780rp.h>
-
-#endif /* __ASM_SH_R7780RP_IDE_H */
-
diff --git a/include/asm-sh/rts7751r2d/rts7751r2d.h b/include/asm-sh/rts7751r2d.h
similarity index 100%
rename from include/asm-sh/rts7751r2d/rts7751r2d.h
rename to include/asm-sh/rts7751r2d.h
diff --git a/include/asm-sh/rts7751r2d/ide.h b/include/asm-sh/rts7751r2d/ide.h
deleted file mode 100644
index 416f96b..0000000
--- a/include/asm-sh/rts7751r2d/ide.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __ASM_SH_RTS7751R2D_IDE_H
-#define __ASM_SH_RTS7751R2D_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/rts7751r2d/rts7751r2d.h>
-
-#endif /* __ASM_SH_RTS7751R2D_IDE_H */
-
diff --git a/include/asm-sh/sh03/ide.h b/include/asm-sh/sh03/ide.h
deleted file mode 100644
index 73ee92e..0000000
--- a/include/asm-sh/sh03/ide.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __ASM_SH_SH03_IDE_H
-#define __ASM_SH_SH03_IDE_H
-
-#define IRQ_CFCARD	8
-#define IRQ_PCMCIA	8
-
-#endif /* __ASM_SH_SH03_IDE_H */
diff --git a/include/asm-sh/shmin/shmin.h b/include/asm-sh/shmin.h
similarity index 100%
rename from include/asm-sh/shmin/shmin.h
rename to include/asm-sh/shmin.h
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index 6c1f8fd..3340126 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -353,6 +353,13 @@
 				    (unsigned long)_n_, sizeof(*(ptr))); \
   })
 
+extern void *set_exception_table_vec(unsigned int vec, void *handler);
+
+static inline void *set_exception_table_evt(unsigned int evt, void *handler)
+{
+	return set_exception_table_vec(evt >> 5, handler);
+}
+
 /* XXX
  * disable hlt during certain critical i/o operations
  */
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
index f1a0cbc..1c2abde 100644
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -324,8 +324,11 @@
 #define __NR_sync_file_range	314
 #define __NR_tee		315
 #define __NR_vmsplice		316
+#define __NR_move_pages		317
+#define __NR_getcpu		318
+#define __NR_epoll_pwait	319
 
-#define NR_syscalls 317
+#define NR_syscalls 320
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index c7a495a..f7827fa 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -318,12 +318,15 @@
 #define __NR_unshare		299
 #define __NR_set_robust_list	300
 #define __NR_get_robust_list	301
+#define __NR_migrate_pages	302
+
+#define NR_SYSCALLS		303
 
 #ifdef __KERNEL__
-/* WARNING: You MAY NOT add syscall numbers larger than 301, since
+/* WARNING: You MAY NOT add syscall numbers larger than 302, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 301 entries (starting at zero).  Therefore
- *          find a free slot in the 0-301 range.
+ *          sized to have 302 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-302 range.
  */
 
 #define _syscall0(type,name) \
diff --git a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h
index c73935d..36511ca 100644
--- a/include/asm-sparc64/compat.h
+++ b/include/asm-sparc64/compat.h
@@ -164,7 +164,7 @@
 	return (u32)(unsigned long)uptr;
 }
 
-static __inline__ void __user *compat_alloc_user_space(long len)
+static inline void __user *compat_alloc_user_space(long len)
 {
 	struct pt_regs *regs = current_thread_info()->kregs;
 	unsigned long usp = regs->u_regs[UREG_I6];
@@ -174,7 +174,10 @@
 	else
 		usp &= 0xffffffffUL;
 
-	return (void __user *) (usp - len);
+	usp -= len;
+	usp &= ~0x7UL;
+
+	return (void __user *) usp;
 }
 
 struct compat_ipc64_perm {
diff --git a/include/asm-sparc64/futex.h b/include/asm-sparc64/futex.h
index dee4020..7392fc4 100644
--- a/include/asm-sparc64/futex.h
+++ b/include/asm-sparc64/futex.h
@@ -87,24 +87,22 @@
 futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
 {
 	__asm__ __volatile__(
-	"\n1:	lduwa	[%2] %%asi, %0\n"
-	"2:	casa	[%2] %%asi, %0, %1\n"
-	"3:\n"
+	"\n1:	casa	[%3] %%asi, %2, %0\n"
+	"2:\n"
 	"	.section .fixup,#alloc,#execinstr\n"
 	"	.align	4\n"
-	"4:	ba	3b\n"
-	"	 mov	%3, %0\n"
+	"3:	ba	2b\n"
+	"	 mov	%4, %0\n"
 	"	.previous\n"
 	"	.section __ex_table,\"a\"\n"
 	"	.align	4\n"
-	"	.word	1b, 4b\n"
-	"	.word	2b, 4b\n"
+	"	.word	1b, 3b\n"
 	"	.previous\n"
-	: "=&r" (oldval)
-	: "r" (newval), "r" (uaddr), "i" (-EFAULT)
+	: "=r" (newval)
+	: "0" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT)
 	: "memory");
 
-	return oldval;
+	return newval;
 }
 
 #endif /* !(_SPARC64_FUTEX_H) */
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 124cf07..63669da 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -320,12 +320,16 @@
 #define __NR_unshare		299
 #define __NR_set_robust_list	300
 #define __NR_get_robust_list	301
+#define __NR_migrate_pages	302
+
+#define NR_SYSCALLS		303
 
 #ifdef __KERNEL__
-/* WARNING: You MAY NOT add syscall numbers larger than 301, since
+
+/* WARNING: You MAY NOT add syscall numbers larger than 302, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 301 entries (starting at zero).  Therefore
- *          find a free slot in the 0-301 range.
+ *          sized to have 302 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-302 range.
  */
 
 #define _syscall0(type,name) \
diff --git a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
index 1010153..f045451 100644
--- a/include/asm-um/common.lds.S
+++ b/include/asm-um/common.lds.S
@@ -42,13 +42,7 @@
 	
   __initcall_start = .;
   .initcall.init : {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
+	INITCALLS
   }
   __initcall_end = .;
 
diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
index ed59aa4..9d1916e 100644
--- a/include/asm-x86_64/acpi.h
+++ b/include/asm-x86_64/acpi.h
@@ -163,6 +163,7 @@
 #define ARCH_HAS_POWER_INIT 1
 
 extern int acpi_skip_timer_override;
+extern int acpi_use_timer_override;
 
 #endif /*__KERNEL__*/
 
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index 792dd52..179cce7 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -76,6 +76,8 @@
 #ifndef __ASSEMBLY__
 typedef int vector_irq_t[NR_VECTORS];
 DECLARE_PER_CPU(vector_irq_t, vector_irq);
+extern void __setup_vector_irq(int cpu);
+extern spinlock_t vector_lock;
 
 /*
  * Various low-level irq details needed by irq.c, process.c,
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
index 171ec2d..561ecbf 100644
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -12,10 +12,6 @@
 
 #define APIC_MISMATCH_DEBUG
 
-#define IO_APIC_BASE(idx) \
-		((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
-		+ (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
-
 /*
  * The structure of the IO-APIC:
  */
@@ -119,36 +115,6 @@
 /* non-0 if default (table-less) MP configuration */
 extern int mpc_default_type;
 
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
-	*IO_APIC_BASE(apic) = reg;
-	return *(IO_APIC_BASE(apic)+4);
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
-	*IO_APIC_BASE(apic) = reg;
-	*(IO_APIC_BASE(apic)+4) = value;
-}
-
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- */
-static inline void io_apic_modify(unsigned int apic, unsigned int value)
-{
-	*(IO_APIC_BASE(apic)+4) = value;
-}
-
-/*
- * Synchronize the IO-APIC and the CPU by doing
- * a dummy read from the IO-APIC
- */
-static inline void io_apic_sync(unsigned int apic)
-{
-	(void) *(IO_APIC_BASE(apic)+4);
-}
-
 /* 1 if "noapic" boot option passed */
 extern int skip_ioapic_setup;
 
diff --git a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
index 14996d9..5642634 100644
--- a/include/asm-x86_64/pda.h
+++ b/include/asm-x86_64/pda.h
@@ -109,6 +109,15 @@
 #define sub_pda(field,val) pda_to_op("sub",field,val)
 #define or_pda(field,val) pda_to_op("or",field,val)
 
+/* This is not atomic against other CPUs -- CPU preemption needs to be off */
+#define test_and_clear_bit_pda(bit,field) ({		\
+	int old__;						\
+	asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0"		\
+	    : "=r" (old__), "+m" (_proxy_pda.field) 		\
+	    : "dIr" (bit), "i" (pda_offset(field)) : "memory");	\
+	old__;							\
+})
+
 #endif
 
 #define PDA_STACKOFFSET (5*8)
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index 6899e77..0555c1c 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -366,6 +366,7 @@
 { 
 	pte_t pte;
 	pte_val(pte) = physpage | pgprot_val(pgprot); 
+	pte_val(pte) &= __supported_pte_mask;
 	return pte; 
 }
  
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index c181fef..e72cfcd 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -122,6 +122,8 @@
 extern int reboot_force;
 extern int notsc_setup(char *);
 
+extern int timer_over_8254;
+
 extern int gsi_irq_sharing(int gsi);
 
 extern void smp_local_timer_interrupt(void);
diff --git a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h
index fd452fc..01d1c17 100644
--- a/include/asm-x86_64/vsyscall.h
+++ b/include/asm-x86_64/vsyscall.h
@@ -59,8 +59,6 @@
 
 extern int sysctl_vsyscall;
 
-extern void vsyscall_set_cpu(int cpu);
-
 #define ARCH_HAVE_XTIME_LOCK 1
 
 #endif /* __KERNEL__ */
diff --git a/include/linux/compat.h b/include/linux/compat.h
index f4ebf96..80b17f4 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -196,7 +196,7 @@
 #define BITS_TO_COMPAT_LONGS(bits) \
 	(((bits)+BITS_PER_COMPAT_LONG-1)/BITS_PER_COMPAT_LONG)
 
-long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
+long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
 		       unsigned long bitmap_size);
 long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
 		       unsigned long bitmap_size);
@@ -230,5 +230,9 @@
 extern int compat_printk(const char *fmt, ...);
 extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
 
+asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
+		compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes,
+		const compat_ulong_t __user *new_nodes);
+
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index cfdb4f6a..c26c3ad 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -131,6 +131,7 @@
 COMPATIBLE_IOCTL(STOP_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY_RO)
 COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+COMPATIBLE_IOCTL(GET_BITMAP_FILE)
 ULONG_IOCTL(SET_BITMAP_FILE)
 /* DM */
 COMPATIBLE_IOCTL(DM_VERSION_32)
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 8f2ffa4..6485e97 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -245,7 +245,7 @@
 	__deprecated_for_modules;
 int crypto_has_alg(const char *name, u32 type, u32 mask);
 #else
-static int crypto_alg_available(const char *name, u32 flags);
+static int crypto_alg_available(const char *name, u32 flags)
 	__deprecated_for_modules;
 static inline int crypto_alg_available(const char *name, u32 flags)
 {
diff --git a/include/linux/device.h b/include/linux/device.h
index 662e6a1..9d4f6a9 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -393,7 +393,7 @@
 extern void device_initialize(struct device * dev);
 extern int __must_check device_add(struct device * dev);
 extern void device_del(struct device * dev);
-extern int __must_check device_for_each_child(struct device *, void *,
+extern int device_for_each_child(struct device *, void *,
 		     int (*fn)(struct device *, void *));
 extern int device_rename(struct device *dev, char *new_name);
 
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index 38dc403..904bf3d 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -69,6 +69,7 @@
 	struct dmi_device *from);
 extern void dmi_scan_machine(void);
 extern int dmi_get_year(int field);
+extern int dmi_name_in_vendors(char *str);
 
 #else
 
@@ -77,6 +78,7 @@
 static inline struct dmi_device * dmi_find_device(int type, const char *name,
 	struct dmi_device *from) { return NULL; }
 static inline int dmi_get_year(int year) { return 0; }
+static inline int dmi_name_in_vendors(char *s) { return 0; }
 
 #endif
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 661c7c5..2fe6e3f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -623,6 +623,9 @@
 	I_MUTEX_QUOTA
 };
 
+extern void inode_double_lock(struct inode *inode1, struct inode *inode2);
+extern void inode_double_unlock(struct inode *inode1, struct inode *inode2);
+
 /*
  * NOTE: in a 32bit arch with a preemptable kernel and
  * an UP compile the i_size_read/write must be atomic
@@ -1709,6 +1712,8 @@
 extern void clear_inode(struct inode *);
 extern void destroy_inode(struct inode *);
 extern struct inode *new_inode(struct super_block *);
+extern int __remove_suid(struct dentry *, int);
+extern int should_remove_suid(struct dentry *);
 extern int remove_suid(struct dentry *);
 extern void remove_dquot_ref(struct super_block *, int, struct list_head *);
 
@@ -1755,6 +1760,8 @@
 		struct pipe_inode_info *, size_t, unsigned int);
 extern ssize_t generic_file_splice_write(struct pipe_inode_info *,
 		struct file *, loff_t *, size_t, unsigned int);
+extern ssize_t generic_file_splice_write_nolock(struct pipe_inode_info *,
+		struct file *, loff_t *, size_t, unsigned int);
 extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe,
 		struct file *out, loff_t *, size_t len, unsigned int flags);
 extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
diff --git a/include/linux/htirq.h b/include/linux/htirq.h
index 1f15ce2..c96ea46 100644
--- a/include/linux/htirq.h
+++ b/include/linux/htirq.h
@@ -1,15 +1,23 @@
 #ifndef LINUX_HTIRQ_H
 #define LINUX_HTIRQ_H
 
+struct ht_irq_msg {
+	u32	address_lo;	/* low 32 bits of the ht irq message */
+	u32	address_hi;	/* high 32 bits of the it irq message */
+};
+
 /* Helper functions.. */
-void write_ht_irq_low(unsigned int irq, u32 data);
-void write_ht_irq_high(unsigned int irq, u32 data);
-u32  read_ht_irq_low(unsigned int irq);
-u32  read_ht_irq_high(unsigned int irq);
+void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
+void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
 void mask_ht_irq(unsigned int irq);
 void unmask_ht_irq(unsigned int irq);
 
 /* The arch hook for getting things started */
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev);
 
+/* For drivers of buggy hardware */
+typedef void (ht_irq_update_t)(struct pci_dev *dev, int irq,
+			       struct ht_irq_msg *msg);
+int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update);
+
 #endif /* LINUX_HTIRQ_H */
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 5081d27..ace64e5 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -60,8 +60,11 @@
  * If the arch doesn't supply something else, assume that hugepage
  * size aligned regions are ok without further preparation.
  */
-static inline int prepare_hugepage_range(unsigned long addr, unsigned long len)
+static inline int prepare_hugepage_range(unsigned long addr, unsigned long len,
+						pgoff_t pgoff)
 {
+	if (pgoff & (~HPAGE_MASK >> PAGE_SHIFT))
+		return -EINVAL;
 	if (len & ~HPAGE_MASK)
 		return -EINVAL;
 	if (addr & ~HPAGE_MASK)
@@ -69,7 +72,8 @@
 	return 0;
 }
 #else
-int prepare_hugepage_range(unsigned long addr, unsigned long len);
+int prepare_hugepage_range(unsigned long addr, unsigned long len,
+						pgoff_t pgoff);
 #endif
 
 #ifndef ARCH_HAS_SETCLEAR_HUGE_PTE
@@ -107,7 +111,7 @@
 #define hugetlb_report_meminfo(buf)		0
 #define hugetlb_report_node_meminfo(n, buf)	0
 #define follow_huge_pmd(mm, addr, pmd, write)	NULL
-#define prepare_hugepage_range(addr, len)	(-EINVAL)
+#define prepare_hugepage_range(addr,len,pgoff)	(-EINVAL)
 #define pmd_huge(x)	0
 #define is_hugepage_only_range(mm, addr, len)	0
 #define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) ({BUG(); 0; })
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 03f43e2..21dd569 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -191,7 +191,7 @@
 #define IGMPV3_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value))
 #define IGMPV3_EXP(thresh, nbmant, nbexp, value) \
 	((value) < (thresh) ? (value) : \
-        ((IGMPV3_MASK(value, nbmant) | (1<<(nbmant+nbexp))) << \
+        ((IGMPV3_MASK(value, nbmant) | (1<<(nbmant))) << \
          (IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp))))
 
 #define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value)
diff --git a/include/linux/in6.h b/include/linux/in6.h
index 9be6a47..f28621f 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -225,7 +225,7 @@
 #endif
 
 /*
- * Netfilter
+ * Netfilter (1)
  *
  * Following socket options are used in ip6_tables;
  * see include/linux/netfilter_ipv6/ip6_tables.h.
@@ -240,4 +240,14 @@
 #define IPV6_RECVTCLASS		66
 #define IPV6_TCLASS		67
 
+/*
+ * Netfilter (2)
+ *
+ * Following socket options are used in ip6_tables;
+ * see include/linux/netfilter_ipv6/ip6_tables.h.
+ *
+ * IP6T_SO_GET_REVISION_MATCH	68
+ * IP6T_SO_GET_REVISION_TARGET	69
+ */
+
 #endif
diff --git a/include/linux/init.h b/include/linux/init.h
index e92b145..5eb5d24 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -84,19 +84,37 @@
  * by link order. 
  * For backwards compatibility, initcall() puts the call in 
  * the device init subsection.
+ *
+ * The `id' arg to __define_initcall() is needed so that multiple initcalls
+ * can point at the same handler without causing duplicate-symbol build errors.
  */
 
-#define __define_initcall(level,fn) \
-	static initcall_t __initcall_##fn __attribute_used__ \
+#define __define_initcall(level,fn,id) \
+	static initcall_t __initcall_##fn##id __attribute_used__ \
 	__attribute__((__section__(".initcall" level ".init"))) = fn
 
-#define core_initcall(fn)		__define_initcall("1",fn)
-#define postcore_initcall(fn)		__define_initcall("2",fn)
-#define arch_initcall(fn)		__define_initcall("3",fn)
-#define subsys_initcall(fn)		__define_initcall("4",fn)
-#define fs_initcall(fn)			__define_initcall("5",fn)
-#define device_initcall(fn)		__define_initcall("6",fn)
-#define late_initcall(fn)		__define_initcall("7",fn)
+/*
+ * A "pure" initcall has no dependencies on anything else, and purely
+ * initializes variables that couldn't be statically initialized.
+ *
+ * This only exists for built-in code, not for modules.
+ */
+#define pure_initcall(fn)		__define_initcall("0",fn,1)
+
+#define core_initcall(fn)		__define_initcall("1",fn,1)
+#define core_initcall_sync(fn)		__define_initcall("1s",fn,1s)
+#define postcore_initcall(fn)		__define_initcall("2",fn,2)
+#define postcore_initcall_sync(fn)	__define_initcall("2s",fn,2s)
+#define arch_initcall(fn)		__define_initcall("3",fn,3)
+#define arch_initcall_sync(fn)		__define_initcall("3s",fn,3s)
+#define subsys_initcall(fn)		__define_initcall("4",fn,4)
+#define subsys_initcall_sync(fn)	__define_initcall("4s",fn,4s)
+#define fs_initcall(fn)			__define_initcall("5",fn,5)
+#define fs_initcall_sync(fn)		__define_initcall("5s",fn,5s)
+#define device_initcall(fn)		__define_initcall("6",fn,6)
+#define device_initcall_sync(fn)	__define_initcall("6s",fn,6s)
+#define late_initcall(fn)		__define_initcall("7",fn,7)
+#define late_initcall_sync(fn)		__define_initcall("7s",fn,7s)
 
 #define __initcall(fn) device_initcall(fn)
 
diff --git a/include/linux/ipmi_msgdefs.h b/include/linux/ipmi_msgdefs.h
index 22f5e2a..4d04d8b 100644
--- a/include/linux/ipmi_msgdefs.h
+++ b/include/linux/ipmi_msgdefs.h
@@ -75,6 +75,8 @@
 #define IPMI_INVALID_COMMAND_ERR	0xc1
 #define IPMI_ERR_MSG_TRUNCATED		0xc6
 #define IPMI_LOST_ARBITRATION_ERR	0x81
+#define IPMI_BUS_ERR			0x82
+#define IPMI_NAK_ON_WRITE_ERR		0x83
 #define IPMI_ERR_UNSPECIFIED		0xff
 
 #define IPMI_CHANNEL_PROTOCOL_IPMB	1
diff --git a/include/linux/ipx.h b/include/linux/ipx.h
index 4f29c60..eb19b4e 100644
--- a/include/linux/ipx.h
+++ b/include/linux/ipx.h
@@ -7,8 +7,8 @@
 
 struct sockaddr_ipx {
 	sa_family_t	sipx_family;
-	__u16		sipx_port;
-	__u32		sipx_network;
+	__be16		sipx_port;
+	__be32		sipx_network;
 	unsigned char 	sipx_node[IPX_NODE_LEN];
 	__u8		sipx_type;
 	unsigned char	sipx_zero;	/* 16 byte fill */
@@ -23,13 +23,13 @@
 #define IPX_CRTITF	1
 
 struct ipx_route_definition {
-	__u32         ipx_network;
-	__u32         ipx_router_network;
+	__be32        ipx_network;
+	__be32        ipx_router_network;
 	unsigned char ipx_router_node[IPX_NODE_LEN];
 };
 
 struct ipx_interface_definition {
-	__u32         ipx_network;
+	__be32        ipx_network;
 	unsigned char ipx_device[16];
 	unsigned char ipx_dlink_type;
 #define IPX_FRAME_NONE		0
@@ -55,8 +55,8 @@
  */
 
 struct ipx_route_def {
-	__u32		ipx_network;
-	__u32		ipx_router_network;
+	__be32		ipx_network;
+	__be32		ipx_router_network;
 #define IPX_ROUTE_NO_ROUTER	0
 	unsigned char	ipx_router_node[IPX_NODE_LEN];
 	unsigned char	ipx_device[16];
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 80f39ca..b9b5e4b 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -30,8 +30,10 @@
 
 #define STACK_MAGIC	0xdeadbeef
 
+#define ALIGN(x,a)		__ALIGN_MASK(x,(typeof(x))(a)-1)
+#define __ALIGN_MASK(x,mask)	(((x)+(mask))&~(mask))
+
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#define ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL))
 #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
@@ -171,6 +173,8 @@
 
 extern int printk_ratelimit(void);
 extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst);
+extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
+				unsigned int interval_msec);
 
 static inline void console_silent(void)
 {
diff --git a/include/linux/libata.h b/include/linux/libata.h
index d0a7ad5..abd2deb 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -143,7 +143,7 @@
 	ATA_DFLAG_CFG_MASK	= (1 << 8) - 1,
 
 	ATA_DFLAG_PIO		= (1 << 8), /* device limited to PIO mode */
-	ATA_DFLAG_NCQ_OFF	= (1 << 9), /* devied limited to non-NCQ mode */
+	ATA_DFLAG_NCQ_OFF	= (1 << 9), /* device limited to non-NCQ mode */
 	ATA_DFLAG_SUSPENDED	= (1 << 10), /* device suspended */
 	ATA_DFLAG_INIT_MASK	= (1 << 16) - 1,
 
@@ -702,7 +702,6 @@
 extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
 extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class);
 extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
-extern int ata_dev_revalidate(struct ata_device *dev, int post_reset);
 extern void ata_port_disable(struct ata_port *);
 extern void ata_std_ports(struct ata_ioports *ioaddr);
 #ifdef CONFIG_PCI
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 09f0f57..daabb3a 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -150,7 +150,7 @@
 extern void mpol_fix_fork_child_flag(struct task_struct *p);
 #define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x))
 
-#ifdef CONFIG_CPUSET
+#ifdef CONFIG_CPUSETS
 #define current_cpuset_is_being_rebound() \
 				(cpuset_being_rebound == current->cpuset)
 #else
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 59855b8..e06683e 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -218,13 +218,9 @@
 	 * under - it drives the swappiness decision: whether to unmap mapped
 	 * pages.
 	 *
-	 * temp_priority is used to remember the scanning priority at which
-	 * this zone was successfully refilled to free_pages == pages_high.
-	 *
-	 * Access to both these fields is quite racy even on uniprocessor.  But
+	 * Access to both this field is quite racy even on uniprocessor.  But
 	 * it is expected to average out OK.
 	 */
-	int temp_priority;
 	int prev_priority;
 
 
@@ -674,6 +670,12 @@
 #define sparse_index_init(_sec, _nid)  do {} while (0)
 #endif /* CONFIG_SPARSEMEM */
 
+#ifdef CONFIG_NODES_SPAN_OTHER_NODES
+#define early_pfn_in_nid(pfn, nid)	(early_pfn_to_nid(pfn) == (nid))
+#else
+#define early_pfn_in_nid(pfn, nid)	(1)
+#endif
+
 #ifndef early_pfn_valid
 #define early_pfn_valid(pfn)	(1)
 #endif
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index ce6c858..24a9ef1 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -402,6 +402,8 @@
 extern struct inode_operations fat_file_inode_operations;
 extern int fat_notify_change(struct dentry * dentry, struct iattr * attr);
 extern void fat_truncate(struct inode *inode);
+extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
+		       struct kstat *stat);
 
 /* fat/inode.c */
 extern void fat_attach(struct inode *inode, loff_t i_pos);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 1aeedf2..2071b02 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -358,7 +358,7 @@
  * @priv:		[OPTIONAL] pointer to private chip date
  * @errstat:		[OPTIONAL] hardware specific function to perform additional error status checks
  *			(determine if errors are correctable)
- * @write_page		[REPLACEABLE] High-level page write function
+ * @write_page:		[REPLACEABLE] High-level page write function
  */
 
 struct nand_chip {
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9264139..83b8c4f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -93,8 +93,10 @@
 #endif
 #endif
 
-#if !defined(CONFIG_NET_IPIP) && \
-    !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE)
+#if !defined(CONFIG_NET_IPIP) && !defined(CONFIG_NET_IPIP_MODULE) && \
+    !defined(CONFIG_NET_IPGRE) &&  !defined(CONFIG_NET_IPGRE_MODULE) && \
+    !defined(CONFIG_IPV6_SIT) && !defined(CONFIG_IPV6_SIT_MODULE) && \
+    !defined(CONFIG_IPV6_TUNNEL) && !defined(CONFIG_IPV6_TUNNEL_MODULE)
 #define MAX_HEADER LL_MAX_HEADER
 #else
 #define MAX_HEADER (LL_MAX_HEADER + 48)
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 04319a7..022edfa 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -96,22 +96,6 @@
 /* Error verdict. */
 #define XT_ERROR_TARGET "ERROR"
 
-/*
- * New IP firewall options for [gs]etsockopt at the RAW IP level.
- * Unlike BSD Linux inherits IP options so you don't have to use a raw
- * socket for this. Instead we check rights in the calls. */
-#define XT_BASE_CTL		64	/* base for firewall socket options */
-
-#define XT_SO_SET_REPLACE	(XT_BASE_CTL)
-#define XT_SO_SET_ADD_COUNTERS	(XT_BASE_CTL + 1)
-#define XT_SO_SET_MAX		XT_SO_SET_ADD_COUNTERS
-
-#define XT_SO_GET_INFO			(XT_BASE_CTL)
-#define XT_SO_GET_ENTRIES		(XT_BASE_CTL + 1)
-#define XT_SO_GET_REVISION_MATCH	(XT_BASE_CTL + 2)
-#define XT_SO_GET_REVISION_TARGET	(XT_BASE_CTL + 3)
-#define XT_SO_GET_MAX			XT_SO_GET_REVISION_TARGET
-
 #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index 44e39b6..0be2354 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -112,19 +112,20 @@
  * New IP firewall options for [gs]etsockopt at the RAW IP level.
  * Unlike BSD Linux inherits IP options so you don't have to use a raw
  * socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in.h before adding new number here.
  */
-#define ARPT_CTL_OFFSET		32
-#define ARPT_BASE_CTL		(XT_BASE_CTL+ARPT_CTL_OFFSET)
+#define ARPT_BASE_CTL		96
 
-#define ARPT_SO_SET_REPLACE		(XT_SO_SET_REPLACE+ARPT_CTL_OFFSET)
-#define ARPT_SO_SET_ADD_COUNTERS	(XT_SO_SET_ADD_COUNTERS+ARPT_CTL_OFFSET)
-#define ARPT_SO_SET_MAX			(XT_SO_SET_MAX+ARPT_CTL_OFFSET)
+#define ARPT_SO_SET_REPLACE		(ARPT_BASE_CTL)
+#define ARPT_SO_SET_ADD_COUNTERS	(ARPT_BASE_CTL + 1)
+#define ARPT_SO_SET_MAX			ARPT_SO_SET_ADD_COUNTERS
 
-#define ARPT_SO_GET_INFO		(XT_SO_GET_INFO+ARPT_CTL_OFFSET)
-#define ARPT_SO_GET_ENTRIES		(XT_SO_GET_ENTRIES+ARPT_CTL_OFFSET)
-/* #define ARPT_SO_GET_REVISION_MATCH	XT_SO_GET_REVISION_MATCH  */
-#define ARPT_SO_GET_REVISION_TARGET	(XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET)
-#define ARPT_SO_GET_MAX			(XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET)
+#define ARPT_SO_GET_INFO		(ARPT_BASE_CTL)
+#define ARPT_SO_GET_ENTRIES		(ARPT_BASE_CTL + 1)
+/* #define ARPT_SO_GET_REVISION_MATCH	(APRT_BASE_CTL + 2) */
+#define ARPT_SO_GET_REVISION_TARGET	(ARPT_BASE_CTL + 3)
+#define ARPT_SO_GET_MAX			(ARPT_SO_GET_REVISION_TARGET)
 
 /* CONTINUE verdict for targets */
 #define ARPT_CONTINUE XT_CONTINUE
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index a536bbd..4f06dad 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -101,18 +101,21 @@
 /*
  * New IP firewall options for [gs]etsockopt at the RAW IP level.
  * Unlike BSD Linux inherits IP options so you don't have to use a raw
- * socket for this. Instead we check rights in the calls. */
-#define IPT_BASE_CTL		XT_BASE_CTL
+ * socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in.h before adding new number here.
+ */
+#define IPT_BASE_CTL		64
 
-#define IPT_SO_SET_REPLACE	XT_SO_SET_REPLACE
-#define IPT_SO_SET_ADD_COUNTERS	XT_SO_SET_ADD_COUNTERS
-#define IPT_SO_SET_MAX		XT_SO_SET_MAX
+#define IPT_SO_SET_REPLACE	(IPT_BASE_CTL)
+#define IPT_SO_SET_ADD_COUNTERS	(IPT_BASE_CTL + 1)
+#define IPT_SO_SET_MAX		IPT_SO_SET_ADD_COUNTERS
 
-#define IPT_SO_GET_INFO			XT_SO_GET_INFO
-#define IPT_SO_GET_ENTRIES		XT_SO_GET_ENTRIES
-#define IPT_SO_GET_REVISION_MATCH	XT_SO_GET_REVISION_MATCH
-#define IPT_SO_GET_REVISION_TARGET	XT_SO_GET_REVISION_TARGET
-#define IPT_SO_GET_MAX			XT_SO_GET_REVISION_TARGET
+#define IPT_SO_GET_INFO			(IPT_BASE_CTL)
+#define IPT_SO_GET_ENTRIES		(IPT_BASE_CTL + 1)
+#define IPT_SO_GET_REVISION_MATCH	(IPT_BASE_CTL + 2)
+#define IPT_SO_GET_REVISION_TARGET	(IPT_BASE_CTL + 3)
+#define IPT_SO_GET_MAX			IPT_SO_GET_REVISION_TARGET
 
 #define IPT_CONTINUE XT_CONTINUE
 #define IPT_RETURN XT_RETURN
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index d7a8e9c0..4aed340 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -107,18 +107,21 @@
 /*
  * New IP firewall options for [gs]etsockopt at the RAW IP level.
  * Unlike BSD Linux inherits IP options so you don't have to use
- * a raw socket for this. Instead we check rights in the calls. */
-#define IP6T_BASE_CTL			XT_BASE_CTL
+ * a raw socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in6.h before adding new number here.
+ */
+#define IP6T_BASE_CTL			64
 
-#define IP6T_SO_SET_REPLACE		XT_SO_SET_REPLACE
-#define IP6T_SO_SET_ADD_COUNTERS	XT_SO_SET_ADD_COUNTERS
-#define IP6T_SO_SET_MAX			XT_SO_SET_MAX
+#define IP6T_SO_SET_REPLACE		(IP6T_BASE_CTL)
+#define IP6T_SO_SET_ADD_COUNTERS	(IP6T_BASE_CTL + 1)
+#define IP6T_SO_SET_MAX			IP6T_SO_SET_ADD_COUNTERS
 
-#define IP6T_SO_GET_INFO		XT_SO_GET_INFO
-#define IP6T_SO_GET_ENTRIES		XT_SO_GET_ENTRIES
-#define	IP6T_SO_GET_REVISION_MATCH	XT_SO_GET_REVISION_MATCH
-#define	IP6T_SO_GET_REVISION_TARGET	XT_SO_GET_REVISION_TARGET
-#define IP6T_SO_GET_MAX			XT_SO_GET_REVISION_TARGET
+#define IP6T_SO_GET_INFO		(IP6T_BASE_CTL)
+#define IP6T_SO_GET_ENTRIES		(IP6T_BASE_CTL + 1)
+#define IP6T_SO_GET_REVISION_MATCH	(IP6T_BASE_CTL + 4)
+#define IP6T_SO_GET_REVISION_TARGET	(IP6T_BASE_CTL + 5)
+#define IP6T_SO_GET_MAX			IP6T_SO_GET_REVISION_TARGET
 
 /* CONTINUE verdict for targets */
 #define IP6T_CONTINUE XT_CONTINUE
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index eb23114..edb54c3 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -89,7 +89,7 @@
 __be32		nfsd_create_v3(struct svc_rqst *, struct svc_fh *,
 				char *name, int len, struct iattr *attrs,
 				struct svc_fh *res, int createmode,
-				u32 *verifier, int *truncp);
+				u32 *verifier, int *truncp, int *created);
 __be32		nfsd_commit(struct svc_rqst *, struct svc_fh *,
 				loff_t, unsigned long);
 #endif /* CONFIG_NFSD_V3 */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index f6baecd..971d1c6 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -45,8 +45,10 @@
 {
 	struct nsproxy *ns = p->nsproxy;
 	if (ns) {
-		put_nsproxy(ns);
+		task_lock(p);
 		p->nsproxy = NULL;
+		task_unlock(p);
+		put_nsproxy(ns);
 	}
 }
 #endif
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 64f9509..c3e255b 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -52,19 +52,23 @@
 void release_pages(struct page **pages, int nr, int cold);
 
 #ifdef CONFIG_NUMA
-extern struct page *page_cache_alloc(struct address_space *x);
-extern struct page *page_cache_alloc_cold(struct address_space *x);
+extern struct page *__page_cache_alloc(gfp_t gfp);
 #else
+static inline struct page *__page_cache_alloc(gfp_t gfp)
+{
+	return alloc_pages(gfp, 0);
+}
+#endif
+
 static inline struct page *page_cache_alloc(struct address_space *x)
 {
-	return alloc_pages(mapping_gfp_mask(x), 0);
+	return __page_cache_alloc(mapping_gfp_mask(x));
 }
 
 static inline struct page *page_cache_alloc_cold(struct address_space *x)
 {
-	return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0);
+	return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD);
 }
-#endif
 
 typedef int filler_t(void *, struct page *);
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 4689e2a..09be0f8 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -455,7 +455,11 @@
 int pci_find_ext_capability (struct pci_dev *dev, int cap);
 struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
 
-struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
+struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
+				struct pci_dev *from);
+struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device,
+				struct pci_dev *from);
+
 struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
 				unsigned int ss_vendor, unsigned int ss_device,
 				struct pci_dev *from);
@@ -660,7 +664,12 @@
 static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
 { return NULL; }
 
-static inline struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from)
+static inline struct pci_dev *pci_get_device(unsigned int vendor,
+				unsigned int device, struct pci_dev *from)
+{ return NULL; }
+
+static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor,
+				unsigned int device, struct pci_dev *from)
 { return NULL; }
 
 static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f3a168f..fa4e1d7 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1213,6 +1213,7 @@
 #define PCI_DEVICE_ID_NVIDIA_NVENET_21              0x0451
 #define PCI_DEVICE_ID_NVIDIA_NVENET_22              0x0452
 #define PCI_DEVICE_ID_NVIDIA_NVENET_23              0x0453
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE       0x0560
 
 #define PCI_VENDOR_ID_IMS		0x10e0
 #define PCI_DEVICE_ID_IMS_TT128		0x9128
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index c312a12..c321316 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -371,6 +371,7 @@
 #define  PCI_EXP_DEVSTA_TRPND	0x20	/* Transactions Pending */
 #define PCI_EXP_LNKCAP		12	/* Link Capabilities */
 #define PCI_EXP_LNKCTL		16	/* Link Control */
+#define  PCI_EXP_LNKCTL_CLKREQ_EN 0x100	/* Enable clkreq */
 #define PCI_EXP_LNKSTA		18	/* Link Status */
 #define PCI_EXP_SLTCAP		20	/* Slot Capabilities */
 #define PCI_EXP_SLTCTL		24	/* Slot Control */
diff --git a/include/linux/personality.h b/include/linux/personality.h
index bf4cf20..012cd55 100644
--- a/include/linux/personality.h
+++ b/include/linux/personality.h
@@ -114,7 +114,7 @@
  * Change personality of the currently running process.
  */
 #define set_personality(pers) \
-	((current->personality == pers) ? 0 : __set_personality(pers))
+	((current->personality == (pers)) ? 0 : __set_personality(pers))
 
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 6b27e07..070394e 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -116,7 +116,9 @@
 #define	PM_DISK_PLATFORM	((__force suspend_disk_method_t) 2)
 #define	PM_DISK_SHUTDOWN	((__force suspend_disk_method_t) 3)
 #define	PM_DISK_REBOOT		((__force suspend_disk_method_t) 4)
-#define	PM_DISK_MAX		((__force suspend_disk_method_t) 5)
+#define	PM_DISK_TEST		((__force suspend_disk_method_t) 5)
+#define	PM_DISK_TESTPROC	((__force suspend_disk_method_t) 6)
+#define	PM_DISK_MAX		((__force suspend_disk_method_t) 7)
 
 struct pm_ops {
 	suspend_disk_method_t pm_disk_mode;
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 84d8877..ebd42a3 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -146,16 +146,16 @@
 
 /* the superblock at the front of the bitmap file -- little endian */
 typedef struct bitmap_super_s {
-	__u32 magic;        /*  0  BITMAP_MAGIC */
-	__u32 version;      /*  4  the bitmap major for now, could change... */
-	__u8  uuid[16];     /*  8  128 bit uuid - must match md device uuid */
-	__u64 events;       /* 24  event counter for the bitmap (1)*/
-	__u64 events_cleared;/*32  event counter when last bit cleared (2) */
-	__u64 sync_size;    /* 40  the size of the md device's sync range(3) */
-	__u32 state;        /* 48  bitmap state information */
-	__u32 chunksize;    /* 52  the bitmap chunk size in bytes */
-	__u32 daemon_sleep; /* 56  seconds between disk flushes */
-	__u32 write_behind; /* 60  number of outstanding write-behind writes */
+	__le32 magic;        /*  0  BITMAP_MAGIC */
+	__le32 version;      /*  4  the bitmap major for now, could change... */
+	__u8  uuid[16];      /*  8  128 bit uuid - must match md device uuid */
+	__le64 events;       /* 24  event counter for the bitmap (1)*/
+	__le64 events_cleared;/*32  event counter when last bit cleared (2) */
+	__le64 sync_size;    /* 40  the size of the md device's sync range(3) */
+	__le32 state;        /* 48  bitmap state information */
+	__le32 chunksize;    /* 52  the bitmap chunk size in bytes */
+	__le32 daemon_sleep; /* 56  seconds between disk flushes */
+	__le32 write_behind; /* 60  number of outstanding write-behind writes */
 
 	__u8  pad[256 - 64]; /* set to zero */
 } bitmap_super_t;
diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h
index b6ebc69..3f2cd98 100644
--- a/include/linux/raid/md_p.h
+++ b/include/linux/raid/md_p.h
@@ -206,52 +206,52 @@
  */
 struct mdp_superblock_1 {
 	/* constant array information - 128 bytes */
-	__u32	magic;		/* MD_SB_MAGIC: 0xa92b4efc - little endian */
-	__u32	major_version;	/* 1 */
-	__u32	feature_map;	/* bit 0 set if 'bitmap_offset' is meaningful */
-	__u32	pad0;		/* always set to 0 when writing */
+	__le32	magic;		/* MD_SB_MAGIC: 0xa92b4efc - little endian */
+	__le32	major_version;	/* 1 */
+	__le32	feature_map;	/* bit 0 set if 'bitmap_offset' is meaningful */
+	__le32	pad0;		/* always set to 0 when writing */
 
 	__u8	set_uuid[16];	/* user-space generated. */
 	char	set_name[32];	/* set and interpreted by user-space */
 
-	__u64	ctime;		/* lo 40 bits are seconds, top 24 are microseconds or 0*/
-	__u32	level;		/* -4 (multipath), -1 (linear), 0,1,4,5 */
-	__u32	layout;		/* only for raid5 and raid10 currently */
-	__u64	size;		/* used size of component devices, in 512byte sectors */
+	__le64	ctime;		/* lo 40 bits are seconds, top 24 are microseconds or 0*/
+	__le32	level;		/* -4 (multipath), -1 (linear), 0,1,4,5 */
+	__le32	layout;		/* only for raid5 and raid10 currently */
+	__le64	size;		/* used size of component devices, in 512byte sectors */
 
-	__u32	chunksize;	/* in 512byte sectors */
-	__u32	raid_disks;
-	__u32	bitmap_offset;	/* sectors after start of superblock that bitmap starts
+	__le32	chunksize;	/* in 512byte sectors */
+	__le32	raid_disks;
+	__le32	bitmap_offset;	/* sectors after start of superblock that bitmap starts
 				 * NOTE: signed, so bitmap can be before superblock
 				 * only meaningful of feature_map[0] is set.
 				 */
 
 	/* These are only valid with feature bit '4' */
-	__u32	new_level;	/* new level we are reshaping to		*/
-	__u64	reshape_position;	/* next address in array-space for reshape */
-	__u32	delta_disks;	/* change in number of raid_disks		*/
-	__u32	new_layout;	/* new layout					*/
-	__u32	new_chunk;	/* new chunk size (bytes)			*/
+	__le32	new_level;	/* new level we are reshaping to		*/
+	__le64	reshape_position;	/* next address in array-space for reshape */
+	__le32	delta_disks;	/* change in number of raid_disks		*/
+	__le32	new_layout;	/* new layout					*/
+	__le32	new_chunk;	/* new chunk size (bytes)			*/
 	__u8	pad1[128-124];	/* set to 0 when written */
 
 	/* constant this-device information - 64 bytes */
-	__u64	data_offset;	/* sector start of data, often 0 */
-	__u64	data_size;	/* sectors in this device that can be used for data */
-	__u64	super_offset;	/* sector start of this superblock */
-	__u64	recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
-	__u32	dev_number;	/* permanent identifier of this  device - not role in raid */
-	__u32	cnt_corrected_read; /* number of read errors that were corrected by re-writing */
+	__le64	data_offset;	/* sector start of data, often 0 */
+	__le64	data_size;	/* sectors in this device that can be used for data */
+	__le64	super_offset;	/* sector start of this superblock */
+	__le64	recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
+	__le32	dev_number;	/* permanent identifier of this  device - not role in raid */
+	__le32	cnt_corrected_read; /* number of read errors that were corrected by re-writing */
 	__u8	device_uuid[16]; /* user-space setable, ignored by kernel */
 	__u8	devflags;	/* per-device flags.  Only one defined...*/
 #define	WriteMostly1	1	/* mask for writemostly flag in above */
 	__u8	pad2[64-57];	/* set to 0 when writing */
 
 	/* array state information - 64 bytes */
-	__u64	utime;		/* 40 bits second, 24 btes microseconds */
-	__u64	events;		/* incremented when superblock updated */
-	__u64	resync_offset;	/* data before this offset (from data_offset) known to be in sync */
-	__u32	sb_csum;	/* checksum upto devs[max_dev] */
-	__u32	max_dev;	/* size of devs[] array to consider */
+	__le64	utime;		/* 40 bits second, 24 btes microseconds */
+	__le64	events;		/* incremented when superblock updated */
+	__le64	resync_offset;	/* data before this offset (from data_offset) known to be in sync */
+	__le32	sb_csum;	/* checksum upto devs[max_dev] */
+	__le32	max_dev;	/* size of devs[] array to consider */
 	__u8	pad3[64-32];	/* set to 0 when writing */
 
 	/* device state information. Indexed by dev_number.
@@ -260,7 +260,7 @@
 	 * into the 'roles' value.  If a device is spare or faulty, then it doesn't
 	 * have a meaningful role.
 	 */
-	__u16	dev_roles[0];	/* role in array, or 0xffff for a spare, or 0xfffe for faulty */
+	__le16	dev_roles[0];	/* role in array, or 0xffff for a spare, or 0xfffe for faulty */
 };
 
 /* feature_map bits */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6735c1c..eafe4a7 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -466,7 +466,6 @@
 	struct pacct_struct pacct;	/* per-process accounting information */
 #endif
 #ifdef CONFIG_TASKSTATS
-	spinlock_t stats_lock;
 	struct taskstats *stats;
 #endif
 };
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index b800d2d..8451052 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -183,13 +183,27 @@
 #define read_lock(lock)			_read_lock(lock)
 
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+
 #define spin_lock_irqsave(lock, flags)	flags = _spin_lock_irqsave(lock)
 #define read_lock_irqsave(lock, flags)	flags = _read_lock_irqsave(lock)
 #define write_lock_irqsave(lock, flags)	flags = _write_lock_irqsave(lock)
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+#define spin_lock_irqsave_nested(lock, flags, subclass) \
+	flags = _spin_lock_irqsave_nested(lock, subclass)
 #else
+#define spin_lock_irqsave_nested(lock, flags, subclass) \
+	flags = _spin_lock_irqsave(lock)
+#endif
+
+#else
+
 #define spin_lock_irqsave(lock, flags)	_spin_lock_irqsave(lock, flags)
 #define read_lock_irqsave(lock, flags)	_read_lock_irqsave(lock, flags)
 #define write_lock_irqsave(lock, flags)	_write_lock_irqsave(lock, flags)
+#define spin_lock_irqsave_nested(lock, flags, subclass)	\
+	spin_lock_irqsave(lock, flags)
+
 #endif
 
 #define spin_lock_irq(lock)		_spin_lock_irq(lock)
diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h
index 8828b81..8a2307ce 100644
--- a/include/linux/spinlock_api_smp.h
+++ b/include/linux/spinlock_api_smp.h
@@ -32,6 +32,8 @@
 void __lockfunc _write_lock_irq(rwlock_t *lock)		__acquires(lock);
 unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
 							__acquires(lock);
+unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass)
+							__acquires(lock);
 unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
 							__acquires(lock);
 unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 1b24bd4..d98562f1 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -6,10 +6,17 @@
  ****************************************************************
  ****************************************************************
  **
+ **  WARNING:
  **  The values in this file are exported to user space via 
- **  the sysctl() binary interface.  However this interface
- **  is unstable and deprecated and will be removed in the future. 
- **  For a stable interface use /proc/sys.
+ **  the sysctl() binary interface.  Do *NOT* change the
+ **  numbering of any existing values here, and do not change
+ **  any numbers within any one set of values.  If you have to
+ **  have to redefine an existing interface, use a new number for it.
+ **  The kernel will then return -ENOTDIR to any application using
+ **  the old binary interface.
+ **
+ **  For new interfaces unless you really need a binary number
+ **  please use CTL_UNNUMBERED.
  **
  ****************************************************************
  ****************************************************************
@@ -48,6 +55,7 @@
 #ifdef __KERNEL__
 #define CTL_ANY		-1	/* Matches any name */
 #define CTL_NONE	0
+#define CTL_UNNUMBERED	CTL_NONE	/* sysctl without a binary number */
 #endif
 
 enum
@@ -961,8 +969,8 @@
 /*
  * Register a set of sysctl names by calling register_sysctl_table
  * with an initialised array of ctl_table's.  An entry with zero
- * ctl_name terminates the table.  table->de will be set up by the
- * registration and need not be initialised in advance.
+ * ctl_name and NULL procname terminates the table.  table->de will be
+ * set up by the registration and need not be initialised in advance.
  *
  * sysctl names can be mirrored automatically under /proc/sys.  The
  * procname supplied controls /proc naming.
@@ -973,7 +981,10 @@
  * Leaf nodes in the sysctl tree will be represented by a single file
  * under /proc; non-leaf nodes will be represented by directories.  A
  * null procname disables /proc mirroring at this node.
- * 
+ *
+ * sysctl entries with a zero ctl_name will not be available through
+ * the binary sysctl interface.
+ *
  * sysctl(2) can automatically manage read and write requests through
  * the sysctl table.  The data and maxlen fields of the ctl_table
  * struct enable minimal validation of the values being written to be
diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h
index 16894b7..6562a20 100644
--- a/include/linux/taskstats_kern.h
+++ b/include/linux/taskstats_kern.h
@@ -23,25 +23,26 @@
 
 static inline void taskstats_tgid_init(struct signal_struct *sig)
 {
-	spin_lock_init(&sig->stats_lock);
 	sig->stats = NULL;
 }
 
-static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+static inline void taskstats_tgid_alloc(struct task_struct *tsk)
 {
+	struct signal_struct *sig = tsk->signal;
 	struct taskstats *stats;
-	unsigned long flags;
 
-	stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
-	if (!stats)
+	if (sig->stats != NULL)
 		return;
 
-	spin_lock_irqsave(&sig->stats_lock, flags);
+	/* No problem if kmem_cache_zalloc() fails */
+	stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
+
+	spin_lock_irq(&tsk->sighand->siglock);
 	if (!sig->stats) {
 		sig->stats = stats;
 		stats = NULL;
 	}
-	spin_unlock_irqrestore(&sig->stats_lock, flags);
+	spin_unlock_irq(&tsk->sighand->siglock);
 
 	if (stats)
 		kmem_cache_free(taskstats_cache, stats);
@@ -49,23 +50,13 @@
 
 static inline void taskstats_tgid_free(struct signal_struct *sig)
 {
-	struct taskstats *stats = NULL;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sig->stats_lock, flags);
-	if (sig->stats) {
-		stats = sig->stats;
-		sig->stats = NULL;
-	}
-	spin_unlock_irqrestore(&sig->stats_lock, flags);
-	if (stats)
-		kmem_cache_free(taskstats_cache, stats);
+	if (sig->stats)
+		kmem_cache_free(taskstats_cache, sig->stats);
 }
 
 extern void taskstats_exit_alloc(struct taskstats **, unsigned int *);
 extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int);
 extern void taskstats_init_early(void);
-extern void taskstats_tgid_alloc(struct signal_struct *);
 #else
 static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
 {}
@@ -77,7 +68,7 @@
 {}
 static inline void taskstats_tgid_init(struct signal_struct *sig)
 {}
-static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+static inline void taskstats_tgid_alloc(struct task_struct *tsk)
 {}
 static inline void taskstats_tgid_free(struct signal_struct *sig)
 {}
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h
index 61eef50..28967ed 100644
--- a/include/linux/ufs_fs.h
+++ b/include/linux/ufs_fs.h
@@ -908,7 +908,7 @@
 			__fs64   fs_csaddr;	/* blk addr of cyl grp summary area */
 			__fs64    fs_pendingblocks;/* blocks in process of being freed */
 			__fs32    fs_pendinginodes;/*inodes in process of being freed */
-		} fs_u2;
+		} __attribute__ ((packed)) fs_u2;
 	} fs_un1;
 	union {
 		struct {
diff --git a/include/linux/unwind.h b/include/linux/unwind.h
index 73e1751..749928c 100644
--- a/include/linux/unwind.h
+++ b/include/linux/unwind.h
@@ -26,6 +26,7 @@
  * Initialize unwind support.
  */
 extern void unwind_init(void);
+extern void unwind_setup(void);
 
 #ifdef CONFIG_MODULES
 
@@ -73,6 +74,7 @@
 struct unwind_frame_info {};
 
 static inline void unwind_init(void) {}
+static inline void unwind_setup(void) {}
 
 #ifdef CONFIG_MODULES
 
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index ce5f148..924e502 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -23,13 +23,14 @@
 #endif
 
 struct vm_struct {
+	/* keep next,addr,size together to speedup lookups */
+	struct vm_struct	*next;
 	void			*addr;
 	unsigned long		size;
 	unsigned long		flags;
 	struct page		**pages;
 	unsigned int		nr_pages;
 	unsigned long		phys_addr;
-	struct vm_struct	*next;
 };
 
 /*
@@ -60,7 +61,8 @@
 extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
 					unsigned long start, unsigned long end);
 extern struct vm_struct *get_vm_area_node(unsigned long size,
-					unsigned long flags, int node);
+					  unsigned long flags, int node,
+					  gfp_t gfp_mask);
 extern struct vm_struct *remove_vm_area(void *addr);
 extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
 			struct page ***pages);
diff --git a/include/linux/wait.h b/include/linux/wait.h
index b3b9048..e820d00 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -79,6 +79,15 @@
 
 extern void init_waitqueue_head(wait_queue_head_t *q);
 
+#ifdef CONFIG_LOCKDEP
+# define __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) \
+	({ init_waitqueue_head(&name); name; })
+# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) \
+	wait_queue_head_t name = __WAIT_QUEUE_HEAD_INIT_ONSTACK(name)
+#else
+# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) DECLARE_WAIT_QUEUE_HEAD(name)
+#endif
+
 static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
 {
 	q->flags = 0;
diff --git a/include/net/dn.h b/include/net/dn.h
index 465b783..ac4ce90 100644
--- a/include/net/dn.h
+++ b/include/net/dn.h
@@ -199,11 +199,6 @@
 {
 	fl->uli_u.dnports.sport = scp->addrloc;
 	fl->uli_u.dnports.dport = scp->addrrem;
-	fl->uli_u.dnports.objnum = scp->addr.sdn_objnum;
-	if (fl->uli_u.dnports.objnum == 0) {
-		fl->uli_u.dnports.objnamel = (__u8)dn_ntohs(scp->addr.sdn_objnamel);
-		memcpy(fl->uli_u.dnports.objname, scp->addr.sdn_objname, 16);
-	}
 }
 
 extern unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu);
diff --git a/include/net/flow.h b/include/net/flow.h
index 3b44d72..5cda27c 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -68,9 +68,6 @@
 		struct {
 			__le16	sport;
 			__le16	dport;
-			__u8	objnum;
-			__u8	objnamel; /* Not 16 bits since max val is 16 */
-			__u8	objname[16]; /* Not zero terminated */
 		} dnports;
 
 		__be32		spi;
diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h
index 425b3a5..617b672 100644
--- a/include/net/ieee80211softmac.h
+++ b/include/net/ieee80211softmac.h
@@ -63,13 +63,11 @@
 
 /*
  * Information about association
- *
- * Do we need a lock for this?
- * We only ever use this structure inlined
- * into our global struct. I've used its lock,
- * but maybe we need a local one here?
  */
 struct ieee80211softmac_assoc_info {
+
+	struct mutex mutex;
+
 	/*
 	 * This is the requested ESSID. It is written
 	 * only by the WX handlers.
@@ -99,12 +97,13 @@
 	 *
 	 * bssfixed is used for SIOCSIWAP.
 	 */
-	u8 static_essid:1,
-	   short_preamble_available:1,
-	   associating:1,
-	   assoc_wait:1,
-	   bssvalid:1,
-	   bssfixed:1;
+	u8 static_essid;
+	u8 short_preamble_available;
+	u8 associating;
+	u8 associated;
+	u8 assoc_wait;
+	u8 bssvalid;
+	u8 bssfixed;
 
 	/* Scan retries remaining */
 	int scan_retry;
@@ -229,12 +228,10 @@
 	/* private stuff follows */
 	/* this lock protects this structure */
 	spinlock_t lock;
-	
-	/* couple of flags */
-	u8 scanning:1, /* protects scanning from being done multiple times at once */
-	   associated:1,
-	   running:1;
-	
+
+	u8 running; /* SoftMAC started? */
+	u8 scanning;
+
 	struct ieee80211softmac_scaninfo *scaninfo;
 	struct ieee80211softmac_assoc_info associnfo;
 	struct ieee80211softmac_bss_info bssinfo;
@@ -250,7 +247,7 @@
 
 	/* we need to keep a list of network structs we copied */
 	struct list_head network_list;
-	
+
 	/* This must be the last item so that it points to the data
 	 * allocated beyond this structure by alloc_ieee80211 */
 	u8 priv[0];
@@ -295,7 +292,7 @@
 {
 	struct ieee80211softmac_txrates *txrates = &mac->txrates;
 
-	if (!mac->associated)
+	if (!mac->associnfo.associated)
 		return txrates->mgt_mcast_rate;
 
 	/* We are associated, sending unicast frame */
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index d599c6b..7849844 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -48,7 +48,7 @@
 
 #define	IP6_ECN_flow_xmit(sk, label) do {				\
 	if (INET_ECN_is_capable(inet_sk(sk)->tos))			\
-		(label) |= __constant_htons(INET_ECN_ECT_0 << 4);	\
+		(label) |= htonl(INET_ECN_ECT_0 << 20);			\
     } while (0)
 
 static inline int IP_ECN_set_ce(struct iphdr *iph)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 49c717e..903108e 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -7,6 +7,7 @@
 #define _IP_VS_H
 
 #include <asm/types.h>		/* For __uXX types */
+#include <linux/types.h>	/* For __beXX types in userland */
 
 #define IP_VS_VERSION_CODE	0x010201
 #define NVERSION(version)			\
diff --git a/include/net/ipx.h b/include/net/ipx.h
index 5c0cf33..c6b2ee6 100644
--- a/include/net/ipx.h
+++ b/include/net/ipx.h
@@ -15,9 +15,9 @@
 #include <linux/list.h>
 
 struct ipx_address {
-	__u32   net;
+	__be32  net;
 	__u8    node[IPX_NODE_LEN]; 
-	__u16   sock;
+	__be16  sock;
 };
 
 #define ipx_broadcast_node	"\377\377\377\377\377\377"
@@ -26,9 +26,9 @@
 #define IPX_MAX_PPROP_HOPS 8
 
 struct ipxhdr {
-	__u16			ipx_checksum __attribute__ ((packed));
-#define IPX_NO_CHECKSUM	0xFFFF
-	__u16			ipx_pktsize __attribute__ ((packed));
+	__be16			ipx_checksum __attribute__ ((packed));
+#define IPX_NO_CHECKSUM	__constant_htons(0xFFFF)
+	__be16			ipx_pktsize __attribute__ ((packed));
 	__u8			ipx_tctrl;
 	__u8			ipx_type;
 #define IPX_TYPE_UNKNOWN	0x00
@@ -48,14 +48,14 @@
 
 struct ipx_interface {
 	/* IPX address */
-	__u32			if_netnum;
+	__be32			if_netnum;
 	unsigned char		if_node[IPX_NODE_LEN];
 	atomic_t		refcnt;
 
 	/* physical device info */
 	struct net_device	*if_dev;
 	struct datalink_proto	*if_dlink;
-	unsigned short		if_dlink_type;
+	__be16			if_dlink_type;
 
 	/* socket support */
 	unsigned short		if_sknum;
@@ -71,7 +71,7 @@
 };
 
 struct ipx_route {
-	__u32			ir_net;
+	__be32			ir_net;
 	struct ipx_interface	*ir_intrfc;
 	unsigned char		ir_routed;
 	unsigned char		ir_router_node[IPX_NODE_LEN];
@@ -82,10 +82,10 @@
 #ifdef __KERNEL__
 struct ipx_cb {
 	u8	ipx_tctrl;
-	u32	ipx_dest_net;
-	u32	ipx_source_net;
+	__be32	ipx_dest_net;
+	__be32	ipx_source_net;
 	struct {
-		u32 netnum;
+		__be32 netnum;
 		int index;
 	} last_hop;
 };
@@ -97,7 +97,7 @@
 	struct sock		sk;
 	struct ipx_address	dest_addr;
 	struct ipx_interface	*intrfc;
-	unsigned short		port;
+	__be16			port;
 #ifdef CONFIG_IPX_INTERN
 	unsigned char		node[IPX_NODE_LEN];
 #endif
@@ -132,7 +132,7 @@
 extern int ipx_proc_init(void);
 extern void ipx_proc_exit(void);
 
-extern const char *ipx_frame_name(unsigned short);
+extern const char *ipx_frame_name(__be16);
 extern const char *ipx_device_name(struct ipx_interface *intrfc);
 
 static __inline__ void ipxitf_hold(struct ipx_interface *intrfc)
diff --git a/include/net/sock.h b/include/net/sock.h
index 40bb90e..9cdbae2 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -883,18 +883,22 @@
 }
 
 /**
+ * 	sk_filter_rcu_free: Free a socket filter
+ *	@rcu: rcu_head that contains the sk_filter to free
+ */
+static inline void sk_filter_rcu_free(struct rcu_head *rcu)
+{
+	struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
+	kfree(fp);
+}
+
+/**
  *	sk_filter_release: Release a socket filter
  *	@sk: socket
  *	@fp: filter to remove
  *
  *	Remove a filter from a socket and release its resources.
  */
- 
-static inline void sk_filter_rcu_free(struct rcu_head *rcu)
-{
-	struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
-	kfree(fp);
-}
 
 static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp)
 {
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index 81b62307..c094e50 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -36,6 +36,22 @@
 #include <linux/socket.h>
 #include <rdma/ib_verbs.h>
 
+struct rdma_addr_client {
+	atomic_t refcount;
+	struct completion comp;
+};
+
+/**
+ * rdma_addr_register_client - Register an address client.
+ */
+void rdma_addr_register_client(struct rdma_addr_client *client);
+
+/**
+ * rdma_addr_unregister_client - Deregister an address client.
+ * @client: Client object to deregister.
+ */
+void rdma_addr_unregister_client(struct rdma_addr_client *client);
+
 struct rdma_dev_addr {
 	unsigned char src_dev_addr[MAX_ADDR_LEN];
 	unsigned char dst_dev_addr[MAX_ADDR_LEN];
@@ -52,6 +68,7 @@
 /**
  * rdma_resolve_ip - Resolve source and destination IP addresses to
  *   RDMA hardware addresses.
+ * @client: Address client associated with request.
  * @src_addr: An optional source address to use in the resolution.  If a
  *   source address is not provided, a usable address will be returned via
  *   the callback.
@@ -64,7 +81,8 @@
  *   or been canceled.  A status of 0 indicates success.
  * @context: User-specified context associated with the call.
  */
-int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
+int rdma_resolve_ip(struct rdma_addr_client *client,
+		    struct sockaddr *src_addr, struct sockaddr *dst_addr,
 		    struct rdma_dev_addr *addr, int timeout_ms,
 		    void (*callback)(int status, struct sockaddr *src_addr,
 				     struct rdma_dev_addr *addr, void *context),
diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h
index db1b814..64a721f 100644
--- a/include/rdma/ib_user_verbs.h
+++ b/include/rdma/ib_user_verbs.h
@@ -458,7 +458,7 @@
 	__u8  cur_qp_state;
 	__u8  path_mtu;
 	__u8  path_mig_state;
-	__u8  en_sqd_async_notify;
+	__u8  sq_draining;
 	__u8  max_rd_atomic;
 	__u8  max_dest_rd_atomic;
 	__u8  min_rnr_timer;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 401192e..61eebec 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -136,7 +136,6 @@
 
 	/* control data */
 	int			id;		/* CID */
-	struct list_head	item;		/* maintains list of conns */
 	int			c_stage;	/* connection state */
 	/*
 	 * Preallocated buffer for pdus that have data but do not
@@ -235,10 +234,8 @@
 						 * - mgmtpool,		   *
 						 * - r2tpool		   */
 	int			state;		/* session state           */
-	struct list_head	item;
 	int			age;		/* counts session re-opens */
 
-	struct list_head	connections;	/* list of connections */
 	int			cmds_max;	/* size of cmds array */
 	struct iscsi_cmd_task	**cmds;		/* Original Cmds arr */
 	struct iscsi_queue	cmdpool;	/* PDU's pool */
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 9582e84..1d77b63 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -35,6 +35,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_transport_sas.h>
+#include <asm/scatterlist.h>
 
 struct block_device;
 
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 84a6d5f..5c0e979 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -97,6 +97,7 @@
 #define PERSISTENT_RESERVE_IN 0x5e
 #define PERSISTENT_RESERVE_OUT 0x5f
 #define REPORT_LUNS           0xa0
+#define MAINTENANCE_IN        0xa3
 #define MOVE_MEDIUM           0xa5
 #define EXCHANGE_MEDIUM       0xa6
 #define READ_12               0xa8
@@ -114,6 +115,8 @@
 #define SERVICE_ACTION_IN     0x9e
 /* values for service action in */
 #define	SAI_READ_CAPACITY_16  0x10
+/* values for maintenance in */
+#define MI_REPORT_TARGET_PGS  0x0a
 
 /* Values for T10/04-262r7 */
 #define	ATA_16		      0x85	/* 16-byte pass-thru */
@@ -430,7 +433,7 @@
 #define SCSI_IOCTL_GET_PCI		0x5387
 
 /* Pull a u32 out of a SCSI message (using BE SCSI conventions) */
-static inline u32 scsi_to_u32(u8 *ptr)
+static inline __u32 scsi_to_u32(__u8 *ptr)
 {
 	return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3];
 }
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 39e8332..4b95c89 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -29,7 +29,6 @@
 struct scsi_transport_template;
 struct iscsi_transport;
 struct Scsi_Host;
-struct mempool_zone;
 struct iscsi_cls_conn;
 struct iscsi_conn;
 struct iscsi_cmd_task;
@@ -157,9 +156,6 @@
 
 	int active;			/* must be accessed with the connlock */
 	struct device dev;		/* sysfs transport/container device */
-	struct mempool_zone *z_error;
-	struct mempool_zone *z_pdu;
-	struct list_head freequeue;
 };
 
 #define iscsi_dev_to_conn(_dev) \
diff --git a/include/sound/version.h b/include/sound/version.h
index 4ad86eb..17137f3 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.13"
-#define CONFIG_SND_DATE " (Fri Oct 06 18:28:19 2006 UTC)"
+#define CONFIG_SND_DATE " (Tue Nov 28 14:07:24 2006 UTC)"
diff --git a/init/Kconfig b/init/Kconfig
index c8b2624..176f7e5 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -304,20 +304,19 @@
 
 config SYSCTL_SYSCALL
 	bool "Sysctl syscall support" if EMBEDDED
-	default n
+	default y
 	select SYSCTL
 	---help---
-	  Enable the deprecated sysctl system call.  sys_sysctl uses
-	  binary paths that have been found to be a major pain to maintain
-	  and use.  The interface in /proc/sys is now the primary and what
-	  everyone uses.
+	  sys_sysctl uses binary paths that have been found challenging
+	  to properly maintain and use.  The interface in /proc/sys
+	  using paths with ascii names is now the primary path to this
+	  information.
 
-	  Nothing has been using the binary sysctl interface for some
-	  time now so nothing should break if you disable sysctl syscall
-	  support, and your kernel will get marginally smaller.
+	  Almost nothing using the binary sysctl interface so if you are
+	  trying to save some space it is probably safe to disable this,
+	  making your kernel marginally smaller.
 
-	  Unless you have an application that uses the sys_sysctl interface
- 	  you should probably say N here.
+	  If unsure say Y here.
 
 config KALLSYMS
 	 bool "Load all symbols for debugging/kksymoops" if EMBEDDED
diff --git a/init/main.c b/init/main.c
index ee12324..36f608a 100644
--- a/init/main.c
+++ b/init/main.c
@@ -503,6 +503,7 @@
 	printk(KERN_NOTICE);
 	printk(linux_banner);
 	setup_arch(&command_line);
+	unwind_setup();
 	setup_per_cpu_areas();
 	smp_prepare_boot_cpu();	/* arch-specific boot-cpu hooks */
 
diff --git a/ipc/msg.c b/ipc/msg.c
index 5b213d9..1266b1d 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -52,7 +52,7 @@
 	long			r_msgtype;
 	long			r_maxsize;
 
-	volatile struct msg_msg	*r_msg;
+	struct msg_msg		*volatile r_msg;
 };
 
 /* one msg_sender for each sleeping sender */
@@ -124,6 +124,7 @@
 	}
 	mutex_unlock(&msg_ids(ns).mutex);
 
+	ipc_fini_ids(ns->ids[IPC_MSG_IDS]);
 	kfree(ns->ids[IPC_MSG_IDS]);
 	ns->ids[IPC_MSG_IDS] = NULL;
 }
diff --git a/ipc/sem.c b/ipc/sem.c
index 0dafcc4..21b3289 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -161,6 +161,7 @@
 	}
 	mutex_unlock(&sem_ids(ns).mutex);
 
+	ipc_fini_ids(ns->ids[IPC_SEM_IDS]);
 	kfree(ns->ids[IPC_SEM_IDS]);
 	ns->ids[IPC_SEM_IDS] = NULL;
 }
diff --git a/ipc/shm.c b/ipc/shm.c
index bfbd317..d1198dd 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -116,6 +116,7 @@
 	}
 	mutex_unlock(&shm_ids(ns).mutex);
 
+	ipc_fini_ids(ns->ids[IPC_SHM_IDS]);
 	kfree(ns->ids[IPC_SHM_IDS]);
 	ns->ids[IPC_SHM_IDS] = NULL;
 }
diff --git a/ipc/util.c b/ipc/util.c
index 42479e4..cd8bb14 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -301,7 +301,7 @@
 	 */
 	rcu_assign_pointer(ids->entries, new);
 
-	ipc_rcu_putref(old);
+	__ipc_fini_ids(ids, old);
 	return newsize;
 }
 
diff --git a/ipc/util.h b/ipc/util.h
index c8fd6b9..e3aa2c5 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -83,6 +83,18 @@
 void ipc_rcu_getref(void *ptr);
 void ipc_rcu_putref(void *ptr);
 
+static inline void __ipc_fini_ids(struct ipc_ids *ids,
+		struct ipc_id_ary *entries)
+{
+	if (entries != &ids->nullentry)
+		ipc_rcu_putref(entries);
+}
+
+static inline void ipc_fini_ids(struct ipc_ids *ids)
+{
+	__ipc_fini_ids(ids, ids->entries);
+}
+
 struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id);
 struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id);
 void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp);
diff --git a/kernel/compat.c b/kernel/compat.c
index 75573e5..6952dd0 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -678,7 +678,7 @@
 		? -EFAULT : 0;
 }
 
-long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
+long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
 		       unsigned long bitmap_size)
 {
 	int i, j;
@@ -982,4 +982,37 @@
 	}
 	return sys_move_pages(pid, nr_pages, pages, nodes, status, flags);
 }
+
+asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
+			compat_ulong_t maxnode,
+			const compat_ulong_t __user *old_nodes,
+			const compat_ulong_t __user *new_nodes)
+{
+	unsigned long __user *old = NULL;
+	unsigned long __user *new = NULL;
+	nodemask_t tmp_mask;
+	unsigned long nr_bits;
+	unsigned long size;
+
+	nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES);
+	size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
+	if (old_nodes) {
+		if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits))
+			return -EFAULT;
+		old = compat_alloc_user_space(new_nodes ? size * 2 : size);
+		if (new_nodes)
+			new = old + size / sizeof(unsigned long);
+		if (copy_to_user(old, nodes_addr(tmp_mask), size))
+			return -EFAULT;
+	}
+	if (new_nodes) {
+		if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits))
+			return -EFAULT;
+		if (new == NULL)
+			new = compat_alloc_user_space(size);
+		if (copy_to_user(new, nodes_addr(tmp_mask), size))
+			return -EFAULT;
+	}
+	return sys_migrate_pages(pid, nr_bits + 1, old, new);
+}
 #endif
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 27dd3ee..272254f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -58,8 +58,8 @@
 		recursive_depth--;
 		return;
 	}
-	mutex_unlock(&cpu_bitmask_lock);
 	recursive = NULL;
+	mutex_unlock(&cpu_bitmask_lock);
 }
 EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
 
@@ -150,18 +150,18 @@
 	p = __stop_machine_run(take_cpu_down, NULL, cpu);
 	mutex_unlock(&cpu_bitmask_lock);
 
-	if (IS_ERR(p)) {
+	if (IS_ERR(p) || cpu_online(cpu)) {
 		/* CPU didn't die: tell everyone.  Can't complain. */
 		if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
 				(void *)(long)cpu) == NOTIFY_BAD)
 			BUG();
 
-		err = PTR_ERR(p);
-		goto out_allowed;
-	}
-
-	if (cpu_online(cpu))
+		if (IS_ERR(p)) {
+			err = PTR_ERR(p);
+			goto out_allowed;
+		}
 		goto out_thread;
+	}
 
 	/* Wait for it to sleep (leaving idle task). */
 	while (!idle_cpu(cpu))
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
index 36752f1..66a0ea4 100644
--- a/kernel/delayacct.c
+++ b/kernel/delayacct.c
@@ -66,6 +66,7 @@
 {
 	struct timespec ts;
 	s64 ns;
+	unsigned long flags;
 
 	do_posix_clock_monotonic_gettime(end);
 	ts = timespec_sub(*end, *start);
@@ -73,10 +74,10 @@
 	if (ns < 0)
 		return;
 
-	spin_lock(&current->delays->lock);
+	spin_lock_irqsave(&current->delays->lock, flags);
 	*total += ns;
 	(*count)++;
-	spin_unlock(&current->delays->lock);
+	spin_unlock_irqrestore(&current->delays->lock, flags);
 }
 
 void __delayacct_blkio_start(void)
@@ -104,6 +105,7 @@
 	s64 tmp;
 	struct timespec ts;
 	unsigned long t1,t2,t3;
+	unsigned long flags;
 
 	/* Though tsk->delays accessed later, early exit avoids
 	 * unnecessary returning of other data
@@ -136,14 +138,14 @@
 
 	/* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */
 
-	spin_lock(&tsk->delays->lock);
+	spin_lock_irqsave(&tsk->delays->lock, flags);
 	tmp = d->blkio_delay_total + tsk->delays->blkio_delay;
 	d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp;
 	tmp = d->swapin_delay_total + tsk->delays->swapin_delay;
 	d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp;
 	d->blkio_count += tsk->delays->blkio_count;
 	d->swapin_count += tsk->delays->swapin_count;
-	spin_unlock(&tsk->delays->lock);
+	spin_unlock_irqrestore(&tsk->delays->lock, flags);
 
 done:
 	return 0;
@@ -152,11 +154,12 @@
 __u64 __delayacct_blkio_ticks(struct task_struct *tsk)
 {
 	__u64 ret;
+	unsigned long flags;
 
-	spin_lock(&tsk->delays->lock);
+	spin_lock_irqsave(&tsk->delays->lock, flags);
 	ret = nsec_to_clock_t(tsk->delays->blkio_delay +
 				tsk->delays->swapin_delay);
-	spin_unlock(&tsk->delays->lock);
+	spin_unlock_irqrestore(&tsk->delays->lock, flags);
 	return ret;
 }
 
diff --git a/kernel/exit.c b/kernel/exit.c
index f250a5e..06de6c4 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -128,6 +128,7 @@
 	flush_sigqueue(&tsk->pending);
 	if (sig) {
 		flush_sigqueue(&sig->shared_pending);
+		taskstats_tgid_free(sig);
 		__cleanup_signal(sig);
 	}
 }
diff --git a/kernel/fork.c b/kernel/fork.c
index 29ebb30..8cdd3e7 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -830,7 +830,7 @@
 	if (clone_flags & CLONE_THREAD) {
 		atomic_inc(&current->signal->count);
 		atomic_inc(&current->signal->live);
-		taskstats_tgid_alloc(current->signal);
+		taskstats_tgid_alloc(current);
 		return 0;
 	}
 	sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
@@ -897,7 +897,6 @@
 void __cleanup_signal(struct signal_struct *sig)
 {
 	exit_thread_group_keys(sig);
-	taskstats_tgid_free(sig);
 	kmem_cache_free(signal_cachep, sig);
 }
 
@@ -1316,9 +1315,8 @@
 	struct pt_regs regs;
 
 	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL, 0);
-	if (!task)
-		return ERR_PTR(-ENOMEM);
-	init_idle(task, cpu);
+	if (!IS_ERR(task))
+		init_idle(task, cpu);
 
 	return task;
 }
diff --git a/kernel/futex.c b/kernel/futex.c
index b364e00..93ef30b 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1507,6 +1507,13 @@
 	struct futex_q *q;
 	struct file *filp;
 	int ret, err;
+	static unsigned long printk_interval;
+
+	if (printk_timed_ratelimit(&printk_interval, 60 * 60 * 1000)) {
+		printk(KERN_WARNING "Process `%s' used FUTEX_FD, which "
+		    	"will be removed from the kernel in June 2007\n",
+			current->comm);
+	}
 
 	ret = -EINVAL;
 	if (!valid_signal(signal))
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 2d0dc3e..ebfd24a 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -233,6 +233,8 @@
 		chip->shutdown = chip->disable;
 	if (!chip->name)
 		chip->name = chip->typename;
+	if (!chip->end)
+		chip->end = dummy_irq_chip.end;
 }
 
 static inline void mask_ack_irq(struct irq_desc *desc, int irq)
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 42aa6f1..a681912 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -231,10 +231,10 @@
 		spin_unlock(&desc->lock);
 
 		action_ret = handle_IRQ_event(irq, action);
-
-		spin_lock(&desc->lock);
 		if (!noirqdebug)
 			note_interrupt(irq, desc, action_ret);
+
+		spin_lock(&desc->lock);
 		if (likely(!(desc->status & IRQ_PENDING)))
 			break;
 		desc->status &= ~IRQ_PENDING;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 6879202..b385878 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -216,6 +216,7 @@
 {
 	struct irq_desc *desc = irq_desc + irq;
 	struct irqaction *old, **p;
+	const char *old_name = NULL;
 	unsigned long flags;
 	int shared = 0;
 
@@ -255,8 +256,10 @@
 		 * set the trigger type must match.
 		 */
 		if (!((old->flags & new->flags) & IRQF_SHARED) ||
-		    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK))
+		    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK)) {
+			old_name = old->name;
 			goto mismatch;
+		}
 
 #if defined(CONFIG_IRQ_PER_CPU)
 		/* All handlers must agree on per-cpuness */
@@ -322,11 +325,13 @@
 	return 0;
 
 mismatch:
-	spin_unlock_irqrestore(&desc->lock, flags);
 	if (!(new->flags & IRQF_PROBE_SHARED)) {
 		printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq);
+		if (old_name)
+			printk(KERN_ERR "current handler: %s\n", old_name);
 		dump_stack();
 	}
+	spin_unlock_irqrestore(&desc->lock, flags);
 	return -EBUSY;
 }
 
diff --git a/kernel/kmod.c b/kernel/kmod.c
index bb4e29d..2b76dee 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -307,14 +307,14 @@
 		return 0;
 
 	f = create_write_pipe();
-	if (!f)
-		return -ENOMEM;
+	if (IS_ERR(f))
+		return PTR_ERR(f);
 	*filp = f;
 
 	f = create_read_pipe(f);
-	if (!f) {
+	if (IS_ERR(f)) {
 		free_write_pipe(*filp);
-		return -ENOMEM;
+		return PTR_ERR(f);
 	}
 	sub_info.stdin = f;
 
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index b739be2..c9fefdb 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -1081,7 +1081,8 @@
 	 */
 	for_each_possible_cpu(i) {
 		start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
-		end   = (unsigned long) &__per_cpu_end   + per_cpu_offset(i);
+		end   = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
+					+ per_cpu_offset(i);
 
 		if ((addr >= start) && (addr < end))
 			return 1;
diff --git a/kernel/module.c b/kernel/module.c
index 67009bd..f016656 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1342,7 +1342,7 @@
 
 	if (!license_is_gpl_compatible(license)) {
 		if (!(tainted & TAINT_PROPRIETARY_MODULE))
-			printk(KERN_WARNING "%s: module license '%s' taints"
+			printk(KERN_WARNING "%s: module license '%s' taints "
 				"kernel.\n", mod->name, license);
 		add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
 	}
@@ -1718,7 +1718,7 @@
 	set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
 	if (strcmp(mod->name, "ndiswrapper") == 0)
-		add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+		add_taint(TAINT_PROPRIETARY_MODULE);
 	if (strcmp(mod->name, "driverloader") == 0)
 		add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
 
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index d3a158a..b1fb786 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -71,7 +71,7 @@
 
 static int prepare_processes(void)
 {
-	int error;
+	int error = 0;
 
 	pm_prepare_console();
 
@@ -84,6 +84,12 @@
 		goto thaw;
 	}
 
+	if (pm_disk_mode == PM_DISK_TESTPROC) {
+		printk("swsusp debug: Waiting for 5 seconds.\n");
+		mdelay(5000);
+		goto thaw;
+	}
+
 	/* Free memory before shutting down devices. */
 	if (!(error = swsusp_shrink_memory()))
 		return 0;
@@ -120,13 +126,21 @@
 	if (error)
 		return error;
 
+	if (pm_disk_mode == PM_DISK_TESTPROC)
+		goto Thaw;
+
 	suspend_console();
 	error = device_suspend(PMSG_FREEZE);
 	if (error) {
 		resume_console();
 		printk("Some devices failed to suspend\n");
-		unprepare_processes();
-		return error;
+		goto Thaw;
+	}
+
+	if (pm_disk_mode == PM_DISK_TEST) {
+		printk("swsusp debug: Waiting for 5 seconds.\n");
+		mdelay(5000);
+		goto Done;
 	}
 
 	pr_debug("PM: snapshotting memory.\n");
@@ -143,16 +157,17 @@
 			power_down(pm_disk_mode);
 		else {
 			swsusp_free();
-			unprepare_processes();
-			return error;
+			goto Thaw;
 		}
-	} else
+	} else {
 		pr_debug("PM: Image restored successfully.\n");
+	}
 
 	swsusp_free();
  Done:
 	device_resume();
 	resume_console();
+ Thaw:
 	unprepare_processes();
 	return error;
 }
@@ -249,6 +264,8 @@
 	[PM_DISK_PLATFORM]	= "platform",
 	[PM_DISK_SHUTDOWN]	= "shutdown",
 	[PM_DISK_REBOOT]	= "reboot",
+	[PM_DISK_TEST]		= "test",
+	[PM_DISK_TESTPROC]	= "testproc",
 };
 
 /**
@@ -303,17 +320,19 @@
 		}
 	}
 	if (mode) {
-		if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT)
+		if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT ||
+		     mode == PM_DISK_TEST || mode == PM_DISK_TESTPROC) {
 			pm_disk_mode = mode;
-		else {
+		} else {
 			if (pm_ops && pm_ops->enter &&
 			    (mode == pm_ops->pm_disk_mode))
 				pm_disk_mode = mode;
 			else
 				error = -EINVAL;
 		}
-	} else
+	} else {
 		error = -EINVAL;
+	}
 
 	pr_debug("PM: suspend-to-disk mode set to '%s'\n",
 		 pm_disk_modes[mode]);
diff --git a/kernel/printk.c b/kernel/printk.c
index f7d427e..6642655 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -31,6 +31,7 @@
 #include <linux/security.h>
 #include <linux/bootmem.h>
 #include <linux/syscalls.h>
+#include <linux/jiffies.h>
 
 #include <asm/uaccess.h>
 
@@ -1101,3 +1102,23 @@
 				printk_ratelimit_burst);
 }
 EXPORT_SYMBOL(printk_ratelimit);
+
+/**
+ * printk_timed_ratelimit - caller-controlled printk ratelimiting
+ * @caller_jiffies: pointer to caller's state
+ * @interval_msecs: minimum interval between prints
+ *
+ * printk_timed_ratelimit() returns true if more than @interval_msecs
+ * milliseconds have elapsed since the last time printk_timed_ratelimit()
+ * returned true.
+ */
+bool printk_timed_ratelimit(unsigned long *caller_jiffies,
+			unsigned int interval_msecs)
+{
+	if (*caller_jiffies == 0 || time_after(jiffies, *caller_jiffies)) {
+		*caller_jiffies = jiffies + msecs_to_jiffies(interval_msecs);
+		return true;
+	}
+	return false;
+}
+EXPORT_SYMBOL(printk_timed_ratelimit);
diff --git a/kernel/signal.c b/kernel/signal.c
index 7ed8d53..df18c16 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -267,18 +267,25 @@
 					 int override_rlimit)
 {
 	struct sigqueue *q = NULL;
+	struct user_struct *user;
 
-	atomic_inc(&t->user->sigpending);
+	/*
+	 * In order to avoid problems with "switch_user()", we want to make
+	 * sure that the compiler doesn't re-load "t->user"
+	 */
+	user = t->user;
+	barrier();
+	atomic_inc(&user->sigpending);
 	if (override_rlimit ||
-	    atomic_read(&t->user->sigpending) <=
+	    atomic_read(&user->sigpending) <=
 			t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
 		q = kmem_cache_alloc(sigqueue_cachep, flags);
 	if (unlikely(q == NULL)) {
-		atomic_dec(&t->user->sigpending);
+		atomic_dec(&user->sigpending);
 	} else {
 		INIT_LIST_HEAD(&q->list);
 		q->flags = 0;
-		q->user = get_uid(t->user);
+		q->user = get_uid(user);
 	}
 	return(q);
 }
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index 476c374..2c6c2bf 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -293,6 +293,27 @@
 }
 
 EXPORT_SYMBOL(_spin_lock_nested);
+unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	preempt_disable();
+	spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_);
+	/*
+	 * On lockdep we dont want the hand-coded irq-enable of
+	 * _raw_spin_lock_flags() code, because lockdep assumes
+	 * that interrupts are not re-enabled during lock-acquire:
+	 */
+#ifdef CONFIG_PROVE_SPIN_LOCKING
+	_raw_spin_lock(lock);
+#else
+	_raw_spin_lock_flags(lock, &flags);
+#endif
+	return flags;
+}
+
+EXPORT_SYMBOL(_spin_lock_irqsave_nested);
 
 #endif
 
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 0e53314..d7306d0 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -135,6 +135,7 @@
 cond_syscall(sys_mremap);
 cond_syscall(sys_remap_file_pages);
 cond_syscall(compat_sys_move_pages);
+cond_syscall(compat_sys_migrate_pages);
 
 /* block-layer dependent */
 cond_syscall(sys_bdflush);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 8bff2c1..09e569f4 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1315,7 +1315,9 @@
 		return -ENOTDIR;
 	if (get_user(n, name))
 		return -EFAULT;
-	for ( ; table->ctl_name; table++) {
+	for ( ; table->ctl_name || table->procname; table++) {
+		if (!table->ctl_name)
+			continue;
 		if (n == table->ctl_name || table->ctl_name == CTL_ANY) {
 			int error;
 			if (table->child) {
@@ -1532,7 +1534,7 @@
 	int len;
 	mode_t mode;
 	
-	for (; table->ctl_name; table++) {
+	for (; table->ctl_name || table->procname; table++) {
 		/* Can't do anything without a proc name. */
 		if (!table->procname)
 			continue;
@@ -1579,7 +1581,7 @@
 static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root)
 {
 	struct proc_dir_entry *de;
-	for (; table->ctl_name; table++) {
+	for (; table->ctl_name || table->procname; table++) {
 		if (!(de = table->de))
 			continue;
 		if (de->mode & S_IFDIR) {
@@ -2680,13 +2682,33 @@
 asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
 {
 	static int msg_count;
+	struct __sysctl_args tmp;
+	int name[CTL_MAXNAME];
+	int i;
+
+	/* Read in the sysctl name for better debug message logging */
+	if (copy_from_user(&tmp, args, sizeof(tmp)))
+		return -EFAULT;
+	if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME)
+		return -ENOTDIR;
+	for (i = 0; i < tmp.nlen; i++)
+		if (get_user(name[i], tmp.name + i))
+			return -EFAULT;
+
+	/* Ignore accesses to kernel.version */
+	if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
+		goto out;
 
 	if (msg_count < 5) {
 		msg_count++;
 		printk(KERN_INFO
 			"warning: process `%s' used the removed sysctl "
-			"system call\n", current->comm);
+			"system call with ", current->comm);
+		for (i = 0; i < tmp.nlen; i++)
+			printk("%d.", name[i]);
+		printk("\n");
 	}
+out:
 	return -ENOSYS;
 }
 
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 5d6a8c5..f45c5e7 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -77,7 +77,8 @@
 	/*
 	 * If new attributes are added, please revisit this allocation
 	 */
-	skb = nlmsg_new(genlmsg_total_size(size), GFP_KERNEL);
+	size = nlmsg_total_size(genlmsg_total_size(size));
+	skb = nlmsg_new(size, GFP_KERNEL);
 	if (!skb)
 		return -ENOMEM;
 
@@ -174,21 +175,19 @@
 	up_write(&listeners->sem);
 }
 
-static int fill_pid(pid_t pid, struct task_struct *pidtsk,
+static int fill_pid(pid_t pid, struct task_struct *tsk,
 		struct taskstats *stats)
 {
 	int rc = 0;
-	struct task_struct *tsk = pidtsk;
 
-	if (!pidtsk) {
-		read_lock(&tasklist_lock);
+	if (!tsk) {
+		rcu_read_lock();
 		tsk = find_task_by_pid(pid);
-		if (!tsk) {
-			read_unlock(&tasklist_lock);
+		if (tsk)
+			get_task_struct(tsk);
+		rcu_read_unlock();
+		if (!tsk)
 			return -ESRCH;
-		}
-		get_task_struct(tsk);
-		read_unlock(&tasklist_lock);
 	} else
 		get_task_struct(tsk);
 
@@ -214,39 +213,30 @@
 
 }
 
-static int fill_tgid(pid_t tgid, struct task_struct *tgidtsk,
+static int fill_tgid(pid_t tgid, struct task_struct *first,
 		struct taskstats *stats)
 {
-	struct task_struct *tsk, *first;
+	struct task_struct *tsk;
 	unsigned long flags;
+	int rc = -ESRCH;
 
 	/*
 	 * Add additional stats from live tasks except zombie thread group
 	 * leaders who are already counted with the dead tasks
 	 */
-	first = tgidtsk;
-	if (!first) {
-		read_lock(&tasklist_lock);
+	rcu_read_lock();
+	if (!first)
 		first = find_task_by_pid(tgid);
-		if (!first) {
-			read_unlock(&tasklist_lock);
-			return -ESRCH;
-		}
-		get_task_struct(first);
-		read_unlock(&tasklist_lock);
-	} else
-		get_task_struct(first);
 
-	/* Start with stats from dead tasks */
-	spin_lock_irqsave(&first->signal->stats_lock, flags);
+	if (!first || !lock_task_sighand(first, &flags))
+		goto out;
+
 	if (first->signal->stats)
 		memcpy(stats, first->signal->stats, sizeof(*stats));
-	spin_unlock_irqrestore(&first->signal->stats_lock, flags);
 
 	tsk = first;
-	read_lock(&tasklist_lock);
 	do {
-		if (tsk->exit_state == EXIT_ZOMBIE && thread_group_leader(tsk))
+		if (tsk->exit_state)
 			continue;
 		/*
 		 * Accounting subsystem can call its functions here to
@@ -257,15 +247,18 @@
 		delayacct_add_tsk(stats, tsk);
 
 	} while_each_thread(first, tsk);
-	read_unlock(&tasklist_lock);
-	stats->version = TASKSTATS_VERSION;
 
+	unlock_task_sighand(first, &flags);
+	rc = 0;
+out:
+	rcu_read_unlock();
+
+	stats->version = TASKSTATS_VERSION;
 	/*
 	 * Accounting subsytems can also add calls here to modify
 	 * fields of taskstats.
 	 */
-
-	return 0;
+	return rc;
 }
 
 
@@ -273,7 +266,7 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&tsk->signal->stats_lock, flags);
+	spin_lock_irqsave(&tsk->sighand->siglock, flags);
 	if (!tsk->signal->stats)
 		goto ret;
 
@@ -285,7 +278,7 @@
 	 */
 	delayacct_add_tsk(tsk->signal->stats, tsk);
 ret:
-	spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
+	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
 	return;
 }
 
@@ -419,7 +412,7 @@
 	return send_reply(rep_skb, info->snd_pid);
 
 nla_put_failure:
-	return genlmsg_cancel(rep_skb, reply);
+	rc = genlmsg_cancel(rep_skb, reply);
 err:
 	nlmsg_free(rep_skb);
 	return rc;
@@ -461,24 +454,26 @@
 	size_t size;
 	int is_thread_group;
 	struct nlattr *na;
-	unsigned long flags;
 
-	if (!family_registered || !tidstats)
+	if (!family_registered)
 		return;
 
-	spin_lock_irqsave(&tsk->signal->stats_lock, flags);
-	is_thread_group = tsk->signal->stats ? 1 : 0;
-	spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
-
-	rc = 0;
 	/*
 	 * Size includes space for nested attributes
 	 */
 	size = nla_total_size(sizeof(u32)) +
 		nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
 
-	if (is_thread_group)
-		size = 2 * size;	/* PID + STATS + TGID + STATS */
+	is_thread_group = (tsk->signal->stats != NULL);
+	if (is_thread_group) {
+		/* PID + STATS + TGID + STATS */
+		size = 2 * size;
+		/* fill the tsk->signal->stats structure */
+		fill_tgid_exit(tsk);
+	}
+
+	if (!tidstats)
+		return;
 
 	rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size);
 	if (rc < 0)
@@ -498,11 +493,8 @@
 		goto send;
 
 	/*
-	 * tsk has/had a thread group so fill the tsk->signal->stats structure
 	 * Doesn't matter if tsk is the leader or the last group member leaving
 	 */
-
-	fill_tgid_exit(tsk);
 	if (!group_dead)
 		goto send;
 
@@ -519,7 +511,6 @@
 
 nla_put_failure:
 	genlmsg_cancel(rep_skb, reply);
-	goto ret;
 err_skb:
 	nlmsg_free(rep_skb);
 ret:
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 47195fa..3afeaa3 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -161,9 +161,9 @@
 			time_adjust += MAX_TICKADJ;
 			tick_length -= MAX_TICKADJ_SCALED;
 		} else {
-			time_adjust = 0;
 			tick_length += (s64)(time_adjust * NSEC_PER_USEC /
 					     HZ) << TICK_LENGTH_SHIFT;
+			time_adjust = 0;
 		}
 	}
 }
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index db44322..96f7701 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -36,7 +36,7 @@
 
 	/* calculate task elapsed time in timespec */
 	do_posix_clock_monotonic_gettime(&uptime);
-	ts = timespec_sub(uptime, current->group_leader->start_time);
+	ts = timespec_sub(uptime, tsk->start_time);
 	/* rebase elapsed time to usec */
 	ac_etime = timespec_to_ns(&ts);
 	do_div(ac_etime, NSEC_PER_USEC);
@@ -58,7 +58,10 @@
 	stats->ac_uid	 = tsk->uid;
 	stats->ac_gid	 = tsk->gid;
 	stats->ac_pid	 = tsk->pid;
-	stats->ac_ppid	 = (tsk->parent) ? tsk->parent->pid : 0;
+	rcu_read_lock();
+	stats->ac_ppid	 = pid_alive(tsk) ?
+				rcu_dereference(tsk->real_parent)->tgid : 0;
+	rcu_read_unlock();
 	stats->ac_utime	 = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
 	stats->ac_stime	 = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
 	stats->ac_minflt = tsk->min_flt;
@@ -77,13 +80,17 @@
  */
 void xacct_add_tsk(struct taskstats *stats, struct task_struct *p)
 {
+	struct mm_struct *mm;
+
 	/* convert pages-jiffies to Mbyte-usec */
 	stats->coremem = jiffies_to_usecs(p->acct_rss_mem1) * PAGE_SIZE / MB;
 	stats->virtmem = jiffies_to_usecs(p->acct_vm_mem1) * PAGE_SIZE / MB;
-	if (p->mm) {
+	mm = get_task_mm(p);
+	if (mm) {
 		/* adjust to KB unit */
-		stats->hiwater_rss   = p->mm->hiwater_rss * PAGE_SIZE / KB;
-		stats->hiwater_vm    = p->mm->hiwater_vm * PAGE_SIZE / KB;
+		stats->hiwater_rss   = mm->hiwater_rss * PAGE_SIZE / KB;
+		stats->hiwater_vm    = mm->hiwater_vm * PAGE_SIZE / KB;
+		mmput(mm);
 	}
 	stats->read_char	= p->rchar;
 	stats->write_char	= p->wchar;
diff --git a/kernel/unwind.c b/kernel/unwind.c
index 2e23686..ed0a21d 100644
--- a/kernel/unwind.c
+++ b/kernel/unwind.c
@@ -11,13 +11,15 @@
 
 #include <linux/unwind.h>
 #include <linux/module.h>
-#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/sort.h>
 #include <linux/stop_machine.h>
 #include <asm/sections.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
 extern char __start_unwind[], __end_unwind[];
+extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];
 
 #define MAX_STACK_DEPTH 8
 
@@ -100,6 +102,8 @@
 	} core, init;
 	const void *address;
 	unsigned long size;
+	const unsigned char *header;
+	unsigned long hdrsz;
 	struct unwind_table *link;
 	const char *name;
 } root_table;
@@ -145,6 +149,10 @@
 	return table;
 }
 
+static unsigned long read_pointer(const u8 **pLoc,
+                                  const void *end,
+                                  signed ptrType);
+
 static void init_unwind_table(struct unwind_table *table,
                               const char *name,
                               const void *core_start,
@@ -152,14 +160,30 @@
                               const void *init_start,
                               unsigned long init_size,
                               const void *table_start,
-                              unsigned long table_size)
+                              unsigned long table_size,
+                              const u8 *header_start,
+                              unsigned long header_size)
 {
+	const u8 *ptr = header_start + 4;
+	const u8 *end = header_start + header_size;
+
 	table->core.pc = (unsigned long)core_start;
 	table->core.range = core_size;
 	table->init.pc = (unsigned long)init_start;
 	table->init.range = init_size;
 	table->address = table_start;
 	table->size = table_size;
+	/* See if the linker provided table looks valid. */
+	if (header_size <= 4
+	    || header_start[0] != 1
+	    || (void *)read_pointer(&ptr, end, header_start[1]) != table_start
+	    || header_start[2] == DW_EH_PE_omit
+	    || read_pointer(&ptr, end, header_start[2]) <= 0
+	    || header_start[3] == DW_EH_PE_omit)
+		header_start = NULL;
+	table->hdrsz = header_size;
+	smp_wmb();
+	table->header = header_start;
 	table->link = NULL;
 	table->name = name;
 }
@@ -169,7 +193,143 @@
 	init_unwind_table(&root_table, "kernel",
 	                  _text, _end - _text,
 	                  NULL, 0,
-	                  __start_unwind, __end_unwind - __start_unwind);
+	                  __start_unwind, __end_unwind - __start_unwind,
+	                  __start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);
+}
+
+static const u32 bad_cie, not_fde;
+static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
+static signed fde_pointer_type(const u32 *cie);
+
+struct eh_frame_hdr_table_entry {
+	unsigned long start, fde;
+};
+
+static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
+{
+	const struct eh_frame_hdr_table_entry *e1 = p1;
+	const struct eh_frame_hdr_table_entry *e2 = p2;
+
+	return (e1->start > e2->start) - (e1->start < e2->start);
+}
+
+static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
+{
+	struct eh_frame_hdr_table_entry *e1 = p1;
+	struct eh_frame_hdr_table_entry *e2 = p2;
+	unsigned long v;
+
+	v = e1->start;
+	e1->start = e2->start;
+	e2->start = v;
+	v = e1->fde;
+	e1->fde = e2->fde;
+	e2->fde = v;
+}
+
+static void __init setup_unwind_table(struct unwind_table *table,
+					void *(*alloc)(unsigned long))
+{
+	const u8 *ptr;
+	unsigned long tableSize = table->size, hdrSize;
+	unsigned n;
+	const u32 *fde;
+	struct {
+		u8 version;
+		u8 eh_frame_ptr_enc;
+		u8 fde_count_enc;
+		u8 table_enc;
+		unsigned long eh_frame_ptr;
+		unsigned int fde_count;
+		struct eh_frame_hdr_table_entry table[];
+	} __attribute__((__packed__)) *header;
+
+	if (table->header)
+		return;
+
+	if (table->hdrsz)
+		printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n",
+		       table->name);
+
+	if (tableSize & (sizeof(*fde) - 1))
+		return;
+
+	for (fde = table->address, n = 0;
+	     tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
+	     tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
+		const u32 *cie = cie_for_fde(fde, table);
+		signed ptrType;
+
+		if (cie == &not_fde)
+			continue;
+		if (cie == NULL
+		    || cie == &bad_cie
+		    || (ptrType = fde_pointer_type(cie)) < 0)
+			return;
+		ptr = (const u8 *)(fde + 2);
+		if (!read_pointer(&ptr,
+		                  (const u8 *)(fde + 1) + *fde,
+		                  ptrType))
+			return;
+		++n;
+	}
+
+	if (tableSize || !n)
+		return;
+
+	hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
+	        + 2 * n * sizeof(unsigned long);
+	header = alloc(hdrSize);
+	if (!header)
+		return;
+	header->version          = 1;
+	header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native;
+	header->fde_count_enc    = DW_EH_PE_abs|DW_EH_PE_data4;
+	header->table_enc        = DW_EH_PE_abs|DW_EH_PE_native;
+	put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
+	BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
+	             % __alignof(typeof(header->fde_count)));
+	header->fde_count        = n;
+
+	BUILD_BUG_ON(offsetof(typeof(*header), table)
+	             % __alignof(typeof(*header->table)));
+	for (fde = table->address, tableSize = table->size, n = 0;
+	     tableSize;
+	     tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
+		const u32 *cie = fde + 1 - fde[1] / sizeof(*fde);
+
+		if (!fde[1])
+			continue; /* this is a CIE */
+		ptr = (const u8 *)(fde + 2);
+		header->table[n].start = read_pointer(&ptr,
+		                                      (const u8 *)(fde + 1) + *fde,
+		                                      fde_pointer_type(cie));
+		header->table[n].fde = (unsigned long)fde;
+		++n;
+	}
+	WARN_ON(n != header->fde_count);
+
+	sort(header->table,
+	     n,
+	     sizeof(*header->table),
+	     cmp_eh_frame_hdr_table_entries,
+	     swap_eh_frame_hdr_table_entries);
+
+	table->hdrsz = hdrSize;
+	smp_wmb();
+	table->header = (const void *)header;
+}
+
+static void *__init balloc(unsigned long sz)
+{
+	return __alloc_bootmem_nopanic(sz,
+	                               sizeof(unsigned int),
+	                               __pa(MAX_DMA_ADDRESS));
+}
+
+void __init unwind_setup(void)
+{
+	setup_unwind_table(&root_table, balloc);
 }
 
 #ifdef CONFIG_MODULES
@@ -193,7 +353,8 @@
 	init_unwind_table(table, module->name,
 	                  module->module_core, module->core_size,
 	                  module->module_init, module->init_size,
-	                  table_start, table_size);
+	                  table_start, table_size,
+	                  NULL, 0);
 
 	if (last_table)
 		last_table->link = table;
@@ -303,6 +464,26 @@
 	return value;
 }
 
+static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
+{
+	const u32 *cie;
+
+	if (!*fde || (*fde & (sizeof(*fde) - 1)))
+		return &bad_cie;
+	if (!fde[1])
+		return &not_fde; /* this is a CIE */
+	if ((fde[1] & (sizeof(*fde) - 1))
+	    || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address)
+		return NULL; /* this is not a valid FDE */
+	cie = fde + 1 - fde[1] / sizeof(*fde);
+	if (*cie <= sizeof(*cie) + 4
+	    || *cie >= fde[1] - sizeof(*fde)
+	    || (*cie & (sizeof(*cie) - 1))
+	    || cie[1])
+		return NULL; /* this is not a (valid) CIE */
+	return cie;
+}
+
 static unsigned long read_pointer(const u8 **pLoc,
                                   const void *end,
                                   signed ptrType)
@@ -610,49 +791,108 @@
 	unsigned i;
 	signed ptrType = -1;
 	uleb128_t retAddrReg = 0;
-	struct unwind_table *table;
+	const struct unwind_table *table;
 	struct unwind_state state;
 
 	if (UNW_PC(frame) == 0)
 		return -EINVAL;
 	if ((table = find_table(pc)) != NULL
 	    && !(table->size & (sizeof(*fde) - 1))) {
-		unsigned long tableSize = table->size;
+		const u8 *hdr = table->header;
+		unsigned long tableSize;
 
-		for (fde = table->address;
-		     tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
-		     tableSize -= sizeof(*fde) + *fde,
-		     fde += 1 + *fde / sizeof(*fde)) {
-			if (!*fde || (*fde & (sizeof(*fde) - 1)))
-				break;
-			if (!fde[1])
-				continue; /* this is a CIE */
-			if ((fde[1] & (sizeof(*fde) - 1))
-			    || fde[1] > (unsigned long)(fde + 1)
-			                - (unsigned long)table->address)
-				continue; /* this is not a valid FDE */
-			cie = fde + 1 - fde[1] / sizeof(*fde);
-			if (*cie <= sizeof(*cie) + 4
-			    || *cie >= fde[1] - sizeof(*fde)
-			    || (*cie & (sizeof(*cie) - 1))
-			    || cie[1]
-			    || (ptrType = fde_pointer_type(cie)) < 0) {
-				cie = NULL; /* this is not a (valid) CIE */
-				continue;
+		smp_rmb();
+		if (hdr && hdr[0] == 1) {
+			switch(hdr[3] & DW_EH_PE_FORM) {
+			case DW_EH_PE_native: tableSize = sizeof(unsigned long); break;
+			case DW_EH_PE_data2: tableSize = 2; break;
+			case DW_EH_PE_data4: tableSize = 4; break;
+			case DW_EH_PE_data8: tableSize = 8; break;
+			default: tableSize = 0; break;
 			}
+			ptr = hdr + 4;
+			end = hdr + table->hdrsz;
+			if (tableSize
+			    && read_pointer(&ptr, end, hdr[1])
+			       == (unsigned long)table->address
+			    && (i = read_pointer(&ptr, end, hdr[2])) > 0
+			    && i == (end - ptr) / (2 * tableSize)
+			    && !((end - ptr) % (2 * tableSize))) {
+				do {
+					const u8 *cur = ptr + (i / 2) * (2 * tableSize);
+
+					startLoc = read_pointer(&cur,
+					                        cur + tableSize,
+					                        hdr[3]);
+					if (pc < startLoc)
+						i /= 2;
+					else {
+						ptr = cur - tableSize;
+						i = (i + 1) / 2;
+					}
+				} while (startLoc && i > 1);
+				if (i == 1
+				    && (startLoc = read_pointer(&ptr,
+				                                ptr + tableSize,
+				                                hdr[3])) != 0
+				    && pc >= startLoc)
+					fde = (void *)read_pointer(&ptr,
+					                           ptr + tableSize,
+					                           hdr[3]);
+			}
+		}
+
+		if (fde != NULL) {
+			cie = cie_for_fde(fde, table);
 			ptr = (const u8 *)(fde + 2);
-			startLoc = read_pointer(&ptr,
-			                        (const u8 *)(fde + 1) + *fde,
-			                        ptrType);
-			endLoc = startLoc
-			         + read_pointer(&ptr,
-			                        (const u8 *)(fde + 1) + *fde,
-			                        ptrType & DW_EH_PE_indirect
-			                        ? ptrType
-			                        : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
-			if (pc >= startLoc && pc < endLoc)
-				break;
-			cie = NULL;
+			if(cie != NULL
+			   && cie != &bad_cie
+			   && cie != &not_fde
+			   && (ptrType = fde_pointer_type(cie)) >= 0
+			   && read_pointer(&ptr,
+			                   (const u8 *)(fde + 1) + *fde,
+			                   ptrType) == startLoc) {
+				if (!(ptrType & DW_EH_PE_indirect))
+					ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
+				endLoc = startLoc
+				         + read_pointer(&ptr,
+				                        (const u8 *)(fde + 1) + *fde,
+				                        ptrType);
+				if(pc >= endLoc)
+					fde = NULL;
+			} else
+				fde = NULL;
+		}
+		if (fde == NULL) {
+			for (fde = table->address, tableSize = table->size;
+			     cie = NULL, tableSize > sizeof(*fde)
+			     && tableSize - sizeof(*fde) >= *fde;
+			     tableSize -= sizeof(*fde) + *fde,
+			     fde += 1 + *fde / sizeof(*fde)) {
+				cie = cie_for_fde(fde, table);
+				if (cie == &bad_cie) {
+					cie = NULL;
+					break;
+				}
+				if (cie == NULL
+				    || cie == &not_fde
+				    || (ptrType = fde_pointer_type(cie)) < 0)
+					continue;
+				ptr = (const u8 *)(fde + 2);
+				startLoc = read_pointer(&ptr,
+				                        (const u8 *)(fde + 1) + *fde,
+				                        ptrType);
+				if (!startLoc)
+					continue;
+				if (!(ptrType & DW_EH_PE_indirect))
+					ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
+				endLoc = startLoc
+				         + read_pointer(&ptr,
+				                        (const u8 *)(fde + 1) + *fde,
+				                        ptrType);
+				if (pc >= startLoc && pc < endLoc)
+					break;
+			}
 		}
 	}
 	if (cie != NULL) {
@@ -698,8 +938,11 @@
 		else {
 			retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end);
 			/* skip augmentation */
-			if (((const char *)(cie + 2))[1] == 'z')
-				ptr += get_uleb128(&ptr, end);
+			if (((const char *)(cie + 2))[1] == 'z') {
+				uleb128_t augSize = get_uleb128(&ptr, end);
+
+				ptr += augSize;
+			}
 			if (ptr > end
 			   || retAddrReg >= ARRAY_SIZE(reg_info)
 			   || REG_INVALID(retAddrReg)
@@ -723,9 +966,7 @@
 	if (cie == NULL || fde == NULL) {
 #ifdef CONFIG_FRAME_POINTER
 		unsigned long top, bottom;
-#endif
 
-#ifdef CONFIG_FRAME_POINTER
 		top = STACK_TOP(frame->task);
 		bottom = STACK_BOTTOM(frame->task);
 # if FRAME_RETADDR_OFFSET < 0
diff --git a/kernel/user.c b/kernel/user.c
index 6408c04..220e586 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -187,6 +187,17 @@
 	atomic_dec(&old_user->processes);
 	switch_uid_keyring(new_user);
 	current->user = new_user;
+
+	/*
+	 * We need to synchronize with __sigqueue_alloc()
+	 * doing a get_uid(p->user).. If that saw the old
+	 * user value, we need to wait until it has exited
+	 * its critical region before we can free the old
+	 * structure.
+	 */
+	smp_mb();
+	spin_unlock_wait(&current->sighand->siglock);
+
 	free_uid(old_user);
 	suid_keys(current);
 }
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 3df9bfc..17c2f03 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -99,7 +99,7 @@
  * @wq: workqueue to use
  * @work: work to queue
  *
- * Returns non-zero if it was successfully added.
+ * Returns 0 if @work was already on a queue, non-zero otherwise.
  *
  * We queue the work to the CPU it was submitted, but there is no
  * guarantee that it will be processed by that CPU.
@@ -138,7 +138,7 @@
  * @work: work to queue
  * @delay: number of jiffies to wait before queueing
  *
- * Returns non-zero if it was successfully added.
+ * Returns 0 if @work was already on a queue, non-zero otherwise.
  */
 int fastcall queue_delayed_work(struct workqueue_struct *wq,
 			struct work_struct *work, unsigned long delay)
@@ -169,7 +169,7 @@
  * @work: work to queue
  * @delay: number of jiffies to wait before queueing
  *
- * Returns non-zero if it was successfully added.
+ * Returns 0 if @work was already on a queue, non-zero otherwise.
  */
 int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
 			struct work_struct *work, unsigned long delay)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 77491e3..d367910 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -341,7 +341,7 @@
 
 config UNWIND_INFO
 	bool "Compile the kernel with frame unwind information"
-	depends on !IA64 && !PARISC
+	depends on !IA64 && !PARISC && !ARM
 	depends on !MODULES || !(MIPS || PPC || SUPERH || V850)
 	help
 	  If you say Y here the resulting kernel image will be slightly larger
diff --git a/lib/string.c b/lib/string.c
index 63077267..a485d75 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -320,7 +320,7 @@
 		return s;
 
 	end = s + size - 1;
-	while (end != s && isspace(*end))
+	while (end >= s && isspace(*end))
 		end--;
 	*(end + 1) = '\0';
 
diff --git a/mm/filemap.c b/mm/filemap.c
index 8558732..7b84dc8 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -467,25 +467,15 @@
 }
 
 #ifdef CONFIG_NUMA
-struct page *page_cache_alloc(struct address_space *x)
+struct page *__page_cache_alloc(gfp_t gfp)
 {
 	if (cpuset_do_page_mem_spread()) {
 		int n = cpuset_mem_spread_node();
-		return alloc_pages_node(n, mapping_gfp_mask(x), 0);
+		return alloc_pages_node(n, gfp, 0);
 	}
-	return alloc_pages(mapping_gfp_mask(x), 0);
+	return alloc_pages(gfp, 0);
 }
-EXPORT_SYMBOL(page_cache_alloc);
-
-struct page *page_cache_alloc_cold(struct address_space *x)
-{
-	if (cpuset_do_page_mem_spread()) {
-		int n = cpuset_mem_spread_node();
-		return alloc_pages_node(n, mapping_gfp_mask(x)|__GFP_COLD, 0);
-	}
-	return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0);
-}
-EXPORT_SYMBOL(page_cache_alloc_cold);
+EXPORT_SYMBOL(__page_cache_alloc);
 #endif
 
 static int __sleep_on_page_lock(void *word)
@@ -826,7 +816,6 @@
 grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
 {
 	struct page *page = find_get_page(mapping, index);
-	gfp_t gfp_mask;
 
 	if (page) {
 		if (!TestSetPageLocked(page))
@@ -834,9 +823,8 @@
 		page_cache_release(page);
 		return NULL;
 	}
-	gfp_mask = mapping_gfp_mask(mapping) & ~__GFP_FS;
-	page = alloc_pages(gfp_mask, 0);
-	if (page && add_to_page_cache_lru(page, mapping, index, gfp_mask)) {
+	page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~__GFP_FS);
+	if (page && add_to_page_cache_lru(page, mapping, index, GFP_KERNEL)) {
 		page_cache_release(page);
 		page = NULL;
 	}
@@ -1884,11 +1872,10 @@
  *	if suid or (sgid and xgrp)
  *		remove privs
  */
-int remove_suid(struct dentry *dentry)
+int should_remove_suid(struct dentry *dentry)
 {
 	mode_t mode = dentry->d_inode->i_mode;
 	int kill = 0;
-	int result = 0;
 
 	/* suid always must be killed */
 	if (unlikely(mode & S_ISUID))
@@ -1901,13 +1888,28 @@
 	if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
 		kill |= ATTR_KILL_SGID;
 
-	if (unlikely(kill && !capable(CAP_FSETID))) {
-		struct iattr newattrs;
+	if (unlikely(kill && !capable(CAP_FSETID)))
+		return kill;
 
-		newattrs.ia_valid = ATTR_FORCE | kill;
-		result = notify_change(dentry, &newattrs);
-	}
-	return result;
+	return 0;
+}
+
+int __remove_suid(struct dentry *dentry, int kill)
+{
+	struct iattr newattrs;
+
+	newattrs.ia_valid = ATTR_FORCE | kill;
+	return notify_change(dentry, &newattrs);
+}
+
+int remove_suid(struct dentry *dentry)
+{
+	int kill = should_remove_suid(dentry);
+
+	if (unlikely(kill))
+		return __remove_suid(dentry, kill);
+
+	return 0;
 }
 EXPORT_SYMBOL(remove_suid);
 
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 2dbec90..a088f59 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -478,6 +478,9 @@
 retry:
 	page = find_lock_page(mapping, idx);
 	if (!page) {
+		size = i_size_read(mapping->host) >> HPAGE_SHIFT;
+		if (idx >= size)
+			goto out;
 		if (hugetlb_get_quota(mapping))
 			goto out;
 		page = alloc_huge_page(vma, address);
diff --git a/mm/migrate.c b/mm/migrate.c
index ba2453f..b4979d4 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -952,7 +952,8 @@
 				goto out;
 
 			pm[i].node = node;
-		}
+		} else
+			pm[i].node = 0;	/* anything to not match MAX_NUMNODES */
 	}
 	/* End marker */
 	pm[nr_pages].node = MAX_NUMNODES;
diff --git a/mm/mmap.c b/mm/mmap.c
index 497e502..7b40abd 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1379,7 +1379,7 @@
 		 * Check if the given range is hugepage aligned, and
 		 * can be made suitable for hugepages.
 		 */
-		ret = prepare_hugepage_range(addr, len);
+		ret = prepare_hugepage_range(addr, len, pgoff);
 	} else {
 		/*
 		 * Ensure that a normal request is not falling in a
@@ -1880,6 +1880,9 @@
 	if ((addr + len) > TASK_SIZE || (addr + len) < addr)
 		return -EINVAL;
 
+	if (is_hugepage_only_range(mm, addr, len))
+		return -EINVAL;
+
 	flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
 
 	error = arch_mmap_check(addr, len, flags);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ebd425c..aa6fcc7 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -853,7 +853,7 @@
 		pcp = &zone_pcp(zone, cpu)->pcp[cold];
 		local_irq_save(flags);
 		if (!pcp->count) {
-			pcp->count += rmqueue_bulk(zone, 0,
+			pcp->count = rmqueue_bulk(zone, 0,
 						pcp->batch, &pcp->list);
 			if (unlikely(!pcp->count))
 				goto failed;
@@ -1689,6 +1689,8 @@
 	for (pfn = start_pfn; pfn < end_pfn; pfn++) {
 		if (!early_pfn_valid(pfn))
 			continue;
+		if (!early_pfn_in_nid(pfn, nid))
+			continue;
 		page = pfn_to_page(pfn);
 		set_page_links(page, zone, nid, pfn);
 		init_page_count(page);
@@ -2259,7 +2261,7 @@
 
 	/* Account for ranges past physical memory on this node */
 	if (range_end_pfn > prev_end_pfn)
-		hole_pages = range_end_pfn -
+		hole_pages += range_end_pfn -
 				max(range_start_pfn, prev_end_pfn);
 
 	return hole_pages;
@@ -2405,7 +2407,7 @@
 		zone->zone_pgdat = pgdat;
 		zone->free_pages = 0;
 
-		zone->temp_priority = zone->prev_priority = DEF_PRIORITY;
+		zone->prev_priority = DEF_PRIORITY;
 
 		zone_pcp_init(zone);
 		INIT_LIST_HEAD(&zone->active_list);
@@ -2610,6 +2612,9 @@
 {
 	int i;
 
+	/* Regions in the early_node_map can be in any order */
+	sort_node_map();
+
 	/* Assuming a sorted map, the first range found has the starting pfn */
 	for_each_active_range_index_in_nid(i, nid)
 		return early_node_map[i].start_pfn;
@@ -2678,9 +2683,6 @@
 			max(max_zone_pfn[i], arch_zone_lowest_possible_pfn[i]);
 	}
 
-	/* Regions in the early_node_map can be in any order */
-	sort_node_map();
-
 	/* Print out the zone ranges */
 	printk("Zone PFN ranges:\n");
 	for (i = 0; i < MAX_NR_ZONES; i++)
diff --git a/mm/readahead.c b/mm/readahead.c
index 1ba736a..23cb61a 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -173,6 +173,8 @@
 
 	if (mapping->a_ops->readpages) {
 		ret = mapping->a_ops->readpages(filp, mapping, pages, nr_pages);
+		/* Clean up the remaining pages */
+		put_pages_list(pages);
 		goto out;
 	}
 
diff --git a/mm/slab.c b/mm/slab.c
index 266449d..3c4a7e3 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -883,7 +883,7 @@
 	if (node == MAX_NUMNODES)
 		node = first_node(node_online_map);
 
-	__get_cpu_var(reap_node) = node;
+	per_cpu(reap_node, cpu) = node;
 }
 
 static void next_reap_node(void)
@@ -3152,12 +3152,15 @@
 	struct zone **z;
 	void *obj = NULL;
 
-	for (z = zonelist->zones; *z && !obj; z++)
+	for (z = zonelist->zones; *z && !obj; z++) {
+		int nid = zone_to_nid(*z);
+
 		if (zone_idx(*z) <= ZONE_NORMAL &&
-				cpuset_zone_allowed(*z, flags))
+				cpuset_zone_allowed(*z, flags) &&
+				cache->nodelists[nid])
 			obj = __cache_alloc_node(cache,
-					flags | __GFP_THISNODE,
-					zone_to_nid(*z));
+					flags | __GFP_THISNODE, nid);
+	}
 	return obj;
 }
 
diff --git a/mm/sparse.c b/mm/sparse.c
index 86c52ab..b3c82ba 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -211,7 +211,7 @@
 	struct page *page, *ret;
 	unsigned long memmap_size = sizeof(struct page) * nr_pages;
 
-	page = alloc_pages(GFP_KERNEL, get_order(memmap_size));
+	page = alloc_pages(GFP_KERNEL|__GFP_NOWARN, get_order(memmap_size));
 	if (page)
 		goto got_map_page;
 
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 1133dd3..86897ee 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -160,13 +160,15 @@
 	return err;
 }
 
-struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
-				unsigned long start, unsigned long end, int node)
+static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
+					    unsigned long start, unsigned long end,
+					    int node, gfp_t gfp_mask)
 {
 	struct vm_struct **p, *tmp, *area;
 	unsigned long align = 1;
 	unsigned long addr;
 
+	BUG_ON(in_interrupt());
 	if (flags & VM_IOREMAP) {
 		int bit = fls(size);
 
@@ -179,16 +181,13 @@
 	}
 	addr = ALIGN(start, align);
 	size = PAGE_ALIGN(size);
+	if (unlikely(!size))
+		return NULL;
 
-	area = kmalloc_node(sizeof(*area), GFP_KERNEL, node);
+	area = kmalloc_node(sizeof(*area), gfp_mask & GFP_LEVEL_MASK, node);
 	if (unlikely(!area))
 		return NULL;
 
-	if (unlikely(!size)) {
-		kfree (area);
-		return NULL;
-	}
-
 	/*
 	 * We always allocate a guard page.
 	 */
@@ -236,7 +235,7 @@
 struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
 				unsigned long start, unsigned long end)
 {
-	return __get_vm_area_node(size, flags, start, end, -1);
+	return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL);
 }
 
 /**
@@ -253,9 +252,11 @@
 	return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END);
 }
 
-struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node)
+struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags,
+				   int node, gfp_t gfp_mask)
 {
-	return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node);
+	return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node,
+				  gfp_mask);
 }
 
 /* Caller must hold vmlist_lock */
@@ -487,7 +488,7 @@
 	if (!size || (size >> PAGE_SHIFT) > num_physpages)
 		return NULL;
 
-	area = get_vm_area_node(size, VM_ALLOC, node);
+	area = get_vm_area_node(size, VM_ALLOC, node, gfp_mask);
 	if (!area)
 		return NULL;
 
@@ -528,11 +529,12 @@
 	void *ret;
 
 	ret = __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
-	write_lock(&vmlist_lock);
-	area = __find_vm_area(ret);
-	area->flags |= VM_USERMAP;
-	write_unlock(&vmlist_lock);
-
+	if (ret) {
+		write_lock(&vmlist_lock);
+		area = __find_vm_area(ret);
+		area->flags |= VM_USERMAP;
+		write_unlock(&vmlist_lock);
+	}
 	return ret;
 }
 EXPORT_SYMBOL(vmalloc_user);
@@ -601,11 +603,12 @@
 	void *ret;
 
 	ret = __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
-	write_lock(&vmlist_lock);
-	area = __find_vm_area(ret);
-	area->flags |= VM_USERMAP;
-	write_unlock(&vmlist_lock);
-
+	if (ret) {
+		write_lock(&vmlist_lock);
+		area = __find_vm_area(ret);
+		area->flags |= VM_USERMAP;
+		write_unlock(&vmlist_lock);
+	}
 	return ret;
 }
 EXPORT_SYMBOL(vmalloc_32_user);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index f05527b..518540a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -723,6 +723,20 @@
 	return nr_reclaimed;
 }
 
+/*
+ * We are about to scan this zone at a certain priority level.  If that priority
+ * level is smaller (ie: more urgent) than the previous priority, then note
+ * that priority level within the zone.  This is done so that when the next
+ * process comes in to scan this zone, it will immediately start out at this
+ * priority level rather than having to build up its own scanning priority.
+ * Here, this priority affects only the reclaim-mapped threshold.
+ */
+static inline void note_zone_scanning_priority(struct zone *zone, int priority)
+{
+	if (priority < zone->prev_priority)
+		zone->prev_priority = priority;
+}
+
 static inline int zone_is_near_oom(struct zone *zone)
 {
 	return zone->pages_scanned >= (zone->nr_active + zone->nr_inactive)*3;
@@ -746,7 +760,7 @@
  * But we had to alter page->flags anyway.
  */
 static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
-				struct scan_control *sc)
+				struct scan_control *sc, int priority)
 {
 	unsigned long pgmoved;
 	int pgdeactivate = 0;
@@ -770,7 +784,7 @@
 		 * `distress' is a measure of how much trouble we're having
 		 * reclaiming pages.  0 -> no problems.  100 -> great trouble.
 		 */
-		distress = 100 >> zone->prev_priority;
+		distress = 100 >> min(zone->prev_priority, priority);
 
 		/*
 		 * The point of this algorithm is to decide when to start
@@ -922,7 +936,7 @@
 			nr_to_scan = min(nr_active,
 					(unsigned long)sc->swap_cluster_max);
 			nr_active -= nr_to_scan;
-			shrink_active_list(nr_to_scan, zone, sc);
+			shrink_active_list(nr_to_scan, zone, sc, priority);
 		}
 
 		if (nr_inactive) {
@@ -972,9 +986,7 @@
 		if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
 			continue;
 
-		zone->temp_priority = priority;
-		if (zone->prev_priority > priority)
-			zone->prev_priority = priority;
+		note_zone_scanning_priority(zone, priority);
 
 		if (zone->all_unreclaimable && priority != DEF_PRIORITY)
 			continue;	/* Let kswapd poll it */
@@ -1024,7 +1036,6 @@
 		if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
 			continue;
 
-		zone->temp_priority = DEF_PRIORITY;
 		lru_pages += zone->nr_active + zone->nr_inactive;
 	}
 
@@ -1065,13 +1076,22 @@
 	if (!sc.all_unreclaimable)
 		ret = 1;
 out:
+	/*
+	 * Now that we've scanned all the zones at this priority level, note
+	 * that level within the zone so that the next thread which performs
+	 * scanning of this zone will immediately start out at this priority
+	 * level.  This affects only the decision whether or not to bring
+	 * mapped pages onto the inactive list.
+	 */
+	if (priority < 0)
+		priority = 0;
 	for (i = 0; zones[i] != 0; i++) {
 		struct zone *zone = zones[i];
 
 		if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
 			continue;
 
-		zone->prev_priority = zone->temp_priority;
+		zone->prev_priority = priority;
 	}
 	return ret;
 }
@@ -1111,6 +1131,11 @@
 		.swap_cluster_max = SWAP_CLUSTER_MAX,
 		.swappiness = vm_swappiness,
 	};
+	/*
+	 * temp_priority is used to remember the scanning priority at which
+	 * this zone was successfully refilled to free_pages == pages_high.
+	 */
+	int temp_priority[MAX_NR_ZONES];
 
 loop_again:
 	total_scanned = 0;
@@ -1118,11 +1143,8 @@
 	sc.may_writepage = !laptop_mode;
 	count_vm_event(PAGEOUTRUN);
 
-	for (i = 0; i < pgdat->nr_zones; i++) {
-		struct zone *zone = pgdat->node_zones + i;
-
-		zone->temp_priority = DEF_PRIORITY;
-	}
+	for (i = 0; i < pgdat->nr_zones; i++)
+		temp_priority[i] = DEF_PRIORITY;
 
 	for (priority = DEF_PRIORITY; priority >= 0; priority--) {
 		int end_zone = 0;	/* Inclusive.  0 = ZONE_DMA */
@@ -1183,10 +1205,9 @@
 			if (!zone_watermark_ok(zone, order, zone->pages_high,
 					       end_zone, 0))
 				all_zones_ok = 0;
-			zone->temp_priority = priority;
-			if (zone->prev_priority > priority)
-				zone->prev_priority = priority;
+			temp_priority[i] = priority;
 			sc.nr_scanned = 0;
+			note_zone_scanning_priority(zone, priority);
 			nr_reclaimed += shrink_zone(priority, zone, &sc);
 			reclaim_state->reclaimed_slab = 0;
 			nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
@@ -1226,10 +1247,15 @@
 			break;
 	}
 out:
+	/*
+	 * Note within each zone the priority level at which this zone was
+	 * brought into a happy state.  So that the next thread which scans this
+	 * zone will start out at that priority level.
+	 */
 	for (i = 0; i < pgdat->nr_zones; i++) {
 		struct zone *zone = pgdat->node_zones + i;
 
-		zone->prev_priority = zone->temp_priority;
+		zone->prev_priority = temp_priority[i];
 	}
 	if (!all_zones_ok) {
 		cond_resched();
@@ -1358,7 +1384,7 @@
 			if (zone->nr_scan_active >= nr_pages || pass > 3) {
 				zone->nr_scan_active = 0;
 				nr_to_scan = min(nr_pages, zone->nr_active);
-				shrink_active_list(nr_to_scan, zone, sc);
+				shrink_active_list(nr_to_scan, zone, sc, prio);
 			}
 		}
 
@@ -1614,6 +1640,7 @@
 		 */
 		priority = ZONE_RECLAIM_PRIORITY;
 		do {
+			note_zone_scanning_priority(zone, priority);
 			nr_reclaimed += shrink_zone(priority, zone, &sc);
 			priority--;
 		} while (priority >= 0 && nr_reclaimed < nr_pages);
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 45b124e..8614e8f 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -587,11 +587,9 @@
 		seq_printf(m,
 			   "\n  all_unreclaimable: %u"
 			   "\n  prev_priority:     %i"
-			   "\n  temp_priority:     %i"
 			   "\n  start_pfn:         %lu",
 			   zone->all_unreclaimable,
 			   zone->prev_priority,
-			   zone->temp_priority,
 			   zone->zone_start_pfn);
 		spin_unlock_irqrestore(&zone->lock, flags);
 		seq_putc(m, '\n');
diff --git a/net/Kconfig b/net/Kconfig
index a81aca4..67e39ad 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -63,6 +63,7 @@
 if INET
 source "net/ipv4/Kconfig"
 source "net/ipv6/Kconfig"
+source "net/netlabel/Kconfig"
 
 endif # if INET
 
@@ -249,8 +250,6 @@
 config WIRELESS_EXT
 	bool
 
-source "net/netlabel/Kconfig"
-
 config FIB_RULES
 	bool
 
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 708e2e0..485e35c 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1584,7 +1584,6 @@
 
 	if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) {
 		rt = atrtr_find(&usat->sat_addr);
-		dev = rt->dev;
 	} else {
 		struct atalk_addr at_hint;
 
@@ -1592,7 +1591,6 @@
 		at_hint.s_net  = at->src_net;
 
 		rt = atrtr_find(&at_hint);
-		dev = rt->dev;
 	}
 	if (!rt)
 		return -ENETUNREACH;
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c
index c0a4ae2..62f6ed1 100644
--- a/net/atm/atm_sysfs.c
+++ b/net/atm/atm_sysfs.c
@@ -141,7 +141,7 @@
 int atm_register_sysfs(struct atm_dev *adev)
 {
 	struct class_device *cdev = &adev->class_dev;
-	int i, err;
+	int i, j, err;
 
 	cdev->class = &atm_class;
 	class_set_devdata(cdev, adev);
@@ -151,10 +151,19 @@
 	if (err < 0)
 		return err;
 
-	for (i = 0; atm_attrs[i]; i++)
-		class_device_create_file(cdev, atm_attrs[i]);
+	for (i = 0; atm_attrs[i]; i++) {
+		err = class_device_create_file(cdev, atm_attrs[i]);
+		if (err)
+			goto err_out;
+	}
 
 	return 0;
+
+err_out:
+	for (j = 0; j < i; j++)
+		class_device_remove_file(cdev, atm_attrs[j]);
+	class_device_del(cdev);
+	return err;
 }
 
 void atm_unregister_sysfs(struct atm_dev *adev)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 65f0948..bb94e6d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -57,6 +57,7 @@
 static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
 {
 	__u8 status;
+	struct hci_conn *pend;
 
 	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
@@ -71,6 +72,15 @@
 			clear_bit(HCI_INQUIRY, &hdev->flags);
 			hci_req_complete(hdev, status);
 		}
+
+		hci_dev_lock(hdev);
+
+		pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
+		if (pend)
+			hci_acl_connect(pend);
+
+		hci_dev_unlock(hdev);
+
 		break;
 
 	default:
@@ -565,11 +575,20 @@
 static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	__u8 status = *((__u8 *) skb->data);
+	struct hci_conn *pend;
 
 	BT_DBG("%s status %d", hdev->name, status);
 
 	clear_bit(HCI_INQUIRY, &hdev->flags);
 	hci_req_complete(hdev, status);
+
+	hci_dev_lock(hdev);
+
+	pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
+	if (pend)
+		hci_acl_connect(pend);
+
+	hci_dev_unlock(hdev);
 }
 
 /* Inquiry Result */
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index f26a9eb..711a085 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -120,10 +120,13 @@
 			if (!hci_test_bit(evt, &flt->event_mask))
 				continue;
 
-			if (flt->opcode && ((evt == HCI_EV_CMD_COMPLETE && 
-					flt->opcode != *(__u16 *)(skb->data + 3)) ||
-					(evt == HCI_EV_CMD_STATUS && 
-					flt->opcode != *(__u16 *)(skb->data + 4))))
+			if (flt->opcode &&
+			    ((evt == HCI_EV_CMD_COMPLETE &&
+			      flt->opcode !=
+			      get_unaligned((__u16 *)(skb->data + 3))) ||
+			     (evt == HCI_EV_CMD_STATUS &&
+			      flt->opcode !=
+			      get_unaligned((__u16 *)(skb->data + 4)))))
 				continue;
 		}
 
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 954eb74..3eeeb7a 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -259,7 +259,9 @@
 
 	BT_DBG("conn %p", conn);
 
-	conn->dev.parent  = &hdev->dev;
+	conn->dev.bus = &bt_bus;
+	conn->dev.parent = &hdev->dev;
+
 	conn->dev.release = bt_release;
 
 	snprintf(conn->dev.bus_id, BUS_ID_SIZE,
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 2b3dcb8..bbf78e6 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1353,12 +1353,12 @@
 
 	/* Configure output options and let the other side know
 	 * which ones we don't like. */
-	if (pi->conf_mtu < pi->omtu) {
-		l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+	if (pi->conf_mtu < pi->omtu)
 		result = L2CAP_CONF_UNACCEPT;
-	} else {
+	else
 		pi->omtu = pi->conf_mtu;
-	}
+
+	l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
 
 	BT_DBG("sk %p result %d", sk, result);
 	return result;
@@ -1533,6 +1533,9 @@
 	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
 		return -ENOENT;
 
+	if (sk->sk_state == BT_DISCONN)
+		goto unlock;
+
 	l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req));
 
 	if (flags & 0x0001) {
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index b8e3a5f..1fb5d42 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -765,7 +765,7 @@
 
 	BT_DBG("tty %p termios %p", tty, old);
 
-	if (!dev)
+	if (!dev || !dev->dlc || !dev->dlc->session)
 		return;
 
 	/* Handle turning off CRTSCTS */
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
index 4e4119a..4c61a7e 100644
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -58,12 +58,13 @@
 {
 	int num;
 	void *buf;
-	size_t size = maxnum * sizeof(struct __fdb_entry);
+	size_t size;
 
-	if (size > PAGE_SIZE) {
-		size = PAGE_SIZE;
+	/* Clamp size to PAGE_SIZE, test maxnum to avoid overflow */
+	if (maxnum > PAGE_SIZE/sizeof(struct __fdb_entry))
 		maxnum = PAGE_SIZE/sizeof(struct __fdb_entry);
-	}
+
+	size = maxnum * sizeof(struct __fdb_entry);
 
 	buf = kmalloc(size, GFP_USER);
 	if (!buf)
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 96bcb2f..de9d1a9 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -376,7 +376,7 @@
 
 	err = sysfs_create_bin_file(brobj, &bridge_forward);
 	if (err) {
-		pr_info("%s: can't create attribue file %s/%s\n",
+		pr_info("%s: can't create attribute file %s/%s\n",
 			__FUNCTION__, dev->name, bridge_forward.attr.name);
 		goto out2;
 	}
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 3df55b2..9f85666 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -86,7 +86,7 @@
 static inline int ebt_dev_check(char *entry, const struct net_device *device)
 {
 	int i = 0;
-	char *devname = device->name;
+	const char *devname = device->name;
 
 	if (*entry == '\0')
 		return 0;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 9308af0..6589adb 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -340,6 +340,12 @@
 	udph->dest = htons(np->remote_port);
 	udph->len = htons(udp_len);
 	udph->check = 0;
+	udph->check = csum_tcpudp_magic(htonl(np->local_ip),
+					htonl(np->remote_ip),
+					udp_len, IPPROTO_UDP,
+					csum_partial((unsigned char *)udph, udp_len, 0));
+	if (udph->check == 0)
+		udph->check = -1;
 
 	skb->nh.iph = iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
 
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index dd023fd..733d86d 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2304,6 +2304,12 @@
 	*mpls |= MPLS_STACK_BOTTOM;
 }
 
+static inline __be16 build_tci(unsigned int id, unsigned int cfi,
+			       unsigned int prio)
+{
+	return htons(id | (cfi << 12) | (prio << 13));
+}
+
 static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 					struct pktgen_dev *pkt_dev)
 {
@@ -2353,16 +2359,16 @@
 	if (pkt_dev->vlan_id != 0xffff) {
 		if(pkt_dev->svlan_id != 0xffff) {
 			svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
-			*svlan_tci = htons(pkt_dev->svlan_id);
-			*svlan_tci |= pkt_dev->svlan_p << 5;
-			*svlan_tci |= pkt_dev->svlan_cfi << 4;
+			*svlan_tci = build_tci(pkt_dev->svlan_id,
+					       pkt_dev->svlan_cfi,
+					       pkt_dev->svlan_p);
 			svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
 			*svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
 		}
 		vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
-		*vlan_tci = htons(pkt_dev->vlan_id);
-		*vlan_tci |= pkt_dev->vlan_p << 5;
-		*vlan_tci |= pkt_dev->vlan_cfi << 4;
+		*vlan_tci = build_tci(pkt_dev->vlan_id,
+				      pkt_dev->vlan_cfi,
+				      pkt_dev->vlan_p);
 		vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
 		*vlan_encapsulated_proto = __constant_htons(ETH_P_IP);
 	}
@@ -2689,16 +2695,16 @@
 	if (pkt_dev->vlan_id != 0xffff) {
 		if(pkt_dev->svlan_id != 0xffff) {
 			svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
-			*svlan_tci = htons(pkt_dev->svlan_id);
-			*svlan_tci |= pkt_dev->svlan_p << 5;
-			*svlan_tci |= pkt_dev->svlan_cfi << 4;
+			*svlan_tci = build_tci(pkt_dev->svlan_id,
+					       pkt_dev->svlan_cfi,
+					       pkt_dev->svlan_p);
 			svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
 			*svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
 		}
 		vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
-		*vlan_tci = htons(pkt_dev->vlan_id);
-		*vlan_tci |= pkt_dev->vlan_p << 5;
-		*vlan_tci |= pkt_dev->vlan_cfi << 4;
+		*vlan_tci = build_tci(pkt_dev->vlan_id,
+				      pkt_dev->vlan_cfi,
+				      pkt_dev->vlan_p);
 		vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
 		*vlan_encapsulated_proto = __constant_htons(ETH_P_IPV6);
 	}
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 3c23760..b8b1063 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -639,6 +639,7 @@
 	n->csum	     = skb->csum;
 	n->ip_summed = skb->ip_summed;
 
+	n->truesize += skb->data_len;
 	n->data_len  = skb->data_len;
 	n->len	     = skb->len;
 
@@ -1946,7 +1947,7 @@
 	do {
 		struct sk_buff *nskb;
 		skb_frag_t *frag;
-		int hsize, nsize;
+		int hsize;
 		int k;
 		int size;
 
@@ -1957,11 +1958,10 @@
 		hsize = skb_headlen(skb) - offset;
 		if (hsize < 0)
 			hsize = 0;
-		nsize = hsize + doffset;
-		if (nsize > len + doffset || !sg)
-			nsize = len + doffset;
+		if (hsize > len || !sg)
+			hsize = len;
 
-		nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
+		nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
 		if (unlikely(!nskb))
 			goto err;
 
diff --git a/net/core/sock.c b/net/core/sock.c
index d472db4..ee6cd25 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1160,7 +1160,7 @@
 			goto failure;
 
 		if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) {
-			skb = alloc_skb(header_len, sk->sk_allocation);
+			skb = alloc_skb(header_len, gfp_mask);
 			if (skb) {
 				int npages;
 				int i;
diff --git a/net/core/wireless.c b/net/core/wireless.c
index ffff0da..cb1b872 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -748,11 +748,39 @@
 		int	extra_size;
 		int	user_length = 0;
 		int	err;
+		int	essid_compat = 0;
 
 		/* Calculate space needed by arguments. Always allocate
 		 * for max space. Easier, and won't last long... */
 		extra_size = descr->max_tokens * descr->token_size;
 
+		/* Check need for ESSID compatibility for WE < 21 */
+		switch (cmd) {
+		case SIOCSIWESSID:
+		case SIOCGIWESSID:
+		case SIOCSIWNICKN:
+		case SIOCGIWNICKN:
+			if (iwr->u.data.length == descr->max_tokens + 1)
+				essid_compat = 1;
+			else if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
+				char essid[IW_ESSID_MAX_SIZE + 1];
+
+				err = copy_from_user(essid, iwr->u.data.pointer,
+						     iwr->u.data.length *
+						     descr->token_size);
+				if (err)
+					return -EFAULT;
+
+				if (essid[iwr->u.data.length - 1] == '\0')
+					essid_compat = 1;
+			}
+			break;
+		default:
+			break;
+		}
+
+		iwr->u.data.length -= essid_compat;
+
 		/* Check what user space is giving us */
 		if(IW_IS_SET(cmd)) {
 			/* Check NULL pointer */
@@ -795,7 +823,8 @@
 #endif	/* WE_IOCTL_DEBUG */
 
 		/* Create the kernel buffer */
-		extra = kmalloc(extra_size, GFP_KERNEL);
+		/*    kzalloc ensures NULL-termination for essid_compat */
+		extra = kzalloc(extra_size, GFP_KERNEL);
 		if (extra == NULL) {
 			return -ENOMEM;
 		}
@@ -819,6 +848,8 @@
 		/* Call the handler */
 		ret = handler(dev, &info, &(iwr->u), extra);
 
+		iwr->u.data.length += essid_compat;
+
 		/* If we have something to return to the user */
 		if (!ret && IW_IS_GET(cmd)) {
 			/* Check if there is enough buffer up there */
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig
index e2a095d..ef8919c 100644
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -4,15 +4,15 @@
 config IP_DCCP
 	tristate "The DCCP Protocol (EXPERIMENTAL)"
 	---help---
-	  Datagram Congestion Control Protocol
+	  Datagram Congestion Control Protocol (RFC 4340)
 
-	  From draft-ietf-dccp-spec-11 <http://www.icir.org/kohler/dcp/draft-ietf-dccp-spec-11.txt>.
+	  From http://www.ietf.org/rfc/rfc4340.txt:
 
 	  The Datagram Congestion Control Protocol (DCCP) is a transport
 	  protocol that implements bidirectional, unicast connections of
 	  congestion-controlled, unreliable datagrams. It should be suitable
 	  for use by applications such as streaming media, Internet telephony,
-	  and on-line games
+	  and on-line games.
 
 	  To compile this protocol support as a module, choose M here: the
 	  module will be called dccp.
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
index 4d176d3..f820887 100644
--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -113,7 +113,7 @@
 
 	memcpy(to, from, len);
 	/*
-	 *	From draft-ietf-dccp-spec-11.txt:
+	 *	From RFC 4340, A.2:
 	 *
 	 *	For each acknowledgement it sends, the HC-Receiver will add an
 	 *	acknowledgement record.  ack_seqno will equal the HC-Receiver
@@ -224,7 +224,7 @@
 }
 
 /*
- * Implements the draft-ietf-dccp-spec-11.txt Appendix A
+ * Implements the RFC 4340, Appendix A
  */
 int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
 		    const u64 ackno, const u8 state)
@@ -237,7 +237,7 @@
 	 * We may well decide to do buffer compression, etc, but for now lets
 	 * just drop.
 	 *
-	 * From Appendix A:
+	 * From Appendix A.1.1 (`New Packets'):
 	 *
 	 *	Of course, the circular buffer may overflow, either when the
 	 *	HC-Sender is sending data at a very high rate, when the
@@ -274,9 +274,9 @@
 		/*
 		 * A.1.2.  Old Packets
 		 *
-		 *	When a packet with Sequence Number S arrives, and
-		 *	S <= buf_ackno, the HC-Receiver will scan the table
-		 *	for the byte corresponding to S. (Indexing structures
+		 *	When a packet with Sequence Number S <= buf_ackno
+		 *	arrives, the HC-Receiver will scan the table for
+		 *	the byte corresponding to S. (Indexing structures
 		 *	could reduce the complexity of this scan.)
 		 */
 		u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno);
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
index 2424eff..cf8f20c 100644
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -28,8 +28,7 @@
 
 /** struct dccp_ackvec - ack vector
  *
- * This data structure is the one defined in the DCCP draft
- * Appendix A.
+ * This data structure is the one defined in RFC 4340, Appendix A.
  *
  * @dccpav_buf_head - circular buffer head
  * @dccpav_buf_tail - circular buffer tail
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 32752f7..8533dab 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -22,11 +22,11 @@
 	  for lost packets, would prefer CCID 2 to CCID 3.  On-line games may
 	  also prefer CCID 2.
 
-	  CCID 2 is further described in:
-	  http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid2-10.txt
+	  CCID 2 is further described in RFC 4341,
+	  http://www.ietf.org/rfc/rfc4341.txt
 
-	  This text was extracted from:
-	  http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt
+	  This text was extracted from RFC 4340 (sec. 10.1),
+	  http://www.ietf.org/rfc/rfc4340.txt
 
 	  If in doubt, say M.
 
@@ -53,15 +53,14 @@
 	  suitable than CCID 2 for applications such streaming media where a
 	  relatively smooth sending rate is of importance.
 
-	  CCID 3 is further described in:
-
-	  http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid3-11.txt.
+	  CCID 3 is further described in RFC 4342,
+	  http://www.ietf.org/rfc/rfc4342.txt
 
 	  The TFRC congestion control algorithms were initially described in
 	  RFC 3448.
 
-	  This text was extracted from:
-	  http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt
+	  This text was extracted from RFC 4340 (sec. 10.2),
+	  http://www.ietf.org/rfc/rfc4340.txt
 	  
 	  If in doubt, say M.
 
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 2efb505..162032b 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -23,7 +23,7 @@
  */
 
 /*
- * This implementation should follow: draft-ietf-dccp-ccid2-10.txt
+ * This implementation should follow RFC 4341
  *
  * BUGS:
  * - sequence number wrapping
@@ -352,14 +352,14 @@
 
 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
 	ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe);
-	ccid2_pr_debug("Sent: seq=%llu\n", seq);
+	ccid2_pr_debug("Sent: seq=%llu\n", (unsigned long long)seq);
 	do {
 		struct ccid2_seq *seqp = hctx->ccid2hctx_seqt;
 
 		while (seqp != hctx->ccid2hctx_seqh) {
 			ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n",
-			       	       seqp->ccid2s_seq, seqp->ccid2s_acked,
-				       seqp->ccid2s_sent);
+			       	       (unsigned long long)seqp->ccid2s_seq,
+				       seqp->ccid2s_acked, seqp->ccid2s_sent);
 			seqp = seqp->ccid2s_next;
 		}
 	} while (0);
@@ -480,7 +480,8 @@
 		/* first measurement */
 		if (hctx->ccid2hctx_srtt == -1) {
 			ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",
-			       	       r, jiffies, seqp->ccid2s_seq);
+			       	       r, jiffies,
+				       (unsigned long long)seqp->ccid2s_seq);
 			ccid2_change_srtt(hctx, r);
 			hctx->ccid2hctx_rttvar = r >> 1;
 		} else {
@@ -636,8 +637,9 @@
 			u64 ackno_end_rl;
 
 			dccp_set_seqno(&ackno_end_rl, ackno - rl);
-			ccid2_pr_debug("ackvec start:%llu end:%llu\n", ackno,
-				       ackno_end_rl);
+			ccid2_pr_debug("ackvec start:%llu end:%llu\n",
+				       (unsigned long long)ackno,
+				       (unsigned long long)ackno_end_rl);
 			/* if the seqno we are analyzing is larger than the
 			 * current ackno, then move towards the tail of our
 			 * seqnos.
@@ -672,7 +674,7 @@
 
 					seqp->ccid2s_acked = 1;
 					ccid2_pr_debug("Got ack for %llu\n",
-					       	       seqp->ccid2s_seq);
+						       (unsigned long long)seqp->ccid2s_seq);
 					ccid2_hc_tx_dec_pipe(sk);
 				}
 				if (seqp == hctx->ccid2hctx_seqt) {
@@ -718,7 +720,7 @@
 		while (1) {
 			if (!seqp->ccid2s_acked) {
 				ccid2_pr_debug("Packet lost: %llu\n",
-					       seqp->ccid2s_seq);
+					       (unsigned long long)seqp->ccid2s_seq);
 				/* XXX need to traverse from tail -> head in
 				 * order to detect multiple congestion events in
 				 * one ack vector.
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 67d2dc0..cec23ad 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -379,8 +379,7 @@
 		packet->dccphtx_seqno  = dp->dccps_gss;
 		/*
 		 * Check if win_count have changed
-		 * Algorithm in "8.1. Window Counter Valuer" in
-		 * draft-ietf-dccp-ccid3-11.txt
+		 * Algorithm in "8.1. Window Counter Value" in RFC 4342.
 		 */
 		quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
 		if (likely(hctx->ccid3hctx_rtt > 8))
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 0a21be4..272e858 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -50,7 +50,7 @@
 #define DCCP_TIMEWAIT_LEN (60 * HZ) /* how long to wait to destroy TIME-WAIT
 				     * state, about 60 seconds */
 
-/* draft-ietf-dccp-spec-11.txt initial RTO value */
+/* RFC 1122, 4.2.3.1 initial RTO value */
 #define DCCP_TIMEOUT_INIT ((unsigned)(3 * HZ))
 
 /* Maximal interval between probes for local resources.  */
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 7f9dc6a..1d24881 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -216,11 +216,11 @@
 		dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
 			       DCCP_PKT_SYNCACK);
 		/*
-		 * From the draft:
+		 * From RFC 4340, sec. 5.7
 		 *
 		 * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets
 		 * MAY have non-zero-length application data areas, whose
-		 * contents * receivers MUST ignore.
+		 * contents receivers MUST ignore.
 		 */
 		goto discard;
 	}
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 7e746c4..e08e768 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -183,7 +183,7 @@
 		dccp_sync_mss(sk, mtu);
 
 		/*
-		 * From: draft-ietf-dccp-spec-11.txt
+		 * From RFC 4340, sec. 14.1:
 		 *
 		 *	DCCP-Sync packets are the best choice for upward
 		 *	probing, since DCCP-Sync probes do not risk application
@@ -449,6 +449,8 @@
 					   dccp_hdr(skb)->dccph_sport);
 }
 
+static struct request_sock_ops dccp_request_sock_ops;
+
 int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
 	struct inet_request_sock *ireq;
@@ -489,7 +491,7 @@
 	if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
 		goto drop;
 
-	req = reqsk_alloc(sk->sk_prot->rsk_prot);
+	req = reqsk_alloc(&dccp_request_sock_ops);
 	if (req == NULL)
 		goto drop;
 
@@ -731,7 +733,7 @@
 	dccp_hdr_reset(skb)->dccph_reset_code =
 				DCCP_SKB_CB(rxskb)->dccpd_reset_code;
 
-	/* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */
+	/* See "8.3.1. Abnormal Termination" in RFC 4340 */
 	seqno = 0;
 	if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
 		dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 7171a78..fc4242c 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -277,7 +277,7 @@
 	__u64 seq;
 
 	sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
-			  &hdr->saddr, dh->dccph_sport, skb->dev->ifindex);
+			  &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
 
 	if (sk == NULL) {
 		ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -550,7 +550,7 @@
 	dccp_hdr_reset(skb)->dccph_reset_code =
 				DCCP_SKB_CB(rxskb)->dccpd_reset_code;
 
-	/* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */
+	/* See "8.3.1. Abnormal Termination" in RFC 4340 */
 	seqno = 0;
 	if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
 		dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
@@ -672,7 +672,6 @@
 
 static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
-	struct inet_request_sock *ireq;
 	struct dccp_sock dp;
 	struct request_sock *req;
 	struct dccp_request_sock *dreq;
@@ -701,7 +700,7 @@
 	if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
 		goto drop;
 
-	req = inet6_reqsk_alloc(sk->sk_prot->rsk_prot);
+	req = inet6_reqsk_alloc(&dccp6_request_sock_ops);
 	if (req == NULL)
 		goto drop;
 
@@ -713,7 +712,6 @@
 		goto drop_and_free;
 
 	ireq6 = inet6_rsk(req);
-	ireq = inet_rsk(req);
 	ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
 	ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
 	req->rcv_wnd	= dccp_feat_default_sequence_window;
@@ -997,6 +995,10 @@
 	if (sk->sk_state == DCCP_OPEN) { /* Fast path */
 		if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
 			goto reset;
+		if (opt_skb) {
+			/* This is where we would goto ipv6_pktoptions. */
+			__kfree_skb(opt_skb);
+		}
 		return 0;
 	}
 
@@ -1021,6 +1023,10 @@
 
 	if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
 		goto reset;
+	if (opt_skb) {
+		/* This is where we would goto ipv6_pktoptions. */
+		__kfree_skb(opt_skb);
+	}
 	return 0;
 
 reset:
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 07a3469..fb0db1f 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -215,7 +215,7 @@
 				      elapsed_time);
 			break;
 			/*
-			 * From draft-ietf-dccp-spec-11.txt:
+			 * From RFC 4340, sec. 10.3:
 			 *
 			 *	Option numbers 128 through 191 are for
 			 *	options sent from the HC-Sender to the
diff --git a/net/dccp/probe.c b/net/dccp/probe.c
index 146496f..fded149 100644
--- a/net/dccp/probe.c
+++ b/net/dccp/probe.c
@@ -160,6 +160,8 @@
 	init_waitqueue_head(&dccpw.wait);
 	spin_lock_init(&dccpw.lock);
 	dccpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &dccpw.lock);
+	if (IS_ERR(dccpw.fifo))
+		return PTR_ERR(dccpw.fifo);
 
 	if (!proc_net_fops_create(procname, S_IRUSR, &dccpprobe_fops))
 		goto err0;
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 3456cd3..21f20f2 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -166,7 +166,7 @@
 	if (scp->addr.sdn_flags & SDF_WILD)
 		return hlist_empty(&dn_wild_sk) ? &dn_wild_sk : NULL;
 
-	return &dn_sk_hash[scp->addrloc & DN_SK_HASH_MASK];
+	return &dn_sk_hash[dn_ntohs(scp->addrloc) & DN_SK_HASH_MASK];
 }
 
 /* 
@@ -180,7 +180,7 @@
 	if (port == 0)
 		return -1;
 
-	sk_for_each(sk, node, &dn_sk_hash[port & DN_SK_HASH_MASK]) {
+	sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(port) & DN_SK_HASH_MASK]) {
 		struct dn_scp *scp = DN_SK(sk);
 		if (scp->addrloc == port)
 			return -1;
@@ -194,12 +194,12 @@
 static unsigned short port = 0x2000;
 	unsigned short i_port = port;
 
-	while(check_port(++port) != 0) {
+	while(check_port(dn_htons(++port)) != 0) {
 		if (port == i_port)
 			return 0;
 	}
 
-	scp->addrloc = port;
+	scp->addrloc = dn_htons(port);
 
 	return 1;
 }
@@ -418,7 +418,7 @@
 	struct dn_scp *scp;
 
 	read_lock(&dn_hash_lock);
-	sk_for_each(sk, node, &dn_sk_hash[cb->dst_port & DN_SK_HASH_MASK]) {
+	sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(cb->dst_port) & DN_SK_HASH_MASK]) {
 		scp = DN_SK(sk);
 		if (cb->src != dn_saddr2dn(&scp->peer))
 			continue;
@@ -1016,13 +1016,14 @@
 
 static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)
 {
-        unsigned char *ptr = skb->data;
-        
-        opt->opt_optl   = *ptr++;
-        opt->opt_status = 0;
-        memcpy(opt->opt_data, ptr, opt->opt_optl);
-        skb_pull(skb, dn_ntohs(opt->opt_optl) + 1);
+	unsigned char *ptr = skb->data;
+	u16 len = *ptr++; /* yes, it's 8bit on the wire */
 
+	BUG_ON(len > 16); /* we've checked the contents earlier */
+	opt->opt_optl   = dn_htons(len);
+	opt->opt_status = 0;
+	memcpy(opt->opt_data, ptr, len);
+	skb_pull(skb, len + 1);
 }
 
 static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo)
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
index 72ecc6e..7683d4f 100644
--- a/net/decnet/dn_nsp_in.c
+++ b/net/decnet/dn_nsp_in.c
@@ -360,9 +360,9 @@
 			scp->max_window = decnet_no_fc_max_cwnd;
 
 		if (skb->len > 0) {
-			unsigned char dlen = *skb->data;
+			u16 dlen = *skb->data;
 			if ((dlen <= 16) && (dlen <= skb->len)) {
-				scp->conndata_in.opt_optl = dn_htons((__u16)dlen);
+				scp->conndata_in.opt_optl = dn_htons(dlen);
 				memcpy(scp->conndata_in.opt_data, skb->data + 1, dlen);
 			}
 		}
@@ -404,9 +404,9 @@
 	memset(scp->discdata_in.opt_data, 0, 16);
 
 	if (skb->len > 0) {
-		unsigned char dlen = *skb->data;
+		u16 dlen = *skb->data;
 		if ((dlen <= 16) && (dlen <= skb->len)) {
-			scp->discdata_in.opt_optl = dn_htons((__u16)dlen);
+			scp->discdata_in.opt_optl = dn_htons(dlen);
 			memcpy(scp->discdata_in.opt_data, skb->data + 1, dlen);
 		}
 	}
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index c2e21cd..b342e4e 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -526,7 +526,7 @@
         struct nsp_conn_init_msg *msg;
 	__u8 len = (__u8)dn_ntohs(scp->conndata_out.opt_optl);
 
-	if ((skb = dn_alloc_skb(sk, 50 + dn_ntohs(scp->conndata_out.opt_optl), gfp)) == NULL)
+	if ((skb = dn_alloc_skb(sk, 50 + len, gfp)) == NULL)
 		return;
 
         msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg));
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 3e0c882..590e0a7 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -124,8 +124,8 @@
 static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
 {
 	struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
-	u16 daddr = fl->fld_dst;
-	u16 saddr = fl->fld_src;
+	__le16 daddr = fl->fld_dst;
+	__le16 saddr = fl->fld_src;
 
 	if (((saddr ^ r->src) & r->srcmask) ||
 	    ((daddr ^ r->dst) & r->dstmask))
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index f7e84e9..a64be6c 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -32,6 +32,7 @@
 	depends on IEEE80211
 	select CRYPTO
 	select CRYPTO_ARC4
+	select CRYPTO_ECB
 	select CRC32
 	---help---
 	Include software based cipher suites in support of IEEE
@@ -58,6 +59,7 @@
 	depends on IEEE80211 && NET_RADIO
 	select CRYPTO
 	select CRYPTO_MICHAEL_MIC
+	select CRYPTO_ECB
 	select CRC32
 	---help---
 	Include software based cipher suites in support of IEEE 802.11i
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 7707041..2759312 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -1078,12 +1078,12 @@
 
 	while (length >= sizeof(*info_element)) {
 		if (sizeof(*info_element) + info_element->len > length) {
-			IEEE80211_ERROR("Info elem: parse failed: "
-					"info_element->len + 2 > left : "
-					"info_element->len+2=%zd left=%d, id=%d.\n",
-					info_element->len +
-					sizeof(*info_element),
-					length, info_element->id);
+			IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
+					     "info_element->len + 2 > left : "
+					     "info_element->len+2=%zd left=%d, id=%d.\n",
+					     info_element->len +
+					     sizeof(*info_element),
+					     length, info_element->id);
 			/* We stop processing but don't return an error here
 			 * because some misbehaviour APs break this rule. ie.
 			 * Orinoco AP1000. */
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index 589f6d2..cf51c87 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -48,7 +48,7 @@
 	dprintk(KERN_INFO PFX "sent association request!\n");
 
 	spin_lock_irqsave(&mac->lock, flags);
-	mac->associated = 0; /* just to make sure */
+	mac->associnfo.associated = 0; /* just to make sure */
 
 	/* Set a timer for timeout */
 	/* FIXME: make timeout configurable */
@@ -62,24 +62,22 @@
 {
 	struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
 	struct ieee80211softmac_network *n;
-	unsigned long flags;
 
-	spin_lock_irqsave(&mac->lock, flags);
+	mutex_lock(&mac->associnfo.mutex);
 	/* we might race against ieee80211softmac_handle_assoc_response,
 	 * so make sure only one of us does something */
-	if (!mac->associnfo.associating) {
-		spin_unlock_irqrestore(&mac->lock, flags);
-		return;
-	}
+	if (!mac->associnfo.associating)
+		goto out;
 	mac->associnfo.associating = 0;
 	mac->associnfo.bssvalid = 0;
-	mac->associated = 0;
+	mac->associnfo.associated = 0;
 
 	n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid);
-	spin_unlock_irqrestore(&mac->lock, flags);
 
 	dprintk(KERN_INFO PFX "assoc request timed out!\n");
 	ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n);
+out:
+	mutex_unlock(&mac->associnfo.mutex);
 }
 
 void
@@ -93,7 +91,7 @@
 
 	netif_carrier_off(mac->dev);
 
-	mac->associated = 0;
+	mac->associnfo.associated = 0;
 	mac->associnfo.bssvalid = 0;
 	mac->associnfo.associating = 0;
 	ieee80211softmac_init_bss(mac);
@@ -107,7 +105,7 @@
 {
 	struct ieee80211softmac_network *found;
 
-	if (mac->associnfo.bssvalid && mac->associated) {
+	if (mac->associnfo.bssvalid && mac->associnfo.associated) {
 		found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
 		if (found)
 			ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
@@ -196,17 +194,18 @@
 	int bssvalid;
 	unsigned long flags;
 
+	mutex_lock(&mac->associnfo.mutex);
+
+	if (!mac->associnfo.associating)
+		goto out;
+
 	/* ieee80211_disassoc might clear this */
 	bssvalid = mac->associnfo.bssvalid;
 
 	/* meh */
-	if (mac->associated)
+	if (mac->associnfo.associated)
 		ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
 
-	spin_lock_irqsave(&mac->lock, flags);
-	mac->associnfo.associating = 1;
-	spin_unlock_irqrestore(&mac->lock, flags);
-
 	/* try to find the requested network in our list, if we found one already */
 	if (bssvalid || mac->associnfo.bssfixed)
 		found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);	
@@ -260,10 +259,8 @@
 
 	if (!found) {
 		if (mac->associnfo.scan_retry > 0) {
-			spin_lock_irqsave(&mac->lock, flags);
 			mac->associnfo.scan_retry--;
-			spin_unlock_irqrestore(&mac->lock, flags);
-		
+
 			/* We know of no such network. Let's scan. 
 			 * NB: this also happens if we had no memory to copy the network info...
 			 * Maybe we can hope to have more memory after scanning finishes ;)
@@ -272,19 +269,17 @@
 			ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
 			if (ieee80211softmac_start_scan(mac))
 				dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
-			return;
+			goto out;
 		} else {
-			spin_lock_irqsave(&mac->lock, flags);
 			mac->associnfo.associating = 0;
-			mac->associated = 0;
-			spin_unlock_irqrestore(&mac->lock, flags);
+			mac->associnfo.associated = 0;
 
 			dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n");
 			/* reset the retry counter for the next user request since we
 			 * break out and don't reschedule ourselves after this point. */
 			mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
 			ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL);
-			return;
+			goto out;
 		}
 	}
 
@@ -297,7 +292,7 @@
 	/* copy the ESSID for displaying it */
 	mac->associnfo.associate_essid.len = found->essid.len;
 	memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1);
-	
+
 	/* we found a network! authenticate (if necessary) and associate to it. */
 	if (found->authenticating) {
 		dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n");
@@ -305,7 +300,7 @@
 			mac->associnfo.assoc_wait = 1;
 			ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
 		}
-		return;
+		goto out;
 	}
 	if (!found->authenticated && !found->authenticating) {
 		/* This relies on the fact that _auth_req only queues the work,
@@ -321,11 +316,14 @@
 			mac->associnfo.assoc_wait = 0;
 			ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
 		}
-		return;
+		goto out;
 	}
 	/* finally! now we can start associating */
 	mac->associnfo.assoc_wait = 0;
 	ieee80211softmac_assoc(mac, found);
+
+out:
+	mutex_unlock(&mac->associnfo.mutex);
 }
 
 /* call this to do whatever is necessary when we're associated */
@@ -341,7 +339,7 @@
 	mac->bssinfo.supported_rates = net->supported_rates;
 	ieee80211softmac_recalc_txrates(mac);
 
-	mac->associated = 1;
+	mac->associnfo.associated = 1;
 
 	mac->associnfo.short_preamble_available =
 		(cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0;
@@ -421,7 +419,7 @@
 			dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status);
 			mac->associnfo.associating = 0;
 			mac->associnfo.bssvalid = 0;
-			mac->associated = 0;
+			mac->associnfo.associated = 0;
 			ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network);
 	}
 	
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
index 82bfddb..b969310 100644
--- a/net/ieee80211/softmac/ieee80211softmac_io.c
+++ b/net/ieee80211/softmac/ieee80211softmac_io.c
@@ -304,7 +304,7 @@
 		2 +		/* Auth Transaction Seq */
 		2 +		/* Status Code */
 		 /* Challenge Text IE */
-		is_shared_response ? 0 : 1 + 1 + net->challenge_len
+		(is_shared_response ? 1 + 1 + net->challenge_len : 0)
 	);
 	if (unlikely((*pkt) == NULL))
 		return 0;
@@ -475,8 +475,13 @@
 {
 	struct ieee80211softmac_device *mac = ieee80211_priv(dev);
 
-	if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
-		ieee80211softmac_process_erp(mac, network->erp_value);
+	/* This might race, but we don't really care and it's not worth
+	 * adding heavyweight locking in this fastpath.
+	 */
+	if (mac->associnfo.associated) {
+		if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
+			ieee80211softmac_process_erp(mac, network->erp_value);
+	}
 
 	return 0;
 }
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index addea1c..33aff4f 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -57,6 +57,7 @@
 	INIT_LIST_HEAD(&softmac->network_list);
 	INIT_LIST_HEAD(&softmac->events);
 
+	mutex_init(&softmac->associnfo.mutex);
 	INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac);
 	INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac);
 	softmac->start_scan = ieee80211softmac_start_scan_implementation;
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index 2aa779d..23068a8 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -73,13 +73,14 @@
 	struct ieee80211softmac_network *n;
 	struct ieee80211softmac_auth_queue_item *authptr;
 	int length = 0;
-	unsigned long flags;
+
+	mutex_lock(&sm->associnfo.mutex);
 
 	/* Check if we're already associating to this or another network
 	 * If it's another network, cancel and start over with our new network
 	 * If it's our network, ignore the change, we're already doing it!
 	 */
-	if((sm->associnfo.associating || sm->associated) &&
+	if((sm->associnfo.associating || sm->associnfo.associated) &&
 	   (data->essid.flags && data->essid.length)) {
 		/* Get the associating network */
 		n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
@@ -87,10 +88,9 @@
 		   !memcmp(n->essid.data, extra, n->essid.len)) {
 			dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
 				MAC_ARG(sm->associnfo.bssid));
-			return 0;
+			goto out;
 		} else {
 			dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
-			spin_lock_irqsave(&sm->lock,flags);
 			/* Cancel assoc work */
 			cancel_delayed_work(&sm->associnfo.work);
 			/* We don't have to do this, but it's a little cleaner */
@@ -98,14 +98,13 @@
 				cancel_delayed_work(&authptr->work);
 			sm->associnfo.bssvalid = 0;
 			sm->associnfo.bssfixed = 0;
-			spin_unlock_irqrestore(&sm->lock,flags);
 			flush_scheduled_work();
+			sm->associnfo.associating = 0;
+			sm->associnfo.associated = 0;
 		}
 	}
 
 
-	spin_lock_irqsave(&sm->lock, flags);
-
 	sm->associnfo.static_essid = 0;
 	sm->associnfo.assoc_wait = 0;
 
@@ -121,10 +120,12 @@
 	 * If applicable, we have already copied the data in */
 	sm->associnfo.req_essid.len = length;
 
+	sm->associnfo.associating = 1;
 	/* queue lower level code to do work (if necessary) */
 	schedule_work(&sm->associnfo.work);
+out:
+	mutex_unlock(&sm->associnfo.mutex);
 
-	spin_unlock_irqrestore(&sm->lock, flags);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);
@@ -136,10 +137,8 @@
 			      char *extra)
 {
 	struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
-	unsigned long flags;
 
-	/* avoid getting inconsistent information */
-	spin_lock_irqsave(&sm->lock, flags);
+	mutex_lock(&sm->associnfo.mutex);
 	/* If all fails, return ANY (empty) */
 	data->essid.length = 0;
 	data->essid.flags = 0;  /* active */
@@ -152,12 +151,13 @@
 	}
 	
 	/* If we're associating/associated, return that */
-	if (sm->associated || sm->associnfo.associating) {
+	if (sm->associnfo.associated || sm->associnfo.associating) {
 		data->essid.length = sm->associnfo.associate_essid.len;
 		data->essid.flags = 1;  /* active */
 		memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
 	}
-	spin_unlock_irqrestore(&sm->lock, flags);
+	mutex_unlock(&sm->associnfo.mutex);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);
@@ -322,15 +322,15 @@
 {
 	struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
 	int err = 0;
-	unsigned long flags;
 
-	spin_lock_irqsave(&mac->lock, flags);
+	mutex_lock(&mac->associnfo.mutex);
 	if (mac->associnfo.bssvalid)
 		memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
 	else
 		memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
 	data->ap_addr.sa_family = ARPHRD_ETHER;
-	spin_unlock_irqrestore(&mac->lock, flags);
+	mutex_unlock(&mac->associnfo.mutex);
+
 	return err;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);
@@ -342,28 +342,27 @@
 			    char *extra)
 {
 	struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
-	unsigned long flags;
 
 	/* sanity check */
 	if (data->ap_addr.sa_family != ARPHRD_ETHER) {
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&mac->lock, flags);
+	mutex_lock(&mac->associnfo.mutex);
 	if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
 		/* the bssid we have is not to be fixed any longer,
 		 * and we should reassociate to the best AP. */
 		mac->associnfo.bssfixed = 0;
 		/* force reassociation */
 		mac->associnfo.bssvalid = 0;
-		if (mac->associated)
+		if (mac->associnfo.associated)
 			schedule_work(&mac->associnfo.work);
 	} else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
 		/* the bssid we have is no longer fixed */
 		mac->associnfo.bssfixed = 0;
         } else {
 		if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
-			if (mac->associnfo.associating || mac->associated) {
+			if (mac->associnfo.associating || mac->associnfo.associated) {
 			/* bssid unchanged and associated or associating - just return */
 				goto out;
 			}
@@ -378,7 +377,8 @@
         }
 
  out:
-	spin_unlock_irqrestore(&mac->lock, flags);
+	mutex_unlock(&mac->associnfo.mutex);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);
@@ -394,7 +394,8 @@
 	int err = 0;
 	char *buf;
 	int i;
-	
+
+	mutex_lock(&mac->associnfo.mutex);
 	spin_lock_irqsave(&mac->lock, flags);
 	/* bleh. shouldn't be locked for that kmalloc... */
 
@@ -432,6 +433,8 @@
 
  out:	
 	spin_unlock_irqrestore(&mac->lock, flags);
+	mutex_unlock(&mac->associnfo.mutex);
+
 	return err;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);
@@ -446,7 +449,8 @@
 	unsigned long flags;
 	int err = 0;
 	int space = wrqu->data.length;
-	
+
+	mutex_lock(&mac->associnfo.mutex);
 	spin_lock_irqsave(&mac->lock, flags);
 	
 	wrqu->data.length = 0;
@@ -459,6 +463,8 @@
 			err = -E2BIG;
 	}
 	spin_unlock_irqrestore(&mac->lock, flags);
+	mutex_lock(&mac->associnfo.mutex);
+
 	return err;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);
@@ -473,10 +479,13 @@
 	struct iw_mlme *mlme = (struct iw_mlme *)extra;
 	u16 reason = cpu_to_le16(mlme->reason_code);
 	struct ieee80211softmac_network *net;
+	int err = -EINVAL;
+
+	mutex_lock(&mac->associnfo.mutex);
 
 	if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) {
 		printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n");
-		return -EINVAL;
+		goto out;
 	}
 
 	switch (mlme->cmd) {
@@ -484,14 +493,22 @@
 		net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
 		if (!net) {
 			printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
-			return -EINVAL;
+			goto out;
 		}
 		return ieee80211softmac_deauth_req(mac, net, reason);
 	case IW_MLME_DISASSOC:
 		ieee80211softmac_send_disassoc_req(mac, reason);
-		return 0;
+		mac->associnfo.associated = 0;
+		mac->associnfo.associating = 0;
+		err = 0;
+		goto out;
 	default:
-		return -EOPNOTSUPP;
+		err = -EOPNOTSUPP;
 	}
+
+out:
+	mutex_unlock(&mac->associnfo.mutex);
+
+	return err;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index e2077a3..6460233 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1307,7 +1307,8 @@
 
 	/* We can't use ip_options_get() directly because it makes a call to
 	 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
-	 * we can't block here. */
+	 * we won't always have CAP_NET_RAW even though we _always_ want to
+	 * set the IPOPT_CIPSO option. */
 	opt_len = (buf_len + 3) & ~3;
 	opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
 	if (opt == NULL) {
@@ -1317,11 +1318,9 @@
 	memcpy(opt->__data, buf, buf_len);
 	opt->optlen = opt_len;
 	opt->is_data = 1;
+	opt->cipso = sizeof(struct iphdr);
 	kfree(buf);
 	buf = NULL;
-	ret_val = ip_options_compile(opt, NULL);
-	if (ret_val != 0)
-		goto socket_setattr_failure;
 
 	sk_inet = inet_sk(sk);
 	if (sk_inet->is_icsk) {
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 8dabbfc..9f02917 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -443,7 +443,7 @@
 				opt->router_alert = optptr - iph;
 			break;
 		      case IPOPT_CIPSO:
-		        if (opt->cipso) {
+			if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) {
 				pp_ptr = optptr;
 				goto error;
 			}
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index f8ce847..955a07a 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -420,7 +420,7 @@
 {
 	struct arphdr *rarp;
 	unsigned char *rarp_ptr;
-	unsigned long sip, tip;
+	u32 sip, tip;
 	unsigned char *sha, *tha;		/* s for "source", t for "target" */
 	struct ic_device *d;
 
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c
index 6d398f1..687c1de 100644
--- a/net/ipv4/ipvs/ip_vs_ftp.c
+++ b/net/ipv4/ipvs/ip_vs_ftp.c
@@ -200,7 +200,7 @@
 		from = n_cp->vaddr;
 		port = n_cp->vport;
 		sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from),
-			ntohs(port)&255, (ntohs(port)>>8)&255);
+			(ntohs(port)>>8)&255, ntohs(port)&255);
 		buf_len = strlen(buf);
 
 		/*
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index bfe779e..6ff05c3 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -117,7 +117,7 @@
 {
 	tcph->check =
 		ip_vs_check_diff(~oldip, newip,
-				 ip_vs_check_diff(oldport ^ htonl(0xFFFF),
+				 ip_vs_check_diff(oldport ^ htons(0xFFFF),
 						  newport, tcph->check));
 }
 
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 54aa760..691c8b6 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -122,10 +122,10 @@
 {
 	uhdr->check =
 		ip_vs_check_diff(~oldip, newip,
-				 ip_vs_check_diff(oldport ^ htonl(0xFFFF),
+				 ip_vs_check_diff(oldport ^ htons(0xFFFF),
 						  newport, uhdr->check));
 	if (!uhdr->check)
-		uhdr->check = htonl(0xFFFF);
+		uhdr->check = -1;
 }
 
 static int
@@ -173,7 +173,7 @@
 						cp->protocol,
 						(*pskb)->csum);
 		if (udph->check == 0)
-			udph->check = htonl(0xFFFF);
+			udph->check = -1;
 		IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
 			  pp->name, udph->check,
 			  (char*)&(udph->check) - (char*)udph);
@@ -228,7 +228,7 @@
 						cp->protocol,
 						(*pskb)->csum);
 		if (udph->check == 0)
-			udph->check = 0xFFFF;
+			udph->check = -1;
 		(*pskb)->ip_summed = CHECKSUM_UNNECESSARY;
 	}
 	return 1;
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 0849f1c..413c2d0a 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -466,7 +466,13 @@
 		return -EINVAL;
 	}
 
+	if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset)
+		return -EINVAL;
+
 	t = arpt_get_target(e);
+	if (e->target_offset + t->u.target_size > e->next_offset)
+		return -EINVAL;
+
 	target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
 							t->u.user.revision),
 					 "arpt_%s", t->u.user.name);
@@ -621,20 +627,18 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
-		duprintf("Looping hook\n");
-		return -ELOOP;
-	}
-
 	/* Finally, each sanity check must pass */
 	i = 0;
 	ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
 				 check_entry, name, size, &i);
 
-	if (ret != 0) {
-		ARPT_ENTRY_ITERATE(entry0, newinfo->size,
-				   cleanup_entry, &i);
-		return ret;
+	if (ret != 0)
+		goto cleanup;
+
+	ret = -ELOOP;
+	if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
+		duprintf("Looping hook\n");
+		goto cleanup;
 	}
 
 	/* And one copy for every other CPU */
@@ -643,6 +647,9 @@
 			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
+	return 0;
+cleanup:
+	ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
 	return ret;
 }
 
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 143c466..8b848aa 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -225,10 +225,8 @@
 	struct ip_conntrack_expect *i;
 	
 	list_for_each_entry(i, &ip_conntrack_expect_list, list) {
-		if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) {
-			atomic_inc(&i->use);
+		if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
 			return i;
-		}
 	}
 	return NULL;
 }
@@ -241,6 +239,8 @@
 	
 	read_lock_bh(&ip_conntrack_lock);
 	i = __ip_conntrack_expect_find(tuple);
+	if (i)
+		atomic_inc(&i->use);
 	read_unlock_bh(&ip_conntrack_lock);
 
 	return i;
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
index 7b74412..6cb9070 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
@@ -1417,7 +1417,7 @@
 		DEBUGP
 		    ("ip_ct_ras: set RAS connection timeout to %u seconds\n",
 		     info->timeout);
-		ip_ct_refresh_acct(ct, ctinfo, NULL, info->timeout * HZ);
+		ip_ct_refresh(ct, *pskb, info->timeout * HZ);
 
 		/* Set expect timeout */
 		read_lock_bh(&ip_conntrack_lock);
@@ -1465,7 +1465,7 @@
 	info->sig_port[!dir] = 0;
 
 	/* Give it 30 seconds for UCF or URJ */
-	ip_ct_refresh_acct(ct, ctinfo, NULL, 30 * HZ);
+	ip_ct_refresh(ct, *pskb, 30 * HZ);
 
 	return 0;
 }
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 262d0d4..55f0ae6 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -153,6 +153,7 @@
 	return ret;
 
 nfattr_failure:
+	ip_conntrack_proto_put(proto);
 	return -1;
 }
 
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 7edad79..97556cc 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -351,9 +351,10 @@
 	if (v->data_len < sizeof(*user_iph))
 		return 0;
 	diff = v->data_len - e->skb->len;
-	if (diff < 0)
-		skb_trim(e->skb, v->data_len);
-	else if (diff > 0) {
+	if (diff < 0) {
+		if (pskb_trim(e->skb, v->data_len))
+			return -ENOMEM;
+	} else if (diff > 0) {
 		if (v->data_len > 0xFFFF)
 			return -EINVAL;
 		if (diff > skb_tailroom(e->skb)) {
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 4b90927..8a45543 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -547,12 +547,18 @@
 		return -EINVAL;
 	}
 
+	if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
+		return -EINVAL;
+
 	j = 0;
 	ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
 	if (ret != 0)
 		goto cleanup_matches;
 
 	t = ipt_get_target(e);
+	ret = -EINVAL;
+	if (e->target_offset + t->u.target_size > e->next_offset)
+			goto cleanup_matches;
 	target = try_then_request_module(xt_find_target(AF_INET,
 						     t->u.user.name,
 						     t->u.user.revision),
@@ -712,19 +718,17 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks, entry0))
-		return -ELOOP;
-
 	/* Finally, each sanity check must pass */
 	i = 0;
 	ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry, name, size, &i);
 
-	if (ret != 0) {
-		IPT_ENTRY_ITERATE(entry0, newinfo->size,
-				  cleanup_entry, &i);
-		return ret;
-	}
+	if (ret != 0)
+		goto cleanup;
+
+	ret = -ELOOP;
+	if (!mark_source_chains(newinfo, valid_hooks, entry0))
+		goto cleanup;
 
 	/* And one copy for every other CPU */
 	for_each_possible_cpu(i) {
@@ -732,6 +736,9 @@
 			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
+	return 0;
+cleanup:
+	IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
 	return ret;
 }
 
@@ -1463,6 +1470,10 @@
 		return -EINVAL;
 	}
 
+	if (e->target_offset + sizeof(struct compat_xt_entry_target) >
+								e->next_offset)
+		return -EINVAL;
+
 	off = 0;
 	entry_offset = (void *)e - (void *)base;
 	j = 0;
@@ -1472,6 +1483,9 @@
 		goto cleanup_matches;
 
 	t = ipt_get_target(e);
+	ret = -EINVAL;
+	if (e->target_offset + t->u.target_size > e->next_offset)
+			goto cleanup_matches;
 	target = try_then_request_module(xt_find_target(AF_INET,
 						     t->u.user.name,
 						     t->u.user.revision),
@@ -1513,7 +1527,7 @@
 
 static inline int compat_copy_match_from_user(struct ipt_entry_match *m,
 	void **dstptr, compat_uint_t *size, const char *name,
-	const struct ipt_ip *ip, unsigned int hookmask, int *i)
+	const struct ipt_ip *ip, unsigned int hookmask)
 {
 	struct ipt_entry_match *dm;
 	struct ipt_match *match;
@@ -1526,22 +1540,13 @@
 	ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm),
 			     name, hookmask, ip->proto,
 			     ip->invflags & IPT_INV_PROTO);
-	if (ret)
-		goto err;
-
-	if (m->u.kernel.match->checkentry
+	if (!ret && m->u.kernel.match->checkentry
 	    && !m->u.kernel.match->checkentry(name, ip, match, dm->data,
 					      hookmask)) {
 		duprintf("ip_tables: check failed for `%s'.\n",
 			 m->u.kernel.match->name);
 		ret = -EINVAL;
-		goto err;
 	}
-	(*i)++;
-	return 0;
-
-err:
-	module_put(m->u.kernel.match->me);
 	return ret;
 }
 
@@ -1553,19 +1558,18 @@
 	struct ipt_target *target;
 	struct ipt_entry *de;
 	unsigned int origsize;
-	int ret, h, j;
+	int ret, h;
 
 	ret = 0;
 	origsize = *size;
 	de = (struct ipt_entry *)*dstptr;
 	memcpy(de, e, sizeof(struct ipt_entry));
 
-	j = 0;
 	*dstptr += sizeof(struct compat_ipt_entry);
 	ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size,
-			name, &de->ip, de->comefrom, &j);
+			name, &de->ip, de->comefrom);
 	if (ret)
-		goto cleanup_matches;
+		goto err;
 	de->target_offset = e->target_offset - (origsize - *size);
 	t = ipt_get_target(e);
 	target = t->u.kernel.target;
@@ -1599,12 +1603,7 @@
 		goto err;
 	}
 	ret = 0;
-	return ret;
-
 err:
-	module_put(t->u.kernel.target->me);
-cleanup_matches:
-	IPT_MATCH_ITERATE(e, cleanup_match, &j);
 	return ret;
 }
 
@@ -1618,7 +1617,7 @@
 		unsigned int *hook_entries,
 		unsigned int *underflows)
 {
-	unsigned int i;
+	unsigned int i, j;
 	struct xt_table_info *newinfo, *info;
 	void *pos, *entry0, *entry1;
 	unsigned int size;
@@ -1636,21 +1635,21 @@
 	}
 
 	duprintf("translate_compat_table: size %u\n", info->size);
-	i = 0;
+	j = 0;
 	xt_compat_lock(AF_INET);
 	/* Walk through entries, checking offsets. */
 	ret = IPT_ENTRY_ITERATE(entry0, total_size,
 				check_compat_entry_size_and_hooks,
 				info, &size, entry0,
 				entry0 + total_size,
-				hook_entries, underflows, &i, name);
+				hook_entries, underflows, &j, name);
 	if (ret != 0)
 		goto out_unlock;
 
 	ret = -EINVAL;
-	if (i != number) {
+	if (j != number) {
 		duprintf("translate_compat_table: %u not %u entries\n",
-			 i, number);
+			 j, number);
 		goto out_unlock;
 	}
 
@@ -1709,8 +1708,10 @@
 free_newinfo:
 	xt_free_table_info(newinfo);
 out:
+	IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j);
 	return ret;
 out_unlock:
+	compat_flush_offsets();
 	xt_compat_unlock(AF_INET);
 	goto out;
 }
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index ad0312d..264763a 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -114,6 +114,14 @@
 	tcph->window = 0;
 	tcph->urg_ptr = 0;
 
+	/* Adjust TCP checksum */
+	tcph->check = 0;
+	tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
+				   nskb->nh.iph->saddr,
+				   nskb->nh.iph->daddr,
+				   csum_partial((char *)tcph,
+						sizeof(struct tcphdr), 0));
+
 	/* Set DF, id = 0 */
 	nskb->nh.iph->frag_off = htons(IP_DF);
 	nskb->nh.iph->id = 0;
@@ -129,14 +137,8 @@
 	if (ip_route_me_harder(&nskb, addr_type))
 		goto free_nskb;
 
-	/* Adjust TCP checksum */
 	nskb->ip_summed = CHECKSUM_NONE;
-	tcph->check = 0;
-	tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
-				   nskb->nh.iph->saddr,
-				   nskb->nh.iph->daddr,
-				   csum_partial((char *)tcph,
-						sizeof(struct tcphdr), 0));
+
 	/* Adjust IP TTL */
 	nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
 
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index b430cf2..5c31dea 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -329,7 +329,7 @@
 	return err; 
 }
 
-static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
 {
 	struct iovec *iov;
 	u8 __user *type = NULL;
@@ -338,7 +338,7 @@
 	unsigned int i;
 
 	if (!msg->msg_iov)
-		return;
+		return 0;
 
 	for (i = 0; i < msg->msg_iovlen; i++) {
 		iov = &msg->msg_iov[i];
@@ -360,8 +360,9 @@
 				code = iov->iov_base;
 
 			if (type && code) {
-				get_user(fl->fl_icmp_type, type);
-			        get_user(fl->fl_icmp_code, code);
+				if (get_user(fl->fl_icmp_type, type) ||
+				    get_user(fl->fl_icmp_code, code))
+					return -EFAULT;
 				probed = 1;
 			}
 			break;
@@ -372,6 +373,7 @@
 		if (probed)
 			break;
 	}
+	return 0;
 }
 
 static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
@@ -480,8 +482,11 @@
 				    .proto = inet->hdrincl ? IPPROTO_RAW :
 					    		     sk->sk_protocol,
 				  };
-		if (!inet->hdrincl)
-			raw_probe_proto_opt(&fl, msg);
+		if (!inet->hdrincl) {
+			err = raw_probe_proto_opt(&fl, msg);
+			if (err)
+				goto done;
+		}
 
 		security_sk_classify_flow(sk, &fl);
 		err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index e82a5be..15061b3 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -129,13 +129,6 @@
 	return ret;
 }
 
-static int __init tcp_congestion_default(void)
-{
-	return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG);
-}
-
-late_initcall(tcp_congestion_default);
-
 ctl_table ipv4_table[] = {
         {
 		.ctl_name	= NET_IPV4_TCP_TIMESTAMPS,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 66e9a72..c05e8ed 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2270,7 +2270,7 @@
 					thash_entries,
 					(num_physpages >= 128 * 1024) ?
 					13 : 15,
-					HASH_HIGHMEM,
+					0,
 					&tcp_hashinfo.ehash_size,
 					NULL,
 					0);
@@ -2286,7 +2286,7 @@
 					tcp_hashinfo.ehash_size,
 					(num_physpages >= 128 * 1024) ?
 					13 : 15,
-					HASH_HIGHMEM,
+					0,
 					&tcp_hashinfo.bhash_size,
 					NULL,
 					64 * 1024);
@@ -2316,9 +2316,10 @@
 		sysctl_max_syn_backlog = 128;
 	}
 
-	sysctl_tcp_mem[0] =  768 << order;
-	sysctl_tcp_mem[1] = 1024 << order;
-	sysctl_tcp_mem[2] = 1536 << order;
+	/* Allow no more than 3/4 kernel memory (usually less) allocated to TCP */
+	sysctl_tcp_mem[0] = (1536 / sizeof (struct inet_bind_hashbucket)) << order;
+	sysctl_tcp_mem[1] = sysctl_tcp_mem[0] * 4 / 3;
+	sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2;
 
 	limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7);
 	max_share = min(4UL*1024*1024, limit);
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index af0aca1..1e2982f 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -131,6 +131,14 @@
 	return ret;
 }
 
+/* Set default value from kernel configuration at bootup */
+static int __init tcp_congestion_default(void)
+{
+	return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG);
+}
+late_initcall(tcp_congestion_default);
+
+
 /* Get current default congestion control */
 void tcp_get_default_congestion_control(char *name)
 {
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index a60ef38..6ad1848 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -190,7 +190,7 @@
          */
 
 	/* change the unit from HZ to bictcp_HZ */
-        t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start)
+        t = ((tcp_time_stamp + (ca->delay_min>>3) - ca->epoch_start)
 	     << BICTCP_HZ) / HZ;
 
         if (t < ca->bic_K)		/* t - K */
@@ -259,7 +259,7 @@
 	    (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
 		return;
 
-	delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
+	delay = (tcp_time_stamp - tp->rx_opt.rcv_tsecr)<<3;
 	if (delay == 0)
 		delay = 1;
 
@@ -366,7 +366,7 @@
 
 	beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta);
 
-	cube_rtt_scale = (bic_scale << 3) / 10;	/* 1024*c/rtt */
+	cube_rtt_scale = (bic_scale * 10);	/* 1024*c/rtt */
 
 	/* calculate the "K" for (wmax-cwnd) = c/rtt * K^3
 	 *  so K = cubic_root( (wmax-cwnd)*rtt/c )
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
index 682e7d5..283be3c 100644
--- a/net/ipv4/tcp_htcp.c
+++ b/net/ipv4/tcp_htcp.c
@@ -23,7 +23,7 @@
 MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher");
 
 struct htcp {
-	u16	alpha;		/* Fixed point arith, << 7 */
+	u32	alpha;		/* Fixed point arith, << 7 */
 	u8	beta;           /* Fixed point arith, << 7 */
 	u8	modeswitch;     /* Delay modeswitch until we had at least one congestion event */
 	u32	last_cong;	/* Time since last congestion event end */
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index 4be336f..f230eee 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -156,6 +156,8 @@
 	init_waitqueue_head(&tcpw.wait);
 	spin_lock_init(&tcpw.lock);
 	tcpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &tcpw.lock);
+	if (IS_ERR(tcpw.fifo))
+		return PTR_ERR(tcpw.fifo);
 
 	if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops))
 		goto err0;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 865d752..9e1bd37 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -928,23 +928,32 @@
 	return 1; 
 #else
 	struct udp_sock *up = udp_sk(sk);
-  	struct udphdr *uh = skb->h.uh;
+  	struct udphdr *uh;
 	struct iphdr *iph;
 	int iphlen, len;
   
-	__u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr);
-	__be32 *udpdata32 = (__be32 *)udpdata;
+	__u8 *udpdata;
+	__be32 *udpdata32;
 	__u16 encap_type = up->encap_type;
 
 	/* if we're overly short, let UDP handle it */
-	if (udpdata > skb->tail)
+	len = skb->len - sizeof(struct udphdr);
+	if (len <= 0)
 		return 1;
 
 	/* if this is not encapsulated socket, then just return now */
 	if (!encap_type)
 		return 1;
 
-	len = skb->tail - udpdata;
+	/* If this is a paged skb, make sure we pull up
+	 * whatever data we need to look at. */
+	if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
+		return 1;
+
+	/* Now we can get the pointers */
+	uh = skb->h.uh;
+	udpdata = (__u8 *)uh + sizeof(struct udphdr);
+	udpdata32 = (__be32 *)udpdata;
 
 	switch (encap_type) {
 	default:
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 8fcae7a..f98ca30 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -169,7 +169,6 @@
 
 static struct fib6_table fib6_main_tbl = {
 	.tb6_id		= RT6_TABLE_MAIN,
-	.tb6_lock	= RW_LOCK_UNLOCKED,
 	.tb6_root	= {
 		.leaf		= &ip6_null_entry,
 		.fn_flags	= RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
@@ -187,6 +186,12 @@
 {
 	unsigned int h;
 
+	/*
+	 * Initialize table lock at a single place to give lockdep a key,
+	 * tables aren't visible prior to being linked to the list.
+	 */
+	rwlock_init(&tb->tb6_lock);
+
 	h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1);
 
 	/*
@@ -199,7 +204,6 @@
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 static struct fib6_table fib6_local_tbl = {
 	.tb6_id		= RT6_TABLE_LOCAL,
-	.tb6_lock	= RW_LOCK_UNLOCKED,
 	.tb6_root 	= {
 		.leaf		= &ip6_null_entry,
 		.fn_flags	= RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
@@ -213,7 +217,6 @@
 	table = kzalloc(sizeof(*table), GFP_ATOMIC);
 	if (table != NULL) {
 		table->tb6_id = id;
-		table->tb6_lock = RW_LOCK_UNLOCKED;
 		table->tb6_root.leaf = &ip6_null_entry;
 		table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
 	}
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 1d672b0..6d4533b 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -330,8 +330,10 @@
 	fl->share = freq->flr_share;
 	addr_type = ipv6_addr_type(&freq->flr_dst);
 	if ((addr_type&IPV6_ADDR_MAPPED)
-	    || addr_type == IPV6_ADDR_ANY)
+	    || addr_type == IPV6_ADDR_ANY) {
+		err = -EINVAL;
 		goto done;
+	}
 	ipv6_addr_copy(&fl->dst, &freq->flr_dst);
 	atomic_set(&fl->users, 1);
 	switch (fl->share) {
@@ -587,6 +589,8 @@
 	while (!fl) {
 		if (++state->bucket <= FL_HASH_MASK)
 			fl = fl_ht[state->bucket];
+		else
+			break;
 	}
 	return fl;
 }
@@ -623,9 +627,13 @@
 	read_unlock_bh(&ip6_fl_lock);
 }
 
-static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl)
+static int ip6fl_seq_show(struct seq_file *seq, void *v)
 {
-	while(fl) {
+	if (v == SEQ_START_TOKEN)
+		seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
+			   "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
+	else {
+		struct ip6_flowlabel *fl = v;
 		seq_printf(seq,
 			   "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n",
 			   (unsigned)ntohl(fl->label),
@@ -636,17 +644,7 @@
 			   (long)(fl->expires - jiffies)/HZ,
 			   NIP6(fl->dst),
 			   fl->opt ? fl->opt->opt_nflen : 0);
-		fl = fl->next;
 	}
-}
-
-static int ip6fl_seq_show(struct seq_file *seq, void *v)
-{
-	if (v == SEQ_START_TOKEN)
-		seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
-			   "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
-	else
-		ip6fl_fl_seq_show(seq, v);
 	return 0;
 }
 
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 84d7ebd..b9f4029 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -542,6 +542,7 @@
 		skb->dev = t->dev;
 		dst_release(skb->dst);
 		skb->dst = NULL;
+		nf_reset(skb);
 		if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
 			ipv6_copy_dscp(ipv6h, skb->nh.ipv6h);
 		ip6ip6_ecn_decapsulate(ipv6h, skb);
@@ -1149,6 +1150,20 @@
 	return err;
 }
 
+static void __exit ip6ip6_destroy_tunnels(void)
+{
+	int h;
+	struct ip6_tnl *t;
+
+	for (h = 0; h < HASH_SIZE; h++) {
+		while ((t = tnls_r_l[h]) != NULL)
+			unregister_netdevice(t->dev);
+	}
+
+	t = tnls_wc[0];
+	unregister_netdevice(t->dev);
+}
+
 /**
  * ip6_tunnel_cleanup - free resources and unregister protocol
  **/
@@ -1158,7 +1173,9 @@
 	if (xfrm6_tunnel_deregister(&ip6ip6_handler))
 		printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
 
-	unregister_netdev(ip6ip6_fb_tnl_dev);
+	rtnl_lock();
+	ip6ip6_destroy_tunnels();
+	rtnl_unlock();
 }
 
 module_init(ip6_tunnel_init);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 41a8a5f..73eb8c3 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1742,6 +1742,7 @@
 
 void ndisc_cleanup(void)
 {
+	unregister_netdevice_notifier(&ndisc_netdev_notifier);
 #ifdef CONFIG_SYSCTL
 	neigh_sysctl_unregister(&nd_tbl.parms);
 #endif
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 4bc4e5b..d7c45a9c 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -40,7 +40,7 @@
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 config IP6_NF_IPTABLES
-	tristate "IP6 tables support (required for filtering/masq/NAT)"
+	tristate "IP6 tables support (required for filtering)"
 	depends on NETFILTER_XTABLES
 	help
 	  ip6tables is a general, extensible packet identification framework.
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 9510c24..9fec832 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -349,9 +349,10 @@
 	if (v->data_len < sizeof(*user_iph))
 		return 0;
 	diff = v->data_len - e->skb->len;
-	if (diff < 0)
-		skb_trim(e->skb, v->data_len);
-	else if (diff > 0) {
+	if (diff < 0) {
+		if (pskb_trim(e->skb, v->data_len))
+			return -ENOMEM;
+	} else if (diff > 0) {
 		if (v->data_len > 0xFFFF)
 			return -EINVAL;
 		if (diff > skb_tailroom(e->skb)) {
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 4ab368f..204e021 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -111,7 +111,7 @@
 		 const char *outdev,
 		 const struct ip6t_ip6 *ip6info,
 		 unsigned int *protoff,
-		 int *fragoff)
+		 int *fragoff, int *hotdrop)
 {
 	size_t i;
 	unsigned long ret;
@@ -169,9 +169,11 @@
 		unsigned short _frag_off;
 
 		protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off);
-		if (protohdr < 0)
+		if (protohdr < 0) {
+			if (_frag_off == 0)
+				*hotdrop = 1;
 			return 0;
-
+		}
 		*fragoff = _frag_off;
 
 		dprintf("Packet protocol %hi ?= %s%hi.\n",
@@ -290,7 +292,7 @@
 		IP_NF_ASSERT(e);
 		IP_NF_ASSERT(back);
 		if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6,
-			&protoff, &offset)) {
+			&protoff, &offset, &hotdrop)) {
 			struct ip6t_entry_target *t;
 
 			if (IP6T_MATCH_ITERATE(e, do_match,
@@ -584,12 +586,19 @@
 		return -EINVAL;
 	}
 
+	if (e->target_offset + sizeof(struct ip6t_entry_target) >
+								e->next_offset)
+		return -EINVAL;
+
 	j = 0;
 	ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j);
 	if (ret != 0)
 		goto cleanup_matches;
 
 	t = ip6t_get_target(e);
+	ret = -EINVAL;
+	if (e->target_offset + t->u.target_size > e->next_offset)
+			goto cleanup_matches;
 	target = try_then_request_module(xt_find_target(AF_INET6,
 							t->u.user.name,
 							t->u.user.revision),
@@ -749,19 +758,17 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks, entry0))
-		return -ELOOP;
-
 	/* Finally, each sanity check must pass */
 	i = 0;
 	ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry, name, size, &i);
 
-	if (ret != 0) {
-		IP6T_ENTRY_ITERATE(entry0, newinfo->size,
-				  cleanup_entry, &i);
-		return ret;
-	}
+	if (ret != 0)
+		goto cleanup;
+
+	ret = -ELOOP;
+	if (!mark_source_chains(newinfo, valid_hooks, entry0))
+		goto cleanup;
 
 	/* And one copy for every other CPU */
 	for_each_possible_cpu(i) {
@@ -769,6 +776,9 @@
 			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
+	return 0;
+cleanup:
+	IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
 	return ret;
 }
 
@@ -1438,6 +1448,9 @@
  * If target header is found, its offset is set in *offset and return protocol
  * number. Otherwise, return -1.
  *
+ * If the first fragment doesn't contain the final protocol header or
+ * NEXTHDR_NONE it is considered invalid.
+ *
  * Note that non-1st fragment is special case that "the protocol number
  * of last header" is "next header" field in Fragment header. In this case,
  * *offset is meaningless and fragment offset is stored in *fragoff if fragoff
@@ -1461,12 +1474,12 @@
 		if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
 			if (target < 0)
 				break;
-			return -1;
+			return -ENOENT;
 		}
 
 		hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
 		if (hp == NULL)
-			return -1;
+			return -EBADMSG;
 		if (nexthdr == NEXTHDR_FRAGMENT) {
 			unsigned short _frag_off, *fp;
 			fp = skb_header_pointer(skb,
@@ -1475,18 +1488,18 @@
 						sizeof(_frag_off),
 						&_frag_off);
 			if (fp == NULL)
-				return -1;
+				return -EBADMSG;
 
 			_frag_off = ntohs(*fp) & ~0x7;
 			if (_frag_off) {
 				if (target < 0 &&
 				    ((!ipv6_ext_hdr(hp->nexthdr)) ||
-				     nexthdr == NEXTHDR_NONE)) {
+				     hp->nexthdr == NEXTHDR_NONE)) {
 					if (fragoff)
 						*fragoff = _frag_off;
 					return hp->nexthdr;
 				}
-				return -1;
+				return -ENOENT;
 			}
 			hdrlen = 8;
 		} else if (nexthdr == NEXTHDR_AUTH)
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index ec1b160..4648664 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -54,9 +54,14 @@
 	const struct ip6t_ah *ahinfo = matchinfo;
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
+	int err;
 
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0)
+	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
+	if (err < 0) {
+		if (err != -ENOENT)
+			*hotdrop = 1;
 		return 0;
+	}
 
 	ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
 	if (ah == NULL) {
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 78d9c8b..cd22eaa 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -52,9 +52,14 @@
 	struct frag_hdr _frag, *fh;
 	const struct ip6t_frag *fraginfo = matchinfo;
 	unsigned int ptr;
+	int err;
 
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0)
+	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
+	if (err < 0) {
+		if (err != -ENOENT)
+			*hotdrop = 1;
 		return 0;
+	}
 
 	fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
 	if (fh == NULL) {
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index d32a205..3f25bab 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -65,9 +65,14 @@
 	u8 _opttype, *tp = NULL;
 	u8 _optlen, *lp = NULL;
 	unsigned int optlen;
+	int err;
 
-	if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0)
+	err = ipv6_find_hdr(skb, &ptr, match->data, NULL);
+	if (err < 0) {
+		if (err != -ENOENT)
+			*hotdrop = 1;
 		return 0;
+	}
 
 	oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
 	if (oh == NULL) {
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index bcb2e16..54d7d14 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -58,9 +58,14 @@
 	unsigned int hdrlen = 0;
 	unsigned int ret = 0;
 	struct in6_addr *ap, _addr;
+	int err;
 
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0)
+	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
+	if (err < 0) {
+		if (err != -ENOENT)
+			*hotdrop = 1;
 		return 0;
+	}
 
 	rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
 	if (rh == NULL) {
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index d09329c..d6dedc4 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -604,7 +604,7 @@
 	return err; 
 }
 
-static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
 {
 	struct iovec *iov;
 	u8 __user *type = NULL;
@@ -616,7 +616,7 @@
 	int i;
 
 	if (!msg->msg_iov)
-		return;
+		return 0;
 
 	for (i = 0; i < msg->msg_iovlen; i++) {
 		iov = &msg->msg_iov[i];
@@ -638,8 +638,9 @@
 				code = iov->iov_base;
 
 			if (type && code) {
-				get_user(fl->fl_icmp_type, type);
-				get_user(fl->fl_icmp_code, code);
+				if (get_user(fl->fl_icmp_type, type) ||
+				    get_user(fl->fl_icmp_code, code))
+					return -EFAULT;
 				probed = 1;
 			}
 			break;
@@ -650,7 +651,8 @@
 			/* check if type field is readable or not. */
 			if (iov->iov_len > 2 - len) {
 				u8 __user *p = iov->iov_base;
-				get_user(fl->fl_mh_type, &p[2 - len]);
+				if (get_user(fl->fl_mh_type, &p[2 - len]))
+					return -EFAULT;
 				probed = 1;
 			} else
 				len += iov->iov_len;
@@ -664,6 +666,7 @@
 		if (probed)
 			break;
 	}
+	return 0;
 }
 
 static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
@@ -787,7 +790,9 @@
 	opt = ipv6_fixup_options(&opt_space, opt);
 
 	fl.proto = proto;
-	rawv6_probe_proto_opt(&fl, msg);
+	err = rawv6_probe_proto_opt(&fl, msg);
+	if (err)
+		goto out;
  
 	ipv6_addr_copy(&fl.fl6_dst, daddr);
 	if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c953466..b39ae99 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -330,6 +330,8 @@
 		read_lock_bh(&neigh->lock);
 		if (neigh->nud_state & NUD_VALID)
 			m = 2;
+		else if (!(neigh->nud_state & NUD_FAILED))
+			m = 1;
 		read_unlock_bh(&neigh->lock);
 	}
 	return m;
@@ -347,9 +349,7 @@
 	m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;
 #endif
 	n = rt6_check_neigh(rt);
-	if (n > 1)
-		m |= 16;
-	else if (!n && strict & RT6_LOOKUP_F_REACHABLE)
+	if (!n && (strict & RT6_LOOKUP_F_REACHABLE))
 		return -1;
 	return m;
 }
@@ -380,10 +380,11 @@
 			continue;
 
 		if (m > mpri) {
-			rt6_probe(match);
+			if (strict & RT6_LOOKUP_F_REACHABLE)
+				rt6_probe(match);
 			match = rt;
 			mpri = m;
-		} else {
+		} else if (strict & RT6_LOOKUP_F_REACHABLE) {
 			rt6_probe(rt);
 		}
 	}
@@ -636,7 +637,7 @@
 	int strict = 0;
 	int attempts = 3;
 	int err;
-	int reachable = RT6_LOOKUP_F_REACHABLE;
+	int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
 
 	strict |= flags & RT6_LOOKUP_F_IFACE;
 
@@ -733,7 +734,7 @@
 	int strict = 0;
 	int attempts = 3;
 	int err;
-	int reachable = RT6_LOOKUP_F_REACHABLE;
+	int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
 
 	strict |= flags & RT6_LOOKUP_F_IFACE;
 
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b481a4d..be699f8 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -854,3 +854,4 @@
 module_init(sit_init);
 module_exit(sit_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("sit0");
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e0c3934..c83f23e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -242,14 +242,13 @@
 {
 	struct ipv6_pinfo *np;
 	struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
-	struct net_device *dev = skb->dev;
 	struct in6_addr *saddr = &hdr->saddr;
 	struct in6_addr *daddr = &hdr->daddr;
 	struct udphdr *uh = (struct udphdr*)(skb->data+offset);
 	struct sock *sk;
 	int err;
 
-	sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex);
+	sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, inet6_iif(skb));
    
 	if (sk == NULL)
 		return;
@@ -348,7 +347,7 @@
 
 	read_lock(&udp_hash_lock);
 	sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
-	dif = skb->dev->ifindex;
+	dif = inet6_iif(skb);
 	sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
 	if (!sk) {
 		kfree_skb(skb);
@@ -429,7 +428,7 @@
 	 * check socket cache ... must talk to Alan about his plans
 	 * for sock caches... i'll skip this for now.
 	 */
-	sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex);
+	sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, inet6_iif(skb));
 
 	if (sk == NULL) {
 		if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 7af227b..7931e4f 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -135,7 +135,7 @@
 	x6spi = __xfrm6_tunnel_spi_lookup(saddr);
 	spi = x6spi ? x6spi->spi : 0;
 	read_unlock_bh(&xfrm6_tunnel_spi_lock);
-	return spi;
+	return htonl(spi);
 }
 
 EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
@@ -210,7 +210,7 @@
 		spi = __xfrm6_tunnel_alloc_spi(saddr);
 	write_unlock_bh(&xfrm6_tunnel_spi_lock);
 
-	return spi;
+	return htonl(spi);
 }
 
 EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index bef3f61..76c6615 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -83,13 +83,13 @@
 struct ipx_interface *ipx_primary_net;
 struct ipx_interface *ipx_internal_net;
 
-extern int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc,
+extern int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc,
 			    unsigned char *node);
 extern void ipxrtr_del_routes(struct ipx_interface *intrfc);
 extern int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
 			       struct iovec *iov, int len, int noblock);
 extern int ipxrtr_route_skb(struct sk_buff *skb);
-extern struct ipx_route *ipxrtr_lookup(__u32 net);
+extern struct ipx_route *ipxrtr_lookup(__be32 net);
 extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
 
 #undef IPX_REFCNT_DEBUG
@@ -177,7 +177,7 @@
 }
 
 static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev,
-						      unsigned short datalink)
+						      __be16 datalink)
 {
 	struct ipx_interface *i;
 
@@ -190,7 +190,7 @@
 }
 
 static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev,
-						    unsigned short datalink)
+						    __be16 datalink)
 {
 	struct ipx_interface *i;
 
@@ -202,7 +202,7 @@
 	return i;
 }
 
-struct ipx_interface *ipxitf_find_using_net(__u32 net)
+struct ipx_interface *ipxitf_find_using_net(__be32 net)
 {
 	struct ipx_interface *i;
 
@@ -237,7 +237,7 @@
 
 /* caller must hold intrfc->if_sklist_lock */
 static struct sock *__ipxitf_find_socket(struct ipx_interface *intrfc,
-					 unsigned short port)
+					 __be16 port)
 {
 	struct sock *s;
 	struct hlist_node *node;
@@ -252,7 +252,7 @@
 
 /* caller must hold a reference to intrfc */
 static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc,
-					unsigned short port)
+					__be16 port)
 {
 	struct sock *s;
 
@@ -268,7 +268,7 @@
 #ifdef CONFIG_IPX_INTERN
 static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc,
 						unsigned char *ipx_node,
-						unsigned short port)
+						__be16 port)
 {
 	struct sock *s;
 	struct hlist_node *node;
@@ -600,10 +600,10 @@
 
 	/* see if we need to include the netnum in the route list */
 	if (IPX_SKB_CB(skb)->last_hop.index >= 0) {
-		u32 *last_hop = (u32 *)(((u8 *) skb->data) +
+		__be32 *last_hop = (__be32 *)(((u8 *) skb->data) +
 				sizeof(struct ipxhdr) +
 				IPX_SKB_CB(skb)->last_hop.index *
-				sizeof(u32));
+				sizeof(__be32));
 		*last_hop = IPX_SKB_CB(skb)->last_hop.netnum;
 		IPX_SKB_CB(skb)->last_hop.index = -1;
 	}
@@ -772,7 +772,7 @@
 		} else {
 			printk(KERN_WARNING "IPX: Network number collision "
 				"%lx\n        %s %s and %s %s\n",
-				(unsigned long) htonl(cb->ipx_source_net),
+				(unsigned long) ntohl(cb->ipx_source_net),
 				ipx_device_name(i),
 				ipx_frame_name(i->if_dlink_type),
 				ipx_device_name(intrfc),
@@ -812,7 +812,7 @@
 	int i, rc = -EINVAL;
 	struct ipx_interface *ifcs;
 	char *c;
-	u32 *l;
+	__be32 *l;
 
 	/* Illegal packet - too many hops or too short */
 	/* We decide to throw it away: no broadcasting, no local processing.
@@ -833,7 +833,7 @@
 		goto out;
 	
 	c = ((u8 *) ipx) + sizeof(struct ipxhdr);
-	l = (u32 *) c;
+	l = (__be32 *) c;
 
 	/* Don't broadcast packet if already seen this net */
 	for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++)
@@ -855,7 +855,7 @@
 		/* That aren't in the list */
 		if (ifcs == intrfc)
 			continue;
-		l = (__u32 *) c;
+		l = (__be32 *) c;
 		/* don't consider the last entry in the packet list,
 		 * it is our netnum, and it is not there yet */
 		for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++)
@@ -885,8 +885,8 @@
 		ipx_primary_net = intrfc;
 }
 
-static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum,
-					  unsigned short dlink_type,
+static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __be32 netnum,
+					  __be16 dlink_type,
 					  struct datalink_proto *dlink,
 					  unsigned char internal,
 					  int ipx_offset)
@@ -960,7 +960,7 @@
 static int ipxitf_create(struct ipx_interface_definition *idef)
 {
 	struct net_device *dev;
-	unsigned short dlink_type = 0;
+	__be16 dlink_type = 0;
 	struct datalink_proto *datalink = NULL;
 	struct ipx_interface *intrfc;
 	int rc;
@@ -1073,7 +1073,7 @@
 static int ipxitf_delete(struct ipx_interface_definition *idef)
 {
 	struct net_device *dev = NULL;
-	unsigned short dlink_type = 0;
+	__be16 dlink_type = 0;
 	struct ipx_interface *intrfc;
 	int rc = 0;
 
@@ -1110,7 +1110,7 @@
 }
 
 static struct ipx_interface *ipxitf_auto_create(struct net_device *dev,
-						unsigned short dlink_type)
+						__be16 dlink_type)
 {
 	struct ipx_interface *intrfc = NULL;
 	struct datalink_proto *datalink;
@@ -1122,7 +1122,7 @@
 	if (dev->addr_len > IPX_NODE_LEN)
 		goto out;
 
-	switch (htons(dlink_type)) {
+	switch (ntohs(dlink_type)) {
 	case ETH_P_IPX:		datalink = pEII_datalink;	break;
 	case ETH_P_802_2:	datalink = p8022_datalink;	break;
 	case ETH_P_SNAP:	datalink = pSNAP_datalink;	break;
@@ -1234,27 +1234,27 @@
 /* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */
 /* This functions should *not* mess with packet contents */
 
-__u16 ipx_cksum(struct ipxhdr *packet, int length) 
+__be16 ipx_cksum(struct ipxhdr *packet, int length)
 {
 	/* 
 	 *	NOTE: sum is a net byte order quantity, which optimizes the 
 	 *	loop. This only works on big and little endian machines. (I
 	 *	don't know of a machine that isn't.)
 	 */
-	/* start at ipx_dest - We skip the checksum field and start with
-	 * ipx_type before the loop, not considering ipx_tctrl in the calc */
-	__u16 *p = (__u16 *)&packet->ipx_dest;
-	__u32 i = (length >> 1) - 1; /* Number of complete words */
-	__u32 sum = packet->ipx_type << sizeof(packet->ipx_tctrl); 
+	/* handle the first 3 words separately; checksum should be skipped
+	 * and ipx_tctrl masked out */
+	__u16 *p = (__u16 *)packet;
+	__u32 sum = p[1] + (p[2] & (__force u16)htons(0x00ff));
+	__u32 i = (length >> 1) - 3; /* Number of remaining complete words */
 
-	/* Loop through all complete words except the checksum field,
-	 * ipx_type (accounted above) and ipx_tctrl (not used in the cksum) */
-	while (--i)
+	/* Loop through them */
+	p += 3;
+	while (i--)
 		sum += *p++;
 
 	/* Add on the last part word if it exists */
 	if (packet->ipx_pktsize & htons(1))
-		sum += ntohs(0xff00) & *p;
+		sum += (__force u16)htons(0xff00) & *p;
 
 	/* Do final fixup */
 	sum = (sum & 0xffff) + (sum >> 16);
@@ -1263,10 +1263,17 @@
 	if (sum >= 0x10000)
 		sum++;
 
-	return ~sum;
+	/*
+	 * Leave 0 alone; we don't want 0xffff here.  Note that we can't get
+	 * here with 0x10000, so this check is the same as ((__u16)sum)
+	 */
+	if (sum)
+		sum = ~sum;
+
+	return (__force __be16)sum;
 }
 
-const char *ipx_frame_name(unsigned short frame)
+const char *ipx_frame_name(__be16 frame)
 {
 	char* rc = "None";
 
@@ -1401,7 +1408,7 @@
 
 /* caller must hold a reference to intrfc */
 
-static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc)
+static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc)
 {
 	unsigned short socketNum = intrfc->if_sknum;
 
@@ -1410,7 +1417,7 @@
 	if (socketNum < IPX_MIN_EPHEMERAL_SOCKET)
 		socketNum = IPX_MIN_EPHEMERAL_SOCKET;
 
-	while (__ipxitf_find_socket(intrfc, ntohs(socketNum)))
+	while (__ipxitf_find_socket(intrfc, htons(socketNum)))
 		if (socketNum > IPX_MAX_EPHEMERAL_SOCKET)
 			socketNum = IPX_MIN_EPHEMERAL_SOCKET;
 		else
@@ -1419,7 +1426,7 @@
 	spin_unlock_bh(&intrfc->if_sklist_lock);
 	intrfc->if_sknum = socketNum;
 
-	return ntohs(socketNum);
+	return htons(socketNum);
 }
 
 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
@@ -1473,7 +1480,7 @@
 						ipxs->port)) {
 			SOCK_DEBUG(sk,
 				"IPX: bind failed because port %X in use.\n",
-				ntohs((int)addr->sipx_port));
+				ntohs(addr->sipx_port));
 			goto out_put;
 		}
 	} else {
@@ -1488,7 +1495,7 @@
 		if (ipxitf_find_socket(intrfc, addr->sipx_port)) {
 			SOCK_DEBUG(sk,
 				"IPX: bind failed because port %X in use.\n",
-				ntohs((int)addr->sipx_port));
+				ntohs(addr->sipx_port));
 			goto out_put;
 		}
 	}
@@ -1665,7 +1672,7 @@
 	intrfc = ipxitf_find_using_phys(dev, pt->type);
 	if (!intrfc) {
 		if (ipxcfg_auto_create_interfaces &&
-		   ntohl(IPX_SKB_CB(skb)->ipx_dest_net)) {
+		   IPX_SKB_CB(skb)->ipx_dest_net) {
 			intrfc = ipxitf_auto_create(dev, pt->type);
 			if (intrfc)
 				ipxitf_hold(intrfc);
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
index 4c0c712..b7463df 100644
--- a/net/ipx/ipx_proc.c
+++ b/net/ipx/ipx_proc.c
@@ -260,22 +260,22 @@
 	ipxs = ipx_sk(s);
 #ifdef CONFIG_IPX_INTERN
 	seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ",
-		   (unsigned long)htonl(ipxs->intrfc->if_netnum),
+		   (unsigned long)ntohl(ipxs->intrfc->if_netnum),
 		   ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3],
-		   ipxs->node[4], ipxs->node[5], htons(ipxs->port));
+		   ipxs->node[4], ipxs->node[5], ntohs(ipxs->port));
 #else
-	seq_printf(seq, "%08lX:%04X  ", (unsigned long) htonl(ipxs->intrfc->if_netnum),
-		   htons(ipxs->port));
+	seq_printf(seq, "%08lX:%04X  ", (unsigned long) ntohl(ipxs->intrfc->if_netnum),
+		   ntohs(ipxs->port));
 #endif	/* CONFIG_IPX_INTERN */
 	if (s->sk_state != TCP_ESTABLISHED)
 		seq_printf(seq, "%-28s", "Not_Connected");
 	else {
 		seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ",
-			   (unsigned long)htonl(ipxs->dest_addr.net),
+			   (unsigned long)ntohl(ipxs->dest_addr.net),
 			   ipxs->dest_addr.node[0], ipxs->dest_addr.node[1],
 			   ipxs->dest_addr.node[2], ipxs->dest_addr.node[3],
 			   ipxs->dest_addr.node[4], ipxs->dest_addr.node[5],
-			   htons(ipxs->dest_addr.sock));
+			   ntohs(ipxs->dest_addr.sock));
 	}
 
 	seq_printf(seq, "%08X  %08X  %02X     %03d\n",
diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c
index a30dbb1..68560ee 100644
--- a/net/ipx/ipx_route.c
+++ b/net/ipx/ipx_route.c
@@ -19,17 +19,17 @@
 
 extern struct ipx_interface *ipx_internal_net;
 
-extern __u16 ipx_cksum(struct ipxhdr *packet, int length);
-extern struct ipx_interface *ipxitf_find_using_net(__u32 net);
+extern __be16 ipx_cksum(struct ipxhdr *packet, int length);
+extern struct ipx_interface *ipxitf_find_using_net(__be32 net);
 extern int ipxitf_demux_socket(struct ipx_interface *intrfc,
 			       struct sk_buff *skb, int copy);
 extern int ipxitf_demux_socket(struct ipx_interface *intrfc,
 			       struct sk_buff *skb, int copy);
 extern int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb,
 		       char *node);
-extern struct ipx_interface *ipxitf_find_using_net(__u32 net);
+extern struct ipx_interface *ipxitf_find_using_net(__be32 net);
 
-struct ipx_route *ipxrtr_lookup(__u32 net)
+struct ipx_route *ipxrtr_lookup(__be32 net)
 {
 	struct ipx_route *r;
 
@@ -48,7 +48,7 @@
 /*
  * Caller must hold a reference to intrfc
  */
-int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc,
+int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc,
 		     unsigned char *node)
 {
 	struct ipx_route *rt;
@@ -118,7 +118,7 @@
 	return rc;
 }
 
-static int ipxrtr_delete(__u32 net)
+static int ipxrtr_delete(__be32 net)
 {
 	struct ipx_route *r, *tmp;
 	int rc;
@@ -238,7 +238,7 @@
 
 	/* Apply checksum. Not allowed on 802.3 links. */
 	if (sk->sk_no_check || intrfc->if_dlink_type == htons(IPX_FRAME_8023))
-		ipx->ipx_checksum = 0xFFFF;
+		ipx->ipx_checksum = htons(0xFFFF);
 	else
 		ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr));
 
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index 5073261..fede837 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -1678,7 +1678,8 @@
 	 *  every IrLAP connection and check every LSAP associated with each
 	 *  the connection.
 	 */
-	spin_lock_irqsave(&irlmp->links->hb_spinlock, flags);
+	spin_lock_irqsave_nested(&irlmp->links->hb_spinlock, flags,
+			SINGLE_DEPTH_NESTING);
 	lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
 	while (lap != NULL) {
 		IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 093b3dd..de0567b 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -469,10 +469,8 @@
 	struct nf_conntrack_expect *i;
 	
 	list_for_each_entry(i, &nf_conntrack_expect_list, list) {
-		if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) {
-			atomic_inc(&i->use);
+		if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
 			return i;
-		}
 	}
 	return NULL;
 }
@@ -485,6 +483,8 @@
 	
 	read_lock_bh(&nf_conntrack_lock);
 	i = __nf_conntrack_expect_find(tuple);
+	if (i)
+		atomic_inc(&i->use);
 	read_unlock_bh(&nf_conntrack_lock);
 
 	return i;
@@ -893,12 +893,6 @@
 
 	memset(conntrack, 0, nf_ct_cache[features].size);
 	conntrack->features = features;
-	if (helper) {
-		struct nf_conn_help *help = nfct_help(conntrack);
-		NF_CT_ASSERT(help);
-		help->helper = helper;
-	}
-
 	atomic_set(&conntrack->ct_general.use, 1);
 	conntrack->ct_general.destroy = destroy_conntrack;
 	conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
@@ -982,8 +976,13 @@
 #endif
 		nf_conntrack_get(&conntrack->master->ct_general);
 		NF_CT_STAT_INC(expect_new);
-	} else
+	} else {
+		struct nf_conn_help *help = nfct_help(conntrack);
+
+		if (help)
+			help->helper = __nf_ct_helper_find(&repl_tuple);
 		NF_CT_STAT_INC(new);
+	}
 
 	/* Overload tuple linked list to put us in unconfirmed list. */
 	list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
@@ -1520,9 +1519,10 @@
 		if (iter(ct, data))
 			goto found;
 	}
+	write_unlock_bh(&nf_conntrack_lock);
 	return NULL;
 found:
-	atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
+	atomic_inc(&ct->ct_general.use);
 	write_unlock_bh(&nf_conntrack_lock);
 	return ct;
 }
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index bd0156a..ab67c2b 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -161,6 +161,7 @@
 	return ret;
 
 nfattr_failure:
+	nf_ct_proto_put(proto);
 	return -1;
 }
 
@@ -949,6 +950,7 @@
 {
 	struct nf_conn *ct;
 	int err = -EINVAL;
+	struct nf_conn_help *help;
 
 	ct = nf_conntrack_alloc(otuple, rtuple);
 	if (ct == NULL || IS_ERR(ct))
@@ -976,9 +978,16 @@
 		ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
 #endif
 
+	help = nfct_help(ct);
+	if (help)
+		help->helper = nf_ct_helper_find_get(rtuple);
+
 	add_timer(&ct->timeout);
 	nf_conntrack_hash_insert(ct);
 
+	if (help && help->helper)
+		nf_ct_helper_put(help->helper);
+
 	return 0;
 
 err:	
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index b59d3b2..1e5207b 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -427,7 +427,7 @@
 	nfmsg->version = NFNETLINK_V0;
 	nfmsg->res_id = htons(inst->group_num);
 
-	pmsg.hw_protocol	= htons(skb->protocol);
+	pmsg.hw_protocol	= skb->protocol;
 	pmsg.hook		= hooknum;
 
 	NFA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg);
@@ -544,7 +544,7 @@
 	}
 	/* global sequence number */
 	if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) {
-		tmp_uint = atomic_inc_return(&global_seq);
+		tmp_uint = htonl(atomic_inc_return(&global_seq));
 		NFA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint);
 	}
 
@@ -878,7 +878,7 @@
 		params = NFA_DATA(nfula[NFULA_CFG_MODE-1]);
 
 		nfulnl_set_mode(inst, params->copy_mode,
-				ntohs(params->copy_range));
+				ntohl(params->copy_range));
 	}
 
 	if (nfula[NFULA_CFG_TIMEOUT-1]) {
@@ -896,8 +896,8 @@
 	}
 
 	if (nfula[NFULA_CFG_QTHRESH-1]) {
-		u_int32_t qthresh = 
-			*(u_int16_t *)NFA_DATA(nfula[NFULA_CFG_QTHRESH-1]);
+		__be32 qthresh =
+			*(__be32 *)NFA_DATA(nfula[NFULA_CFG_QTHRESH-1]);
 
 		nfulnl_set_qthresh(inst, ntohl(qthresh));
 	}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 8eb2473..e815a9a 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -414,7 +414,7 @@
 	nfmsg->res_id = htons(queue->queue_num);
 
 	pmsg.packet_id 		= htonl(entry->id);
-	pmsg.hw_protocol	= htons(entskb->protocol);
+	pmsg.hw_protocol	= entskb->protocol;
 	pmsg.hook		= entinf->hook;
 
 	NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg);
@@ -622,9 +622,10 @@
 	int diff;
 
 	diff = data_len - e->skb->len;
-	if (diff < 0)
-		skb_trim(e->skb, data_len);
-	else if (diff > 0) {
+	if (diff < 0) {
+		if (pskb_trim(e->skb, data_len))
+			return -ENOMEM;
+	} else if (diff > 0) {
 		if (data_len > 0xFFFF)
 			return -EINVAL;
 		if (diff > skb_tailroom(e->skb)) {
diff --git a/net/netlabel/Kconfig b/net/netlabel/Kconfig
index 9f7121a..56958c8 100644
--- a/net/netlabel/Kconfig
+++ b/net/netlabel/Kconfig
@@ -4,7 +4,7 @@
 
 config NETLABEL
 	bool "NetLabel subsystem support"
-	depends on NET && SECURITY
+	depends on SECURITY
 	default n
 	---help---
 	  NetLabel provides support for explicit network packet labeling
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index d56e0d2..d527c89 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1075,8 +1075,9 @@
 			return -EINVAL;
 		len = sizeof(int);
 		val = nlk->flags & NETLINK_RECV_PKTINFO ? 1 : 0;
-		put_user(len, optlen);
-		put_user(val, optval);
+		if (put_user(len, optlen) ||
+		    put_user(val, optval))
+			return -EFAULT;
 		err = 0;
 		break;
 	default:
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 9b9c555..4b52fa7 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1284,8 +1284,7 @@
 						  struct htb_class, sibling));
 
 	/* note: this delete may happen twice (see htb_delete) */
-	if (!hlist_unhashed(&cl->hlist))
-		hlist_del(&cl->hlist);
+	hlist_del_init(&cl->hlist);
 	list_del(&cl->sibling);
 
 	if (cl->prio_activity)
@@ -1333,8 +1332,7 @@
 	sch_tree_lock(sch);
 
 	/* delete from hash and active; remainder in destroy_class */
-	if (!hlist_unhashed(&cl->hlist))
-		hlist_del(&cl->hlist);
+	hlist_del_init(&cl->hlist);
 
 	if (cl->prio_activity)
 		htb_deactivate(q, cl);
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 45939ba..0441876 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -4,7 +4,7 @@
  * 		This program is free software; you can redistribute it and/or
  * 		modify it under the terms of the GNU General Public License
  * 		as published by the Free Software Foundation; either version
- * 		2 of the License, or (at your option) any later version.
+ * 		2 of the License.
  *
  *  		Many of the algorithms and ideas for this came from
  *		NIST Net which is not copyrighted. 
@@ -170,6 +170,8 @@
 		return NET_XMIT_BYPASS;
 	}
 
+	skb_orphan(skb);
+
 	/*
 	 * If we need to duplicate packet, then re-insert at top of the
 	 * qdisc tree, since parent queuer expects that only one
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 27329ce..ed0445f 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -346,11 +346,18 @@
 	struct list_head *pos, *temp;
 	int i;
 
-	list_del(&asoc->asocs);
+	/* Only real associations count against the endpoint, so
+	 * don't bother for if this is a temporary association.
+	 */
+	if (!asoc->temp) {
+		list_del(&asoc->asocs);
 
-	/* Decrement the backlog value for a TCP-style listening socket. */
-	if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
-		sk->sk_ack_backlog--;
+		/* Decrement the backlog value for a TCP-style listening
+		 * socket.
+		 */
+		if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
+			sk->sk_ack_backlog--;
+	}
 
 	/* Mark as dead, so other users can know this structure is
 	 * going away.
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 35c49ff..9b6b394 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -144,6 +144,13 @@
 {
 	struct sock *sk = ep->base.sk;
 
+	/* If this is a temporary association, don't bother
+	 * since we'll be removing it shortly and don't
+	 * want anyone to find it anyway.
+	 */
+	if (asoc->temp)
+		return;
+
 	/* Now just add it to our list of asocs */
 	list_add_tail(&asoc->asocs, &ep->asocs);
 
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 64f6301..6d82f40 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -135,6 +135,9 @@
 
 	SCTP_INC_STATS_BH(SCTP_MIB_INSCTPPACKS);
 
+	if (skb_linearize(skb))
+		goto discard_it;
+
 	sh = (struct sctphdr *) skb->h.raw;
 
 	/* Pull up the IP and SCTP headers. */
@@ -768,6 +771,9 @@
 /* Add an association to the hash. Local BH-safe. */
 void sctp_hash_established(struct sctp_association *asoc)
 {
+	if (asoc->temp)
+		return;
+
 	sctp_local_bh_disable();
 	__sctp_hash_established(asoc);
 	sctp_local_bh_enable();
@@ -801,6 +807,9 @@
 /* Remove association from the hash table.  Local BH-safe. */
 void sctp_unhash_established(struct sctp_association *asoc)
 {
+	if (asoc->temp)
+		return;
+
 	sctp_local_bh_disable();
 	__sctp_unhash_established(asoc);
 	sctp_local_bh_enable();
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index fac7674..5b4f82f 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -591,7 +591,7 @@
 	newinet->dport = htons(asoc->peer.port);
 	newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
 	newinet->pmtudisc = inet->pmtudisc;
-      	newinet->id = 0;
+      	newinet->id = asoc->next_tsn ^ jiffies;
 
 	newinet->uc_ttl = -1;
 	newinet->mc_loop = 1;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9f34dec..935bc91 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3372,6 +3372,7 @@
 {
 	struct sock *sk = asoc->base.sk;
 	struct socket *sock;
+	struct inet_sock *inetsk;
 	int err = 0;
 
 	/* An association cannot be branched off from an already peeled-off
@@ -3389,6 +3390,14 @@
 	 * asoc to the newsk.
 	 */
 	sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
+
+	/* Make peeled-off sockets more like 1-1 accepted sockets.
+	 * Set the daddr and initialize id to something more random
+	 */
+	inetsk = inet_sk(sock->sk);
+	inetsk->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
+	inetsk->id = asoc->next_tsn ^ jiffies;
+
 	*sockp = sock;
 
 	return err;
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 8f2320a..ee9bb15 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -126,6 +126,7 @@
 	if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) {
 		hlist_del(&dom->hash);
 		dom->flavour->domain_release(dom);
+		spin_unlock(&auth_domain_lock);
 	}
 }
 
@@ -147,10 +148,8 @@
 			return hp;
 		}
 	}
-	if (new) {
+	if (new)
 		hlist_add_head(&new->hash, head);
-		kref_get(&new->ref);
-	}
 	spin_unlock(&auth_domain_lock);
 	return new;
 }
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 96521f1..64ca1f6 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -299,9 +299,15 @@
 static inline void
 svc_sock_put(struct svc_sock *svsk)
 {
-	if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) {
+	if (atomic_dec_and_test(&svsk->sk_inuse) &&
+			test_bit(SK_DEAD, &svsk->sk_flags)) {
 		dprintk("svc: releasing dead socket\n");
-		sock_release(svsk->sk_sock);
+		if (svsk->sk_sock->file)
+			sockfd_put(svsk->sk_sock);
+		else
+			sock_release(svsk->sk_sock);
+		if (svsk->sk_info_authunix != NULL)
+			svcauth_unix_info_release(svsk->sk_info_authunix);
 		kfree(svsk);
 	}
 }
@@ -1604,20 +1610,13 @@
 		if (test_bit(SK_TEMP, &svsk->sk_flags))
 			serv->sv_tmpcnt--;
 
-	if (!atomic_read(&svsk->sk_inuse)) {
-		spin_unlock_bh(&serv->sv_lock);
-		if (svsk->sk_sock->file)
-			sockfd_put(svsk->sk_sock);
-		else
-			sock_release(svsk->sk_sock);
-		if (svsk->sk_info_authunix != NULL)
-			svcauth_unix_info_release(svsk->sk_info_authunix);
-		kfree(svsk);
-	} else {
-		spin_unlock_bh(&serv->sv_lock);
-		dprintk(KERN_NOTICE "svc: server socket destroy delayed\n");
-		/* svsk->sk_server = NULL; */
-	}
+	/* This atomic_inc should be needed - svc_delete_socket
+	 * should have the semantic of dropping a reference.
+	 * But it doesn't yet....
+	 */
+	atomic_inc(&svsk->sk_inuse);
+	spin_unlock_bh(&serv->sv_lock);
+	svc_sock_put(svsk);
 }
 
 /*
diff --git a/net/tipc/port.c b/net/tipc/port.c
index c1a1a767..b7f3199 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -1136,11 +1136,12 @@
 	int res = -EINVAL;
 
 	p_ptr = tipc_port_lock(ref);
+	if (!p_ptr)
+		return -EINVAL;
+
 	dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, "
 	    "lower = %u, upper = %u\n",
 	    ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper);
-	if (!p_ptr)
-		return -EINVAL;
 	if (p_ptr->publ.connected)
 		goto exit;
 	if (seq->lower > seq->upper)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 84bbf84..899de9e 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -505,6 +505,14 @@
 						  x->id.proto, family);
 }
 
+static void xfrm_hash_grow_check(int have_hash_collision)
+{
+	if (have_hash_collision &&
+	    (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
+	    xfrm_state_num > xfrm_state_hmask)
+		schedule_work(&xfrm_hash_work);
+}
+
 struct xfrm_state *
 xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 
 		struct flowi *fl, struct xfrm_tmpl *tmpl,
@@ -598,6 +606,8 @@
 			x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
 			x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
 			add_timer(&x->timer);
+			xfrm_state_num++;
+			xfrm_hash_grow_check(x->bydst.next != NULL);
 		} else {
 			x->km.state = XFRM_STATE_DEAD;
 			xfrm_state_put(x);
@@ -614,14 +624,6 @@
 	return x;
 }
 
-static void xfrm_hash_grow_check(int have_hash_collision)
-{
-	if (have_hash_collision &&
-	    (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
-	    xfrm_state_num > xfrm_state_hmask)
-		schedule_work(&xfrm_hash_work);
-}
-
 static void __xfrm_state_insert(struct xfrm_state *x)
 {
 	unsigned int h;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2b2e59d..2ee14f8 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -323,7 +323,7 @@
 	x->props.replay_window = p->replay_window;
 	x->props.reqid = p->reqid;
 	x->props.family = p->family;
-	x->props.saddr = p->saddr;
+	memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr));
 	x->props.flags = p->flags;
 }
 
@@ -495,6 +495,7 @@
 			goto out;
 		}
 
+		err = -ESRCH;
 		x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto,
 					     p->family);
 	}
@@ -545,7 +546,7 @@
 	memcpy(&p->lft, &x->lft, sizeof(p->lft));
 	memcpy(&p->curlft, &x->curlft, sizeof(p->curlft));
 	memcpy(&p->stats, &x->stats, sizeof(p->stats));
-	p->saddr = x->props.saddr;
+	memcpy(&p->saddr, &x->props.saddr, sizeof(p->saddr));
 	p->mode = x->props.mode;
 	p->replay_window = x->props.replay_window;
 	p->reqid = x->props.reqid;
@@ -1927,6 +1928,9 @@
 	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
 	len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
+#ifdef CONFIG_XFRM_SUB_POLICY
+	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
+#endif
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
@@ -2034,6 +2038,9 @@
 	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
 	len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
+#ifdef CONFIG_XFRM_SUB_POLICY
+	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
+#endif
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
@@ -2060,6 +2067,9 @@
 		len += RTA_SPACE(headlen);
 		headlen = sizeof(*id);
 	}
+#ifdef CONFIG_XFRM_SUB_POLICY
+	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
+#endif
 	len += NLMSG_SPACE(headlen);
 
 	skb = alloc_skb(len, GFP_ATOMIC);
@@ -2106,10 +2116,12 @@
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
 	unsigned char *b;
+	int len = 0;
 #ifdef CONFIG_XFRM_SUB_POLICY
 	struct xfrm_userpolicy_type upt;
+	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
 #endif
-	int len = NLMSG_LENGTH(0);
+	len += NLMSG_LENGTH(0);
 
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index 4ab6cbf..d6071cb 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -250,7 +250,7 @@
 void extfunc(char * filename) { docfunctions(filename, FUNCTION);   }
 
 /*
- * Document spåecific function(s) in a file.
+ * Document specific function(s) in a file.
  * Call kernel-doc with the following parameters:
  * kernel-doc -docbook -function function1 [-function function2]
  */
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
index 331c079..4c723fd 100644
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -158,7 +158,7 @@
 }
 
 list_header() {
-	echo "deps_initramfs := \\"
+	:
 }
 
 header() {
@@ -227,6 +227,7 @@
 case "$arg" in
 	"-l")	# files included in initramfs - used by kbuild
 		dep_list="list_"
+		echo "deps_initramfs := \\"
 		shift
 		;;
 	"-o")	# generate gzipped cpio image named $1
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index e8ad1f6..b49584c 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -6,6 +6,8 @@
 *.tab.c
 *.tab.h
 zconf.hash.c
+*.moc
+lkc_defs.h
 
 #
 # configuration programs
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index ebc781b..d54440f 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -221,16 +221,14 @@
  */
 static void color_setup(const char *theme)
 {
-	if (set_theme(theme)) {
-		if (has_colors()) {	/* Terminal supports color? */
-			start_color();
-			init_dialog_colors();
-		}
-	}
-	else
-	{
+	int use_color;
+
+	use_color = set_theme(theme);
+	if (use_color && has_colors()) {
+		start_color();
+		init_dialog_colors();
+	} else
 		set_mono_theme();
-	}
 }
 
 /*
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 393f374..338bdea 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -1259,6 +1259,7 @@
  * Construct the complete config widget
  */
 ConfigMainWindow::ConfigMainWindow(void)
+	: searchWindow(0)
 {
 	QMenuBar* menu;
 	bool ok;
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 4127796..2e11416 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -921,6 +921,8 @@
 		".fixup",
 		".smp_locks",
 		".plt",  /* seen on ARCH=um build on x86_64. Harmless */
+		"__ftr_fixup",		/* powerpc cpu feature fixup */
+		"__fw_ftr_fixup",	/* powerpc firmware feature fixup */
 		NULL
 	};
 	/* Start of section names */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index e9969a2..28ee187 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1754,7 +1754,8 @@
 						get_file(devnull);
 					} else {
 						devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
-						if (!devnull) {
+						if (IS_ERR(devnull)) {
+							devnull = NULL;
 							put_unused_fd(fd);
 							fput(file);
 							continue;
@@ -3313,7 +3314,13 @@
 
 static int selinux_socket_setsockopt(struct socket *sock,int level,int optname)
 {
-	return socket_has_perm(current, sock, SOCKET__SETOPT);
+	int err;
+
+	err = socket_has_perm(current, sock, SOCKET__SETOPT);
+	if (err)
+		return err;
+
+	return selinux_netlbl_socket_setsockopt(sock, level, optname);
 }
 
 static int selinux_socket_getsockopt(struct socket *sock, int level,
diff --git a/security/selinux/include/selinux_netlabel.h b/security/selinux/include/selinux_netlabel.h
index ecab4bd..9de10cc2 100644
--- a/security/selinux/include/selinux_netlabel.h
+++ b/security/selinux/include/selinux_netlabel.h
@@ -53,6 +53,9 @@
 void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
 				      struct sk_security_struct *newssec);
 int selinux_netlbl_inode_permission(struct inode *inode, int mask);
+int selinux_netlbl_socket_setsockopt(struct socket *sock,
+				     int level,
+				     int optname);
 #else
 static inline void selinux_netlbl_cache_invalidate(void)
 {
@@ -114,6 +117,13 @@
 {
 	return 0;
 }
+
+static inline int selinux_netlbl_socket_setsockopt(struct socket *sock,
+						   int level,
+						   int optname)
+{
+	return 0;
+}
 #endif /* CONFIG_NETLABEL */
 
 #endif
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b1f6fb3..bfe1227 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2682,4 +2682,41 @@
 
 	return peer_sid;
 }
+
+/**
+ * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel
+ * @sock: the socket
+ * @level: the socket level or protocol
+ * @optname: the socket option name
+ *
+ * Description:
+ * Check the setsockopt() call and if the user is trying to replace the IP
+ * options on a socket and a NetLabel is in place for the socket deny the
+ * access; otherwise allow the access.  Returns zero when the access is
+ * allowed, -EACCES when denied, and other negative values on error.
+ *
+ */
+int selinux_netlbl_socket_setsockopt(struct socket *sock,
+				     int level,
+				     int optname)
+{
+	int rc = 0;
+	struct inode *inode = SOCK_INODE(sock);
+	struct sk_security_struct *sksec = sock->sk->sk_security;
+	struct inode_security_struct *isec = inode->i_security;
+	struct netlbl_lsm_secattr secattr;
+
+	mutex_lock(&isec->lock);
+	if (level == IPPROTO_IP && optname == IP_OPTIONS &&
+	    sksec->nlbl_state == NLBL_LABELED) {
+		netlbl_secattr_init(&secattr);
+		rc = netlbl_socket_getattr(sock, &secattr);
+		if (rc == 0 && (secattr.cache || secattr.mls_lvl_vld))
+			rc = -EACCES;
+		netlbl_secattr_destroy(&secattr);
+	}
+	mutex_unlock(&isec->lock);
+
+	return rc;
+}
 #endif /* CONFIG_NETLABEL */
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
index 2ef55a1..9de8485b 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -514,9 +514,15 @@
 	mutex_lock(&tas->mtx);
 	oldacr = tas->acr;
 
-	tas->acr &= ~TAS_ACR_INPUT_B;
+	/*
+	 * Despite what the data sheet says in one place, the
+	 * TAS_ACR_B_MONAUREAL bit forces mono output even when
+	 * input A (line in) is selected.
+	 */
+	tas->acr &= ~(TAS_ACR_INPUT_B | TAS_ACR_B_MONAUREAL);
 	if (ucontrol->value.enumerated.item[0])
-		tas->acr |= TAS_ACR_INPUT_B;
+		tas->acr |= TAS_ACR_INPUT_B | TAS_ACR_B_MONAUREAL |
+		      TAS_ACR_B_MON_SEL_RIGHT;
 	if (oldacr == tas->acr) {
 		mutex_unlock(&tas->mtx);
 		return 0;
@@ -686,8 +692,7 @@
 	if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp))
 		goto outerr;
 
-	tas->acr |= TAS_ACR_ANALOG_PDOWN | TAS_ACR_B_MONAUREAL |
-		TAS_ACR_B_MON_SEL_RIGHT;
+	tas->acr |= TAS_ACR_ANALOG_PDOWN;
 	if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
 		goto outerr;
 
diff --git a/sound/core/control.c b/sound/core/control.c
index 6973a96..48ef0a0 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1018,10 +1018,6 @@
 	}
 	switch (info->type) {
 	case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
-		private_size = sizeof(char);
-		if (info->count > 128)
-			return -EINVAL;
-		break;
 	case SNDRV_CTL_ELEM_TYPE_INTEGER:
 		private_size = sizeof(long);
 		if (info->count > 128)
diff --git a/sound/core/info.c b/sound/core/info.c
index e43662b..0b4aab3 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -120,7 +120,10 @@
 	len = buffer->len - buffer->size;
 	va_start(args, fmt);
 	for (;;) {
-		res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args);
+		va_list ap;
+		va_copy(ap, args);
+		res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, ap);
+		va_end(ap);
 		if (res < len)
 			break;
 		err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 505b23e..e0821eb 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2359,7 +2359,8 @@
 		substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
 	snd_assert(substream != NULL, return -ENXIO);
 	pcm = substream->pcm;
-	snd_pcm_oss_sync(pcm_oss_file);
+	if (!pcm->card->shutdown)
+		snd_pcm_oss_sync(pcm_oss_file);
 	mutex_lock(&pcm->open_mutex);
 	snd_pcm_oss_release_file(pcm_oss_file);
 	mutex_unlock(&pcm->open_mutex);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 37b4b10..66e24b5 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1310,7 +1310,8 @@
 			       int f_flags)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+	if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
+	    runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
 		return -EBADFD;
 	if (snd_pcm_running(substream))
 		return -EBUSY;
@@ -1568,7 +1569,8 @@
 	runtime = substream->runtime;
 	card = substream->pcm->card;
 
-	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+	if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
+	    runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
 		return -EBADFD;
 
 	snd_power_lock(card);
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index 412dd62..9f7b32e 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -22,13 +22,10 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
-#include <linux/time.h>
-#include <linux/threads.h>
 #include <linux/interrupt.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/timer.h>
-#include <sound/info.h>
 
 #if defined(CONFIG_RTC) || defined(CONFIG_RTC_MODULE)
 
@@ -50,7 +47,9 @@
  * The hardware dependent description for this timer.
  */
 static struct snd_timer_hardware rtc_hw = {
-	.flags =	SNDRV_TIMER_HW_FIRST|SNDRV_TIMER_HW_AUTO,
+	.flags =	SNDRV_TIMER_HW_AUTO |
+			SNDRV_TIMER_HW_FIRST |
+			SNDRV_TIMER_HW_TASKLET,
 	.ticks =	100000000L,		/* FIXME: XXX */
 	.open =		rtctimer_open,
 	.close =	rtctimer_close,
@@ -60,6 +59,7 @@
 
 static int rtctimer_freq = RTC_FREQ;		/* frequency */
 static struct snd_timer *rtctimer;
+static struct tasklet_struct rtc_tasklet;
 static rtc_task_t rtc_task;
 
 
@@ -81,6 +81,7 @@
 	rtc_task_t *rtc = t->private_data;
 	if (rtc) {
 		rtc_unregister(rtc);
+		tasklet_kill(&rtc_tasklet);
 		t->private_data = NULL;
 	}
 	return 0;
@@ -105,12 +106,17 @@
 	return 0;
 }
 
+static void rtctimer_tasklet(unsigned long data)
+{
+	snd_timer_interrupt((struct snd_timer *)data, 1);
+}
+
 /*
  * interrupt
  */
 static void rtctimer_interrupt(void *private_data)
 {
-	snd_timer_interrupt(private_data, 1);
+	tasklet_hi_schedule(private_data);
 }
 
 
@@ -139,9 +145,11 @@
 	timer->hw = rtc_hw;
 	timer->hw.resolution = NANO_SEC / rtctimer_freq;
 
+	tasklet_init(&rtc_tasklet, rtctimer_tasklet, (unsigned long)timer);
+
 	/* set up RTC callback */
 	rtc_task.func = rtctimer_interrupt;
-	rtc_task.private_data = timer;
+	rtc_task.private_data = &rtc_tasklet;
 
 	err = snd_timer_global_register(timer);
 	if (err < 0) {
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 557c4de..57371f1 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -13,6 +13,7 @@
 
 config SND_ADLIB
 	tristate "AdLib FM card"
+	depends on SND
 	select SND_OPL3_LIB
 	help
 	  Say Y here to include support for AdLib FM cards.
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index b33a5fb..5903450 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -120,6 +120,8 @@
 	struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
 	int err;
 
+	if (!cfg)
+		return -ENOMEM;
 	acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
 	if (acard->dev == NULL) {
 		kfree(cfg);
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 3c1e9fd..d1f6dfc 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -289,6 +289,8 @@
 	struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
 	int err;
 
+	if (!cfg)
+		return -ENOMEM;
 	acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL);
 	if (acard->cap == NULL) {
 		kfree(cfg);
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index f12cd09..4ec2d79 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -564,6 +564,8 @@
 	struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
 	int err;
 
+	if (!cfg)
+		return -ENOMEM;
 	iwcard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
 	if (iwcard->dev == NULL) {
 		kfree(cfg);
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index a1ad39a..df22737 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -1683,6 +1683,8 @@
 	struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
 	int err;
 
+	if (!cfg)
+		return -ENOMEM;
 	chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
 	if (chip->dev == NULL) {
 		kfree(cfg);
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index 3b3b4da..51f5541 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -26,7 +26,7 @@
 #include <asm/cpu/dac.h>
 #include <asm/cpu/timer.h>
 #include <asm/machvec.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 #include <asm/hd64461.h>
 
 #define MODNAME "sh_dac_audio"
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index a79e918..6577b23 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -570,8 +570,7 @@
 			ac97->power_up &= ~(1 << (reg>>1));
 		else
 			ac97->power_up |= 1 << (reg>>1);
-		if (power_save)
-			update_power_regs(ac97);
+		update_power_regs(ac97);
 	}
 #endif
 	return err;
@@ -2337,10 +2336,7 @@
 		}
 	}
 
-	if (! power_save)
-		return 0;
-
-	if (! powerup && ac97->power_workq)
+	if (power_save && !powerup && ac97->power_workq)
 		/* adjust power-down bits after two seconds delay
 		 * (for avoiding loud click noises for many (OSS) apps
 		 *  that open/close frequently)
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 13a8cef..a7edd56 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -2032,8 +2032,10 @@
 	outl(0xffffffff, ALI_REG(chip, ALI_STOP));
 
 	spin_unlock_irq(&chip->reg_lock);
+
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -2048,8 +2050,15 @@
 	if (! im)
 		return 0;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "ali5451: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
+	pci_set_master(pci);
 
 	spin_lock_irq(&chip->reg_lock);
 	
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 9b16c29..95f70f3 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -768,9 +768,9 @@
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
 
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -779,9 +779,14 @@
 	struct snd_card *card = pci_get_drvdata(pci);
 	struct snd_als300 *chip = card->private_data;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "als300: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	snd_als300_init(chip);
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 15fc392..8fb55d3 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -804,9 +804,9 @@
 	snd_pcm_suspend_all(chip->pcm);
 	snd_sbmixer_suspend(chip);
 
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -816,9 +816,14 @@
 	struct snd_card_als4000 *acard = card->private_data;
 	struct snd_sb *chip = acard->chip;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "als4000: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	snd_als4000_configure(chip);
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 3e8fc5a..e3e99f3 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1442,9 +1442,9 @@
 	snd_atiixp_aclink_down(chip);
 	snd_atiixp_chip_stop(chip);
 
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1454,9 +1454,14 @@
 	struct atiixp *chip = card->private_data;
 	int i;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "atiixp: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	snd_atiixp_aclink_reset(chip);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index c5dda1b..dc54f2c 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1128,9 +1128,9 @@
 	snd_atiixp_aclink_down(chip);
 	snd_atiixp_chip_stop(chip);
 
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1140,9 +1140,14 @@
 	struct atiixp_modem *chip = card->private_data;
 	int i;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "atiixp-modem: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	snd_atiixp_aclink_reset(chip);
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 692f203..2414ee6 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1903,9 +1903,9 @@
 	for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
 		chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2);
 
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1916,9 +1916,14 @@
 	struct snd_azf3328 *chip = card->private_data;
 	int reg;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "azt3328: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 1f7e710..0093cd1 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3122,9 +3122,9 @@
 	/* disable ints */
 	snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);
 
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -3134,9 +3134,14 @@
 	struct cmipci *cm = card->private_data;
 	int i;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "cmipci: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	/* reset / initialize to a sane state */
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index d54924e..0905fa8 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -2050,6 +2050,7 @@
 
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -2060,8 +2061,14 @@
 	unsigned int i;
 	u32 ulCLK;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "cs4281: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 16d4ebf..2807b97 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -3687,8 +3687,10 @@
 	/* disable CLKRUN */
 	chip->active_ctrl(chip, -chip->amplifier);
 	chip->amplifier = amp_saved; /* restore the status */
+
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -3698,9 +3700,16 @@
 	struct snd_cs46xx *chip = card->private_data;
 	int amp_saved;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "cs46xx: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
+
 	amp_saved = chip->amplifier;
 	chip->amplifier = 0;
 	chip->active_ctrl(chip, 1); /* force to on */
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
index aad0e69..3e4d198 100644
--- a/sound/pci/cs5535audio/cs5535audio_pm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -73,9 +73,10 @@
 	snd_ac97_suspend(cs5535au->ac97);
 	/* save important regs, then disable aclink in hw */
 	snd_cs5535audio_stop_hardware(cs5535au);
+
 	pci_disable_device(pci);
 	pci_save_state(pci);
-
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -87,8 +88,14 @@
 	int timeout;
 	int i;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	/* set LNK_WRM_RST to reset AC link */
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 493ec08..55caf34 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -226,9 +226,9 @@
 
 	snd_emu10k1_done(emu);
 
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -237,11 +237,16 @@
 	struct snd_card *card = pci_get_drvdata(pci);
 	struct snd_emu10k1 *emu = card->private_data;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "emu10k1: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
-	
+
 	snd_emu10k1_resume_init(emu);
 	snd_emu10k1_efx_resume(emu);
 	snd_ac97_resume(emu->ac97);
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 8058059..8bc4ffa 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -956,6 +956,7 @@
 	 .ca0151_chip = 1,
 	 .spk71 = 1,
 	 .spdif_bug = 1,
+	 .adc_1361t = 1,  /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
 	 .ac97_chip = 1} ,
 	{.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
 	 .driver = "Audigy2", .name = "Audigy 2 [Unknown]",
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 8cb4fb2..d2a811f 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -2072,9 +2072,10 @@
 	udelay(100);
 	snd_ak4531_suspend(ensoniq->u.es1370.ak4531);
 #endif	
-	pci_set_power_state(pci, PCI_D3hot);
+
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -2083,9 +2084,14 @@
 	struct snd_card *card = pci_get_drvdata(pci);
 	struct ensoniq *ensoniq = card->private_data;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR DRIVER_NAME ": pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	snd_ensoniq_chip_init(ensoniq);
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 2da988f..1a8d36d 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1481,10 +1481,14 @@
 		*d = snd_es1938_reg_read(chip, *s);
 
 	outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
-	if (chip->irq >= 0)
+	if (chip->irq >= 0) {
+		synchronize_irq(chip->irq);
 		free_irq(chip->irq, chip);
+		chip->irq = -1;
+	}
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1494,10 +1498,22 @@
 	struct es1938 *chip = card->private_data;
 	unsigned char *s, *d;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
-	request_irq(pci->irq, snd_es1938_interrupt,
-		    IRQF_DISABLED|IRQF_SHARED, "ES1938", chip);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "es1938: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
+
+	if (request_irq(pci->irq, snd_es1938_interrupt,
+			IRQF_DISABLED|IRQF_SHARED, "ES1938", chip)) {
+		printk(KERN_ERR "es1938: unable to grab IRQ %d, "
+		       "disabling device\n", pci->irq);
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	chip->irq = pci->irq;
 	snd_es1938_chip_init(chip);
 
@@ -1556,8 +1572,10 @@
 
 	snd_es1938_free_gameport(chip);
 
-	if (chip->irq >= 0)
+	if (chip->irq >= 0) {
+		synchronize_irq(chip->irq);
 		free_irq(chip->irq, chip);
+	}
 	pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
 	kfree(chip);
@@ -1602,6 +1620,7 @@
 	spin_lock_init(&chip->mixer_lock);
 	chip->card = card;
 	chip->pci = pci;
+	chip->irq = -1;
 	if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
 		kfree(chip);
 		pci_disable_device(pci);
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index b9d723c..092da53e 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -432,46 +432,6 @@
 #define ESM_MODE_PLAY		0
 #define ESM_MODE_CAPTURE	1
 
-/* acpi states */
-enum {
-	ACPI_D0=0,
-	ACPI_D1,
-	ACPI_D2,
-	ACPI_D3
-};
-
-/* bits in the acpi masks */
-#define ACPI_12MHZ	( 1 << 15)
-#define ACPI_24MHZ	( 1 << 14)
-#define ACPI_978	( 1 << 13)
-#define ACPI_SPDIF	( 1 << 12)
-#define ACPI_GLUE	( 1 << 11)
-#define ACPI__10	( 1 << 10) /* reserved */
-#define ACPI_PCIINT	( 1 << 9)
-#define ACPI_HV		( 1 << 8) /* hardware volume */
-#define ACPI_GPIO	( 1 << 7)
-#define ACPI_ASSP	( 1 << 6)
-#define ACPI_SB		( 1 << 5) /* sb emul */
-#define ACPI_FM		( 1 << 4) /* fm emul */
-#define ACPI_RB		( 1 << 3) /* ringbus / aclink */
-#define ACPI_MIDI	( 1 << 2) 
-#define ACPI_GP		( 1 << 1) /* game port */
-#define ACPI_WP		( 1 << 0) /* wave processor */
-
-#define ACPI_ALL	(0xffff)
-#define ACPI_SLEEP	(~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \
-			ACPI_MIDI|ACPI_GP|ACPI_WP))
-#define ACPI_NONE	(ACPI__10)
-
-/* these masks indicate which units we care about at
-	which states */
-static u16 acpi_state_mask[] = {
-	[ACPI_D0] = ACPI_ALL,
-	[ACPI_D1] = ACPI_SLEEP,
-	[ACPI_D2] = ACPI_SLEEP,
-	[ACPI_D3] = ACPI_NONE
-};
-
 
 /* APU use in the driver */
 enum snd_enum_apu_type {
@@ -2160,21 +2120,6 @@
 }
 
 /*
- * power management
- */
-static void snd_es1968_set_acpi(struct es1968 *chip, int state)
-{
-	u16 active_mask = acpi_state_mask[state];
-
-	pci_set_power_state(chip->pci, state);
-	/* make sure the units we care about are on 
-		XXX we might want to do this before state flipping? */
-	pci_write_config_word(chip->pci, 0x54, ~ active_mask);
-	pci_write_config_word(chip->pci, 0x56, ~ active_mask);
-}
-
-
-/*
  * initialize maestro chip
  */
 static void snd_es1968_chip_init(struct es1968 *chip)
@@ -2196,9 +2141,6 @@
 	 * IRQs.
 	 */
 	
-	/* do config work at full power */
-	snd_es1968_set_acpi(chip, ACPI_D0);
-
 	/* Config Reg A */
 	pci_read_config_word(pci, ESM_CONFIG_A, &w);
 
@@ -2397,9 +2339,10 @@
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
 	snd_es1968_bob_stop(chip);
-	snd_es1968_set_acpi(chip, ACPI_D3);
+
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -2413,9 +2356,16 @@
 		return 0;
 
 	/* restore all our config */
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "es1968: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
+
 	snd_es1968_chip_init(chip);
 
 	/* need to restore the base pointers.. */ 
@@ -2514,7 +2464,6 @@
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
 	snd_es1968_free_gameport(chip);
-	snd_es1968_set_acpi(chip, ACPI_D3);
 	chip->master_switch = NULL;
 	chip->master_volume = NULL;
 	pci_release_regions(chip->pci);
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 3ec7d7e..77e3d5c 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1531,9 +1531,9 @@
 		chip->saved_regs[i] = inw(chip->port + saved_regs[i]);
 	/* FIXME: tea575x suspend */
 
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1543,9 +1543,14 @@
 	struct fm801 *chip = card->private_data;
 	int i;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "fm801: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	snd_fm801_chip_init(chip, 1);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index feeed12..e35cfd3 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -55,7 +55,7 @@
 static int position_fix;
 static int probe_mask = -1;
 static int single_cmd;
-static int disable_msi;
+static int enable_msi;
 
 module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -69,8 +69,8 @@
 MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
 module_param(single_cmd, bool, 0444);
 MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only).");
-module_param(disable_msi, int, 0);
-MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
+module_param(enable_msi, int, 0);
+MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
 
 
 /* just for backward compatibility */
@@ -86,6 +86,7 @@
 			 "{ATI, SB450},"
 			 "{ATI, SB600},"
 			 "{ATI, RS600},"
+			 "{ATI, RS690},"
 			 "{VIA, VT8251},"
 			 "{VIA, VT8237A},"
 			 "{SiS, SIS966},"
@@ -336,6 +337,7 @@
 	unsigned int initialized :1;
 	unsigned int single_cmd :1;
 	unsigned int polling_mode :1;
+	unsigned int msi :1;
 };
 
 /* driver types */
@@ -396,6 +398,7 @@
  */
 #define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0)
 
+static int azx_acquire_irq(struct azx *chip, int do_disconnect);
 
 /*
  * Interface for HD codec
@@ -535,6 +538,18 @@
 		schedule_timeout_interruptible(1);
 	} while (time_after_eq(timeout, jiffies));
 
+	if (chip->msi) {
+		snd_printk(KERN_WARNING "hda_intel: No response from codec, "
+			   "disabling MSI...\n");
+		free_irq(chip->irq, chip);
+		chip->irq = -1;
+		pci_disable_msi(chip->pci);
+		chip->msi = 0;
+		if (azx_acquire_irq(chip, 1) < 0)
+			return -1;
+		goto again;
+	}
+
 	if (!chip->polling_mode) {
 		snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, "
 			   "switching to polling mode...\n");
@@ -1363,6 +1378,20 @@
 	return 0;
 }
 
+static int azx_acquire_irq(struct azx *chip, int do_disconnect)
+{
+	if (request_irq(chip->pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+			"HDA Intel", chip)) {
+		printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
+		       "disabling device\n", chip->pci->irq);
+		if (do_disconnect)
+			snd_card_disconnect(chip->card);
+		return -1;
+	}
+	chip->irq = chip->pci->irq;
+	return 0;
+}
+
 
 #ifdef CONFIG_PM
 /*
@@ -1379,12 +1408,16 @@
 		snd_pcm_suspend_all(chip->pcm[i]);
 	snd_hda_suspend(chip->bus, state);
 	azx_free_cmd_io(chip);
-	if (chip->irq >= 0)
+	if (chip->irq >= 0) {
+		synchronize_irq(chip->irq);
 		free_irq(chip->irq, chip);
-	if (!disable_msi)
+		chip->irq = -1;
+	}
+	if (chip->msi)
 		pci_disable_msi(chip->pci);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1393,15 +1426,20 @@
 	struct snd_card *card = pci_get_drvdata(pci);
 	struct azx *chip = card->private_data;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
-	if (!disable_msi)
-		pci_enable_msi(pci);
-	/* FIXME: need proper error handling */
-	request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
-		    "HDA Intel", chip);
-	chip->irq = pci->irq;
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "hda-intel: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
+	if (chip->msi)
+		if (pci_enable_msi(pci) < 0)
+			chip->msi = 0;
+	if (azx_acquire_irq(chip, 1) < 0)
+		return -EIO;
 	azx_init_chip(chip);
 	snd_hda_resume(chip->bus);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -1431,15 +1469,14 @@
 		/* disable position buffer */
 		azx_writel(chip, DPLBASE, 0);
 		azx_writel(chip, DPUBASE, 0);
-
-		synchronize_irq(chip->irq);
 	}
 
 	if (chip->irq >= 0) {
+		synchronize_irq(chip->irq);
 		free_irq(chip->irq, (void*)chip);
-		if (!disable_msi)
-			pci_disable_msi(chip->pci);
 	}
+	if (chip->msi)
+		pci_disable_msi(chip->pci);
 	if (chip->remap_addr)
 		iounmap(chip->remap_addr);
 
@@ -1494,6 +1531,7 @@
 	chip->pci = pci;
 	chip->irq = -1;
 	chip->driver_type = driver_type;
+	chip->msi = enable_msi;
 
 	chip->position_fix = position_fix;
 	chip->single_cmd = single_cmd;
@@ -1523,16 +1561,14 @@
 		goto errout;
 	}
 
-	if (!disable_msi)
-		pci_enable_msi(pci);
+	if (chip->msi)
+		if (pci_enable_msi(pci) < 0)
+			chip->msi = 0;
 
-	if (request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
-			"HDA Intel", (void*)chip)) {
-		snd_printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
+	if (azx_acquire_irq(chip, 0) < 0) {
 		err = -EBUSY;
 		goto errout;
 	}
-	chip->irq = pci->irq;
 
 	pci_set_master(pci);
 	synchronize_irq(chip->irq);
@@ -1677,6 +1713,7 @@
 	{ 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */
 	{ 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
 	{ 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
+	{ 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */
 	{ 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
 	{ 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
 	{ 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 511df07..edd22de 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -818,6 +818,8 @@
 	  .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7,
 	  .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1263,
+	  .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5F */
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1297,
 	  .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */
 	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30af,
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index a27440f..7333f27 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -161,5 +161,6 @@
  */
 struct hda_codec_preset snd_hda_preset_atihdmi[] = {
 	{ .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
+	{ .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi },
 	{} /* terminator */
 };
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 84a3eb8..fb96144 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1799,7 +1799,7 @@
 	/* SPDIF for stream index #1 */
 	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
 		codec->num_pcms = 2;
-		info++;
+		info = spec->pcm_rec + 1;
 		info->name = spec->stream_name_digital;
 		if (spec->multiout.dig_out_nid &&
 		    spec->stream_digital_playback) {
@@ -1820,7 +1820,7 @@
 	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
 	    spec->adc_nids) {
 		codec->num_pcms = 3;
-		info++;
+		info = spec->pcm_rec + 2;
 		info->name = spec->stream_name_analog;
 		/* No playback stream for second PCM */
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
@@ -5870,7 +5870,7 @@
 	{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397,
 	  .config = ALC262_FUJITSU },
 	{ .modelname = "hp-bpc", .config = ALC262_HP_BPC },
-	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x208c,
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x280c,
 	  .config = ALC262_HP_BPC }, /* xw4400 */
 	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3014,
 	  .config = ALC262_HP_BPC }, /* xw6400 */
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 731b7b9..fe51ef3 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -336,6 +336,13 @@
 	  .pci_subvendor = PCI_VENDOR_ID_INTEL,
 	  .pci_subdevice = 0x2668,	/* DFI LanParty */
 	  .config = STAC_REF },
+	/* Dell laptops have BIOS problem */
+	{ .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01b5,
+	  .config = STAC_REF },	/* Dell Inspiron 630m */
+	{ .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01c2,
+	  .config = STAC_REF },	/* Dell Latitude D620 */
+	{ .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01cb,
+	  .config = STAC_REF },	/* Dell Latitude 120L */
 	{} /* terminator */
 };
 
@@ -591,13 +598,6 @@
 	  .pci_subvendor = PCI_VENDOR_ID_INTEL,
 	  .pci_subdevice = 0x2668,	/* DFI LanParty */
 	  .config = STAC_REF },		/* SigmaTel reference board */
-	/* Dell laptops have BIOS problem */
-	{ .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01b5,
-	  .config = STAC_REF },	/* Dell Inspiron 630m */
-	{ .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01c2,
-	  .config = STAC_REF },	/* Dell Latitude D620 */
-	{ .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01cb,
-	  .config = STAC_REF },	/* Dell Latitude 120L */
 	{} /* terminator */
 };
 
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index f4319b8..9c1bce7 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1962,6 +1962,12 @@
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
+		.subvendor = 0x10f7,
+		.subdevice = 0x834c,
+		.name = "Panasonic CF-R4",
+		.type = AC97_TUNE_HP_ONLY,
+	},
+	{
 		.subvendor = 0x110a,
 		.subdevice = 0x0056,
 		.name = "Fujitsu-Siemens Scenic",	/* AD1981? */
@@ -2476,10 +2482,14 @@
 	if (chip->device_type == DEVICE_INTEL_ICH4)
 		chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
 
-	if (chip->irq >= 0)
+	if (chip->irq >= 0) {
+		synchronize_irq(chip->irq);
 		free_irq(chip->irq, chip);
+		chip->irq = -1;
+	}
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -2489,11 +2499,22 @@
 	struct intel8x0 *chip = card->private_data;
 	int i;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "intel8x0: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
-	request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED,
-		    card->shortname, chip);
+	if (request_irq(pci->irq, snd_intel8x0_interrupt,
+			IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+		printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
+		       "disabling device\n", pci->irq);
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	chip->irq = pci->irq;
 	synchronize_irq(chip->irq);
 	snd_intel8x0_chip_init(chip, 0);
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 6703f5c..bd467c5 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1045,10 +1045,14 @@
 	for (i = 0; i < chip->pcm_devs; i++)
 		snd_pcm_suspend_all(chip->pcm[i]);
 	snd_ac97_suspend(chip->ac97);
-	if (chip->irq >= 0)
+	if (chip->irq >= 0) {
+		synchronize_irq(chip->irq);
 		free_irq(chip->irq, chip);
+		chip->irq = -1;
+	}
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1057,11 +1061,22 @@
 	struct snd_card *card = pci_get_drvdata(pci);
 	struct intel8x0m *chip = card->private_data;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "intel8x0m: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
-	request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED,
-		    card->shortname, chip);
+	if (request_irq(pci->irq, snd_intel8x0_interrupt,
+			IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+		printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
+		       "disabling device\n", pci->irq);
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	chip->irq = pci->irq;
 	snd_intel8x0_chip_init(chip, 0);
 	snd_ac97_resume(chip->ac97);
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 05605f4..8cab342 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2589,12 +2589,9 @@
 		chip->suspend_mem[index++] = 
 			snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA, i);
 
-	/* power down apci registers */
-	snd_m3_outw(chip, 0xffff, 0x54);
-	snd_m3_outw(chip, 0xffff, 0x56);
-
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -2607,8 +2604,14 @@
 	if (chip->suspend_mem == NULL)
 		return 0;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "maestor3: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	/* first lets just bring everything back. .*/
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index b1bbdb9..945d21b 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1390,6 +1390,7 @@
 	chip->coeffs_current = 0;
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1401,8 +1402,17 @@
 
 	/* Perform a full reset on the hardware */
 	chip->in_resume = 1;
+
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "nm256: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
+	pci_set_master(pci);
+
 	snd_nm256_init_chip(chip);
 
 	/* restore ac97 */
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index ec48991..56e0c01 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1178,9 +1178,9 @@
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1189,9 +1189,14 @@
 	struct snd_card *card = pci_get_drvdata(pci);
 	struct snd_riptide *chip = card->private_data;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "riptide: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 	snd_riptide_initialize(chip);
 	snd_ac97_resume(chip->ac97);
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 0d47887..1fbc432 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -3966,15 +3966,9 @@
 	snd_ac97_suspend(trident->ac97);
 	snd_ac97_suspend(trident->ac97_sec);
 
-	switch (trident->device) {
-	case TRIDENT_DEVICE_ID_DX:
-	case TRIDENT_DEVICE_ID_NX:
-		break;			/* TODO */
-	case TRIDENT_DEVICE_ID_SI7018:
-		break;
-	}
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -3983,9 +3977,15 @@
 	struct snd_card *card = pci_get_drvdata(pci);
 	struct snd_trident *trident = card->private_data;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
-	pci_set_master(pci); /* to be sure */
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "trident: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
+	pci_set_master(pci);
 
 	switch (trident->device) {
 	case TRIDENT_DEVICE_ID_DX:
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index e6990e0..92b0736 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2185,9 +2185,9 @@
 		chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
 	}
 
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -2197,9 +2197,15 @@
 	struct via82xx *chip = card->private_data;
 	int i;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "via82xx: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
+	pci_set_master(pci);
 
 	snd_via82xx_chip_init(chip);
 
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 5ab1cf3..feb27c9 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1032,9 +1032,10 @@
 		snd_via82xx_channel_reset(chip, &chip->devs[i]);
 	synchronize_irq(chip->irq);
 	snd_ac97_suspend(chip->ac97);
-	pci_set_power_state(pci, PCI_D3hot);
+
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -1044,9 +1045,14 @@
 	struct via82xx_modem *chip = card->private_data;
 	int i;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "via82xx-modem: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 
 	snd_via82xx_chip_init(chip);
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index e7cd8ac..af49e8a 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -266,9 +266,9 @@
 	int err;
 
 	err = snd_vx_suspend(&vx->core, state);
-	pci_set_power_state(pci, PCI_D3hot);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return err;
 }
 
@@ -277,9 +277,14 @@
 	struct snd_card *card = pci_get_drvdata(pci);
 	struct snd_vx222 *vx = card->private_data;
 
-	pci_restore_state(pci);
-	pci_enable_device(pci);
 	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "vx222: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 	return snd_vx_resume(&vx->core);
 }
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index ebc6da8..a40c108 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2218,6 +2218,7 @@
 	snd_ymfpci_disable_dsp(chip);
 	pci_disable_device(pci);
 	pci_save_state(pci);
+	pci_set_power_state(pci, pci_choose_state(pci, state));
 	return 0;
 }
 
@@ -2227,8 +2228,14 @@
 	struct snd_ymfpci *chip = card->private_data;
 	unsigned int i;
 
+	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
-	pci_enable_device(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "ymfpci: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
 	pci_set_master(pci);
 	snd_ymfpci_aclink_reset(pci);
 	snd_ymfpci_codec_ready(chip, 0);
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c82b01c..67202b9 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -1469,7 +1469,8 @@
 	subs->cur_audiofmt = NULL;
 	subs->cur_rate = 0;
 	subs->period_bytes = 0;
-	release_substream_urbs(subs, 0);
+	if (!subs->stream->chip->shutdown)
+		release_substream_urbs(subs, 0);
 	return snd_pcm_free_vmalloc_buffer(substream);
 }
 
diff --git a/usr/Makefile b/usr/Makefile
index e338e7b..382702a 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -20,7 +20,7 @@
 hostprogs-y := gen_init_cpio
 initramfs   := $(CONFIG_SHELL) $(srctree)/scripts/gen_initramfs_list.sh
 ramfs-input := $(if $(filter-out "",$(CONFIG_INITRAMFS_SOURCE)), \
-                    $(CONFIG_INITRAMFS_SOURCE),-d)
+			$(shell echo $(CONFIG_INITRAMFS_SOURCE)),-d)
 ramfs-args  := \
         $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \
         $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))